]> icculus.org git repositories - mikachu/openbox.git/blob - openbox/actions/sendkeyevent.c
Save target window across restarts for sendkeyevent.
[mikachu/openbox.git] / openbox / actions / sendkeyevent.c
1 #include "openbox/actions.h"
2 #include "openbox/client.h"
3 #include "openbox/window.h"
4 #include "obt/display.h"
5 #include "obt/prop.h"
6 #include "openbox/openbox.h"
7 #include "gettext.h"
8
9 typedef struct {
10     KeyCode key;
11 } Options;
12
13 static gpointer setup_sendkey_func(xmlNodePtr node);
14 static void free_sendkey_func(gpointer options);
15 static gboolean sendkey(ObActionsData *data, gpointer options);
16 static gboolean settarget(ObActionsData *data, gpointer options);
17
18 static Window target;
19
20 void action_sendkeyevent_startup(void)
21 {
22     actions_register("SendKeyEvent",
23                      setup_sendkey_func, g_free,
24                      sendkey,
25                      NULL, NULL);
26     actions_register("SetKeyTarget",
27                      NULL, NULL,
28                      settarget,
29                      NULL, NULL);
30     OBT_PROP_GET32(obt_root(ob_screen), OB_TARGET_WINDOW, WINDOW, (guint32 *)&target);
31 }
32
33 static KeyCode parse_key(gchar *s)
34 {
35     KeySym sym;
36
37     sym = XStringToKeysym(s);
38     if (sym == NoSymbol) {
39         g_warning(_("Invalid key name '%s' in SendKeyEvent action."), s);
40         return 0;
41     }
42
43     return XKeysymToKeycode(obt_display, sym);
44 }
45
46 static gpointer setup_sendkey_func(xmlNodePtr node)
47 {
48     xmlNodePtr n;
49     Options *o;
50
51     o = g_new0(Options, 1);
52
53     if ((n = obt_parse_find_node(node, "key"))) {
54         gchar *s = obt_parse_node_string(n);
55         o->key = parse_key(s);
56         g_free(s);
57     } else
58         o->key = parse_key("space");
59
60     return o;
61 }
62
63 /* Always return FALSE because its not interactive */
64 static gboolean sendkey(ObActionsData *data, gpointer options)
65 {
66     Options *o = options;
67     XEvent ev;
68
69     if (!o->key) /* the key couldn't be parsed */
70         return FALSE;
71
72     ev.xkey.window = target;
73     ev.xkey.state = 0;
74     ev.xkey.keycode = o->key;
75     obt_display_ignore_errors(TRUE);
76     ev.type = KeyPress;
77     XSendEvent(obt_display, target, False, 0, &ev);
78     ev.type = KeyRelease;
79     XSendEvent(obt_display, target, False, 0, &ev);
80     obt_display_ignore_errors(FALSE);
81
82     return FALSE;
83 }
84
85 /* Always return FALSE because its not interactive */
86 static gboolean settarget(ObActionsData *data, gpointer options)
87 {
88     if (data->client) {
89       target = data->client->window;
90       OBT_PROP_SET32(obt_root(ob_screen), OB_TARGET_WINDOW, WINDOW, target);
91     }
92
93     return FALSE;
94 }