New SendKeyEvent and SetKeyTarget actions.
authorMikael Magnusson <mikachu@comhem.se>
Tue, 5 Feb 2008 10:19:10 +0000 (11:19 +0100)
committerMikael Magnusson <mikachu@gmail.com>
Sun, 19 Sep 2010 15:53:23 +0000 (17:53 +0200)
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
obt/prop.c
obt/prop.h
openbox/actions/all.c
openbox/actions/all.h
openbox/actions/sendkeyevent.c [new file with mode: 0644]
po/POTFILES.in

index 71ecbb4126b39cb82c6a6de4895e39f0efa39c6b..26f3f729f0887f875f9ba1152ea040c6e960f548 100644 (file)
@@ -217,6 +217,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/shadelowerraise.c \
        openbox/actions/showdesktop.c \
index bef9c9996d4d091707d7cf9ed4b0016c6da7025d..693d4d2b544db13c8ca453deeb983259a176b8b3 100644 (file)
@@ -196,6 +196,7 @@ void obt_prop_startup(void)
     CREATE_(OB_APP_NAME);
     CREATE_(OB_APP_CLASS);
     CREATE_(OB_APP_TYPE);
+    CREATE_(OB_TARGET_WINDOW);
 }
 
 Atom obt_prop_atom(ObtPropAtom a)
index 7ccc218e195ab1d0a09debcc101b0746ddf610e8..621376d22468a471a04dabd7cc0fd2fbe6af9c97 100644 (file)
@@ -217,6 +217,7 @@ typedef enum {
     OBT_PROP_OB_APP_NAME,
     OBT_PROP_OB_APP_CLASS,
     OBT_PROP_OB_APP_TYPE,
+    OBT_PROP_OB_TARGET_WINDOW,
 
     OBT_PROP_NUM_ATOMS
 } ObtPropAtom;
index 7b226b1f5579d1771bc518d9beefe3de36c857fa..1c0e21a9f704a00e9a8bee83d165730cdf0be2b9 100644 (file)
@@ -40,6 +40,7 @@ void action_all_startup(void)
     action_growtoedge_startup();
     action_if_startup();
     action_focustobottom_startup();
+    action_sendkeyevent_startup();
     /* 3.4-compatibility */
     action_shadelowerraise_startup();
 }
index ec576844820375df22e12d2a8178f38e4c2e368c..cc3f580d9f8cb636b026ca7f9825be67957c6da6 100644 (file)
@@ -41,6 +41,7 @@ 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);
 /* 3.4-compatibility */
 void action_shadelowerraise_startup(void);
 
diff --git a/openbox/actions/sendkeyevent.c b/openbox/actions/sendkeyevent.c
new file mode 100644 (file)
index 0000000..72be282
--- /dev/null
@@ -0,0 +1,92 @@
+#include "openbox/actions.h"
+#include "openbox/client.h"
+#include "openbox/window.h"
+#include "openbox/translate.h"
+#include "obt/display.h"
+#include "obt/prop.h"
+#include "openbox/openbox.h"
+#include "gettext.h"
+
+typedef struct {
+    guint key;
+    guint state;
+    gboolean target;
+} Options;
+
+static gpointer setup_sendkey_func(xmlNodePtr node);
+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);
+    actions_register("SetKeyTarget",
+                     NULL, NULL,
+                     settarget);
+    OBT_PROP_GET32(obt_root(ob_screen), OB_TARGET_WINDOW, WINDOW, (guint32 *)&target);
+}
+
+static gpointer setup_sendkey_func(xmlNodePtr node)
+{
+    xmlNodePtr n;
+    Options *o;
+
+    o = g_new0(Options, 1);
+    o->target = TRUE;
+
+    if ((n = obt_xml_find_node(node, "key"))) {
+        gchar *s = obt_xml_node_string(n);
+        translate_key(s, &o->state, &o->key);
+        g_free(s);
+    } else
+        translate_key("space", &o->state, &o->key);
+    if ((n = obt_xml_find_node(node, "usetarget")))
+        o->target = obt_xml_node_bool(n);
+
+    return o;
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean sendkey(ObActionsData *data, gpointer options)
+{
+    Options *o = options;
+    XEvent ev;
+    Window win;
+
+    if (!o->key) /* the key couldn't be parsed */
+        return FALSE;
+
+    if (o->target)
+        win = target;
+    else if (data->client)
+        win = data->client->window;
+    else
+        return FALSE;
+
+    ev.xkey.window = win;
+    ev.xkey.state = o->state;
+    ev.xkey.keycode = o->key;
+    obt_display_ignore_errors(TRUE);
+    ev.type = KeyPress;
+    XSendEvent(obt_display, win, False, 0, &ev);
+    ev.type = KeyRelease;
+    XSendEvent(obt_display, win, 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;
+      OBT_PROP_SET32(obt_root(ob_screen), OB_TARGET_WINDOW, WINDOW, target);
+    }
+
+    return FALSE;
+}
index 45097149367093a4b4cc93d43319e1a4d0e408b8..326a5e72d8f96cc6e3f37072baf9e686bb7dc582 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