diff --git a/cmd-set-option.c b/cmd-set-option.c index 01d691d5..e236b95d 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -176,9 +176,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) /* Start or stop timers when automatic-rename changed. */ if (strcmp(oe->name, "automatic-rename") == 0) { - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - if ((w = ARRAY_ITEM(&windows, i)) == NULL) - continue; + RB_FOREACH(w, windows, &windows) { if (options_get_number(&w->options, "automatic-rename")) queue_window_name(w); else if (event_initialized(&w->name_timer)) diff --git a/resize.c b/resize.c index 9ad73c81..5b89b093 100644 --- a/resize.c +++ b/resize.c @@ -49,7 +49,7 @@ recalculate_sizes(void) struct client *c; struct window *w; struct window_pane *wp; - u_int i, j, ssx, ssy, has, limit; + u_int i, ssx, ssy, has, limit; int flag, has_status, is_zoomed, forced; RB_FOREACH(s, sessions, &sessions) { @@ -57,8 +57,8 @@ recalculate_sizes(void) s->attached = 0; ssx = ssy = UINT_MAX; - for (j = 0; j < ARRAY_LENGTH(&clients); j++) { - c = ARRAY_ITEM(&clients, j); + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); if (c == NULL || c->flags & CLIENT_SUSPENDED) continue; if (c->session == s) { @@ -92,9 +92,8 @@ recalculate_sizes(void) s->sy = ssy; } - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - w = ARRAY_ITEM(&windows, i); - if (w == NULL || w->active == NULL) + RB_FOREACH(w, windows, &windows) { + if (w->active == NULL) continue; flag = options_get_number(&w->options, "aggressive-resize"); diff --git a/server-client.c b/server-client.c index c022a36f..e2f65e71 100644 --- a/server-client.c +++ b/server-client.c @@ -720,11 +720,7 @@ server_client_loop(void) * Any windows will have been redrawn as part of clients, so clear * their flags now. Also check pane focus and resize. */ - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - w = ARRAY_ITEM(&windows, i); - if (w == NULL) - continue; - + RB_FOREACH(w, windows, &windows) { w->flags &= ~WINDOW_REDRAW; TAILQ_FOREACH(wp, &w->panes, entry) { if (wp->fd != -1) { diff --git a/server-window.c b/server-window.c index a2355701..f157da35 100644 --- a/server-window.c +++ b/server-window.c @@ -34,24 +34,20 @@ void server_window_loop(void) { struct window *w; - struct winlink *wl; struct session *s; - u_int i; - - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - w = ARRAY_ITEM(&windows, i); - if (w == NULL) - continue; + struct winlink *wl; + RB_FOREACH(w, windows, &windows) { RB_FOREACH(s, sessions, &sessions) { - wl = session_has(s, w); - if (wl == NULL) - continue; + RB_FOREACH(wl, winlinks, &s->windows) { + if (wl->window != w) + continue; - if (server_window_check_bell(s, wl) || - server_window_check_activity(s, wl) || - server_window_check_silence(s, wl)) - server_status_session(s); + if (server_window_check_bell(s, wl) || + server_window_check_activity(s, wl) || + server_window_check_silence(s, wl)) + server_status_session(s); + } } } } diff --git a/server.c b/server.c index bb96d9af..1183d64d 100644 --- a/server.c +++ b/server.c @@ -137,7 +137,7 @@ server_start(int lockfd, char *lockfile) logfile("server"); log_debug("server started, pid %ld", (long) getpid()); - ARRAY_INIT(&windows); + RB_INIT(&windows); RB_INIT(&all_window_panes); ARRAY_INIT(&clients); ARRAY_INIT(&dead_clients); @@ -438,14 +438,11 @@ server_child_signal(void) void server_child_exited(pid_t pid, int status) { - struct window *w; + struct window *w, *w1; struct window_pane *wp; struct job *job; - u_int i; - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - if ((w = ARRAY_ITEM(&windows, i)) == NULL) - continue; + RB_FOREACH_SAFE(w, windows, &windows, w1) { TAILQ_FOREACH(wp, &w->panes, entry) { if (wp->pid == pid) { wp->status = status; @@ -469,14 +466,11 @@ server_child_stopped(pid_t pid, int status) { struct window *w; struct window_pane *wp; - u_int i; if (WSTOPSIG(status) == SIGTTIN || WSTOPSIG(status) == SIGTTOU) return; - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - if ((w = ARRAY_ITEM(&windows, i)) == NULL) - continue; + RB_FOREACH(w, windows, &windows) { TAILQ_FOREACH(wp, &w->panes, entry) { if (wp->pid == pid) { if (killpg(pid, SIGCONT) != 0) @@ -493,18 +487,13 @@ server_second_callback(unused int fd, unused short events, unused void *arg) struct window *w; struct window_pane *wp; struct timeval tv; - u_int i; if (options_get_number(&global_s_options, "lock-server")) server_lock_server(); else server_lock_sessions(); - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - w = ARRAY_ITEM(&windows, i); - if (w == NULL) - continue; - + RB_FOREACH(w, windows, &windows) { TAILQ_FOREACH(wp, &w->panes, entry) { if (wp->mode != NULL && wp->mode->timer != NULL) wp->mode->timer(wp); diff --git a/tmux.h b/tmux.h index 52dc1529..e52b14f1 100644 --- a/tmux.h +++ b/tmux.h @@ -983,8 +983,10 @@ struct window { struct options options; u_int references; + + RB_ENTRY(window) entry; }; -ARRAY_DECL(windows, struct window *); +RB_HEAD(windows, window); /* Entry on local window list. */ struct winlink { @@ -2121,6 +2123,8 @@ void screen_reflow(struct screen *, u_int); /* window.c */ extern struct windows windows; extern struct window_pane_tree all_window_panes; +int window_cmp(struct window *, struct window *); +RB_PROTOTYPE(windows, window, entry, window_cmp); int winlink_cmp(struct winlink *, struct winlink *); RB_PROTOTYPE(winlinks, winlink, entry, winlink_cmp); int window_pane_cmp(struct window_pane *, struct window_pane *); diff --git a/window.c b/window.c index d8f29026..5ca8aa0c 100644 --- a/window.c +++ b/window.c @@ -64,6 +64,14 @@ void window_pane_error_callback(struct bufferevent *, short, void *); struct window_pane *window_pane_choose_best(struct window_pane_list *); +RB_GENERATE(windows, window, entry, window_cmp); + +int +window_cmp(struct window *w1, struct window *w2) +{ + return (w1->id - w2->id); +} + RB_GENERATE(winlinks, winlink, entry, winlink_cmp); int @@ -248,25 +256,18 @@ winlink_stack_remove(struct winlink_stack *stack, struct winlink *wl) struct window * window_find_by_id(u_int id) { - struct window *w; - u_int i; + struct window w; - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - w = ARRAY_ITEM(&windows, i); - if (w != NULL && w->id == id) - return (w); - } - return (NULL); + w.id = id; + return (RB_FIND(windows, &windows, &w)); } struct window * window_create1(u_int sx, u_int sy) { struct window *w; - u_int i; w = xcalloc(1, sizeof *w); - w->id = next_window_id++; w->name = NULL; w->flags = 0; @@ -283,16 +284,11 @@ window_create1(u_int sx, u_int sy) if (options_get_number(&w->options, "automatic-rename")) queue_window_name(w); - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - if (ARRAY_ITEM(&windows, i) == NULL) { - ARRAY_SET(&windows, i, w); - break; - } - } - if (i == ARRAY_LENGTH(&windows)) - ARRAY_ADD(&windows, w); w->references = 0; + w->id = next_window_id++; + RB_INSERT (windows, &windows, w); + return (w); } @@ -327,19 +323,9 @@ window_create(const char *name, int argc, char **argv, const char *path, void window_destroy(struct window *w) { - u_int i; - window_unzoom(w); - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - if (w == ARRAY_ITEM(&windows, i)) - break; - } - if (i == ARRAY_LENGTH(&windows)) - fatalx("index not found"); - ARRAY_SET(&windows, i, NULL); - while (!ARRAY_EMPTY(&windows) && ARRAY_LAST(&windows) == NULL) - ARRAY_TRUNC(&windows, 1); + RB_REMOVE(windows, &windows, w); if (w->layout_root != NULL) layout_free(w); @@ -1328,26 +1314,18 @@ window_pane_find_right(struct window_pane *wp) void winlink_clear_flags(struct winlink *wl) { - struct winlink *wm; struct session *s; - struct window *w; - u_int i; + struct winlink *wl_loop; - for (i = 0; i < ARRAY_LENGTH(&windows); i++) { - if ((w = ARRAY_ITEM(&windows, i)) == NULL) - continue; - - RB_FOREACH(s, sessions, &sessions) { - if ((wm = session_has(s, w)) == NULL) + RB_FOREACH(s, sessions, &sessions) { + RB_FOREACH(wl_loop, winlinks, &s->windows) { + if (wl_loop->window != wl->window) + continue; + if ((wl_loop->flags & WINLINK_ALERTFLAGS) == 0) continue; - if (wm->window != wl->window) - continue; - if ((wm->flags & WINLINK_ALERTFLAGS) == 0) - continue; - - wm->flags &= ~WINLINK_ALERTFLAGS; - wm->window->flags &= ~WINDOW_ALERTFLAGS; + wl_loop->flags &= ~WINLINK_ALERTFLAGS; + wl_loop->window->flags &= ~WINDOW_ALERTFLAGS; server_status_session(s); } }