From be752cc81c68b47af5a6645a2405e3be5d3ee6af Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Thu, 9 Apr 2009 17:17:10 +0200 Subject: [PATCH] client: change global linked list to an array Signed-off-by: Julien Danjou --- awesome.c | 7 +++--- client.c | 73 ++++++++++++++++++++++++++++++++++++++++-------------- client.h | 2 -- event.c | 3 ++- ewmh.c | 17 ++++++------- layout.c | 8 +++--- screen.c | 8 +++--- structs.h | 4 +-- titlebar.c | 16 +++++------- wibox.c | 15 ++++++++--- widget.c | 5 +++- 11 files changed, 98 insertions(+), 60 deletions(-) diff --git a/awesome.c b/awesome.c index e151e715..f6089c5a 100644 --- a/awesome.c +++ b/awesome.c @@ -59,7 +59,6 @@ typedef struct void awesome_atexit(void) { - client_t *c; int screen_nbr, nscreens; a_dbus_cleanup(); @@ -81,10 +80,10 @@ awesome_atexit(void) systray_cleanup(screen_nbr); /* remap all clients since some WM won't handle them otherwise */ - for(c = globalconf.clients; c; c = c->next) + foreach(c, globalconf.clients) { - client_unban(c); - titlebar_client_detach(c); + client_unban(*c); + titlebar_client_detach(*c); } xcb_flush(globalconf.connection); diff --git a/client.c b/client.c index 03b2f42d..ba796070 100644 --- a/client.c +++ b/client.c @@ -131,9 +131,10 @@ client_getcontent(client_t *c) client_t * client_getbywin(xcb_window_t w) { - client_t *c; - for(c = globalconf.clients; c && c->win != w; c = c->next); - return c; + for(int i = 0; i < globalconf.clients.len; i++) + if(globalconf.clients.tab[i]->win == w) + return globalconf.clients.tab[i]; + return NULL; } /** Record that a client lost focus. @@ -240,8 +241,13 @@ void client_focus(client_t *c) { /* We have to set focus on first client */ - if(!c && !(c = globalconf.clients)) - return; + if(!c) + { + if(globalconf.clients.len) + c = globalconf.clients.tab[0]; + else + return; + } if(!client_maybevisible(c, c->screen)) return; @@ -475,7 +481,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, screen_client_moveto(c, screen, false, true); /* Push client in client list */ - client_list_push(&globalconf.clients, client_ref(&c)); + client_array_push(&globalconf.clients, client_ref(&c)); /* Push client in stack */ client_raise(c); @@ -711,13 +717,15 @@ client_resize(client_t *c, area_t geometry, bool hints) void client_update_strut_positions(int screen) { - client_t *c; area_t allowed_area, geom; /* Ignore all struts for starters. */ - for(c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) + { + client_t *c = *_c; if(c->screen == screen && client_hasstrut(c)) c->ignore_strut = true; + } /* Rationale: * Top and bottom panels are common, so they take precendence. @@ -725,8 +733,9 @@ client_update_strut_positions(int screen) */ /* WINDOW_TYPE_DOCK: top + bottom. */ - for(c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) { + client_t *c = *_c; if(c->screen != screen || !client_hasstrut(c) || c->type != WINDOW_TYPE_DOCK) continue; @@ -767,8 +776,9 @@ client_update_strut_positions(int screen) } /* WINDOW_TYPE_DOCK: left + right. */ - for(c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) { + client_t *c = *_c; if(c->screen != screen || !client_hasstrut(c) || c->type != WINDOW_TYPE_DOCK) continue; @@ -809,8 +819,9 @@ client_update_strut_positions(int screen) } /* not WINDOW_TYPE_DOCK: top + bottom. */ - for(c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) { + client_t *c = *_c; if(c->screen != screen || !client_hasstrut(c) || c->type == WINDOW_TYPE_DOCK) continue; @@ -851,8 +862,9 @@ client_update_strut_positions(int screen) } /* not WINDOW_TYPE_DOCK: left + right. */ - for(c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) { + client_t *c = *_c; if(c->screen != screen || !client_hasstrut(c) || c->type == WINDOW_TYPE_DOCK) continue; @@ -1180,15 +1192,25 @@ client_unmanage(client_t *c) tag_array_t *tags = &globalconf.screens[c->screen].tags; /* Reset transient_for attributes of widows that maybe refering to us */ - for(client_t *tc = globalconf.clients; tc; tc = tc->next) + foreach(_tc, globalconf.clients) + { + client_t *tc = *_tc; if(tc->transient_for == c) tc->transient_for = NULL; + } if(globalconf.screens[c->phys_screen].client_focus == c) client_unfocus(c); /* remove client everywhere */ - client_list_detach(&globalconf.clients, c); + client_t **_c = NULL; + foreach(iter, globalconf.clients) + if(c == *iter) + { + _c = iter; + break; + } + client_array_remove(&globalconf.clients, _c); stack_client_delete(c); for(int i = 0; i < tags->len; i++) untag_client(c, tags->tab[i]); @@ -1267,27 +1289,30 @@ static int luaA_client_get(lua_State *L) { int i = 1, screen; - client_t *c; screen = luaL_optnumber(L, 1, 0) - 1; lua_newtable(L); if(screen == SCREEN_UNDEF) - for(c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) { + client_t *c = *_c; luaA_client_userdata_new(globalconf.L, c); lua_rawseti(L, -2, i++); } else { luaA_checkscreen(screen); - for(c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) + { + client_t *c = *_c; if(c->screen == screen) { luaA_client_userdata_new(globalconf.L, c); lua_rawseti(L, -2, i++); } + } } return 1; @@ -1373,7 +1398,19 @@ luaA_client_swap(lua_State *L) if(*c != *swap) { - client_list_swap(&globalconf.clients, *swap, *c); + /* makes c and swap points on array address, not Lua */ + foreach(iter, globalconf.clients) + if(*c == *iter) + c = iter; + else if(*swap == *iter) + swap = iter; + + /* swap entry in the array */ + client_t *tmp; + tmp = *c; + *c = *swap; + *swap = tmp; + client_need_arrange(*c); client_need_arrange(*swap); diff --git a/client.h b/client.h index 0d28753a..3cf9ca95 100644 --- a/client.h +++ b/client.h @@ -84,8 +84,6 @@ int luaA_client_newindex(lua_State *); int luaA_client_userdata_new(lua_State *, client_t *); -DO_SLIST(client_t, client, client_unref) - static inline void client_stack(void) { diff --git a/event.c b/event.c index 8c82dfda..809cbca9 100644 --- a/event.c +++ b/event.c @@ -878,8 +878,9 @@ event_handle_mappingnotify(void *data, window_grabkeys(s->root, &globalconf.keys); } - for(client_t *c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) { + client_t *c = *_c; xcb_ungrab_key(connection, XCB_GRAB_ANY, c->win, XCB_BUTTON_MASK_ANY); window_grabkeys(c->win, &c->keys); } diff --git a/ewmh.c b/ewmh.c index 892a5e26..7d8b9318 100644 --- a/ewmh.c +++ b/ewmh.c @@ -143,18 +143,15 @@ ewmh_init(int phys_screen) void ewmh_update_net_client_list(int phys_screen) { - xcb_window_t *wins; - client_t *c; + xcb_window_t *wins = p_alloca(xcb_window_t, globalconf.clients.len); + int n = 0; - - for(c = globalconf.clients; c; c = c->next) - n++; - - wins = p_alloca(xcb_window_t, n); - - for(n = 0, c = globalconf.clients; c; c = c->next, n++) + foreach(_c, globalconf.clients) + { + client_t *c = *_c; if(c->phys_screen == phys_screen) - wins[n] = c->win; + wins[n++] = c->win; + } xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, xutil_screen_get(globalconf.connection, phys_screen)->root, diff --git a/layout.c b/layout.c index 4ffa69d9..87dca76a 100644 --- a/layout.c +++ b/layout.c @@ -31,11 +31,11 @@ static void arrange(int screen) { - client_t *c; uint32_t select_input_val[] = { CLIENT_SELECT_INPUT_EVENT_MASK & ~(XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW) }; - for(c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) { + client_t *c = *_c; /* Bob Marley v2: * While we arrange, we do not want to receive EnterNotify or LeaveNotify * events, or we would get spurious events. */ @@ -74,9 +74,9 @@ arrange(int screen) /* Now, we want to receive EnterNotify and LeaveNotify events back. */ select_input_val[0] = CLIENT_SELECT_INPUT_EVENT_MASK; - for(c = globalconf.clients; c; c = c->next) + foreach(c, globalconf.clients) xcb_change_window_attributes(globalconf.connection, - c->win, + (*c)->win, XCB_CW_EVENT_MASK, select_input_val); } diff --git a/screen.c b/screen.c index 0b5cb3d9..f648bd2a 100644 --- a/screen.c +++ b/screen.c @@ -178,9 +178,9 @@ screen_area_get(int screen, wibox_array_t *wiboxes, /* Some clients request more space than their size, because another window of the same app already has some space. */ /* So we clamp the strut size. */ if(strut) - { - client_t *c; - for(c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) + { + client_t *c = *_c; if(client_isvisible(c, screen) && !c->ignore_strut) { if(c->strut.top_start_x || c->strut.top_end_x) @@ -212,7 +212,7 @@ screen_area_get(int screen, wibox_array_t *wiboxes, right += c->geometry.width; } } - } + } /* swindow geometry includes borders. */ if(wiboxes) diff --git a/structs.h b/structs.h index a7d61a09..fc55ec12 100644 --- a/structs.h +++ b/structs.h @@ -242,8 +242,6 @@ struct client_t bool size_hints_honor; /** Window it is transient for */ client_t *transient_for; - /** Next and previous clients */ - client_t *prev, *next; }; ARRAY_TYPE(client_t *, client) @@ -322,7 +320,7 @@ struct awesome_t /** Check for XTest extension */ bool have_xtest; /** Clients list */ - client_t *clients; + client_array_t clients; /** Embedded windows */ xembed_window_array_t embedded; /** Path to config file */ diff --git a/titlebar.c b/titlebar.c index a9f2a319..afae07b6 100644 --- a/titlebar.c +++ b/titlebar.c @@ -34,11 +34,9 @@ client_t * client_getbytitlebar(wibox_t *titlebar) { - client_t *c; - - for(c = globalconf.clients; c; c = c->next) - if(c->titlebar == titlebar) - return c; + foreach(c, globalconf.clients) + if((*c)->titlebar == titlebar) + return *c; return NULL; } @@ -50,11 +48,9 @@ client_getbytitlebar(wibox_t *titlebar) client_t * client_getbytitlebarwin(xcb_window_t win) { - client_t *c; - - for(c = globalconf.clients; c; c = c->next) - if(c->titlebar && c->titlebar->sw.window == win) - return c; + foreach(c, globalconf.clients) + if((*c)->titlebar && (*c)->titlebar->sw.window == win) + return *c; return NULL; } diff --git a/wibox.c b/wibox.c index 94b9ab3f..59e51a98 100644 --- a/wibox.c +++ b/wibox.c @@ -504,9 +504,12 @@ wibox_getbywin(xcb_window_t w) return s; } - for(client_t *c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) + { + client_t *c = *_c; if(c->titlebar && c->titlebar->sw.window == w) return c->titlebar; + } return NULL; } @@ -541,9 +544,12 @@ wibox_refresh(void) wibox_draw(s); } - for(client_t *c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) + { + client_t *c = *_c; if(c->titlebar && c->titlebar->need_update) wibox_draw(c->titlebar); + } } /** Reposition all wiboxes. @@ -797,13 +803,16 @@ luaA_wibox_invalidate_byitem(lua_State *L, const void *item) } - for(client_t *c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) + { + client_t *c = *_c; if(c->titlebar && luaA_wibox_hasitem(L, c->titlebar, item)) { /* recompute widget node list */ wibox_widgets_table_build(L, c->titlebar); lua_pop(L, 1); /* remove widgets table */ } + } } /** Wibox object. diff --git a/widget.c b/widget.c index d6f31185..e49cde8f 100644 --- a/widget.c +++ b/widget.c @@ -325,7 +325,9 @@ widget_invalidate_bywidget(widget_t *widget) } } - for(client_t *c = globalconf.clients; c; c = c->next) + foreach(_c, globalconf.clients) + { + client_t *c = *_c; if(c->titlebar && !c->titlebar->need_update) for(int j = 0; j < c->titlebar->widgets.len; j++) if(c->titlebar->widgets.tab[j].widget == widget) @@ -333,6 +335,7 @@ widget_invalidate_bywidget(widget_t *widget) c->titlebar->need_update = true; break; } + } } /** Create a new widget.