Cache a screen's workarea

Instead of computing the workarea whenever some Lua code asks for it, it is now
remembered explicitly as a property on a screen. This allows us to only emit
property::workarea if the workarea actually changed.

Fixes: https://github.com/awesomeWM/awesome/issues/756
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-05-08 16:30:37 +02:00
parent d497cdf081
commit 08845c7a4b
5 changed files with 37 additions and 43 deletions

View File

@ -1543,14 +1543,6 @@ client_resize(client_t *c, area_t geometry, bool honor_hints)
return false; return false;
} }
static void
client_emit_property_workarea_on_screen(lua_State *L, client_t *c)
{
luaA_object_push(L, c->screen);
luaA_object_emit_signal(L, -1, "property::workarea", 0);
lua_pop(L, 1);
}
/** Set a client minimized, or not. /** Set a client minimized, or not.
* \param L The Lua VM state. * \param L The Lua VM state.
* \param cidx The client index. * \param cidx The client index.
@ -1610,7 +1602,7 @@ client_set_minimized(lua_State *L, int cidx, bool s)
xcb_map_window(globalconf.connection, c->window); xcb_map_window(globalconf.connection, c->window);
} }
if(strut_has_value(&c->strut)) if(strut_has_value(&c->strut))
client_emit_property_workarea_on_screen(L, c); screen_update_workarea(c->screen);
luaA_object_emit_signal(L, cidx, "property::minimized", 0); luaA_object_emit_signal(L, cidx, "property::minimized", 0);
} }
} }
@ -1630,7 +1622,7 @@ client_set_hidden(lua_State *L, int cidx, bool s)
c->hidden = s; c->hidden = s;
banning_need_update(); banning_need_update();
if(strut_has_value(&c->strut)) if(strut_has_value(&c->strut))
client_emit_property_workarea_on_screen(L, c); screen_update_workarea(c->screen);
luaA_object_emit_signal(L, cidx, "property::hidden", 0); luaA_object_emit_signal(L, cidx, "property::hidden", 0);
} }
} }
@ -1922,7 +1914,7 @@ client_unmanage(client_t *c, bool window_valid)
luaA_class_emit_signal(L, &client_class, "list", 0); luaA_class_emit_signal(L, &client_class, "list", 0);
if(strut_has_value(&c->strut)) if(strut_has_value(&c->strut))
client_emit_property_workarea_on_screen(L, c); screen_update_workarea(c->screen);
/* Get rid of all titlebars */ /* Get rid of all titlebars */
for (client_titlebar_t bar = CLIENT_TITLEBAR_TOP; bar < CLIENT_TITLEBAR_COUNT; bar++) { for (client_titlebar_t bar = CLIENT_TITLEBAR_TOP; bar < CLIENT_TITLEBAR_COUNT; bar++) {

View File

@ -323,9 +323,8 @@ drawin_set_visible(lua_State *L, int udx, bool v)
luaA_object_emit_signal(L, udx, "property::visible", 0); luaA_object_emit_signal(L, udx, "property::visible", 0);
if(strut_has_value(&drawin->strut)) if(strut_has_value(&drawin->strut))
{ {
luaA_object_push(L, screen_getbycoord(drawin->geometry.x, drawin->geometry.y)); screen_update_workarea(
luaA_object_emit_signal(L, -1, "property::workarea", 0); screen_getbycoord(drawin->geometry.x, drawin->geometry.y));
lua_pop(L, 1);
} }
} }
} }

View File

