From 4d9bbf0ba6aa18a70441394bb95f8ee07e9210e7 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Thu, 15 Sep 2016 18:28:46 +0200 Subject: [PATCH 1/5] Remove an obsolete argument to client_resize_do() Thanks to Java being broken, the function always sends a notice anyway. Signed-off-by: Uli Schlachter --- objects/client.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/objects/client.c b/objects/client.c index 891e339b6..52d9c4220 100644 --- a/objects/client.c +++ b/objects/client.c @@ -757,7 +757,7 @@ static area_t titlebar_get_area(client_t *c, client_titlebar_t bar); static drawable_t *titlebar_get_drawable(lua_State *L, client_t *c, int cl_idx, client_titlebar_t bar); -static void client_resize_do(client_t *c, area_t geometry, bool force_notice); +static void client_resize_do(client_t *c, area_t geometry); /** Collect a client. * \param L The Lua VM state. @@ -1148,8 +1148,8 @@ border_width_callback(client_t *c, uint16_t old_width, uint16_t new_width) &diff_x, &diff_y); geometry.x += diff_x; geometry.y += diff_y; - /* force_notice = true -> inform client about changes */ - client_resize_do(c, geometry, true); + /* inform client about changes */ + client_resize_do(c, geometry); } } @@ -1498,25 +1498,15 @@ client_apply_size_hints(client_t *c, area_t geometry) } static void -client_resize_do(client_t *c, area_t geometry, bool force_notice) +client_resize_do(client_t *c, area_t geometry) { lua_State *L = globalconf_get_lua_State(); - bool send_notice = force_notice; bool hide_titlebars = c->fullscreen; - bool java_is_broken = true; screen_t *new_screen = c->screen; if(!screen_area_in_screen(new_screen, geometry)) new_screen = screen_getbycoord(geometry.x, geometry.y); - if(c->geometry.width == geometry.width - && c->geometry.height == geometry.height) - /* We are moving without changing the size, see ICCCM 4.2.3 */ - send_notice = true; - if(java_is_broken) - /* Java strong. Java Hulk. Java make own rules! */ - send_notice = true; - /* Also store geometry including border */ area_t old_geometry = c->geometry; c->geometry = geometry; @@ -1546,8 +1536,8 @@ client_resize_do(client_t *c, area_t geometry, bool force_notice) XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, (uint32_t[]) { real_geometry.x, real_geometry.y, real_geometry.width, real_geometry.height }); - if(send_notice) - client_send_configure(c); + /* ICCCM 4.2.3 says something else, but Java always needs this... */ + client_send_configure(c); client_restore_enterleave_events(); @@ -1629,7 +1619,7 @@ client_resize(client_t *c, area_t geometry, bool honor_hints) || c->geometry.width != geometry.width || c->geometry.height != geometry.height) { - client_resize_do(c, geometry, false); + client_resize_do(c, geometry); return true; } @@ -1799,7 +1789,7 @@ client_set_fullscreen(lua_State *L, int cidx, bool s) luaA_object_emit_signal(L, abs_cidx, "request::geometry", 1); luaA_object_emit_signal(L, abs_cidx, "property::fullscreen", 0); /* Force a client resize, so that titlebars get shown/hidden */ - client_resize_do(c, c->geometry, true); + client_resize_do(c, c->geometry); stack_windows(); } } @@ -2631,7 +2621,7 @@ titlebar_resize(lua_State *L, int cidx, client_t *c, client_titlebar_t bar, int } c->titlebar[bar].size = size; - client_resize_do(c, geometry, true); + client_resize_do(c, geometry); luaA_object_emit_signal(L, cidx, property_name, 0); } From bc6d06a3052c8f9085dc1b4d8355f2788cd9d776 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Thu, 15 Sep 2016 18:29:56 +0200 Subject: [PATCH 2/5] Remove an unnecessary variable Signed-off-by: Uli Schlachter --- objects/client.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/objects/client.c b/objects/client.c index 52d9c4220..057b76ee3 100644 --- a/objects/client.c +++ b/objects/client.c @@ -1501,7 +1501,6 @@ static void client_resize_do(client_t *c, area_t geometry) { lua_State *L = globalconf_get_lua_State(); - bool hide_titlebars = c->fullscreen; screen_t *new_screen = c->screen; if(!screen_area_in_screen(new_screen, geometry)) @@ -1516,7 +1515,7 @@ client_resize_do(client_t *c, area_t geometry) /* Configure the client for its new size */ area_t real_geometry = geometry; - if (!hide_titlebars) + if (!c->fullscreen) { real_geometry.x = c->titlebar[CLIENT_TITLEBAR_LEFT].size; real_geometry.y = c->titlebar[CLIENT_TITLEBAR_TOP].size; @@ -1570,7 +1569,7 @@ client_resize_do(client_t *c, area_t geometry) /* Convert to global coordinates */ area.x += geometry.x; area.y += geometry.y; - if (hide_titlebars) + if (c->fullscreen) area.width = area.height = 0; drawable_set_geometry(L, -1, area); From 8283a12ec94022f1b03a4c5083d8f47671b22179 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Thu, 15 Sep 2016 18:31:29 +0200 Subject: [PATCH 3/5] Only export a single refresh function for clients We still need client_focus_refresh() as a separate entry point, because it is used by event.c. Signed-off-by: Uli Schlachter --- event.h | 5 ++--- objects/client.c | 9 ++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/event.h b/event.h index 5849f7324..47ea42878 100644 --- a/event.h +++ b/event.h @@ -35,8 +35,8 @@ void luaA_emit_refresh(void); void drawin_refresh(void); /* objects/client.c */ +void client_refresh(void); void client_focus_refresh(void); -void client_border_refresh(void); /* objects/screen.c */ void screen_refresh(void); @@ -49,8 +49,7 @@ awesome_refresh(void) banning_refresh(); stack_refresh(); drawin_refresh(); - client_border_refresh(); - client_focus_refresh(); + client_refresh(); return xcb_flush(globalconf.connection); } diff --git a/objects/client.c b/objects/client.c index 057b76ee3..845e6e1fe 100644 --- a/objects/client.c +++ b/objects/client.c @@ -1128,13 +1128,20 @@ client_focus_refresh(void) win, globalconf.timestamp); } -void +static void client_border_refresh(void) { foreach(c, globalconf.clients) window_border_refresh((window_t *) *c); } +void +client_refresh(void) +{ + client_border_refresh(); + client_focus_refresh(); +} + static void border_width_callback(client_t *c, uint16_t old_width, uint16_t new_width) { From dd1d81a3acaf0da065ffab124b4a6f82da373de3 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Thu, 15 Sep 2016 18:36:34 +0200 Subject: [PATCH 4/5] client.c: Use AREA_EQUAL() Signed-off-by: Uli Schlachter --- objects/client.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/objects/client.c b/objects/client.c index 845e6e1fe..054aeb7fa 100644 --- a/objects/client.c +++ b/objects/client.c @@ -1620,10 +1620,7 @@ client_resize(client_t *c, area_t geometry, bool honor_hints) if (honor_hints) geometry = client_apply_size_hints(c, geometry); - if(c->geometry.x != geometry.x - || c->geometry.y != geometry.y - || c->geometry.width != geometry.width - || c->geometry.height != geometry.height) + if(!AREA_EQUAL(c->geometry, geometry)) { client_resize_do(c, geometry); From baaff93a7349a9da67b4b8f291a62820828f14bd Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Thu, 15 Sep 2016 18:48:56 +0200 Subject: [PATCH 5/5] Only configure client geometries once per main loop iteration This should "protect" the user from some stupidities that Lua code might be doing that e.g. makes a client jump to another position and then immediately back to where it was before. Only the last change in a single main loop iteration will actually have any effect. Original idea by Daniel here: https://github.com/awesomeWM/awesome/pull/174 Signed-off-by: Uli Schlachter --- objects/client.c | 76 +++++++++++++++++++++++++++++------------------- objects/client.h | 3 ++ 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/objects/client.c b/objects/client.c index 054aeb7fa..e561aae2b 100644 --- a/objects/client.c +++ b/objects/client.c @@ -1135,9 +1135,55 @@ client_border_refresh(void) window_border_refresh((window_t *) *c); } +static void +client_geometry_refresh(void) +{ + client_ignore_enterleave_events(); + foreach(_c, globalconf.clients) + { + client_t *c = *_c; + + /* Compute the client window's and frame window's geometry */ + area_t geometry = c->geometry; + area_t real_geometry = c->geometry; + if (!c->fullscreen) + { + real_geometry.x = c->titlebar[CLIENT_TITLEBAR_LEFT].size; + real_geometry.y = c->titlebar[CLIENT_TITLEBAR_TOP].size; + real_geometry.width -= c->titlebar[CLIENT_TITLEBAR_LEFT].size; + real_geometry.width -= c->titlebar[CLIENT_TITLEBAR_RIGHT].size; + real_geometry.height -= c->titlebar[CLIENT_TITLEBAR_TOP].size; + real_geometry.height -= c->titlebar[CLIENT_TITLEBAR_BOTTOM].size; + } else { + real_geometry.x = 0; + real_geometry.y = 0; + } + + /* Is there anything to do? */ + if (AREA_EQUAL(geometry, c->x11_frame_geometry) + && AREA_EQUAL(real_geometry, c->x11_client_geometry)) + continue; + + xcb_configure_window(globalconf.connection, c->frame_window, + XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, + (uint32_t[]) { geometry.x, geometry.y, geometry.width, geometry.height }); + xcb_configure_window(globalconf.connection, c->window, + XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, + (uint32_t[]) { real_geometry.x, real_geometry.y, real_geometry.width, real_geometry.height }); + + c->x11_frame_geometry = geometry; + c->x11_client_geometry = real_geometry; + + /* ICCCM 4.2.3 says something else, but Java always needs this... */ + client_send_configure(c); + } + client_restore_enterleave_events(); +} + void client_refresh(void) { + client_geometry_refresh(); client_border_refresh(); client_focus_refresh(); } @@ -1517,36 +1563,6 @@ client_resize_do(client_t *c, area_t geometry) area_t old_geometry = c->geometry; c->geometry = geometry; - /* Ignore all spurious enter/leave notify events */ - client_ignore_enterleave_events(); - - /* Configure the client for its new size */ - area_t real_geometry = geometry; - if (!c->fullscreen) - { - real_geometry.x = c->titlebar[CLIENT_TITLEBAR_LEFT].size; - real_geometry.y = c->titlebar[CLIENT_TITLEBAR_TOP].size; - real_geometry.width -= c->titlebar[CLIENT_TITLEBAR_LEFT].size; - real_geometry.width -= c->titlebar[CLIENT_TITLEBAR_RIGHT].size; - real_geometry.height -= c->titlebar[CLIENT_TITLEBAR_TOP].size; - real_geometry.height -= c->titlebar[CLIENT_TITLEBAR_BOTTOM].size; - } else { - real_geometry.x = 0; - real_geometry.y = 0; - } - - xcb_configure_window(globalconf.connection, c->frame_window, - XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, - (uint32_t[]) { geometry.x, geometry.y, geometry.width, geometry.height }); - xcb_configure_window(globalconf.connection, c->window, - XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, - (uint32_t[]) { real_geometry.x, real_geometry.y, real_geometry.width, real_geometry.height }); - - /* ICCCM 4.2.3 says something else, but Java always needs this... */ - client_send_configure(c); - - client_restore_enterleave_events(); - luaA_object_push(L, c); if (!AREA_EQUAL(old_geometry, geometry)) luaA_object_emit_signal(L, -1, "property::geometry", 0); diff --git a/objects/client.h b/objects/client.h index 733a4362a..e2dcfc8e9 100644 --- a/objects/client.h +++ b/objects/client.h @@ -61,6 +61,9 @@ struct client_t char *class, *instance; /** Window geometry */ area_t geometry; + /** Old window geometry currently configured in X11 */ + area_t x11_client_geometry; + area_t x11_frame_geometry; /** Startup ID */ char *startup_id; /** True if the client is sticky */