globalshortcut-win: Register 0-9 as num keys too

This commit is contained in:
Jonas Kvinge
2022-04-02 00:43:41 +02:00
parent f471462a84
commit 8f016880af
4 changed files with 85 additions and 28 deletions

View File

@@ -25,7 +25,9 @@
#include "globalshortcut.h" #include "globalshortcut.h"
#include "keymapper_win.h" #include "keymapper_win.h"
int GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) { #include "core/logging.h"
int GlobalShortcut::nativeModifiers(const Qt::KeyboardModifiers qt_mods) {
int native_mods = 0; int native_mods = 0;
if (qt_mods & Qt::ShiftModifier) native_mods |= MOD_SHIFT; if (qt_mods & Qt::ShiftModifier) native_mods |= MOD_SHIFT;
@@ -36,22 +38,57 @@ int GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) {
} }
int GlobalShortcut::nativeKeycode(Qt::Key qt_key) { int GlobalShortcut::nativeKeycode(const Qt::Key qt_keycode) {
int key_code = 0; int key_code = 0;
if (KeyMapperWin::keymapper_win_.contains(qt_key)) { if (KeyMapperWin::keymapper_win_.contains(qt_keycode)) {
key_code = KeyMapperWin::keymapper_win_.value(qt_key); key_code = KeyMapperWin::keymapper_win_.value(qt_keycode);
} }
return key_code; return key_code;
} }
bool GlobalShortcut::registerShortcut(int native_key, int native_mods) { int GlobalShortcut::nativeKeycode2(const Qt::Key qt_keycode) {
return RegisterHotKey(0, native_mods ^ native_key, native_mods, native_key);
switch (qt_keycode) {
case Qt::Key_0:
return VK_NUMPAD0;
case Qt::Key_1:
return VK_NUMPAD1;
case Qt::Key_2:
return VK_NUMPAD2;
case Qt::Key_3:
return VK_NUMPAD3;
case Qt::Key_4:
return VK_NUMPAD4;
case Qt::Key_5:
return VK_NUMPAD5;
case Qt::Key_6:
return VK_NUMPAD6;
case Qt::Key_7:
return VK_NUMPAD7;
case Qt::Key_8:
return VK_NUMPAD8;
case Qt::Key_9:
return VK_NUMPAD9;
default:
break;
}
return 0;
} }
bool GlobalShortcut::unregisterShortcut(int native_key, int native_mods) { bool GlobalShortcut::registerShortcut(const int native_key, const int native_mods) {
return RegisterHotKey(0, native_mods ^ native_key, native_mods, native_key);
}
bool GlobalShortcut::unregisterShortcut(const int native_key, const int native_mods) {
return UnregisterHotKey(0, native_mods ^ native_key); return UnregisterHotKey(0, native_mods ^ native_key);
} }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@@ -69,6 +106,7 @@ bool GlobalShortcut::nativeEventFilter(const QByteArray &eventtype, void *messag
quint32 key_code = HIWORD(msg->lParam); quint32 key_code = HIWORD(msg->lParam);
quint32 modifiers = LOWORD(msg->lParam); quint32 modifiers = LOWORD(msg->lParam);
activateShortcut(key_code, modifiers); activateShortcut(key_code, modifiers);
return true; return true;
} }

View File

