diff --git a/client.c b/client.c index da6262d0..5c88d2c2 100644 --- a/client.c +++ b/client.c @@ -234,8 +234,6 @@ client_ban(client_t *c) XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, request); - titlebar_ban(c->titlebar); - c->isbanned = true; /* All the wiboxes (may) need to be repositioned. */ @@ -834,6 +832,10 @@ client_setfullscreen(client_t *c, bool s) { area_t geometry; + /* Make sure the current geometry is stored without titlebar. */ + if (s) + titlebar_ban(c->titlebar); + /* become fullscreen! */ if((c->isfullscreen = s)) { @@ -1053,21 +1055,6 @@ client_unban(client_t *c) request); window_configure(c->win, c->geometries.internal, c->border); - /* Do this manually because the system doesn't know we moved the toolbar. - * Note that !isvisible titlebars are unmapped and for fullscreen it'll - * end up offscreen anyway. */ - if(c->titlebar) - { - simple_window_t *sw = &c->titlebar->sw; - /* All resizing is done, so only move now. */ - request[0] = sw->geometry.x; - request[1] = sw->geometry.y; - - xcb_configure_window(globalconf.connection, sw->window, - XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, - request); - } - c->isbanned = false; /* All the wiboxes (may) need to be repositioned. */ @@ -1245,8 +1232,7 @@ client_setborder(client_t *c, int width) client_need_arrange(c); /* Changing border size also affects the size of the titlebar. */ - if (c->titlebar) - titlebar_update_geometry(c); + titlebar_update_geometry(c); hooks_property(c, "border_width"); } diff --git a/layout.c b/layout.c index f4a5c094..db60f2ea 100644 --- a/layout.c +++ b/layout.c @@ -23,6 +23,7 @@ #include "tag.h" #include "window.h" #include "screen.h" +#include "titlebar.h" extern awesome_t globalconf; @@ -45,6 +46,12 @@ arrange(int screen) XCB_CW_EVENT_MASK, select_input_val); + /* Restore titlebar before client, so geometry is ok again. */ + if(titlebar_isvisible(c, screen)) + titlebar_unban(c->titlebar); + else if(c->screen == screen) + titlebar_ban(c->titlebar); + if(client_isvisible(c, screen)) client_unban(c); /* we don't touch other screens windows */ diff --git a/structs.h b/structs.h index 3c1e5f39..5d1c3855 100644 --- a/structs.h +++ b/structs.h @@ -110,6 +110,8 @@ typedef struct char *cursor; /** Background image */ image_t *bg_image; + /* Banned? used for titlebars */ + bool isbanned; /** Button bindings */ button_array_t buttons; } wibox_t; diff --git a/titlebar.c b/titlebar.c index d5de3e46..50f27b80 100644 --- a/titlebar.c +++ b/titlebar.c @@ -68,8 +68,9 @@ void titlebar_ban(wibox_t *titlebar) { /* Do it manually because client geometry remains unchanged. */ - if(titlebar) + if(titlebar && !titlebar->isbanned) { + client_t *c; simple_window_t *sw = &titlebar->sw; if(sw->window) @@ -80,6 +81,44 @@ titlebar_ban(wibox_t *titlebar) XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, request); } + + /* Remove titlebar geometry from client. */ + if ((c = client_getbytitlebar(titlebar))) + c->geometry = titlebar_geometry_remove(titlebar, 0, c->geometry); + + titlebar->isbanned = true; + } +} + +/** Move a titlebar on top of its client. + * \param titlebar The titlebar. + */ +void +titlebar_unban(wibox_t *titlebar) +{ + /* Do this manually because the system doesn't know we moved the toolbar. + * Note that !isvisible titlebars are unmapped and for fullscreen it'll + * end up offscreen anyway. */ + if(titlebar && titlebar->isbanned) + { + client_t *c; + simple_window_t *sw = &titlebar->sw; + + if (sw->window) + { + /* All resizing is done, so only move now. */ + uint32_t request[] = { sw->geometry.x, sw->geometry.y }; + + xcb_configure_window(globalconf.connection, sw->window, + XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, + request); + } + + titlebar->isbanned = false; + + /* Add titlebar geometry from client. */ + if ((c = client_getbytitlebar(titlebar))) + c->geometry = titlebar_geometry_add(titlebar, 0, c->geometry); } } @@ -250,8 +289,7 @@ titlebar_client_attach(client_t *c, wibox_t *t) * titlebar if needed. */ titlebar_update_geometry(c); - if(t->isvisible) - xcb_map_window(globalconf.connection, t->sw.window); + xcb_map_window(globalconf.connection, t->sw.window); client_need_arrange(c); client_stack(); @@ -267,14 +305,10 @@ titlebar_set_visible(wibox_t *t, bool visible) { if (visible != t->isvisible) { - /* The price of (un)mapping something small like a titlebar is pretty cheap. - * It would complicate matters if this rare case was treated like clients. - * Clients are moved out of the viewport when banned. - */ if ((t->isvisible = visible)) - xcb_map_window(globalconf.connection, t->sw.window); + titlebar_unban(t); else - xcb_unmap_window(globalconf.connection, t->sw.window); + titlebar_ban(t); globalconf.screens[t->screen].need_arrange = true; client_stack(); diff --git a/titlebar.h b/titlebar.h index 691b6950..cf47514a 100644 --- a/titlebar.h +++ b/titlebar.h @@ -23,6 +23,8 @@ #define AWESOME_TITLEBAR_H #include "wibox.h" +#include "client.h" +#include "window.h" client_t * client_getbytitlebar(wibox_t *); client_t * client_getbytitlebarwin(xcb_window_t); @@ -32,9 +34,24 @@ void titlebar_client_detach(client_t *); void titlebar_client_attach(client_t *, wibox_t *); void titlebar_set_visible(wibox_t *, bool); void titlebar_ban(wibox_t *); +void titlebar_unban(wibox_t *); int luaA_titlebar_newindex(lua_State *, wibox_t *, awesome_token_t); +static inline bool +titlebar_isvisible(client_t *c, int screen) +{ + if(client_isvisible(c, screen)) + { + if(c->isfullscreen) + return false; + if(!c->titlebar || !c->titlebar->isvisible) + return false; + return true; + } + return false; +} + /** Add the titlebar geometry and border to a geometry. * \param t The titlebar * \param border The client border size. @@ -48,7 +65,7 @@ titlebar_geometry_add(wibox_t *t, int border, area_t geometry) * This can then be substracted/added to the witdh/height/x/y. * In this case the border is included, because it belongs to a different window. */ - if(t) + if(t && !t->isbanned) switch(t->position) { case Top: @@ -89,7 +106,7 @@ titlebar_geometry_remove(wibox_t *t, int border, area_t geometry) * This can then be substracted/added to the witdh/height/x/y. * In this case the border is included, because it belongs to a different window. */ - if(t) + if(t && !t->isbanned) switch(t->position) { case Top: @@ -131,10 +148,6 @@ titlebar_update_geometry(client_t *c) /* Client geometry without titlebar, but including borders, since that is always consistent. */ titlebar_geometry_compute(c, titlebar_geometry_remove(c->titlebar, 0, c->geometry), &geom); wibox_moveresize(c->titlebar, geom); - - /* If the client is banned, move the titlebar out! */ - if(c->isbanned) - titlebar_ban(c->titlebar); } #endif diff --git a/wibox.h b/wibox.h index 398ac4c2..0dd140a9 100644 --- a/wibox.h +++ b/wibox.h @@ -41,8 +41,16 @@ void wibox_delete(wibox_t **); static inline void wibox_moveresize(wibox_t *wibox, area_t geometry) { - if(wibox->sw.window) + if(wibox->sw.window && !wibox->isbanned) simplewindow_moveresize(&wibox->sw, geometry); + else if(wibox->sw.window && wibox->isbanned) + { + area_t real_geom = geometry; + geometry.x = -geometry.width; + geometry.y = -geometry.height; + simplewindow_moveresize(&wibox->sw, geometry); + wibox->sw.geometry = real_geom; + } else wibox->sw.geometry = geometry; wibox->need_update = true;