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;
}
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.
* \param L The Lua VM state.
* \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);
}
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);
}
}
@ -1630,7 +1622,7 @@ client_set_hidden(lua_State *L, int cidx, bool s)
c->hidden = s;
banning_need_update();
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);
}
}
@ -1922,7 +1914,7 @@ client_unmanage(client_t *c, bool window_valid)
luaA_class_emit_signal(L, &client_class, "list", 0);
if(strut_has_value(&c->strut))
client_emit_property_workarea_on_screen(L, c);
screen_update_workarea(c->screen);
/* Get rid of all titlebars */
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);
if(strut_has_value(&drawin->strut))
{
luaA_object_push(L, screen_getbycoord(drawin->geometry.x, drawin->geometry.y));
luaA_object_emit_signal(L, -1, "property::workarea", 0);
lua_pop(L, 1);
screen_update_workarea(
screen_getbycoord(drawin->geometry.x, drawin->geometry.y));
}
}
}

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;
}
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.
*/
void
@ -497,10 +507,7 @@ screen_scan(void)
screen_deduplicate(L, &globalconf.screens);
foreach(screen, globalconf.screens) {
(*screen)->valid = true;
luaA_object_push(L, *screen);
luaA_object_emit_signal(L, -1, "added", 0);
lua_pop(L, 1);
screen_added(L, *screen);
}
screen_update_primary();
@ -533,8 +540,8 @@ screen_modified(screen_t *existing_screen, screen_t *other_screen)
existing_screen->geometry = other_screen->geometry;
luaA_object_push(L, existing_screen);
luaA_object_emit_signal(L, -1, "property::geometry", 0);
luaA_object_emit_signal(L, -1, "property::workarea", 0);
lua_pop(L, 1);
screen_update_workarea(existing_screen);
}
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;
if(!found) {
screen_array_append(&globalconf.screens, *new_screen);
(*new_screen)->valid = true;
luaA_object_push(L, *new_screen);
luaA_object_emit_signal(L, -1, "added", 0);
screen_added(L, *new_screen);
/* Get an extra reference since both new_screens and
* globalconf.screens reference this screen now */
luaA_object_push(L, *new_screen);
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);
}
/** Get screens info.
* \param screen Screen.
* \param strut Honor windows strut.
* \return The screen area.
*/
static area_t
screen_area_get(screen_t *screen, bool strut)
void screen_update_workarea(screen_t *screen)
{
if(!strut)
return screen->geometry;
area_t area = screen->geometry;
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.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.
@ -815,8 +819,8 @@ screen_client_moveto(client_t *c, screen_t *new_screen, bool doresize)
return;
}
from = screen_area_get(old_screen, false);
to = screen_area_get(c->screen, false);
from = old_screen->geometry;
to = c->screen->geometry;
area_t new_geometry = c->geometry;
@ -1000,7 +1004,7 @@ luaA_screen_get_outputs(lua_State *L, screen_t *s)
static int
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;
}

View File

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

View File

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