From db781556d63d1a50bd1b1b4b6b5423ef703bf2c7 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 29 Feb 2008 23:16:31 -0500 Subject: [PATCH] Add a hook system. They hooks don't run yet but they parse from the config file. --- Makefile.am | 2 ++ openbox/config.c | 44 ++++++++++++++++++++++++++++++ openbox/hooks.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ openbox/hooks.h | 43 +++++++++++++++++++++++++++++ openbox/misc.h | 1 + openbox/openbox.c | 3 +++ 6 files changed, 174 insertions(+) create mode 100644 openbox/hooks.c create mode 100644 openbox/hooks.h diff --git a/Makefile.am b/Makefile.am index b721508..9027759 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/openbox/config.c b/openbox/config.c index 109b215..cc86ce7 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -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"); + } +} + /* @@ -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 index 0000000..4cf97c0 --- /dev/null +++ b/openbox/hooks.c @@ -0,0 +1,81 @@ +#include "hooks.h" +#include "actions.h" + +#include + +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 index 0000000..16ed632 --- /dev/null +++ b/openbox/hooks.h @@ -0,0 +1,43 @@ +#ifndef ob__hooks_h +#define ob__hooks_h + +#include + +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 diff --git a/openbox/misc.h b/openbox/misc.h index c73c926..13530ed 100644 --- a/openbox/misc.h +++ b/openbox/misc.h @@ -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; diff --git a/openbox/openbox.c b/openbox/openbox.c index 49587ab..79b080d 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -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(); -- 1.9.1