@@ -119,7 +119,7 @@ quint32 AppRootWindow() {
} // namespace } // namespace
int GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) { int GlobalShortcut::nativeModifiers(const Qt::KeyboardModifiers qt_mods) {
int native_mods = 0; int native_mods = 0;
if (qt_mods & Qt::ShiftModifier) native_mods |= ShiftMask; if (qt_mods & Qt::ShiftModifier) native_mods |= ShiftMask;
@@ -130,41 +130,43 @@ int GlobalShortcut::nativeModifiers(Qt::KeyboardModifiers qt_mods) {
} }
int GlobalShortcut::nativeKeycode(Qt::Key qt_key) { int GlobalShortcut::nativeKeycode(const Qt::Key qt_keycode) {
Display *disp = X11Display(); Display *disp = X11Display();
if (!disp) return false; if (!disp) return false;
quint32 keysym = 0; quint32 keysym = 0;
if (KeyMapperX11::keymapper_x11_.contains(qt_key)) { if (KeyMapperX11::keymapper_x11_.contains(qt_keycode)) {
keysym = KeyMapperX11::keymapper_x11_.value(qt_key); keysym = KeyMapperX11::keymapper_x11_.value(qt_keycode);
} }
else { else {
keysym = XStringToKeysym(QKeySequence(qt_key).toString().toLatin1().data()); keysym = XStringToKeysym(QKeySequence(qt_keycode).toString().toLatin1().data());
if (keysym == NoSymbol) return 0; if (keysym == NoSymbol) return 0;
} }
return XKeysymToKeycode(disp, keysym); return XKeysymToKeycode(disp, keysym);
} }
bool GlobalShortcut::registerShortcut(int native_key, int native_mods) { int GlobalShortcut::nativeKeycode2(const Qt::Key qt_keycode) { return 0; }
bool GlobalShortcut::registerShortcut(const int native_key, const int native_mods) {
Display *disp = X11Display(); Display *disp = X11Display();
if (!disp) return false; if (!disp) return false;
for (quint32 mask_mods : mask_modifiers_) { for (const quint32 mask_mods : mask_modifiers_) {
XGrabKey(disp, native_key, (native_mods | mask_mods), AppRootWindow(), True, GrabModeAsync, GrabModeAsync); XGrabKey(disp, native_key, (native_mods | mask_mods), AppRootWindow(), True, GrabModeAsync, GrabModeAsync);
} }
return true; return true;
} }
bool GlobalShortcut::unregisterShortcut(int native_key, int native_mods) { bool GlobalShortcut::unregisterShortcut(const int native_key, const int native_mods) {
Display *disp = X11Display(); Display *disp = X11Display();
if (!disp) return false; if (!disp) return false;
for (quint32 mask_mods : mask_modifiers_) { for (const quint32 mask_mods : mask_modifiers_) {
XUngrabKey(disp, native_key, native_mods | mask_mods, AppRootWindow()); XUngrabKey(disp, native_key, native_mods | mask_mods, AppRootWindow());
} }
return true; return true;

View File

@@ -44,6 +44,7 @@ GlobalShortcut::GlobalShortcut(QObject *parent)
qt_key_(Qt::Key(0)), qt_key_(Qt::Key(0)),
qt_mods_(Qt::NoModifier), qt_mods_(Qt::NoModifier),
native_key_(0), native_key_(0),
native_key2_(0),
native_mods_(0) { native_mods_(0) {
Q_ASSERT(!initialized_); Q_ASSERT(!initialized_);
@@ -100,16 +101,20 @@ bool GlobalShortcut::setShortcut(const QKeySequence &shortcut) {
if (native_key_ == 0) return false; if (native_key_ == 0) return false;
native_mods_ = nativeModifiers(qt_mods_); native_mods_ = nativeModifiers(qt_mods_);
bool result = registerShortcut(native_key_, native_mods_); bool success = registerShortcut(native_key_, native_mods_);
if (result) { if (success) {
internal_shortcuts_.insert(qMakePair(native_key_, native_mods_), this); internal_shortcuts_.insert(qMakePair(native_key_, native_mods_), this);
qLog(Info) << "Registered shortcut" << shortcut_.toString(); qLog(Info) << "Registered shortcut" << shortcut_.toString();
native_key2_ = nativeKeycode2(qt_key_);
if (native_key2_ > 0 && registerShortcut(native_key2_, native_mods_)) {
internal_shortcuts_.insert(qMakePair(native_key2_, native_mods_), this);
}
} }
else { else {
qLog(Error) << "Failed to register shortcut" << shortcut_.toString(); qLog(Error) << "Failed to register shortcut" << shortcut_.toString();
} }
return result; return success;
} }
@@ -123,12 +128,22 @@ bool GlobalShortcut::unsetShortcut() {
if (gshortcut != this) return false; if (gshortcut != this) return false;
} }
bool result = unregisterShortcut(native_key_, native_mods_); bool success = unregisterShortcut(native_key_, native_mods_);
if (result) { if (success) {
if (internal_shortcuts_.contains(hash)) { if (internal_shortcuts_.contains(hash)) {
internal_shortcuts_.remove(hash); internal_shortcuts_.remove(hash);
} }
qLog(Info) << "Unregister shortcut" << shortcut_.toString(); qLog(Info) << "Unregister shortcut" << shortcut_.toString();
if (native_key2_ > 0) {
QPair<quint32, quint32> hash2 = qMakePair(native_key2_, native_mods_);
if (internal_shortcuts_.contains(hash2)) {
GlobalShortcut *gshortcut2 = internal_shortcuts_.value(hash);
if (gshortcut2 == this) {
unregisterShortcut(native_key2_, native_mods_);
internal_shortcuts_.remove(hash2);
}
}
}
} }
else { else {
qLog(Error) << "Failed to unregister shortcut" << shortcut_.toString(); qLog(Error) << "Failed to unregister shortcut" << shortcut_.toString();
@@ -139,11 +154,11 @@ bool GlobalShortcut::unsetShortcut() {
native_key_ = 0; native_key_ = 0;
native_mods_ = 0; native_mods_ = 0;
return result; return success;
} }
void GlobalShortcut::activateShortcut(quint32 native_key, quint32 native_mod) { void GlobalShortcut::activateShortcut(const quint32 native_key, const quint32 native_mod) {
Q_ASSERT(initialized_); Q_ASSERT(initialized_);

View File

@@ -53,13 +53,14 @@ class GlobalShortcut : public QObject, QAbstractNativeEventFilter {
private: private:
static void activateShortcut(quint32 native_key, quint32 native_mods); static void activateShortcut(const quint32 native_key, const quint32 native_mods);
static int nativeModifiers(Qt::KeyboardModifiers qt_mods); static int nativeModifiers(const Qt::KeyboardModifiers qt_mods);
static int nativeKeycode(Qt::Key qt_keycode); static int nativeKeycode(const Qt::Key qt_keycode);
static int nativeKeycode2(const Qt::Key qt_keycode);
static bool registerShortcut(int native_key, int native_mods); static bool registerShortcut(const int native_key, const int native_mods);
static bool unregisterShortcut(int native_key, int native_mods); static bool unregisterShortcut(const int native_key, const int native_mods);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
bool nativeEventFilter(const QByteArray &eventtype, void *message, qintptr *result) override; bool nativeEventFilter(const QByteArray &eventtype, void *message, qintptr *result) override;
@@ -76,6 +77,7 @@ class GlobalShortcut : public QObject, QAbstractNativeEventFilter {
Qt::Key qt_key_; Qt::Key qt_key_;
Qt::KeyboardModifiers qt_mods_; Qt::KeyboardModifiers qt_mods_;
int native_key_; int native_key_;
int native_key2_;
int native_mods_; int native_mods_;
}; };