From bfd9960df254c5bc29d1f7fd42298ec857c8484f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Mon, 12 Oct 2015 12:56:19 +0200 Subject: [PATCH] Suppress no_focus for first window on a workspace. With this patch, the no_focus directive will be ignored if the to-be-opened window is the first on its workspace as there's no reason the user would not want to focus it in this case. This improves usability when, for example, using a tabbed workspace_layout. fixes #1987 --- docs/userguide | 4 ++++ src/manage.c | 18 ++++++++++++++---- testcases/t/242-no-focus.t | 30 ++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/docs/userguide b/docs/userguide index b077eb66..41af30a1 100644 --- a/docs/userguide +++ b/docs/userguide @@ -610,6 +610,10 @@ Note that this does not apply to all cases, e.g., when feeding data into a runni causing it to request being focused. To configure the behavior in such cases, refer to <>. ++no_focus+ will also be ignored for the first window on a workspace as there shouldn't be +a reason to not focus the window in this case. This allows for better usability in +combination with +workspace_layout+. + *Syntax*: ------------------- no_focus diff --git a/src/manage.c b/src/manage.c index e3769670..5cfe490e 100644 --- a/src/manage.c +++ b/src/manage.c @@ -524,13 +524,23 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki /* Send an event about window creation */ ipc_send_window_event("new", nc); + if (set_focus && assignment_for(cwindow, A_NO_FOCUS) != NULL) { + /* The first window on a workspace should always be focused. We have to + * compare with == 1 because the container has already been inserted at + * this point. */ + if (con_num_children(ws) == 1) { + DLOG("This is the first window on this workspace, ignoring no_focus.\n"); + } else { + DLOG("no_focus was set for con = %p, not setting focus.\n", nc); + set_focus = false; + } + } + /* Defer setting focus after the 'new' event has been sent to ensure the * proper window event sequence. */ if (set_focus && !nc->window->doesnt_accept_focus && nc->mapped) { - if (assignment_for(cwindow, A_NO_FOCUS) == NULL) { - DLOG("Now setting focus.\n"); - con_focus(nc); - } + DLOG("Now setting focus.\n"); + con_focus(nc); } tree_render(); diff --git a/testcases/t/242-no-focus.t b/testcases/t/242-no-focus.t index 143ae5cf..0a7f5c93 100644 --- a/testcases/t/242-no-focus.t +++ b/testcases/t/242-no-focus.t @@ -30,13 +30,15 @@ font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 EOT $pid = launch_with_config($config); - + $ws = fresh_workspace; $first = open_window; $focused = get_focused($ws); $second = open_window; +sync_with_i3; isnt(get_focused($ws), $focused, 'focus has changed'); +is($x->input_focus, $second->id, 'input focus has changed'); exit_gracefully($pid); @@ -53,13 +55,37 @@ no_focus [instance=notme] EOT $pid = launch_with_config($config); - + $ws = fresh_workspace; $first = open_window; $focused = get_focused($ws); $second = open_window(wm_class => 'notme'); +sync_with_i3; is(get_focused($ws), $focused, 'focus has not changed'); +is($x->input_focus, $first->id, 'input focus has not changed'); + +exit_gracefully($pid); + +##################################################################### +## 3: no_focus doesn't affect the first window opened on a workspace +##################################################################### + +$config = < 'focusme'); + +sync_with_i3; +is($x->input_focus, $first->id, 'input focus has changed'); exit_gracefully($pid);