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)
This commit is contained in:
Emmanuel Lepage Vallee 2019-07-10 20:59:53 -04:00
parent cd6998b18d
commit 875941e9ac
2 changed files with 48 additions and 3 deletions

View File

@ -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,

View File

@ -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;