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.
|
||||
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)
|
||||
|
@ -39,7 +40,7 @@ end
|
|||
-- @param tag A tag object
|
||||
local function check_focus_tag(t)
|
||||
local s = t.screen
|
||||
if not s then return end
|
||||
if (not s) or (not s.valid) then return end
|
||||
s = screen[s]
|
||||
check_focus({ screen = s })
|
||||
if client.focus and screen[client.focus.screen] ~= s then
|
||||
|
|
|
@ -250,12 +250,14 @@ end
|
|||
-- @see awful.tag.find_fallback
|
||||
-- @tparam[opt=awful.tag.find_fallback()] tag fallback_tag Tag to assign
|
||||
-- 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.
|
||||
-- If there are no clients exclusively on this tag then delete it. Any
|
||||
-- stickied clients are assigned to the optional 'fallback_tag'.
|
||||
-- If after deleting the tag there is no selected tag, try and restore from
|
||||
-- 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
|
||||
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
|
||||
-- nowhere to go, abort.
|
||||
if (not c.sticky and nb_tags == 1) or
|
||||
(c.sticky and fallback_tag == nil) then
|
||||
if (not c.sticky and nb_tags == 1 and not force) then
|
||||
return
|
||||
-- If a client has multiple tags, then do not move it to fallback
|
||||
elseif nb_tags < 2 then
|
||||
|
@ -294,6 +295,7 @@ function tag.object.delete(self, fallback_tag)
|
|||
|
||||
-- delete the tag
|
||||
data.tags[self].screen = nil
|
||||
data.tags[self] = nil
|
||||
self.activated = false
|
||||
|
||||
-- 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::volatile")
|
||||
capi.tag.add_signal("request::screen")
|
||||
capi.tag.add_signal("removal-pending")
|
||||
|
||||
capi.screen.add_signal("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(...)
|
||||
return tag.new(...)
|
||||
end
|
||||
|
|
|
@ -168,7 +168,9 @@ function taglist.new(screen, filter, buttons, style, update_function, base_widge
|
|||
-- Add a delayed callback for the first update.
|
||||
if not queued_update[screen] then
|
||||
timer.delayed_call(function()
|
||||
if screen.valid then
|
||||
taglist_update(screen, w, buttons, filter, data, style, uf)
|
||||
end
|
||||
queued_update[screen] = false
|
||||
end)
|
||||
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("untagged", uc)
|
||||
capi.client.connect_signal("unmanage", uc)
|
||||
capi.screen.connect_signal("removed", function(s)
|
||||
instances[get_screen(s)] = nil
|
||||
end)
|
||||
end
|
||||
w._do_taglist_update()
|
||||
local list = instances[screen]
|
||||
|
|
|
@ -181,7 +181,9 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg
|
|||
if not queued_update then
|
||||
timer.delayed_call(function()
|
||||
queued_update = false
|
||||
if screen.valid then
|
||||
tasklist_update(screen, w, buttons, filter, data, style, uf)
|
||||
end
|
||||
end)
|
||||
queued_update = true
|
||||
end
|
||||
|
@ -201,9 +203,11 @@ function tasklist.new(screen, filter, buttons, style, update_function, base_widg
|
|||
end
|
||||
local function u()
|
||||
for s in pairs(instances) do
|
||||
if s.valid then
|
||||
us(s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tag.attached_connect_signal(nil, "property::selected", u)
|
||||
tag.attached_connect_signal(nil, "property::activated", u)
|
||||
|
@ -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("focus", u)
|
||||
capi.client.connect_signal("unfocus", u)
|
||||
capi.screen.connect_signal("removed", function(s)
|
||||
instances[get_screen(s)] = nil
|
||||
end)
|
||||
end
|
||||
w._do_tasklist_update()
|
||||
local list = instances[screen]
|
||||
|
|
|
@ -154,6 +154,16 @@ screen.connect_for_each_screen(function(s)
|
|||
}
|
||||
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
|
||||
function naughty.is_suspended()
|
||||
return suspended
|
||||
|
|
|
@ -1020,6 +1020,57 @@ luaA_screen_count(lua_State *L)
|
|||
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
|
||||
screen_class_setup(lua_State *L)
|
||||
{
|
||||
|
@ -1030,6 +1081,7 @@ screen_class_setup(lua_State *L)
|
|||
{ "__index", luaA_screen_module_index },
|
||||
{ "__newindex", luaA_default_newindex },
|
||||
{ "__call", luaA_screen_module_call },
|
||||
{ "fake_add", luaA_screen_fake_add },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -1037,6 +1089,7 @@ screen_class_setup(lua_State *L)
|
|||
{
|
||||
LUA_OBJECT_META(screen)
|
||||
LUA_CLASS_META
|
||||
{ "fake_remove", luaA_screen_fake_remove },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
|
|
@ -4,29 +4,26 @@ local spawn = require("awful.spawn")
|
|||
-- It is used to test the `awful.rules`
|
||||
|
||||
return function(class, title, use_sn)
|
||||
class = class or 'test_app'
|
||||
title = title or 'Awesome test client'
|
||||
|
||||
local cmd = {"lua" , "-e", table.concat {
|
||||
"local lgi = require 'lgi';",
|
||||
"local Gtk = lgi.require('Gtk');",
|
||||
"Gtk.init();",
|
||||
"local class = '",
|
||||
class or 'test_app',"';",
|
||||
"local class = '",class,"';",
|
||||
"local window = Gtk.Window {",
|
||||
" default_width = 100,",
|
||||
" default_height = 100,",
|
||||
" on_destroy = Gtk.main_quit,",
|
||||
" title = '",title,
|
||||
"'};",
|
||||
"window:set_wmclass(class, class);",
|
||||
"local app = Gtk.Application {",
|
||||
" application_id = 'org.awesomewm.tests.",class,
|
||||
"'};",
|
||||
"function app:on_activate()",
|
||||
" window.application = self;",
|
||||
"window:show_all();",
|
||||
"end;",
|
||||
"app:run {''}"
|
||||
"Gtk:main{...}"
|
||||
}}
|
||||
|
||||
return spawn(cmd, use_sn)
|
||||
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_signal("property::workarea")
|
||||
screen.add_signal("added")
|
||||
screen.add_signal("removed")
|
||||
|
||||
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