From 875941e9ac608123e1080897d198c524cca1e181 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Wed, 10 Jul 2019 20:59:53 -0400 Subject: [PATCH] screen: Store the lifecycle metadata. With this commit, the C code stores if the screen was created with `fake_screen` and also stores if the Lua side "promise" to manage (aka, track the viewport and remove it) the object. There is now 3 kind of screens: * Managed by C (created and deleted by the core code) * Managed by Lua (replicate the core code, but with more hooks) * Unmanaged (created directly with fake_screen) --- objects/screen.c | 39 ++++++++++++++++++++++++++++++++++++++- objects/screen.h | 12 ++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/objects/screen.c b/objects/screen.c index 2169e7af4..5f8af4ca3 100644 --- a/objects/screen.c +++ b/objects/screen.c @@ -590,6 +590,7 @@ screen_add(lua_State *L, screen_array_t *screens) luaA_object_ref(L, -1); screen_array_append(screens, new_screen); new_screen->xid = XCB_NONE; + new_screen->lifecycle = SCREEN_LIFECYCLE_USER; return new_screen; } @@ -667,6 +668,7 @@ screen_scan_randr_monitors(lua_State *L, screen_array_t *screens) continue; new_screen = screen_add(L, screens); + new_screen->lifecycle |= SCREEN_LIFECYCLE_C; viewport->screen = new_screen; new_screen->viewport = viewport; new_screen->geometry.x = monitor_iter.data->x; @@ -767,6 +769,7 @@ screen_scan_randr_crtcs(lua_State *L, screen_array_t *screens) /* Prepare the new screen */ screen_t *new_screen = screen_add(L, screens); + new_screen->lifecycle |= SCREEN_LIFECYCLE_C; viewport->screen = new_screen; new_screen->viewport = viewport; new_screen->geometry.x = crtc_info_r->x; @@ -906,6 +909,7 @@ screen_scan_xinerama(lua_State *L, screen_array_t *screens) screen_t *s = screen_add(L, screens); viewport->screen = s; s->viewport = viewport; + s->lifecycle |= SCREEN_LIFECYCLE_C; s->geometry.x = xsi[screen].x_org; s->geometry.y = xsi[screen].y_org; s->geometry.width = xsi[screen].width; @@ -931,6 +935,7 @@ static void screen_scan_x11(lua_State *L, screen_array_t *screens) screen_t *s = screen_add(L, screens); viewport->screen = s; + s->lifecycle |= SCREEN_LIFECYCLE_C; s->viewport = viewport; s->geometry.x = 0; s->geometry.y = 0; @@ -1134,9 +1139,11 @@ screen_refresh(gpointer unused) for(int i = 0; i < globalconf.screens.len; i++) { screen_t *old_screen = globalconf.screens.tab[i]; bool found = old_screen->xid == FAKE_SCREEN_XID; + foreach(new_screen, new_screens) found |= (*new_screen)->xid == old_screen->xid; - if(!found) { + + if(old_screen->lifecycle & SCREEN_LIFECYCLE_C && !found) { screen_array_take(&globalconf.screens, i); i--; @@ -1586,6 +1593,19 @@ luaA_screen_get_outputs(lua_State *L, screen_t *s) return 1; } +static int +luaA_screen_get_managed(lua_State *L, screen_t *s) +{ + if (s->lifecycle & SCREEN_LIFECYCLE_LUA) + lua_pushstring(L, "Lua"); + else if (s->lifecycle & SCREEN_LIFECYCLE_C) + lua_pushstring(L, "C"); + else + lua_pushstring(L, "none"); + + return 1; +} + static int luaA_screen_get_workarea(lua_State *L, screen_t *s) { @@ -1631,9 +1651,22 @@ luaA_screen_fake_add(lua_State *L) int y = luaL_checkinteger(L, 2); int width = luaL_checkinteger(L, 3); int height = luaL_checkinteger(L, 4); + + /* If the screen is managed by internal Lua code */ + bool managed = false; + + /* Allow undocumented arguments for internal use only */ + if(lua_istable(L, 5)) { + lua_getfield(L, 5, "_managed"); + managed = lua_isboolean(L, 6) && luaA_checkboolean(L, 6); + + lua_pop(L, 1); + } + screen_t *s; s = screen_add(L, &globalconf.screens); + s->lifecycle |= managed ? SCREEN_LIFECYCLE_LUA : SCREEN_LIFECYCLE_USER; s->geometry.x = x; s->geometry.y = y; s->geometry.width = width; @@ -1803,6 +1836,10 @@ screen_class_setup(lua_State *L) NULL, (lua_class_propfunc_t) luaA_screen_get_outputs, NULL); + luaA_class_add_property(&screen_class, "_managed", + NULL, + (lua_class_propfunc_t) luaA_screen_get_managed, + NULL); luaA_class_add_property(&screen_class, "workarea", NULL, (lua_class_propfunc_t) luaA_screen_get_workarea, diff --git a/objects/screen.h b/objects/screen.h index 405aba054..54f8104a8 100644 --- a/objects/screen.h +++ b/objects/screen.h @@ -30,16 +30,24 @@ typedef struct screen_output_t screen_output_t; ARRAY_TYPE(screen_output_t, screen_output) +/** Different ways to manage screens */ +typedef enum { + SCREEN_LIFECYCLE_USER = 0, /*!< Unmanaged (ei. from fake_add) */ + SCREEN_LIFECYCLE_LUA = 0x1 << 0, /*!< Is managed internally by Lua */ + SCREEN_LIFECYCLE_C = 0x1 << 1, /*!< Is managed internally by C */ +} screen_lifecycle_t; + struct a_screen { LUA_OBJECT_HEADER - /** Is this screen still valid and may be used? */ bool valid; + /** Who manages the screen lifecycle */ + screen_lifecycle_t lifecycle; /** Screen geometry */ area_t geometry; /** Screen workarea */ area_t workarea; - /** Opaque pointer to the psysical geometry */ + /** Opaque pointer to the viewport */ struct viewport_t *viewport; /** Some XID identifying this screen */ uint32_t xid;