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>
Sat, 11 Oct 2014 00:17:19 +0000 (02:17 +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]
openbox/screen.c
po/POTFILES.in

index e7ef29fcf5a85e6b7dbb4467e9a768a10a3ae5d6..d14042e8d70abca5d15d3c5ba9e92d0d8bc59da4 100644 (file)
@@ -231,6 +231,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 0cecccf4dfa6d5b160a78e515aeca185b2b462f5..ad40b2b9f609fc03ca46c318f4cd73442d4eb216 100644 (file)
@@ -200,6 +200,7 @@ void obt_prop_startup(void)
     CREATE_(OB_APP_GROUP_NAME);
     CREATE_(OB_APP_GROUP_CLASS);
     CREATE_(OB_APP_TYPE);
+    CREATE_(OB_TARGET_WINDOW);
 }
 
 Atom obt_prop_atom(ObtPropAtom a)
index acb5c956ede42d3c1ca2182de40218e5d071df1c..804ac4091f43b6370b69b37c5fa35f5722781f7f 100644 (file)
@@ -222,6 +222,7 @@ typedef enum {
     OBT_PROP_OB_APP_GROUP_NAME,
     OBT_PROP_OB_APP_GROUP_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 e758ada1c5207f2abd82fd2e94351ea61d2d89e5..d254c5285b6094dfbafb56fec13ece424cbffe6d 100644 (file)
@@ -308,6 +308,7 @@ gboolean screen_annex(void)
     supported[i++] = OBT_PROP_ATOM(OB_APP_GROUP_NAME);
     supported[i++] = OBT_PROP_ATOM(OB_APP_GROUP_CLASS);
     supported[i++] = OBT_PROP_ATOM(OB_APP_TYPE);
+    supported[i++] = OBT_PROP_ATOM(OB_TARGET_WINDOW);
     g_assert(i == num_support);
 
     OBT_PROP_SETA32(obt_root(ob_screen),
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