From eefea5444e3af7f933a712518bc50007db79dd81 Mon Sep 17 00:00:00 2001 From: Weslly Date: Wed, 29 Mar 2017 12:52:35 -0300 Subject: [PATCH] Change auto-type sequence on mac to support other keyboard layouts --- src/autotype/mac/AutoTypeMac.cpp | 54 ++++++++++++++++++++++---------- src/autotype/mac/AutoTypeMac.h | 4 +-- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp index 75ff0099a..89435c263 100644 --- a/src/autotype/mac/AutoTypeMac.cpp +++ b/src/autotype/mac/AutoTypeMac.cpp @@ -120,7 +120,7 @@ bool AutoTypePlatformMac::registerGlobalShortcut(Qt::Key key, Qt::KeyboardModifi qWarning("Invalid key code"); return false; } - uint16 nativeModifiers = qtToNativeModifiers(modifiers); + CGEventFlags nativeModifiers = qtToNativeModifiers(modifiers, false); if (::RegisterEventHotKey(nativeKeyCode, nativeModifiers, m_hotkeyId, GetApplicationEventTarget(), 0, &m_hotkeyRef) != noErr) { qWarning("Register hotkey failed"); return false; @@ -201,7 +201,7 @@ void AutoTypePlatformMac::sendChar(const QChar& ch, bool isKeyDown) // Send key code to active window // see: Quartz Event Services // -void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown, bool isCommand = false) +void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown, Qt::KeyboardModifiers modifiers = 0) { uint16 keyCode = qtToNativeKeyCode(key); if (keyCode == INVALID_KEYCODE) { @@ -209,10 +209,9 @@ void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown, bool isCommand = } CGEventRef keyEvent = ::CGEventCreateKeyboardEvent(nullptr, keyCode, isKeyDown); + CGEventFlags nativeModifiers = qtToNativeModifiers(modifiers, true); if (keyEvent != nullptr) { - if (isCommand && isKeyDown) { - ::CGEventSetFlags(keyEvent, kCGEventFlagMaskCommand); - } + ::CGEventSetFlags(keyEvent, nativeModifiers); ::CGEventPost(kCGSessionEventTap, keyEvent); ::CFRelease(keyEvent); } @@ -320,6 +319,8 @@ uint16 AutoTypePlatformMac::qtToNativeKeyCode(Qt::Key key) case Qt::Key_Period: return kVK_ANSI_Period; + case Qt::Key_Shift: + return kVK_Shift; case Qt::Key_Control: return kVK_Command; case Qt::Key_Backspace: @@ -400,21 +401,34 @@ uint16 AutoTypePlatformMac::qtToNativeKeyCode(Qt::Key key) // Translate qt key modifiers to mac os modifiers // see: https://doc.qt.io/qt-5/osx-issues.html#special-keys // -uint16 AutoTypePlatformMac::qtToNativeModifiers(Qt::KeyboardModifiers modifiers) +CGEventFlags AutoTypePlatformMac::qtToNativeModifiers(Qt::KeyboardModifiers modifiers, bool native) { - uint16 nativeModifiers = 0; + CGEventFlags nativeModifiers = 0; + + CGEventFlags shiftMod = shiftKey; + CGEventFlags cmdMod = cmdKey; + CGEventFlags optionMod = optionKey; + CGEventFlags controlMod = controlKey; + + if (native) { + shiftMod = kCGEventFlagMaskShift; + cmdMod = kCGEventFlagMaskCommand; + optionMod = kCGEventFlagMaskAlternate; + controlMod = kCGEventFlagMaskControl; + } + if (modifiers & Qt::ShiftModifier) { - nativeModifiers |= shiftKey; + nativeModifiers |= shiftMod; } if (modifiers & Qt::ControlModifier) { - nativeModifiers |= cmdKey; + nativeModifiers |= cmdMod; } if (modifiers & Qt::AltModifier) { - nativeModifiers |= optionKey; + nativeModifiers |= optionMod; } if (modifiers & Qt::MetaModifier) { - nativeModifiers |= controlKey; + nativeModifiers |= controlMod; } return nativeModifiers; @@ -498,12 +512,20 @@ void AutoTypeExecutorMac::execClearField(AutoTypeClearField* action = nullptr) { Q_UNUSED(action); - m_platform->sendKey(Qt::Key_Control, true, true); - m_platform->sendKey(Qt::Key_A, true, true); - m_platform->sendKey(Qt::Key_Control, false, true); - m_platform->sendKey(Qt::Key_A, false); + m_platform->sendKey(Qt::Key_Control, true, Qt::ControlModifier); + m_platform->sendKey(Qt::Key_Up, true, Qt::ControlModifier); + m_platform->sendKey(Qt::Key_Up, false, Qt::ControlModifier); + m_platform->sendKey(Qt::Key_Control, false); + usleep(25 * 1000); + m_platform->sendKey(Qt::Key_Shift, true, Qt::ShiftModifier); + m_platform->sendKey(Qt::Key_Control, true, Qt::ShiftModifier | Qt::ControlModifier); + m_platform->sendKey(Qt::Key_Down, true, Qt::ShiftModifier | Qt::ControlModifier); + m_platform->sendKey(Qt::Key_Down, false, Qt::ShiftModifier | Qt::ControlModifier); + m_platform->sendKey(Qt::Key_Control, false, Qt::ShiftModifier); + m_platform->sendKey(Qt::Key_Shift, false); + usleep(25 * 1000); m_platform->sendKey(Qt::Key_Backspace, true); m_platform->sendKey(Qt::Key_Backspace, false); - + usleep(25 * 1000); } diff --git a/src/autotype/mac/AutoTypeMac.h b/src/autotype/mac/AutoTypeMac.h index 86b01826b..82f8b0eb6 100644 --- a/src/autotype/mac/AutoTypeMac.h +++ b/src/autotype/mac/AutoTypeMac.h @@ -49,7 +49,7 @@ public: bool raiseOwnWindow() override; void sendChar(const QChar& ch, bool isKeyDown); - void sendKey(Qt::Key key, bool isKeyDown, bool isCommand); + void sendKey(Qt::Key key, bool isKeyDown, Qt::KeyboardModifiers modifiers); signals: void globalShortcutTriggered(); @@ -60,7 +60,7 @@ private: EventHotKeyID m_hotkeyId; static uint16 qtToNativeKeyCode(Qt::Key key); - static uint16 qtToNativeModifiers(Qt::KeyboardModifiers modifiers); + static CGEventFlags qtToNativeModifiers(Qt::KeyboardModifiers modifiers, bool native); static int windowLayer(CFDictionaryRef window); static QString windowTitle(CFDictionaryRef window); static OSStatus hotkeyHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData);