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 <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2017-05-13 23:32:28 +02:00 committed by Daniel Hahler
parent f22a69d54e
commit 40e9393d94
1 changed files with 12 additions and 2 deletions

View File

@ -13,6 +13,10 @@ local client = client
local aclient = require("awful.client") local aclient = require("awful.client")
local timer = require("gears.timer") 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. --- Give focus when clients appear/disappear.
-- --
-- @param obj An object that should have a .screen property. -- @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 if not obj.screen.valid then return end
-- When no visible client has the focus... -- When no visible client has the focus...
if not client.focus or not client.focus:isvisible() then 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 if c then
c:emit_signal("request::activate", "autofocus.check_focus", c:emit_signal("request::activate", "autofocus.check_focus",
{raise=false}) {raise=false})
@ -43,7 +50,10 @@ local function check_focus_tag(t)
s = screen[s] s = screen[s]
check_focus({ screen = s }) check_focus({ screen = s })
if client.focus and screen[client.focus.screen] ~= s then 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 if c then
c:emit_signal("request::activate", "autofocus.check_focus_tag", c:emit_signal("request::activate", "autofocus.check_focus_tag",
{raise=false}) {raise=false})