1 #include <Carbon/Carbon.h>
4 #include <QApplication>
7 static QHash<Identifier, EventHotKeyRef>
keyRefs;
13 Q_UNUSED(nextHandler);
15 #if !TTK_QT_VERSION_CHECK(5,0,0)
16 QAbstractEventDispatcher::instance()->filterEvent((
void*)event);
18 QAbstractEventDispatcher::instance()->filterNativeEvent({}, (
void*)event,
nullptr);
23 #if !TTK_QT_VERSION_CHECK(5,0,0)
26 bool QGlobalShortcutPrivate::nativeEventFilter(
const QByteArray &,
void *message,
qint *)
29 EventRef
event = (EventRef) message;
30 if(GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed)
33 GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID,
nullptr,
sizeof(keyID),
nullptr, &keyID);
34 activateShortcut(keyID.signature, keyID.id);
42 if(modifiers & Qt::ShiftModifier)
44 if(modifiers & Qt::ControlModifier)
46 if(modifiers & Qt::AltModifier)
48 if(modifiers & Qt::MetaModifier)
50 if(modifiers & Qt::KeypadModifier)
51 native |= kEventKeyModifierNumLockMask;
58 if(key == Qt::Key_Return)
return kVK_Return;
59 else if(key == Qt::Key_Enter)
return kVK_ANSI_KeypadEnter;
60 else if(key == Qt::Key_Tab)
return kVK_Tab;
61 else if(key == Qt::Key_Space)
return kVK_Space;
62 else if(key == Qt::Key_Backspace)
return kVK_Delete;
63 else if(key == Qt::Key_Escape)
return kVK_Escape;
64 else if(key == Qt::Key_CapsLock)
return kVK_CapsLock;
65 else if(key == Qt::Key_Option)
return kVK_Option;
66 else if(key == Qt::Key_F17)
return kVK_F17;
67 else if(key == Qt::Key_VolumeUp)
return kVK_VolumeUp;
68 else if(key == Qt::Key_VolumeDown)
return kVK_VolumeDown;
69 else if(key == Qt::Key_F18)
return kVK_F18;
70 else if(key == Qt::Key_F19)
return kVK_F19;
71 else if(key == Qt::Key_F20)
return kVK_F20;
72 else if(key == Qt::Key_F5)
return kVK_F5;
73 else if(key == Qt::Key_F6)
return kVK_F6;
74 else if(key == Qt::Key_F7)
return kVK_F7;
75 else if(key == Qt::Key_F3)
return kVK_F3;
76 else if(key == Qt::Key_F8)
return kVK_F8;
77 else if(key == Qt::Key_F9)
return kVK_F9;
78 else if(key == Qt::Key_F11)
return kVK_F11;
79 else if(key == Qt::Key_F13)
return kVK_F13;
80 else if(key == Qt::Key_F16)
return kVK_F16;
81 else if(key == Qt::Key_F14)
return kVK_F14;
82 else if(key == Qt::Key_F10)
return kVK_F10;
83 else if(key == Qt::Key_F12)
return kVK_F12;
84 else if(key == Qt::Key_F15)
return kVK_F15;
85 else if(key == Qt::Key_Help)
return kVK_Help;
86 else if(key == Qt::Key_Home)
return kVK_Home;
87 else if(key == Qt::Key_PageUp)
return kVK_PageUp;
88 else if(key == Qt::Key_Delete)
return kVK_ForwardDelete;
89 else if(key == Qt::Key_F4)
return kVK_F4;
90 else if(key == Qt::Key_End)
return kVK_End;
91 else if(key == Qt::Key_F2)
return kVK_F2;
92 else if(key == Qt::Key_PageDown)
return kVK_PageDown;
93 else if(key == Qt::Key_F1)
return kVK_F1;
94 else if(key == Qt::Key_Left)
return kVK_LeftArrow;
95 else if(key == Qt::Key_Right)
return kVK_RightArrow;
96 else if(key == Qt::Key_Down)
return kVK_DownArrow;
97 else if(key == Qt::Key_Up)
return kVK_UpArrow;
99 CFDataRef currentLayoutData;
100 TISInputSourceRef currentKeyboard = TISCopyCurrentASCIICapableKeyboardLayoutInputSource();
102 if(currentKeyboard ==
nullptr)
105 currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
106 CFRelease(currentKeyboard);
108 if(currentLayoutData ==
nullptr)
111 UCKeyboardLayout *header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData);
112 UCKeyboardTypeHeader *table = header->keyboardTypeList;
115 uint8_t *data = (uint8_t*)header;
116 for(quint32 i = 0; i < header->keyboardTypeCount; ++i)
118 UCKeyStateRecordsIndex *stateRec = 0;
119 if(table[i].keyStateRecordsIndexOffset != 0)
121 stateRec =
TTKReinterpretCast(UCKeyStateRecordsIndex*, data + table[i].keyStateRecordsIndexOffset);
122 if(stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat)
128 UCKeyToCharTableIndex *charTable =
TTKReinterpretCast(UCKeyToCharTableIndex*, data + table[i].keyToCharTableIndexOffset);
129 if(charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat)
134 for(quint32 j = 0; j < charTable->keyToCharTableCount; ++j)
136 UCKeyOutput *keyToChar =
TTKReinterpretCast(UCKeyOutput*, data + charTable->keyToCharTableOffsets[j]);
137 for(quint32 k = 0; k < charTable->keyToCharTableSize; ++k)
139 if(keyToChar[k] & kUCKeyOutputTestForIndexMask)
141 long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
142 if(stateRec && idx < stateRec->keyStateRecordCount)
144 UCKeyStateRecord *rec =
TTKReinterpretCast(UCKeyStateRecord*, data + stateRec->keyStateRecordOffsets[idx]);
145 if(rec->stateZeroCharData == ch)
151 else if(!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE)
153 if(keyToChar[k] == ch)
170 t.eventClass = kEventClassKeyboard;
171 t.eventKind = kEventHotKeyPressed;
176 keyID.signature = nativeKey;
177 keyID.id = nativeMods;
179 EventHotKeyRef ref = 0;
180 const bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref);
196 return !UnregisterEventHotKey(
keyRefs.take(
id));
static quint32 nativeKeycode(Qt::Key keycode)
static QString message(const TTK::Attribute attr)
static bool q_mac_handler_installed
QPair< quint32, quint32 > Identifier
static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers)
static constexpr wchar_t key[]
static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
static bool eventFilter(void *message)
static bool registerShortcut(quint32 nativeKey, quint32 nativeMods)
static QHash< Identifier, EventHotKeyRef > keyRefs
QPair< quint32, quint32 > Identifier
#define TTKReinterpretCast(x, y)
OSStatus q_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void *data)