summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ChangeLog36
-rw-r--r--src/bar.c6
-rw-r--r--src/data.h24
-rw-r--r--src/events.c8
-rw-r--r--src/list.c202
-rw-r--r--src/list.h6
-rw-r--r--src/main.c2
-rw-r--r--src/manage.c22
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
diff --git a/src/bar.c b/src/bar.c
index 16bc8e3..732b8ef 100644
--- a/src/bar.c
+++ b/src/bar.c
@@ -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));
diff --git a/src/data.h b/src/data.h
index 9ba8419..e79ab41 100644
--- a/src/data.h
+++ b/src/data.h
@@ -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;
diff --git a/src/list.c b/src/list.c
index 4252250..e15d416 100644
--- a/src/list.c
+++ b/src/list.c
@@ -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)
{
diff --git a/src/list.h b/src/list.h
index 672b520..c713129 100644
--- a/src/list.h
+++ b/src/list.h
@@ -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 */
diff --git a/src/main.c b/src/main.c
index 16a7613..daa47f4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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