We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Mitmproxy odd UI behaviour
##### Steps to reproduce the problem:

1. Run `mitmproxy` and start intercepting flows.

2. Let the UI fill with flows and then goto the last flow.

![m1](https://user-images.githubusercontent.com/20314742/32436238-62843d80-c309-11e7-9c28-df97ff8b4688.png)

3. Press up key to go one flow above.

4. The UI shifts one flow downwards instead of marker going one flow upwards.

![m2](https://user-images.githubusercontent.com/20314742/32436228-5d7a0df6-c309-11e7-85ca-16f5438d6adf.png)


##### Any other comments? What have you tried so far?

This is not a deal breaker or anything but a bit annoying. This seems to happen only with the last flow in UI.

##### System information

<!-- Paste the output of "mitmproxy --version" here. -->

```
Mitmproxy: 3.0.0 
Python:    3.6.2
OpenSSL:   OpenSSL 1.0.2g  1 Mar 2016
Platform:  Linux-4.8.0-53-generic-x86_64-with-debian-stretch-sid
```

<!-- Please use the mitmproxy forums (https://discourse.mitmproxy.org/) for support/how-to questions. Thanks! :) -->

Mitmproxy odd UI behaviour
##### Steps to reproduce the problem:

1. Run `mitmproxy` and start intercepting flows.

2. Let the UI fill with flows and then goto the last flow.

![m1](https://user-images.githubusercontent.com/20314742/32436238-62843d80-c309-11e7-9c28-df97ff8b4688.png)

3. Press up key to go one flow above.

4. The UI shifts one flow downwards instead of marker going one flow upwards.

![m2](https://user-images.githubusercontent.com/20314742/32436228-5d7a0df6-c309-11e7-85ca-16f5438d6adf.png)


##### Any other comments? What have you tried so far?

This is not a deal breaker or anything but a bit annoying. This seems to happen only with the last flow in UI.

##### System information

<!-- Paste the output of "mitmproxy --version" here. -->

```
Mitmproxy: 3.0.0 
Python:    3.6.2
OpenSSL:   OpenSSL 1.0.2g  1 Mar 2016
Platform:  Linux-4.8.0-53-generic-x86_64-with-debian-stretch-sid
```

<!-- Please use the mitmproxy forums (https://discourse.mitmproxy.org/) for support/how-to questions. Thanks! :) -->


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mitmproxy/tools/console/window.py`
Content:
```
1 import re
2 
3 import urwid
4 from mitmproxy.tools.console import common
5 from mitmproxy.tools.console import signals
6 from mitmproxy.tools.console import statusbar
7 from mitmproxy.tools.console import flowlist
8 from mitmproxy.tools.console import flowview
9 from mitmproxy.tools.console import commands
10 from mitmproxy.tools.console import keybindings
11 from mitmproxy.tools.console import options
12 from mitmproxy.tools.console import overlay
13 from mitmproxy.tools.console import help
14 from mitmproxy.tools.console import grideditor
15 from mitmproxy.tools.console import eventlog
16 
17 
18 class Header(urwid.Frame):
19     def __init__(self, widget, title, focus):
20         super().__init__(
21             widget,
22             header = urwid.AttrWrap(
23                 urwid.Text(title),
24                 "heading" if focus else "heading_inactive"
25             )
26         )
27 
28 
29 class WindowStack:
30     def __init__(self, master, base):
31         self.master = master
32         self.windows = dict(
33             flowlist = flowlist.FlowListBox(master),
34             flowview = flowview.FlowView(master),
35             commands = commands.Commands(master),
36             keybindings = keybindings.KeyBindings(master),
37             options = options.Options(master),
38             help = help.HelpView(master),
39             eventlog = eventlog.EventLog(master),
40 
41             edit_focus_query = grideditor.QueryEditor(master),
42             edit_focus_cookies = grideditor.CookieEditor(master),
43             edit_focus_setcookies = grideditor.SetCookieEditor(master),
44             edit_focus_form = grideditor.RequestFormEditor(master),
45             edit_focus_path = grideditor.PathEditor(master),
46             edit_focus_request_headers = grideditor.RequestHeaderEditor(master),
47             edit_focus_response_headers = grideditor.ResponseHeaderEditor(master),
48         )
49         self.stack = [base]
50         self.overlay = None
51 
52     def set_overlay(self, o, **kwargs):
53         self.overlay = overlay.SimpleOverlay(
54             self, o, self.top_widget(), o.width, **kwargs,
55         )
56 
57     def top_window(self):
58         """
59             The current top window, ignoring overlays.
60         """
61         return self.windows[self.stack[-1]]
62 
63     def top_widget(self):
64         """
65             The current top widget - either a window or the active overlay.
66         """
67         if self.overlay:
68             return self.overlay
69         return self.top_window()
70 
71     def push(self, wname):
72         if self.stack[-1] == wname:
73             return
74         prev = self.top_window()
75         self.stack.append(wname)
76         self.call("layout_pushed", prev)
77 
78     def pop(self, *args, **kwargs):
79         """
80             Pop off the stack, return True if we're already at the top.
81         """
82         if not self.overlay and len(self.stack) == 1:
83             return True
84         self.call("layout_popping")
85         if self.overlay:
86             self.overlay = None
87         else:
88             self.stack.pop()
89 
90     def call(self, name, *args, **kwargs):
91         """
92             Call a function on both the top window, and the overlay if there is
93             one. If the widget has a key_responder, we call the function on the
94             responder instead.
95         """
96         getattr(self.top_window(), name)(*args, **kwargs)
97         if self.overlay:
98             getattr(self.overlay, name)(*args, **kwargs)
99 
100 
101 class Window(urwid.Frame):
102     def __init__(self, master):
103         self.statusbar = statusbar.StatusBar(master)
104         super().__init__(
105             None,
106             header = None,
107             footer = urwid.AttrWrap(self.statusbar, "background")
108         )
109         self.master = master
110         self.master.view.sig_view_refresh.connect(self.view_changed)
111         self.master.view.sig_view_add.connect(self.view_changed)
112         self.master.view.sig_view_remove.connect(self.view_changed)
113         self.master.view.sig_view_update.connect(self.view_changed)
114         self.master.view.focus.sig_change.connect(self.view_changed)
115         self.master.view.focus.sig_change.connect(self.focus_changed)
116 
117         signals.focus.connect(self.sig_focus)
118         signals.flow_change.connect(self.flow_changed)
119         signals.pop_view_state.connect(self.pop)
120         signals.push_view_state.connect(self.push)
121 
122         self.master.options.subscribe(self.configure, ["console_layout"])
123         self.master.options.subscribe(self.configure, ["console_layout_headers"])
124         self.pane = 0
125         self.stacks = [
126             WindowStack(master, "flowlist"),
127             WindowStack(master, "eventlog")
128         ]
129 
130     def focus_stack(self):
131         return self.stacks[self.pane]
132 
133     def configure(self, otions, updated):
134         self.refresh()
135 
136     def refresh(self):
137         """
138             Redraw the layout.
139         """
140         c = self.master.options.console_layout
141         if c == "single":
142             self.pane = 0
143 
144         def wrapped(idx):
145             window = self.stacks[idx].top_window()
146             widget = self.stacks[idx].top_widget()
147             if self.master.options.console_layout_headers and window.title:
148                 return Header(widget, window.title, self.pane == idx)
149             else:
150                 return widget
151 
152         w = None
153         if c == "single":
154             w = wrapped(0)
155         elif c == "vertical":
156             w = urwid.Pile(
157                 [
158                     wrapped(i) for i, s in enumerate(self.stacks)
159                 ]
160             )
161         else:
162             w = urwid.Columns(
163                 [wrapped(i) for i, s in enumerate(self.stacks)],
164                 dividechars=1
165             )
166 
167         self.body = urwid.AttrWrap(w, "background")
168 
169     def flow_changed(self, sender, flow):
170         if self.master.view.focus.flow:
171             if flow.id == self.master.view.focus.flow.id:
172                 self.focus_changed()
173 
174     def focus_changed(self, *args, **kwargs):
175         """
176             Triggered when the focus changes - either when it's modified, or
177             when it changes to a different flow altogether.
178         """
179         for i in self.stacks:
180             i.call("focus_changed")
181 
182     def view_changed(self, *args, **kwargs):
183         """
184             Triggered when the view list has changed.
185         """
186         for i in self.stacks:
187             i.call("view_changed")
188 
189     def set_overlay(self, o, **kwargs):
190         """
191             Set an overlay on the currently focused stack.
192         """
193         self.focus_stack().set_overlay(o, **kwargs)
194         self.refresh()
195 
196     def push(self, wname):
197         """
198             Push a window onto the currently focused stack.
199         """
200         self.focus_stack().push(wname)
201         self.refresh()
202         self.view_changed()
203         self.focus_changed()
204 
205     def pop(self, *args, **kwargs):
206         """
207             Pop a window from the currently focused stack. If there is only one
208             window on the stack, this prompts for exit.
209         """
210         if self.focus_stack().pop():
211             self.master.prompt_for_exit()
212         else:
213             self.refresh()
214             self.view_changed()
215             self.focus_changed()
216 
217     def current(self, keyctx):
218         """
219             Returns the active widget, but only the current focus or overlay has
220             a matching key context.
221         """
222         t = self.focus_stack().top_widget()
223         if t.keyctx == keyctx:
224             return t
225 
226     def current_window(self, keyctx):
227         """
228             Returns the active window, ignoring overlays.
229         """
230         t = self.focus_stack().top_window()
231         if t.keyctx == keyctx:
232             return t
233 
234     def any(self, keyctx):
235         """
236             Returns the top window of either stack if they match the context.
237         """
238         for t in [x.top_window() for x in self.stacks]:
239             if t.keyctx == keyctx:
240                 return t
241 
242     def sig_focus(self, sender, section):
243         self.focus_position = section
244 
245     def switch(self):
246         """
247             Switch between the two panes.
248         """
249         if self.master.options.console_layout == "single":
250             self.pane = 0
251         else:
252             self.pane = (self.pane + 1) % len(self.stacks)
253         self.refresh()
254 
255     def mouse_event(self, *args, **kwargs):
256         # args: (size, event, button, col, row)
257         k = super().mouse_event(*args, **kwargs)
258         if not k:
259             if args[1] == "mouse drag":
260                 signals.status_message.send(
261                     message = "Hold down fn, shift, alt or ctrl to select text or use the --no-mouse parameter.",
262                     expire = 1
263                 )
264             elif args[1] == "mouse press" and args[2] == 4:
265                 self.keypress(args[0], "up")
266             elif args[1] == "mouse press" and args[2] == 5:
267                 self.keypress(args[0], "down")
268             else:
269                 return False
270             return True
271 
272     def keypress(self, size, k):
273         if self.focus_part == "footer":
274             return super().keypress(size, k)
275         else:
276             fs = self.focus_stack().top_widget()
277             k = fs.keypress(size, k)
278             if k:
279                 return self.master.keymap.handle(fs.keyctx, k)
280 
281 
282 class Screen(urwid.raw_display.Screen):
283 
284     def write(self, data):
285         if common.IS_WSL:
286             # replace urwid's SI/SO, which produce artifacts under WSL.
287             # at some point we may figure out what they actually do.
288             data = re.sub("[\x0e\x0f]", "", data)
289         super().write(data)
290
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mitmproxy/tools/console/window.py b/mitmproxy/tools/console/window.py
--- a/mitmproxy/tools/console/window.py
+++ b/mitmproxy/tools/console/window.py
@@ -156,12 +156,14 @@
             w = urwid.Pile(
                 [
                     wrapped(i) for i, s in enumerate(self.stacks)
-                ]
+                ],
+                focus_item=self.pane
             )
         else:
             w = urwid.Columns(
                 [wrapped(i) for i, s in enumerate(self.stacks)],
-                dividechars=1
+                dividechars=1,
+                focus_column=self.pane
             )
 
         self.body = urwid.AttrWrap(w, "background")
@@ -270,13 +272,12 @@
             return True
 
     def keypress(self, size, k):
-        if self.focus_part == "footer":
-            return super().keypress(size, k)
-        else:
-            fs = self.focus_stack().top_widget()
-            k = fs.keypress(size, k)
-            if k:
-                return self.master.keymap.handle(fs.keyctx, k)
+        k = super().keypress(size, k)
+        if k:
+            return self.master.keymap.handle(
+                self.focus_stack().top_widget().keyctx,
+                k
+            )
 
 
 class Screen(urwid.raw_display.Screen):

{"golden_diff": "diff --git a/mitmproxy/tools/console/window.py b/mitmproxy/tools/console/window.py\n--- a/mitmproxy/tools/console/window.py\n+++ b/mitmproxy/tools/console/window.py\n@@ -156,12 +156,14 @@\n             w = urwid.Pile(\n                 [\n                     wrapped(i) for i, s in enumerate(self.stacks)\n-                ]\n+                ],\n+                focus_item=self.pane\n             )\n         else:\n             w = urwid.Columns(\n                 [wrapped(i) for i, s in enumerate(self.stacks)],\n-                dividechars=1\n+                dividechars=1,\n+                focus_column=self.pane\n             )\n \n         self.body = urwid.AttrWrap(w, \"background\")\n@@ -270,13 +272,12 @@\n             return True\n \n     def keypress(self, size, k):\n-        if self.focus_part == \"footer\":\n-            return super().keypress(size, k)\n-        else:\n-            fs = self.focus_stack().top_widget()\n-            k = fs.keypress(size, k)\n-            if k:\n-                return self.master.keymap.handle(fs.keyctx, k)\n+        k = super().keypress(size, k)\n+        if k:\n+            return self.master.keymap.handle(\n+                self.focus_stack().top_widget().keyctx,\n+                k\n+            )\n \n \n class Screen(urwid.raw_display.Screen):\n", "issue": "Mitmproxy odd UI behaviour\n##### Steps to reproduce the problem:\r\n\r\n1. Run `mitmproxy` and start intercepting flows.\r\n\r\n2. Let the UI fill with flows and then goto the last flow.\r\n\r\n![m1](https://user-images.githubusercontent.com/20314742/32436238-62843d80-c309-11e7-9c28-df97ff8b4688.png)\r\n\r\n3. Press up key to go one flow above.\r\n\r\n4. The UI shifts one flow downwards instead of marker going one flow upwards.\r\n\r\n![m2](https://user-images.githubusercontent.com/20314742/32436228-5d7a0df6-c309-11e7-85ca-16f5438d6adf.png)\r\n\r\n\r\n##### Any other comments? What have you tried so far?\r\n\r\nThis is not a deal breaker or anything but a bit annoying. This seems to happen only with the last flow in UI.\r\n\r\n##### System information\r\n\r\n<!-- Paste the output of \"mitmproxy --version\" here. -->\r\n\r\n```\r\nMitmproxy: 3.0.0 \r\nPython:    3.6.2\r\nOpenSSL:   OpenSSL 1.0.2g  1 Mar 2016\r\nPlatform:  Linux-4.8.0-53-generic-x86_64-with-debian-stretch-sid\r\n```\r\n\r\n<!-- Please use the mitmproxy forums (https://discourse.mitmproxy.org/) for support/how-to questions. Thanks! :) -->\r\n\nMitmproxy odd UI behaviour\n##### Steps to reproduce the problem:\r\n\r\n1. Run `mitmproxy` and start intercepting flows.\r\n\r\n2. Let the UI fill with flows and then goto the last flow.\r\n\r\n![m1](https://user-images.githubusercontent.com/20314742/32436238-62843d80-c309-11e7-9c28-df97ff8b4688.png)\r\n\r\n3. Press up key to go one flow above.\r\n\r\n4. The UI shifts one flow downwards instead of marker going one flow upwards.\r\n\r\n![m2](https://user-images.githubusercontent.com/20314742/32436228-5d7a0df6-c309-11e7-85ca-16f5438d6adf.png)\r\n\r\n\r\n##### Any other comments? What have you tried so far?\r\n\r\nThis is not a deal breaker or anything but a bit annoying. This seems to happen only with the last flow in UI.\r\n\r\n##### System information\r\n\r\n<!-- Paste the output of \"mitmproxy --version\" here. -->\r\n\r\n```\r\nMitmproxy: 3.0.0 \r\nPython:    3.6.2\r\nOpenSSL:   OpenSSL 1.0.2g  1 Mar 2016\r\nPlatform:  Linux-4.8.0-53-generic-x86_64-with-debian-stretch-sid\r\n```\r\n\r\n<!-- Please use the mitmproxy forums (https://discourse.mitmproxy.org/) for support/how-to questions. Thanks! :) -->\r\n\n", "before_files": [{"content": "import re\n\nimport urwid\nfrom mitmproxy.tools.console import common\nfrom mitmproxy.tools.console import signals\nfrom mitmproxy.tools.console import statusbar\nfrom mitmproxy.tools.console import flowlist\nfrom mitmproxy.tools.console import flowview\nfrom mitmproxy.tools.console import commands\nfrom mitmproxy.tools.console import keybindings\nfrom mitmproxy.tools.console import options\nfrom mitmproxy.tools.console import overlay\nfrom mitmproxy.tools.console import help\nfrom mitmproxy.tools.console import grideditor\nfrom mitmproxy.tools.console import eventlog\n\n\nclass Header(urwid.Frame):\n    def __init__(self, widget, title, focus):\n        super().__init__(\n            widget,\n            header = urwid.AttrWrap(\n                urwid.Text(title),\n                \"heading\" if focus else \"heading_inactive\"\n            )\n        )\n\n\nclass WindowStack:\n    def __init__(self, master, base):\n        self.master = master\n        self.windows = dict(\n            flowlist = flowlist.FlowListBox(master),\n            flowview = flowview.FlowView(master),\n            commands = commands.Commands(master),\n            keybindings = keybindings.KeyBindings(master),\n            options = options.Options(master),\n            help = help.HelpView(master),\n            eventlog = eventlog.EventLog(master),\n\n            edit_focus_query = grideditor.QueryEditor(master),\n            edit_focus_cookies = grideditor.CookieEditor(master),\n            edit_focus_setcookies = grideditor.SetCookieEditor(master),\n            edit_focus_form = grideditor.RequestFormEditor(master),\n            edit_focus_path = grideditor.PathEditor(master),\n            edit_focus_request_headers = grideditor.RequestHeaderEditor(master),\n            edit_focus_response_headers = grideditor.ResponseHeaderEditor(master),\n        )\n        self.stack = [base]\n        self.overlay = None\n\n    def set_overlay(self, o, **kwargs):\n        self.overlay = overlay.SimpleOverlay(\n            self, o, self.top_widget(), o.width, **kwargs,\n        )\n\n    def top_window(self):\n        \"\"\"\n            The current top window, ignoring overlays.\n        \"\"\"\n        return self.windows[self.stack[-1]]\n\n    def top_widget(self):\n        \"\"\"\n            The current top widget - either a window or the active overlay.\n        \"\"\"\n        if self.overlay:\n            return self.overlay\n        return self.top_window()\n\n    def push(self, wname):\n        if self.stack[-1] == wname:\n            return\n        prev = self.top_window()\n        self.stack.append(wname)\n        self.call(\"layout_pushed\", prev)\n\n    def pop(self, *args, **kwargs):\n        \"\"\"\n            Pop off the stack, return True if we're already at the top.\n        \"\"\"\n        if not self.overlay and len(self.stack) == 1:\n            return True\n        self.call(\"layout_popping\")\n        if self.overlay:\n            self.overlay = None\n        else:\n            self.stack.pop()\n\n    def call(self, name, *args, **kwargs):\n        \"\"\"\n            Call a function on both the top window, and the overlay if there is\n            one. If the widget has a key_responder, we call the function on the\n            responder instead.\n        \"\"\"\n        getattr(self.top_window(), name)(*args, **kwargs)\n        if self.overlay:\n            getattr(self.overlay, name)(*args, **kwargs)\n\n\nclass Window(urwid.Frame):\n    def __init__(self, master):\n        self.statusbar = statusbar.StatusBar(master)\n        super().__init__(\n            None,\n            header = None,\n            footer = urwid.AttrWrap(self.statusbar, \"background\")\n        )\n        self.master = master\n        self.master.view.sig_view_refresh.connect(self.view_changed)\n        self.master.view.sig_view_add.connect(self.view_changed)\n        self.master.view.sig_view_remove.connect(self.view_changed)\n        self.master.view.sig_view_update.connect(self.view_changed)\n        self.master.view.focus.sig_change.connect(self.view_changed)\n        self.master.view.focus.sig_change.connect(self.focus_changed)\n\n        signals.focus.connect(self.sig_focus)\n        signals.flow_change.connect(self.flow_changed)\n        signals.pop_view_state.connect(self.pop)\n        signals.push_view_state.connect(self.push)\n\n        self.master.options.subscribe(self.configure, [\"console_layout\"])\n        self.master.options.subscribe(self.configure, [\"console_layout_headers\"])\n        self.pane = 0\n        self.stacks = [\n            WindowStack(master, \"flowlist\"),\n            WindowStack(master, \"eventlog\")\n        ]\n\n    def focus_stack(self):\n        return self.stacks[self.pane]\n\n    def configure(self, otions, updated):\n        self.refresh()\n\n    def refresh(self):\n        \"\"\"\n            Redraw the layout.\n        \"\"\"\n        c = self.master.options.console_layout\n        if c == \"single\":\n            self.pane = 0\n\n        def wrapped(idx):\n            window = self.stacks[idx].top_window()\n            widget = self.stacks[idx].top_widget()\n            if self.master.options.console_layout_headers and window.title:\n                return Header(widget, window.title, self.pane == idx)\n            else:\n                return widget\n\n        w = None\n        if c == \"single\":\n            w = wrapped(0)\n        elif c == \"vertical\":\n            w = urwid.Pile(\n                [\n                    wrapped(i) for i, s in enumerate(self.stacks)\n                ]\n            )\n        else:\n            w = urwid.Columns(\n                [wrapped(i) for i, s in enumerate(self.stacks)],\n                dividechars=1\n            )\n\n        self.body = urwid.AttrWrap(w, \"background\")\n\n    def flow_changed(self, sender, flow):\n        if self.master.view.focus.flow:\n            if flow.id == self.master.view.focus.flow.id:\n                self.focus_changed()\n\n    def focus_changed(self, *args, **kwargs):\n        \"\"\"\n            Triggered when the focus changes - either when it's modified, or\n            when it changes to a different flow altogether.\n        \"\"\"\n        for i in self.stacks:\n            i.call(\"focus_changed\")\n\n    def view_changed(self, *args, **kwargs):\n        \"\"\"\n            Triggered when the view list has changed.\n        \"\"\"\n        for i in self.stacks:\n            i.call(\"view_changed\")\n\n    def set_overlay(self, o, **kwargs):\n        \"\"\"\n            Set an overlay on the currently focused stack.\n        \"\"\"\n        self.focus_stack().set_overlay(o, **kwargs)\n        self.refresh()\n\n    def push(self, wname):\n        \"\"\"\n            Push a window onto the currently focused stack.\n        \"\"\"\n        self.focus_stack().push(wname)\n        self.refresh()\n        self.view_changed()\n        self.focus_changed()\n\n    def pop(self, *args, **kwargs):\n        \"\"\"\n            Pop a window from the currently focused stack. If there is only one\n            window on the stack, this prompts for exit.\n        \"\"\"\n        if self.focus_stack().pop():\n            self.master.prompt_for_exit()\n        else:\n            self.refresh()\n            self.view_changed()\n            self.focus_changed()\n\n    def current(self, keyctx):\n        \"\"\"\n            Returns the active widget, but only the current focus or overlay has\n            a matching key context.\n        \"\"\"\n        t = self.focus_stack().top_widget()\n        if t.keyctx == keyctx:\n            return t\n\n    def current_window(self, keyctx):\n        \"\"\"\n            Returns the active window, ignoring overlays.\n        \"\"\"\n        t = self.focus_stack().top_window()\n        if t.keyctx == keyctx:\n            return t\n\n    def any(self, keyctx):\n        \"\"\"\n            Returns the top window of either stack if they match the context.\n        \"\"\"\n        for t in [x.top_window() for x in self.stacks]:\n            if t.keyctx == keyctx:\n                return t\n\n    def sig_focus(self, sender, section):\n        self.focus_position = section\n\n    def switch(self):\n        \"\"\"\n            Switch between the two panes.\n        \"\"\"\n        if self.master.options.console_layout == \"single\":\n            self.pane = 0\n        else:\n            self.pane = (self.pane + 1) % len(self.stacks)\n        self.refresh()\n\n    def mouse_event(self, *args, **kwargs):\n        # args: (size, event, button, col, row)\n        k = super().mouse_event(*args, **kwargs)\n        if not k:\n            if args[1] == \"mouse drag\":\n                signals.status_message.send(\n                    message = \"Hold down fn, shift, alt or ctrl to select text or use the --no-mouse parameter.\",\n                    expire = 1\n                )\n            elif args[1] == \"mouse press\" and args[2] == 4:\n                self.keypress(args[0], \"up\")\n            elif args[1] == \"mouse press\" and args[2] == 5:\n                self.keypress(args[0], \"down\")\n            else:\n                return False\n            return True\n\n    def keypress(self, size, k):\n        if self.focus_part == \"footer\":\n            return super().keypress(size, k)\n        else:\n            fs = self.focus_stack().top_widget()\n            k = fs.keypress(size, k)\n            if k:\n                return self.master.keymap.handle(fs.keyctx, k)\n\n\nclass Screen(urwid.raw_display.Screen):\n\n    def write(self, data):\n        if common.IS_WSL:\n            # replace urwid's SI/SO, which produce artifacts under WSL.\n            # at some point we may figure out what they actually do.\n            data = re.sub(\"[\\x0e\\x0f]\", \"\", data)\n        super().write(data)\n", "path": "mitmproxy/tools/console/window.py"}], "after_files": [{"content": "import re\n\nimport urwid\nfrom mitmproxy.tools.console import common\nfrom mitmproxy.tools.console import signals\nfrom mitmproxy.tools.console import statusbar\nfrom mitmproxy.tools.console import flowlist\nfrom mitmproxy.tools.console import flowview\nfrom mitmproxy.tools.console import commands\nfrom mitmproxy.tools.console import keybindings\nfrom mitmproxy.tools.console import options\nfrom mitmproxy.tools.console import overlay\nfrom mitmproxy.tools.console import help\nfrom mitmproxy.tools.console import grideditor\nfrom mitmproxy.tools.console import eventlog\n\n\nclass Header(urwid.Frame):\n    def __init__(self, widget, title, focus):\n        super().__init__(\n            widget,\n            header = urwid.AttrWrap(\n                urwid.Text(title),\n                \"heading\" if focus else \"heading_inactive\"\n            )\n        )\n\n\nclass WindowStack:\n    def __init__(self, master, base):\n        self.master = master\n        self.windows = dict(\n            flowlist = flowlist.FlowListBox(master),\n            flowview = flowview.FlowView(master),\n            commands = commands.Commands(master),\n            keybindings = keybindings.KeyBindings(master),\n            options = options.Options(master),\n            help = help.HelpView(master),\n            eventlog = eventlog.EventLog(master),\n\n            edit_focus_query = grideditor.QueryEditor(master),\n            edit_focus_cookies = grideditor.CookieEditor(master),\n            edit_focus_setcookies = grideditor.SetCookieEditor(master),\n            edit_focus_form = grideditor.RequestFormEditor(master),\n            edit_focus_path = grideditor.PathEditor(master),\n            edit_focus_request_headers = grideditor.RequestHeaderEditor(master),\n            edit_focus_response_headers = grideditor.ResponseHeaderEditor(master),\n        )\n        self.stack = [base]\n        self.overlay = None\n\n    def set_overlay(self, o, **kwargs):\n        self.overlay = overlay.SimpleOverlay(\n            self, o, self.top_widget(), o.width, **kwargs,\n        )\n\n    def top_window(self):\n        \"\"\"\n            The current top window, ignoring overlays.\n        \"\"\"\n        return self.windows[self.stack[-1]]\n\n    def top_widget(self):\n        \"\"\"\n            The current top widget - either a window or the active overlay.\n        \"\"\"\n        if self.overlay:\n            return self.overlay\n        return self.top_window()\n\n    def push(self, wname):\n        if self.stack[-1] == wname:\n            return\n        prev = self.top_window()\n        self.stack.append(wname)\n        self.call(\"layout_pushed\", prev)\n\n    def pop(self, *args, **kwargs):\n        \"\"\"\n            Pop off the stack, return True if we're already at the top.\n        \"\"\"\n        if not self.overlay and len(self.stack) == 1:\n            return True\n        self.call(\"layout_popping\")\n        if self.overlay:\n            self.overlay = None\n        else:\n            self.stack.pop()\n\n    def call(self, name, *args, **kwargs):\n        \"\"\"\n            Call a function on both the top window, and the overlay if there is\n            one. If the widget has a key_responder, we call the function on the\n            responder instead.\n        \"\"\"\n        getattr(self.top_window(), name)(*args, **kwargs)\n        if self.overlay:\n            getattr(self.overlay, name)(*args, **kwargs)\n\n\nclass Window(urwid.Frame):\n    def __init__(self, master):\n        self.statusbar = statusbar.StatusBar(master)\n        super().__init__(\n            None,\n            header = None,\n            footer = urwid.AttrWrap(self.statusbar, \"background\")\n        )\n        self.master = master\n        self.master.view.sig_view_refresh.connect(self.view_changed)\n        self.master.view.sig_view_add.connect(self.view_changed)\n        self.master.view.sig_view_remove.connect(self.view_changed)\n        self.master.view.sig_view_update.connect(self.view_changed)\n        self.master.view.focus.sig_change.connect(self.view_changed)\n        self.master.view.focus.sig_change.connect(self.focus_changed)\n\n        signals.focus.connect(self.sig_focus)\n        signals.flow_change.connect(self.flow_changed)\n        signals.pop_view_state.connect(self.pop)\n        signals.push_view_state.connect(self.push)\n\n        self.master.options.subscribe(self.configure, [\"console_layout\"])\n        self.master.options.subscribe(self.configure, [\"console_layout_headers\"])\n        self.pane = 0\n        self.stacks = [\n            WindowStack(master, \"flowlist\"),\n            WindowStack(master, \"eventlog\")\n        ]\n\n    def focus_stack(self):\n        return self.stacks[self.pane]\n\n    def configure(self, otions, updated):\n        self.refresh()\n\n    def refresh(self):\n        \"\"\"\n            Redraw the layout.\n        \"\"\"\n        c = self.master.options.console_layout\n        if c == \"single\":\n            self.pane = 0\n\n        def wrapped(idx):\n            window = self.stacks[idx].top_window()\n            widget = self.stacks[idx].top_widget()\n            if self.master.options.console_layout_headers and window.title:\n                return Header(widget, window.title, self.pane == idx)\n            else:\n                return widget\n\n        w = None\n        if c == \"single\":\n            w = wrapped(0)\n        elif c == \"vertical\":\n            w = urwid.Pile(\n                [\n                    wrapped(i) for i, s in enumerate(self.stacks)\n                ],\n                focus_item=self.pane\n            )\n        else:\n            w = urwid.Columns(\n                [wrapped(i) for i, s in enumerate(self.stacks)],\n                dividechars=1,\n                focus_column=self.pane\n            )\n\n        self.body = urwid.AttrWrap(w, \"background\")\n\n    def flow_changed(self, sender, flow):\n        if self.master.view.focus.flow:\n            if flow.id == self.master.view.focus.flow.id:\n                self.focus_changed()\n\n    def focus_changed(self, *args, **kwargs):\n        \"\"\"\n            Triggered when the focus changes - either when it's modified, or\n            when it changes to a different flow altogether.\n        \"\"\"\n        for i in self.stacks:\n            i.call(\"focus_changed\")\n\n    def view_changed(self, *args, **kwargs):\n        \"\"\"\n            Triggered when the view list has changed.\n        \"\"\"\n        for i in self.stacks:\n            i.call(\"view_changed\")\n\n    def set_overlay(self, o, **kwargs):\n        \"\"\"\n            Set an overlay on the currently focused stack.\n        \"\"\"\n        self.focus_stack().set_overlay(o, **kwargs)\n        self.refresh()\n\n    def push(self, wname):\n        \"\"\"\n            Push a window onto the currently focused stack.\n        \"\"\"\n        self.focus_stack().push(wname)\n        self.refresh()\n        self.view_changed()\n        self.focus_changed()\n\n    def pop(self, *args, **kwargs):\n        \"\"\"\n            Pop a window from the currently focused stack. If there is only one\n            window on the stack, this prompts for exit.\n        \"\"\"\n        if self.focus_stack().pop():\n            self.master.prompt_for_exit()\n        else:\n            self.refresh()\n            self.view_changed()\n            self.focus_changed()\n\n    def current(self, keyctx):\n        \"\"\"\n            Returns the active widget, but only the current focus or overlay has\n            a matching key context.\n        \"\"\"\n        t = self.focus_stack().top_widget()\n        if t.keyctx == keyctx:\n            return t\n\n    def current_window(self, keyctx):\n        \"\"\"\n            Returns the active window, ignoring overlays.\n        \"\"\"\n        t = self.focus_stack().top_window()\n        if t.keyctx == keyctx:\n            return t\n\n    def any(self, keyctx):\n        \"\"\"\n            Returns the top window of either stack if they match the context.\n        \"\"\"\n        for t in [x.top_window() for x in self.stacks]:\n            if t.keyctx == keyctx:\n                return t\n\n    def sig_focus(self, sender, section):\n        self.focus_position = section\n\n    def switch(self):\n        \"\"\"\n            Switch between the two panes.\n        \"\"\"\n        if self.master.options.console_layout == \"single\":\n            self.pane = 0\n        else:\n            self.pane = (self.pane + 1) % len(self.stacks)\n        self.refresh()\n\n    def mouse_event(self, *args, **kwargs):\n        # args: (size, event, button, col, row)\n        k = super().mouse_event(*args, **kwargs)\n        if not k:\n            if args[1] == \"mouse drag\":\n                signals.status_message.send(\n                    message = \"Hold down fn, shift, alt or ctrl to select text or use the --no-mouse parameter.\",\n                    expire = 1\n                )\n            elif args[1] == \"mouse press\" and args[2] == 4:\n                self.keypress(args[0], \"up\")\n            elif args[1] == \"mouse press\" and args[2] == 5:\n                self.keypress(args[0], \"down\")\n            else:\n                return False\n            return True\n\n    def keypress(self, size, k):\n        k = super().keypress(size, k)\n        if k:\n            return self.master.keymap.handle(\n                self.focus_stack().top_widget().keyctx,\n                k\n            )\n\n\nclass Screen(urwid.raw_display.Screen):\n\n    def write(self, data):\n        if common.IS_WSL:\n            # replace urwid's SI/SO, which produce artifacts under WSL.\n            # at some point we may figure out what they actually do.\n            data = re.sub(\"[\\x0e\\x0f]\", \"\", data)\n        super().write(data)\n", "path": "mitmproxy/tools/console/window.py"}]}