From 5b507a84df9f784513ee6abb71d415e557e56e09 Mon Sep 17 00:00:00 2001 From: Alexandre Vicente Date: Tue, 21 Apr 2020 12:45:10 -0300 Subject: [PATCH 01/40] Hotkey release signal --- QHotkey/qhotkey.cpp | 7 +++++++ QHotkey/qhotkey.h | 3 +++ QHotkey/qhotkey_mac.cpp | 39 +++++++++++++++++++++++++++++++++------ QHotkey/qhotkey_p.h | 1 + QHotkey/qhotkey_win.cpp | 24 +++++++++++++++++++++--- QHotkey/qhotkey_x11.cpp | 27 +++++++++++++++++++++++++-- 6 files changed, 90 insertions(+), 11 deletions(-) diff --git a/QHotkey/qhotkey.cpp b/QHotkey/qhotkey.cpp index 8dadc08..853b68d 100644 --- a/QHotkey/qhotkey.cpp +++ b/QHotkey/qhotkey.cpp @@ -262,6 +262,13 @@ void QHotkeyPrivate::activateShortcut(QHotkey::NativeShortcut shortcut) signal.invoke(hkey, Qt::QueuedConnection); } +void QHotkeyPrivate::releaseShortcut(QHotkey::NativeShortcut shortcut) +{ + QMetaMethod signal = QMetaMethod::fromSignal(&QHotkey::released); + for(QHotkey *hkey : shortcuts.values(shortcut)) + signal.invoke(hkey, Qt::QueuedConnection); +} + void QHotkeyPrivate::addMappingInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers, const QHotkey::NativeShortcut &nativeShortcut) { mapping.insert({keycode, modifiers}, nativeShortcut); diff --git a/QHotkey/qhotkey.h b/QHotkey/qhotkey.h index 479dff5..a1b5ce9 100644 --- a/QHotkey/qhotkey.h +++ b/QHotkey/qhotkey.h @@ -100,6 +100,9 @@ public slots: //! Will be emitted if the shortcut is pressed void activated(QPrivateSignal); + //! Will be emitted if the shortcut press is released + void released(QPrivateSignal); + //! @notifyAcFn{QHotkey::registered} void registeredChanged(bool registered); diff --git a/QHotkey/qhotkey_mac.cpp b/QHotkey/qhotkey_mac.cpp index a410373..11e765e 100644 --- a/QHotkey/qhotkey_mac.cpp +++ b/QHotkey/qhotkey_mac.cpp @@ -9,7 +9,8 @@ class QHotkeyPrivateMac : public QHotkeyPrivate // QAbstractNativeEventFilter interface bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; - static OSStatus hotkeyEventHandler(EventHandlerCallRef nextHandler, EventRef event, void* data); + static OSStatus hotkeyPressEventHandler(EventHandlerCallRef nextHandler, EventRef event, void* data); + static OSStatus hotkeyReleaseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void* data); protected: // QHotkeyPrivate interface @@ -203,10 +204,15 @@ bool QHotkeyPrivateMac::registerShortcut(QHotkey::NativeShortcut shortcut) { if (!this->isHotkeyHandlerRegistered) { - EventTypeSpec eventSpec; - eventSpec.eventClass = kEventClassKeyboard; - eventSpec.eventKind = kEventHotKeyPressed; - InstallApplicationEventHandler(&QHotkeyPrivateMac::hotkeyEventHandler, 1, &eventSpec, NULL, NULL); + EventTypeSpec pressEventSpec; + pressEventSpec.eventClass = kEventClassKeyboard; + pressEventSpec.eventKind = kEventHotKeyPressed; + InstallApplicationEventHandler(&QHotkeyPrivateMac::hotkeyPressEventHandler, 1, &pressEventSpec, NULL, NULL); + + EventTypeSpec releaseEventSpec; + releaseEventSpec.eventClass = kEventClassKeyboard; + releaseEventSpec.eventKind = kEventHotKeyReleased; + InstallApplicationEventHandler(&QHotkeyPrivateMac::hotkeyReleaseEventHandler, 1, &releaseEventSpec, NULL, NULL); } EventHotKeyID hkeyID; @@ -244,7 +250,7 @@ bool QHotkeyPrivateMac::unregisterShortcut(QHotkey::NativeShortcut shortcut) } } -OSStatus QHotkeyPrivateMac::hotkeyEventHandler(EventHandlerCallRef nextHandler, EventRef event, void* data) +OSStatus QHotkeyPrivateMac::hotkeyPressEventHandler(EventHandlerCallRef nextHandler, EventRef event, void* data) { Q_UNUSED(nextHandler); Q_UNUSED(data); @@ -264,3 +270,24 @@ OSStatus QHotkeyPrivateMac::hotkeyEventHandler(EventHandlerCallRef nextHandler, return noErr; } + +OSStatus QHotkeyPrivateMac::hotkeyReleaseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void* data) +{ + Q_UNUSED(nextHandler); + Q_UNUSED(data); + + if (GetEventClass(event) == kEventClassKeyboard && + GetEventKind(event) == kEventHotKeyReleased) { + EventHotKeyID hkeyID; + GetEventParameter(event, + kEventParamDirectObject, + typeEventHotKeyID, + NULL, + sizeof(EventHotKeyID), + NULL, + &hkeyID); + hotkeyPrivate->releaseShortcut({hkeyID.signature, hkeyID.id}); + } + + return noErr; +} \ No newline at end of file diff --git a/QHotkey/qhotkey_p.h b/QHotkey/qhotkey_p.h index 847f7db..8fce3ae 100644 --- a/QHotkey/qhotkey_p.h +++ b/QHotkey/qhotkey_p.h @@ -25,6 +25,7 @@ class QHOTKEY_SHARED_EXPORT QHotkeyPrivate : public QObject, public QAbstractNat protected: void activateShortcut(QHotkey::NativeShortcut shortcut); + void releaseShortcut(QHotkey::NativeShortcut shortcut); virtual quint32 nativeKeycode(Qt::Key keycode, bool &ok) = 0;//platform implement virtual quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) = 0;//platform implement diff --git a/QHotkey/qhotkey_win.cpp b/QHotkey/qhotkey_win.cpp index ead6763..4b7c2f1 100644 --- a/QHotkey/qhotkey_win.cpp +++ b/QHotkey/qhotkey_win.cpp @@ -2,16 +2,19 @@ #include "qhotkey_p.h" #include #include +#include #define HKEY_ID(nativeShortcut) (((nativeShortcut.key ^ (nativeShortcut.modifier << 8)) & 0x0FFF) | 0x7000) class QHotkeyPrivateWin : public QHotkeyPrivate { public: + QHotkeyPrivateWin(); // QAbstractNativeEventFilter interface bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; protected: + void pollForHotkeyRelease(); // QHotkeyPrivate interface quint32 nativeKeycode(Qt::Key keycode, bool &ok) Q_DECL_OVERRIDE; quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) Q_DECL_OVERRIDE; @@ -20,6 +23,8 @@ class QHotkeyPrivateWin : public QHotkeyPrivate private: static QString formatWinError(DWORD winError); + QTimer pollTimer; + QHotkey::NativeShortcut polledShortcut; }; NATIVE_INSTANCE(QHotkeyPrivateWin) @@ -34,12 +39,25 @@ bool QHotkeyPrivateWin::nativeEventFilter(const QByteArray &eventType, void *mes Q_UNUSED(result) MSG* msg = static_cast(message); - if(msg->message == WM_HOTKEY) - this->activateShortcut({HIWORD(msg->lParam), LOWORD(msg->lParam)}); + if(msg->message == WM_HOTKEY) { + QHotkey::NativeShortcut shortcut = {HIWORD(msg->lParam), LOWORD(msg->lParam)}; + this->activateShortcut(shortcut); + this->polledShortcut = shortcut; + this->pollTimer.start(); + } return false; } +void QHotkeyPrivateWin::pollForHotkeyRelease() +{ + bool pressed = (GetAsyncKeyState(this->polledShortcut.key) & (1 << 15)) != 0; + if(!pressed) { + this->pollTimer.stop(); + this->releaseShortcut(this->polledShortcut); + } +} + quint32 QHotkeyPrivateWin::nativeKeycode(Qt::Key keycode, bool &ok) { ok = true; @@ -235,7 +253,7 @@ bool QHotkeyPrivateWin::registerShortcut(QHotkey::NativeShortcut shortcut) { BOOL ok = RegisterHotKey(NULL, HKEY_ID(shortcut), - shortcut.modifier, + shortcut.modifier + MOD_NOREPEAT, shortcut.key); if(ok) return true; diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index 43f8956..ab3d306 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,9 @@ class QHotkeyPrivateX11 : public QHotkeyPrivate private: XErrorHandler prevHandler; + xcb_key_press_event_t prevHandledEvent; + xcb_key_press_event_t prevEvent; + QTimer *releaseTimer = nullptr; static int handleError(Display *display, XErrorEvent *error); }; @@ -62,8 +66,27 @@ bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray &eventType, void *mes xcb_generic_event_t *genericEvent = static_cast(message); if (genericEvent->response_type == XCB_KEY_PRESS) { - xcb_key_press_event_t *keyEvent = static_cast(message); - this->activateShortcut({keyEvent->detail, keyEvent->state & QHotkeyPrivateX11::validModsMask}); + xcb_key_press_event_t keyEvent = *static_cast(message); + this->prevEvent = keyEvent; + if (this->prevHandledEvent.response_type == XCB_KEY_RELEASE) { + if(this->prevHandledEvent.time == keyEvent.time) return false; + } + this->activateShortcut({keyEvent.detail, keyEvent.state & QHotkeyPrivateX11::validModsMask}); + } else if (genericEvent->response_type == XCB_KEY_RELEASE) { + xcb_key_release_event_t keyEvent = *static_cast(message); + this->prevEvent = keyEvent; + QTimer *timer = new QTimer(this); + timer->setSingleShot(true); + timer->setInterval(50); + connect(timer, &QTimer::timeout, this, [this, keyEvent, timer] { + if(this->prevEvent.time == keyEvent.time && this->prevEvent.response_type == keyEvent.response_type && this->prevEvent.detail == keyEvent.detail){ + this->releaseShortcut({keyEvent.detail, keyEvent.state & QHotkeyPrivateX11::validModsMask}); + } + delete timer; + }); + timer->start(); + this->releaseTimer = timer; + this->prevHandledEvent = keyEvent; } return false; From d32957e52cf9b597675ee21207cb7a456b8ee879 Mon Sep 17 00:00:00 2001 From: Alexandre Vicente Date: Tue, 21 Apr 2020 15:48:50 -0300 Subject: [PATCH 02/40] X11 header fix --- QHotkey/qhotkey_x11.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index ab3d306..9cb01eb 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -29,7 +29,10 @@ class QHotkeyPrivateX11 : public QHotkeyPrivate private: static const QVector specialModifiers; static const quint32 validModsMask; - + XErrorHandler prevHandler; + xcb_key_press_event_t prevHandledEvent; + xcb_key_press_event_t prevEvent; + static QString formatX11Error(Display *display, int errorCode); class HotkeyErrorHandler { @@ -41,9 +44,6 @@ class QHotkeyPrivateX11 : public QHotkeyPrivate static QString errorString; private: - XErrorHandler prevHandler; - xcb_key_press_event_t prevHandledEvent; - xcb_key_press_event_t prevEvent; QTimer *releaseTimer = nullptr; static int handleError(Display *display, XErrorEvent *error); From 12e05bfd4e09556a900953a66c4e4196d20b23ff Mon Sep 17 00:00:00 2001 From: Alexandre Vicente Date: Tue, 21 Apr 2020 22:02:52 -0300 Subject: [PATCH 03/40] Fix missing poll connect on Windows --- QHotkey/qhotkey_win.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/QHotkey/qhotkey_win.cpp b/QHotkey/qhotkey_win.cpp index 4b7c2f1..19712db 100644 --- a/QHotkey/qhotkey_win.cpp +++ b/QHotkey/qhotkey_win.cpp @@ -28,6 +28,11 @@ class QHotkeyPrivateWin : public QHotkeyPrivate }; NATIVE_INSTANCE(QHotkeyPrivateWin) +QHotkeyPrivateWin::QHotkeyPrivateWin(){ + pollTimer.setInterval(50); + connect(&pollTimer, &QTimer::timeout, this, &QHotkeyPrivateWin::pollForHotkeyRelease); +} + bool QHotkeyPrivate::isPlatformSupported() { return true; From e113ace9a16bd9f6b189db91b52234ba6ae8402f Mon Sep 17 00:00:00 2001 From: Alexandre Vicente Date: Tue, 21 Apr 2020 22:10:49 -0300 Subject: [PATCH 04/40] Indentation fix --- QHotkey/qhotkey.cpp | 6 +++--- QHotkey/qhotkey.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/QHotkey/qhotkey.cpp b/QHotkey/qhotkey.cpp index 853b68d..ccff07f 100644 --- a/QHotkey/qhotkey.cpp +++ b/QHotkey/qhotkey.cpp @@ -264,9 +264,9 @@ void QHotkeyPrivate::activateShortcut(QHotkey::NativeShortcut shortcut) void QHotkeyPrivate::releaseShortcut(QHotkey::NativeShortcut shortcut) { - QMetaMethod signal = QMetaMethod::fromSignal(&QHotkey::released); - for(QHotkey *hkey : shortcuts.values(shortcut)) - signal.invoke(hkey, Qt::QueuedConnection); + QMetaMethod signal = QMetaMethod::fromSignal(&QHotkey::released); + for(QHotkey *hkey : shortcuts.values(shortcut)) + signal.invoke(hkey, Qt::QueuedConnection); } void QHotkeyPrivate::addMappingInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers, const QHotkey::NativeShortcut &nativeShortcut) diff --git a/QHotkey/qhotkey.h b/QHotkey/qhotkey.h index a1b5ce9..c8270d4 100644 --- a/QHotkey/qhotkey.h +++ b/QHotkey/qhotkey.h @@ -100,8 +100,8 @@ public slots: //! Will be emitted if the shortcut is pressed void activated(QPrivateSignal); - //! Will be emitted if the shortcut press is released - void released(QPrivateSignal); + //! Will be emitted if the shortcut press is released + void released(QPrivateSignal); //! @notifyAcFn{QHotkey::registered} void registeredChanged(bool registered); From 7028920db574e078b9cd4f278b47b1c3ae8c0c4d Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Sat, 2 May 2020 21:05:04 +0200 Subject: [PATCH 05/40] fix #33 --- QHotkey/qhotkey_x11.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index 9cb01eb..5606177 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -29,10 +29,10 @@ class QHotkeyPrivateX11 : public QHotkeyPrivate private: static const QVector specialModifiers; static const quint32 validModsMask; - XErrorHandler prevHandler; + QTimer *releaseTimer = nullptr; xcb_key_press_event_t prevHandledEvent; xcb_key_press_event_t prevEvent; - + static QString formatX11Error(Display *display, int errorCode); class HotkeyErrorHandler { @@ -44,7 +44,7 @@ class QHotkeyPrivateX11 : public QHotkeyPrivate static QString errorString; private: - QTimer *releaseTimer = nullptr; + XErrorHandler prevHandler; static int handleError(Display *display, XErrorEvent *error); }; @@ -96,18 +96,18 @@ QString QHotkeyPrivateX11::getX11String(Qt::Key keycode) { switch(keycode){ - case Qt::Key_MediaLast : - case Qt::Key_MediaPrevious : + case Qt::Key_MediaLast : + case Qt::Key_MediaPrevious : return "XF86AudioPrev"; - case Qt::Key_MediaNext : + case Qt::Key_MediaNext : return "XF86AudioNext"; - case Qt::Key_MediaPause : - case Qt::Key_MediaPlay : + case Qt::Key_MediaPause : + case Qt::Key_MediaPlay : case Qt::Key_MediaTogglePlayPause : return "XF86AudioPlay"; case Qt::Key_MediaRecord : - return "XF86AudioRecord"; - case Qt::Key_MediaStop : + return "XF86AudioRecord"; + case Qt::Key_MediaStop : return "XF86AudioStop"; default : return QKeySequence(keycode).toString(QKeySequence::NativeText); From 83a0066760140e676fc12278be6f1aedde3a5987 Mon Sep 17 00:00:00 2001 From: Sven Kipry Date: Tue, 5 May 2020 07:53:57 +0200 Subject: [PATCH 06/40] fix include path in CMakeLists.txt The include path is not set correctly when QHotkey is build as a subproject. To fix that CMAKE_CURRENT_SOURCE_DIR should be used instead of CMAKE_SOURCE_DIR in target_include_directories. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41f2037..30c40ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ target_link_libraries(qhotkey ${LIBS}) target_include_directories(qhotkey PUBLIC - $ + $ $) set_target_properties(qhotkey PROPERTIES From 0352904ec175216e7fdc4138f6aa3bcd7f0250b1 Mon Sep 17 00:00:00 2001 From: Patrizio Bekerle Date: Sat, 23 May 2020 07:46:08 +0200 Subject: [PATCH 07/40] Fix not declared MOD_NOREPEAT (Skycoder42/QHotkey/#36) (#37) Fix not declared MOD_NOREPEAT (#36) --- QHotkey/qhotkey_win.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/QHotkey/qhotkey_win.cpp b/QHotkey/qhotkey_win.cpp index 19712db..244ed51 100644 --- a/QHotkey/qhotkey_win.cpp +++ b/QHotkey/qhotkey_win.cpp @@ -6,6 +6,10 @@ #define HKEY_ID(nativeShortcut) (((nativeShortcut.key ^ (nativeShortcut.modifier << 8)) & 0x0FFF) | 0x7000) +#if !defined(MOD_NOREPEAT) +#define MOD_NOREPEAT 0x4000 +#endif + class QHotkeyPrivateWin : public QHotkeyPrivate { public: From 055d242ded352f5f67ff11bdbd995d5eaa845424 Mon Sep 17 00:00:00 2001 From: Shatur95 Date: Sat, 6 Jun 2020 22:42:09 +0300 Subject: [PATCH 08/40] Improve CMake rules * Disable building examples by default. * Use CMAKE_CURRENT_SOURCE_DIR instead of CMAKE_SOURCE_DIR. * Add an option to disable install rules. --- CMakeLists.txt | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 30c40ee..8b3d190 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,8 @@ cmake_minimum_required(VERSION 3.1) project(qhotkey VERSION 1.2.2 LANGUAGES CXX) -option(QHOTKEY_EXAMPLES "Build examples" ON) +option(QHOTKEY_EXAMPLES "Build examples" OFF) +option(QHOTKEY_INSTALL "Enable install rule" ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) @@ -53,18 +54,20 @@ if(QHOTKEY_EXAMPLES) add_subdirectory(HotkeyTest) endif() -include(GNUInstallDirs) -set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/QHotkey) - -install( - TARGETS qhotkey EXPORT QHotkeyConfig - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -install(FILES - ${CMAKE_SOURCE_DIR}/QHotkey/qhotkey.h - ${CMAKE_SOURCE_DIR}/QHotkey/QHotkey - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/) -install(EXPORT QHotkeyConfig DESTINATION ${INSTALL_CONFIGDIR}) - -export(TARGETS qhotkey FILE QHotkeyConfig.cmake) +if(QHOTKEY_INSTALL) + include(GNUInstallDirs) + set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/QHotkey) + + install( + TARGETS qhotkey EXPORT QHotkeyConfig + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/QHotkey/qhotkey.h + ${CMAKE_CURRENT_SOURCE_DIR}/QHotkey/QHotkey + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/) + install(EXPORT QHotkeyConfig DESTINATION ${INSTALL_CONFIGDIR}) + + export(TARGETS qhotkey FILE QHotkeyConfig.cmake) +endif() From 483e07365ee943b19f8078a4951090b6a9b87a65 Mon Sep 17 00:00:00 2001 From: Shatur95 Date: Wed, 1 Jul 2020 23:16:13 +0300 Subject: [PATCH 09/40] Improve error messages * Show information about shortcut. * Make errors translatable. --- QHotkey/qhotkey.cpp | 14 ++++++++++---- QHotkey/qhotkey_mac.cpp | 6 ++---- QHotkey/qhotkey_p.h | 2 ++ QHotkey/qhotkey_win.cpp | 6 ++---- QHotkey/qhotkey_x11.cpp | 6 ++---- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/QHotkey/qhotkey.cpp b/QHotkey/qhotkey.cpp index ccff07f..7b6a399 100644 --- a/QHotkey/qhotkey.cpp +++ b/QHotkey/qhotkey.cpp @@ -279,8 +279,10 @@ bool QHotkeyPrivate::addShortcutInvoked(QHotkey *hotkey) QHotkey::NativeShortcut shortcut = hotkey->_nativeShortcut; if(!shortcuts.contains(shortcut)) { - if(!registerShortcut(shortcut)) + if(!registerShortcut(shortcut)) { + qCWarning(logQHotkey) << QHotkey::tr("Failed to register %1. Error: %2").arg(hotkey->shortcut().toString(), error); return false; + } } shortcuts.insert(shortcut, hotkey); @@ -296,9 +298,13 @@ bool QHotkeyPrivate::removeShortcutInvoked(QHotkey *hotkey) return false; hotkey->_registered = false; emit hotkey->registeredChanged(true); - if(shortcuts.count(shortcut) == 0) - return unregisterShortcut(shortcut); - else + if(shortcuts.count(shortcut) == 0) { + if (!unregisterShortcut(shortcut)) { + qCWarning(logQHotkey) << QHotkey::tr("Failed to unregister %1. Error: %2").arg(hotkey->shortcut().toString(), error); + return false; + } else + return true; + } else return true; } diff --git a/QHotkey/qhotkey_mac.cpp b/QHotkey/qhotkey_mac.cpp index 11e765e..0e06299 100644 --- a/QHotkey/qhotkey_mac.cpp +++ b/QHotkey/qhotkey_mac.cpp @@ -227,8 +227,7 @@ bool QHotkeyPrivateMac::registerShortcut(QHotkey::NativeShortcut shortcut) 0, &eventRef); if (status != noErr) { - qCWarning(logQHotkey) << "Failed to register hotkey. Error:" - << status; + error = QString::number(status); return false; } else { this->hotkeyRefs.insert(shortcut, eventRef); @@ -241,8 +240,7 @@ bool QHotkeyPrivateMac::unregisterShortcut(QHotkey::NativeShortcut shortcut) EventHotKeyRef eventRef = QHotkeyPrivateMac::hotkeyRefs.value(shortcut); OSStatus status = UnregisterEventHotKey(eventRef); if (status != noErr) { - qCWarning(logQHotkey) << "Failed to unregister hotkey. Error:" - << status; + error = QString::number(status); return false; } else { this->hotkeyRefs.remove(shortcut); diff --git a/QHotkey/qhotkey_p.h b/QHotkey/qhotkey_p.h index 8fce3ae..eec3bd6 100644 --- a/QHotkey/qhotkey_p.h +++ b/QHotkey/qhotkey_p.h @@ -33,6 +33,8 @@ class QHOTKEY_SHARED_EXPORT QHotkeyPrivate : public QObject, public QAbstractNat virtual bool registerShortcut(QHotkey::NativeShortcut shortcut) = 0;//platform implement virtual bool unregisterShortcut(QHotkey::NativeShortcut shortcut) = 0;//platform implement + QString error; + private: QHash, QHotkey::NativeShortcut> mapping; QMultiHash shortcuts; diff --git a/QHotkey/qhotkey_win.cpp b/QHotkey/qhotkey_win.cpp index 244ed51..22c64a8 100644 --- a/QHotkey/qhotkey_win.cpp +++ b/QHotkey/qhotkey_win.cpp @@ -267,8 +267,7 @@ bool QHotkeyPrivateWin::registerShortcut(QHotkey::NativeShortcut shortcut) if(ok) return true; else { - qCWarning(logQHotkey) << "Failed to register hotkey. Error:" - << qPrintable(QHotkeyPrivateWin::formatWinError(::GetLastError())); + error = QHotkeyPrivateWin::formatWinError(::GetLastError()); return false; } } @@ -279,8 +278,7 @@ bool QHotkeyPrivateWin::unregisterShortcut(QHotkey::NativeShortcut shortcut) if(ok) return true; else { - qCWarning(logQHotkey) << "Failed to unregister hotkey. Error:" - << qPrintable(QHotkeyPrivateWin::formatWinError(::GetLastError())); + error = QHotkeyPrivateWin::formatWinError(::GetLastError()); return false; } } diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index 5606177..1c99939 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -170,8 +170,7 @@ bool QHotkeyPrivateX11::registerShortcut(QHotkey::NativeShortcut shortcut) XSync(display, False); if(errorHandler.hasError) { - qCWarning(logQHotkey) << "Failed to register hotkey. Error:" - << qPrintable(errorHandler.errorString); + error = errorHandler.errorString; this->unregisterShortcut(shortcut); return false; } else @@ -194,8 +193,7 @@ bool QHotkeyPrivateX11::unregisterShortcut(QHotkey::NativeShortcut shortcut) XSync(display, False); if(errorHandler.hasError) { - qCWarning(logQHotkey) << "Failed to unregister hotkey. Error:" - << qPrintable(errorHandler.errorString); + error = errorHandler.errorString; return false; } else return true; From 941cb2f15fb68e613dcf65d8977c487f7d332f56 Mon Sep 17 00:00:00 2001 From: Oleg Antonyan Date: Tue, 18 Aug 2020 20:43:44 +0200 Subject: [PATCH 10/40] fix SIGSEGV on wayland --- QHotkey/qhotkey_x11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index 1c99939..fdd3ab2 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -154,7 +154,7 @@ quint32 QHotkeyPrivateX11::nativeModifiers(Qt::KeyboardModifiers modifiers, bool bool QHotkeyPrivateX11::registerShortcut(QHotkey::NativeShortcut shortcut) { Display *display = QX11Info::display(); - if(!display) + if(!display || !QX11Info::isPlatformX11()) return false; HotkeyErrorHandler errorHandler; From b73b4955ae22d7ebb7acd2e4b70ab31a708c23fa Mon Sep 17 00:00:00 2001 From: Shatur95 Date: Thu, 15 Oct 2020 01:31:52 +0300 Subject: [PATCH 11/40] Fix implicit conversion warning --- QHotkey/qhotkey_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QHotkey/qhotkey_win.cpp b/QHotkey/qhotkey_win.cpp index 22c64a8..a03b8c0 100644 --- a/QHotkey/qhotkey_win.cpp +++ b/QHotkey/qhotkey_win.cpp @@ -71,7 +71,7 @@ quint32 QHotkeyPrivateWin::nativeKeycode(Qt::Key keycode, bool &ok) { ok = true; if(keycode <= 0xFFFF) {//Try to obtain the key from it's "character" - const SHORT vKey = VkKeyScanW(keycode); + const SHORT vKey = VkKeyScanW(static_cast(keycode)); if(vKey > -1) return LOBYTE(vKey); } From f0799fd4a47d86112b2b81b874d5f4b79dd8ef8b Mon Sep 17 00:00:00 2001 From: Shatur95 Date: Thu, 15 Oct 2020 21:50:58 +0300 Subject: [PATCH 12/40] Fix Clang Tidy warnings readability-convert-member-functions-to-static modernize-use-auto readability-else-after-return readability-static-accessed-through-instance readability-inconsistent-declaration-parameter-name --- QHotkey/qhotkey.cpp | 84 +++++++++++++++++++---------------------- QHotkey/qhotkey_x11.cpp | 24 ++++++------ 2 files changed, 51 insertions(+), 57 deletions(-) diff --git a/QHotkey/qhotkey.cpp b/QHotkey/qhotkey.cpp index 7b6a399..ea3957e 100644 --- a/QHotkey/qhotkey.cpp +++ b/QHotkey/qhotkey.cpp @@ -25,14 +25,13 @@ QHotkey::QHotkey(QObject *parent) : QObject(parent), _keyCode(Qt::Key_unknown), _modifiers(Qt::NoModifier), - _nativeShortcut(), _registered(false) {} -QHotkey::QHotkey(const QKeySequence &sequence, bool autoRegister, QObject *parent) : +QHotkey::QHotkey(const QKeySequence &shortcut, bool autoRegister, QObject *parent) : QHotkey(parent) { - setShortcut(sequence, autoRegister); + setShortcut(shortcut, autoRegister); } QHotkey::QHotkey(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegister, QObject *parent) : @@ -57,8 +56,7 @@ QKeySequence QHotkey::shortcut() const { if(_keyCode == Qt::Key_unknown) return QKeySequence(); - else - return QKeySequence(_keyCode | _modifiers); + return QKeySequence(static_cast(_keyCode | _modifiers)); } Qt::Key QHotkey::keyCode() const @@ -83,9 +81,9 @@ bool QHotkey::isRegistered() const bool QHotkey::setShortcut(const QKeySequence &shortcut, bool autoRegister) { - if(shortcut.isEmpty()) { + if(shortcut.isEmpty()) return resetShortcut(); - } else if(shortcut.count() > 1) { + if(shortcut.count() > 1) { qCWarning(logQHotkey, "Keysequences with multiple shortcuts are not allowed! " "Only the first shortcut will be used!"); } @@ -118,15 +116,14 @@ bool QHotkey::setShortcut(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool if(_nativeShortcut.isValid()) { if(autoRegister) return QHotkeyPrivate::instance()->addShortcut(this); - else - return true; - } else { - qCWarning(logQHotkey) << "Unable to map shortcut to native keys. Key:" << keyCode << "Modifiers:" << modifiers; - _keyCode = Qt::Key_unknown; - _modifiers = Qt::NoModifier; - _nativeShortcut = NativeShortcut(); - return false; + return true; } + + qCWarning(logQHotkey) << "Unable to map shortcut to native keys. Key:" << keyCode << "Modifiers:" << modifiers; + _keyCode = Qt::Key_unknown; + _modifiers = Qt::NoModifier; + _nativeShortcut = NativeShortcut(); + return false; } bool QHotkey::resetShortcut() @@ -158,35 +155,32 @@ bool QHotkey::setNativeShortcut(QHotkey::NativeShortcut nativeShortcut, bool aut _nativeShortcut = nativeShortcut; if(autoRegister) return QHotkeyPrivate::instance()->addShortcut(this); - else - return true; - } else { - _keyCode = Qt::Key_unknown; - _modifiers = Qt::NoModifier; - _nativeShortcut = NativeShortcut(); return true; - } + } + + _keyCode = Qt::Key_unknown; + _modifiers = Qt::NoModifier; + _nativeShortcut = NativeShortcut(); + return true; } bool QHotkey::setRegistered(bool registered) { if(_registered && !registered) return QHotkeyPrivate::instance()->removeShortcut(this); - else if(!_registered && registered) { + if(!_registered && registered) { if(!_nativeShortcut.isValid()) return false; - else - return QHotkeyPrivate::instance()->addShortcut(this); - } else - return true; + return QHotkeyPrivate::instance()->addShortcut(this); + } + return true; } // ---------- QHotkeyPrivate implementation ---------- -QHotkeyPrivate::QHotkeyPrivate() : - shortcuts() +QHotkeyPrivate::QHotkeyPrivate() { Q_ASSERT_X(qApp, Q_FUNC_INFO, "QHotkey requires QCoreApplication to be instantiated"); qApp->eventDispatcher()->installNativeEventFilter(this); @@ -211,8 +205,8 @@ QHotkey::NativeShortcut QHotkeyPrivate::nativeShortcut(Qt::Key keycode, Qt::Keyb Q_ARG(Qt::Key, keycode), Q_ARG(Qt::KeyboardModifiers, modifiers))) { return QHotkey::NativeShortcut(); - } else - return res; + } + return res; } bool QHotkeyPrivate::addShortcut(QHotkey *hotkey) @@ -228,11 +222,11 @@ bool QHotkeyPrivate::addShortcut(QHotkey *hotkey) Q_RETURN_ARG(bool, res), Q_ARG(QHotkey*, hotkey))) { return false; - } else { - if(res) - emit hotkey->registeredChanged(true); - return res; } + + if(res) + emit hotkey->registeredChanged(true); + return res; } bool QHotkeyPrivate::removeShortcut(QHotkey *hotkey) @@ -248,11 +242,11 @@ bool QHotkeyPrivate::removeShortcut(QHotkey *hotkey) Q_RETURN_ARG(bool, res), Q_ARG(QHotkey*, hotkey))) { return false; - } else { - if(res) - emit hotkey->registeredChanged(false); - return res; } + + if(res) + emit hotkey->registeredChanged(false); + return res; } void QHotkeyPrivate::activateShortcut(QHotkey::NativeShortcut shortcut) @@ -302,10 +296,10 @@ bool QHotkeyPrivate::removeShortcutInvoked(QHotkey *hotkey) if (!unregisterShortcut(shortcut)) { qCWarning(logQHotkey) << QHotkey::tr("Failed to unregister %1. Error: %2").arg(hotkey->shortcut().toString(), error); return false; - } else - return true; - } else + } return true; + } + return true; } QHotkey::NativeShortcut QHotkeyPrivate::nativeShortcutInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers) @@ -313,13 +307,13 @@ QHotkey::NativeShortcut QHotkeyPrivate::nativeShortcutInvoked(Qt::Key keycode, Q if(mapping.contains({keycode, modifiers})) return mapping.value({keycode, modifiers}); - bool ok1, ok2 = false; + bool ok1 = false; auto k = nativeKeycode(keycode, ok1); + bool ok2 = false; auto m = nativeModifiers(modifiers, ok2); if(ok1 && ok2) return {k, m}; - else - return {}; + return {}; } diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index fdd3ab2..b08bde2 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -22,7 +22,7 @@ class QHotkeyPrivateX11 : public QHotkeyPrivate // QHotkeyPrivate interface quint32 nativeKeycode(Qt::Key keycode, bool &ok) Q_DECL_OVERRIDE; quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) Q_DECL_OVERRIDE; - QString getX11String(Qt::Key keycode); + static QString getX11String(Qt::Key keycode); bool registerShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; bool unregisterShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; @@ -64,7 +64,7 @@ bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray &eventType, void *mes Q_UNUSED(eventType) Q_UNUSED(result) - xcb_generic_event_t *genericEvent = static_cast(message); + auto *genericEvent = static_cast(message); if (genericEvent->response_type == XCB_KEY_PRESS) { xcb_key_press_event_t keyEvent = *static_cast(message); this->prevEvent = keyEvent; @@ -75,7 +75,7 @@ bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray &eventType, void *mes } else if (genericEvent->response_type == XCB_KEY_RELEASE) { xcb_key_release_event_t keyEvent = *static_cast(message); this->prevEvent = keyEvent; - QTimer *timer = new QTimer(this); + auto *timer = new QTimer(this); timer->setSingleShot(true); timer->setInterval(50); connect(timer, &QTimer::timeout, this, [this, keyEvent, timer] { @@ -132,8 +132,8 @@ quint32 QHotkeyPrivateX11::nativeKeycode(Qt::Key keycode, bool &ok) if(res != 0) ok = true; return res; - } else - return 0; + } + return 0; } quint32 QHotkeyPrivateX11::nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) @@ -173,8 +173,8 @@ bool QHotkeyPrivateX11::registerShortcut(QHotkey::NativeShortcut shortcut) error = errorHandler.errorString; this->unregisterShortcut(shortcut); return false; - } else - return true; + } + return true; } bool QHotkeyPrivateX11::unregisterShortcut(QHotkey::NativeShortcut shortcut) @@ -188,15 +188,15 @@ bool QHotkeyPrivateX11::unregisterShortcut(QHotkey::NativeShortcut shortcut) XUngrabKey(display, shortcut.key, shortcut.modifier | specialMod, - DefaultRootWindow(display)); + XDefaultRootWindow(display)); } XSync(display, False); - if(errorHandler.hasError) { - error = errorHandler.errorString; + if(HotkeyErrorHandler::hasError) { + error = HotkeyErrorHandler::errorString; return false; - } else - return true; + } + return true; } QString QHotkeyPrivateX11::formatX11Error(Display *display, int errorCode) From 2a87965ed645f2657b3380a482d8e786747048ad Mon Sep 17 00:00:00 2001 From: Shatur95 Date: Thu, 15 Oct 2020 22:12:11 +0300 Subject: [PATCH 13/40] Add mising override --- QHotkey/qhotkey.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QHotkey/qhotkey.h b/QHotkey/qhotkey.h index c8270d4..3fc988e 100644 --- a/QHotkey/qhotkey.h +++ b/QHotkey/qhotkey.h @@ -68,7 +68,7 @@ class QHOTKEY_SHARED_EXPORT QHotkey : public QObject explicit QHotkey(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegister = false, QObject *parent = nullptr); //! Constructs a hotkey from a native shortcut and optionally registers it explicit QHotkey(const NativeShortcut &shortcut, bool autoRegister = false, QObject *parent = nullptr); - ~QHotkey(); + ~QHotkey() override; //! @readAcFn{QHotkey::registered} bool isRegistered() const; From 4bb901a41e4044eb97fc0f982c8abf4f9422a406 Mon Sep 17 00:00:00 2001 From: Shatur95 Date: Sat, 17 Oct 2020 01:07:57 +0300 Subject: [PATCH 14/40] Pass NativeShortcut by value (trivially copyable) --- QHotkey/qhotkey.cpp | 14 +++++++------- QHotkey/qhotkey.h | 14 +++++++------- QHotkey/qhotkey_p.h | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/QHotkey/qhotkey.cpp b/QHotkey/qhotkey.cpp index ea3957e..ae6da22 100644 --- a/QHotkey/qhotkey.cpp +++ b/QHotkey/qhotkey.cpp @@ -8,7 +8,7 @@ Q_LOGGING_CATEGORY(logQHotkey, "QHotkey") -void QHotkey::addGlobalMapping(const QKeySequence &shortcut, const QHotkey::NativeShortcut &nativeShortcut) +void QHotkey::addGlobalMapping(const QKeySequence &shortcut, QHotkey::NativeShortcut nativeShortcut) { QMetaObject::invokeMethod(QHotkeyPrivate::instance(), "addMappingInvoked", Qt::QueuedConnection, Q_ARG(Qt::Key, Qt::Key(shortcut[0] & ~Qt::KeyboardModifierMask)), @@ -40,7 +40,7 @@ QHotkey::QHotkey(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegi setShortcut(keyCode, modifiers, autoRegister); } -QHotkey::QHotkey(const QHotkey::NativeShortcut &shortcut, bool autoRegister, QObject *parent) : +QHotkey::QHotkey(QHotkey::NativeShortcut shortcut, bool autoRegister, QObject *parent) : QHotkey(parent) { setNativeShortcut(shortcut, autoRegister); @@ -263,7 +263,7 @@ void QHotkeyPrivate::releaseShortcut(QHotkey::NativeShortcut shortcut) signal.invoke(hkey, Qt::QueuedConnection); } -void QHotkeyPrivate::addMappingInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers, const QHotkey::NativeShortcut &nativeShortcut) +void QHotkeyPrivate::addMappingInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers, QHotkey::NativeShortcut nativeShortcut) { mapping.insert({keycode, modifiers}, nativeShortcut); } @@ -335,26 +335,26 @@ bool QHotkey::NativeShortcut::isValid() const return valid; } -bool QHotkey::NativeShortcut::operator ==(const QHotkey::NativeShortcut &other) const +bool QHotkey::NativeShortcut::operator ==(QHotkey::NativeShortcut other) const { return (key == other.key) && (modifier == other.modifier) && valid == other.valid; } -bool QHotkey::NativeShortcut::operator !=(const QHotkey::NativeShortcut &other) const +bool QHotkey::NativeShortcut::operator !=(QHotkey::NativeShortcut other) const { return (key != other.key) || (modifier != other.modifier) || valid != other.valid; } -uint qHash(const QHotkey::NativeShortcut &key) +uint qHash(QHotkey::NativeShortcut key) { return qHash(key.key) ^ qHash(key.modifier); } -uint qHash(const QHotkey::NativeShortcut &key, uint seed) +uint qHash(QHotkey::NativeShortcut key, uint seed) { return qHash(key.key, seed) ^ qHash(key.modifier, seed); } diff --git a/QHotkey/qhotkey.h b/QHotkey/qhotkey.h index 3fc988e..f669640 100644 --- a/QHotkey/qhotkey.h +++ b/QHotkey/qhotkey.h @@ -46,16 +46,16 @@ class QHOTKEY_SHARED_EXPORT QHotkey : public QObject bool isValid() const; //! Equality operator - bool operator ==(const NativeShortcut &other) const; + bool operator ==(NativeShortcut other) const; //! Inequality operator - bool operator !=(const NativeShortcut &other) const; + bool operator !=(NativeShortcut other) const; private: bool valid; }; //! Adds a global mapping of a key sequence to a replacement native shortcut - static void addGlobalMapping(const QKeySequence &shortcut, const NativeShortcut &nativeShortcut); + static void addGlobalMapping(const QKeySequence &shortcut, NativeShortcut nativeShortcut); //! Checks if global shortcuts are supported by the current platform static bool isPlatformSupported(); @@ -67,7 +67,7 @@ class QHOTKEY_SHARED_EXPORT QHotkey : public QObject //! Constructs a hotkey with a key and modifiers and optionally registers it explicit QHotkey(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegister = false, QObject *parent = nullptr); //! Constructs a hotkey from a native shortcut and optionally registers it - explicit QHotkey(const NativeShortcut &shortcut, bool autoRegister = false, QObject *parent = nullptr); + explicit QHotkey(NativeShortcut shortcut, bool autoRegister = false, QObject *parent = nullptr); ~QHotkey() override; //! @readAcFn{QHotkey::registered} @@ -94,7 +94,7 @@ public slots: bool resetShortcut(); //! Set this hotkey to a native shortcut - bool setNativeShortcut(NativeShortcut nativeShortcut, bool autoRegister = false); + bool setNativeShortcut(QHotkey::NativeShortcut nativeShortcut, bool autoRegister = false); signals: //! Will be emitted if the shortcut is pressed @@ -114,8 +114,8 @@ public slots: bool _registered; }; -uint QHOTKEY_SHARED_EXPORT qHash(const QHotkey::NativeShortcut &key); -uint QHOTKEY_SHARED_EXPORT qHash(const QHotkey::NativeShortcut &key, uint seed); +uint QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key); +uint QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key, uint seed); QHOTKEY_SHARED_EXPORT Q_DECLARE_LOGGING_CATEGORY(logQHotkey) diff --git a/QHotkey/qhotkey_p.h b/QHotkey/qhotkey_p.h index eec3bd6..b7c1721 100644 --- a/QHotkey/qhotkey_p.h +++ b/QHotkey/qhotkey_p.h @@ -39,7 +39,7 @@ class QHOTKEY_SHARED_EXPORT QHotkeyPrivate : public QObject, public QAbstractNat QHash, QHotkey::NativeShortcut> mapping; QMultiHash shortcuts; - Q_INVOKABLE void addMappingInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers, const QHotkey::NativeShortcut &nativeShortcut); + Q_INVOKABLE void addMappingInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers, QHotkey::NativeShortcut nativeShortcut); Q_INVOKABLE bool addShortcutInvoked(QHotkey *hotkey); Q_INVOKABLE bool removeShortcutInvoked(QHotkey *hotkey); Q_INVOKABLE QHotkey::NativeShortcut nativeShortcutInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers); From 384f780b28a083f7abf045906cfffc5d58935121 Mon Sep 17 00:00:00 2001 From: Shatur95 Date: Sat, 17 Oct 2020 01:08:08 +0300 Subject: [PATCH 15/40] Use QStringLiteral --- QHotkey/qhotkey_x11.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index b08bde2..5310a07 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -98,17 +98,17 @@ QString QHotkeyPrivateX11::getX11String(Qt::Key keycode) case Qt::Key_MediaLast : case Qt::Key_MediaPrevious : - return "XF86AudioPrev"; + return QStringLiteral("XF86AudioPrev"); case Qt::Key_MediaNext : - return "XF86AudioNext"; + return QStringLiteral("XF86AudioNext"); case Qt::Key_MediaPause : case Qt::Key_MediaPlay : case Qt::Key_MediaTogglePlayPause : - return "XF86AudioPlay"; + return QStringLiteral("XF86AudioPlay"); case Qt::Key_MediaRecord : - return "XF86AudioRecord"; + return QStringLiteral("XF86AudioRecord"); case Qt::Key_MediaStop : - return "XF86AudioStop"; + return QStringLiteral("XF86AudioStop"); default : return QKeySequence(keycode).toString(QKeySequence::NativeText); } From 8584ff1b1589ffd2c567486e2f3f6219d5e8e4e8 Mon Sep 17 00:00:00 2001 From: Shatur95 Date: Tue, 20 Oct 2020 13:33:22 +0300 Subject: [PATCH 16/40] Use QTimer::singleShort https://doc.qt.io/qt-5/qtimer.html#singleShot-4 --- QHotkey/qhotkey_x11.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index 5310a07..e3f8519 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -29,7 +29,6 @@ class QHotkeyPrivateX11 : public QHotkeyPrivate private: static const QVector specialModifiers; static const quint32 validModsMask; - QTimer *releaseTimer = nullptr; xcb_key_press_event_t prevHandledEvent; xcb_key_press_event_t prevEvent; @@ -75,17 +74,11 @@ bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray &eventType, void *mes } else if (genericEvent->response_type == XCB_KEY_RELEASE) { xcb_key_release_event_t keyEvent = *static_cast(message); this->prevEvent = keyEvent; - auto *timer = new QTimer(this); - timer->setSingleShot(true); - timer->setInterval(50); - connect(timer, &QTimer::timeout, this, [this, keyEvent, timer] { + QTimer::singleShot(50, [this, keyEvent] { if(this->prevEvent.time == keyEvent.time && this->prevEvent.response_type == keyEvent.response_type && this->prevEvent.detail == keyEvent.detail){ this->releaseShortcut({keyEvent.detail, keyEvent.state & QHotkeyPrivateX11::validModsMask}); } - delete timer; }); - timer->start(); - this->releaseTimer = timer; this->prevHandledEvent = keyEvent; } From 25f21849b3335f437ec6ee2cc74f043d174aaebb Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Thu, 30 Sep 2021 14:46:35 -0300 Subject: [PATCH 17/40] Add support for Qt6 (#51) CMake: The 'QT_MAJOR' CMake variable controls which major version of Qt is used for building. Defaults to '5', so nothing changes when using the default 'cmake' invocation, as it will default to search/build for Qt5. qmake: Just build in the usual way with 'qmake6 && make' or 'qmake-qt5 && make'. When building with Qt6 on GNU/Linux and similar UNIXes, the minimium required Qt version is 6.2.0, as Qt 6.1 and 6.0 lacks support for getting the X11 display. --- CMakeLists.txt | 32 +++++++++++++++++++------- HotkeyTest/CMakeLists.txt | 11 ++++++--- QHotkey/qhotkey.cpp | 27 ++++++++++++++++++---- QHotkey/qhotkey.h | 8 ++++++- QHotkey/qhotkey_x11.cpp | 48 +++++++++++++++++++++++++++++++++------ qhotkey.prc | 11 ++++++++- 6 files changed, 112 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b3d190..f85f8be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,15 +7,27 @@ option(QHOTKEY_INSTALL "Enable install rule" ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -find_package(Qt5 COMPONENTS Core Widgets REQUIRED) +set(QT_MAJOR 5 CACHE STRING "Qt major version to use") -qt5_wrap_cpp(MOC_HEADERS - QHotkey/qhotkey.h - QHotkey/qhotkey_p.h) +if(QT_MAJOR EQUAL 6) + find_package(Qt${QT_MAJOR} 6.2.0 COMPONENTS Core Widgets REQUIRED) +else() + find_package(Qt${QT_MAJOR} COMPONENTS Core Widgets REQUIRED) +endif() + +if(QT_MAJOR GREATER_EQUAL 6) + qt_wrap_cpp(MOC_HEADERS + QHotkey/qhotkey.h + QHotkey/qhotkey_p.h) +else() + qt5_wrap_cpp(MOC_HEADERS + QHotkey/qhotkey.h + QHotkey/qhotkey_p.h) +endif() set(LIBS - Qt5::Core - Qt5::Widgets) + Qt${QT_MAJOR}::Core + Qt${QT_MAJOR}::Widgets) set(SRC_FILES QHotkey/qhotkey.cpp) @@ -30,10 +42,14 @@ elseif(WIN32) set(SRC_FILES ${SRC_FILES} QHotkey/qhotkey_win.cpp) else() find_package(X11 REQUIRED) - find_package(Qt5X11Extras REQUIRED) + if(QT_MAJOR GREATER_EQUAL 6) + set(LIBS ${LIBS} ${X11_LIBRARIES}) + else() + find_package(Qt${QT_MAJOR}X11Extras REQUIRED) + set(LIBS ${LIBS} ${X11_LIBRARIES} Qt${QT_MAJOR}::X11Extras) + endif() include_directories(${X11_INCLUDE_DIR}) - set(LIBS ${LIBS} ${X11_LIBRARIES} Qt5::X11Extras) set(SRC_FILES ${SRC_FILES} QHotkey/qhotkey_x11.cpp) endif() diff --git a/HotkeyTest/CMakeLists.txt b/HotkeyTest/CMakeLists.txt index 67dfc8e..6915fb3 100644 --- a/HotkeyTest/CMakeLists.txt +++ b/HotkeyTest/CMakeLists.txt @@ -1,12 +1,17 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) -qt5_wrap_ui(test_UI_HEADERS hottestwidget.ui) -qt5_wrap_cpp(test_MOC_HEADERS hottestwidget.h) +if(QT_MAJOR GREATER_EQUAL 6) + qt_wrap_ui(test_UI_HEADERS hottestwidget.ui) + qt_wrap_cpp(test_MOC_HEADERS hottestwidget.h) +else() + qt5_wrap_ui(test_UI_HEADERS hottestwidget.ui) + qt5_wrap_cpp(test_MOC_HEADERS hottestwidget.h) +endif() add_executable(HotkeyTest main.cpp hottestwidget.cpp ${test_UI_HEADERS} ${test_MOC_HEADERS}) -target_link_libraries(HotkeyTest Qt5::Widgets qhotkey) +target_link_libraries(HotkeyTest Qt${QT_MAJOR}::Widgets qhotkey) target_include_directories(HotkeyTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/QHotkey/qhotkey.cpp b/QHotkey/qhotkey.cpp index ae6da22..e1ce190 100644 --- a/QHotkey/qhotkey.cpp +++ b/QHotkey/qhotkey.cpp @@ -10,9 +10,15 @@ Q_LOGGING_CATEGORY(logQHotkey, "QHotkey") void QHotkey::addGlobalMapping(const QKeySequence &shortcut, QHotkey::NativeShortcut nativeShortcut) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const int key = shortcut[0].toCombined(); +#else + const int key = shortcut[0]; +#endif + QMetaObject::invokeMethod(QHotkeyPrivate::instance(), "addMappingInvoked", Qt::QueuedConnection, - Q_ARG(Qt::Key, Qt::Key(shortcut[0] & ~Qt::KeyboardModifierMask)), - Q_ARG(Qt::KeyboardModifiers, Qt::KeyboardModifiers(shortcut[0] & Qt::KeyboardModifierMask)), + Q_ARG(Qt::Key, Qt::Key(key & ~Qt::KeyboardModifierMask)), + Q_ARG(Qt::KeyboardModifiers, Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask)), Q_ARG(QHotkey::NativeShortcut, nativeShortcut)); } @@ -56,7 +62,12 @@ QKeySequence QHotkey::shortcut() const { if(_keyCode == Qt::Key_unknown) return QKeySequence(); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return QKeySequence((_keyCode | _modifiers).toCombined()); +#else return QKeySequence(static_cast(_keyCode | _modifiers)); +#endif } Qt::Key QHotkey::keyCode() const @@ -88,8 +99,14 @@ bool QHotkey::setShortcut(const QKeySequence &shortcut, bool autoRegister) "Only the first shortcut will be used!"); } - return setShortcut(Qt::Key(shortcut[0] & ~Qt::KeyboardModifierMask), - Qt::KeyboardModifiers(shortcut[0] & Qt::KeyboardModifierMask), +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const int key = shortcut[0].toCombined(); +#else + const int key = shortcut[0]; +#endif + + return setShortcut(Qt::Key(key & ~Qt::KeyboardModifierMask), + Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask), autoRegister); } @@ -354,7 +371,7 @@ uint qHash(QHotkey::NativeShortcut key) return qHash(key.key) ^ qHash(key.modifier); } -uint qHash(QHotkey::NativeShortcut key, uint seed) +QHOTKEY_HASH_SEED qHash(QHotkey::NativeShortcut key, QHOTKEY_HASH_SEED seed) { return qHash(key.key, seed) ^ qHash(key.modifier, seed); } diff --git a/QHotkey/qhotkey.h b/QHotkey/qhotkey.h index f669640..f21a2c8 100644 --- a/QHotkey/qhotkey.h +++ b/QHotkey/qhotkey.h @@ -16,6 +16,12 @@ #define QHOTKEY_SHARED_EXPORT #endif +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + #define QHOTKEY_HASH_SEED size_t +#else + #define QHOTKEY_HASH_SEED uint +#endif + //! A class to define global, systemwide Hotkeys class QHOTKEY_SHARED_EXPORT QHotkey : public QObject { @@ -115,7 +121,7 @@ public slots: }; uint QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key); -uint QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key, uint seed); +QHOTKEY_HASH_SEED QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key, QHOTKEY_HASH_SEED seed); QHOTKEY_SHARED_EXPORT Q_DECLARE_LOGGING_CATEGORY(logQHotkey) diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index e3f8519..fc06c7a 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -1,7 +1,17 @@ #include "qhotkey.h" #include "qhotkey_p.h" -#include -#include + +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) + #include + + #define _NATIVE_EVENT_RESULT qintptr +#else + #include + #include + + #define _NATIVE_EVENT_RESULT long +#endif + #include #include #include @@ -16,7 +26,7 @@ class QHotkeyPrivateX11 : public QHotkeyPrivate { public: // QAbstractNativeEventFilter interface - bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; + bool nativeEventFilter(const QByteArray &eventType, void *message, _NATIVE_EVENT_RESULT *result) override; protected: // QHotkeyPrivate interface @@ -52,13 +62,17 @@ NATIVE_INSTANCE(QHotkeyPrivateX11) bool QHotkeyPrivate::isPlatformSupported() { +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) + return qGuiApp->nativeInterface(); +#else return QX11Info::isPlatformX11(); +#endif } const QVector QHotkeyPrivateX11::specialModifiers = {0, Mod2Mask, LockMask, (Mod2Mask | LockMask)}; const quint32 QHotkeyPrivateX11::validModsMask = ShiftMask | ControlMask | Mod1Mask | Mod4Mask; -bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray &eventType, void *message, long *result) +bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray &eventType, void *message, _NATIVE_EVENT_RESULT *result) { Q_UNUSED(eventType) Q_UNUSED(result) @@ -120,8 +134,16 @@ quint32 QHotkeyPrivateX11::nativeKeycode(Qt::Key keycode, bool &ok) return 0; } - if(QX11Info::isPlatformX11()) { - auto res = XKeysymToKeycode(QX11Info::display(), keysym); +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) + const QNativeInterface::QX11Application *x11Interface = qGuiApp->nativeInterface(); + Display *display = x11Interface->display(); +#else + const bool x11Interface = QX11Info::isPlatformX11(); + Display *display = QX11Info::display(); +#endif + + if(x11Interface) { + auto res = XKeysymToKeycode(display, keysym); if(res != 0) ok = true; return res; @@ -146,8 +168,15 @@ quint32 QHotkeyPrivateX11::nativeModifiers(Qt::KeyboardModifiers modifiers, bool bool QHotkeyPrivateX11::registerShortcut(QHotkey::NativeShortcut shortcut) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) + const QNativeInterface::QX11Application *x11Interface = qGuiApp->nativeInterface(); + Display *display = x11Interface->display(); +#else + const bool x11Interface = QX11Info::isPlatformX11(); Display *display = QX11Info::display(); - if(!display || !QX11Info::isPlatformX11()) +#endif + + if(!display || !x11Interface) return false; HotkeyErrorHandler errorHandler; @@ -172,7 +201,12 @@ bool QHotkeyPrivateX11::registerShortcut(QHotkey::NativeShortcut shortcut) bool QHotkeyPrivateX11::unregisterShortcut(QHotkey::NativeShortcut shortcut) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) + Display *display = qGuiApp->nativeInterface()->display(); +#else Display *display = QX11Info::display(); +#endif + if(!display) return false; diff --git a/qhotkey.prc b/qhotkey.prc index 30e2b04..d8e8ac0 100644 --- a/qhotkey.prc +++ b/qhotkey.prc @@ -1,6 +1,15 @@ mac: LIBS += -framework Carbon else:win32: LIBS += -luser32 else:unix { - QT += x11extras + equals(QT_MAJOR_VERSION, 6) { + lessThan(QT_VERSION, 6.2.0) { + error("Qt 6.2.0 or greater is required when using Qt6") + } + } + else { + lessThan(QT_MAJOR_VERSION, 6) { + QT += x11extras + } + } LIBS += -lX11 } From 6b3cc35bbd91562ee5192b6b9e9e510a00769c97 Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Fri, 1 Oct 2021 15:04:20 -0300 Subject: [PATCH 18/40] CMake: honor CMAKE_INSTALL_INCLUDEDIR in exported target Remove the hardcode to the 'include' directory in the CMake exported target. This will let the user correctly access the headers when building a client application with a QHotkey package that is installed with a CMAKE_INSTALL_INCLUDEDIR different than 'include'. --- CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f85f8be..2eb65cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,10 +57,12 @@ add_library(qhotkey ${SRC_FILES} ${MOC_HEADERS}) add_library(QHotkey::QHotkey ALIAS qhotkey) target_link_libraries(qhotkey ${LIBS}) +include(GNUInstallDirs) + target_include_directories(qhotkey PUBLIC $ - $) + $) set_target_properties(qhotkey PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} @@ -71,7 +73,6 @@ if(QHOTKEY_EXAMPLES) endif() if(QHOTKEY_INSTALL) - include(GNUInstallDirs) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/QHotkey) install( @@ -82,7 +83,7 @@ if(QHOTKEY_INSTALL) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/QHotkey/qhotkey.h ${CMAKE_CURRENT_SOURCE_DIR}/QHotkey/QHotkey - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/) + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(EXPORT QHotkeyConfig DESTINATION ${INSTALL_CONFIGDIR}) export(TARGETS qhotkey FILE QHotkeyConfig.cmake) From dbec7d3a2da333de746ef693477a377af29ef4ce Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Sun, 3 Oct 2021 05:01:00 -0300 Subject: [PATCH 19/40] Readme: add build instructions This will also provide information about the supported Qt versions. --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index e4f3f78..8256f1f 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,32 @@ The QHotkey is a class that can be used to create hotkeys/global shortcuts, aka **Note:** For now Wayland is not supported, as it is simply not possible to register a global shortcut with wayland. For more details, or possible Ideas on how to get Hotkeys working on wayland, see [Issue #14](https://github.com/Skycoder42/QHotkey/issues/14). +## Building + +QHotkey supports both Qt6 and Qt5. When using Qt6, version 6.2.0 or later required. It can be built by either the CMake or qmake building systems. + +### CMake + +The CMake `QT_MAJOR` variable controls which major version of Qt is used for building, and defaults to `5`. For example, use the CMake command line option `-DQT_MAJOR=6` for building with Qt6. To build the testing application `QHotkeyTest`, specify `-DQHOTKEY_EXAMPLES=ON`. CMake example usage: + +``` +$ cd QHotkey +$ cmake -B build -S . -DQT_MAJOR=6 +$ cmake --build build +# cmake --install build +``` + +### qmake + +The major version of Qt is chosen by the qmake invokation itself, as the qmake executable is tied to a specific Qt version. The executable name can vary between operating systems. qmake example usage: + +``` +$ cd QHotkey +$ qmake +$ make +# make install +``` + ## Installation The package is providet as qpm package, [`de.skycoder42.qhotkey`](https://www.qpm.io/packages/de.skycoder42.qhotkey/index.html). You can install it either via qpmx (preferred) or directly via qpm. From 79e5dd65be78ccd43db69a40a40624a6203b1f51 Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Sun, 3 Oct 2021 08:07:20 -0300 Subject: [PATCH 20/40] CMake: change link type and remove Qt Widgets (#53) Link type can be changed to PRIVATE. Only Qt Core will remain as PUBLIC linking. It looks like that Qt Widgets is not needed and can be removed. On Qt6, Qt6::Gui is strictly needed. --- CMakeLists.txt | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2eb65cf..df165bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,9 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(QT_MAJOR 5 CACHE STRING "Qt major version to use") if(QT_MAJOR EQUAL 6) - find_package(Qt${QT_MAJOR} 6.2.0 COMPONENTS Core Widgets REQUIRED) + find_package(Qt${QT_MAJOR} 6.2.0 COMPONENTS Core Gui REQUIRED) else() - find_package(Qt${QT_MAJOR} COMPONENTS Core Widgets REQUIRED) + find_package(Qt${QT_MAJOR} COMPONENTS Core Gui REQUIRED) endif() if(QT_MAJOR GREATER_EQUAL 6) @@ -25,38 +25,35 @@ else() QHotkey/qhotkey_p.h) endif() -set(LIBS - Qt${QT_MAJOR}::Core - Qt${QT_MAJOR}::Widgets) - -set(SRC_FILES - QHotkey/qhotkey.cpp) +add_library(qhotkey QHotkey/qhotkey.cpp ${MOC_HEADERS}) +add_library(QHotkey::QHotkey ALIAS qhotkey) +target_link_libraries(qhotkey PUBLIC Qt${QT_MAJOR}::Core) +target_link_libraries(qhotkey PRIVATE Qt${QT_MAJOR}::Gui) if(APPLE) find_library(CARBON_LIBRARY Carbon) mark_as_advanced(CARBON_LIBRARY) - set(SRC_FILES ${SRC_FILES} QHotkey/qhotkey_mac.cpp) - set(LIBS ${LIBS} ${CARBON_LIBRARY}) + target_sources(qhotkey PRIVATE QHotkey/qhotkey_mac.cpp) + target_link_libraries(qhotkey PRIVATE ${CARBON_LIBRARY}) elseif(WIN32) - set(SRC_FILES ${SRC_FILES} QHotkey/qhotkey_win.cpp) + target_sources(qhotkey PRIVATE QHotkey/qhotkey_win.cpp) else() find_package(X11 REQUIRED) if(QT_MAJOR GREATER_EQUAL 6) - set(LIBS ${LIBS} ${X11_LIBRARIES}) + target_link_libraries(qhotkey PRIVATE ${X11_LIBRARIES}) else() find_package(Qt${QT_MAJOR}X11Extras REQUIRED) - set(LIBS ${LIBS} ${X11_LIBRARIES} Qt${QT_MAJOR}::X11Extras) + target_link_libraries(qhotkey + PRIVATE + ${X11_LIBRARIES} + Qt${QT_MAJOR}::X11Extras) endif() include_directories(${X11_INCLUDE_DIR}) - set(SRC_FILES ${SRC_FILES} QHotkey/qhotkey_x11.cpp) + target_sources(qhotkey PRIVATE QHotkey/qhotkey_x11.cpp) endif() -add_library(qhotkey ${SRC_FILES} ${MOC_HEADERS}) -add_library(QHotkey::QHotkey ALIAS qhotkey) -target_link_libraries(qhotkey ${LIBS}) - include(GNUInstallDirs) target_include_directories(qhotkey From 7b10ea6d64acb9d9f8ccd86b7bcd503435fcc844 Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Sun, 3 Oct 2021 08:18:23 -0300 Subject: [PATCH 21/40] Qt6 support for Windows and Mac (#54) This follows commit 25f2184. On Windows, changing the return value of the qHash() variant that takes one argument fixes the following warning on MSVC 2019: qhotkey.cpp:(371,45): warning C4267: 'return': conversion from 'size_t' to 'uint', possible loss of data --- QHotkey/qhotkey.cpp | 2 +- QHotkey/qhotkey.h | 2 +- QHotkey/qhotkey_mac.cpp | 6 +++--- QHotkey/qhotkey_p.h | 6 ++++++ QHotkey/qhotkey_win.cpp | 4 ++-- QHotkey/qhotkey_x11.cpp | 4 ---- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/QHotkey/qhotkey.cpp b/QHotkey/qhotkey.cpp index e1ce190..3b76d9c 100644 --- a/QHotkey/qhotkey.cpp +++ b/QHotkey/qhotkey.cpp @@ -366,7 +366,7 @@ bool QHotkey::NativeShortcut::operator !=(QHotkey::NativeShortcut other) const valid != other.valid; } -uint qHash(QHotkey::NativeShortcut key) +QHOTKEY_HASH_SEED qHash(QHotkey::NativeShortcut key) { return qHash(key.key) ^ qHash(key.modifier); } diff --git a/QHotkey/qhotkey.h b/QHotkey/qhotkey.h index f21a2c8..c520ba3 100644 --- a/QHotkey/qhotkey.h +++ b/QHotkey/qhotkey.h @@ -120,7 +120,7 @@ public slots: bool _registered; }; -uint QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key); +QHOTKEY_HASH_SEED QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key); QHOTKEY_HASH_SEED QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key, QHOTKEY_HASH_SEED seed); QHOTKEY_SHARED_EXPORT Q_DECLARE_LOGGING_CATEGORY(logQHotkey) diff --git a/QHotkey/qhotkey_mac.cpp b/QHotkey/qhotkey_mac.cpp index 0e06299..2cf0db4 100644 --- a/QHotkey/qhotkey_mac.cpp +++ b/QHotkey/qhotkey_mac.cpp @@ -7,7 +7,7 @@ class QHotkeyPrivateMac : public QHotkeyPrivate { public: // QAbstractNativeEventFilter interface - bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; + bool nativeEventFilter(const QByteArray &eventType, void *message, _NATIVE_EVENT_RESULT *result) override; static OSStatus hotkeyPressEventHandler(EventHandlerCallRef nextHandler, EventRef event, void* data); static OSStatus hotkeyReleaseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void* data); @@ -33,7 +33,7 @@ bool QHotkeyPrivate::isPlatformSupported() bool QHotkeyPrivateMac::isHotkeyHandlerRegistered = false; QHash QHotkeyPrivateMac::hotkeyRefs; -bool QHotkeyPrivateMac::nativeEventFilter(const QByteArray &eventType, void *message, long *result) +bool QHotkeyPrivateMac::nativeEventFilter(const QByteArray &eventType, void *message, _NATIVE_EVENT_RESULT *result) { Q_UNUSED(eventType) Q_UNUSED(message) @@ -288,4 +288,4 @@ OSStatus QHotkeyPrivateMac::hotkeyReleaseEventHandler(EventHandlerCallRef nextHa } return noErr; -} \ No newline at end of file +} diff --git a/QHotkey/qhotkey_p.h b/QHotkey/qhotkey_p.h index b7c1721..d1bd1d2 100644 --- a/QHotkey/qhotkey_p.h +++ b/QHotkey/qhotkey_p.h @@ -7,6 +7,12 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + #define _NATIVE_EVENT_RESULT qintptr +#else + #define _NATIVE_EVENT_RESULT long +#endif + class QHOTKEY_SHARED_EXPORT QHotkeyPrivate : public QObject, public QAbstractNativeEventFilter { Q_OBJECT diff --git a/QHotkey/qhotkey_win.cpp b/QHotkey/qhotkey_win.cpp index a03b8c0..715b92e 100644 --- a/QHotkey/qhotkey_win.cpp +++ b/QHotkey/qhotkey_win.cpp @@ -15,7 +15,7 @@ class QHotkeyPrivateWin : public QHotkeyPrivate public: QHotkeyPrivateWin(); // QAbstractNativeEventFilter interface - bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; + bool nativeEventFilter(const QByteArray &eventType, void *message, _NATIVE_EVENT_RESULT *result) override; protected: void pollForHotkeyRelease(); @@ -42,7 +42,7 @@ bool QHotkeyPrivate::isPlatformSupported() return true; } -bool QHotkeyPrivateWin::nativeEventFilter(const QByteArray &eventType, void *message, long *result) +bool QHotkeyPrivateWin::nativeEventFilter(const QByteArray &eventType, void *message, _NATIVE_EVENT_RESULT *result) { Q_UNUSED(eventType) Q_UNUSED(result) diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index fc06c7a..ce408e6 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -3,13 +3,9 @@ #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) #include - - #define _NATIVE_EVENT_RESULT qintptr #else #include #include - - #define _NATIVE_EVENT_RESULT long #endif #include From 7f5840fd34644a6970f8ac544eee3d2ba28618b5 Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Sun, 3 Oct 2021 11:21:34 +0300 Subject: [PATCH 22/40] Add CI --- .github/workflows/build.yml | 57 +++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 15 ++-------- HotkeyTest/CMakeLists.txt | 16 ++++------- QHotkey/qhotkey_p.h | 3 -- 4 files changed, 65 insertions(+), 26 deletions(-) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..0467049 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,57 @@ +name: Build + +on: + push: + branches-ignore: + - "releases/**" + paths-ignore: + - "**.md" + +jobs: + build: + strategy: + matrix: + qt_version: [5.12.11, 5.15.2, 6.2.0] + platform: [ubuntu-20.04, windows-latest, macos-latest] + include: + - qt_version: 6.2.0 + additional_arguments: -D QT_MAJOR=6 + - platform: ubuntu-20.04 + make: make + CXXFLAGS: -Wall -Wextra -pedantic -Werror + MAKEFLAGS: -j2 + - platform: macos-latest + make: make + CXXFLAGS: -Wall -Wextra -pedantic -Werror -Wno-gnu-zero-variadic-macro-arguments # Ignore false-positive warning for qCWarning + MAKEFLAGS: -j3 + - platform: windows-latest + make: nmake + CXXFLAGS: /W4 /WX /MP + + runs-on: ${{ matrix.platform }} + env: + CXXFLAGS: ${{ matrix.CXXFLAGS }} + MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + + steps: + - name: Clone repo + uses: actions/checkout@v2.3.4 + + - name: Install Qt + uses: jurplel/install-qt-action@v2.14.0 + with: + version: ${{ matrix.qt_version }} + + - name: Build with CMake + run: | + cmake . -D QHOTKEY_EXAMPLES=ON ${{ matrix.additional_arguments }} + cmake --build . + + - name: Setup MSVC environment for QMake + uses: ilammy/msvc-dev-cmd@v1 + + - name: Build with QMake + working-directory: HotkeyTest + run: | + qmake + ${{ matrix.make }} diff --git a/CMakeLists.txt b/CMakeLists.txt index df165bc..fe49287 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ option(QHOTKEY_EXAMPLES "Build examples" OFF) option(QHOTKEY_INSTALL "Enable install rule" ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_AUTOMOC ON) set(QT_MAJOR 5 CACHE STRING "Qt major version to use") @@ -15,17 +16,7 @@ else() find_package(Qt${QT_MAJOR} COMPONENTS Core Gui REQUIRED) endif() -if(QT_MAJOR GREATER_EQUAL 6) - qt_wrap_cpp(MOC_HEADERS - QHotkey/qhotkey.h - QHotkey/qhotkey_p.h) -else() - qt5_wrap_cpp(MOC_HEADERS - QHotkey/qhotkey.h - QHotkey/qhotkey_p.h) -endif() - -add_library(qhotkey QHotkey/qhotkey.cpp ${MOC_HEADERS}) +add_library(qhotkey QHotkey/qhotkey.cpp) add_library(QHotkey::QHotkey ALIAS qhotkey) target_link_libraries(qhotkey PUBLIC Qt${QT_MAJOR}::Core) target_link_libraries(qhotkey PRIVATE Qt${QT_MAJOR}::Gui) @@ -43,7 +34,7 @@ else() if(QT_MAJOR GREATER_EQUAL 6) target_link_libraries(qhotkey PRIVATE ${X11_LIBRARIES}) else() - find_package(Qt${QT_MAJOR}X11Extras REQUIRED) + find_package(Qt${QT_MAJOR} COMPONENTS X11Extras REQUIRED) target_link_libraries(qhotkey PRIVATE ${X11_LIBRARIES} diff --git a/HotkeyTest/CMakeLists.txt b/HotkeyTest/CMakeLists.txt index 6915fb3..17d3f2e 100644 --- a/HotkeyTest/CMakeLists.txt +++ b/HotkeyTest/CMakeLists.txt @@ -1,17 +1,11 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) -if(QT_MAJOR GREATER_EQUAL 6) - qt_wrap_ui(test_UI_HEADERS hottestwidget.ui) - qt_wrap_cpp(test_MOC_HEADERS hottestwidget.h) -else() - qt5_wrap_ui(test_UI_HEADERS hottestwidget.ui) - qt5_wrap_cpp(test_MOC_HEADERS hottestwidget.h) -endif() +set(CMAKE_AUTOUIC ON) add_executable(HotkeyTest main.cpp hottestwidget.cpp - ${test_UI_HEADERS} - ${test_MOC_HEADERS}) -target_link_libraries(HotkeyTest Qt${QT_MAJOR}::Widgets qhotkey) -target_include_directories(HotkeyTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + hottestwidget.ui) + +find_package(Qt${QT_MAJOR} COMPONENTS Widgets REQUIRED) +target_link_libraries(HotkeyTest Qt${QT_MAJOR}::Widgets QHotkey::QHotkey) diff --git a/QHotkey/qhotkey_p.h b/QHotkey/qhotkey_p.h index d1bd1d2..d588270 100644 --- a/QHotkey/qhotkey_p.h +++ b/QHotkey/qhotkey_p.h @@ -59,7 +59,4 @@ class QHOTKEY_SHARED_EXPORT QHotkeyPrivate : public QObject, public QAbstractNat return hotkeyPrivate;\ } -Q_DECLARE_METATYPE(Qt::Key) -Q_DECLARE_METATYPE(Qt::KeyboardModifiers) - #endif // QHOTKEY_P_H From 1d49a63827ae9d9180d8c6d95cb2e2b548d39880 Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Sun, 3 Oct 2021 13:52:50 -0300 Subject: [PATCH 23/40] CMake: add package version config file (#57) By adding this file, client applications can have proper version checking support when calling 'find_package()'. --- .github/workflows/build.yml | 3 +++ CMakeLists.txt | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0467049..6dc6312 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,9 @@ on: - "releases/**" paths-ignore: - "**.md" + pull_request: + paths-ignore: + - "**.md" jobs: build: diff --git a/CMakeLists.txt b/CMakeLists.txt index fe49287..b5c1131 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.1) -project(qhotkey VERSION 1.2.2 LANGUAGES CXX) +project(qhotkey VERSION 1.4.2 LANGUAGES CXX) option(QHOTKEY_EXAMPLES "Build examples" OFF) option(QHOTKEY_INSTALL "Enable install rule" ON) @@ -52,9 +52,18 @@ target_include_directories(qhotkey $ $) +include(CMakePackageConfigHelpers) + set_target_properties(qhotkey PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} - VERSION ${PROJECT_VERSION}) + VERSION ${PROJECT_VERSION} + INTERFACE_QHotkey_MAJOR_VERSION ${PROJECT_VERSION_MAJOR} + COMPATIBLE_INTERFACE_STRING QHotkey_MAJOR_VERSION) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/QHotkeyConfigVersion.cmake + VERSION "${PROJECT_VERSION}" + COMPATIBILITY AnyNewerVersion) if(QHOTKEY_EXAMPLES) add_subdirectory(HotkeyTest) @@ -72,6 +81,9 @@ if(QHOTKEY_INSTALL) ${CMAKE_CURRENT_SOURCE_DIR}/QHotkey/qhotkey.h ${CMAKE_CURRENT_SOURCE_DIR}/QHotkey/QHotkey DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/QHotkeyConfigVersion.cmake + DESTINATION ${INSTALL_CONFIGDIR}) install(EXPORT QHotkeyConfig DESTINATION ${INSTALL_CONFIGDIR}) export(TARGETS qhotkey FILE QHotkeyConfig.cmake) From e0bc2a9b9fa71e325956d0a2d37be2d4a7441f58 Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Tue, 5 Oct 2021 01:25:26 +0300 Subject: [PATCH 24/40] Fix shared library build --- .github/workflows/build.yml | 15 +++++++++++++-- CMakeLists.txt | 5 +++++ QHotkey/QHotkey.pro | 2 +- QHotkey/qhotkey.h | 24 ++++++++++++------------ QHotkey/qhotkey_p.h | 2 +- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6dc6312..91171e8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,16 +45,27 @@ jobs: with: version: ${{ matrix.qt_version }} - - name: Build with CMake + - name: Build with CMake as static run: | cmake . -D QHOTKEY_EXAMPLES=ON ${{ matrix.additional_arguments }} cmake --build . + - name: Build with CMake as shared + run: | + cmake . -D BUILD_SHARED_LIBS=ON -D QHOTKEY_EXAMPLES=ON ${{ matrix.additional_arguments }} + cmake --build . + - name: Setup MSVC environment for QMake uses: ilammy/msvc-dev-cmd@v1 - - name: Build with QMake + - name: Build with QMake as static working-directory: HotkeyTest run: | qmake ${{ matrix.make }} + + - name: Build with QMake as shared + working-directory: HotkeyTest + run: | + qmake "DEFINES+=QHOTKEY_SHARED QHOTKEY_LIBRARY" + ${{ matrix.make }} diff --git a/CMakeLists.txt b/CMakeLists.txt index b5c1131..57880a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,11 @@ add_library(QHotkey::QHotkey ALIAS qhotkey) target_link_libraries(qhotkey PUBLIC Qt${QT_MAJOR}::Core) target_link_libraries(qhotkey PRIVATE Qt${QT_MAJOR}::Gui) +if(BUILD_SHARED_LIBS) + target_compile_definitions(qhotkey PRIVATE QHOTKEY_LIBRARY) + target_compile_definitions(qhotkey PUBLIC QHOTKEY_SHARED) +endif() + if(APPLE) find_library(CARBON_LIBRARY Carbon) mark_as_advanced(CARBON_LIBRARY) diff --git a/QHotkey/QHotkey.pro b/QHotkey/QHotkey.pro index 44e937b..5a261e0 100644 --- a/QHotkey/QHotkey.pro +++ b/QHotkey/QHotkey.pro @@ -6,7 +6,7 @@ VERSION = 1.2.1 include(../qhotkey.pri) -DEFINES += QHOTKEY_LIB QHOTKEY_LIB_BUILD +DEFINES += QHOTKEY_SHARED QHOTKEY_LIBRARY # use INSTALL_ROOT to modify the install location headers.files = $$PUBLIC_HEADERS diff --git a/QHotkey/qhotkey.h b/QHotkey/qhotkey.h index c520ba3..3697c8e 100644 --- a/QHotkey/qhotkey.h +++ b/QHotkey/qhotkey.h @@ -6,14 +6,14 @@ #include #include -#ifdef QHOTKEY_LIB - #ifdef QHOTKEY_LIB_BUILD - #define QHOTKEY_SHARED_EXPORT Q_DECL_EXPORT - #else - #define QHOTKEY_SHARED_EXPORT Q_DECL_IMPORT - #endif +#ifdef QHOTKEY_SHARED +# ifdef QHOTKEY_LIBRARY +# define QHOTKEY_EXPORT Q_DECL_EXPORT +# else +# define QHOTKEY_EXPORT Q_DECL_IMPORT +# endif #else - #define QHOTKEY_SHARED_EXPORT +# define QHOTKEY_EXPORT #endif #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) @@ -23,7 +23,7 @@ #endif //! A class to define global, systemwide Hotkeys -class QHOTKEY_SHARED_EXPORT QHotkey : public QObject +class QHOTKEY_EXPORT QHotkey : public QObject { Q_OBJECT //! @private @@ -36,7 +36,7 @@ class QHOTKEY_SHARED_EXPORT QHotkey : public QObject public: //! Defines shortcut with native keycodes - class QHOTKEY_SHARED_EXPORT NativeShortcut { + class QHOTKEY_EXPORT NativeShortcut { public: //! The native keycode quint32 key; @@ -120,10 +120,10 @@ public slots: bool _registered; }; -QHOTKEY_HASH_SEED QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key); -QHOTKEY_HASH_SEED QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key, QHOTKEY_HASH_SEED seed); +QHOTKEY_HASH_SEED QHOTKEY_EXPORT qHash(QHotkey::NativeShortcut key); +QHOTKEY_HASH_SEED QHOTKEY_EXPORT qHash(QHotkey::NativeShortcut key, QHOTKEY_HASH_SEED seed); -QHOTKEY_SHARED_EXPORT Q_DECLARE_LOGGING_CATEGORY(logQHotkey) +QHOTKEY_EXPORT Q_DECLARE_LOGGING_CATEGORY(logQHotkey) Q_DECLARE_METATYPE(QHotkey::NativeShortcut) diff --git a/QHotkey/qhotkey_p.h b/QHotkey/qhotkey_p.h index d588270..8bc5ab6 100644 --- a/QHotkey/qhotkey_p.h +++ b/QHotkey/qhotkey_p.h @@ -13,7 +13,7 @@ #define _NATIVE_EVENT_RESULT long #endif -class QHOTKEY_SHARED_EXPORT QHotkeyPrivate : public QObject, public QAbstractNativeEventFilter +class QHOTKEY_EXPORT QHotkeyPrivate : public QObject, public QAbstractNativeEventFilter { Q_OBJECT From 1114df5081f2cda334531ac664c7434c13dccfe6 Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Tue, 5 Oct 2021 19:08:48 +0300 Subject: [PATCH 25/40] Bump version to 1.4.2 in QMake --- QHotkey/QHotkey.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QHotkey/QHotkey.pro b/QHotkey/QHotkey.pro index 5a261e0..edc1110 100644 --- a/QHotkey/QHotkey.pro +++ b/QHotkey/QHotkey.pro @@ -2,7 +2,7 @@ TEMPLATE = lib win32: CONFIG += dll TARGET = QHotkey -VERSION = 1.2.1 +VERSION = 1.4.2 include(../qhotkey.pri) From 64fec66d358ead43784e085b424375f65b145307 Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Thu, 28 Oct 2021 22:33:17 +0300 Subject: [PATCH 26/40] Fix memory leak in README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8256f1f..95ab938 100644 --- a/README.md +++ b/README.md @@ -74,17 +74,17 @@ The following example shows a simple application that will run without a window int main(int argc, char *argv[]) { - QApplication a(argc, argv); + QApplication app(argc, argv); - auto hotkey = new QHotkey(QKeySequence("ctrl+alt+Q"), true, &a);//The hotkey will be automatically registered - qDebug() << "Is Registered: " << hotkey->isRegistered(); + QHotkey hotkey(QKeySequence("Ctrl+Alt+Q"), true, &app); //The hotkey will be automatically registered + qDebug() << "Is segistered:" << hotkey.isRegistered(); - QObject::connect(hotkey, &QHotkey::activated, qApp, [&](){ + QObject::connect(&hotkey, &QHotkey::activated, qApp, [&](){ qDebug() << "Hotkey Activated - the application will quit now"; qApp->quit(); }); - return a.exec(); + return app.exec(); } ``` From fcf83f3e36d98c0f896704424622809bddf3d53c Mon Sep 17 00:00:00 2001 From: Hennadii Chernyshchyk Date: Thu, 28 Oct 2021 23:38:08 +0300 Subject: [PATCH 27/40] Use QT_DEFAULT_MAJOR_VERSION --- .github/workflows/build.yml | 2 +- CMakeLists.txt | 20 +++++++++++--------- HotkeyTest/CMakeLists.txt | 4 ++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 91171e8..7affb86 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: platform: [ubuntu-20.04, windows-latest, macos-latest] include: - qt_version: 6.2.0 - additional_arguments: -D QT_MAJOR=6 + additional_arguments: -D QT_DEFAULT_MAJOR_VERSION=6 - platform: ubuntu-20.04 make: make CXXFLAGS: -Wall -Wextra -pedantic -Werror diff --git a/CMakeLists.txt b/CMakeLists.txt index 57880a7..641aafc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,18 +8,20 @@ option(QHOTKEY_INSTALL "Enable install rule" ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_AUTOMOC ON) -set(QT_MAJOR 5 CACHE STRING "Qt major version to use") +if(NOT QT_DEFAULT_MAJOR_VERSION) + set(QT_DEFAULT_MAJOR_VERSION 5 CACHE STRING "Qt version to use (5 or 6), defaults to 5") +endif() -if(QT_MAJOR EQUAL 6) - find_package(Qt${QT_MAJOR} 6.2.0 COMPONENTS Core Gui REQUIRED) +if(QT_DEFAULT_MAJOR_VERSION EQUAL 6) + find_package(Qt${QT_DEFAULT_MAJOR_VERSION} 6.2.0 COMPONENTS Core Gui REQUIRED) else() - find_package(Qt${QT_MAJOR} COMPONENTS Core Gui REQUIRED) + find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS Core Gui REQUIRED) endif() add_library(qhotkey QHotkey/qhotkey.cpp) add_library(QHotkey::QHotkey ALIAS qhotkey) -target_link_libraries(qhotkey PUBLIC Qt${QT_MAJOR}::Core) -target_link_libraries(qhotkey PRIVATE Qt${QT_MAJOR}::Gui) +target_link_libraries(qhotkey PUBLIC Qt${QT_DEFAULT_MAJOR_VERSION}::Core) +target_link_libraries(qhotkey PRIVATE Qt${QT_DEFAULT_MAJOR_VERSION}::Gui) if(BUILD_SHARED_LIBS) target_compile_definitions(qhotkey PRIVATE QHOTKEY_LIBRARY) @@ -36,14 +38,14 @@ elseif(WIN32) target_sources(qhotkey PRIVATE QHotkey/qhotkey_win.cpp) else() find_package(X11 REQUIRED) - if(QT_MAJOR GREATER_EQUAL 6) + if(QT_DEFAULT_MAJOR_VERSION GREATER_EQUAL 6) target_link_libraries(qhotkey PRIVATE ${X11_LIBRARIES}) else() - find_package(Qt${QT_MAJOR} COMPONENTS X11Extras REQUIRED) + find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS X11Extras REQUIRED) target_link_libraries(qhotkey PRIVATE ${X11_LIBRARIES} - Qt${QT_MAJOR}::X11Extras) + Qt${QT_DEFAULT_MAJOR_VERSION}::X11Extras) endif() include_directories(${X11_INCLUDE_DIR}) diff --git a/HotkeyTest/CMakeLists.txt b/HotkeyTest/CMakeLists.txt index 17d3f2e..714585d 100644 --- a/HotkeyTest/CMakeLists.txt +++ b/HotkeyTest/CMakeLists.txt @@ -7,5 +7,5 @@ add_executable(HotkeyTest hottestwidget.cpp hottestwidget.ui) -find_package(Qt${QT_MAJOR} COMPONENTS Widgets REQUIRED) -target_link_libraries(HotkeyTest Qt${QT_MAJOR}::Widgets QHotkey::QHotkey) +find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS Widgets REQUIRED) +target_link_libraries(HotkeyTest Qt${QT_DEFAULT_MAJOR_VERSION}::Widgets QHotkey::QHotkey) From 6a0cc377e6d950ac0407bd3a80809934062e4f4e Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Thu, 28 Oct 2021 18:08:58 -0300 Subject: [PATCH 28/40] Bump version to 1.5.0 --- CMakeLists.txt | 2 +- QHotkey/QHotkey.pro | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 641aafc..d0904e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.1) -project(qhotkey VERSION 1.4.2 LANGUAGES CXX) +project(qhotkey VERSION 1.5.0 LANGUAGES CXX) option(QHOTKEY_EXAMPLES "Build examples" OFF) option(QHOTKEY_INSTALL "Enable install rule" ON) diff --git a/QHotkey/QHotkey.pro b/QHotkey/QHotkey.pro index edc1110..3a79376 100644 --- a/QHotkey/QHotkey.pro +++ b/QHotkey/QHotkey.pro @@ -2,7 +2,7 @@ TEMPLATE = lib win32: CONFIG += dll TARGET = QHotkey -VERSION = 1.4.2 +VERSION = 1.5.0 include(../qhotkey.pri) From 34330d6ff5d2ca111c376f6d7da66be9d1817430 Mon Sep 17 00:00:00 2001 From: Shatur95 Date: Fri, 29 Oct 2021 00:24:53 +0300 Subject: [PATCH 29/40] Link Gui as PUBLIC --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0904e9..a3d1097 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,8 +20,7 @@ endif() add_library(qhotkey QHotkey/qhotkey.cpp) add_library(QHotkey::QHotkey ALIAS qhotkey) -target_link_libraries(qhotkey PUBLIC Qt${QT_DEFAULT_MAJOR_VERSION}::Core) -target_link_libraries(qhotkey PRIVATE Qt${QT_DEFAULT_MAJOR_VERSION}::Gui) +target_link_libraries(qhotkey PUBLIC Qt${QT_DEFAULT_MAJOR_VERSION}::Core Qt${QT_DEFAULT_MAJOR_VERSION}::Gui) if(BUILD_SHARED_LIBS) target_compile_definitions(qhotkey PRIVATE QHOTKEY_LIBRARY) From 308c96c28f9be4dc9139371200cd50c68f823a73 Mon Sep 17 00:00:00 2001 From: waneon Date: Sun, 6 Feb 2022 06:52:21 +0900 Subject: [PATCH 30/40] Fix invalid variable name in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 95ab938..5e40930 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,11 @@ QHotkey supports both Qt6 and Qt5. When using Qt6, version 6.2.0 or later requir ### CMake -The CMake `QT_MAJOR` variable controls which major version of Qt is used for building, and defaults to `5`. For example, use the CMake command line option `-DQT_MAJOR=6` for building with Qt6. To build the testing application `QHotkeyTest`, specify `-DQHOTKEY_EXAMPLES=ON`. CMake example usage: +The CMake `QT_DEFAULT_MAJOR_VERSION` variable controls which major version of Qt is used for building, and defaults to `5`. For example, use the CMake command line option `-DQT_DEFAULT_MAJOR_VERSION=6` for building with Qt6. To build the testing application `QHotkeyTest`, specify `-DQHOTKEY_EXAMPLES=ON`. CMake example usage: ``` $ cd QHotkey -$ cmake -B build -S . -DQT_MAJOR=6 +$ cmake -B build -S . -DQT_DEFAULT_MAJOR_VERSION=6 $ cmake --build build # cmake --install build ``` From 52e25acf221e5ac86ce648f6922620fb2d6a7121 Mon Sep 17 00:00:00 2001 From: YueLiang <38413990+Yue-Liang@users.noreply.github.com> Date: Mon, 21 Feb 2022 16:01:45 +0800 Subject: [PATCH 31/40] Fix bug for get natice keycode failed in mac (#66) TISCopyCurrentKeyboardInputSource will return null when using Chinese input method. Use TISCopyCurrentASCIICapableKeyboardLayoutInputSource instead. --- QHotkey/qhotkey_mac.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QHotkey/qhotkey_mac.cpp b/QHotkey/qhotkey_mac.cpp index 2cf0db4..799f515 100644 --- a/QHotkey/qhotkey_mac.cpp +++ b/QHotkey/qhotkey_mac.cpp @@ -134,7 +134,7 @@ quint32 QHotkeyPrivateMac::nativeKeycode(Qt::Key keycode, bool &ok) UTF16Char ch = keycode; CFDataRef currentLayoutData; - TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + TISInputSourceRef currentKeyboard = TISCopyCurrentASCIICapableKeyboardLayoutInputSource(); if (currentKeyboard == NULL) return 0; From c501fbbadaf9f561ad5a5c35964f924783a69647 Mon Sep 17 00:00:00 2001 From: luz paz Date: Wed, 22 Jun 2022 19:20:55 -0400 Subject: [PATCH 32/40] Fix typos Found via `codespell -q 3` --- HotkeyTest/hottestwidget.ui | 6 +++--- QHotkey/qhotkey_x11.cpp | 2 +- README.md | 12 ++++++------ doc/qhotkey.dox | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/HotkeyTest/hottestwidget.ui b/HotkeyTest/hottestwidget.ui index c1db840..8da0d92 100644 --- a/HotkeyTest/hottestwidget.ui +++ b/HotkeyTest/hottestwidget.ui @@ -769,7 +769,7 @@ - <b>Testing:</b> Please press the combinations listed below to check whether they work properly or not. Everytime a shortcut is triggered, the checkbox will toggle it's value. Set the test active to begin. + <b>Testing:</b> Please press the combinations listed below to check whether they work properly or not. Every time a shortcut is triggered, the checkbox will toggle it's value. Set the test active to begin. true @@ -927,7 +927,7 @@ - <html><head/><body><p>This test was designed to try out multi-threaded shortcuts. The QHotkey class is completly <span style=" font-weight:600;">threadsafe</span>, but this test can help to see if it acutally works (It does).</p><p>If activated, <span style=" font-style:italic;">Hotkey 4 and Hotkey 5 </span>of the Playground will each run on their own thread. This means:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" text-decoration: underline;">Mainthread:</span> Hotkey 1, 2, 3</li><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" text-decoration: underline;">Second thread:</span> Hotkey 4</li><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" text-decoration: underline;">Third thread:</span> Hotkey 5</li></ul><p><span style=" font-weight:600;">Note:</span> The two hotkeys will be moved to the threads. For simplicity-reasons, you can't move them back in this test (But its possible, just not done here). Restart the test to get them back.</p></body></html> + <html><head/><body><p>This test was designed to try out multi-threaded shortcuts. The QHotkey class is completely <span style=" font-weight:600;">threadsafe</span>, but this test can help to see if it actually works (It does).</p><p>If activated, <span style=" font-style:italic;">Hotkey 4 and Hotkey 5 </span>of the Playground will each run on their own thread. This means:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" text-decoration: underline;">Mainthread:</span> Hotkey 1, 2, 3</li><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" text-decoration: underline;">Second thread:</span> Hotkey 4</li><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" text-decoration: underline;">Third thread:</span> Hotkey 5</li></ul><p><span style=" font-weight:600;">Note:</span> The two hotkeys will be moved to the threads. For simplicity-reasons, you can't move them back in this test (But its possible, just not done here). Restart the test to get them back.</p></body></html> Qt::RichText @@ -973,7 +973,7 @@ - <html><head/><body><p>QHotkey allows you to set native shortcuts explicitly. These, of course, only work on the platform they were choosen for. All platform use special constants for their key codes and modifiers, which makes it pretty simple to use them from code. If you want to test them out here, google for the tables.</p><p>In most cases, you will not need to specify native shortcuts directly. However, as explaind on previos tabs, some shotcuts may not be creatable from Qt's key (e.g. Numblock numbers). In that case, you can set the directly.</p><p><span style=" text-decoration: underline;">Example: Ctrl+A</span></p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Windows:</span> Key: <span style=" font-style:italic;">0x0041</span>, Modifier: <span style=" font-style:italic;">0x0002</span></li><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">X11:</span> Key: <span style=" font-style:italic;">0x0026</span>, Modifier: <span style=" font-style:italic;">0x0004</span></li><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">OsX:</span> Key: <span style=" font-style:italic;">0x0000</span>, Modifier: <span style=" font-style:italic;">0x0100</span><span style=" text-decoration: underline;"><br/></span></li></ul></body></html> + <html><head/><body><p>QHotkey allows you to set native shortcuts explicitly. These, of course, only work on the platform they were chosen for. All platform use special constants for their key codes and modifiers, which makes it pretty simple to use them from code. If you want to test them out here, google for the tables.</p><p>In most cases, you will not need to specify native shortcuts directly. However, as explained on previous tabs, some shortcuts may not be creatable from Qt's key (e.g. Numblock numbers). In that case, you can set the directly.</p><p><span style=" text-decoration: underline;">Example: Ctrl+A</span></p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Windows:</span> Key: <span style=" font-style:italic;">0x0041</span>, Modifier: <span style=" font-style:italic;">0x0002</span></li><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">X11:</span> Key: <span style=" font-style:italic;">0x0026</span>, Modifier: <span style=" font-style:italic;">0x0004</span></li><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">OsX:</span> Key: <span style=" font-style:italic;">0x0000</span>, Modifier: <span style=" font-style:italic;">0x0100</span><span style=" text-decoration: underline;"><br/></span></li></ul></body></html> true diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index ce408e6..d3ac1d1 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -13,7 +13,7 @@ #include #include -//compability to pre Qt 5.8 +//compatibility to pre Qt 5.8 #ifndef Q_FALLTHROUGH #define Q_FALLTHROUGH() (void)0 #endif diff --git a/README.md b/README.md index 5e40930..47595e0 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ $ cmake --build build ### qmake -The major version of Qt is chosen by the qmake invokation itself, as the qmake executable is tied to a specific Qt version. The executable name can vary between operating systems. qmake example usage: +The major version of Qt is chosen by the qmake invocation itself, as the qmake executable is tied to a specific Qt version. The executable name can vary between operating systems. qmake example usage: ``` $ cd QHotkey @@ -94,18 +94,18 @@ int main(int argc, char *argv[]) By running the example in `./HotkeyTest` you can test out the QHotkey class. There are 4 sections: - **Playground:** You can enter some sequences here and try it out with different key combinations. - **Testings:** A list of selected hotkeys. Activate it and try out which ones work for you (*Hint:* Depending on OS and keyboard layout, it's very possible that a few don't work). -- **Threading:** Activate the checkbox to move 2 Hotkeys of the playground to seperate threads. It should work without a difference. +- **Threading:** Activate the checkbox to move 2 Hotkeys of the playground to separate threads. It should work without a difference. - **Native Shortcut**: Allows you to try out the direct usage of native shortcuts ### Logging -By default, QHotkey prints some warning messages if something goes wrong (For example, a key that cannot be translated). All messages of QHotkey are grouped into the [QLoggingCategory](https://doc.qt.io/qt-5/qloggingcategory.html) `"QHotkey"`. If you want to simply disable the logging, call the folling function somewhere in your code: +By default, QHotkey prints some warning messages if something goes wrong (For example, a key that cannot be translated). All messages of QHotkey are grouped into the [QLoggingCategory](https://doc.qt.io/qt-5/qloggingcategory.html) `"QHotkey"`. If you want to simply disable the logging, call the following function somewhere in your code: ```cpp QLoggingCategory::setFilterRules(QStringLiteral("QHotkey.warning=false")); ``` -This will turn all warnings of QHotkey of (It only uses warnings for now, thats why this is enough). For more information about all the things you can do with the logging categories, check the Qt-Documentation +This will turn all warnings of QHotkey of (It only uses warnings for now, that's why this is enough). For more information about all the things you can do with the logging categories, check the Qt-Documentation -## Thread saftey -The QHotkey class itself is reentrant - wich means you can create as many instances as required on any thread. This allows you to use the QHotkey on all threads. **But** you should never use the QHotkey instance on a thread that is different from the one the instance belongs to! Internally the system uses a singleton instance that handles the hotkey events and distributes them to the QHotkey instances. This internal class is completley threadsafe. +## Thread safety +The QHotkey class itself is reentrant - which means you can create as many instances as required on any thread. This allows you to use the QHotkey on all threads. **But** you should never use the QHotkey instance on a thread that is different from the one the instance belongs to! Internally the system uses a singleton instance that handles the hotkey events and distributes them to the QHotkey instances. This internal class is completely threadsafe. However, this singleton instance only runs on the main thread. (One reason is that some of the OS-Functions are not thread safe). To make threaded hotkeys possible, the critical functions (registering/unregistering hotkeys and keytranslation) are all run on the mainthread too. The QHotkey instances on other threads use `QMetaObject::invokeMethod` with a `Qt::BlockingQueuedConnection`. diff --git a/doc/qhotkey.dox b/doc/qhotkey.dox index fe184f3..dabde3c 100644 --- a/doc/qhotkey.dox +++ b/doc/qhotkey.dox @@ -38,7 +38,7 @@ In addition to the normal accessors, a modification of the QHotkey::shortcut pro @default{`QKeySequence()` (`Qt::Key_unknown` + `Qt::NoModifier`)} Holds the shortcut this hotkey will be registered on. It can be used as QKeySequence or as a combination of -a Qt::Key and Qt::KeyboardModifiers. All write-accessors specifiy an additional parameter to immediatly register +a Qt::Key and Qt::KeyboardModifiers. All write-accessors specify an additional parameter to immediately register the hotkey. @note Since the operating systems do not support hotkeys that consist of multiple key-combinations in a sequence, @@ -107,7 +107,7 @@ it does. This does not happen if used from the main thread. If the hotkey is still registered on destruction, it will automatically unregister itself. -@warning If using a hotkey on a thread other than the main thread, make shure the QApplication is still running it's eventloop. +@warning If using a hotkey on a thread other than the main thread, make sure the QApplication is still running it's eventloop. Otherwise your application will hang up. @sa QHotkey::registered @@ -144,7 +144,7 @@ from the thread this instance lives on. This method can be used to remap specific hotkey to a different native representation than the one that would be used by default. This can be useful if specific key combinations work fine -on allmost all platforms, but on one you need a different keycode for the same effect. See +on almost all platforms, but on one you need a different keycode for the same effect. See [Issue #15](https://github.com/Skycoder42/QHotkey/issues/15) for an example where this is the case. From 6b1c6f1f4e2a26e346e6a813adba6427f3d2c054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20O=2E=20Cordero=20P=C3=A9rez?= Date: Tue, 21 Jun 2022 15:35:35 -0400 Subject: [PATCH 33/40] Made Windows BYTE typedef uppercase in attempt to get QHotkey to compile with MSVC 2019. --- QHotkey/qhotkey_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QHotkey/qhotkey_win.cpp b/QHotkey/qhotkey_win.cpp index 715b92e..9a88e30 100644 --- a/QHotkey/qhotkey_win.cpp +++ b/QHotkey/qhotkey_win.cpp @@ -235,7 +235,7 @@ quint32 QHotkeyPrivateWin::nativeKeycode(Qt::Key keycode, bool &ok) default: if(keycode <= 0xFFFF) - return (byte)keycode; + return (BYTE)keycode; else { ok = false; return 0; From 94efd5fb61178b10d94b83838740b580ce79cd6c Mon Sep 17 00:00:00 2001 From: "Javier O. Cordero" Date: Thu, 30 Jun 2022 20:16:06 -0400 Subject: [PATCH 34/40] Using static_cast as suggested by Shatur. --- QHotkey/qhotkey_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QHotkey/qhotkey_win.cpp b/QHotkey/qhotkey_win.cpp index 9a88e30..e6bbc36 100644 --- a/QHotkey/qhotkey_win.cpp +++ b/QHotkey/qhotkey_win.cpp @@ -235,7 +235,7 @@ quint32 QHotkeyPrivateWin::nativeKeycode(Qt::Key keycode, bool &ok) default: if(keycode <= 0xFFFF) - return (BYTE)keycode; + return static_cast(keycode); else { ok = false; return 0; From 34777f2e91b72cdc62a415975cc3ec53475ed022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20O=2E=20Cordero=20P=C3=A9rez?= Date: Thu, 7 Jul 2022 09:01:21 -0400 Subject: [PATCH 35/40] CPack instructions to build Debian package Co-authored-by: Hennadii Chernyshchyk --- CMakeLists.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3d1097..d34519e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required(VERSION 3.1) -project(qhotkey VERSION 1.5.0 LANGUAGES CXX) +project(qhotkey + VERSION 1.5.0 + DESCRIPTION "Global hotkey library for Qt software" + HOMEPAGE_URL "https://skycoder42.github.io/QHotkey/" + LANGUAGES CXX) option(QHOTKEY_EXAMPLES "Build examples" OFF) option(QHOTKEY_INSTALL "Enable install rule" ON) @@ -18,6 +22,21 @@ else() find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS Core Gui REQUIRED) endif() +# General settings +set(CPACK_PACKAGE_VENDOR "Skycoder42") +set(CPACK_PACKAGE_CONTACT "Shatur") +set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md") +# CPACK: DEB Specific Settings +set(CPACK_DEBIAN_PACKAGE_NAME "libqhotkey") +set(CPACK_DEBIAN_PACKAGE_SECTION "Libraries") +# Set dependencies +if(QT_DEFAULT_MAJOR_VERSION EQUAL 6) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt6x11extras6 (>= 6.2.0)") +else() + set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5x11extras5 (>= 5.15.2)") +endif() +include(CPack) + add_library(qhotkey QHotkey/qhotkey.cpp) add_library(QHotkey::QHotkey ALIAS qhotkey) target_link_libraries(qhotkey PUBLIC Qt${QT_DEFAULT_MAJOR_VERSION}::Core Qt${QT_DEFAULT_MAJOR_VERSION}::Gui) From cd72a013275803fce33e028fc8b05ae32248da1f Mon Sep 17 00:00:00 2001 From: FredBill1 <36622430+FredBill1@users.noreply.github.com> Date: Tue, 18 Apr 2023 17:14:52 +0800 Subject: [PATCH 36/40] Properly emit `released` signal when pressing multiple hotkeys at the same time on Windows (#86) Co-authored-by: Hennadii Chernyshchyk --- QHotkey/qhotkey_win.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/QHotkey/qhotkey_win.cpp b/QHotkey/qhotkey_win.cpp index e6bbc36..949d87a 100644 --- a/QHotkey/qhotkey_win.cpp +++ b/QHotkey/qhotkey_win.cpp @@ -1,7 +1,9 @@ #include "qhotkey.h" #include "qhotkey_p.h" #include +#include #include +#include #include #define HKEY_ID(nativeShortcut) (((nativeShortcut.key ^ (nativeShortcut.modifier << 8)) & 0x0FFF) | 0x7000) @@ -28,7 +30,7 @@ class QHotkeyPrivateWin : public QHotkeyPrivate private: static QString formatWinError(DWORD winError); QTimer pollTimer; - QHotkey::NativeShortcut polledShortcut; + QList polledShortcuts; }; NATIVE_INSTANCE(QHotkeyPrivateWin) @@ -51,8 +53,9 @@ bool QHotkeyPrivateWin::nativeEventFilter(const QByteArray &eventType, void *mes if(msg->message == WM_HOTKEY) { QHotkey::NativeShortcut shortcut = {HIWORD(msg->lParam), LOWORD(msg->lParam)}; this->activateShortcut(shortcut); - this->polledShortcut = shortcut; - this->pollTimer.start(); + if (this->polledShortcuts.empty()) + this->pollTimer.start(); + this->polledShortcuts.append(shortcut); } return false; @@ -60,11 +63,15 @@ bool QHotkeyPrivateWin::nativeEventFilter(const QByteArray &eventType, void *mes void QHotkeyPrivateWin::pollForHotkeyRelease() { - bool pressed = (GetAsyncKeyState(this->polledShortcut.key) & (1 << 15)) != 0; - if(!pressed) { + auto it = std::remove_if(this->polledShortcuts.begin(), this->polledShortcuts.end(), [this](const QHotkey::NativeShortcut &shortcut) { + bool pressed = (GetAsyncKeyState(shortcut.key) & (1 << 15)) != 0; + if (!pressed) + this->releaseShortcut(shortcut); + return !pressed; + }); + this->polledShortcuts.erase(it, this->polledShortcuts.end()); + if (this->polledShortcuts.empty()) this->pollTimer.stop(); - this->releaseShortcut(this->polledShortcut); - } } quint32 QHotkeyPrivateWin::nativeKeycode(Qt::Key keycode, bool &ok) From b519155479a1a0af816f4b5f4b00d49a165cd8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20O=2E=20Cordero=20P=C3=A9rez?= Date: Mon, 20 May 2024 09:09:14 -0400 Subject: [PATCH 37/40] Bump Qt and CI script versions, fix macOS support, and drop support for qmake (#98) --- .github/workflows/build.yml | 25 +++++-------------------- HotkeyTest/HotkeyTest.pro | 21 --------------------- QHotkey.pro | 10 ---------- QHotkey/QHotkey.pro | 16 ---------------- QHotkey/qhotkey.pri | 1 - README.md | 13 +------------ qhotkey.prc | 15 --------------- qhotkey.pri | 17 ----------------- 8 files changed, 6 insertions(+), 112 deletions(-) delete mode 100644 HotkeyTest/HotkeyTest.pro delete mode 100644 QHotkey.pro delete mode 100644 QHotkey/QHotkey.pro delete mode 100644 QHotkey/qhotkey.pri delete mode 100644 qhotkey.prc delete mode 100644 qhotkey.pri diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7affb86..89d7c90 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,10 +14,10 @@ jobs: build: strategy: matrix: - qt_version: [5.12.11, 5.15.2, 6.2.0] + qt_version: [5.12.12, 5.15.2, 6.2.2] platform: [ubuntu-20.04, windows-latest, macos-latest] include: - - qt_version: 6.2.0 + - qt_version: 6.2.2 additional_arguments: -D QT_DEFAULT_MAJOR_VERSION=6 - platform: ubuntu-20.04 make: make @@ -41,31 +41,16 @@ jobs: uses: actions/checkout@v2.3.4 - name: Install Qt - uses: jurplel/install-qt-action@v2.14.0 + uses: jurplel/install-qt-action@v3.3.0 with: version: ${{ matrix.qt_version }} - name: Build with CMake as static run: | - cmake . -D QHOTKEY_EXAMPLES=ON ${{ matrix.additional_arguments }} + cmake . -D QHOTKEY_EXAMPLES=ON -D CMAKE_OSX_ARCHITECTURES="x86_64" ${{ matrix.additional_arguments }} cmake --build . - name: Build with CMake as shared run: | - cmake . -D BUILD_SHARED_LIBS=ON -D QHOTKEY_EXAMPLES=ON ${{ matrix.additional_arguments }} + cmake . -D BUILD_SHARED_LIBS=ON -D QHOTKEY_EXAMPLES=ON -D CMAKE_OSX_ARCHITECTURES="x86_64" ${{ matrix.additional_arguments }} cmake --build . - - - name: Setup MSVC environment for QMake - uses: ilammy/msvc-dev-cmd@v1 - - - name: Build with QMake as static - working-directory: HotkeyTest - run: | - qmake - ${{ matrix.make }} - - - name: Build with QMake as shared - working-directory: HotkeyTest - run: | - qmake "DEFINES+=QHOTKEY_SHARED QHOTKEY_LIBRARY" - ${{ matrix.make }} diff --git a/HotkeyTest/HotkeyTest.pro b/HotkeyTest/HotkeyTest.pro deleted file mode 100644 index a43f662..0000000 --- a/HotkeyTest/HotkeyTest.pro +++ /dev/null @@ -1,21 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-02-05T22:01:03 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = HotkeyTest -TEMPLATE = app - -include(../qhotkey.pri) - -SOURCES += main.cpp\ - hottestwidget.cpp - -HEADERS += hottestwidget.h - -FORMS += hottestwidget.ui diff --git a/QHotkey.pro b/QHotkey.pro deleted file mode 100644 index 5fa7cbe..0000000 --- a/QHotkey.pro +++ /dev/null @@ -1,10 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += \ - HotkeyTest \ - QHotkey - -DISTFILES += README.md \ - LICENSE \ - doc/qhotkey.doxy \ - doc/qhotkey.dox diff --git a/QHotkey/QHotkey.pro b/QHotkey/QHotkey.pro deleted file mode 100644 index 3a79376..0000000 --- a/QHotkey/QHotkey.pro +++ /dev/null @@ -1,16 +0,0 @@ -TEMPLATE = lib -win32: CONFIG += dll - -TARGET = QHotkey -VERSION = 1.5.0 - -include(../qhotkey.pri) - -DEFINES += QHOTKEY_SHARED QHOTKEY_LIBRARY - -# use INSTALL_ROOT to modify the install location -headers.files = $$PUBLIC_HEADERS -headers.path = $$[QT_INSTALL_HEADERS] -target.path = $$[QT_INSTALL_LIBS] -INSTALLS += target headers - diff --git a/QHotkey/qhotkey.pri b/QHotkey/qhotkey.pri deleted file mode 100644 index a7c9725..0000000 --- a/QHotkey/qhotkey.pri +++ /dev/null @@ -1 +0,0 @@ -message(The pri file has been moved one directory up! use that one instead) diff --git a/README.md b/README.md index 47595e0..4058dfd 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The QHotkey is a class that can be used to create hotkeys/global shortcuts, aka ## Building -QHotkey supports both Qt6 and Qt5. When using Qt6, version 6.2.0 or later required. It can be built by either the CMake or qmake building systems. +QHotkey supports both Qt6 and Qt5. When using Qt6, version 6.2.0 or later required. It can be built using the CMake building system. ### CMake @@ -29,17 +29,6 @@ $ cmake --build build # cmake --install build ``` -### qmake - -The major version of Qt is chosen by the qmake invocation itself, as the qmake executable is tied to a specific Qt version. The executable name can vary between operating systems. qmake example usage: - -``` -$ cd QHotkey -$ qmake -$ make -# make install -``` - ## Installation The package is providet as qpm package, [`de.skycoder42.qhotkey`](https://www.qpm.io/packages/de.skycoder42.qhotkey/index.html). You can install it either via qpmx (preferred) or directly via qpm. diff --git a/qhotkey.prc b/qhotkey.prc deleted file mode 100644 index d8e8ac0..0000000 --- a/qhotkey.prc +++ /dev/null @@ -1,15 +0,0 @@ -mac: LIBS += -framework Carbon -else:win32: LIBS += -luser32 -else:unix { - equals(QT_MAJOR_VERSION, 6) { - lessThan(QT_VERSION, 6.2.0) { - error("Qt 6.2.0 or greater is required when using Qt6") - } - } - else { - lessThan(QT_MAJOR_VERSION, 6) { - QT += x11extras - } - } - LIBS += -lX11 -} diff --git a/qhotkey.pri b/qhotkey.pri deleted file mode 100644 index 1dc2ae9..0000000 --- a/qhotkey.pri +++ /dev/null @@ -1,17 +0,0 @@ -CONFIG += C++11 - -PUBLIC_HEADERS += $$PWD/QHotkey/qhotkey.h \ - $$PWD/QHotkey/QHotkey - -HEADERS += $$PUBLIC_HEADERS \ - $$PWD/QHotkey/qhotkey_p.h - -SOURCES += $$PWD/QHotkey/qhotkey.cpp - -mac: SOURCES += $$PWD/QHotkey/qhotkey_mac.cpp -else:win32: SOURCES += $$PWD/QHotkey/qhotkey_win.cpp -else:unix: SOURCES += $$PWD/QHotkey/qhotkey_x11.cpp - -INCLUDEPATH += $$PWD/QHotkey - -include($$PWD/qhotkey.prc) From bb630252684d3556b79ac7a521616692f348fcf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20O=2E=20Cordero=20P=C3=A9rez?= Date: Mon, 20 May 2024 15:13:12 -0400 Subject: [PATCH 38/40] Fix: Prevent crash on Wayland when using Qt 6 (#97) --- QHotkey/qhotkey_x11.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/QHotkey/qhotkey_x11.cpp b/QHotkey/qhotkey_x11.cpp index d3ac1d1..d9d73f7 100644 --- a/QHotkey/qhotkey_x11.cpp +++ b/QHotkey/qhotkey_x11.cpp @@ -132,13 +132,16 @@ quint32 QHotkeyPrivateX11::nativeKeycode(Qt::Key keycode, bool &ok) #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) const QNativeInterface::QX11Application *x11Interface = qGuiApp->nativeInterface(); - Display *display = x11Interface->display(); #else const bool x11Interface = QX11Info::isPlatformX11(); - Display *display = QX11Info::display(); #endif if(x11Interface) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) + Display *display = x11Interface->display(); +#else + Display *display = QX11Info::display(); +#endif auto res = XKeysymToKeycode(display, keysym); if(res != 0) ok = true; From 8f90bdf90c0f98f639bcff6c49d8da80ad4b31ea Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Sun, 6 Jul 2025 07:48:05 -0300 Subject: [PATCH 39/40] Add compatibility with CMake 4.0 (#103) Starting at CMake 4.0, the minimum required policy version is 3.5.0[1], either specified by 'cmake_minimum_required()' or by 'cmake_policy()'. This also applies to individual policies when they are set, which must match 3.5.0 or later policies. [1] https://cmake.org/cmake/help/v4.0/command/cmake_minimum_required.html --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d34519e..727218e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.5) project(qhotkey VERSION 1.5.0 From 6c0e98492c59206139f8490706aadeb8ed033057 Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Sun, 6 Jul 2025 07:48:54 -0300 Subject: [PATCH 40/40] Add compatibility with QT_NO_KEYWORDS macro (#104) The Qt documentation recommends[1] not using Qt keywords in the public API of Qt libraries, specially the 'signals' and 'slots' Qt keywords. Without this, client applications that are compiled with the 'QT_NO_KEYWORDS'[2] macro (or that are compiled in conjunction with other libraries that also defines the same Qt keywords) will fail to build. The 'QT_NO_SIGNALS_SLOTS_KEYWORDS'[1] macro assures that the library is not using 'signals' and 'slots' Qt keywords, since it will fail to build when they are used. Useful for code sanity and for avoiding future pull requests that may try to use these Qt keywords. [1] https://doc.qt.io/qt-6/signalsandslots.html#signals-and-slots-in-qt-based-libraries [2] https://doc.qt.io/qt-6/qtglobal.html#QT_NO_KEYWORDS --- CMakeLists.txt | 2 ++ QHotkey/qhotkey.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 727218e..32cda4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,8 @@ add_library(qhotkey QHotkey/qhotkey.cpp) add_library(QHotkey::QHotkey ALIAS qhotkey) target_link_libraries(qhotkey PUBLIC Qt${QT_DEFAULT_MAJOR_VERSION}::Core Qt${QT_DEFAULT_MAJOR_VERSION}::Gui) +target_compile_definitions(qhotkey PRIVATE QT_NO_SIGNALS_SLOTS_KEYWORDS) + if(BUILD_SHARED_LIBS) target_compile_definitions(qhotkey PRIVATE QHOTKEY_LIBRARY) target_compile_definitions(qhotkey PUBLIC QHOTKEY_SHARED) diff --git a/QHotkey/qhotkey.h b/QHotkey/qhotkey.h index 3697c8e..12f5fec 100644 --- a/QHotkey/qhotkey.h +++ b/QHotkey/qhotkey.h @@ -88,7 +88,7 @@ class QHOTKEY_EXPORT QHotkey : public QObject //! Get the current native shortcut NativeShortcut currentNativeShortcut() const; -public slots: +public Q_SLOTS: //! @writeAcFn{QHotkey::registered} bool setRegistered(bool registered); @@ -102,7 +102,7 @@ public slots: //! Set this hotkey to a native shortcut bool setNativeShortcut(QHotkey::NativeShortcut nativeShortcut, bool autoRegister = false); -signals: +Q_SIGNALS: //! Will be emitted if the shortcut is pressed void activated(QPrivateSignal); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy