From f172359ba5b1f00e51700731f6ba4c6e640e68cc Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 17 Aug 2011 16:36:19 +0200 Subject: [PATCH] =?UTF-8?q?Bugfix:=20Don=E2=80=99t=20change=20focus=20when?= =?UTF-8?q?=20assigned=20windows=20start=20on=20invisible=20workspaces=20(?= =?UTF-8?q?+test)=20(Thanks=20ioflag)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #468 --- src/manage.c | 10 ++-- testcases/t/73-regress-focus-assign.t | 73 +++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 testcases/t/73-regress-focus-assign.t diff --git a/src/manage.c b/src/manage.c index 18f38228..8f31654e 100644 --- a/src/manage.c +++ b/src/manage.c @@ -264,9 +264,13 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki if (fs == NULL) { DLOG("Not in fullscreen mode, focusing\n"); - if (!cwindow->dock) - con_focus(nc); - else DLOG("dock, not focusing\n"); + if (!cwindow->dock) { + /* Check that the workspace is visible. If the window was assigned + * to an invisible workspace, we should not steal focus. */ + if (workspace_is_visible(ws)) { + con_focus(nc); + } else DLOG("workspace not visible, not focusing\n"); + } else DLOG("dock, not focusing\n"); } else { DLOG("fs = %p, ws = %p, not focusing\n", fs, ws); /* Insert the new container in focus stack *after* the currently diff --git a/testcases/t/73-regress-focus-assign.t b/testcases/t/73-regress-focus-assign.t new file mode 100644 index 00000000..7ad87103 --- /dev/null +++ b/testcases/t/73-regress-focus-assign.t @@ -0,0 +1,73 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# !NO_I3_INSTANCE! will prevent complete-run.pl from starting i3 +# +# Regression: Checks if focus is stolen when a window is managed which is +# assigned to an invisible workspace +# +use i3test; +use X11::XCB qw(:all); +use X11::XCB::Connection; +use v5.10; + +my $x = X11::XCB::Connection->new; + +# TODO: move to X11::XCB +sub set_wm_class { + my ($id, $class, $instance) = @_; + + # Add a _NET_WM_STRUT_PARTIAL hint + my $atomname = $x->atom(name => 'WM_CLASS'); + my $atomtype = $x->atom(name => 'STRING'); + + $x->change_property( + PROP_MODE_REPLACE, + $id, + $atomname->id, + $atomtype->id, + 8, + length($class) + length($instance) + 2, + "$instance\x00$class\x00" + ); +} + + +##################################################################### +# start a window and see that it does not get assigned with an empty config +##################################################################### + +my $config = <{focused}, 'current workspace focused'); + +my $window = $x->root->create_child( + class => WINDOW_CLASS_INPUT_OUTPUT, + rect => [ 0, 0, 30, 30 ], + background_color => '#0000ff', +); + +$window->_create; +set_wm_class($window->id, 'special', 'special'); +$window->name('special window'); +$window->map; +sleep 0.25; + + +ok(@{get_ws_content($tmp)} == 0, 'special window not on current workspace'); +ok(@{get_ws_content('targetws')} == 1, 'special window on targetws'); +ok(get_ws($tmp)->{focused}, 'current workspace still focused'); + +exit_gracefully($process->pid); + +$window->destroy; + +done_testing;