@ -478,6 +478,16 @@ static void screen_scan_x11(lua_State *L, screen_array_t *screens)
s->geometry.height = xcb_screen->height_in_pixels; s->geometry.height = xcb_screen->height_in_pixels;
} }
static void
screen_added(lua_State *L, screen_t *screen)
{
screen->workarea = screen->geometry;
screen->valid = true;
luaA_object_push(L, screen);
luaA_object_emit_signal(L, -1, "added", 0);
lua_pop(L, 1);
}
/** Get screens informations and fill global configuration. /** Get screens informations and fill global configuration.
*/ */
void void
@ -497,10 +507,7 @@ screen_scan(void)
screen_deduplicate(L, &globalconf.screens); screen_deduplicate(L, &globalconf.screens);
foreach(screen, globalconf.screens) { foreach(screen, globalconf.screens) {
(*screen)->valid = true; screen_added(L, *screen);
luaA_object_push(L, *screen);
luaA_object_emit_signal(L, -1, "added", 0);
lua_pop(L, 1);
} }
screen_update_primary(); screen_update_primary();
@ -533,8 +540,8 @@ screen_modified(screen_t *existing_screen, screen_t *other_screen)
existing_screen->geometry = other_screen->geometry; existing_screen->geometry = other_screen->geometry;
luaA_object_push(L, existing_screen); luaA_object_push(L, existing_screen);
luaA_object_emit_signal(L, -1, "property::geometry", 0); luaA_object_emit_signal(L, -1, "property::geometry", 0);
luaA_object_emit_signal(L, -1, "property::workarea", 0);
lua_pop(L, 1); lua_pop(L, 1);
screen_update_workarea(existing_screen);
} }
bool outputs_changed = existing_screen->outputs.len != other_screen->outputs.len; bool outputs_changed = existing_screen->outputs.len != other_screen->outputs.len;
@ -584,11 +591,10 @@ screen_refresh(void)
found |= (*new_screen)->xid == (*old_screen)->xid; found |= (*new_screen)->xid == (*old_screen)->xid;
if(!found) { if(!found) {
screen_array_append(&globalconf.screens, *new_screen); screen_array_append(&globalconf.screens, *new_screen);
(*new_screen)->valid = true; screen_added(L, *new_screen);
luaA_object_push(L, *new_screen);
luaA_object_emit_signal(L, -1, "added", 0);
/* Get an extra reference since both new_screens and /* Get an extra reference since both new_screens and
* globalconf.screens reference this screen now */ * globalconf.screens reference this screen now */
luaA_object_push(L, *new_screen);
luaA_object_ref(L, -1); luaA_object_ref(L, -1);
} }
} }
@ -696,17 +702,8 @@ screen_coord_in_screen(screen_t *s, int x, int y)
&& (y >= s->geometry.y && y < s->geometry.y + s->geometry.height); && (y >= s->geometry.y && y < s->geometry.y + s->geometry.height);
} }
/** Get screens info. void screen_update_workarea(screen_t *screen)
* \param screen Screen.
* \param strut Honor windows strut.
* \return The screen area.
*/
static area_t
screen_area_get(screen_t *screen, bool strut)
{ {
if(!strut)
return screen->geometry;
area_t area = screen->geometry; area_t area = screen->geometry;
uint16_t top = 0, bottom = 0, left = 0, right = 0; uint16_t top = 0, bottom = 0, left = 0, right = 0;
@ -762,7 +759,14 @@ screen_area_get(screen_t *screen, bool strut)
area.width -= left + right; area.width -= left + right;
area.height -= top + bottom; area.height -= top + bottom;
return area; if (AREA_EQUAL(area, screen->workarea))
return;
screen->workarea = area;
lua_State *L = globalconf_get_lua_State();
luaA_object_push(L, screen);
luaA_object_emit_signal(L, -1, "property::workarea", 0);
lua_pop(L, 1);
} }
/** Get display info. /** Get display info.
@ -815,8 +819,8 @@ screen_client_moveto(client_t *c, screen_t *new_screen, bool doresize)
return; return;
} }
from = screen_area_get(old_screen, false); from = old_screen->geometry;
to = screen_area_get(c->screen, false); to = c->screen->geometry;
area_t new_geometry = c->geometry; area_t new_geometry = c->geometry;
@ -1000,7 +1004,7 @@ luaA_screen_get_outputs(lua_State *L, screen_t *s)
static int static int
luaA_screen_get_workarea(lua_State *L, screen_t *s) luaA_screen_get_workarea(lua_State *L, screen_t *s)
{ {
luaA_pusharea(L, screen_area_get(s, true)); luaA_pusharea(L, s->workarea);
return 1; return 1;
} }

View File

@ -37,6 +37,8 @@ struct a_screen
bool valid; bool valid;
/** Screen geometry */ /** Screen geometry */
area_t geometry; area_t geometry;
/** Screen workarea */
area_t workarea;
/** The screen outputs informations */ /** The screen outputs informations */
screen_output_array_t outputs; screen_output_array_t outputs;
/** Some XID identifying this screen */ /** Some XID identifying this screen */
@ -52,6 +54,7 @@ int screen_get_index(screen_t *);
area_t display_area_get(void); area_t display_area_get(void);
void screen_client_moveto(client_t *, screen_t *, bool); void screen_client_moveto(client_t *, screen_t *, bool);
void screen_update_primary(void); void screen_update_primary(void);
void screen_update_workarea(screen_t *);
screen_t *screen_get_primary(void); screen_t *screen_get_primary(void);
screen_t *luaA_checkscreen(lua_State *, int); screen_t *luaA_checkscreen(lua_State *, int);

View File

@ -31,6 +31,7 @@
#include "common/atoms.h" #include "common/atoms.h"
#include "common/xutil.h" #include "common/xutil.h"
#include "ewmh.h" #include "ewmh.h"
#include "objects/screen.h"
#include "property.h" #include "property.h"
#include "xwindow.h" #include "xwindow.h"
@ -83,14 +84,9 @@ luaA_window_struts(lua_State *L)
luaA_tostrut(L, 2, &window->strut); luaA_tostrut(L, 2, &window->strut);
ewmh_update_strut(window->window, &window->strut); ewmh_update_strut(window->window, &window->strut);
luaA_object_emit_signal(L, 1, "property::struts", 0); luaA_object_emit_signal(L, 1, "property::struts", 0);
/* FIXME: Only emit if the workarea actually changed /* We don't know the correct screen, update them all */
* (= window is visible, only on the right screen)? */
foreach(s, globalconf.screens) foreach(s, globalconf.screens)
{ screen_update_workarea(*s);
luaA_object_push(L, *s);
luaA_object_emit_signal(L, -1, "property::workarea", 0);
lua_pop(L, 1);
}
} }
return luaA_pushstrut(L, window->strut); return luaA_pushstrut(L, window->strut);