queue hooks so that they don't run as each thing happens, instead run them at the...
authorDana Jansens <danakj@orodu.net>
Sat, 1 Mar 2008 06:52:38 +0000 (01:52 -0500)
committerDana Jansens <danakj@orodu.net>
Sat, 1 Mar 2008 06:52:38 +0000 (01:52 -0500)
openbox/client.c
openbox/event.c
openbox/focus.c
openbox/hooks.c
openbox/hooks.h
openbox/screen.c

index 7c23e8e..c0864bc 100644 (file)
@@ -562,7 +562,7 @@ void client_manage(Window window, ObPrompt *prompt)
     ob_debug("Managed window 0x%lx plate 0x%x (%s)",
              window, self->frame->window, self->class);
 
-    hooks_run(OB_HOOK_WIN_NEW, self);
+    hooks_queue(OB_HOOK_WIN_NEW, self);
 }
 
 
@@ -638,6 +638,7 @@ void client_unmanage(ObClient *self)
     if (!self->prompt)
         XChangeSaveSet(obt_display, self->window, SetModeDelete);
 
+    /* this can't be queued to run later */
     hooks_run(OB_HOOK_WIN_CLOSE, self);
 
     /* update the focus lists */
@@ -2525,7 +2526,7 @@ gboolean client_show(ObClient *self)
         */
         client_change_wm_state(self);
 
-        hooks_run(OB_HOOK_WIN_VISIBLE, self);
+        hooks_queue(OB_HOOK_WIN_VISIBLE, self);
     }
     return show;
 }
@@ -2565,7 +2566,7 @@ gboolean client_hide(ObClient *self)
         */
         client_change_wm_state(self);
 
-        hooks_run(OB_HOOK_WIN_INVISIBLE, self);
+        hooks_queue(OB_HOOK_WIN_INVISIBLE, self);
     }
     return hide;
 }
@@ -3162,7 +3163,8 @@ static void client_iconify_recursive(ObClient *self,
         /* do this after starting the animation so it doesn't flash */
         client_showhide(self);
 
-        hooks_run((iconic ? OB_HOOK_WIN_ICONIC : OB_HOOK_WIN_UNICONIC), self);
+        hooks_queue((iconic ? OB_HOOK_WIN_ICONIC : OB_HOOK_WIN_UNICONIC),
+                    self);
     }
 
     /* iconify all direct transients, and deiconify all transients
@@ -3251,7 +3253,7 @@ void client_maximize(ObClient *self, gboolean max, gint dir)
     client_setup_decor_and_functions(self, FALSE);
     client_move_resize(self, x, y, w, h);
 
-    hooks_run((max ? OB_HOOK_WIN_MAX : OB_HOOK_WIN_UNMAX), self);
+    hooks_queue((max ? OB_HOOK_WIN_MAX : OB_HOOK_WIN_UNMAX), self);
 }
 
 void client_shade(ObClient *self, gboolean shade)
@@ -3266,7 +3268,7 @@ void client_shade(ObClient *self, gboolean shade)
     /* resize the frame to just the titlebar */
     frame_adjust_area(self->frame, FALSE, TRUE, FALSE);
 
-    hooks_run((shade ? OB_HOOK_WIN_SHADE : OB_HOOK_WIN_UNSHADE), self);
+    hooks_queue((shade ? OB_HOOK_WIN_SHADE : OB_HOOK_WIN_UNSHADE), self);
 }
 
 static void client_ping_event(ObClient *self, gboolean dead)
@@ -3470,7 +3472,7 @@ static void client_set_desktop_recursive(ObClient *self,
             client_reconfigure(self, FALSE);
 
         if (old != self->desktop)
-            hooks_run(OB_HOOK_WIN_DESK_CHANGE, self);
+            hooks_queue(OB_HOOK_WIN_DESK_CHANGE, self);
     }
 
     /* move all transients */
@@ -3874,8 +3876,8 @@ void client_set_undecorated(ObClient *self, gboolean undecorated)
         client_setup_decor_and_functions(self, TRUE);
         client_change_state(self); /* reflect this in the state hints */
 
-        hooks_run((undecorated ?
-                   OB_HOOK_WIN_UNDECORATED : OB_HOOK_WIN_DECORATED), self);
+        hooks_queue((undecorated ?
+                     OB_HOOK_WIN_UNDECORATED : OB_HOOK_WIN_DECORATED), self);
     }
 }
 
index 142cf1f..2563be2 100644 (file)
@@ -738,6 +738,11 @@ static void event_process(const XEvent *ec, gpointer data)
              e->type == MotionNotify)
         event_handle_user_input(client, e);
 
+    XFlush(obt_display);
+
+    /* run all the hooks at once */
+    hooks_run_queue();
+
     /* if something happens and it's not from an XEvent, then we don't know
        the time */
     event_curtime = CurrentTime;
