Repository: mitmproxy/mitmproxy

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! :) -->



Discussion:
Good catch. Thanks! 😃
Are you comfortable taking a stab at this and attempt a PR? ☺️ 
Yeah, sure! I'll make a PR as soon as I make any progress.
Thanks! Please feel free to hop on our Slack chat if you have any questions. :-)
@mhils Is this still open ? I would like to give it a try.
@akash612 Yeah, I am a bit busy at the moment. Feel free to take this.
Is this issue open? I would like to give it a try.

This might be an urwid issue - if I resize my terminal to an odd number of rows, the issue disappears. More concretely, urwid's focus_pos may be confused here.
Persisting from Slack:

**mhils [22:29]** https://github.com/mitmproxy/mitmproxy/blame/master/mitmproxy/tools/console/window.py#L276-L279 <- this makes sure that keypresses are relayed to the currently active window, right?

**cortesi [22:30]** 
yep


**mhils [22:30]** 
I'm looking into https://github.com/mitmproxy/mitmproxy/issues/2620 at the moment.
in a nutshell, the problem is that we just pass down `size` in the code I just linked.
this breaks some internal urwid calculations as the size of the flowlist is smaller than the size of the window.
so we kind of have to mimic this: https://github.com/urwid/urwid/blob/master/urwid/container.py#L1119-L1124

**cortesi [22:34]** 
@mhils yes, i’ve come across this type of issue with urwid before, and unfortunately the solution is never nice:
https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/tools/console/options.py#L273-L280
Good catch. Thanks! 😃
Are you comfortable taking a stab at this and attempt a PR? ☺️ 
Yeah, sure! I'll make a PR as soon as I make any progress.
Thanks! Please feel free to hop on our Slack chat if you have any questions. :-)
@mhils Is this still open ? I would like to give it a try.
@akash612 Yeah, I am a bit busy at the moment. Feel free to take this.
Is this issue open? I would like to give it a try.

This might be an urwid issue - if I resize my terminal to an odd number of rows, the issue disappears. More concretely, urwid's focus_pos may be confused here.
Persisting from Slack:

**mhils [22:29]** https://github.com/mitmproxy/mitmproxy/blame/master/mitmproxy/tools/console/window.py#L276-L279 <- this makes sure that keypresses are relayed to the currently active window, right?

**cortesi [22:30]** 
yep


**mhils [22:30]** 
I'm looking into https://github.com/mitmproxy/mitmproxy/issues/2620 at the moment.
in a nutshell, the problem is that we just pass down `size` in the code I just linked.
this breaks some internal urwid calculations as the size of the flowlist is smaller than the size of the window.
so we kind of have to mimic this: https://github.com/urwid/urwid/blob/master/urwid/container.py#L1119-L1124

**cortesi [22:34]** 
@mhils yes, i’ve come across this type of issue with urwid before, and unfortunately the solution is never nice:
https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/tools/console/options.py#L273-L280

Resolving patch:
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 @@ def wrapped(idx):
             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 @@ def mouse_event(self, *args, **kwargs):
             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):


Test patch: