From fbce834b20052952d48fea1299343797beab5ae1 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Sun, 1 Apr 2018 02:02:50 +0300 Subject: [PATCH] Window decoration scrolling: don't focus sibling The current behaviour is buggy in the following layout: T [ A* V [ B C ] ], where the focus stack in V is B > C. When the user scrolls down, focus correctly moves to B but if the user scrolls down again the whole vertical container is focused. This happens because 'bool scroll_next_possible' is false but con_activate is called on the tabbed container's sibling - the vertical container. --- src/click.c | 8 +--- testcases/t/297-scroll-tabbed.t | 79 +++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 testcases/t/297-scroll-tabbed.t diff --git a/src/click.c b/src/click.c index b036c5f8..f4727f28 100644 --- a/src/click.c +++ b/src/click.c @@ -234,14 +234,10 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod event->detail == XCB_BUTTON_SCROLL_RIGHT)) { DLOG("Scrolling on a window decoration\n"); orientation_t orientation = (con->parent->layout == L_STACKED ? VERT : HORIZ); - /* Focus the currently focused container on the same level that the - * user scrolled on. e.g. the tabbed decoration contains - * "urxvt | i3: V[xterm geeqie] | firefox", - * focus is on the xterm, but the user scrolled on urxvt. - * The splitv container will be focused. */ + /* Use the focused child of the tabbed / stacked container, not the + * container the user scrolled on. */ Con *focused = con->parent; focused = TAILQ_FIRST(&(focused->focus_head)); - con_activate(focused); /* To prevent scrolling from going outside the container (see ticket * #557), we first check if scrolling is possible at all. */ bool scroll_prev_possible = (TAILQ_PREV(focused, nodes_head, nodes) != NULL); diff --git a/testcases/t/297-scroll-tabbed.t b/testcases/t/297-scroll-tabbed.t new file mode 100644 index 00000000..6deeaf65 --- /dev/null +++ b/testcases/t/297-scroll-tabbed.t @@ -0,0 +1,79 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • https://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • https://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • https://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Tests if scrolling the tab bar on a tabbed container works and verifies that +# only one window is focused as a result. +# Ticket: #3215 (PR) +# Bug still in: 4.15-92-g666aa9e0 +use i3test; +use i3test::XTEST; + +sub scroll_down { + # button5 = scroll down + xtest_button_press(5, 3, 3); + xtest_button_release(5, 3, 3); + xtest_sync_with_i3; +} + +sub scroll_up { + # button4 = scroll up + xtest_button_press(4, 3, 3); + xtest_button_release(4, 3, 3); + xtest_sync_with_i3; +} + +# Decoration of top left window. +$x->root->warp_pointer(3, 3); + +# H [ T [ H [ A B ] C D V [ E F ] ] G ] +# Inner horizontal split. +open_window; +cmd 'layout tabbed'; +cmd 'splith'; +my $first = open_window; +cmd 'focus parent'; +# Simple tabs. +open_window; +my $second_last = open_window; +# V-Split container +open_window; +cmd 'splitv'; +my $last = open_window; +# Second child of the outer horizontal split, next to the tabbed one. +open_window; +cmd 'move right, move right'; + +cmd '[id=' . $first->id . '] focus'; + +# Scroll from first to last. +scroll_down; +scroll_down; +is($x->input_focus, $second_last->id, 'Sanity check: scrolling'); +scroll_down; +is($x->input_focus, $last->id, 'Last window focused through scrolling'); +scroll_down; +is($x->input_focus, $last->id, 'Scrolling again doesn\'t leave the tabbed container and doesn\'t focus the whole sibling'); + +# Scroll from last to first. +scroll_up; +is($x->input_focus, $second_last->id, 'Scrolling up works'); +scroll_up; +scroll_up; +is($x->input_focus, $first->id, 'First window focused through scrolling'); +scroll_up; +is($x->input_focus, $first->id, 'Scrolling again doesn\'t focus the whole sibling'); + +done_testing; -- 2.39.5