From 172f3563f753353f13e9d6cec88f4c28f66987eb Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 17 Sep 2011 19:28:41 +0100 Subject: [PATCH 1/3] Implement focus switching (focus left/right) for floating windows Fixes: #475 --- src/tree.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/tree.c b/src/tree.c index 240c22a6..3f0705fc 100644 --- a/src/tree.c +++ b/src/tree.c @@ -421,13 +421,36 @@ static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap) return true; } - if (con->type == CT_FLOATING_CON) { - /* TODO: implement focus for floating windows */ - return false; - } - Con *parent = con->parent; + if (con->type == CT_FLOATING_CON) { + /* left/right focuses the previous/next floating container */ + if (orientation == HORIZ) { + Con *next; + if (way == 'n') + next = TAILQ_NEXT(con, floating_windows); + else next = TAILQ_PREV(con, floating_head, floating_windows); + + /* If there is no next/previous container, wrap */ + if (!next) { + if (way == 'n') + next = TAILQ_FIRST(&(parent->floating_head)); + else next = TAILQ_LAST(&(parent->floating_head), floating_head); + } + + /* Still no next/previous container? bail out */ + if (!next) + return false; + + con_focus(con_descend_focused(next)); + return true; + } else { + /* up/down cycles through the Z-index */ + /* TODO: implement cycling through the z-index */ + return false; + } + } + /* If the orientation does not match or there is no other con to focus, we * need to go higher in the hierarchy */ if (con_orientation(parent) != orientation || From e6a854a742a999d6a9ee6f43914b9bd0d09141e8 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 17 Sep 2011 19:29:06 +0100 Subject: [PATCH 2/3] Remove obsolete code for floating focus --- src/floating.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/floating.c b/src/floating.c index 2fbf66bc..e225b8a6 100644 --- a/src/floating.c +++ b/src/floating.c @@ -520,31 +520,6 @@ void drag_pointer(Con *con, xcb_button_press_event_t *event, xcb_window_t } #if 0 -/* - * Changes focus in the given direction for floating clients. - * - * Changing to the left/right means going to the previous/next floating client, - * changing to top/bottom means cycling through the Z-index. - * - */ -void floating_focus_direction(xcb_connection_t *conn, Client *currently_focused, direction_t direction) { - DLOG("floating focus\n"); - - if (direction == D_LEFT || direction == D_RIGHT) { - /* Go to the next/previous floating client */ - Client *client; - - while ((client = (direction == D_LEFT ? TAILQ_PREV(currently_focused, floating_clients_head, floating_clients) : - TAILQ_NEXT(currently_focused, floating_clients))) != - TAILQ_END(&(currently_focused->workspace->floating_clients))) { - if (!client->floating) - continue; - set_focus(conn, client, true); - return; - } - } -} - /* * Moves the client 10px to the specified direction. * From c8c95030ad13900900a18c2326908132d134b055 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 17 Sep 2011 19:29:23 +0100 Subject: [PATCH 3/3] tests: extend t/35-floating-focus to use focus left/right on floating windows --- testcases/t/35-floating-focus.t | 41 +++++++++++++++++++++++++++++++++ testcases/t/lib/i3test.pm | 13 ++++++++--- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/testcases/t/35-floating-focus.t b/testcases/t/35-floating-focus.t index 3f820ea5..6adad246 100644 --- a/testcases/t/35-floating-focus.t +++ b/testcases/t/35-floating-focus.t @@ -170,5 +170,46 @@ sleep 0.25; is($x->input_focus, $second->id, 'second (floating) container focused'); +############################################################################# +# 6: see if switching floating focus using the focus left/right command works +############################################################################# + +$tmp = fresh_workspace; + +$first = open_standard_window($x, '#ff0000', 1); # window 10 +$second = open_standard_window($x, '#00ff00', 1); # window 11 +$third = open_standard_window($x, '#0000ff', 1); # window 12 + +is($x->input_focus, $third->id, 'third container focused'); + +cmd 'focus left'; + +sleep 0.25; + +is($x->input_focus, $second->id, 'second container focused'); + +cmd 'focus left'; + +sleep 0.25; + +is($x->input_focus, $first->id, 'first container focused'); + +cmd 'focus left'; + +sleep 0.25; + +is($x->input_focus, $third->id, 'focus wrapped to third container'); + +cmd 'focus right'; + +sleep 0.25; + +is($x->input_focus, $first->id, 'focus wrapped to first container'); + +cmd 'focus right'; + +sleep 0.25; + +is($x->input_focus, $second->id, 'focus on second container'); done_testing; diff --git a/testcases/t/lib/i3test.pm b/testcases/t/lib/i3test.pm index 054bb2ae..749b89b7 100644 --- a/testcases/t/lib/i3test.pm +++ b/testcases/t/lib/i3test.pm @@ -48,16 +48,23 @@ use warnings; } sub open_standard_window { - my ($x, $color) = @_; + my ($x, $color, $floating) = @_; $color ||= '#c0c0c0'; - my $window = $x->root->create_child( + # We cannot use a hashref here because create_child expands the arguments into an array + my @args = ( class => WINDOW_CLASS_INPUT_OUTPUT, - rect => [ 0, 0, 30, 30 ], + rect => X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30 ), background_color => $color, ); + if (defined($floating) && $floating) { + @args = (@args, window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY')); + } + + my $window = $x->root->create_child(@args); + $window->name('Window ' . counter_window()); $window->map;