diff --git a/include/data.h b/include/data.h index 9d5b841e..12c23554 100644 --- a/include/data.h +++ b/include/data.h @@ -232,6 +232,8 @@ struct Workspace { * opened, for example) have the same size as always */ float *width_factor; float *height_factor; + + TAILQ_ENTRY(Workspace) workspaces; }; /** @@ -492,7 +494,7 @@ struct Screen { int num; /** Current workspace selected on this virtual screen */ - int current_workspace; + Workspace *current_workspace; /** x, y, width, height */ Rect rect; diff --git a/include/table.h b/include/table.h index 05f543d6..18561474 100644 --- a/include/table.h +++ b/include/table.h @@ -21,8 +21,8 @@ #define CUR_CELL (CUR_TABLE[current_col][current_row]) extern Workspace *c_ws; -extern Workspace *workspaces; -extern int num_workspaces; +extern TAILQ_HEAD(workspaces_head, Workspace) *workspaces; +//extern int num_workspaces; extern int current_col; extern int current_row; diff --git a/src/cfgparse.y b/src/cfgparse.y index 26e00af9..a1c7aeef 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -112,7 +112,7 @@ void parse_file(const char *f) { /* Then, allocate a new buffer and copy the file over to the new one, * but replace occurences of our variables */ char *walk = buf, *destwalk; - char *new = smalloc((stbuf.st_size + extra_bytes) * sizeof(char)); + char *new = smalloc((stbuf.st_size + extra_bytes + 1) * sizeof(char)); destwalk = new; while (walk < (buf + stbuf.st_size)) { /* Find the next variable */ @@ -335,11 +335,12 @@ new_container: * Thus, the user very likely awaits the default container mode * to trigger in this case, regardless of where it is inside * his configuration file. */ - for (int c = 0; c < num_workspaces; c++) { - if (workspaces[c].table == NULL) + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) { + if (ws->table == NULL) continue; switch_layout_mode(global_conn, - workspaces[c].table[0][0], + ws->table[0][0], config.container_mode); } } @@ -350,10 +351,11 @@ new_container: config.container_stack_limit_value = $7; /* See the comment above */ - for (int c = 0; c < num_workspaces; c++) { - if (workspaces[c].table == NULL) + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) { + if (ws->table == NULL) continue; - Container *con = workspaces[c].table[0][0]; + Container *con = ws->table[0][0]; con->stack_limit = config.container_stack_limit; con->stack_limit_value = config.container_stack_limit_value; } diff --git a/src/click.c b/src/click.c index d9aff341..0aacf450 100644 --- a/src/click.c +++ b/src/click.c @@ -128,29 +128,40 @@ static bool button_press_bar(xcb_connection_t *conn, xcb_button_press_event_t *e /* Check if the button was one of button4 or button5 (scroll up / scroll down) */ if (event->detail == XCB_BUTTON_INDEX_4 || event->detail == XCB_BUTTON_INDEX_5) { - int add = (event->detail == XCB_BUTTON_INDEX_4 ? -1 : 1); - for (int i = c_ws->num + add; (i >= 0) && (i < num_workspaces); i += add) - if (workspaces[i].screen == screen) { - workspace_show(conn, i+1); - return true; + Workspace *ws = c_ws; + if (event->detail == XCB_BUTTON_INDEX_5) { + while ((ws = TAILQ_NEXT(ws, workspaces)) != TAILQ_END(workspaces_head)) { + if (ws->screen == screen) { + workspace_show(conn, ws->num + 1); + return true; + } } + } else { + while ((ws = TAILQ_PREV(ws, workspaces_head, workspaces)) != TAILQ_END(workspaces)) { + if (ws->screen == screen) { + workspace_show(conn, ws->num + 1); + return true; + } + } + } return true; } int drawn = 0; /* Because workspaces can be on different screens, we need to loop through all of them and decide to count it based on its ->screen */ - for (int i = 0; i < num_workspaces; i++) { - if (workspaces[i].screen != screen) + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) { + if (ws->screen != screen) continue; LOG("Checking if click was on workspace %d with drawn = %d, tw = %d\n", - i, drawn, workspaces[i].text_width); + ws->num, drawn, ws->text_width); if (event->event_x > (drawn + 1) && - event->event_x <= (drawn + 1 + workspaces[i].text_width + 5 + 5)) { - workspace_show(conn, i+1); + event->event_x <= (drawn + 1 + ws->text_width + 5 + 5)) { + workspace_show(conn, ws->num + 1); return true; } - drawn += workspaces[i].text_width + 5 + 5 + 2; + drawn += ws->text_width + 5 + 5 + 2; } return true; } diff --git a/src/client.c b/src/client.c index bd5be673..6cd11d9d 100644 --- a/src/client.c +++ b/src/client.c @@ -332,8 +332,9 @@ void client_mark(xcb_connection_t *conn, Client *client, const char *mark) { /* Make sure no other client has this mark set */ Client *current; - for (int c = 0; c < 10; c++) - SLIST_FOREACH(current, &(workspaces[c].focus_stack), focus_clients) { + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) + SLIST_FOREACH(current, &(ws->focus_stack), focus_clients) { if (current == client || current->mark == NULL || strcmp(current->mark, mark) != 0) diff --git a/src/commands.c b/src/commands.c index a43085c6..c566ffe1 100644 --- a/src/commands.c +++ b/src/commands.c @@ -63,8 +63,9 @@ static void jump_to_mark(xcb_connection_t *conn, const char *mark) { Client *current; LOG("Jumping to \"%s\"\n", mark); - for (int c = 0; c < num_workspaces; c++) - SLIST_FOREACH(current, &(workspaces[c].focus_stack), focus_clients) { + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) + SLIST_FOREACH(current, &(ws->focus_stack), focus_clients) { if (current->mark == NULL || strcmp(current->mark, mark) != 0) continue; @@ -130,7 +131,7 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t } LOG("Switching to ws %d\n", target->current_workspace + 1); - workspace_show(conn, target->current_workspace + 1); + workspace_show(conn, target->current_workspace->num + 1); return; } @@ -165,7 +166,7 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t /* No screen found? Then wrap */ screen = get_screen_most((direction == D_UP ? D_DOWN : D_UP), container->workspace->screen); } - t_ws = workspace_get(screen->current_workspace); + t_ws = screen->current_workspace; new_row = (direction == D_UP ? (t_ws->rows - 1) : 0); } @@ -207,7 +208,7 @@ static void focus_thing(xcb_connection_t *conn, direction_t direction, thing_t t LOG("Wrapping screen around horizontally\n"); screen = get_screen_most((direction == D_LEFT ? D_RIGHT : D_LEFT), container->workspace->screen); } - t_ws = workspace_get(screen->current_workspace); + t_ws = screen->current_workspace; new_col = (direction == D_LEFT ? (t_ws->cols - 1) : 0); } @@ -784,31 +785,25 @@ static char **append_argument(char **original, char *argument) { * */ static void next_previous_workspace(xcb_connection_t *conn, int direction) { - Workspace *t_ws; - int i; + Workspace *ws = c_ws; if (direction == 'n') { - /* If we are on the last workspace, we cannot go any further */ - if (c_ws->num == (num_workspaces-1)) - return; + while ((ws = TAILQ_NEXT(ws, workspaces)) != TAILQ_END(workspaces_head)) { + if (ws->screen == NULL) + continue; - for (i = c_ws->num + 1; i < num_workspaces; i++) { - t_ws = &(workspaces[i]); - if (t_ws->screen != NULL) - break; + workspace_show(conn, ws->num + 1); + return; } } else if (direction == 'p') { - if (c_ws->num == 0) + while ((ws = TAILQ_PREV(ws, workspaces_head, workspaces)) != TAILQ_END(workspaces)) { + if (ws->screen == NULL) + continue; + + workspace_show(conn, ws->num + 1); return; - for (i = c_ws->num - 1; i >= 0 ; i--) { - t_ws = &(workspaces[i]); - if (t_ws->screen != NULL) - break; } } - - if (t_ws->screen != NULL) - workspace_show(conn, i+1); } static void parse_resize_command(xcb_connection_t *conn, Client *last_focused, const char *command) { diff --git a/src/config.c b/src/config.c index 52cf55b2..0e94afce 100644 --- a/src/config.c +++ b/src/config.c @@ -183,6 +183,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath, while (!TAILQ_EMPTY(bindings)) { bind = TAILQ_FIRST(bindings); TAILQ_REMOVE(bindings, bind, bindings); + FREE(bind->translated_to); FREE(bind->command); FREE(bind); } @@ -481,7 +482,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath, LOG("setting name to \"%s\"\n", name); if (*name != '\0') - workspace_set_name(&(workspaces[ws_num - 1]), name); + workspace_set_name(workspace_get(ws_num - 1), name); free(ws_str); continue; } @@ -590,8 +591,8 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath, REQUIRED_OPTION(font); /* Set an empty name for every workspace which got no name */ - for (int i = 0; i < num_workspaces; i++) { - Workspace *ws = &(workspaces[i]); + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) { if (ws->name != NULL) { /* If the font was not specified when the workspace name * was loaded, we need to predict the text width now */ @@ -601,7 +602,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath, continue; } - workspace_set_name(&(workspaces[i]), NULL); + workspace_set_name(ws, NULL); } return; diff --git a/src/handlers.c b/src/handlers.c index cf28b906..863aed48 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -170,7 +170,7 @@ static void check_crossing_screen_boundary(uint32_t x, uint32_t y) { c_ws->current_row = current_row; c_ws->current_col = current_col; - c_ws = &workspaces[screen->current_workspace]; + c_ws = screen->current_workspace; current_row = c_ws->current_row; current_col = c_ws->current_col; LOG("We're now on virtual screen number %d\n", screen->num); @@ -486,7 +486,7 @@ int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_noti /* If this workspace is currently active, we don’t delete it */ i3Screen *screen; TAILQ_FOREACH(screen, virtual_screens, screens) - if (screen->current_workspace == client->workspace->num) { + if (screen->current_workspace == client->workspace) { workspace_active = true; workspace_empty = false; break; @@ -908,7 +908,7 @@ int handle_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t * the workspace bar */ if (!workspace_is_visible(client->workspace)) { i3Screen *screen = client->workspace->screen; - render_workspace(conn, screen, &(workspaces[screen->current_workspace])); + render_workspace(conn, screen, screen->current_workspace); xcb_flush(conn); } diff --git a/src/layout.c b/src/layout.c index 59309c9d..f04b6de3 100644 --- a/src/layout.c +++ b/src/layout.c @@ -238,7 +238,7 @@ void reposition_client(xcb_connection_t *conn, Client *client) { LOG("Client is on workspace %p with screen %p\n", client->workspace, client->workspace->screen); LOG("but screen at %d, %d is %p\n", client->rect.x, client->rect.y, screen); - floating_assign_to_workspace(client, workspace_get(screen->current_workspace)); + floating_assign_to_workspace(client, screen->current_workspace); } /* @@ -586,14 +586,14 @@ static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int wid xcb_change_gc_single(conn, screen->bargc, XCB_GC_FONT, font->id); int drawn = 0; - for (int c = 0; c < num_workspaces; c++) { - if (workspaces[c].screen != screen) + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) { + if (ws->screen != screen) continue; struct Colortriple *color; - Workspace *ws = &workspaces[c]; - if (screen->current_workspace == c) + if (screen->current_workspace == ws) color = &(config.bar.focused); else if (ws->urgent) color = &(config.bar.urgent); @@ -742,7 +742,8 @@ void render_layout(xcb_connection_t *conn) { return; TAILQ_FOREACH(screen, virtual_screens, screens) - render_workspace(conn, screen, &(workspaces[screen->current_workspace])); + if (screen->current_workspace != NULL) + render_workspace(conn, screen, screen->current_workspace); xcb_flush(conn); } diff --git a/src/mainx.c b/src/mainx.c index 4f235eca..322e51e2 100644 --- a/src/mainx.c +++ b/src/mainx.c @@ -211,8 +211,8 @@ int main(int argc, char *argv[], char *env[]) { * connection and a loaded configuration (default mode for new * containers may be stacking, which requires a new window to be * created), it had to be delayed. */ - expand_table_cols(&(workspaces[0])); - expand_table_rows(&(workspaces[0])); + expand_table_cols(TAILQ_FIRST(workspaces)); + expand_table_rows(TAILQ_FIRST(workspaces)); /* Place requests for the atoms we need as soon as possible */ #define REQUEST_ATOM(name) atom_cookies[name] = xcb_intern_atom(conn, 0, strlen(#name), #name); @@ -456,7 +456,7 @@ int main(int argc, char *argv[], char *env[]) { } LOG("Starting on %d\n", screen->current_workspace); - c_ws = &workspaces[screen->current_workspace]; + c_ws = screen->current_workspace; manage_existing_windows(conn, &prophs, root); diff --git a/src/manage.c b/src/manage.c index 5dcb837c..d4500134 100644 --- a/src/manage.c +++ b/src/manage.c @@ -329,7 +329,7 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, LOG("Assignment \"%s\" matches, so putting it on workspace %d\n", assign->windowclass_title, assign->workspace); - if (c_ws->screen->current_workspace == (assign->workspace-1)) { + if (c_ws->screen->current_workspace->num == (assign->workspace-1)) { LOG("We are already there, no need to do anything\n"); break; } diff --git a/src/table.c b/src/table.c index 4c5653aa..72cf3d35 100644 --- a/src/table.c +++ b/src/table.c @@ -26,10 +26,11 @@ #include "i3.h" #include "layout.h" #include "config.h" +#include "workspace.h" int current_workspace = 0; int num_workspaces = 1; -Workspace *workspaces; +struct workspaces_head *workspaces; /* Convenience pointer to the current workspace */ Workspace *c_ws; int current_col = 0; @@ -40,12 +41,13 @@ int current_row = 0; * */ void init_table() { - workspaces = scalloc(sizeof(Workspace)); - c_ws = workspaces; + workspaces = scalloc(sizeof(struct workspaces_head)); + TAILQ_INIT(workspaces); - workspaces[0].screen = NULL; - workspaces[0].num = 0; - TAILQ_INIT(&(workspaces[0].floating_clients)); + c_ws = scalloc(sizeof(Workspace)); + workspace_set_name(c_ws, NULL); + TAILQ_INIT(&(c_ws->floating_clients)); + TAILQ_INSERT_TAIL(workspaces, c_ws, workspaces); } static void new_container(Workspace *workspace, Container **container, int col, int row) { diff --git a/src/util.c b/src/util.c index 7990b56e..149af2da 100644 --- a/src/util.c +++ b/src/util.c @@ -458,12 +458,13 @@ Client *get_matching_client(xcb_connection_t *conn, const char *window_classtitl } LOG("Getting clients for class \"%s\" / title \"%s\"\n", to_class, to_title); - for (int workspace = 0; workspace < num_workspaces; workspace++) { - if (workspaces[workspace].screen == NULL) + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) { + if (ws->screen == NULL) continue; Client *client; - SLIST_FOREACH(client, &(workspaces[workspace].focus_stack), focus_clients) { + SLIST_FOREACH(client, &(ws->focus_stack), focus_clients) { LOG("Checking client with class=%s, name=%s\n", client->window_class, client->name); if (!client_matches_class_name(client, to_class, to_title, to_title_ucs, to_title_ucs_len)) continue; diff --git a/src/workspace.c b/src/workspace.c index 36f807d2..8f0b42d7 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -34,80 +34,31 @@ * */ Workspace *workspace_get(int number) { - if (number > (num_workspaces-1)) { - int old_num_workspaces = num_workspaces; + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) + if (ws->num == number) + return ws; - /* Convert all container->workspace and client->workspace - * pointers to numbers representing their workspace. Necessary - * because the realloc() may make all the pointers invalid, so - * we need to preserve them this way and restore them later. - * - * To distinguish between the first workspace and a NULL - * pointer, we store + 1. */ - for (int c = 0; c < num_workspaces; c++) { - FOR_TABLE(&(workspaces[c])) { - Container *con = workspaces[c].table[cols][rows]; - if (con->workspace != NULL) { - LOG("Handling con %p with pointer %p (num %d)\n", con, con->workspace, con->workspace->num); - con->workspace = (Workspace*)(con->workspace->num + 1); - } - } - Client *current; - SLIST_FOREACH(current, &(workspaces[c].focus_stack), focus_clients) { - if (current->workspace == NULL) - continue; - LOG("Handling client %p with pointer %p (num %d)\n", current, current->workspace, current->workspace->num); - current->workspace = (Workspace*)(current->workspace->num + 1); - } - } + /* If we are still there, we could not find the requested workspace. */ + int last_ws = TAILQ_LAST(workspaces, workspaces_head)->num; - /* preserve c_ws */ - c_ws = (Workspace*)(c_ws->num); + LOG("We need to initialize that one, last ws = %d\n", last_ws); - LOG("We need to initialize that one\n"); - num_workspaces = number+1; - workspaces = realloc(workspaces, num_workspaces * sizeof(Workspace)); - /* Zero out the new workspaces so that we have sane default values */ - for (int c = old_num_workspaces; c < num_workspaces; c++) - memset(&workspaces[c], 0, sizeof(Workspace)); + for (int c = last_ws; c < number; c++) { + LOG("Creating new ws\n"); - /* Immediately after the realloc(), we restore the pointers. - * They may be used when initializing the new workspaces, for - * example when the user configures containers to be stacking - * by default, thus requiring re-rendering the layout. */ - c_ws = workspace_get((int)c_ws); + ws = scalloc(sizeof(Workspace)); + ws->num = number; + TAILQ_INIT(&(ws->floating_clients)); + expand_table_cols(ws); + expand_table_rows(ws); + workspace_set_name(ws, NULL); - for (int c = 0; c < old_num_workspaces; c++) { - FOR_TABLE(&(workspaces[c])) { - Container *con = workspaces[c].table[cols][rows]; - if (con->workspace != NULL) { - LOG("Handling con %p with (num %d)\n", con, con->workspace); - con->workspace = workspace_get((int)con->workspace - 1); - } - } - Client *current; - SLIST_FOREACH(current, &(workspaces[c].focus_stack), focus_clients) { - if (current->workspace == NULL) - continue; - LOG("Handling client %p with (num %d)\n", current, current->workspace); - current->workspace = workspace_get((int)current->workspace - 1); - } - } - - /* Initialize the new workspaces */ - for (int c = old_num_workspaces; c < num_workspaces; c++) { - memset(&workspaces[c], 0, sizeof(Workspace)); - workspaces[c].num = c; - TAILQ_INIT(&(workspaces[c].floating_clients)); - expand_table_cols(&(workspaces[c])); - expand_table_rows(&(workspaces[c])); - workspace_set_name(&(workspaces[c]), NULL); - } - - LOG("done\n"); + TAILQ_INSERT_TAIL(workspaces, ws, workspaces); } + LOG("done\n"); - return &(workspaces[number]); + return ws; } /* @@ -145,7 +96,7 @@ void workspace_set_name(Workspace *ws, const char *name) { * */ bool workspace_is_visible(Workspace *ws) { - return (ws->screen->current_workspace == ws->num); + return (ws->screen->current_workspace == ws); } /* @@ -174,7 +125,7 @@ void workspace_show(xcb_connection_t *conn, int workspace) { /* Store the old client */ Client *old_client = CUR_CELL->currently_focused; - c_ws = workspace_get(t_ws->screen->current_workspace); + c_ws = t_ws->screen->current_workspace; current_col = c_ws->current_col; current_row = c_ws->current_row; if (CUR_CELL->currently_focused != NULL) @@ -192,7 +143,7 @@ void workspace_show(xcb_connection_t *conn, int workspace) { } /* Check if we need to change something or if we’re already there */ - if (c_ws->screen->current_workspace == (workspace-1)) { + if (c_ws->screen->current_workspace->num == (workspace-1)) { Client *last_focused = SLIST_FIRST(&(c_ws->focus_stack)); if (last_focused != SLIST_END(&(c_ws->focus_stack))) set_focus(conn, last_focused, true); @@ -204,9 +155,8 @@ void workspace_show(xcb_connection_t *conn, int workspace) { return; } - t_ws->screen->current_workspace = workspace-1; Workspace *old_workspace = c_ws; - c_ws = workspace_get(workspace-1); + c_ws = t_ws->screen->current_workspace = workspace_get(workspace-1); /* Unmap all clients of the old workspace */ workspace_unmap_clients(conn, old_workspace); @@ -325,8 +275,8 @@ void workspace_initialize(Workspace *ws, i3Screen *screen) { Workspace *get_first_workspace_for_screen(struct screens_head *slist, i3Screen *screen) { Workspace *result = NULL; - for (int c = 0; c < num_workspaces; c++) { - Workspace *ws = workspace_get(c); + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) { if (ws->preferred_screen == NULL || !screens_are_equal(get_screen_from_preference(slist, ws->preferred_screen), screen)) continue; @@ -337,11 +287,12 @@ Workspace *get_first_workspace_for_screen(struct screens_head *slist, i3Screen * if (result == NULL) { /* No assignment found, returning first unused workspace */ - for (int c = 0; c < num_workspaces; c++) { - if (workspaces[c].screen != NULL) + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) { + if (ws->screen != NULL) continue; - result = workspace_get(c); + result = ws; break; } } @@ -349,7 +300,11 @@ Workspace *get_first_workspace_for_screen(struct screens_head *slist, i3Screen * if (result == NULL) { LOG("No existing free workspace found to assign, creating a new one\n"); - result = workspace_get(num_workspaces); + Workspace *ws; + int last_ws = 0; + TAILQ_FOREACH(ws, workspaces, workspaces) + last_ws = ws->num; + result = workspace_get(last_ws + 1); } workspace_initialize(result, screen); diff --git a/src/xinerama.c b/src/xinerama.c index 77da7bbf..df7f9408 100644 --- a/src/xinerama.c +++ b/src/xinerama.c @@ -133,7 +133,7 @@ static void initialize_screen(xcb_connection_t *conn, i3Screen *screen, Workspac i3Font *font = load_font(conn, config.font); workspace->screen = screen; - screen->current_workspace = workspace->num; + screen->current_workspace = workspace; /* Create a bar for each screen */ Rect bar_rect = {screen->rect.x, @@ -298,12 +298,13 @@ void xinerama_requery_screens(xcb_connection_t *conn) { int screen_count = 0; /* Mark each workspace which currently is assigned to a screen, so we * can garbage-collect afterwards */ - for (int c = 0; c < num_workspaces; c++) - workspaces[c].reassigned = (workspaces[c].screen == NULL); + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) + ws->reassigned = (ws->screen == NULL); TAILQ_FOREACH(screen, new_screens, screens) { screen->num = screen_count; - screen->current_workspace = -1; + screen->current_workspace = NULL; TAILQ_FOREACH(old_screen, virtual_screens, screens) { if (old_screen->num != screen_count) @@ -334,8 +335,8 @@ void xinerama_requery_screens(xcb_connection_t *conn) { screen->dock_clients = old_screen->dock_clients; /* Update the dimensions */ - for (int c = 0; c < num_workspaces; c++) { - Workspace *ws = &(workspaces[c]); + Workspace *ws; + TAILQ_FOREACH(ws, workspaces, workspaces) { if (ws->screen != old_screen) continue; @@ -347,7 +348,7 @@ void xinerama_requery_screens(xcb_connection_t *conn) { break; } - if (screen->current_workspace == -1) { + if (screen->current_workspace == NULL) { /* Find the first unused workspace, preferring the ones * which are assigned to this screen and initialize * the screen with it. */ @@ -364,38 +365,36 @@ void xinerama_requery_screens(xcb_connection_t *conn) { } /* Check for workspaces which are out of bounds */ - for (int c = 0; c < num_workspaces; c++) { - if (workspaces[c].reassigned) + TAILQ_FOREACH(ws, workspaces, workspaces) { + if (ws->reassigned) continue; - /* f_ws is a shortcut to the workspace to fix */ - Workspace *f_ws = &(workspaces[c]); Client *client; - LOG("Closing bar window (%p)\n", f_ws->screen->bar); - xcb_destroy_window(conn, f_ws->screen->bar); + LOG("Closing bar window (%p)\n", ws->screen->bar); + xcb_destroy_window(conn, ws->screen->bar); - LOG("Workspace %d's screen out of bounds, assigning to first screen\n", c+1); - f_ws->screen = first; - memcpy(&(f_ws->rect), &(first->rect), sizeof(Rect)); + LOG("Workspace %d's screen out of bounds, assigning to first screen\n", ws->num + 1); + ws->screen = first; + memcpy(&(ws->rect), &(first->rect), sizeof(Rect)); /* Force reconfiguration for each client on that workspace */ - FOR_TABLE(f_ws) - CIRCLEQ_FOREACH(client, &(f_ws->table[cols][rows]->clients), clients) + FOR_TABLE(ws) + CIRCLEQ_FOREACH(client, &(ws->table[cols][rows]->clients), clients) client->force_reconfigure = true; /* Render the workspace to reconfigure the clients. However, they will be visible now, so… */ - render_workspace(conn, first, f_ws); + render_workspace(conn, first, ws); /* …unless we want to see them at the moment, we should hide that workspace */ - if (workspace_is_visible(f_ws)) + if (workspace_is_visible(ws)) continue; - workspace_unmap_clients(conn, f_ws); + workspace_unmap_clients(conn, ws); - if (c_ws == f_ws) { + if (c_ws == ws) { LOG("Need to adjust c_ws...\n"); - c_ws = &(workspaces[first->current_workspace]); + c_ws = first->current_workspace; } } xcb_flush(conn);