diff --git a/client.c b/client.c index c8387ce3..47fe4e64 100644 --- a/client.c +++ b/client.c @@ -319,7 +319,6 @@ client_stack(void) uint32_t config_win_vals[2]; client_node_t *node; layer_t layer; - statusbar_t *sb; int screen; config_win_vals[0] = XCB_NONE; @@ -333,7 +332,9 @@ client_stack(void) /* then stack statusbar window */ for(screen = 0; screen < globalconf.nscreen; screen++) - for(sb = globalconf.screens[screen].statusbar; sb; sb = sb->next) + 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, @@ -342,6 +343,7 @@ client_stack(void) config_win_vals); config_win_vals[0] = sb->sw->window; } + } /* finally stack everything else */ for(layer = LAYER_FULLSCREEN - 1; layer >= LAYER_DESKTOP; layer--) @@ -833,8 +835,11 @@ client_unmanage(client_t *c) if(client_hasstrut(c)) /* All the statusbars (may) need to be repositioned */ for(int screen = 0; screen < globalconf.nscreen; screen++) - for(statusbar_t *s = globalconf.screens[screen].statusbar; s; s = s->next) + for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + { + statusbar_t *s = globalconf.screens[screen].statusbars.tab[i]; statusbar_position_update(s); + } /* set client as invalid */ c->invalid = true; diff --git a/event.c b/event.c index d105b5cb..fb307733 100644 --- a/event.c +++ b/event.c @@ -130,7 +130,6 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e const int nb_screen = xcb_setup_roots_length(xcb_get_setup(connection)); client_t *c; widget_node_t *w; - statusbar_t *statusbar; /* ev->state is * button status (8 bits) + modifiers status (8 bits) @@ -139,7 +138,9 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e ev->state &= 0x00ff; for(screen = 0; screen < globalconf.nscreen; screen++) - for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next) + 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)) { @@ -157,6 +158,7 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e /* return even if no widget match */ return 0; } + } if((c = client_getbytitlebarwin(ev->event))) { @@ -221,8 +223,11 @@ event_handle_configurerequest(void *data __attribute__ ((unused)), if(client_hasstrut(c)) /* All the statusbars (may) need to be repositioned */ for(int screen = 0; screen < globalconf.nscreen; screen++) - for(statusbar_t *s = globalconf.screens[screen].statusbar; s; s = s->next) + for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + { + statusbar_t *s = globalconf.screens[screen].statusbars.tab[i]; statusbar_position_update(s); + } } else { @@ -488,20 +493,22 @@ event_handle_expose(void *data __attribute__ ((unused)), xcb_connection_t *connection __attribute__ ((unused)), xcb_expose_event_t *ev) { - int screen; - statusbar_t *statusbar; - client_t *c; - if(!ev->count) { + int screen; + client_t *c; + for(screen = 0; screen < globalconf.nscreen; screen++) - for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next) + 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) { simplewindow_refresh_pixmap(statusbar->sw); return 0; } + } if((c = client_getbytitlebarwin(ev->window))) simplewindow_refresh_pixmap(c->titlebar->sw); diff --git a/ewmh.c b/ewmh.c index ca6f15e0..f15407b2 100644 --- a/ewmh.c +++ b/ewmh.c @@ -212,7 +212,7 @@ ewmh_update_workarea(int phys_screen) tag_array_t *tags = &globalconf.screens[phys_screen].tags; uint32_t *area = p_alloca(uint32_t, tags->len * 4); area_t geom = screen_area_get(phys_screen, - globalconf.screens[phys_screen].statusbar, + &globalconf.screens[phys_screen].statusbars, &globalconf.screens[phys_screen].padding, true); @@ -534,8 +534,11 @@ ewmh_client_strut_update(client_t *c, xcb_get_property_reply_t *strut_r) client_need_arrange(c); /* All the statusbars (may) need to be repositioned */ for(int screen = 0; screen < globalconf.nscreen; screen++) - for(statusbar_t *s = globalconf.screens[screen].statusbar; s; s = s->next) + for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + { + statusbar_t *s = globalconf.screens[screen].statusbars.tab[i]; statusbar_position_update(s); + } } } diff --git a/layouts/fair.c b/layouts/fair.c index ed0e0d5f..95550c3b 100644 --- a/layouts/fair.c +++ b/layouts/fair.c @@ -42,7 +42,7 @@ layout_fair(int screen, const orientation_t orientation) area_t geometry, area; area = screen_area_get(screen, - globalconf.screens[screen].statusbar, + &globalconf.screens[screen].statusbars, &globalconf.screens[screen].padding, true); diff --git a/layouts/fibonacci.c b/layouts/fibonacci.c index 3ffbf28e..cd783e73 100644 --- a/layouts/fibonacci.c +++ b/layouts/fibonacci.c @@ -33,7 +33,7 @@ layout_fibonacci(int screen, int shape) client_t *c; area_t geometry, area; geometry = area = screen_area_get(screen, - globalconf.screens[screen].statusbar, + &globalconf.screens[screen].statusbars, &globalconf.screens[screen].padding, true); diff --git a/layouts/magnifier.c b/layouts/magnifier.c index c10dd33f..8fecc969 100644 --- a/layouts/magnifier.c +++ b/layouts/magnifier.c @@ -35,7 +35,7 @@ layout_magnifier(int screen) client_t *c, *focus; tag_t **curtags = tags_get_current(screen); area_t geometry, area = screen_area_get(screen, - globalconf.screens[screen].statusbar, + &globalconf.screens[screen].statusbars, &globalconf.screens[screen].padding, true); diff --git a/layouts/max.c b/layouts/max.c index f7be2ebc..31e0787a 100644 --- a/layouts/max.c +++ b/layouts/max.c @@ -31,7 +31,7 @@ layout_max(int screen) { client_t *c; area_t area = screen_area_get(screen, - globalconf.screens[screen].statusbar, + &globalconf.screens[screen].statusbars, &globalconf.screens[screen].padding, true); diff --git a/layouts/tile.c b/layouts/tile.c index 80870062..96ebd128 100644 --- a/layouts/tile.c +++ b/layouts/tile.c @@ -43,7 +43,7 @@ _tile(int screen, const position_t position) tag_t **curtags = tags_get_current(screen); area = screen_area_get(screen, - globalconf.screens[screen].statusbar, + &globalconf.screens[screen].statusbars, &globalconf.screens[screen].padding, true); diff --git a/mouse.c b/mouse.c index 639f7b6d..c959d056 100644 --- a/mouse.c +++ b/mouse.c @@ -132,7 +132,7 @@ mouse_snapclient(client_t *c, area_t geometry, int snap) area_t snapper_geometry; area_t screen_geometry = screen_area_get(c->screen, - globalconf.screens[c->screen].statusbar, + &globalconf.screens[c->screen].statusbars, &globalconf.screens[c->screen].padding, false); @@ -750,7 +750,7 @@ mouse_client_resize_tiled(client_t *c) layout = tag->layout; area = screen_area_get(tag->screen, - globalconf.screens[tag->screen].statusbar, + &globalconf.screens[tag->screen].statusbars, &globalconf.screens[tag->screen].padding, true); @@ -854,7 +854,7 @@ mouse_client_resize_magnified(client_t *c, bool infobox) root = xutil_screen_get(globalconf.connection, c->phys_screen)->root; area = screen_area_get(tag->screen, - globalconf.screens[tag->screen].statusbar, + &globalconf.screens[tag->screen].statusbars, &globalconf.screens[tag->screen].padding, true); diff --git a/screen.c b/screen.c index 7f7b7a6f..7daebb67 100644 --- a/screen.c +++ b/screen.c @@ -156,17 +156,16 @@ screen_getbycoord(int screen, int x, int y) /** Get screens info. * \param screen Screen number. - * \param statusbar Statusbar list to remove. + * \param statusbars Statusbar list to remove. * \param padding Padding. * \param strut Honor windows strut. * \return The screen area. */ area_t -screen_area_get(int screen, statusbar_t *statusbar, +screen_area_get(int screen, statusbar_array_t *statusbars, padding_t *padding, bool strut) { area_t area = globalconf.screens[screen].geometry; - statusbar_t *sb; uint16_t top = 0, bottom = 0, left = 0, right = 0; /* make padding corrections */ @@ -216,23 +215,27 @@ screen_area_get(int screen, statusbar_t *statusbar, } - for(sb = statusbar; sb; sb = sb->next) - switch(sb->position) + if(statusbars) + for(int i = 0; i < statusbars->len; i++) { - case Top: - 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); - break; - case Left: - 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); - break; - default: - break; + statusbar_t *sb = statusbars->tab[i]; + switch(sb->position) + { + case Top: + 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); + break; + case Left: + 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); + break; + default: + break; + } } area.x += left; @@ -245,25 +248,26 @@ screen_area_get(int screen, statusbar_t *statusbar, /** Get display info. * \param phys_screen Physical screen number. - * \param statusbar The statusbars. + * \param statusbars The statusbars. * \param padding Padding. * \return The display area. */ area_t -display_area_get(int phys_screen, statusbar_t *statusbar, padding_t *padding) +display_area_get(int phys_screen, statusbar_array_t *statusbars, padding_t *padding) { - area_t area = { 0, 0, 0, 0 }; - statusbar_t *sb; xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen); + area_t area = { .x = 0, + .y = 0, + .width = s->width_in_pixels, + .height = s->height_in_pixels }; - area.width = s->width_in_pixels; - area.height = s->height_in_pixels; - - for(sb = statusbar; sb; sb = sb->next) - { - area.y += sb->position == Top ? sb->height : 0; - area.height -= (sb->position == Top || sb->position == Bottom) ? sb->height : 0; - } + if(statusbars) + for(int i = 0; i < statusbars->len; i++) + { + statusbar_t *sb = statusbars->tab[i]; + area.y += sb->position == Top ? sb->height : 0; + area.height -= (sb->position == Top || sb->position == Bottom) ? sb->height : 0; + } /* make padding corrections */ if(padding) @@ -508,7 +512,7 @@ luaA_screen_index(lua_State *L) lua_setfield(L, -2, "height"); break; case A_TK_WORKAREA: - g = screen_area_get(s->index, s->statusbar, &s->padding, true); + g = screen_area_get(s->index, &s->statusbars, &s->padding, true); lua_newtable(L); lua_pushnumber(L, g.x); lua_setfield(L, -2, "x"); @@ -544,8 +548,6 @@ luaA_screen_padding(lua_State *L) if(lua_gettop(L) == 2) { - statusbar_t *sb; - luaA_checktable(L, 2); s->padding.right = luaA_getopt_number(L, 2, "right", 0); @@ -556,8 +558,8 @@ luaA_screen_padding(lua_State *L) s->need_arrange = true; /* All the statusbar repositioned */ - for(sb = s->statusbar; sb; sb = sb->next) - statusbar_position_update(sb); + for(int i = 0; i < s->statusbars.len; i++) + statusbar_position_update(s->statusbars.tab[i]); ewmh_update_workarea(screen_virttophys(s->index)); } diff --git a/screen.h b/screen.h index 39154e24..d93ce5e6 100644 --- a/screen.h +++ b/screen.h @@ -28,8 +28,8 @@ void screen_scan(void); int screen_getbycoord(int, int, int); -area_t screen_area_get(int, statusbar_t *, padding_t *, bool); -area_t display_area_get(int, statusbar_t *, padding_t *); +area_t screen_area_get(int, statusbar_array_t *, padding_t *, bool); +area_t display_area_get(int, statusbar_array_t *, padding_t *); int screen_virttophys(int); void screen_client_moveto(client_t *, int, bool, bool); diff --git a/statusbar.c b/statusbar.c index 11ce0e55..d724e3fb 100644 --- a/statusbar.c +++ b/statusbar.c @@ -236,11 +236,13 @@ statusbar_draw(statusbar_t *statusbar) statusbar_t * statusbar_getbywin(xcb_window_t w) { - statusbar_t *s; - for(int i = 0; i < globalconf.nscreen; i++) - for(s = globalconf.screens[i].statusbar; s; s = s->next) + for(int screen = 0; screen < globalconf.nscreen; screen++) + 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) return s; + } return NULL; } @@ -249,13 +251,13 @@ statusbar_getbywin(xcb_window_t w) void statusbar_refresh(void) { - int screen; - statusbar_t *statusbar; - - for(screen = 0; screen < globalconf.nscreen; screen++) - for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next) - if(statusbar->need_update) - statusbar_draw(statusbar); + for(int screen = 0; screen < globalconf.nscreen; screen++) + for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + { + statusbar_t *s = globalconf.screens[screen].statusbars.tab[i]; + if(s->need_update) + statusbar_draw(s); + } } static void @@ -278,7 +280,6 @@ statusbar_clean(statusbar_t *statusbar) void statusbar_position_update(statusbar_t *statusbar) { - statusbar_t *sb; area_t area, wingeometry; xcb_pixmap_t dw; xcb_screen_t *s = NULL; @@ -291,8 +292,9 @@ statusbar_position_update(statusbar_t *statusbar) &globalconf.screens[statusbar->screen].padding, true); /* Top and Bottom statusbar_t have prio */ - for(sb = globalconf.screens[statusbar->screen].statusbar; sb; sb = sb->next) + for(int i = 0; i < globalconf.screens[statusbar->screen].statusbars.len; i++) { + statusbar_t *sb = globalconf.screens[statusbar->screen].statusbars.tab[i]; /* Ignore every statusbar after me that is in the same position */ if(statusbar == sb) { @@ -656,7 +658,12 @@ statusbar_remove(statusbar_t *statusbar) /* restore position */ statusbar->position = p; - statusbar_list_detach(&globalconf.screens[statusbar->screen].statusbar, statusbar); + for(int i = 0; i < globalconf.screens[statusbar->screen].statusbars.len; i++) + if(globalconf.screens[statusbar->screen].statusbars.tab[i] == statusbar) + { + statusbar_array_take(&globalconf.screens[statusbar->screen].statusbars, i); + break; + } globalconf.screens[statusbar->screen].need_arrange = true; statusbar->screen = SCREEN_UNDEF; statusbar_unref(&statusbar); @@ -671,7 +678,7 @@ static int luaA_statusbar_newindex(lua_State *L) { size_t len; - statusbar_t *s, **statusbar = luaA_checkudata(L, 1, "statusbar"); + statusbar_t **statusbar = luaA_checkudata(L, 1, "statusbar"); const char *buf, *attr = luaL_checklstring(L, 2, &len); position_t p; int screen; @@ -692,21 +699,27 @@ luaA_statusbar_newindex(lua_State *L) (*statusbar)->screen + 1); /* Check for uniq name and id. */ - for(s = globalconf.screens[screen].statusbar; s; s = s->next) + for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + { + statusbar_t *s = globalconf.screens[screen].statusbars.tab[i]; if(!a_strcmp(s->name, (*statusbar)->name)) luaL_error(L, "a statusbar with that name is already on screen %d\n", screen + 1); + } statusbar_remove(*statusbar); (*statusbar)->screen = screen; - statusbar_list_append(&globalconf.screens[screen].statusbar, *statusbar); + statusbar_array_append(&globalconf.screens[screen].statusbars, *statusbar); statusbar_ref(statusbar); /* All the other statusbar and ourselves need to be repositioned */ - for(s = globalconf.screens[screen].statusbar; s; s = s->next) + for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + { + statusbar_t *s = globalconf.screens[screen].statusbars.tab[i]; statusbar_position_update(s); + } ewmh_update_workarea(screen_virttophys(screen)); } @@ -743,8 +756,11 @@ luaA_statusbar_newindex(lua_State *L) (*statusbar)->position = p; if((*statusbar)->screen != SCREEN_UNDEF) { - for(s = globalconf.screens[(*statusbar)->screen].statusbar; s; s = s->next) + for(int i = 0; i < globalconf.screens[(*statusbar)->screen].statusbars.len; i++) + { + statusbar_t *s = globalconf.screens[(*statusbar)->screen].statusbars.tab[i]; statusbar_position_update(s); + } ewmh_update_workarea(screen_virttophys((*statusbar)->screen)); } } diff --git a/statusbar.h b/statusbar.h index c158a19b..f7969d98 100644 --- a/statusbar.h +++ b/statusbar.h @@ -42,7 +42,7 @@ void statusbar_position_update(statusbar_t *); int luaA_statusbar_userdata_new(lua_State *, statusbar_t *); DO_RCNT(statusbar_t, statusbar, statusbar_delete) -DO_SLIST(statusbar_t, statusbar, statusbar_delete) +ARRAY_FUNCS(statusbar_t *, statusbar, statusbar_unref) #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/structs.h b/structs.h index a56029aa..9bcd3153 100644 --- a/structs.h +++ b/structs.h @@ -245,9 +245,8 @@ struct statusbar_t } colors; /** Widget the mouse is over */ widget_node_t *mouse_over; - /** Next and previous statusbars */ - statusbar_t *prev, *next; }; +ARRAY_TYPE(statusbar_t *, statusbar) /* Strut */ typedef struct @@ -401,8 +400,8 @@ typedef struct bool need_arrange; /** Tag list */ tag_array_t tags; - /** Status bar */ - statusbar_t *statusbar; + /** Statusbars */ + statusbar_array_t statusbars; /** Padding */ padding_t padding; /** Window that contains the systray */ diff --git a/widget.c b/widget.c index 4b1ab872..31c981b3 100644 --- a/widget.c +++ b/widget.c @@ -210,18 +210,18 @@ widget_common_new(widget_t *widget) void widget_invalidate_cache(int screen, int flags) { - statusbar_t *statusbar; - widget_node_t *widget; + for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + { + statusbar_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; + widget_node_t *widget; - for(statusbar = globalconf.screens[screen].statusbar; - statusbar; - statusbar = statusbar->next) for(widget = statusbar->widgets; widget; widget = widget->next) if(widget->widget->cache_flags & flags) { statusbar->need_update = true; break; } + } } /** Set a statusbar needs update because it has widget, or redraw a titlebar. @@ -232,14 +232,14 @@ void widget_invalidate_bywidget(widget_t *widget) { int screen; - statusbar_t *statusbar; widget_node_t *witer; client_t *c; for(screen = 0; screen < globalconf.nscreen; screen++) - for(statusbar = globalconf.screens[screen].statusbar; - statusbar; - statusbar = statusbar->next) + for(int i = 0; i < globalconf.screens[screen].statusbars.len; i++) + { + statusbar_t *statusbar = globalconf.screens[screen].statusbars.tab[i]; + if(!statusbar->need_update) for(witer = statusbar->widgets; witer; witer = witer->next) if(witer->widget == widget) @@ -247,6 +247,7 @@ widget_invalidate_bywidget(widget_t *widget) statusbar->need_update = true; break; } + } for(c = globalconf.clients; c; c = c->next) if(c->titlebar && !c->titlebar->need_update)