diff --git a/lib/awful/ewmh.lua b/lib/awful/ewmh.lua index d110cd314..c1f2d0580 100644 --- a/lib/awful/ewmh.lua +++ b/lib/awful/ewmh.lua @@ -122,20 +122,41 @@ function ewmh.activate(c, context, hints) -- luacheck: no unused args end end +-- Get tags that are on the same screen as the client. This should _almost_ +-- always return the same content as c:tags(). +local function get_valid_tags(c, s) + local tags, new_tags = c:tags(), {} + + for _, t in ipairs(tags) do + if screen[s] == t.screen then + table.insert(new_tags, t) + end + end + + return new_tags +end + --- Tag a window with its requested tag. -- -- It is the default signal handler for `request::tag` on a `client`. -- -- @signalhandler awful.ewmh.tag -- @client c A client to tag --- @tag[opt] t A tag to use. If omitted, then the client is made sticky. +-- @tparam[opt] tag|boolean t A tag to use. If true, then the client is made sticky. -- @tparam[opt={}] table hints Extra information function ewmh.tag(c, t, hints) --luacheck: no unused -- There is nothing to do - if not t and #c:tags() > 0 then return end + if not t and #get_valid_tags(c, c.screen) > 0 then return end if not t then - c:to_selected_tags() + if c.transient_for then + c.screen = c.transient_for.screen + if not c.sticky then + c:tags(c.transient_for:tags()) + end + else + c:to_selected_tags() + end elseif type(t) == "boolean" and t then c.sticky = true else diff --git a/lib/awful/tag.lua b/lib/awful/tag.lua index 560e6bab3..a0dd00a3e 100644 --- a/lib/awful/tag.lua +++ b/lib/awful/tag.lua @@ -12,6 +12,7 @@ local util = require("awful.util") local ascreen = require("awful.screen") local beautiful = require("beautiful") local object = require("gears.object") +local timer = require("gears.timer") local pairs = pairs local ipairs = ipairs local table = table @@ -1277,21 +1278,25 @@ function tag.attached_connect_signal(screen, ...) end -- Register standard signals. -capi.client.connect_signal("manage", function(c) - -- If we are not managing this application at startup, - -- move it to the screen where the mouse is. - -- We only do it for "normal" windows (i.e. no dock, etc). - if not awesome.startup and c.type ~= "desktop" and c.type ~= "dock" then - if c.transient_for then - c.screen = c.transient_for.screen - if not c.sticky then - c:tags(c.transient_for:tags()) +capi.client.connect_signal("property::screen", function(c) + -- First, the delayed timer is necessary to avoid a race condition with + -- awful.rules. It is also messing up the tags before the user have a chance + -- to set them manually. + timer.delayed_call(function() + local tags, new_tags = c:tags(), {} + + for _, t in ipairs(tags) do + if t.screen == c.screen then + table.insert(new_tags, t) end - else - c.screen = ascreen.focused() end - end - c:connect_signal("property::screen", function() c:to_selected_tags() end) + + if #new_tags == 0 then + c:emit_signal("request::tag", nil, {reason="screen"}) + elseif #new_tags < #tags then + c:tags(new_tags) + end + end) end) -- Keep track of the number of urgent clients.