diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 36 | ||||
-rw-r--r-- | src/bar.c | 6 | ||||
-rw-r--r-- | src/data.h | 24 | ||||
-rw-r--r-- | src/events.c | 8 | ||||
-rw-r--r-- | src/list.c | 202 | ||||
-rw-r--r-- | src/list.h | 6 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/manage.c | 22 |
8 files changed, 222 insertions, 84 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 52d2e5a..42bdb3a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,39 @@ +2001-02-23 shawn <sabetts@diggin.lamenet.tmp> + + * main.c (main): passes return value of find_window_other() to + set_active_window(). + + * list.h (remove_from_window_list): removed prototype + (find_window_in_list): new prototype + (append_to_list): likewise + (insert_into_list): likewise + (remove_from_list): likewise + + * list.c: propogated use of rp_unmapped_window_sentinel and + rp_mapped_window_sentinel. + (find_window_in_list): new function + (find_window): calls find_window_in_list to search mapped and + unmapped window lists. + (remove_from_window_list): removed function + (init_window_list): initialized sentinels + (find_window_prev): searches only the mapped window list. + (find_window_next): likewise + (find_window_other): likewise + (append_to_list): new function + (insert_into_list): new function + (remove_from_list): new function + + * events.c (unmap_notify): Searches only the mapped window + list. moves the window from the unmapped window list to the mapped + window list. + + * data.h: removed rp_window_head and rp_window_tail, updated + dependant files. Added rp_mapped_window_sentinel and + rp_unmapped_window_sentinel globals. + + * bar.c (update_window_names): loops only through mapped window + list. + 2001-02-21 Ryan Yeske <rcyeske@cut.hotdog.tmp> * manage.c (manage): comment out broken sort_window_list_by_number @@ -104,12 +104,12 @@ update_window_names (screen_info *s) sbuf_clear (bar_buffer); - for (w = rp_window_head; w; w = w->next) + for (w = rp_mapped_window_sentinel->next; + w != rp_mapped_window_sentinel; + w = w->next) { PRINT_DEBUG ("%d-%s\n", w->number, w->name); - if (w->state == STATE_UNMAPPED) continue; - if (w == rp_current_window) mark_start = strlen (sbuf_get (bar_buffer)); @@ -84,8 +84,28 @@ struct rp_action /* void (*func)(void *); */ }; -extern rp_window *rp_window_head, *rp_window_tail; -extern rp_window *rp_current_window; +/* These _sentinel pointers point to a special rp_window whose next + pointer points to the head of the list and whose prev pointer + points to the tail. This is done to simplify removing an element + from the list: since there are no head and tail global variable + pointers that need to be updated, functions that manipulate + elements in a list don't need to know what list they belong to. The + last element's next pointer points to the sentinel as does the + first element's prev pointer. An empty list is represented by the + sentinel's prev and next pointers pointing to itself. */ + +/* A list of mapped windows. These windows show up in the window + list and have a number assigned to them. */ +extern rp_window *rp_mapped_window_sentinel; + +/* A list of unmapped windows. These windows do not have a number + assigned to them and are not visible/active. */ +extern rp_window *rp_unmapped_window_sentinel; + +/* Pointer to the currently focused window. Points to an element in + the mapped window list. NULL if there are no mapped windows. */ +extern rp_window *rp_current_window; + extern screen_info *screens; extern int num_screens; diff --git a/src/events.c b/src/events.c index ce81d24..2c56253 100644 --- a/src/events.c +++ b/src/events.c @@ -44,6 +44,7 @@ new_window (XCreateWindowEvent *e) if (e->override_redirect) return; s = find_screen (e->parent); + win = find_window (e->window); if (s && !win && e->window != s->key_window && e->window != s->bar_window @@ -61,7 +62,9 @@ unmap_notify (XEvent *ev) rp_window *win; s = find_screen (ev->xunmap.event); - win = find_window (ev->xunmap.window); + + /* FIXME: Should we only look in the mapped window list? */ + win = find_window_in_list (ev->xunmap.window, rp_mapped_window_sentinel); if (s && win) { @@ -72,6 +75,9 @@ unmap_notify (XEvent *ev) return_window_number (win->number); win->number = -1; win->state = STATE_UNMAPPED; + + remove_from_list (win); + append_to_list (win, rp_unmapped_window_sentinel); /* Update the state of the actual window */ ignore_badwindow = 1; @@ -26,7 +26,8 @@ #include "ratpoison.h" -rp_window *rp_window_head, *rp_window_tail; +rp_window *rp_unmapped_window_sentinel; +rp_window *rp_mapped_window_sentinel; rp_window *rp_current_window; /* Get the mouse position relative to the root of the specified window */ @@ -74,53 +75,44 @@ add_to_window_list (screen_info *s, Window w) } strcpy (new_window->name, "Unnamed"); - if (rp_window_head == NULL) - { - /* The list is empty. */ - rp_window_head = new_window; - rp_window_tail = new_window; - new_window->next = NULL; - return new_window; - } - - /* Add the window to the head of the list. */ - new_window->next = rp_window_head; - rp_window_head->prev = new_window; - rp_window_head = new_window; + /* Add the window to the end of the unmapped list. */ + append_to_list (new_window, rp_unmapped_window_sentinel); return new_window; } -/* Check to see if the window is already in our list of managed windows. */ +/* Check to see if the window is in the list of windows. */ rp_window * -find_window (Window w) +find_window_in_list (Window w, rp_window *sentinel) { rp_window *cur; - for (cur = rp_window_head; cur; cur = cur->next) - if (cur->w == w) return cur; + for (cur = sentinel->next; cur != sentinel; cur = cur->next) + { + if (cur->w == w) return cur; + } return NULL; } - -void -remove_from_window_list (rp_window *w) + +/* Check to see if the window is in any of the lists of windows. */ +rp_window * +find_window (Window w) { - if (rp_window_head == w) rp_window_head = w->next; - if (rp_window_tail == w) rp_window_tail = w->prev; + rp_window *win = NULL; - if (w->prev != NULL) w->prev->next = w->next; - if (w->next != NULL) w->next->prev = w->prev; + win = find_window_in_list (w, rp_mapped_window_sentinel); - /* set rp_current_window to NULL, so a dangling pointer is not - left. */ - if (rp_current_window == w) rp_current_window = NULL; + if (!win) + { + win = find_window_in_list (w, rp_unmapped_window_sentinel); + } - XFree (w->hints); - free (w); - PRINT_DEBUG ("Removed window from list.\n"); + return win; } + + void set_current_window (rp_window *win) { @@ -130,7 +122,22 @@ set_current_window (rp_window *win) void init_window_list () { - rp_window_head = rp_window_tail = NULL; + rp_mapped_window_sentinel = malloc (sizeof (rp_window)); + rp_unmapped_window_sentinel = malloc (sizeof (rp_window)); + + if (!rp_mapped_window_sentinel + || !rp_unmapped_window_sentinel) + { + PRINT_ERROR ("Out of memory!\n"); + exit (EXIT_FAILURE); + } + + rp_mapped_window_sentinel->next = rp_mapped_window_sentinel; + rp_mapped_window_sentinel->prev = rp_mapped_window_sentinel; + + rp_unmapped_window_sentinel->next = rp_unmapped_window_sentinel; + rp_unmapped_window_sentinel->prev = rp_unmapped_window_sentinel; + rp_current_window = NULL; } @@ -139,9 +146,11 @@ find_window_number (int n) { rp_window *cur; - for (cur=rp_window_head; cur; cur=cur->next) + for (cur = rp_mapped_window_sentinel->next; + cur != rp_mapped_window_sentinel; + cur = cur->next) { - if (cur->state == STATE_UNMAPPED) continue; +/* if (cur->state == STATE_UNMAPPED) continue; */ if (n == cur->number) return cur; } @@ -167,10 +176,12 @@ find_window_name (char *name) { rp_window *w; - for (w = rp_window_head; w; w = w->next) + for (w = rp_mapped_window_sentinel->next; + w != rp_mapped_window_sentinel; + w = w->next) { - if (w->state == STATE_UNMAPPED) - continue; +/* if (w->state == STATE_UNMAPPED) */ +/* continue; */ if (str_comp (name, w->name, strlen (name))) return w; @@ -180,58 +191,65 @@ find_window_name (char *name) return NULL; } -/* return the previous window in the list */ +/* return the previous window in the list. Assumes window is in the + mapped window list. */ rp_window* find_window_prev (rp_window *w) { - if (!(w || (w = rp_current_window))) - return NULL; - - w = w->prev; - if (w == NULL) - w = rp_window_tail; - if (w->state == STATE_UNMAPPED) - return find_window_prev (w); - else - return w; + rp_window *prev; + + if (!w) return NULL; + + prev = w->prev; + + if (prev == rp_mapped_window_sentinel) + { + prev = rp_mapped_window_sentinel->prev; + if (prev == w) + { + return NULL; + } + } + + return prev; } -/* return the next window in the list */ +/* return the next window in the list. Assumes window is in the mapped + window list. */ rp_window* find_window_next (rp_window *w) { - if (!(w || (w = rp_current_window))) - return NULL; - - w = w->next; - if (w == NULL) - w = rp_window_head; - if (w->state == STATE_UNMAPPED) - return find_window_next (w); - else - return w; + rp_window *next; + + if (!w) return NULL; + + next = w->next; + + if (next == rp_mapped_window_sentinel) + { + next = rp_mapped_window_sentinel->next; + if (next == w) + { + return NULL; + } + } + + return next; } rp_window * find_window_other () { int last_access = 0; - rp_window *cur, *most_recent; - - /* Find the first mapped window */ - for (most_recent = rp_window_head; most_recent; most_recent=most_recent->next) - { - if (most_recent->state == STATE_MAPPED) break; - } - - /* If there are no mapped windows, don't bother with the next part */ - if (most_recent == NULL) return NULL; + rp_window *most_recent = NULL; + rp_window *cur; - for (cur=rp_window_head; cur; cur=cur->next) + for (cur = rp_mapped_window_sentinel->next; + cur != rp_mapped_window_sentinel; + cur = cur->next) { if (cur->last_access >= last_access - && cur != rp_current_window - && cur->state == STATE_MAPPED) + && cur != rp_current_window) { most_recent = cur; last_access = cur->last_access; @@ -294,6 +312,46 @@ find_window_other () /* } */ /* } */ +void +append_to_list (rp_window *win, rp_window *sentinel) +{ + win->prev = sentinel->prev; + sentinel->prev->next = win; + sentinel->prev = win; + win->next = sentinel; +} + +/* Assumes the list is sorted by increasing number. Inserts win into + to Right place to keep the list sorted. */ +void +insert_into_list (rp_window *win, rp_window *sentinel) +{ + rp_window *cur; + + for (cur = sentinel->next; cur != sentinel; cur = cur->next) + { + if (cur->number > win->number) + { + win->next = cur; + win->prev = cur->prev; + + cur->prev->next = win; + cur->prev = win; + + return; + } + } + + append_to_list (win, sentinel); +} + +void +remove_from_list (rp_window *win) +{ + win->next->prev = win->prev; + win->prev->next = win->next; +} + static void save_mouse_position (rp_window *win) { @@ -24,10 +24,10 @@ rp_window *add_to_window_list (screen_info *s, Window w); void init_window_list (); -void remove_from_window_list (rp_window *w); /* void next_window (); */ /* void prev_window (); */ void last_window (); +rp_window *find_window_in_list (Window w, rp_window *sentinel); rp_window *find_window (Window w); void maximize_current_window (); void set_active_window (rp_window *rp_w); @@ -41,4 +41,8 @@ rp_window* find_window_next (rp_window *w); rp_window* find_window_number (int n); void sort_window_list_by_number (); +void append_to_list (rp_window *win, rp_window *sentinel); +void insert_into_list (rp_window *win, rp_window *sentinel); +void remove_from_list (rp_window *win); + #endif /* ! _RATPOISON_LIST_H */ @@ -282,7 +282,7 @@ main (int argc, char *argv[]) initialize_default_keybindings (); /* Set an initial window as active. */ - set_active_window (rp_window_head); + set_active_window (find_window_other ()); handle_events (); diff --git a/src/manage.c b/src/manage.c index 7d9f552..ebdae08 100644 --- a/src/manage.c +++ b/src/manage.c @@ -196,6 +196,10 @@ manage (rp_window *win, screen_info *s) win->state = STATE_MAPPED; win->number = get_unique_window_number (); + /* Put win in the mapped window list */ + remove_from_list (win); + insert_into_list (win, rp_mapped_window_sentinel); + /* sort_window_list_by_number(); */ PRINT_DEBUG ("window '%s' managed.\n", win->name); @@ -205,13 +209,23 @@ void unmanage (rp_window *w) { return_window_number (w->number); - remove_from_window_list (w); + remove_from_list (w); + XFree (w->hints); + + free (w); #ifdef AUTO_CLOSE - if (!rp_current_window) + if (rp_mapped_window_sentinel->next == rp_mapped_window_sentinel + && rp_mapped_window_sentinel->prev == rp_mapped_window_sentinel) { - /* If rp_current_window is NULL then we have run out of managed - windows, So kill ratpoison. */ + /* If the mapped window list is empty then we have run out of + managed windows, So kill ratpoison. */ + + /* FIXME: The unmapped window list may also have to be checked + in the case that the only mapped window in unmapped and + shortly after another window is mapped most likely by the + same app. */ + send_kill(); } #endif |