]> Dogcows Code - chaz/openbox/blobdiff - openbox/mainloop.c
consistant glib type usage
[chaz/openbox] / openbox / mainloop.c
index dea9e8c16ac293f9b6a62756e6311332309be1b8..0dd3b6b8b4e881497ff3ecc92b755774b5347bfc 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "mainloop.h"
 #include "action.h"
+#include "client.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -88,7 +89,7 @@ struct _ObMainLoop
     guint signals_fired[NUM_SIGNALS];
     GSList *signal_handlers[NUM_SIGNALS];
 
-    GQueue *action_queue;
+    GSList *action_queue;
 };
 
 struct _ObMainLoopTimer
@@ -120,6 +121,7 @@ struct _ObMainLoopXHandlerType
     ObMainLoop *loop;
     gpointer data;
     ObMainLoopXHandler func;
+    ObMainLoopXDoneHandler done_func;
     GDestroyNotify destroy;
 };
 
@@ -178,7 +180,7 @@ ObMainLoop *ob_main_loop_new(Display *display)
 
     all_loops = g_slist_prepend(all_loops, loop);
 
-    loop->action_queue = g_queue_new();
+    loop->action_queue = NULL;
 
     return loop;
 }
@@ -230,7 +232,9 @@ void ob_main_loop_destroy(ObMainLoop *loop)
             }
         }
 
-        g_queue_free(loop->action_queue);
+        for (it = loop->action_queue; it; it = g_slist_next(it))
+            action_unref(it->data);
+        g_slist_free(loop->action_queue);
 
         g_free(loop);
     }
@@ -249,7 +253,20 @@ static void fd_handle_foreach(gpointer key,
 
 void ob_main_loop_queue_action(ObMainLoop *loop, ObAction *act)
 {
-    g_queue_push_tail(loop->action_queue, action_copy(act));
+    loop->action_queue = g_slist_append(loop->action_queue, action_copy(act));
+}
+
+static void ob_main_loop_client_destroy(ObClient *client, gpointer data)
+{
+    ObMainLoop *loop = data;
+    GSList *it;
+
+    for (it = loop->action_queue; it; it = g_slist_next(it)) {
+        ObAction *act = it->data;
+
+        if (act->data.any.c == client)
+            act->data.any.c = NULL;
+    }
 }
 
 void ob_main_loop_run(ObMainLoop *loop)
@@ -263,6 +280,8 @@ void ob_main_loop_run(ObMainLoop *loop)
     loop->run = TRUE;
     loop->running = TRUE;
 
+    client_add_destructor(ob_main_loop_client_destroy, loop);
+
     while (loop->run) {
         if (loop->signal_fired) {
             guint i;
@@ -294,35 +313,65 @@ void ob_main_loop_run(ObMainLoop *loop)
                     h->func(&e, h->data);
                 }
             } while (XPending(loop->display));
-        } else if ((act = g_queue_pop_head(loop->action_queue))) {
-             /* only fire off one action at a time, then go back for more
-                X events, since the action might cause some X events (like
-                FocusIn :) */
-            act->func(&act->data);
-            action_unref(act);
         } else {
-            /* this only runs if there were no x events received */
-
-            timer_dispatch(loop, (GTimeVal**)&wait);
-
-            selset = loop->fd_set;
-            /* there is a small race condition here. if a signal occurs
-               between this if() and the select() then we will not process
-               the signal until 'wait' expires. possible solutions include
-               using GStaticMutex, and having the signal handler set 'wait'
-               to 0 */
-            if (!loop->signal_fired)
-                select(loop->fd_max + 1, &selset, NULL, NULL, wait);
-
-            /* handle the X events with highest prioirity */
-            if (FD_ISSET(loop->fd_x, &selset))
-                continue;
+            for (it = loop->x_handlers; it; it = g_slist_next(it)) {
+                ObMainLoopXHandlerType *h = it->data;
+                if (h->done_func)
+                    h->done_func(h->data);
+            }
 
-            g_hash_table_foreach(loop->fd_handlers,
-                                 fd_handle_foreach, &selset);
+            if (loop->action_queue) {
+                /* only fire off one action at a time, then go back for more
+                   X events, since the action might cause some X events (like
+                   FocusIn :) */
+
+                do {
+                    act = loop->action_queue->data;
+                    if (act->data.any.client_action ==
+                        OB_CLIENT_ACTION_ALWAYS &&
+                        !act->data.any.c)
+                    {
+                        loop->action_queue =
+                            g_slist_delete_link(loop->action_queue,
+                                                loop->action_queue);
+                        action_unref(act);
+                        act = NULL;
+                    }
+                } while (!act && loop->action_queue);
+
+                if  (act) {
+                    act->func(&act->data);
+                    loop->action_queue =
+                        g_slist_delete_link(loop->action_queue,
+                                            loop->action_queue);
+                    action_unref(act);
+                }
+            } else {
+                /* this only runs if there were no x events received */
+
+                timer_dispatch(loop, (GTimeVal**)&wait);
+
+                selset = loop->fd_set;
+                /* there is a small race condition here. if a signal occurs
+                   between this if() and the select() then we will not process
+                   the signal until 'wait' expires. possible solutions include
+                   using GStaticMutex, and having the signal handler set 'wait'
+                   to 0 */
+                if (!loop->signal_fired)
+                    select(loop->fd_max + 1, &selset, NULL, NULL, wait);
+
+                /* handle the X events with highest prioirity */
+                if (FD_ISSET(loop->fd_x, &selset))
+                    continue;
+
+                g_hash_table_foreach(loop->fd_handlers,
+                                     fd_handle_foreach, &selset);
+            }
         }
     }
 
+    client_remove_destructor(ob_main_loop_client_destroy);
+
     loop->running = FALSE;
 }
 
@@ -335,6 +384,7 @@ void ob_main_loop_exit(ObMainLoop *loop)
 
 void ob_main_loop_x_add(ObMainLoop *loop,
                         ObMainLoopXHandler handler,
+                        ObMainLoopXDoneHandler done_handler,
                         gpointer data,
                         GDestroyNotify notify)
 {
@@ -343,6 +393,7 @@ void ob_main_loop_x_add(ObMainLoop *loop,
     h = g_new(ObMainLoopXHandlerType, 1);
     h->loop = loop;
     h->func = handler;
+    h->done_func = done_handler;
     h->data = data;
     h->destroy = notify;
     loop->x_handlers = g_slist_prepend(loop->x_handlers, h);
@@ -514,9 +565,9 @@ void ob_main_loop_fd_remove(ObMainLoop *loop,
 #define NEAREST_TIMEOUT(loop) \
     (((ObMainLoopTimer*)(loop)->timers->data)->timeout)
 
-static long timecompare(GTimeVal *a, GTimeVal *b)
+static glong timecompare(GTimeVal *a, GTimeVal *b)
 {
-    long r;
+    glong r;
 
     if ((r = b->tv_sec - a->tv_sec)) return r;
     return b->tv_usec - a->tv_usec;
@@ -623,6 +674,8 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait)
         if (curr->del_me) {
             /* delete the top */
             loop->timers = g_slist_delete_link(loop->timers, it); 
+            if (curr->destroy)
+                curr->destroy(curr->data);
             g_free(curr);
             continue;
         }
This page took 0.025985 seconds and 4 git commands to generate.