aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/General/hotkey/hotkey.pro1
-rw-r--r--src/plugins/General/hotkey/hotkeymanager.h17
-rw-r--r--src/plugins/General/hotkey/hotkeymanager_x11.cpp145
3 files changed, 23 insertions, 140 deletions
diff --git a/src/plugins/General/hotkey/hotkey.pro b/src/plugins/General/hotkey/hotkey.pro
index 320d4e1a0..7d305430c 100644
--- a/src/plugins/General/hotkey/hotkey.pro
+++ b/src/plugins/General/hotkey/hotkey.pro
@@ -24,6 +24,5 @@ unix {
target.path = $$PLUGIN_DIR/General
INSTALLS += target
PKGCONFIG += x11
- DEFINES += HAVE_XKBLIB_H
QT += x11extras
}
diff --git a/src/plugins/General/hotkey/hotkeymanager.h b/src/plugins/General/hotkey/hotkeymanager.h
index b7674f78d..16176bfe6 100644
--- a/src/plugins/General/hotkey/hotkeymanager.h
+++ b/src/plugins/General/hotkey/hotkeymanager.h
@@ -24,9 +24,7 @@
#include <QString>
#include <QTableWidgetItem>
#include <QList>
-#ifdef Q_OS_WIN
#include <QAbstractNativeEventFilter>
-#endif
#include <qmmpui/general.h>
class QEvent;
@@ -72,7 +70,7 @@ public:
static quint32 defaultKey(int act);
};
-class HotkeyManager : public QObject
+class HotkeyManager : public QObject, public QAbstractNativeEventFilter
{
Q_OBJECT
public:
@@ -84,21 +82,10 @@ public:
static QList<long> ignModifiersList();
static quint32 keycodeToKeysym(quint32 keycode);
-#ifdef QMMP_WS_X11
-protected:
- virtual bool eventFilter(QObject* o, QEvent* e);
-#endif
-
private:
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
#ifdef QMMP_WS_X11
- static void ensureModifiers();
QList <Hotkey *> m_grabbedKeys;
- static long m_alt_mask;
- static long m_meta_mask;
- static long m_super_mask;
- static long m_hyper_mask;
- static long m_numlock_mask;
- static bool m_haveMods;
#endif
#ifdef Q_OS_WIN
diff --git a/src/plugins/General/hotkey/hotkeymanager_x11.cpp b/src/plugins/General/hotkey/hotkeymanager_x11.cpp
index 2ac7f3a1a..9ee93a0cc 100644
--- a/src/plugins/General/hotkey/hotkeymanager_x11.cpp
+++ b/src/plugins/General/hotkey/hotkeymanager_x11.cpp
@@ -24,21 +24,19 @@
#ifdef QMMP_WS_X11
#include <QSettings>
#include <QX11Info>
+#include <QtDebug>
#include <QEvent>
#include <QKeyEvent>
#include <QCoreApplication>
#include <QApplication>
-#include <QDesktopWidget>
+#include <QAbstractEventDispatcher>
#define Visual XVisual
-extern "C"
-{
+extern "C" {
#include <X11/X.h>
-#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/XF86keysym.h>
-#ifdef HAVE_XKBLIB_H
#include <X11/XKBlib.h>
-#endif
+#include <xcb/xcb_keysyms.h>
}
#undef CursorShape
#undef Status
@@ -80,14 +78,8 @@ quint32 Hotkey::defaultKey(int act)
HotkeyManager::HotkeyManager(QObject *parent) : QObject(parent)
{
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
- //Workaround Qt regression of no longer delivering events for the root window
- //See qtbase commit 2b34aefcf02f09253473b096eb4faffd3e62b5f4
- //More information: https://bugs.kde.org/show_bug.cgi?id=360841
- qApp->desktop()->winId();
-#endif
QCoreApplication::instance()->installEventFilter(this);
- WId rootWindow = QX11Info::appRootWindow();
+ WId rootWindow = DefaultRootWindow(QX11Info::display());
QSettings settings(Qmmp::configFile(), QSettings::IniFormat); //load settings
settings.beginGroup("Hotkey");
for (int i = Hotkey::PLAY, j = 0; i <= Hotkey::VOLUME_MUTE; ++i, ++j)
@@ -105,7 +97,8 @@ HotkeyManager::HotkeyManager(QObject *parent) : QObject(parent)
hotkey->code = XKeysymToKeycode(QX11Info::display(), hotkey->key);
if(!hotkey->code)
continue;
- XGrabKey(QX11Info::display(), hotkey->code, mod | mask_mod, rootWindow, False,
+
+ XGrabKey(QX11Info::display(), hotkey->code, mod | mask_mod, rootWindow, True,
GrabModeAsync, GrabModeAsync);
hotkey->mod = mod | mask_mod;
m_grabbedKeys << hotkey;
@@ -114,11 +107,13 @@ HotkeyManager::HotkeyManager(QObject *parent) : QObject(parent)
}
settings.endGroup();
XSync(QX11Info::display(), False);
- // XSetErrorHandler();
+ qApp->installNativeEventFilter(this);
}
HotkeyManager::~HotkeyManager()
{
+ if(qApp && qApp->eventDispatcher())
+ qApp->removeNativeEventFilter(this);
foreach(Hotkey *key, m_grabbedKeys)
{
if(key->code)
@@ -142,13 +137,17 @@ const QString HotkeyManager::getKeyString(quint32 key, quint32 modifiers)
return keyStr;
}
-bool HotkeyManager::eventFilter(QObject* o, QEvent* e)
+bool HotkeyManager::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
- if (e->type() == QEvent::KeyPress)
+ Q_UNUSED(eventType);
+ Q_UNUSED(result);
+ xcb_generic_event_t *e = static_cast<xcb_generic_event_t*>(message);
+
+ if(e->response_type == XCB_KEY_PRESS)
{
- QKeyEvent* k = static_cast<QKeyEvent*>(e);
- quint32 key = keycodeToKeysym(k->nativeScanCode());
- quint32 mod = k->nativeModifiers ();
+ xcb_key_press_event_t *ke = (xcb_key_press_event_t*)e;
+ quint32 key = keycodeToKeysym(ke->detail);
+ quint32 mod = ke->state;
SoundCore *core = SoundCore::instance();
MediaPlayer *player = MediaPlayer::instance();
foreach(Hotkey *hotkey, m_grabbedKeys)
@@ -203,123 +202,21 @@ bool HotkeyManager::eventFilter(QObject* o, QEvent* e)
break;
}
- return true;
- }
- }
- return QObject::eventFilter(o, e);
-}
-long HotkeyManager::m_alt_mask = 0;
-long HotkeyManager::m_meta_mask = 0;
-long HotkeyManager::m_super_mask = 0;
-long HotkeyManager::m_hyper_mask = 0;
-long HotkeyManager::m_numlock_mask = 0;
-bool HotkeyManager::m_haveMods = false;
-
-//copied from globalshortcutmanager_x11.cpp by Justin Karneges and Michail Pishchagin (Psi project)
-void HotkeyManager::ensureModifiers()
-{
- if (m_haveMods)
- return;
-
- Display* appDpy = QX11Info::display();
- XModifierKeymap* map = XGetModifierMapping(appDpy);
- if (map)
- {
- // XkbKeycodeToKeysym helper code adapeted from xmodmap
- int min_keycode, max_keycode, keysyms_per_keycode = 1;
- XDisplayKeycodes (appDpy, &min_keycode, &max_keycode);
- XFree(XGetKeyboardMapping (appDpy, min_keycode, (max_keycode - min_keycode + 1), &keysyms_per_keycode));
-
- int i, maskIndex = 0, mapIndex = 0;
- for (maskIndex = 0; maskIndex < 8; maskIndex++)
- {
- for (i = 0; i < map->max_keypermod; i++)
- {
- if (map->modifiermap[mapIndex])
- {
- KeySym sym;
- int symIndex = 0;
- do
- {
-#ifdef HAVE_XKBLIB_H
- sym = XkbKeycodeToKeysym(appDpy, map->modifiermap[mapIndex], symIndex, 0);
-#else
- sym = XKeycodeToKeysym(appDpy, map->modifiermap[mapIndex], symIndex);
-#endif
- symIndex++;
- }
- while ( !sym && symIndex < keysyms_per_keycode);
- if (!m_alt_mask && (sym == XK_Alt_L || sym == XK_Alt_R))
- {
- m_alt_mask = 1 << maskIndex;
- }
- if (!m_meta_mask && (sym == XK_Meta_L || sym == XK_Meta_R))
- {
- m_meta_mask = 1 << maskIndex;
- }
- if (!m_super_mask && (sym == XK_Super_L || sym == XK_Super_R))
- {
- m_super_mask = 1 << maskIndex;
- }
- if (!m_hyper_mask && (sym == XK_Hyper_L || sym == XK_Hyper_R))
- {
- m_hyper_mask = 1 << maskIndex;
- }
- if (!m_numlock_mask && (sym == XK_Num_Lock))
- {
- m_numlock_mask = 1 << maskIndex;
- }
- }
- mapIndex++;
- }
- }
-
- XFreeModifiermap(map);
- // logic from qt source see gui/kernel/qkeymapper_x11.cpp
- if (!m_meta_mask || m_meta_mask == m_alt_mask)
- {
- // no meta keys... s,meta,super,
- m_meta_mask = m_super_mask;
- if (!m_meta_mask || m_meta_mask == m_alt_mask)
- {
- // no super keys either? guess we'll use hyper then
- m_meta_mask = m_hyper_mask;
- }
}
}
- else
- {
- // assume defaults
- m_alt_mask = Mod1Mask;
- m_meta_mask = Mod4Mask;
- }
-
- m_haveMods = true;
+ return false;
}
QList<long> HotkeyManager::ignModifiersList()
{
- ensureModifiers();
- QList<long> ret;
- if (m_numlock_mask)
- {
- ret << 0 << LockMask << m_numlock_mask << (LockMask | m_numlock_mask);
- }
- else
- {
- ret << 0 << LockMask;
- }
+ QList<long> ret = { 0, Mod2Mask, LockMask, (Mod2Mask | LockMask) };
return ret;
}
quint32 HotkeyManager::keycodeToKeysym(quint32 keycode)
{
-#ifdef HAVE_XKBLIB_H
return XkbKeycodeToKeysym(QX11Info::display(), keycode, 0, 0);
-#else
- return XKeycodeToKeysym(QX11Info::display(), keycode,0);
-#endif
}
#include "moc_hotkeymanager.cpp"