diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2013-11-17 19:27:19 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2013-11-17 19:27:19 +0100 |
commit | 8373c6cd439e4cf393d03f603e8e914cc7dfabf6 (patch) | |
tree | a221260630aeb5babcb57db2d1185f46a0c61fd4 | |
parent | 3dbd4228b5823b72dd095ceaeada878a2b9a5dac (diff) |
Try to fix mac keybindings
-rw-r--r-- | qxt-mini/plat/qxtglobalshortcut_mac.cpp | 456 | ||||
-rw-r--r-- | qxt-mini/qxtglobalshortcut_p.h | 185 |
2 files changed, 327 insertions, 314 deletions
diff --git a/qxt-mini/plat/qxtglobalshortcut_mac.cpp b/qxt-mini/plat/qxtglobalshortcut_mac.cpp index 58b9a904..be2e632d 100644 --- a/qxt-mini/plat/qxtglobalshortcut_mac.cpp +++ b/qxt-mini/plat/qxtglobalshortcut_mac.cpp @@ -1,4 +1,4 @@ -#include <Carbon/Carbon.h>
+#include <Carbon/Carbon.h> /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. @@ -29,230 +29,230 @@ ** <http://libqxt.org> <foundation@libqxt.org> *****************************************************************************/ -#include "qxtglobalshortcut_p.h"
-#include <QMap>
-#include <QHash>
-#include <QtDebug>
-#include <QApplication>
-
-typedef QPair<uint, uint> Identifier;
-static QMap<quint32, EventHotKeyRef> keyRefs;
-static QHash<Identifier, quint32> keyIDs;
-static quint32 hotKeySerial = 0;
-static bool qxt_mac_handler_installed = false;
-
-OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data)
-{
- Q_UNUSED(nextHandler);
- Q_UNUSED(data);
- if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed)
- {
- EventHotKeyID keyID;
- GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
- Identifier id = keyIDs.key(keyID.id);
- QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first);
- }
- return noErr;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
-{
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= shiftKey;
- if (modifiers & Qt::ControlModifier)
- native |= cmdKey;
- if (modifiers & Qt::AltModifier)
- native |= optionKey;
- if (modifiers & Qt::MetaModifier)
- native |= controlKey;
- if (modifiers & Qt::KeypadModifier)
- native |= kEventKeyModifierNumLockMask;
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
-{
- UTF16Char ch;
- // Constants found in NSEvent.h from AppKit.framework
- switch (key)
- {
- case Qt::Key_Return:
- return kVK_Return;
- case Qt::Key_Enter:
- return kVK_ANSI_KeypadEnter;
- case Qt::Key_Tab:
- return kVK_Tab;
- case Qt::Key_Space:
- return kVK_Space;
- case Qt::Key_Backspace:
- return kVK_Delete;
- case Qt::Key_Control:
- return kVK_Command;
- case Qt::Key_Shift:
- return kVK_Shift;
- case Qt::Key_CapsLock:
- return kVK_CapsLock;
- case Qt::Key_Option:
- return kVK_Option;
- case Qt::Key_Meta:
- return kVK_Control;
- case Qt::Key_F17:
- return kVK_F17;
- case Qt::Key_VolumeUp:
- return kVK_VolumeUp;
- case Qt::Key_VolumeDown:
- return kVK_VolumeDown;
- case Qt::Key_F18:
- return kVK_F18;
- case Qt::Key_F19:
- return kVK_F19;
- case Qt::Key_F20:
- return kVK_F20;
- case Qt::Key_F5:
- return kVK_F5;
- case Qt::Key_F6:
- return kVK_F6;
- case Qt::Key_F7:
- return kVK_F7;
- case Qt::Key_F3:
- return kVK_F3;
- case Qt::Key_F8:
- return kVK_F8;
- case Qt::Key_F9:
- return kVK_F9;
- case Qt::Key_F11:
- return kVK_F11;
- case Qt::Key_F13:
- return kVK_F13;
- case Qt::Key_F16:
- return kVK_F16;
- case Qt::Key_F14:
- return kVK_F14;
- case Qt::Key_F10:
- return kVK_F10;
- case Qt::Key_F12:
- return kVK_F12;
- case Qt::Key_F15:
- return kVK_F15;
- case Qt::Key_Help:
- return kVK_Help;
- case Qt::Key_Home:
- return kVK_Home;
- case Qt::Key_PageUp:
- return kVK_PageUp;
- case Qt::Key_Delete:
- return kVK_ForwardDelete;
- case Qt::Key_F4:
- return kVK_F4;
- case Qt::Key_End:
- return kVK_End;
- case Qt::Key_F2:
- return kVK_F2;
- case Qt::Key_PageDown:
- return kVK_PageDown;
- case Qt::Key_F1:
- return kVK_F1;
- case Qt::Key_Left:
- return kVK_LeftArrow;
- case Qt::Key_Right:
- return kVK_RightArrow;
- case Qt::Key_Down:
- return kVK_DownArrow;
- case Qt::Key_Up:
- return kVK_UpArrow;
- default:
- ;
- }
-
- if (key == Qt::Key_Escape) ch = 27;
- else if (key == Qt::Key_Return) ch = 13;
- else if (key == Qt::Key_Enter) ch = 3;
- else if (key == Qt::Key_Tab) ch = 9;
- else ch = key;
-
- CFDataRef currentLayoutData;
- TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
-
- if (currentKeyboard == NULL)
- return 0;
-
- currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
- CFRelease(currentKeyboard);
- if (currentLayoutData == NULL)
- return 0;
-
- UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData);
- UCKeyboardTypeHeader* table = header->keyboardTypeList;
-
- uint8_t *data = (uint8_t*)header;
- // God, would a little documentation for this shit kill you...
- for (quint32 i=0; i < header->keyboardTypeCount; i++)
- {
- UCKeyStateRecordsIndex* stateRec = 0;
- if (table[i].keyStateRecordsIndexOffset != 0)
- {
- stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset);
- if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0;
- }
-
- UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset);
- if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue;
-
- for (quint32 j=0; j < charTable->keyToCharTableCount; j++)
- {
- UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]);
- for (quint32 k=0; k < charTable->keyToCharTableSize; k++)
- {
- if (keyToChar[k] & kUCKeyOutputTestForIndexMask)
- {
- long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
- if (stateRec && idx < stateRec->keyStateRecordCount)
- {
- UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]);
- if (rec->stateZeroCharData == ch) return k;
- }
- }
- else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE)
- {
- if (keyToChar[k] == ch) return k;
- }
- } // for k
- } // for j
- } // for i
- return 0;
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- if (!qxt_mac_handler_installed)
- {
- EventTypeSpec t;
- t.eventClass = kEventClassKeyboard;
- t.eventKind = kEventHotKeyPressed;
- InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL);
- }
-
- EventHotKeyID keyID;
- keyID.signature = 'cute';
- keyID.id = ++hotKeySerial;
-
- EventHotKeyRef ref = 0;
- bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref);
- if (rv)
- {
- keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
- keyRefs.insert(keyID.id, ref);
- }
- return rv;
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- Identifier id(nativeMods, nativeKey);
- if (!keyIDs.contains(id)) return false;
-
- EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
- keyIDs.remove(id);
- return !UnregisterEventHotKey(ref);
-}
+#include "qxtglobalshortcut_p.h" +#include <QMap> +#include <QHash> +#include <QtDebug> +#include <QApplication> + +typedef QPair<uint, uint> Identifier; +static QMap<quint32, EventHotKeyRef> keyRefs; +static QHash<Identifier, quint32> keyIDs; +static quint32 hotKeySerial = 0; +static bool qxt_mac_handler_installed = false; + +OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data) +{ + Q_UNUSED(nextHandler); + Q_UNUSED(data); + if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed) + { + EventHotKeyID keyID; + GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID); + Identifier id = keyIDs.key(keyID.id); + QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first); + } + return noErr; +} + +quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) +{ + quint32 native = 0; + if (modifiers & Qt::ShiftModifier) + native |= shiftKey; + if (modifiers & Qt::ControlModifier) + native |= cmdKey; + if (modifiers & Qt::AltModifier) + native |= optionKey; + if (modifiers & Qt::MetaModifier) + native |= controlKey; + if (modifiers & Qt::KeypadModifier) + native |= kEventKeyModifierNumLockMask; + return native; +} + +quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) +{ + UTF16Char ch; + // Constants found in NSEvent.h from AppKit.framework + switch (key) + { + case Qt::Key_Return: + return kVK_Return; + case Qt::Key_Enter: + return kVK_ANSI_KeypadEnter; + case Qt::Key_Tab: + return kVK_Tab; + case Qt::Key_Space: + return kVK_Space; + case Qt::Key_Backspace: + return kVK_Delete; + case Qt::Key_Control: + return kVK_Command; + case Qt::Key_Shift: + return kVK_Shift; + case Qt::Key_CapsLock: + return kVK_CapsLock; + case Qt::Key_Option: + return kVK_Option; + case Qt::Key_Meta: + return kVK_Control; + case Qt::Key_F17: + return kVK_F17; + case Qt::Key_VolumeUp: + return kVK_VolumeUp; + case Qt::Key_VolumeDown: + return kVK_VolumeDown; + case Qt::Key_F18: + return kVK_F18; + case Qt::Key_F19: + return kVK_F19; + case Qt::Key_F20: + return kVK_F20; + case Qt::Key_F5: + return kVK_F5; + case Qt::Key_F6: + return kVK_F6; + case Qt::Key_F7: + return kVK_F7; + case Qt::Key_F3: + return kVK_F3; + case Qt::Key_F8: + return kVK_F8; + case Qt::Key_F9: + return kVK_F9; + case Qt::Key_F11: + return kVK_F11; + case Qt::Key_F13: + return kVK_F13; + case Qt::Key_F16: + return kVK_F16; + case Qt::Key_F14: + return kVK_F14; + case Qt::Key_F10: + return kVK_F10; + case Qt::Key_F12: + return kVK_F12; + case Qt::Key_F15: + return kVK_F15; + case Qt::Key_Help: + return kVK_Help; + case Qt::Key_Home: + return kVK_Home; + case Qt::Key_PageUp: + return kVK_PageUp; + case Qt::Key_Delete: + return kVK_ForwardDelete; + case Qt::Key_F4: + return kVK_F4; + case Qt::Key_End: + return kVK_End; + case Qt::Key_F2: + return kVK_F2; + case Qt::Key_PageDown: + return kVK_PageDown; + case Qt::Key_F1: + return kVK_F1; + case Qt::Key_Left: + return kVK_LeftArrow; + case Qt::Key_Right: + return kVK_RightArrow; + case Qt::Key_Down: + return kVK_DownArrow; + case Qt::Key_Up: + return kVK_UpArrow; + default: + ; + } + + if (key == Qt::Key_Escape) ch = 27; + else if (key == Qt::Key_Return) ch = 13; + else if (key == Qt::Key_Enter) ch = 3; + else if (key == Qt::Key_Tab) ch = 9; + else ch = key; + + CFDataRef currentLayoutData; + TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + + if (currentKeyboard == NULL) + return 0; + + currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); + CFRelease(currentKeyboard); + if (currentLayoutData == NULL) + return 0; + + UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData); + UCKeyboardTypeHeader* table = header->keyboardTypeList; + + uint8_t *data = (uint8_t*)header; + // God, would a little documentation for this shit kill you... + for (quint32 i=0; i < header->keyboardTypeCount; i++) + { + UCKeyStateRecordsIndex* stateRec = 0; + if (table[i].keyStateRecordsIndexOffset != 0) + { + stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset); + if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0; + } + + UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset); + if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue; + + for (quint32 j=0; j < charTable->keyToCharTableCount; j++) + { + UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]); + for (quint32 k=0; k < charTable->keyToCharTableSize; k++) + { + if (keyToChar[k] & kUCKeyOutputTestForIndexMask) + { + long idx = keyToChar[k] & kUCKeyOutputGetIndexMask; + if (stateRec && idx < stateRec->keyStateRecordCount) + { + UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]); + if (rec->stateZeroCharData == ch) return k; + } + } + else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE) + { + if (keyToChar[k] == ch) return k; + } + } // for k + } // for j + } // for i + return 0; +} + +bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) +{ + if (!qxt_mac_handler_installed) + { + EventTypeSpec t; + t.eventClass = kEventClassKeyboard; + t.eventKind = kEventHotKeyPressed; + InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL); + } + + EventHotKeyID keyID; + keyID.signature = 'cute'; + keyID.id = ++hotKeySerial; + + EventHotKeyRef ref = 0; + bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref); + if (rv) + { + keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id); + keyRefs.insert(keyID.id, ref); + } + return rv; +} + +bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) +{ + Identifier id(nativeMods, nativeKey); + if (!keyIDs.contains(id)) return false; + + EventHotKeyRef ref = keyRefs.take(keyIDs[id]); + keyIDs.remove(id); + return !UnregisterEventHotKey(ref); +} diff --git a/qxt-mini/qxtglobalshortcut_p.h b/qxt-mini/qxtglobalshortcut_p.h index 0d88b354..e3f3ddd3 100644 --- a/qxt-mini/qxtglobalshortcut_p.h +++ b/qxt-mini/qxtglobalshortcut_p.h @@ -1,86 +1,99 @@ -#ifndef QXTGLOBALSHORTCUT_P_H
-/****************************************************************************
-** Copyright (c) 2006 - 2011, the LibQxt project.
-** See the Qxt AUTHORS file for a list of authors and copyright holders.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of the LibQxt project nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-** <http://libqxt.org> <foundation@libqxt.org>
-*****************************************************************************/
-
-#define QXTGLOBALSHORTCUT_P_H
-
-#include "qxtglobalshortcut.h"
-#include <QAbstractEventDispatcher>
-#include <QKeySequence>
-#include <QHash>
-
-#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
-#include <QAbstractNativeEventFilter>
-#endif
-
-
-class QxtGlobalShortcutPrivate : public QxtPrivate<QxtGlobalShortcut>
-#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
- ,public QAbstractNativeEventFilter
-#endif
-{
-public:
- QXT_DECLARE_PUBLIC(QxtGlobalShortcut)
- QxtGlobalShortcutPrivate();
- ~QxtGlobalShortcutPrivate();
-
- bool enabled;
- Qt::Key key;
- Qt::KeyboardModifiers mods;
-
- bool setShortcut(const QKeySequence& shortcut);
- bool unsetShortcut();
-
- static bool error;
-#ifndef Q_OS_DARWIN
- static int ref;
-# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- static QAbstractEventDispatcher::EventFilter prevEventFilter;
- static bool eventFilter(void* message);
-# else
- virtual bool nativeEventFilter(const QByteArray & eventType, void * message, long * result);
-# endif // QT_VERSION < QT_VERSION_CHECK(5,0,0)
-# else
- virtual bool nativeEventFilter(const QByteArray & eventType, void * message, long * result) {}
-#endif // Q_WS_MAC
-
- static void activateShortcut(quint32 nativeKey, quint32 nativeMods);
-
-private:
- static quint32 nativeKeycode(Qt::Key keycode);
- static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers);
-
- static bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
- static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
-
- static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts;
-};
-
-#endif // QXTGLOBALSHORTCUT_P_H
+#ifndef QXTGLOBALSHORTCUT_P_H +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** <http://libqxt.org> <foundation@libqxt.org> +*****************************************************************************/ + +#define QXTGLOBALSHORTCUT_P_H + +#include "qxtglobalshortcut.h" +#include <QAbstractEventDispatcher> +#include <QKeySequence> +#include <QHash> + +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +#include <QAbstractNativeEventFilter> +#endif + +#ifdef Q_OS_DARWIN +# include <Cocoa/Cocoa.h> +#endif + +class QxtGlobalShortcutPrivate : public QxtPrivate<QxtGlobalShortcut> +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + ,public QAbstractNativeEventFilter +#endif +{ +public: + QXT_DECLARE_PUBLIC(QxtGlobalShortcut) + QxtGlobalShortcutPrivate(); + ~QxtGlobalShortcutPrivate(); + + bool enabled; + Qt::Key key; + Qt::KeyboardModifiers mods; + + bool setShortcut(const QKeySequence& shortcut); + bool unsetShortcut(); + + static bool error; +#ifndef Q_OS_DARWIN + static int ref; +# if QT_VERSION < QT_VERSION_CHECK(5,0,0) + static QAbstractEventDispatcher::EventFilter prevEventFilter; + static bool eventFilter(void* message); +# else + virtual bool nativeEventFilter(const QByteArray & eventType, void * message, long * result); +# endif // QT_VERSION < QT_VERSION_CHECK(5,0,0) +# else + virtual bool nativeEventFilter(const QByteArray & eventType, void * message, long * result) { + EventRef Event = reinterpret_cast<EventRef>(message); + UInt32 EventClass = GetEventClass (Event); + UInt32 EventKind = GetEventKind (Event); + if (kEventClassKeyboard && EventKind == kEventRawKeyDown) + { + UInt32 keyPressed; + GetEventParameter(Event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyPressed); + return keyPressed == nativeKeycode(key); + } + } +#endif // Q_WS_MAC + + static void activateShortcut(quint32 nativeKey, quint32 nativeMods); + +private: + static quint32 nativeKeycode(Qt::Key keycode); + static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers); + + static bool registerShortcut(quint32 nativeKey, quint32 nativeMods); + static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods); + + static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts; +}; + +#endif // QXTGLOBALSHORTCUT_P_H |