wmclockmon: update change-log
[dockapps.git] / wmcliphist / hotkeys.c
blob7ad8b096bcd9755f83e74c4dfeeee86bd4a28a5c
1 #include "wmcliphist.h"
2 #include <gdk/gdkkeysyms.h>
4 /* Exec on hotkey? */
5 int exec_hotkey = 1;
7 /* hotkeys */
8 gchar menukey_str[32] = DEF_MENUKEY;
9 guint menukey;
10 guint menukey_mask;
12 gchar prev_item_key_str[32] = DEF_PREV_ITEM_KEY;
13 guint prev_item_key;
14 guint prev_item_mask;
16 gchar exec_item_key_str[32] = DEF_EXEC_ITEM_KEY;
17 guint exec_item_key;
18 guint exec_item_mask;
21 * filter grabbed hotkeys
23 GdkFilterReturn
24 global_keys_filter(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
26 XEvent *xevent = (XEvent *)gdk_xevent;
28 begin_func("global_keys_filter");
30 if (xevent->type == KeyPress) {
31 if (xevent->xkey.keycode ==
32 XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), menukey) &&
33 xevent->xkey.state & menukey_mask) {
34 /* popup history menu */
35 gtk_menu_popup(GTK_MENU(menu_hist),
36 NULL, NULL,
37 NULL, NULL,
39 GDK_CURRENT_TIME);
40 return_val(GDK_FILTER_REMOVE);
41 } else if (xevent->xkey.keycode ==
42 XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), prev_item_key)
43 && xevent->xkey.state & prev_item_mask) {
44 /* switch first two history items */
45 GList *second;
46 if (history_items == NULL) {
47 return_val(GDK_FILTER_REMOVE);
49 second = g_list_first(history_items)->next;
50 if (second == NULL) {
51 return_val(GDK_FILTER_REMOVE);
54 move_item_to_begin((HISTORY_ITEM *) second->data);
56 return_val(GDK_FILTER_REMOVE);
57 } else if (xevent->xkey.keycode ==
58 XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), exec_item_key) &&
59 xevent->xkey.state & exec_item_mask) {
60 /* exec command on current item */
61 if (exec_hotkey) {
62 HISTORY_ITEM *hist_item;
63 hist_item = (HISTORY_ITEM *) g_list_first(history_items)->data;
64 exec_item(hist_item->content, NULL);
66 return_val(GDK_FILTER_REMOVE);
70 return_val(GDK_FILTER_CONTINUE);
75 * parse key string
77 int
78 hotkey_parse(char *hotkey, guint *key, guint *mask)
80 char c;
81 char *tmp = g_new0(char, strlen(hotkey));
82 int i, idx = 0;
84 begin_func("hotkey_parse");
86 *mask = 0;
88 for (i = 0; i < strlen(hotkey); i++) {
89 c = hotkey[i];
90 if (isalpha(c)) {
91 tmp[idx++] = c;
92 tmp[idx] = '\0';
93 } else if (c == '+' || c == '-') {
94 idx = 0;
95 if (strcasecmp(tmp, "control") == 0 ||
96 strcasecmp(tmp, "ctrl") == 0)
97 *mask |= ControlMask;
98 else if (strcasecmp(tmp, "alt") == 0)
99 *mask |= Mod1Mask;
100 else if (strcasecmp(tmp, "shift") == 0)
101 *mask |= ShiftMask;
102 else {
103 fprintf(stderr, "Invalid key modifier: %s\n",
104 tmp);
105 g_free(tmp);
106 return_val(-1);
111 if ((*key = gdk_keyval_from_name(tmp)) == GDK_KEY_VoidSymbol) {
112 g_free(tmp);
113 return_val(-1);
116 g_free(tmp);
117 return_val(0);
122 #define grab_key(keysym, basemask) \
123 XGrabKey(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym), \
124 basemask, GDK_ROOT_WINDOW(), True, GrabModeAsync, \
125 GrabModeAsync); \
126 XGrabKey(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym), \
127 basemask | LockMask, GDK_ROOT_WINDOW(), True, \
128 GrabModeAsync, GrabModeAsync); \
129 XGrabKey(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym), \
130 basemask | Mod2Mask, GDK_ROOT_WINDOW(), True, \
131 GrabModeAsync, GrabModeAsync); \
132 XGrabKey(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym), \
133 basemask | Mod2Mask | LockMask, GDK_ROOT_WINDOW(), \
134 True, GrabModeAsync, GrabModeAsync);
137 #define ungrab_key(keysym, basemask) \
138 XUngrabKey(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym), \
139 basemask, GDK_ROOT_WINDOW()); \
140 XUngrabKey(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym), \
141 basemask | LockMask, GDK_ROOT_WINDOW()); \
142 XUngrabKey(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym), \
143 basemask | Mod2Mask, GDK_ROOT_WINDOW()); \
144 XUngrabKey(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), XKeysymToKeycode(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), keysym), \
145 basemask | Mod2Mask | LockMask, GDK_ROOT_WINDOW());
149 * initialize hotkeys
151 void
152 hotkeys_init()
154 char msg_str[128];
156 begin_func("hotkeys_init");
158 if (hotkey_parse(menukey_str, &menukey, &menukey_mask) != 0) {
159 sprintf(msg_str, "Invalid menu hotkey '%s'.\nFalling back to "
160 "default (" DEF_MENUKEY ")\n", menukey_str);
161 show_message(msg_str, "Warning", "OK", NULL, NULL);
162 strcpy(menukey_str, DEF_MENUKEY);
163 hotkey_parse(menukey_str, &menukey, &menukey_mask);
165 if (hotkey_parse(prev_item_key_str, &prev_item_key, &prev_item_mask) != 0) {
166 sprintf(msg_str, "Invalid previous item hotkey '%s'.\n"
167 "Falling back to default (" DEF_PREV_ITEM_KEY
168 ")\n", prev_item_key_str);
169 show_message(msg_str, "Warning", "OK", NULL, NULL);
170 hotkey_parse(DEF_PREV_ITEM_KEY, &prev_item_key,
171 &prev_item_mask);
173 if (hotkey_parse(exec_item_key_str, &exec_item_key, &exec_item_mask) != 0) {
174 sprintf(msg_str, "Invalid exec hotkey '%s'.\n"
175 "Falling back to default (" DEF_EXEC_ITEM_KEY
176 ")\n", exec_item_key_str);
177 show_message(msg_str, "Warning", "OK", NULL, NULL);
178 hotkey_parse(DEF_EXEC_ITEM_KEY, &exec_item_key,
179 &exec_item_mask);
181 gdk_window_add_filter(gdk_get_default_root_window(), global_keys_filter, NULL);
182 grab_key(menukey, menukey_mask);
183 grab_key(prev_item_key, prev_item_mask);
184 grab_key(exec_item_key, exec_item_mask);
186 return_void();
190 * disable hotkeys
192 void
193 hotkeys_done()
195 begin_func("hotkeys_done");
196 ungrab_key(menukey, menukey_mask);
197 return_void();