Merge pull request #1182 from psychon/screen_swap

Screen swap
This commit is contained in:
Emmanuel Lepage Vallée 2016-11-07 19:23:48 -05:00 committed by GitHub
commit 92a494a799
4 changed files with 109 additions and 2 deletions

View File

@ -2343,13 +2343,11 @@ luaA_client_swap(lua_State *L)
luaA_object_push(L, swap);
lua_pushboolean(L, true);
luaA_object_emit_signal(L, -4, "swapped", 2);
lua_pop(L, 2);
luaA_object_push(L, swap);
luaA_object_push(L, c);
lua_pushboolean(L, false);
luaA_object_emit_signal(L, -3, "swapped", 2);
lua_pop(L, 3);
}
return 0;

View File

@ -79,6 +79,16 @@
* @signal removed
*/
/** This signal is emitted when the list of available screens changes.
* @signal .list
*/
/** When 2 screens are swapped
* @tparam screen screen The other screen
* @tparam boolean is_source If self is the source or the destination of the swap
* @signal .swapped
*/
/**
* The primary screen.
*
@ -603,6 +613,7 @@ screen_refresh(void)
screen_array_t new_screens;
lua_State *L = globalconf_get_lua_State();
bool list_changed = false;
screen_array_init(&new_screens);
if (globalconf.have_randr_15)
@ -624,6 +635,8 @@ screen_refresh(void)
* globalconf.screens reference this screen now */
luaA_object_push(L, *new_screen);
luaA_object_ref(L, -1);
list_changed = true;
}
}
@ -642,6 +655,8 @@ screen_refresh(void)
lua_pop(L, 1);
luaA_object_unref(L, old_screen);
old_screen->valid = false;
list_changed = true;
}
}
@ -656,6 +671,9 @@ screen_refresh(void)
screen_array_wipe(&new_screens);
screen_update_primary();
if (list_changed)
luaA_class_emit_signal(L, &screen_class, "list", 0);
}
/** Return the squared distance of the given screen to the coordinates.
@ -1088,6 +1106,7 @@ luaA_screen_fake_add(lua_State *L)
s->geometry.height = height;
screen_added(L, s);
luaA_class_emit_signal(L, &screen_class, "list", 0);
luaA_object_push(L, s);
return 1;
@ -1109,6 +1128,7 @@ luaA_screen_fake_remove(lua_State *L)
luaA_object_push(L, s);
screen_removed(L, -1);
lua_pop(L, 1);
luaA_class_emit_signal(L, &screen_class, "list", 0);
luaA_object_unref(L, s);
s->valid = false;
@ -1145,6 +1165,47 @@ luaA_screen_fake_resize(lua_State *L)
return 0;
}
/** Swap a screen with another one in global screen list.
* @client s A screen to swap with.
* @function swap
*/
static int
luaA_screen_swap(lua_State *L)
{
screen_t *s = luaA_checkudata(L, 1, &screen_class);
screen_t *swap = luaA_checkudata(L, 2, &screen_class);
if(s != swap)
{
screen_t **ref_s = NULL, **ref_swap = NULL;
foreach(item, globalconf.screens)
{
if(*item == s)
ref_s = item;
else if(*item == swap)
ref_swap = item;
if(ref_s && ref_swap)
break;
}
/* swap ! */
*ref_s = swap;
*ref_swap = s;
luaA_class_emit_signal(L, &screen_class, "list", 0);
luaA_object_push(L, swap);
lua_pushboolean(L, true);
luaA_object_emit_signal(L, -4, "swapped", 2);
luaA_object_push(L, swap);
luaA_object_push(L, s);
lua_pushboolean(L, false);
luaA_object_emit_signal(L, -3, "swapped", 2);
}
return 0;
}
void
screen_class_setup(lua_State *L)
{
@ -1165,6 +1226,7 @@ screen_class_setup(lua_State *L)
LUA_CLASS_META
{ "fake_remove", luaA_screen_fake_remove },
{ "fake_resize", luaA_screen_fake_resize },
{ "swap", luaA_screen_swap },
{ NULL, NULL },
};

View File

@ -0,0 +1,33 @@
-- Test if client's c:swap() corrupts the Lua stack
local runner = require("_runner")
local test_client = require("_client")
runner.run_steps({
-- Spawn two clients
function(count)
if count == 1 then
test_client()
test_client()
end
if #client.get() >= 2 then
return true
end
end,
-- Swap them
function()
assert(#client.get() == 2, #client.get())
local c1 = client.get()[1]
local c2 = client.get()[2]
c2:swap(c1)
c1:swap(c2)
c1:swap(c2)
c1:swap(c2)
c2:swap(c1)
return true
end,
})
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -9,6 +9,11 @@ local real_screen = screen[1]
local fake_screen = screen.fake_add(50, 50, 500, 500)
local test_client1, test_client2
local list_count = 0
screen.connect_signal("list", function()
list_count = list_count + 1
end)
local steps = {
-- Step 1: Set up some clients to experiment with and assign them as needed
function(count)
@ -53,6 +58,15 @@ local steps = {
assert(wb.y == 110, wb.y)
assert(wb.width == 600, wb.width)
-- Test screen order changes
assert(list_count == 0)
assert(screen[1] == real_screen)
assert(screen[2] == fake_screen)
real_screen:swap(fake_screen)
assert(list_count == 1)
assert(screen[2] == real_screen)
assert(screen[1] == fake_screen)
return true
end,