Merge branch 'fake-screen2' of https://github.com/psychon/awesome
This commit is contained in:
commit
c62da0dcc7
|
@ -18,6 +18,7 @@ local timer = require("gears.timer")
|
||||||
--
|
--
|
||||||
-- @param obj An object that should have a .screen property.
|
-- @param obj An object that should have a .screen property.
|
||||||
local function check_focus(obj)
|
local function check_focus(obj)
|
||||||
|
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, aclient.focus.filter)
|
||||||
|
@ -39,7 +40,7 @@ end
|
||||||
-- @param tag A tag object
|
-- @param tag A tag object
|
||||||
local function check_focus_tag(t)
|
local function check_focus_tag(t)
|
||||||
local s = t.screen
|
local s = t.screen
|
||||||
if not s then return end
|
if (not s) or (not s.valid) then return end
|
||||||
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
|
||||||
|
|
|
@ -250,12 +250,14 @@ end
|
||||||
-- @see awful.tag.find_fallback
|
-- @see awful.tag.find_fallback
|
||||||
-- @tparam[opt=awful.tag.find_fallback()] tag fallback_tag Tag to assign
|
-- @tparam[opt=awful.tag.find_fallback()] tag fallback_tag Tag to assign
|
||||||
-- stickied tags to.
|
-- stickied tags to.
|
||||||
|
-- @tparam[opt=false] boolean force Move even non-sticky clients to the fallback
|
||||||
|
-- tag.
|
||||||
-- @return Returns true if the tag is successfully deleted, nil otherwise.
|
-- @return Returns true if the tag is successfully deleted, nil otherwise.
|
||||||
-- If there are no clients exclusively on this tag then delete it. Any
|
-- If there are no clients exclusively on this tag then delete it. Any
|
||||||
-- stickied clients are assigned to the optional 'fallback_tag'.
|
-- stickied clients are assigned to the optional 'fallback_tag'.
|
||||||
-- If after deleting the tag there is no selected tag, try and restore from
|
-- If after deleting the tag there is no selected tag, try and restore from
|
||||||
-- history or select the first tag on the screen.
|
-- history or select the first tag on the screen.
|
||||||
function tag.object.delete(self, fallback_tag)
|
function tag.object.delete(self, fallback_tag, force)
|
||||||
|
|
||||||
-- abort if the taf isn't currently activated
|
-- abort if the taf isn't currently activated
|
||||||
if not self.activated then return end
|
if not self.activated then return end
|
||||||
|
@ -283,8 +285,7 @@ function tag.object.delete(self, fallback_tag)
|
||||||
|
|
||||||
-- If a client has only this tag, or stickied clients with
|
-- If a client has only this tag, or stickied clients with
|
||||||
-- nowhere to go, abort.
|
-- nowhere to go, abort.
|
||||||
if (not c.sticky and nb_tags == 1) or
|
if (not c.sticky and nb_tags == 1 and not force) then
|
||||||
(c.sticky and fallback_tag == nil) then
|
|
||||||
return
|
return
|
||||||
-- If a client has multiple tags, then do not move it to fallback
|
-- If a client has multiple tags, then do not move it to fallback
|
||||||
elseif nb_tags < 2 then
|
elseif nb_tags < 2 then
|
||||||
|
@ -294,6 +295,7 @@ function tag.object.delete(self, fallback_tag)
|
||||||
|
|
||||||
-- delete the tag
|
-- delete the tag
|
||||||
data.tags[self].screen = nil
|
data.tags[self].screen = nil
|
||||||
|
data.tags[self] = nil
|
||||||
self.activated = false
|
self.activated = false
|
||||||
|
|
||||||
-- Update all indexes
|
-- Update all indexes
|
||||||
|
@ -1350,11 +1352,45 @@ capi.tag.add_signal("property::urgent")
|
||||||
|
|
||||||
capi.tag.add_signal("property::urgent_count")
|
capi.tag.add_signal("property::urgent_count")
|
||||||
capi.tag.add_signal("property::volatile")
|
capi.tag.add_signal("property::volatile")
|
||||||
|
capi.tag.add_signal("request::screen")
|
||||||
|
capi.tag.add_signal("removal-pending")
|
||||||
|
|
||||||
capi.screen.add_signal("tag::history::update")
|
capi.screen.add_signal("tag::history::update")
|
||||||
|
|
||||||
capi.screen.connect_signal("tag::history::update", tag.history.update)
|
capi.screen.connect_signal("tag::history::update", tag.history.update)
|
||||||
|
|
||||||
|
capi.screen.connect_signal("removed", function(s)
|
||||||
|
-- First give other code a chance to move the tag to another screen
|
||||||
|
for _, t in pairs(s.tags) do
|
||||||
|
t:emit_signal("request::screen")
|
||||||
|
end
|
||||||
|
-- Everything that's left: Tell everyone that these tags go away (other code
|
||||||
|
-- could e.g. save clients)
|
||||||
|
for _, t in pairs(s.tags) do
|
||||||
|
t:emit_signal("removal-pending")
|
||||||
|
end
|
||||||
|
-- Give other code yet another change to save clients
|
||||||
|
for _, c in pairs(capi.client.get(s)) do
|
||||||
|
c:emit_signal("request::tag", nil, { reason = "screen-removed" })
|
||||||
|
end
|
||||||
|
-- Then force all clients left to go somewhere random
|
||||||
|
local fallback = nil
|
||||||
|
for other_screen in capi.screen do
|
||||||
|
if #other_screen.tags > 0 then
|
||||||
|
fallback = other_screen.tags[1]
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, t in pairs(s.tags) do
|
||||||
|
t:delete(fallback, true)
|
||||||
|
end
|
||||||
|
-- If any tag survived until now, forcefully get rid of it
|
||||||
|
for _, t in pairs(s.tags) do
|
||||||
|
t.activated = false
|
||||||
|
data.tags[t] = nil
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
function tag.mt:__call(...)
|
function tag.mt:__call(...)
|
||||||
return tag.new(...)
|
return tag.new(...)
|
||||||
end
|
end
|
||||||
|
|
|
@ -168,7 +168,9 @@ function taglist.new(screen, filter, buttons, style, update_function, base_widge
|
||||||
-- Add a delayed callback for the first update.
|
-- Add a delayed callback for the first update.
|
||||||
if not queued_update[screen] then
|
if not queued_update[screen] then
|
||||||
timer.delayed_call(function()
|
timer.delayed_call(function()
|
||||||
taglist_update(screen, w, buttons, filter, data, style, uf)
|
if screen.valid then
|
||||||
|
taglist_update(screen, w, buttons, filter, data, style, uf)
|
||||||
|
end
|
||||||
queued_update[screen] = false
|
queued_update[screen] = false
|
||||||
end)
|
end)
|
||||||
queued_update[screen] = true
|
queued_update[screen] = true
|
||||||
|
@ -203,6 +205,9 @@ function taglist.new(screen, filter, buttons, style, update_function, base_widge
|
||||||
capi.client.connect_signal("tagged", uc)
|
capi.client.connect_signal("tagged", uc)
|
||||||
capi.client.connect_signal("untagged", uc)
|
capi.client.connect_signal("untagged", uc)
|
||||||
capi.client.connect_signal("unmanage", uc)
|
capi.client.connect_signal("unmanage", uc)
|
||||||
|
capi.screen.connect_signal("removed", function(s)
|
||||||
|
instances[get_screen(s)] = nil
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
w._do_taglist_update()
|
w._do_taglist_update()
|
||||||
local list = instances[screen]
|
local list = instances[screen]
|
||||||
|
|
|
@ -181,7 +181,9 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg
|
||||||
if not queued_update then
|
if not queued_update then
|
||||||
timer.delayed_call(function()
|
timer.delayed_call(function()
|
||||||
queued_update = false
|
queued_update = false
|
||||||
tasklist_update(screen, w, buttons, filter, data, style, uf)
|
if screen.valid then
|
||||||
|
tasklist_update(screen, w, buttons, filter, data, style, uf)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
queued_update = true
|
queued_update = true
|
||||||
end
|
end
|
||||||
|
@ -201,7 +203,9 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg
|
||||||
end
|
end
|
||||||
local function u()
|
local function u()
|
||||||
for s in pairs(instances) do
|
for s in pairs(instances) do
|
||||||
us(s)
|
if s.valid then
|
||||||
|
us(s)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -238,6 +242,9 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg
|
||||||
capi.client.connect_signal("list", u)
|
capi.client.connect_signal("list", u)
|
||||||
capi.client.connect_signal("focus", u)
|
capi.client.connect_signal("focus", u)
|
||||||
capi.client.connect_signal("unfocus", u)
|
capi.client.connect_signal("unfocus", u)
|
||||||
|
capi.screen.connect_signal("removed", function(s)
|
||||||
|
instances[get_screen(s)] = nil
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
w._do_tasklist_update()
|
w._do_tasklist_update()
|
||||||
local list = instances[screen]
|
local list = instances[screen]
|
||||||
|
|
|
@ -154,6 +154,16 @@ screen.connect_for_each_screen(function(s)
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
capi.screen.connect_signal("removed", function(scr)
|
||||||
|
-- Destroy all notifications on this screen
|
||||||
|
for _, list in pairs(naughty.notifications[scr]) do
|
||||||
|
while #list > 0 do
|
||||||
|
naughty.destroy(list[1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
naughty.notifications[scr] = nil
|
||||||
|
end)
|
||||||
|
|
||||||
--- Notification state
|
--- Notification state
|
||||||
function naughty.is_suspended()
|
function naughty.is_suspended()
|
||||||
return suspended
|
return suspended
|
||||||
|
|
|
@ -1020,6 +1020,57 @@ luaA_screen_count(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Add a fake screen.
|
||||||
|
* @tparam integer x X-coordinate for screen.
|
||||||
|
* @tparam integer y Y-coordinate for screen.
|
||||||
|
* @tparam integer width width for screen.
|
||||||
|
* @tparam integer height height for screen.
|
||||||
|
* @return The new screen.
|
||||||
|
* @function fake_add
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
luaA_screen_fake_add(lua_State *L)
|
||||||
|
{
|
||||||
|
int x = luaL_checkinteger(L, 1);
|
||||||
|
int y = luaL_checkinteger(L, 2);
|
||||||
|
int width = luaL_checkinteger(L, 3);
|
||||||
|
int height = luaL_checkinteger(L, 4);
|
||||||
|
screen_t *s;
|
||||||
|
|
||||||
|
s = screen_add(L, &globalconf.screens);
|
||||||
|
s->geometry.x = x;
|
||||||
|
s->geometry.y = y;
|
||||||
|
s->geometry.width = width;
|
||||||
|
s->geometry.height = height;
|
||||||
|
s->valid = true;
|
||||||
|
luaA_object_push(L, s);
|
||||||
|
luaA_object_emit_signal(L, -1, "added", 0);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove a screen.
|
||||||
|
* @function fake_remove.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
luaA_screen_fake_remove(lua_State *L)
|
||||||
|
{
|
||||||
|
screen_t *s = luaA_checkudata(L, 1, &screen_class);
|
||||||
|
int idx = screen_get_index(s) - 1;
|
||||||
|
if (idx < 0)
|
||||||
|
/* WTF? */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
screen_array_take(&globalconf.screens, idx);
|
||||||
|
luaA_object_push(L, s);
|
||||||
|
screen_removed(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
luaA_object_unref(L, s);
|
||||||
|
s->valid = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_class_setup(lua_State *L)
|
screen_class_setup(lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -1030,6 +1081,7 @@ screen_class_setup(lua_State *L)
|
||||||
{ "__index", luaA_screen_module_index },
|
{ "__index", luaA_screen_module_index },
|
||||||
{ "__newindex", luaA_default_newindex },
|
{ "__newindex", luaA_default_newindex },
|
||||||
{ "__call", luaA_screen_module_call },
|
{ "__call", luaA_screen_module_call },
|
||||||
|
{ "fake_add", luaA_screen_fake_add },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1037,6 +1089,7 @@ screen_class_setup(lua_State *L)
|
||||||
{
|
{
|
||||||
LUA_OBJECT_META(screen)
|
LUA_OBJECT_META(screen)
|
||||||
LUA_CLASS_META
|
LUA_CLASS_META
|
||||||
|
{ "fake_remove", luaA_screen_fake_remove },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,29 +4,26 @@ local spawn = require("awful.spawn")
|
||||||
-- It is used to test the `awful.rules`
|
-- It is used to test the `awful.rules`
|
||||||
|
|
||||||
return function(class, title, use_sn)
|
return function(class, title, use_sn)
|
||||||
|
class = class or 'test_app'
|
||||||
title = title or 'Awesome test client'
|
title = title or 'Awesome test client'
|
||||||
|
|
||||||
local cmd = {"lua" , "-e", table.concat {
|
local cmd = {"lua" , "-e", table.concat {
|
||||||
"local lgi = require 'lgi';",
|
"local lgi = require 'lgi';",
|
||||||
"local Gtk = lgi.require('Gtk');",
|
"local Gtk = lgi.require('Gtk');",
|
||||||
"Gtk.init();",
|
"Gtk.init();",
|
||||||
"local class = '",
|
"local class = '",class,"';",
|
||||||
class or 'test_app',"';",
|
|
||||||
"local window = Gtk.Window {",
|
"local window = Gtk.Window {",
|
||||||
" default_width = 100,",
|
" default_width = 100,",
|
||||||
" default_height = 100,",
|
" default_height = 100,",
|
||||||
|
" on_destroy = Gtk.main_quit,",
|
||||||
" title = '",title,
|
" title = '",title,
|
||||||
"'};",
|
"'};",
|
||||||
"window:set_wmclass(class, class);",
|
"window:set_wmclass(class, class);",
|
||||||
"local app = Gtk.Application {",
|
"window:show_all();",
|
||||||
" application_id = 'org.awesomewm.tests.",class,
|
"Gtk:main{...}"
|
||||||
"'};",
|
|
||||||
"function app:on_activate()",
|
|
||||||
" window.application = self;",
|
|
||||||
" window:show_all();",
|
|
||||||
"end;",
|
|
||||||
"app:run {''}"
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
return spawn(cmd, use_sn)
|
return spawn(cmd, use_sn)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||||
|
|
|
@ -100,6 +100,8 @@ end
|
||||||
screen._add_screen {width=320, height=240}
|
screen._add_screen {width=320, height=240}
|
||||||
|
|
||||||
screen.add_signal("property::workarea")
|
screen.add_signal("property::workarea")
|
||||||
|
screen.add_signal("added")
|
||||||
|
screen.add_signal("removed")
|
||||||
|
|
||||||
return screen
|
return screen
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
-- Tests for screen additions & removals
|
||||||
|
|
||||||
|
local runner = require("_runner")
|
||||||
|
local test_client = require("_client")
|
||||||
|
local naughty = require("naughty")
|
||||||
|
|
||||||
|
local real_screen = screen[1]
|
||||||
|
local fake_screen = screen.fake_add(50, 50, 500, 500)
|
||||||
|
local test_client1, test_client2
|
||||||
|
|
||||||
|
local steps = {
|
||||||
|
-- Step 1: Set up some clients to experiment with and assign them as needed
|
||||||
|
function(count)
|
||||||
|
if count == 1 then -- Setup.
|
||||||
|
test_client()
|
||||||
|
test_client()
|
||||||
|
end
|
||||||
|
local cls = client.get()
|
||||||
|
if #cls == 2 then
|
||||||
|
test_client1, test_client2 = cls[1], cls[2]
|
||||||
|
test_client1.screen = real_screen
|
||||||
|
test_client2.screen = fake_screen
|
||||||
|
|
||||||
|
-- Display a notification on the screen-to-be-removed
|
||||||
|
naughty.notify{ text = "test", screen = fake_screen }
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- Step 2: Say goodbye to the screen
|
||||||
|
function()
|
||||||
|
fake_screen:fake_remove()
|
||||||
|
|
||||||
|
-- TODO: This is a hack to make the test work, how to do this so that it
|
||||||
|
-- also works "in the wild"?
|
||||||
|
mypromptbox[fake_screen] = nil
|
||||||
|
mylayoutbox[fake_screen] = nil
|
||||||
|
mytaglist[fake_screen] = nil
|
||||||
|
mytasklist[fake_screen] = nil
|
||||||
|
mywibox[fake_screen] = nil
|
||||||
|
|
||||||
|
-- Wrap in a weak table to allow garbage collection
|
||||||
|
fake_screen = setmetatable({ fake_screen }, { __mode = "v" })
|
||||||
|
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- Step 3: Everything should now be on the main screen, the old screen
|
||||||
|
-- should be garbage collectable
|
||||||
|
function()
|
||||||
|
assert(test_client1.screen == real_screen, test_client1.screen)
|
||||||
|
assert(test_client2.screen == real_screen, test_client2.screen)
|
||||||
|
|
||||||
|
collectgarbage("collect")
|
||||||
|
if #fake_screen == 0 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
runner.run_steps(steps)
|
||||||
|
|
||||||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
Loading…
Reference in New Issue