diff --git a/client.c b/client.c index 47fe4e64..b915d2bf 100644 --- a/client.c +++ b/client.c @@ -202,8 +202,8 @@ client_ban(client_t *c) window_state_set(c->win, XCB_WM_STATE_ICONIC); else window_state_set(c->win, XCB_WM_STATE_WITHDRAWN); - if(c->titlebar && c->titlebar->position && c->titlebar->sw) - xcb_unmap_window(globalconf.connection, c->titlebar->sw->window); + if(c->titlebar && c->titlebar->position) + xcb_unmap_window(globalconf.connection, c->titlebar->sw.window); } /** Give focus to client, or to first client if client is NULL. @@ -260,14 +260,13 @@ client_stack_below(client_t *c, xcb_window_t previous) config_win_vals[1] = XCB_STACK_MODE_BELOW; if(c->titlebar - && c->titlebar->sw && c->titlebar->position) { xcb_configure_window(globalconf.connection, - c->titlebar->sw->window, + c->titlebar->sw.window, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, config_win_vals); - config_win_vals[0] = c->titlebar->sw->window; + config_win_vals[0] = c->titlebar->sw.window; } xcb_configure_window(globalconf.connection, c->win, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, @@ -335,14 +334,11 @@ client_stack(void) for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) { statusbar_t *sb = globalconf.screens[screen].statusbars.tab[i]; - if(sb->sw) - { - xcb_configure_window(globalconf.connection, - sb->sw->window, - XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, - config_win_vals); - config_win_vals[0] = sb->sw->window; - } + xcb_configure_window(globalconf.connection, + sb->sw.window, + XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, + config_win_vals); + config_win_vals[0] = sb->sw.window; } /* finally stack everything else */ @@ -775,12 +771,12 @@ client_unban(client_t *c) { xcb_map_window(globalconf.connection, c->win); window_state_set(c->win, XCB_WM_STATE_NORMAL); - if(c->titlebar && c->titlebar->sw && c->titlebar->position) + if(c->titlebar && c->titlebar->position) { if(c->isfullscreen) - xcb_unmap_window(globalconf.connection, c->titlebar->sw->window); + xcb_unmap_window(globalconf.connection, c->titlebar->sw.window); else - xcb_map_window(globalconf.connection, c->titlebar->sw->window); + xcb_map_window(globalconf.connection, c->titlebar->sw.window); } } @@ -821,7 +817,7 @@ client_unmanage(client_t *c) if(c->titlebar) { - simplewindow_delete(&c->titlebar->sw); + xcb_unmap_window(globalconf.connection, c->titlebar->sw.window); titlebar_unref(&c->titlebar); c->titlebar = NULL; } @@ -1294,7 +1290,7 @@ luaA_client_newindex(lua_State *L) /* If client had a titlebar, unref it */ if((*c)->titlebar) { - simplewindow_delete(&(*c)->titlebar->sw); + xcb_unmap_window(globalconf.connection, (*c)->titlebar->sw.window); titlebar_unref(&(*c)->titlebar); (*c)->titlebar = NULL; client_need_arrange(*c); @@ -1303,8 +1299,7 @@ luaA_client_newindex(lua_State *L) if(t) { /* Attach titlebar to client */ - (*c)->titlebar = *t; - titlebar_ref(t); + (*c)->titlebar = titlebar_ref(t); titlebar_init(*c); } client_stack(); diff --git a/event.c b/event.c index fb307733..08cff6f4 100644 --- a/event.c +++ b/event.c @@ -81,14 +81,14 @@ event_handle_mouse_button(client_t *c, /** Get a widget node from a statusbar by coords. * \param Container position. * \param widgets The widget list. - * \param height The container height. * \param width The container width. + * \param height The container height. * \param x X coordinate of the widget. * \param y Y coordinate of the widget. * \return A widget node. */ static widget_node_t * -widget_getbycoords(position_t position, widget_node_t *widgets, int height, int width, int x, int y) +widget_getbycoords(position_t position, widget_node_t *widgets, int width, int height, int x, int y) { int tmp; widget_node_t *w; @@ -98,13 +98,13 @@ widget_getbycoords(position_t position, widget_node_t *widgets, int height, int { case Right: tmp = y; - y = height - x; + y = width - x; x = tmp; break; case Left: tmp = y; y = x; - x = width - tmp; + x = height - tmp; break; default: break; @@ -141,18 +141,18 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) { statusbar_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; - if(statusbar->sw - && (statusbar->sw->window == ev->event || statusbar->sw->window == ev->child)) + if(statusbar->sw.window == ev->event || statusbar->sw.window == ev->child) { /* If the statusbar is child, then x,y are * relative to root window */ - if(statusbar->sw->window == ev->child) + if(statusbar->sw.window == ev->child) { - ev->event_x -= statusbar->sw->geometry.x; - ev->event_y -= statusbar->sw->geometry.y; + ev->event_x -= statusbar->sw.geometry.x; + ev->event_y -= statusbar->sw.geometry.y; } if((w = widget_getbycoords(statusbar->position, statusbar->widgets, - statusbar->width, statusbar->height, + statusbar->sw.geometry.width, + statusbar->sw.geometry.height, ev->event_x, ev->event_y))) w->widget->button(w, ev, statusbar->screen, statusbar, AWESOME_TYPE_STATUSBAR); /* return even if no widget match */ @@ -388,7 +388,8 @@ event_handle_motionnotify(void *data __attribute__ ((unused)), if(statusbar) { w = widget_getbycoords(statusbar->position, statusbar->widgets, - statusbar->width, statusbar->height, + statusbar->sw.geometry.width, + statusbar->sw.geometry.height, ev->event_x, ev->event_y); event_handle_widget_motionnotify(statusbar, AWESOME_TYPE_STATUSBAR, @@ -397,7 +398,8 @@ event_handle_motionnotify(void *data __attribute__ ((unused)), else if((c = client_getbytitlebarwin(ev->event))) { w = widget_getbycoords(c->titlebar->position, c->titlebar->widgets, - c->titlebar->width, c->titlebar->height, + c->titlebar->sw.geometry.width, + c->titlebar->sw.geometry.height, ev->event_x, ev->event_y); event_handle_widget_motionnotify(c->titlebar, AWESOME_TYPE_TITLEBAR, @@ -502,16 +504,15 @@ event_handle_expose(void *data __attribute__ ((unused)), for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) { statusbar_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; - if(statusbar->sw - && statusbar->sw->window == ev->window) + if(statusbar->sw.window == ev->window) { - simplewindow_refresh_pixmap(statusbar->sw); + simplewindow_refresh_pixmap(&statusbar->sw); return 0; } } if((c = client_getbytitlebarwin(ev->window))) - simplewindow_refresh_pixmap(c->titlebar->sw); + simplewindow_refresh_pixmap(&c->titlebar->sw); } return 0; diff --git a/mouse.c b/mouse.c index 914b41d9..7b23cc0e 100644 --- a/mouse.c +++ b/mouse.c @@ -260,15 +260,15 @@ mouse_infobox_draw(simple_window_t *sw, #define MOUSE_INFOBOX_STRING_DEFAULT "0000x0000+0000+0000" /** Initialize the infobox window. + * \param sw The simple window to init. * \param phys_screen Physical screen number. * \param border Border size of the client. * \param geometry Client geometry. * \return The simple window. */ -static simple_window_t * -mouse_infobox_new(int phys_screen, int border, area_t geometry) +static void +mouse_infobox_new(simple_window_t *sw, int phys_screen, int border, area_t geometry) { - simple_window_t *sw; area_t geom; draw_parser_data_t pdata; @@ -282,17 +282,15 @@ mouse_infobox_new(int phys_screen, int border, area_t geometry) geom.x = geometry.x + ((2 * border + geometry.width) - geom.width) / 2; geom.y = geometry.y + ((2 * border + geometry.height) - geom.height) / 2; - sw = simplewindow_new(phys_screen, - geom.x, geom.y, - geom.width, geom.height, 0, - Top, &globalconf.colors.fg, &globalconf.colors.bg); + simplewindow_init(sw, phys_screen, + geom.x, geom.y, + geom.width, geom.height, 0, + Top, &globalconf.colors.fg, &globalconf.colors.bg); xcb_map_window(globalconf.connection, sw->window); mouse_infobox_draw(sw, geometry, border); draw_parser_data_wipe(&pdata); - - return sw; } /** Get the pointer position. @@ -477,7 +475,7 @@ mouse_client_move(client_t *c, int snap, bool infobox) /* current layout */ layout_t *layout; /* the infobox */ - simple_window_t *sw = NULL; + simple_window_t sw; /* the root window */ xcb_window_t root; @@ -496,7 +494,9 @@ mouse_client_move(client_t *c, int snap, bool infobox) return; if(infobox && (client_isfloating(c) || layout == layout_floating)) - sw = mouse_infobox_new(c->phys_screen, c->border, c->geometry); + mouse_infobox_new(&sw, c->phys_screen, c->border, c->geometry); + else + infobox = false; /* for each motion event */ while(mouse_track_mouse_drag(&mouse_x, &mouse_y)) @@ -517,8 +517,8 @@ mouse_client_move(client_t *c, int snap, bool infobox) c->ismoving = false; /* draw the infobox */ - if(sw) - mouse_infobox_draw(sw, c->geometry, c->border); + if(infobox) + mouse_infobox_draw(&sw, c->geometry, c->border); statusbar_refresh(); @@ -560,8 +560,8 @@ mouse_client_move(client_t *c, int snap, bool infobox) xcb_ungrab_pointer(globalconf.connection, XCB_CURRENT_TIME); /* free the infobox */ - if(sw) - simplewindow_delete(&sw); + if(infobox) + simplewindow_wipe(&sw); } @@ -579,7 +579,7 @@ mouse_client_resize_floating(client_t *c, corner_t corner, bool infobox) /* the other is moved with the mouse */ int mouse_x = 0, mouse_y = 0; /* the infobox */ - simple_window_t *sw = NULL; + simple_window_t sw; size_t cursor = CurResize; int top, bottom, left, right; @@ -626,7 +626,7 @@ mouse_client_resize_floating(client_t *c, corner_t corner, bool infobox) /* create the infobox */ if(infobox) - sw = mouse_infobox_new(c->phys_screen, c->border, c->geometry); + mouse_infobox_new(&sw, c->phys_screen, c->border, c->geometry); /* for each motion event */ while(mouse_track_mouse_drag(&mouse_x, &mouse_y)) @@ -699,16 +699,16 @@ mouse_client_resize_floating(client_t *c, corner_t corner, bool infobox) titlebar_draw(c); /* draw the infobox */ - if(sw) - mouse_infobox_draw(sw, c->geometry, c->border); + if(infobox) + mouse_infobox_draw(&sw, c->geometry, c->border); } /* relase pointer */ mouse_ungrab_pointer(); /* free the infobox */ - if(sw) - simplewindow_delete(&sw); + if(infobox) + simplewindow_wipe(&sw); } /** Resize the master column/row of a tiled layout @@ -828,7 +828,7 @@ mouse_client_resize_magnified(client_t *c, bool infobox) /* current tag */ tag_t *tag; /* the infobox */ - simple_window_t *sw = NULL; + simple_window_t sw; xcb_window_t root; tag = tags_get_current(c->screen)[0]; @@ -879,7 +879,7 @@ mouse_client_resize_magnified(client_t *c, bool infobox) /* create the infobox */ if(infobox) - sw = mouse_infobox_new(c->phys_screen, c->border, c->geometry); + mouse_infobox_new(&sw, c->phys_screen, c->border, c->geometry); /* for each motion event */ while(mouse_track_mouse_drag(&mouse_x, &mouse_y)) @@ -908,16 +908,16 @@ mouse_client_resize_magnified(client_t *c, bool infobox) } /* draw the infobox */ - if(sw) - mouse_infobox_draw(sw, c->geometry, c->border); + if(infobox) + mouse_infobox_draw(&sw, c->geometry, c->border); } /* ungrab pointer */ mouse_ungrab_pointer(); /* free the infobox */ - if(sw) - simplewindow_delete(&sw); + if(infobox) + simplewindow_wipe(&sw); } /** Resize a client with the mouse. diff --git a/screen.c b/screen.c index 7daebb67..74153ee2 100644 --- a/screen.c +++ b/screen.c @@ -222,16 +222,16 @@ screen_area_get(int screen, statusbar_array_t *statusbars, switch(sb->position) { case Top: - top = MAX(top, (uint16_t) (sb->sw->geometry.y - area.y) + sb->sw->geometry.height); + top = MAX(top, (uint16_t) (sb->sw.geometry.y - area.y) + sb->sw.geometry.height); break; case Bottom: - bottom = MAX(bottom, (uint16_t) (area.y + area.height) - sb->sw->geometry.y); + bottom = MAX(bottom, (uint16_t) (area.y + area.height) - sb->sw.geometry.y); break; case Left: - left = MAX(left, (uint16_t) (sb->sw->geometry.x - area.x) + sb->sw->geometry.width); + left = MAX(left, (uint16_t) (sb->sw.geometry.x - area.x) + sb->sw.geometry.width); break; case Right: - right = MAX(right, (uint16_t) (area.x + area.width) - sb->sw->geometry.x); + right = MAX(right, (uint16_t) (area.x + area.width) - sb->sw.geometry.x); break; default: break; diff --git a/statusbar.c b/statusbar.c index 53c3f496..a61ae74d 100644 --- a/statusbar.c +++ b/statusbar.c @@ -41,6 +41,9 @@ statusbar_systray_kickout(int phys_screen) { xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); + /* Who! Check that we're not deleting a statusbar with a systray, because it + * may be its parent. If so, we reparent to root before, otherwise it will + * hurt very much. */ xcb_reparent_window(globalconf.connection, globalconf.screens[phys_screen].systray.window, s->root, -512, -512); @@ -64,7 +67,7 @@ statusbar_systray_refresh(statusbar_t *statusbar) uint32_t config_win_vals_off[2] = { -512, -512 }; xembed_window_t *em; position_t pos; - int phys_screen = statusbar->sw->phys_screen; + int phys_screen = statusbar->sw.ctx.phys_screen; if(statusbar->position && systray->widget->isvisible @@ -83,7 +86,7 @@ statusbar_systray_refresh(statusbar_t *statusbar) { case Left: config_win_vals[0] = systray->area.y; - config_win_vals[1] = statusbar->sw->geometry.height - systray->area.x - systray->area.width; + config_win_vals[1] = statusbar->sw.geometry.height - systray->area.x - systray->area.width; config_win_vals[2] = systray->area.height; config_win_vals[3] = systray->area.width; break; @@ -101,13 +104,13 @@ statusbar_systray_refresh(statusbar_t *statusbar) break; } /* reparent */ - if(globalconf.screens[phys_screen].systray.parent != statusbar->sw->window) + if(globalconf.screens[phys_screen].systray.parent != statusbar->sw.window) { xcb_reparent_window(globalconf.connection, globalconf.screens[phys_screen].systray.window, - statusbar->sw->window, + statusbar->sw.window, config_win_vals[0], config_win_vals[1]); - globalconf.screens[phys_screen].systray.parent = statusbar->sw->window; + globalconf.screens[phys_screen].systray.parent = statusbar->sw.window; } xcb_configure_window(globalconf.connection, globalconf.screens[phys_screen].systray.window, @@ -134,7 +137,7 @@ statusbar_systray_refresh(statusbar_t *statusbar) for(em = globalconf.embedded; em; em = em->next) if(em->phys_screen == phys_screen) { - if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) statusbar->sw->geometry.y) + if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) statusbar->sw.geometry.y) { xcb_map_window(globalconf.connection, em->win); xcb_configure_window(globalconf.connection, em->win, @@ -157,7 +160,7 @@ statusbar_systray_refresh(statusbar_t *statusbar) for(em = globalconf.embedded; em; em = em->next) if(em->phys_screen == phys_screen) { - if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) statusbar->sw->geometry.y + statusbar->sw->geometry.width) + if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) statusbar->sw.geometry.y + statusbar->sw.geometry.width) { xcb_map_window(globalconf.connection, em->win); xcb_configure_window(globalconf.connection, em->win, @@ -182,7 +185,7 @@ statusbar_systray_refresh(statusbar_t *statusbar) if(em->phys_screen == phys_screen) { /* if(x + width < systray.x + systray.width) */ - if(config_win_vals[0] + config_win_vals[2] <= (uint32_t) AREA_RIGHT(systray->area) + statusbar->sw->geometry.x) + if(config_win_vals[0] + config_win_vals[2] <= (uint32_t) AREA_RIGHT(systray->area) + statusbar->sw.geometry.x) { xcb_map_window(globalconf.connection, em->win); xcb_configure_window(globalconf.connection, em->win, @@ -218,12 +221,12 @@ statusbar_draw(statusbar_t *statusbar) if(statusbar->position) { - widget_render(statusbar->widgets, &statusbar->sw->ctx, statusbar->sw->gc, - statusbar->sw->pixmap, + widget_render(statusbar->widgets, &statusbar->sw.ctx, statusbar->sw.gc, + statusbar->sw.pixmap, statusbar->screen, statusbar->position, - statusbar->sw->geometry.x, statusbar->sw->geometry.y, + statusbar->sw.geometry.x, statusbar->sw.geometry.y, statusbar, AWESOME_TYPE_STATUSBAR); - simplewindow_refresh_pixmap(statusbar->sw); + simplewindow_refresh_pixmap(&statusbar->sw); } statusbar_systray_refresh(statusbar); @@ -240,7 +243,7 @@ statusbar_getbywin(xcb_window_t w) for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) { statusbar_t *s = globalconf.screens[screen].statusbars.tab[i]; - if(s->sw->window == w) + if(s->sw.window == w) return s; } return NULL; @@ -260,18 +263,6 @@ statusbar_refresh(void) } } -static void -statusbar_clean(statusbar_t *statusbar) -{ - /* Who! Check that we're not deleting a statusbar with a systray, because it - * may be its parent. If so, we reparent to root before, otherwise it will - * hurt very much. */ - if(statusbar->sw) - statusbar_systray_kickout(statusbar->sw->phys_screen); - - simplewindow_delete(&statusbar->sw); -} - /** Update the statusbar position. It deletes every statusbar resources and * create them back. * \param statusbar The statusbar. @@ -283,7 +274,12 @@ statusbar_position_update(statusbar_t *statusbar) bool ignore = false; if(statusbar->position == Off) - return statusbar_clean(statusbar); + { + xcb_unmap_window(globalconf.connection, statusbar->sw.window); + /* kick out systray if needed */ + statusbar_systray_refresh(statusbar); + return; + } area = screen_area_get(statusbar->screen, NULL, &globalconf.screens[statusbar->screen].padding, true); @@ -447,28 +443,31 @@ statusbar_position_update(statusbar_t *statusbar) break; } - /* same window size and position ? */ - if(!statusbar->sw - || wingeometry.width != statusbar->sw->geometry.width - || wingeometry.height != statusbar->sw->geometry.height) + if(!statusbar->sw.window) { int phys_screen = screen_virttophys(statusbar->screen); - statusbar_clean(statusbar); - - statusbar->sw = - simplewindow_new(phys_screen, 0, 0, - wingeometry.width, wingeometry.height, 0, - statusbar->position, - &statusbar->colors.fg, &statusbar->colors.bg); - - simplewindow_move(statusbar->sw, wingeometry.x, wingeometry.y); - xcb_map_window(globalconf.connection, statusbar->sw->window); - statusbar->need_update = true; + simplewindow_init(&statusbar->sw, phys_screen, + wingeometry.x, wingeometry.y, + wingeometry.width, wingeometry.height, + 0, statusbar->position, + &statusbar->colors.fg, &statusbar->colors.bg); + xcb_map_window(globalconf.connection, statusbar->sw.window); + } + /* same window size and position ? */ + else + { + if(wingeometry.width != statusbar->sw.geometry.width + || wingeometry.height != statusbar->sw.geometry.height) + { + simplewindow_resize(&statusbar->sw, wingeometry.width, wingeometry.height); + statusbar->need_update = true; + } + + if(wingeometry.x != statusbar->sw.geometry.x + || wingeometry.y != statusbar->sw.geometry.y) + simplewindow_move(&statusbar->sw, wingeometry.x, wingeometry.y); } - else if(wingeometry.x != statusbar->sw->geometry.x - || wingeometry.y != statusbar->sw->geometry.y) - simplewindow_move(statusbar->sw, wingeometry.x, wingeometry.y); /* Set need update */ globalconf.screens[statusbar->screen].need_arrange = true; @@ -620,8 +619,6 @@ statusbar_remove(statusbar_t *statusbar) { position_t p; - statusbar_systray_kickout(screen_virttophys(statusbar->screen)); - /* save position */ p = statusbar->position; statusbar->position = Off; @@ -629,6 +626,10 @@ statusbar_remove(statusbar_t *statusbar) /* restore position */ statusbar->position = p; + simplewindow_wipe(&statusbar->sw); + /* sw.window is used to now if the window has been init or not */ + statusbar->sw.window = 0; + for(int i = 0; i < globalconf.screens[statusbar->screen].statusbars.len; i++) if(globalconf.screens[statusbar->screen].statusbars.tab[i] == statusbar) { @@ -704,8 +705,7 @@ luaA_statusbar_newindex(lua_State *L) if((buf = luaL_checklstring(L, 3, &len))) if(xcolor_init_reply(xcolor_init_unchecked(&(*statusbar)->colors.fg, buf, len))) { - if((*statusbar)->sw) - (*statusbar)->sw->ctx.fg = (*statusbar)->colors.fg; + (*statusbar)->sw.ctx.fg = (*statusbar)->colors.fg; (*statusbar)->need_update = true; } break; @@ -713,8 +713,7 @@ luaA_statusbar_newindex(lua_State *L) if((buf = luaL_checklstring(L, 3, &len))) if(xcolor_init_reply(xcolor_init_unchecked(&(*statusbar)->colors.bg, buf, len))) { - if((*statusbar)->sw) - (*statusbar)->sw->ctx.bg = (*statusbar)->colors.bg; + (*statusbar)->sw.ctx.bg = (*statusbar)->colors.bg; (*statusbar)->need_update = true; } break; @@ -724,6 +723,8 @@ luaA_statusbar_newindex(lua_State *L) if(p != (*statusbar)->position) { (*statusbar)->position = p; + simplewindow_wipe(&(*statusbar)->sw); + (*statusbar)->sw.window = 0; if((*statusbar)->screen != SCREEN_UNDEF) { for(int i = 0; i < globalconf.screens[(*statusbar)->screen].statusbars.len; i++) diff --git a/statusbar.h b/statusbar.h index f7969d98..8a76c5e8 100644 --- a/statusbar.h +++ b/statusbar.h @@ -29,7 +29,7 @@ static inline void statusbar_delete(statusbar_t **statusbar) { - simplewindow_delete(&(*statusbar)->sw); + simplewindow_wipe(&(*statusbar)->sw); widget_node_list_wipe(&(*statusbar)->widgets); p_delete(&(*statusbar)->name); p_delete(statusbar); diff --git a/structs.h b/structs.h index 87eec9cd..9a6b1b1c 100644 --- a/structs.h +++ b/structs.h @@ -185,7 +185,7 @@ struct titlebar_t /** Width and height */ int width, height; /** Titlebar window */ - simple_window_t *sw; + simple_window_t sw; /** Default colors */ struct { @@ -219,7 +219,7 @@ struct statusbar_t /** Ref count */ int refcount; /** Window */ - simple_window_t *sw; + simple_window_t sw; /** statusbar_t name */ char *name; /** Bar width */ diff --git a/swindow.c b/swindow.c index 1d13e19a..69bd801e 100644 --- a/swindow.c +++ b/swindow.c @@ -30,7 +30,8 @@ extern awesome_t globalconf; -/** Create a simple window. +/** Initialize a simple window. + * \param sw The simple window to initialize. * \param phys_screen Physical screen number. * \param x x coordinate. * \param y y coordinate. @@ -40,29 +41,25 @@ extern awesome_t globalconf; * \param position The rendering position. * \param bg Default foreground color. * \param bg Default background color. - * \return A pointer to a newly allocated simple window, which must be deleted - * with simplewindow_delete(). */ -simple_window_t * -simplewindow_new(int phys_screen, int x, int y, - unsigned int w, unsigned int h, - unsigned int border_width, - position_t position, - const xcolor_t *fg, const xcolor_t *bg) +void +simplewindow_init(simple_window_t *sw, + int phys_screen, + int x, int y, + unsigned int w, unsigned int h, + unsigned int border_width, + position_t position, + const xcolor_t *fg, const xcolor_t *bg) { - simple_window_t *sw; xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); uint32_t create_win_val[3]; const uint32_t gc_mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; const uint32_t gc_values[2] = { s->black_pixel, s->white_pixel }; - sw = p_new(simple_window_t, 1); - sw->geometry.x = x; sw->geometry.y = y; sw->geometry.width = w; sw->geometry.height = h; - sw->phys_screen = phys_screen; create_win_val[0] = XCB_BACK_PIXMAP_PARENT_RELATIVE; create_win_val[1] = 1; @@ -104,26 +101,20 @@ simplewindow_new(int phys_screen, int x, int y, sw->gc = xcb_generate_id(globalconf.connection); xcb_create_gc(globalconf.connection, sw->gc, s->root, gc_mask, gc_values); - sw->border_width = border_width; + sw->border.width = border_width; sw->position = position; - - return sw; } -/** Destroy a simple window and all its resources. - * \param sw The simple_window_t to delete. +/** Destroy all resources of a simple window. + * \param sw The simple_window_t to wipe. */ void -simplewindow_delete(simple_window_t **sw) +simplewindow_wipe(simple_window_t *sw) { - if(*sw) - { - xcb_destroy_window(globalconf.connection, (*sw)->window); - xcb_free_pixmap(globalconf.connection, (*sw)->pixmap); - xcb_free_gc(globalconf.connection, (*sw)->gc); - draw_context_wipe(&(*sw)->ctx); - p_delete(sw); - } + xcb_destroy_window(globalconf.connection, sw->window); + xcb_free_pixmap(globalconf.connection, sw->pixmap); + xcb_free_gc(globalconf.connection, sw->gc); + draw_context_wipe(&sw->ctx); } /** Move a simple window. @@ -147,6 +138,7 @@ static void simplewindow_draw_context_update(simple_window_t *sw, xcb_screen_t *s) { xcolor_t fg = sw->ctx.fg, bg = sw->ctx.bg; + int phys_screen = sw->ctx.phys_screen; draw_context_wipe(&sw->ctx); @@ -161,12 +153,12 @@ simplewindow_draw_context_update(simple_window_t *sw, xcb_screen_t *s) s->root_depth, sw->ctx.pixmap, s->root, sw->geometry.height, sw->geometry.width); - draw_context_init(&sw->ctx, sw->phys_screen, + draw_context_init(&sw->ctx, phys_screen, sw->geometry.height, sw->geometry.width, sw->ctx.pixmap, &fg, &bg); break; default: - draw_context_init(&sw->ctx, sw->phys_screen, + draw_context_init(&sw->ctx, phys_screen, sw->geometry.width, sw->geometry.height, sw->pixmap, &fg, &bg); break; @@ -183,7 +175,7 @@ simplewindow_resize(simple_window_t *sw, int w, int h) { if(w > 0 && h > 0 && (sw->geometry.width != w || sw->geometry.height != h)) { - xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->phys_screen); + xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen); uint32_t resize_win_vals[2]; sw->geometry.width = resize_win_vals[0] = w; @@ -209,7 +201,7 @@ void simplewindow_moveresize(simple_window_t *sw, int x, int y, int w, int h) { uint32_t moveresize_win_vals[4], mask_vals = 0; - xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->phys_screen); + xcb_screen_t *s = xutil_screen_get(globalconf.connection, sw->ctx.phys_screen); if(sw->geometry.x != x || sw->geometry.y != y) { @@ -261,7 +253,7 @@ simplewindow_border_width_set(simple_window_t *sw, uint32_t border_width) { xcb_configure_window(globalconf.connection, sw->window, XCB_CONFIG_WINDOW_BORDER_WIDTH, &border_width); - sw->border_width = border_width; + sw->border.width = border_width; } /** Set a simple window border color. @@ -273,6 +265,7 @@ simplewindow_border_color_set(simple_window_t *sw, const xcolor_t *color) { xcb_change_window_attributes(globalconf.connection, sw->window, XCB_CW_BORDER_PIXEL, &color->pixel); + sw->border.color = *color; } // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/swindow.h b/swindow.h index dbf45ba0..33b05dcb 100644 --- a/swindow.h +++ b/swindow.h @@ -28,10 +28,6 @@ /** A simple window. */ typedef struct simple_window_t { - /** Orientation */ - - /** The physical screen number the window is on. */ - int phys_screen; /** The window object. */ xcb_window_t window; /** The pixmap copied to the window object. */ @@ -40,17 +36,25 @@ typedef struct simple_window_t xcb_gcontext_t gc; /** The window geometry. */ area_t geometry; - /** The window border width */ - int border_width; + /** The window border */ + struct + { + /** The window border width */ + int width; + /** The window border color */ + xcolor_t color; + } border; /** Draw context */ draw_context_t ctx; /** Position */ position_t position; } simple_window_t; -simple_window_t * simplewindow_new(int, int, int, unsigned int, unsigned int, unsigned int, - position_t, const xcolor_t *, const xcolor_t *); -void simplewindow_delete(simple_window_t **); +void simplewindow_init(simple_window_t *s, + int, int, int, unsigned int, unsigned int, unsigned int, + position_t, const xcolor_t *, const xcolor_t *); + +void simplewindow_wipe(simple_window_t *); void simplewindow_move(simple_window_t *, int, int); void simplewindow_resize(simple_window_t *, int, int); diff --git a/titlebar.c b/titlebar.c index f66d8dae..c2a90a55 100644 --- a/titlebar.c +++ b/titlebar.c @@ -57,7 +57,7 @@ client_getbytitlebarwin(xcb_window_t win) client_t *c; for(c = globalconf.clients; c; c = c->next) - if(c->titlebar && c->titlebar->sw && c->titlebar->sw->window == win) + if(c->titlebar && c->titlebar->sw.window == win) return c; return NULL; @@ -69,16 +69,16 @@ client_getbytitlebarwin(xcb_window_t win) void titlebar_draw(client_t *c) { - if(!c || !c->titlebar || !c->titlebar->sw || !c->titlebar->position) + if(!c || !c->titlebar || !c->titlebar->position) return; - widget_render(c->titlebar->widgets, &c->titlebar->sw->ctx, - c->titlebar->sw->gc, c->titlebar->sw->pixmap, + widget_render(c->titlebar->widgets, &c->titlebar->sw.ctx, + c->titlebar->sw.gc, c->titlebar->sw.pixmap, c->screen, c->titlebar->position, - c->titlebar->sw->geometry.x, c->titlebar->sw->geometry.y, + c->titlebar->sw.geometry.x, c->titlebar->sw.geometry.y, c->titlebar, AWESOME_TYPE_TITLEBAR); - simplewindow_refresh_pixmap(c->titlebar->sw); + simplewindow_refresh_pixmap(&c->titlebar->sw); c->titlebar->need_update = false; } @@ -106,36 +106,36 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res) return; case Top: if(c->titlebar->width) - width = MAX(1, MIN(c->titlebar->width, geometry.width - 2 * c->titlebar->border.width)); + width = MAX(1, MIN(c->titlebar->width, geometry.width - 2 * c->titlebar->sw.border.width)); else - width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->border.width); + width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width); switch(c->titlebar->align) { default: break; case AlignRight: - x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->border.width; + x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->sw.border.width; break; case AlignCenter: x_offset = (geometry.width - width) / 2; break; } res->x = geometry.x + x_offset; - res->y = geometry.y - c->titlebar->height - 2 * c->titlebar->border.width + c->border; + res->y = geometry.y - c->titlebar->height - 2 * c->titlebar->sw.border.width + c->border; res->width = width; res->height = c->titlebar->height; break; case Bottom: if(c->titlebar->width) - width = MAX(1, MIN(c->titlebar->width, geometry.width - 2 * c->titlebar->border.width)); + width = MAX(1, MIN(c->titlebar->width, geometry.width - 2 * c->titlebar->sw.border.width)); else - width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->border.width); + width = MAX(1, geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width); switch(c->titlebar->align) { default: break; case AlignRight: - x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->border.width; + x_offset = 2 * c->border + geometry.width - width - 2 * c->titlebar->sw.border.width; break; case AlignCenter: x_offset = (geometry.width - width) / 2; @@ -148,15 +148,15 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res) break; case Left: if(c->titlebar->width) - width = MAX(1, MIN(c->titlebar->width, geometry.height - 2 * c->titlebar->border.width)); + width = MAX(1, MIN(c->titlebar->width, geometry.height - 2 * c->titlebar->sw.border.width)); else - width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->border.width); + width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width); switch(c->titlebar->align) { default: break; case AlignRight: - y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->border.width; + y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->sw.border.width; break; case AlignCenter: y_offset = (geometry.height - width) / 2; @@ -169,15 +169,15 @@ titlebar_geometry_compute(client_t *c, area_t geometry, area_t *res) break; case Right: if(c->titlebar->width) - width = MAX(1, MIN(c->titlebar->width, geometry.height - 2 * c->titlebar->border.width)); + width = MAX(1, MIN(c->titlebar->width, geometry.height - 2 * c->titlebar->sw.border.width)); else - width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->border.width); + width = MAX(1, geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width); switch(c->titlebar->align) { default: break; case AlignRight: - y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->border.width; + y_offset = 2 * c->border + geometry.height - width - 2 * c->titlebar->sw.border.width; break; case AlignCenter: y_offset = (geometry.height - width) / 2; @@ -200,6 +200,10 @@ titlebar_init(client_t *c) int width = 0, height = 0; area_t geom; + /* already had a window? */ + if(c->titlebar->sw.window) + simplewindow_wipe(&c->titlebar->sw); + switch(c->titlebar->position) { default: @@ -208,30 +212,29 @@ titlebar_init(client_t *c) case Top: case Bottom: if(c->titlebar->width) - width = MIN(c->titlebar->width, c->geometry.width - 2 * c->titlebar->border.width); + width = MIN(c->titlebar->width, c->geometry.width - 2 * c->titlebar->sw.border.width); else - width = c->geometry.width + 2 * c->border - 2 * c->titlebar->border.width; + width = c->geometry.width + 2 * c->border - 2 * c->titlebar->sw.border.width; height = c->titlebar->height; break; case Left: case Right: if(c->titlebar->width) - height = MIN(c->titlebar->width, c->geometry.height - 2 * c->titlebar->border.width); + height = MIN(c->titlebar->width, c->geometry.height - 2 * c->titlebar->sw.border.width); else - height = c->geometry.height + 2 * c->border - 2 * c->titlebar->border.width; + height = c->geometry.height + 2 * c->border - 2 * c->titlebar->sw.border.width; width = c->titlebar->height; break; } titlebar_geometry_compute(c, c->geometry, &geom); - c->titlebar->sw = simplewindow_new(c->phys_screen, geom.x, geom.y, - geom.width, geom.height, - c->titlebar->border.width, - c->titlebar->position, - &c->titlebar->colors.fg, &c->titlebar->colors.bg); + simplewindow_init(&c->titlebar->sw, c->phys_screen, + geom.x, geom.y, geom.width, geom.height, + c->titlebar->border.width, c->titlebar->position, + &c->titlebar->colors.fg, &c->titlebar->colors.bg); - simplewindow_border_color_set(c->titlebar->sw, &c->titlebar->border.color); + simplewindow_border_color_set(&c->titlebar->sw, &c->titlebar->border.color); client_need_arrange(c); @@ -302,7 +305,7 @@ luaA_titlebar_newindex(lua_State *L) size_t len; titlebar_t **titlebar = luaA_checkudata(L, 1, "titlebar"); const char *buf, *attr = luaL_checklstring(L, 2, &len); - client_t *c = NULL, **newc; + client_t *c = NULL; int i; position_t position; @@ -310,18 +313,12 @@ luaA_titlebar_newindex(lua_State *L) { case A_TK_CLIENT: if(!lua_isnil(L, 3)) - newc = luaA_checkudata(L, 3, "client"); - else - newc = NULL; - - if(newc) { + client_t **newc = luaA_checkudata(L, 3, "client"); if((*newc)->titlebar) { - simplewindow_delete(&(*newc)->titlebar->sw); + xcb_unmap_window(globalconf.connection, (*newc)->titlebar->sw.window); titlebar_unref(&(*newc)->titlebar); - (*newc)->titlebar = NULL; - client_need_arrange(*newc); } /* Attach titlebar to client */ (*newc)->titlebar = *titlebar; @@ -329,16 +326,13 @@ luaA_titlebar_newindex(lua_State *L) titlebar_init(*newc); c = *newc; } - else + else if((c = client_getbytitlebar(*titlebar))) { - if((c = client_getbytitlebar(*titlebar))) - { - simplewindow_delete(&(*titlebar)->sw); - /* unref and NULL the ref */ - titlebar_unref(&c->titlebar); - c->titlebar = NULL; - client_need_arrange(c); - } + xcb_unmap_window(globalconf.connection, (*titlebar)->sw.window); + /* unref and NULL the ref */ + titlebar_unref(&c->titlebar); + c->titlebar = NULL; + client_need_arrange(c); } client_stack(); break; @@ -357,16 +351,13 @@ luaA_titlebar_newindex(lua_State *L) case A_TK_BORDER_COLOR: if((buf = luaL_checklstring(L, 3, &len))) if(xcolor_init_reply(xcolor_init_unchecked(&(*titlebar)->border.color, buf, len))) - if((*titlebar)->sw) - xcb_change_window_attributes(globalconf.connection, (*titlebar)->sw->window, - XCB_CW_BORDER_PIXEL, &(*titlebar)->border.color.pixel); + simplewindow_border_color_set(&c->titlebar->sw, &c->titlebar->border.color); return 0; case A_TK_FG: if((buf = luaL_checklstring(L, 3, &len))) if(xcolor_init_reply(xcolor_init_unchecked(&(*titlebar)->colors.fg, buf, len))) { - if((*titlebar)->sw) - (*titlebar)->sw->ctx.fg = (*titlebar)->colors.fg; + (*titlebar)->sw.ctx.fg = (*titlebar)->colors.fg; (*titlebar)->need_update = true; } return 0; @@ -374,8 +365,7 @@ luaA_titlebar_newindex(lua_State *L) if((buf = luaL_checklstring(L, 3, &len))) if(xcolor_init_reply(xcolor_init_unchecked(&(*titlebar)->colors.bg, buf, len))) { - if((*titlebar)->sw) - (*titlebar)->sw->ctx.bg = (*titlebar)->colors.bg; + (*titlebar)->sw.ctx.bg = (*titlebar)->colors.bg; (*titlebar)->need_update = true; } break; @@ -386,7 +376,6 @@ luaA_titlebar_newindex(lua_State *L) { (*titlebar)->position = position; c = client_getbytitlebar(*titlebar); - simplewindow_delete(&c->titlebar->sw); titlebar_init(c); } break; @@ -446,7 +435,7 @@ luaA_titlebar_index(lua_State *L) luaA_pushcolor(L, &(*titlebar)->colors.bg); break; case A_TK_POSITION: - lua_pushstring(L, position_tostr((*titlebar)->position)); + lua_pushstring(L, position_tostr((*titlebar)->position)); break; default: return 0; diff --git a/titlebar.h b/titlebar.h index 088aa479..54a1559c 100644 --- a/titlebar.h +++ b/titlebar.h @@ -42,25 +42,25 @@ int luaA_titlebar_userdata_new(lua_State *, titlebar_t *); static inline area_t titlebar_geometry_add(titlebar_t *t, int border, area_t geometry) { - if(t && t->sw) + if(t) switch(t->position) { case Top: - geometry.y -= t->sw->geometry.height + 2 * t->border.width - border; - geometry.height += t->sw->geometry.height + 2 * t->border.width - border; + geometry.y -= t->sw.geometry.height + 2 * t->sw.border.width - border; + geometry.height += t->sw.geometry.height + 2 * t->sw.border.width - border; geometry.width += 2 * border; break; case Bottom: - geometry.height += t->sw->geometry.height + 2 * t->border.width - border; + geometry.height += t->sw.geometry.height + 2 * t->sw.border.width - border; geometry.width += 2 * border; break; case Left: - geometry.x -= t->sw->geometry.width + 2 * t->border.width - border; - geometry.width += t->sw->geometry.width + 2 * t->border.width - border; + geometry.x -= t->sw.geometry.width + 2 * t->sw.border.width - border; + geometry.width += t->sw.geometry.width + 2 * t->sw.border.width - border; geometry.height += 2 * border; break; case Right: - geometry.width += t->sw->geometry.width + 2 * t->border.width - border; + geometry.width += t->sw.geometry.width + 2 * t->sw.border.width - border; geometry.height += 2 * border; break; default: @@ -84,25 +84,25 @@ titlebar_geometry_add(titlebar_t *t, int border, area_t geometry) static inline area_t titlebar_geometry_remove(titlebar_t *t, int border, area_t geometry) { - if(t && t->sw) + if(t) switch(t->position) { case Top: - geometry.y += t->sw->geometry.height + 2 * t->border.width - border; - geometry.height -= t->sw->geometry.height + 2 * t->border.width - border; + geometry.y += t->sw.geometry.height + 2 * t->sw.border.width - border; + geometry.height -= t->sw.geometry.height + 2 * t->sw.border.width - border; geometry.width -= 2 * border; break; case Bottom: - geometry.height -= t->sw->geometry.height + 2 * t->border.width - border; + geometry.height -= t->sw.geometry.height + 2 * t->sw.border.width - border; geometry.width -= 2 * border; break; case Left: - geometry.x += t->sw->geometry.width + 2 * t->border.width - border; - geometry.width -= t->sw->geometry.width + 2 * t->border.width - border; + geometry.x += t->sw.geometry.width + 2 * t->sw.border.width - border; + geometry.width -= t->sw.geometry.width + 2 * t->sw.border.width - border; geometry.height -= 2 * border; break; case Right: - geometry.width -= t->sw->geometry.width + 2 * t->border.width - border; + geometry.width -= t->sw.geometry.width + 2 * t->sw.border.width - border; geometry.height -= 2 * border; break; default: @@ -125,11 +125,11 @@ titlebar_update_geometry_floating(client_t *c) { area_t geom; - if(!c->titlebar || !c->titlebar->sw) + if(!c->titlebar) return; titlebar_geometry_compute(c, c->geometry, &geom); - simplewindow_moveresize(c->titlebar->sw, geom.x, geom.y, geom.width, geom.height); + simplewindow_moveresize(&c->titlebar->sw, geom.x, geom.y, geom.width, geom.height); c->titlebar->need_update = true; } @@ -142,11 +142,11 @@ titlebar_update_geometry_tiled(client_t *c, area_t geometry) { area_t geom; - if(!c->titlebar || !c->titlebar->sw) + if(!c->titlebar) return; titlebar_geometry_compute(c, geometry, &geom); - simplewindow_moveresize(c->titlebar->sw, geom.x, geom.y, geom.width, geom.height); + simplewindow_moveresize(&c->titlebar->sw, geom.x, geom.y, geom.width, geom.height); c->titlebar->need_update = true; } diff --git a/widgets/systray.c b/widgets/systray.c index 19d0dc95..27971f4c 100644 --- a/widgets/systray.c +++ b/widgets/systray.c @@ -54,7 +54,7 @@ systray_draw(draw_context_t *ctx, int i = 0; xembed_window_t *em; for(em = globalconf.embedded; em; em = em->next) - if(em->phys_screen == sb->sw->phys_screen) + if(em->phys_screen == sb->sw.ctx.phys_screen) i++; /** \todo use clas hints */ w->area.width = MIN(i * ctx->height, ctx->width - used); @@ -82,7 +82,7 @@ systray_draw(draw_context_t *ctx, /* set statusbar orientation */ /** \todo stop setting that property on each redraw */ xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, - globalconf.screens[sb->sw->phys_screen].systray.window, + globalconf.screens[sb->sw.ctx.phys_screen].systray.window, _NET_SYSTEM_TRAY_ORIENTATION, CARDINAL, 32, 1, &orient); return w->area.width;