Skip to content

Commit b038857

Browse files
committed
Win32 global hotkeys MVP
1 parent 9e7fbb1 commit b038857

File tree

13 files changed

+1004
-241
lines changed

13 files changed

+1004
-241
lines changed

configure.ac

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,20 @@ ENABLE_PLUGIN_WITH_DEP(hotkey,
479479
GDKX11,
480480
gdk-x11-2.0)
481481

482+
483+
test_hotkeyw32 () {
484+
if test $HAVE_MSWINDOWS = yes ; then
485+
have_hotkeyw32=yes
486+
else
487+
have_hotkeyw32=no
488+
fi
489+
}
490+
491+
ENABLE_PLUGIN_WITH_TEST(hotkeyw32,
492+
Windows hotkeys plugin,
493+
auto,
494+
GENERAL)
495+
482496
ENABLE_PLUGIN_WITH_DEP(aosd,
483497
X11 OSD,
484498
auto,
@@ -831,6 +845,7 @@ if test "x$USE_GTK" = "xyes" ; then
831845
echo " Status Icon: yes"
832846
echo " X11 Global Hotkeys: $have_hotkey"
833847
echo " X11 On-Screen Display (aosd): $have_aosd"
848+
echo " Windows Global hotkeys: $have_hotkeyw32"
834849
echo
835850
fi
836851

src/hotkey/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
PLUGIN = hotkey${PLUGIN_SUFFIX}
22

3-
SRCS = plugin.cc gui.cc grab.cc
3+
SRCS = plugin.cc gui.cc grab.cc x_hotkey.cc hotkey_api_common.cc
44

55
include ../../buildsys.mk
66
include ../../extra.mk

src/hotkey/api_hotkey.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#ifndef _X_HOTKEY_H_INCLUDED
2+
#define _X_HOTKEY_H_INCLUDED
3+
4+
#include <gtk/gtkstyle.h>
5+
#include <utility>
6+
#ifndef _WIN32
7+
#include <X11/X.h>
8+
#include <X11/XF86keysym.h>
9+
#endif
10+
#include "plugin.h"
11+
12+
13+
14+
class Hotkey {
15+
16+
//#ifdef _WIN32
17+
//#define OS_KeySym int
18+
//#else
19+
//#define OS_KeySym KeySym
20+
//#endif
21+
22+
#ifdef _WIN32
23+
typedef int OS_KeySym;
24+
#else
25+
typedef KeySym OS_KeySym;
26+
#endif
27+
28+
public:
29+
static void set_keytext(GtkWidget *entry, int key, int mask, int type);
30+
static std::pair<int, int> get_is_mod(GdkEventKey *event);
31+
template <typename T_GDK_EVENT>
32+
static int calculate_mod(T_GDK_EVENT *event);
33+
static void add_hotkey(HotkeyConfiguration **pphotkey, OS_KeySym keysym, int mask, int type, EVENT event);
34+
static void key_to_string(int key, char **out_keytext);
35+
};
36+
37+
#ifndef _WIN32
38+
#define OS_KEY_AudioPrev XF86XK_AudioPrev
39+
#define OS_KEY_AudioPlay XF86XK_AudioPlay
40+
#define OS_KEY_AudioPause XF86XK_AudioPause
41+
#define OS_KEY_AudioStop XF86XK_AudioStop
42+
#define OS_KEY_AudioNext XF86XK_AudioNext
43+
#define OS_KEY_AudioMute XF86XK_AudioMute
44+
#define OS_KEY_AudioRaiseVolume XF86XK_AudioRaiseVolume
45+
#define OS_KEY_AudioLowerVolume XF86XK_AudioLowerVolume
46+
#else
47+
48+
#define OS_KEY_AudioPrev 0
49+
#define OS_KEY_AudioPlay 0
50+
#define OS_KEY_AudioPause 0
51+
#define OS_KEY_AudioStop 0
52+
#define OS_KEY_AudioNext 0
53+
#define OS_KEY_AudioMute 0
54+
#define OS_KEY_AudioRaiseVolume 0
55+
#define OS_KEY_AudioLowerVolume 0
56+
57+
#endif
58+
59+
#endif //_X_HOTKEY_H_INCLUDED

src/hotkey/grab.cc

Lines changed: 91 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@
3434
*/
3535

3636
#include <gtk/gtk.h>
37+
38+
#ifndef _WIN32
3739
#include <gdk/gdkx.h>
40+
#else
41+
#include <X11/Xlib.h>
42+
#include <cassert>
43+
#include <libaudcore/runtime.h>
44+
#endif
3845

3946
#include "grab.h"
4047
#include "plugin.h"
@@ -46,6 +53,87 @@ static unsigned int scrolllock_mask = 0;
4653
static unsigned int capslock_mask = 0;
4754

4855

56+
static int x11_error_handler (Display *dpy, XErrorEvent *error)
57+
{
58+
return 0;
59+
}
60+
61+
static GdkFilterReturn
62+
gdk_filter(GdkXEvent *xevent,
63+
GdkEvent *event,
64+
void * data)
65+
{
66+
#ifdef _WIN32
67+
AUDDBG("lHotkeyFlow:win CommonGrab: Filter trigger.");
68+
assert(false);
69+
#endif
70+
HotkeyConfiguration *hotkey;
71+
hotkey = &(get_config()->first);
72+
switch (((XEvent*)xevent)->type)
73+
{
74+
case KeyPress:
75+
{
76+
XKeyEvent *keyevent = (XKeyEvent*)xevent;
77+
while (hotkey)
78+
{
79+
if ((hotkey->key == keyevent->keycode) &&
80+
(hotkey->mask == (keyevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) &&
81+
(hotkey->type == TYPE_KEY))
82+
{
83+
if (handle_keyevent(hotkey->event))
84+
return GDK_FILTER_REMOVE;
85+
break;
86+
}
87+
88+
hotkey = hotkey->next;
89+
}
90+
break;
91+
}
92+
case ButtonPress:
93+
{
94+
XButtonEvent *buttonevent = (XButtonEvent*)xevent;
95+
while (hotkey)
96+
{
97+
if ((hotkey->key == buttonevent->button) &&
98+
(hotkey->mask == (buttonevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) &&
99+
(hotkey->type == TYPE_MOUSE))
100+
{
101+
if (handle_keyevent(hotkey->event))
102+
return GDK_FILTER_REMOVE;
103+
break;
104+
}
105+
106+
hotkey = hotkey->next;
107+
}
108+
109+
break;
110+
}
111+
}
112+
113+
return GDK_FILTER_CONTINUE;
114+
}
115+
116+
gboolean setup_filter()
117+
{
118+
#ifdef _WIN32
119+
AUDDBG("lHotkeyFlow:win CommonGrab: filter up");
120+
#endif
121+
gdk_window_add_filter (gdk_screen_get_root_window
122+
(gdk_screen_get_default ()), gdk_filter, nullptr);
123+
124+
return true;
125+
}
126+
127+
void release_filter()
128+
{
129+
#ifdef _WIN32
130+
AUDDBG("lHotkeyFlow:win CommonGrab: down filter");
131+
#endif
132+
gdk_window_remove_filter (gdk_screen_get_root_window
133+
(gdk_screen_get_default ()), gdk_filter, nullptr);
134+
}
135+
136+
#ifndef _WIN32
49137
/* Taken from xbindkeys */
50138
static void get_offending_modifiers (Display * dpy)
51139
{
@@ -54,8 +142,8 @@ static void get_offending_modifiers (Display * dpy)
54142
KeyCode nlock, slock;
55143

56144
static int mask_table[8] = {
57-
ShiftMask, LockMask, ControlMask, Mod1Mask,
58-
Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
145+
HK_SHIFT_MASK, LockMask, HK_CONTROL_MASK, HK_MOD1_ALT_MASK,
146+
HK_MOD2_MASK, HK_MOD3_MASK, HK_MOD4_MASK, HK_MOD5_MASK
59147
};
60148

61149
nlock = XKeysymToKeycode (dpy, XK_Num_Lock);
@@ -84,12 +172,6 @@ static void get_offending_modifiers (Display * dpy)
84172
XFreeModifiermap (modmap);
85173
}
86174

87-
88-
static int x11_error_handler (Display *dpy, XErrorEvent *error)
89-
{
90-
return 0;
91-
}
92-
93175
/* grab required keys */
94176
static void grab_key(const HotkeyConfiguration *hotkey, Display *xdisplay, Window x_root_window)
95177
{
@@ -320,69 +402,4 @@ void ungrab_keys ( )
320402

321403
grabbed = 0;
322404
}
323-
324-
325-
static GdkFilterReturn
326-
gdk_filter(GdkXEvent *xevent,
327-
GdkEvent *event,
328-
void * data)
329-
{
330-
HotkeyConfiguration *hotkey;
331-
hotkey = &(get_config()->first);
332-
switch (((XEvent*)xevent)->type)
333-
{
334-
case KeyPress:
335-
{
336-
XKeyEvent *keyevent = (XKeyEvent*)xevent;
337-
while (hotkey)
338-
{
339-
if ((hotkey->key == keyevent->keycode) &&
340-
(hotkey->mask == (keyevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) &&
341-
(hotkey->type == TYPE_KEY))
342-
{
343-
if (handle_keyevent(hotkey->event))
344-
return GDK_FILTER_REMOVE;
345-
break;
346-
}
347-
348-
hotkey = hotkey->next;
349-
}
350-
break;
351-
}
352-
case ButtonPress:
353-
{
354-
XButtonEvent *buttonevent = (XButtonEvent*)xevent;
355-
while (hotkey)
356-
{
357-
if ((hotkey->key == buttonevent->button) &&
358-
(hotkey->mask == (buttonevent->state & ~(scrolllock_mask | numlock_mask | capslock_mask))) &&
359-
(hotkey->type == TYPE_MOUSE))
360-
{
361-
if (handle_keyevent(hotkey->event))
362-
return GDK_FILTER_REMOVE;
363-
break;
364-
}
365-
366-
hotkey = hotkey->next;
367-
}
368-
369-
break;
370-
}
371-
}
372-
373-
return GDK_FILTER_CONTINUE;
374-
}
375-
376-
gboolean setup_filter()
377-
{
378-
gdk_window_add_filter (gdk_screen_get_root_window
379-
(gdk_screen_get_default ()), gdk_filter, nullptr);
380-
381-
return true;
382-
}
383-
384-
void release_filter()
385-
{
386-
gdk_window_remove_filter (gdk_screen_get_root_window
387-
(gdk_screen_get_default ()), gdk_filter, nullptr);
388-
}
405+
#endif

0 commit comments

Comments
 (0)