Add a hook system. They hooks don't run yet but they parse from the config file.
authorDana Jansens <danakj@orodu.net>
Sat, 1 Mar 2008 04:16:31 +0000 (23:16 -0500)
committerDana Jansens <danakj@orodu.net>
Sat, 1 Mar 2008 04:37:57 +0000 (23:37 -0500)
Makefile.am
openbox/config.c
openbox/hooks.c [new file with mode: 0644]
openbox/hooks.h [new file with mode: 0644]
openbox/misc.h
openbox/openbox.c

index b721508..9027759 100644 (file)
@@ -242,6 +242,8 @@ openbox_openbox_SOURCES = \
        openbox/grab.h \
        openbox/group.c \
        openbox/group.h \
+       openbox/hooks.c \
+       openbox/hooks.h \
        openbox/keyboard.c \
        openbox/keyboard.h \
        openbox/keytree.c \
index 109b215..cc86ce7 100644 (file)
@@ -22,6 +22,7 @@
 #include "mouse.h"
 #include "actions.h"
 #include "translate.h"
+#include "hooks.h"
 #include "client.h"
 #include "screen.h"
 #include "openbox.h"
@@ -342,6 +343,47 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d)
     }
 }
 
+static void parse_hook(xmlNodePtr node, gpointer d)
+{
+    gchar *name;
+    ObHook hook;
+    xmlNodePtr n;
+
+
+    if (!obt_parse_attr_string(node, "name", &name)) {
+        g_message(_("Hook in config file is missing a name"));
+        return;
+    }
+
+    hook = hooks_hook_from_name(name);
+    if (!hook)
+        g_message(_("Unknown hook \"%s\" in config file"), name);
+    else {
+        if ((n = obt_parse_find_node(node->children, "action")))
+            while (n) {
+                ObActionsAct *action;
+
+                action = actions_parse(n);
+                if (action)
+                    hooks_add(hook, action);
+                n = obt_parse_find_node(n->next, "action");
+            }
+    }
+
+    g_free(name);
+}
+
+static void parse_hooks(xmlNodePtr node, gpointer d)
+{
+    xmlNodePtr n;
+
+    if ((n = obt_parse_find_node(node->children, "hook")))
+        while (n) {
+            parse_hook(n, NULL);
+            n = obt_parse_find_node(n->next, "hook");
+        }
+}
+
 /*
 
 <keybind key="C-x">
@@ -987,6 +1029,8 @@ void config_startup(ObtParseInst *i)
 
     obt_parse_register(i, "menu", parse_menu, NULL);
 
+    obt_parse_register(i, "hooks", parse_hooks, NULL);
+
     config_per_app_settings = NULL;
 
     obt_parse_register(i, "applications", parse_per_app_settings, NULL);
diff --git a/openbox/hooks.c b/openbox/hooks.c
new file mode 100644 (file)
index 0000000..4cf97c0
--- /dev/null
@@ -0,0 +1,81 @@
+#include "hooks.h"
+#include "actions.h"
+
+#include <glib.h>
+
+static GSList *hooks[OB_NUM_HOOKS*2];
+
+void hooks_startup(gboolean reconfig)
+{
+}
+
+void hooks_shutdown(gboolean reconfig)
+{
+    gint i;
+
+    for (i = 0; i < OB_NUM_HOOKS*2; ++i)
+        while (hooks[i]) {
+            actions_act_unref(hooks[i]->data);
+            hooks[i] = g_slist_delete_link(hooks[i], hooks[i]);
+        }
+}
+
+ObHook hooks_hook_from_name(const gchar *n)
+{
+    if (!g_ascii_strcasecmp(n, "WindowNew"))
+        return OB_HOOK_WIN_NEW;
+    if (!g_ascii_strcasecmp(n, "WindowClosed"))
+        return OB_HOOK_WIN_CLOSE;
+    if (!g_ascii_strcasecmp(n, "WindowVisible"))
+        return OB_HOOK_WIN_VISIBLE;
+    if (!g_ascii_strcasecmp(n, "WindowInvisible"))
+        return OB_HOOK_WIN_INVISIBLE;
+    if (!g_ascii_strcasecmp(n, "WindowIconified"))
+        return OB_HOOK_WIN_ICONIC;
+    if (!g_ascii_strcasecmp(n, "WindowUniconified"))
+        return OB_HOOK_WIN_UNICONIC;
+    if (!g_ascii_strcasecmp(n, "WindowMaximized"))
+        return OB_HOOK_WIN_MAX;
+    if (!g_ascii_strcasecmp(n, "WindowUnmaximized"))
+        return OB_HOOK_WIN_UNMAX;
+    if (!g_ascii_strcasecmp(n, "WindowShaded"))
+        return OB_HOOK_WIN_SHADE;
+    if (!g_ascii_strcasecmp(n, "WindowUnshaded"))
+        return OB_HOOK_WIN_UNSHADE;
+    if (!g_ascii_strcasecmp(n, "WindowFocused"))
+        return OB_HOOK_WIN_FOCUS;
+    if (!g_ascii_strcasecmp(n, "WindowUnfocused"))
+        return OB_HOOK_WIN_UNFOCUS;
+    if (!g_ascii_strcasecmp(n, "WindowOnCurrentDesktop"))
+        return OB_HOOK_WIN_CURRENT_DESK;
+    if (!g_ascii_strcasecmp(n, "WindowOnOtherDesktop"))
+        return OB_HOOK_WIN_OTHER_DESK;
+    if (!g_ascii_strcasecmp(n, "WindowDecorated"))
+        return OB_HOOK_WIN_DECORATED;
+    if (!g_ascii_strcasecmp(n, "WindowUndecorated"))
+        return OB_HOOK_WIN_UNDECORATED;
+    return OB_HOOK_INVALID;
+}
+
+void hooks_fire(ObHook hook, struct _ObClient *c)
+{
+    GSList *it;
+
+    g_assert(hook < OB_NUM_HOOKS);
+
+    for (it = hooks[hook]; it; it = g_slist_next(it))
+        actions_run_acts(it->data,
+                         OB_USER_ACTION_HOOK,
+                         0, -1, -1, 0,
+                         OB_FRAME_CONTEXT_NONE,
+                         c);
+}
+
+void hooks_add(ObHook hook, struct _ObActionsAct *act)
+{
+    g_assert(hook < OB_NUM_HOOKS);
+
+    /* append so they are executed in the same order as they appear in the
+       config file */
+    hooks[hook] = g_slist_append(hooks[hook], act);
+}
diff --git a/openbox/hooks.h b/openbox/hooks.h
new file mode 100644 (file)
index 0000000..16ed632
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef ob__hooks_h
+#define ob__hooks_h
+
+#include <glib.h>
+
+struct _ObActionsAct;
+struct _ObClient;
+
+typedef enum {
+    OB_HOOK_INVALID,
+    OB_HOOK_WIN_NEW,
+    OB_HOOK_WIN_CLOSE,
+    OB_HOOK_WIN_VISIBLE,
+    OB_HOOK_WIN_INVISIBLE,
+    OB_HOOK_WIN_ICONIC,
+    OB_HOOK_WIN_UNICONIC,
+    OB_HOOK_WIN_MAX,
+    OB_HOOK_WIN_UNMAX,
+    OB_HOOK_WIN_SHADE,
+    OB_HOOK_WIN_UNSHADE,
+    OB_HOOK_WIN_FOCUS,
+    OB_HOOK_WIN_UNFOCUS,
+    OB_HOOK_WIN_CURRENT_DESK,
+    OB_HOOK_WIN_OTHER_DESK,
+    OB_HOOK_WIN_DECORATED,
+    OB_HOOK_WIN_UNDECORATED,
+    OB_NUM_HOOKS
+} ObHook;
+
+void hooks_startup(gboolean reconfig);
+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_fire(ObHook hook, struct _ObClient *c);
+
+void hooks_add(ObHook hook, struct _ObActionsAct *act);
+
+#endif
index c73c926..13530ed 100644 (file)
@@ -107,6 +107,7 @@ typedef enum {
     OB_USER_ACTION_MOUSE_DOUBLE_CLICK,
     OB_USER_ACTION_MOUSE_MOTION,
     OB_USER_ACTION_MENU_SELECTION,
+    OB_USER_ACTION_HOOK,
     OB_NUM_USER_ACTIONS
 } ObUserAction;
 
index 49587ab..79b080d 100644 (file)
@@ -42,6 +42,7 @@
 #include "config.h"
 #include "ping.h"
 #include "prompt.h"
+#include "hooks.h"
 #include "gettext.h"
 #include "render/render.h"
 #include "render/theme.h"
@@ -297,6 +298,7 @@ gint main(gint argc, gchar **argv)
             /* focus_backup is used for stacking, so this needs to come before
                anything that calls stacking_add */
             sn_startup(reconfigure);
+            hooks_startup(reconfigure);
             window_startup(reconfigure);
             focus_startup(reconfigure);
             focus_cycle_startup(reconfigure);
@@ -373,6 +375,7 @@ gint main(gint argc, gchar **argv)
             focus_cycle_shutdown(reconfigure);
             focus_shutdown(reconfigure);
             window_shutdown(reconfigure);
+            hooks_shutdown(reconfigure);
             sn_shutdown(reconfigure);
             event_shutdown(reconfigure);
             config_shutdown();