From 40e9393d942aef4107e4c4ac5e34e06c51cae81a Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 13 May 2017 23:32:28 +0200 Subject: [PATCH] awful.autofocus: Discriminate sticky clients (#1697) A relatively common problem with awesome is with mixing sticky clients and the focus history. Once a sticky client ever had the focus, it will always get the focus after a tag switch. This is because the focus history is global and the sticky client is always the most recently focused and currently visible client in the list. Work around this by discriminating sticky clients: First try to find a client to focus, but ignore sticky clients. When this does not find anything, try again, but this time also consider sticky clients. (Basically the same issue exists with clients that are on multiple tags, but I guess that one can be ignored.) Fixes: https://github.com/awesomeWM/awesome/issues/733 Signed-off-by: Uli Schlachter --- lib/awful/autofocus.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/awful/autofocus.lua b/lib/awful/autofocus.lua index 5fcd22094..8087f3dae 100644 --- a/lib/awful/autofocus.lua +++ b/lib/awful/autofocus.lua @@ -13,6 +13,10 @@ local client = client local aclient = require("awful.client") local timer = require("gears.timer") +local function filter_sticky(c) + return not c.sticky and aclient.focus.filter(c) +end + --- Give focus when clients appear/disappear. -- -- @param obj An object that should have a .screen property. @@ -20,7 +24,10 @@ local function check_focus(obj) if not obj.screen.valid then return end -- When no visible client has the focus... if not client.focus or not client.focus:isvisible() then - local c = aclient.focus.history.get(screen[obj.screen], 0, aclient.focus.filter) + local c = aclient.focus.history.get(screen[obj.screen], 0, filter_sticky) + if not c then + c = aclient.focus.history.get(screen[obj.screen], 0, aclient.focus.filter) + end if c then c:emit_signal("request::activate", "autofocus.check_focus", {raise=false}) @@ -43,7 +50,10 @@ local function check_focus_tag(t) s = screen[s] check_focus({ screen = s }) if client.focus and screen[client.focus.screen] ~= s then - local c = aclient.focus.history.get(s, 0, aclient.focus.filter) + local c = aclient.focus.history.get(s, 0, filter_sticky) + if not c then + c = aclient.focus.history.get(s, 0, aclient.focus.filter) + end if c then c:emit_signal("request::activate", "autofocus.check_focus_tag", {raise=false})