#include "mouse.h"
#include "actions.h"
#include "translate.h"
+#include "hooks.h"
#include "client.h"
#include "screen.h"
#include "openbox.h"
}
}
+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">
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);
--- /dev/null
+#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);
+}
--- /dev/null
+#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
#include "config.h"
#include "ping.h"
#include "prompt.h"
+#include "hooks.h"
#include "gettext.h"
#include "render/render.h"
#include "render/theme.h"
/* 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);
focus_cycle_shutdown(reconfigure);
focus_shutdown(reconfigure);
window_shutdown(reconfigure);
+ hooks_shutdown(reconfigure);
sn_shutdown(reconfigure);
event_shutdown(reconfigure);
config_shutdown();