index 5eb27bc..23cf910 100644 (file)
@@ -105,8 +105,8 @@ void focus_set_client(ObClient *client)
         OBT_PROP_SET32(obt_root(ob_screen), NET_ACTIVE_WINDOW, WINDOW, active);
     }
 
-    hooks_run(OB_HOOK_WIN_UNFOCUS, old);
-    hooks_run(OB_HOOK_WIN_FOCUS, client);
+    hooks_queue(OB_HOOK_WIN_UNFOCUS, old);
+    hooks_queue(OB_HOOK_WIN_FOCUS, client);
 }
 
 static ObClient* focus_fallback_target(gboolean allow_refocus,
index 7d7f700..ad57fdb 100644 (file)
@@ -3,12 +3,22 @@
 #include "client.h"
 #include "focus.h"
 #include "debug.h"
+#include "obt/display.h"
 
 #include <glib.h>
 
 static GSList *hooks[OB_NUM_HOOKS];
 static const gchar *names[OB_NUM_HOOKS];
 
+typedef struct {
+    ObHook hook;
+    struct _ObClient *client;
+} ObHookQueue;
+
+#define QUEUE_SIZE 20
+ObHookQueue run_queue[QUEUE_SIZE];
+gint        queue_size;
+
 void hooks_startup(gboolean reconfig)
 {
     gint i;
@@ -16,6 +26,8 @@ void hooks_startup(gboolean reconfig)
     for (i = 0; i < OB_NUM_HOOKS; ++i)
         hooks[i] = NULL;
 
+    queue_size = 0;
+
     names[OB_HOOK_WIN_NEW] = "WindowNew";
     names[OB_HOOK_WIN_CLOSE] = "WindowClosed";
     names[OB_HOOK_WIN_VISIBLE] = "WindowVisible";
@@ -55,19 +67,27 @@ ObHook hooks_hook_from_name(const gchar *n)
     return OB_HOOK_INVALID;
 }
 
-void hooks_run(ObHook hook, struct _ObClient *client)
+void hooks_queue(ObHook hook, struct _ObClient *client)
 {
-    GSList *it;
+    ObHookQueue *q;
 
     g_assert(hook < OB_NUM_HOOKS && hook > OB_HOOK_INVALID);
 
-    ob_debug("Running hook %s for client 0x%x", names[hook],
+    ob_debug("Queing hook %s for client 0x%x", names[hook],
              (client ? client->window : 0));
-    actions_run_acts(hooks[hook],
-                     OB_USER_ACTION_HOOK,
-                     0, -1, -1, 0,
-                     OB_FRAME_CONTEXT_NONE,
-                     client);
+    q = &run_queue[queue_size++];
+    q->hook = hook;
+    q->client = client;
+
+    if (queue_size == QUEUE_SIZE)
+        /* queue is full */
+        hooks_run_queue();
+}
+
+void hooks_run(ObHook hook, struct _ObClient *c)
+{
+    hooks_queue(hook, c);
+    hooks_run_queue();
 }
 
 void hooks_add(ObHook hook, struct _ObActionsAct *act)
@@ -78,3 +98,21 @@ void hooks_add(ObHook hook, struct _ObActionsAct *act)
        config file */
     hooks[hook] = g_slist_append(hooks[hook], act);
 }
+
+void hooks_run_queue(void)
+{
+    gint i;
+
+    for (i = 0; i < queue_size; ++i) {
+        const ObHookQueue *q = &run_queue[i];
+
+        ob_debug("Running hook %s for client 0x%x", names[q->hook],
+                 (q->client ? q->client->window : 0));
+        actions_run_acts(hooks[q->hook],
+                         OB_USER_ACTION_HOOK,
+                         0, -1, -1, 0,
+                         OB_FRAME_CONTEXT_NONE,
+                         q->client);
+    }
+    queue_size = 0;
+}
index 442eef0..322f952 100644 (file)
@@ -32,12 +32,11 @@ void hooks_shutdown(gboolean reconfig);
 
 ObHook hooks_hook_from_name(const gchar *n);
 
-/*! Run a hook.
-  @param on TRUE if the hook is being run cuz a state was turned on, FALSE
-            if a state was turned off
-*/
+void hooks_queue(ObHook hook, struct _ObClient *c);
 void hooks_run(ObHook hook, struct _ObClient *c);
 
 void hooks_add(ObHook hook, struct _ObActionsAct *act);
 
+void hooks_run_queue(void);
+
 #endif
index 3432ac4..cd46c53 100644 (file)
@@ -710,7 +710,7 @@ void screen_set_desktop(guint num, gboolean dofocus)
     if (event_curtime != CurrentTime)
         screen_desktop_user_time = event_curtime;
 
-    hooks_run(OB_HOOK_SCREEN_DESK_CHANGE, NULL);
+    hooks_queue(OB_HOOK_SCREEN_DESK_CHANGE, NULL);
 }
 
 void screen_add_desktop(gboolean current)