From 08845c7a4b925cf6d81f533171054b23a6067fb5 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sun, 8 May 2016 16:30:37 +0200 Subject: [PATCH] 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 --- objects/client.c | 14 +++----------- objects/drawin.c | 5 ++--- objects/screen.c | 48 ++++++++++++++++++++++++++---------------------- objects/screen.h | 3 +++ objects/window.c | 10 +++------- 5 files changed, 37 insertions(+), 43 deletions(-) diff --git a/objects/client.c b/objects/client.c index 656fd953..dababb9f 100644 --- a/objects/client.c +++ b/objects/client.c @@ -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++) { diff --git a/objects/drawin.c b/objects/drawin.c index 7e4bd415..8b711069 100644 --- a/objects/drawin.c +++ b/objects/drawin.c @@ -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)); } } } diff --git a/objects/screen.c b/objects/screen.c index 3efca2dd..f8fdfa01 100644 --- a/objects/screen.c +++ b/objects/screen.c @@ -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; } diff --git a/objects/screen.h b/objects/screen.h index bba8810f..6b419c80 100644 --- a/objects/screen.h +++ b/objects/screen.h @@ -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); diff --git a/objects/window.c b/objects/window.c index 15b582c8..7176b0d3 100644 --- a/objects/window.c +++ b/objects/window.c @@ -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);