New SendKeyEvent and SetKeyTarget actions.
authorMikael Magnusson <mikachu@comhem.se>
Tue, 5 Feb 2008 10:19:10 +0000 (11:19 +0100)
committerMikael Magnusson <mikachu@comhem.se>
Sat, 1 Mar 2008 17:26:35 +0000 (18:26 +0100)
These let you define SendKeyEvent actions that send a specified key to a target
 window. The target window can be changed at runtime with the SetKeyTarget action.

Makefile.am
openbox/actions/all.c
openbox/actions/all.h
openbox/actions/sendkeyevent.c [new file with mode: 0644]
po/POTFILES.in

index 83bdcf0..24ed0a9 100644 (file)
@@ -204,6 +204,7 @@ openbox_openbox_SOURCES = \
        openbox/actions/resize.c \
        openbox/actions/resizerelative.c \
        openbox/actions/restart.c \
+       openbox/actions/sendkeyevent.c \
        openbox/actions/shade.c \
        openbox/actions/showdesktop.c \
        openbox/actions/showmenu.c \
index 0ac0dae..f5d5d06 100644 (file)
@@ -39,4 +39,5 @@ void action_all_startup(void)
     action_growtoedge_startup();
     action_if_startup();
     action_focustobottom_startup();
+    action_sendkeyevent_startup();
 }
index ac58260..332e8d1 100644 (file)
@@ -40,5 +40,6 @@ void action_movetoedge_startup(void);
 void action_growtoedge_startup(void);
 void action_if_startup(void);
 void action_focustobottom_startup(void);
+void action_sendkeyevent_startup(void);
 
 #endif
diff --git a/openbox/actions/sendkeyevent.c b/openbox/actions/sendkeyevent.c
new file mode 100644 (file)
index 0000000..2817882
--- /dev/null
@@ -0,0 +1,89 @@
+#include "openbox/actions.h"
+#include "openbox/client.h"
+#include "openbox/window.h"
+#include "obt/display.h"
+#include "gettext.h"
+
+typedef struct {
+    KeyCode key;
+} Options;
+
+static gpointer setup_sendkey_func(xmlNodePtr node);
+static void free_sendkey_func(gpointer options);
+static gboolean sendkey(ObActionsData *data, gpointer options);
+static gboolean settarget(ObActionsData *data, gpointer options);
+
+static Window target;
+
+void action_sendkeyevent_startup(void)
+{
+    actions_register("SendKeyEvent",
+                     setup_sendkey_func, g_free,
+                     sendkey,
+                     NULL, NULL);
+    actions_register("SetKeyTarget",
+                     NULL, NULL,
+                     settarget,
+                     NULL, NULL);
+}
+
+static KeyCode parse_key(gchar *s)
+{
+    KeySym sym;
+
+    sym = XStringToKeysym(s);
+    if (sym == NoSymbol) {
+        g_warning(_("Invalid key name '%s' in SendKeyEvent action."), s);
+        return 0;
+    }
+
+    return XKeysymToKeycode(obt_display, sym);
+}
+
+static gpointer setup_sendkey_func(xmlNodePtr node)
+{
+    xmlNodePtr n;
+    Options *o;
+
+    o = g_new0(Options, 1);
+
+    if ((n = obt_parse_find_node(node, "key"))) {
+        gchar *s = obt_parse_node_string(n);
+        o->key = parse_key(s);
+        g_free(s);
+    } else
+        o->key = parse_key("space");
+
+    return o;
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean sendkey(ObActionsData *data, gpointer options)
+{
+    Options *o = options;
+    XEvent ev;
+
+    if (!o->key) /* the key couldn't be parsed */
+        return FALSE;
+
+    ev.xkey.window = target;
+    ev.xkey.state = 0;
+    ev.xkey.keycode = o->key;
+    obt_display_ignore_errors(TRUE);
+    ev.type = KeyPress;
+    XSendEvent(obt_display, target, False, 0, &ev);
+    ev.type = KeyRelease;
+    XSendEvent(obt_display, target, False, 0, &ev);
+    obt_display_ignore_errors(FALSE);
+
+    return FALSE;
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean settarget(ObActionsData *data, gpointer options)
+{
+    if (data->client)
+      target = data->client->window;
+
+    return FALSE;
+}
index 200e9ca..f61e443 100644 (file)
@@ -2,6 +2,7 @@
 openbox/actions.c
 openbox/actions/execute.c
 openbox/actions/exit.c
+openbox/actions/sendkeyevent.c
 openbox/client.c
 openbox/client_list_combined_menu.c
 openbox/client_list_menu.c