TTKMusicPlayer  3.7.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
qglobalshortcut_x11.cpp
Go to the documentation of this file.
1 #include "qglobalshortcut_p.h"
2 #include <xcb/xcb.h>
3 #include <X11/Xlib.h>
4 #if !TTK_QT_VERSION_CHECK(6,0,0) && TTK_QT_VERSION_CHECK(5,1,0) || !TTK_QT_VERSION_CHECK(5,0,0)
5 #include <QX11Info>
6 static Display *X11Display()
7 {
8  return QX11Info::display();
9 }
10 
11 static Window X11RootWindow()
12 {
13  return QX11Info::appRootWindow();
14 }
15 #else
16 static Display *X11Display()
17 {
18  static Display *display = XOpenDisplay(/*getenv("DISPLAY")*/NULL);
19  return display;
20 }
21 
22 static Window X11RootWindow()
23 {
24  return XRootWindow(X11Display(), -1);
25 }
26 #endif
27 
28 //static int (*original_x_errhandler)(Display *display, XErrorEvent *event);
29 
30 //static int q_x_errhandler(Display *display, XErrorEvent *event)
31 //{
32 // Q_UNUSED(display);
33 // switch(event->error_code)
34 // {
35 // case BadAccess:
36 // case BadValue:
37 // case BadWindow:
38 // if(event->request_code == 33 /* X_GrabKey */ || event->request_code == 34 /* X_UngrabKey */)
39 // {
40 // QGlobalShortcutPrivate::m_error = true;
41 // //TODO:
42 // //char errstr[256];
43 // //XGetErrorText(dpy, err->error_code, errstr, 256);
44 // }
45 // default: return 0;
46 // }
47 //}
48 
49 #if !TTK_QT_VERSION_CHECK(5,0,0)
50 bool QGlobalShortcutPrivate::eventFilter(void *message)
51 {
52  XEvent *event = TTKStaticCast(XEvent*, message);
53  if(event->type == KeyPress)
54  {
55  XKeyEvent *key = TTKReinterpretCast(XKeyEvent*, event);
56  unsigned int keycode = key->keycode;
57  unsigned int keystate = key->state;
58 #else
59 bool QGlobalShortcutPrivate::nativeEventFilter(const QByteArray &type, void *message, qint *)
60 {
61  xcb_key_press_event_t *kev = nullptr;
62  if(type == "xcb_generic_event_t")
63  {
64  xcb_generic_event_t *event = TTKStaticCast(xcb_generic_event_t*, message);
65  if((event->response_type & 127) == XCB_KEY_PRESS)
66  {
67  kev = TTKStaticCast(xcb_key_press_event_t*, message);
68  }
69  }
70 
71  if(kev != nullptr)
72  {
73  unsigned int keycode = kev->detail;
74  unsigned int keystate = 0;
75 
76  if(kev->state & XCB_MOD_MASK_1)
77  keystate |= Mod1Mask;
78  if(kev->state & XCB_MOD_MASK_CONTROL)
79  keystate |= ControlMask;
80  if(kev->state & XCB_MOD_MASK_4)
81  keystate |= Mod4Mask;
82  if(kev->state & XCB_MOD_MASK_SHIFT)
83  keystate |= ShiftMask;
84 #endif
85  activateShortcut(keycode,
86  // Mod1Mask == Alt, Mod4Mask == Meta
87  keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
88  }
89  return false;
90 }
91 
92 quint32 QGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
93 {
94  // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
95  quint32 native = 0;
96  if(modifiers & Qt::ShiftModifier)
97  native |= ShiftMask;
98  if(modifiers & Qt::ControlModifier)
99  native |= ControlMask;
100  if(modifiers & Qt::AltModifier)
101  native |= Mod1Mask;
102  if(modifiers & Qt::MetaModifier)
103  native |= Mod4Mask;
104 
105  return native;
106 }
107 
108 quint32 QGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
109 {
110  Display *display = X11Display();
111  return display ? XKeysymToKeycode(display, XStringToKeysym(QKeySequence(key).toString().toLatin1().data())) : 0;
112 }
113 
114 bool QGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
115 {
116  Display *display = X11Display();
117  if(!display)
118  {
119  m_error = true;
120  return false;
121  }
122 
123  Window window = X11RootWindow();
124  Bool owner = True;
125  int pointer = GrabModeAsync;
126  int keyboard = GrabModeAsync;
127  m_error = false;
128 
129 // original_x_errhandler = XSetErrorHandler(q_x_errhandler);
130  XGrabKey(display, nativeKey, nativeMods, window, owner, pointer, keyboard);
131  XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner, pointer, keyboard); // allow numlock
132  XSync(display, False);
133 // XSetErrorHandler(original_x_errhandler);
134  return !m_error;
135 }
136 
137 bool QGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
138 {
139  Display *display = X11Display();
140  if(!display)
141  {
142  m_error = true;
143  return false;
144  }
145 
146  Window window = X11RootWindow();
147  m_error = false;
148 
149 // original_x_errhandler = XSetErrorHandler(q_x_errhandler);
150  XUngrabKey(display, nativeKey, nativeMods, window);
151  XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); // allow numlock
152  XSync(display, False);
153 // XSetErrorHandler(original_x_errhandler);
154  return !m_error;
155 }
static quint32 nativeKeycode(Qt::Key keycode)
#define TTKStaticCast(x, y)
Definition: ttkglobal.h:159
static constexpr wchar_t key[]
static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers)
#define qint
Definition: ttkqtglobal.h:168
static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
TTK_MODULE_EXPORT QString toString(Record type)
static Window X11RootWindow()
static bool eventFilter(void *message)
static bool registerShortcut(quint32 nativeKey, quint32 nativeMods)
#define TTKReinterpretCast(x, y)
Definition: ttkglobal.h:153
static Display * X11Display()
static void activateShortcut(quint32 nativeKey, quint32 nativeMods)