From 32fe0493c4e8262719482f66faa87697694fd92d Mon Sep 17 00:00:00 2001 From: Weslly Date: Thu, 23 Mar 2017 10:36:52 -0300 Subject: [PATCH 01/11] Add auto-type {CLEARFIELD} on mac --- src/autotype/mac/AutoTypeMac.cpp | 27 +++++++++++++++++++++++++++ src/autotype/mac/AutoTypeMac.h | 1 + 2 files changed, 28 insertions(+) diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp index 08df6310e..504103fca 100644 --- a/src/autotype/mac/AutoTypeMac.cpp +++ b/src/autotype/mac/AutoTypeMac.cpp @@ -488,3 +488,30 @@ void AutoTypeExecutorMac::execKey(AutoTypeKey* action) m_platform->sendKey(action->key, false); usleep(25 * 1000); } + +void execClearFieldHelper(uint16 keyCode, bool isKeyDown, bool modifier = false) +{ + CGEventRef keyEvent = ::CGEventCreateKeyboardEvent(nullptr, keyCode, isKeyDown); + if (keyEvent != nullptr) { + if (modifier) { + ::CGEventSetFlags(keyEvent, kCGEventFlagMaskCommand); + } + + ::CGEventPost(kCGSessionEventTap, keyEvent); + ::CFRelease(keyEvent); + } + usleep(25 * 1000); +} + +void AutoTypeExecutorMac::execClearField(AutoTypeClearField* action = nullptr) +{ + Q_UNUSED(action); + + execClearFieldHelper(kVK_ANSI_A, true, true); + execClearFieldHelper(kVK_ANSI_A, false); + execClearFieldHelper(kVK_Command, false); + execClearFieldHelper(kVK_Delete, true); + execClearFieldHelper(kVK_Delete, false); + + usleep(25 * 1000); +} diff --git a/src/autotype/mac/AutoTypeMac.h b/src/autotype/mac/AutoTypeMac.h index 5fbbf763b..c2dde398a 100644 --- a/src/autotype/mac/AutoTypeMac.h +++ b/src/autotype/mac/AutoTypeMac.h @@ -73,6 +73,7 @@ public: void execChar(AutoTypeChar* action) override; void execKey(AutoTypeKey* action) override; + void execClearField(AutoTypeClearField* action) override; private: AutoTypePlatformMac* const m_platform; From 720ae949aa1971c2f157cdb187cba7984d232620 Mon Sep 17 00:00:00 2001 From: Weslly Date: Thu, 23 Mar 2017 11:14:46 -0300 Subject: [PATCH 02/11] Rename ClearField keypress helper function --- src/autotype/mac/AutoTypeMac.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp index 504103fca..57e2e9e15 100644 --- a/src/autotype/mac/AutoTypeMac.cpp +++ b/src/autotype/mac/AutoTypeMac.cpp @@ -489,7 +489,7 @@ void AutoTypeExecutorMac::execKey(AutoTypeKey* action) usleep(25 * 1000); } -void execClearFieldHelper(uint16 keyCode, bool isKeyDown, bool modifier = false) +void execKeyPress(uint16 keyCode, bool isKeyDown, bool modifier = false) { CGEventRef keyEvent = ::CGEventCreateKeyboardEvent(nullptr, keyCode, isKeyDown); if (keyEvent != nullptr) { @@ -507,11 +507,11 @@ void AutoTypeExecutorMac::execClearField(AutoTypeClearField* action = nullptr) { Q_UNUSED(action); - execClearFieldHelper(kVK_ANSI_A, true, true); - execClearFieldHelper(kVK_ANSI_A, false); - execClearFieldHelper(kVK_Command, false); - execClearFieldHelper(kVK_Delete, true); - execClearFieldHelper(kVK_Delete, false); + execKeyPress(kVK_ANSI_A, true, true); + execKeyPress(kVK_ANSI_A, false); + execKeyPress(kVK_Command, false); + execKeyPress(kVK_Delete, true); + execKeyPress(kVK_Delete, false); usleep(25 * 1000); } From 28678f4e06cb1f466a6ed4c3081bc9ad95fcabbc Mon Sep 17 00:00:00 2001 From: Weslly Date: Fri, 24 Mar 2017 10:15:31 -0300 Subject: [PATCH 03/11] Add auto-type {CLEARFIELD} on Windows --- src/autotype/windows/AutoTypeWindows.cpp | 34 ++++++++++++++++++++++++ src/autotype/windows/AutoTypeWindows.h | 1 + 2 files changed, 35 insertions(+) diff --git a/src/autotype/windows/AutoTypeWindows.cpp b/src/autotype/windows/AutoTypeWindows.cpp index 0818a37bc..3c8d896ed 100644 --- a/src/autotype/windows/AutoTypeWindows.cpp +++ b/src/autotype/windows/AutoTypeWindows.cpp @@ -527,3 +527,37 @@ void AutoTypeExecutorWin::execKey(AutoTypeKey* action) ::Sleep(25); } +void execKeyPress(const DWORD keyCode, bool isKeyDown) +{ + DWORD nativeFlags = 0; + + if (!isKeyDown) { + nativeFlags |= KEYEVENTF_KEYUP; + } + + INPUT in; + in.type = INPUT_KEYBOARD; + in.ki.wVk = LOWORD(keyCode); + in.ki.wScan = LOWORD(::MapVirtualKeyW(keyCode, MAPVK_VK_TO_VSC)); + in.ki.dwFlags = nativeFlags; + in.ki.time = 0; + in.ki.dwExtraInfo = ::GetMessageExtraInfo(); + + ::SendInput(1, &in, sizeof(INPUT)); + + ::Sleep(25); +} + +void AutoTypeExecutorWin::execClearField(AutoTypeClearField* action = nullptr) +{ + Q_UNUSED(action); + + execKeyPress(VK_CONTROL, true); + execKeyPress(0x41, true); + execKeyPress(0x41, false); + execKeyPress(VK_CONTROL, false); + execKeyPress(VK_BACK, true); + execKeyPress(VK_BACK, false); + + ::Sleep(25); +} diff --git a/src/autotype/windows/AutoTypeWindows.h b/src/autotype/windows/AutoTypeWindows.h index f8b213cb0..6ffae4d1e 100644 --- a/src/autotype/windows/AutoTypeWindows.h +++ b/src/autotype/windows/AutoTypeWindows.h @@ -64,6 +64,7 @@ public: void execChar(AutoTypeChar* action) override; void execKey(AutoTypeKey* action) override; + void execClearField(AutoTypeClearField* action) override; private: AutoTypePlatformWin* const m_platform; From 7620395f92faab3949a7f0302e8b64e8ff492b08 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Sat, 25 Mar 2017 22:23:43 +0100 Subject: [PATCH 04/11] Add auto-type {CLEARFIELD} on XCB --- src/autotype/xcb/AutoTypeXCB.cpp | 29 +++++++++++++++++++++++++++-- src/autotype/xcb/AutoTypeXCB.h | 2 ++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/autotype/xcb/AutoTypeXCB.cpp b/src/autotype/xcb/AutoTypeXCB.cpp index e6ac74bbf..5d58e33c6 100644 --- a/src/autotype/xcb/AutoTypeXCB.cpp +++ b/src/autotype/xcb/AutoTypeXCB.cpp @@ -723,6 +723,12 @@ bool AutoTypePlatformX11::keysymModifiers(KeySym keysym, int keycode, unsigned i * are set ON, many events will be sent. */ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym) +{ + SendKey(keysym,true); + SendKey(keysym,false); +} + +void AutoTypePlatformX11::SendKey(KeySym keysym, bool isKeyDown) { Window cur_focus; int revert_to; @@ -802,8 +808,11 @@ void AutoTypePlatformX11::SendKeyPressedEvent(KeySym keysym) /* press and release key */ event.keycode = keycode; - SendEvent(&event, KeyPress); - SendEvent(&event, KeyRelease); + if (isKeyDown) { + SendEvent(&event, KeyPress); + } else { + SendEvent(&event, KeyRelease); + } /* release the modifiers */ SendModifier(&event, press_mask, KeyRelease); @@ -840,6 +849,22 @@ void AutoTypeExecutorX11::execKey(AutoTypeKey* action) m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(action->key)); } +void AutoTypeExecutorX11::execClearField(AutoTypeClearField* action = nullptr) +{ + Q_UNUSED(action); + + m_platform->SendKey(XK_Control_L, true); + m_platform->SendKeyPressedEvent(XK_a); + m_platform->SendKey(XK_Control_L, false); + m_platform->SendKeyPressedEvent(XK_Delete); + + timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 25 * 1000 * 1000; + nanosleep(&ts, nullptr); +} + + int AutoTypePlatformX11::initialTimeout() { return 500; diff --git a/src/autotype/xcb/AutoTypeXCB.h b/src/autotype/xcb/AutoTypeXCB.h index dc251e3f9..186d0eb8b 100644 --- a/src/autotype/xcb/AutoTypeXCB.h +++ b/src/autotype/xcb/AutoTypeXCB.h @@ -58,6 +58,7 @@ public: KeySym keyToKeySym(Qt::Key key); void SendKeyPressedEvent(KeySym keysym); + void SendKey(KeySym keysym, bool isKeyDown); signals: void globalShortcutTriggered(); @@ -126,6 +127,7 @@ public: void execChar(AutoTypeChar* action) override; void execKey(AutoTypeKey* action) override; + void execClearField(AutoTypeClearField* action) override; private: AutoTypePlatformX11* const m_platform; From 268f09160d0881f55646e4b44def5e40fa40146a Mon Sep 17 00:00:00 2001 From: Weslly Date: Sat, 25 Mar 2017 18:42:52 -0300 Subject: [PATCH 05/11] Add command modifier support for AutoTypePlatformMac::sendKey --- src/autotype/mac/AutoTypeMac.cpp | 40 ++++++++++++++------------------ src/autotype/mac/AutoTypeMac.h | 2 +- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp index 57e2e9e15..122bffeaa 100644 --- a/src/autotype/mac/AutoTypeMac.cpp +++ b/src/autotype/mac/AutoTypeMac.cpp @@ -201,15 +201,25 @@ 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) +void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown, bool isCommand = false) { - uint16 keyCode = qtToNativeKeyCode(key); + uint16 keyCode = 0; + + if (isCommand && key == Qt::Key_Any) { + keyCode = kVK_Command; + } else { + keyCode = qtToNativeKeyCode(key); + } + if (keyCode == INVALID_KEYCODE) { return; } CGEventRef keyEvent = ::CGEventCreateKeyboardEvent(nullptr, keyCode, isKeyDown); if (keyEvent != nullptr) { + if (isCommand && isKeyDown) { + ::CGEventSetFlags(keyEvent, kCGEventFlagMaskCommand); + } ::CGEventPost(kCGSessionEventTap, keyEvent); ::CFRelease(keyEvent); } @@ -489,29 +499,13 @@ void AutoTypeExecutorMac::execKey(AutoTypeKey* action) usleep(25 * 1000); } -void execKeyPress(uint16 keyCode, bool isKeyDown, bool modifier = false) -{ - CGEventRef keyEvent = ::CGEventCreateKeyboardEvent(nullptr, keyCode, isKeyDown); - if (keyEvent != nullptr) { - if (modifier) { - ::CGEventSetFlags(keyEvent, kCGEventFlagMaskCommand); - } - - ::CGEventPost(kCGSessionEventTap, keyEvent); - ::CFRelease(keyEvent); - } - usleep(25 * 1000); -} - void AutoTypeExecutorMac::execClearField(AutoTypeClearField* action = nullptr) { Q_UNUSED(action); - - execKeyPress(kVK_ANSI_A, true, true); - execKeyPress(kVK_ANSI_A, false); - execKeyPress(kVK_Command, false); - execKeyPress(kVK_Delete, true); - execKeyPress(kVK_Delete, false); - + m_platform->sendKey(Qt::Key_A, true, true); + m_platform->sendKey(Qt::Key_A, false); + m_platform->sendKey(Qt::Key_Any, false, true); + 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 c2dde398a..86b01826b 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); + void sendKey(Qt::Key key, bool isKeyDown, bool isCommand); signals: void globalShortcutTriggered(); From 36250f518075d1b348eb4b63193590be5f0c608a Mon Sep 17 00:00:00 2001 From: Weslly Date: Sat, 25 Mar 2017 19:03:17 -0300 Subject: [PATCH 06/11] Use AutoTypePlatformWin::sendKey instead of creating a new function --- src/autotype/AutoTypeAction.cpp | 2 -- src/autotype/mac/AutoTypeMac.cpp | 2 ++ src/autotype/windows/AutoTypeWindows.cpp | 35 ++++++------------------ 3 files changed, 10 insertions(+), 29 deletions(-) diff --git a/src/autotype/AutoTypeAction.cpp b/src/autotype/AutoTypeAction.cpp index 090ca8234..64dae7962 100644 --- a/src/autotype/AutoTypeAction.cpp +++ b/src/autotype/AutoTypeAction.cpp @@ -90,6 +90,4 @@ void AutoTypeExecutor::execDelay(AutoTypeDelay* action) void AutoTypeExecutor::execClearField(AutoTypeClearField* action) { Q_UNUSED(action); - - // TODO: implement } diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp index 122bffeaa..2806a4486 100644 --- a/src/autotype/mac/AutoTypeMac.cpp +++ b/src/autotype/mac/AutoTypeMac.cpp @@ -502,10 +502,12 @@ void AutoTypeExecutorMac::execKey(AutoTypeKey* action) void AutoTypeExecutorMac::execClearField(AutoTypeClearField* action = nullptr) { Q_UNUSED(action); + m_platform->sendKey(Qt::Key_A, true, true); m_platform->sendKey(Qt::Key_A, false); m_platform->sendKey(Qt::Key_Any, false, true); m_platform->sendKey(Qt::Key_Backspace, true); m_platform->sendKey(Qt::Key_Backspace, false); + usleep(25 * 1000); } diff --git a/src/autotype/windows/AutoTypeWindows.cpp b/src/autotype/windows/AutoTypeWindows.cpp index 3c8d896ed..0b1474412 100644 --- a/src/autotype/windows/AutoTypeWindows.cpp +++ b/src/autotype/windows/AutoTypeWindows.cpp @@ -189,6 +189,8 @@ DWORD AutoTypePlatformWin::qtToNativeKeyCode(Qt::Key key) case Qt::Key_Enter: case Qt::Key_Return: return VK_RETURN; // 0x0D + case Qt::Key_Control: + return VK_CONTROL; // 0x11 case Qt::Key_Pause: return VK_PAUSE; // 0x13 case Qt::Key_CapsLock: @@ -527,37 +529,16 @@ void AutoTypeExecutorWin::execKey(AutoTypeKey* action) ::Sleep(25); } -void execKeyPress(const DWORD keyCode, bool isKeyDown) -{ - DWORD nativeFlags = 0; - - if (!isKeyDown) { - nativeFlags |= KEYEVENTF_KEYUP; - } - - INPUT in; - in.type = INPUT_KEYBOARD; - in.ki.wVk = LOWORD(keyCode); - in.ki.wScan = LOWORD(::MapVirtualKeyW(keyCode, MAPVK_VK_TO_VSC)); - in.ki.dwFlags = nativeFlags; - in.ki.time = 0; - in.ki.dwExtraInfo = ::GetMessageExtraInfo(); - - ::SendInput(1, &in, sizeof(INPUT)); - - ::Sleep(25); -} - void AutoTypeExecutorWin::execClearField(AutoTypeClearField* action = nullptr) { Q_UNUSED(action); - execKeyPress(VK_CONTROL, true); - execKeyPress(0x41, true); - execKeyPress(0x41, false); - execKeyPress(VK_CONTROL, false); - execKeyPress(VK_BACK, true); - execKeyPress(VK_BACK, false); + m_platform->sendKey(Qt::Key_Control, true); + m_platform->sendKey(Qt::Key_A, true); + m_platform->sendKey(Qt::Key_A, false); + m_platform->sendKey(Qt::Key_Control, false); + m_platform->sendKey(Qt::Key_Backspace, true); + m_platform->sendKey(Qt::Key_Backspace, false); ::Sleep(25); } From ea1ffe7fb55453ef37f95a0304ba2dcb1acecda8 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Sat, 25 Mar 2017 23:22:01 +0100 Subject: [PATCH 07/11] use QT key instead of native ones --- src/autotype/xcb/AutoTypeXCB.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/autotype/xcb/AutoTypeXCB.cpp b/src/autotype/xcb/AutoTypeXCB.cpp index 5d58e33c6..b5fe9e7e7 100644 --- a/src/autotype/xcb/AutoTypeXCB.cpp +++ b/src/autotype/xcb/AutoTypeXCB.cpp @@ -473,6 +473,8 @@ KeySym AutoTypePlatformX11::keyToKeySym(Qt::Key key) return XK_Print; case Qt::Key_ScrollLock: return XK_Scroll_Lock; + case Qt::Key_Control: + return XK_Control_L; default: if (key >= Qt::Key_F1 && key <= Qt::Key_F16) { return XK_F1 + (key - Qt::Key_F1); @@ -853,10 +855,10 @@ void AutoTypeExecutorX11::execClearField(AutoTypeClearField* action = nullptr) { Q_UNUSED(action); - m_platform->SendKey(XK_Control_L, true); - m_platform->SendKeyPressedEvent(XK_a); - m_platform->SendKey(XK_Control_L, false); - m_platform->SendKeyPressedEvent(XK_Delete); + m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), true); + m_platform->SendKeyPressedEvent(m_platform->charToKeySym('a')); + m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), false); + m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(Qt::Key_Delete)); timespec ts; ts.tv_sec = 0; From 6c1f023768f6ce83021c514f313569c3a3301fa4 Mon Sep 17 00:00:00 2001 From: Weslly Date: Sat, 25 Mar 2017 21:07:22 -0300 Subject: [PATCH 08/11] More accurate hotkey sequence --- src/autotype/mac/AutoTypeMac.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp index 2806a4486..75ff0099a 100644 --- a/src/autotype/mac/AutoTypeMac.cpp +++ b/src/autotype/mac/AutoTypeMac.cpp @@ -203,14 +203,7 @@ void AutoTypePlatformMac::sendChar(const QChar& ch, bool isKeyDown) // void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown, bool isCommand = false) { - uint16 keyCode = 0; - - if (isCommand && key == Qt::Key_Any) { - keyCode = kVK_Command; - } else { - keyCode = qtToNativeKeyCode(key); - } - + uint16 keyCode = qtToNativeKeyCode(key); if (keyCode == INVALID_KEYCODE) { return; } @@ -327,6 +320,8 @@ uint16 AutoTypePlatformMac::qtToNativeKeyCode(Qt::Key key) case Qt::Key_Period: return kVK_ANSI_Period; + case Qt::Key_Control: + return kVK_Command; case Qt::Key_Backspace: return kVK_Delete; case Qt::Key_Tab: @@ -503,9 +498,10 @@ 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_Any, false, true); m_platform->sendKey(Qt::Key_Backspace, true); m_platform->sendKey(Qt::Key_Backspace, false); From a6e142dd0240528545bfd74416831d0cf3657cfb Mon Sep 17 00:00:00 2001 From: thez3ro Date: Mon, 27 Mar 2017 18:11:34 +0200 Subject: [PATCH 09/11] support different keyboard layout --- src/autotype/xcb/AutoTypeXCB.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/autotype/xcb/AutoTypeXCB.cpp b/src/autotype/xcb/AutoTypeXCB.cpp index b5fe9e7e7..9290639f2 100644 --- a/src/autotype/xcb/AutoTypeXCB.cpp +++ b/src/autotype/xcb/AutoTypeXCB.cpp @@ -473,8 +473,12 @@ KeySym AutoTypePlatformX11::keyToKeySym(Qt::Key key) return XK_Print; case Qt::Key_ScrollLock: return XK_Scroll_Lock; + case Qt::Key_Shift: + return XK_Shift_L; case Qt::Key_Control: return XK_Control_L; + case Qt::Key_Alt: + return XK_Alt_L; default: if (key >= Qt::Key_F1 && key <= Qt::Key_F16) { return XK_F1 + (key - Qt::Key_F1); @@ -855,14 +859,23 @@ void AutoTypeExecutorX11::execClearField(AutoTypeClearField* action = nullptr) { Q_UNUSED(action); - m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), true); - m_platform->SendKeyPressedEvent(m_platform->charToKeySym('a')); - m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), false); - m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(Qt::Key_Delete)); - timespec ts; ts.tv_sec = 0; ts.tv_nsec = 25 * 1000 * 1000; + + m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), true); + m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(Qt::Key_Home)); + m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), false); + nanosleep(&ts, nullptr); + + m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), true); + m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Shift), true); + m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(Qt::Key_End)); + m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Shift), false); + m_platform->SendKey(m_platform->keyToKeySym(Qt::Key_Control), false); + nanosleep(&ts, nullptr); + + m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(Qt::Key_Backspace)); nanosleep(&ts, nullptr); } From eefea5444e3af7f933a712518bc50007db79dd81 Mon Sep 17 00:00:00 2001 From: Weslly Date: Wed, 29 Mar 2017 12:52:35 -0300 Subject: [PATCH 10/11] 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); From 0aa20f931df53a6a1563a54758b90eae40ab9b9e Mon Sep 17 00:00:00 2001 From: Weslly Date: Sat, 8 Apr 2017 02:13:12 -0300 Subject: [PATCH 11/11] Change windows clearfield key sequence to avoid keyboard layout errors --- src/autotype/windows/AutoTypeWindows.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/autotype/windows/AutoTypeWindows.cpp b/src/autotype/windows/AutoTypeWindows.cpp index 0b1474412..81baeefac 100644 --- a/src/autotype/windows/AutoTypeWindows.cpp +++ b/src/autotype/windows/AutoTypeWindows.cpp @@ -189,6 +189,8 @@ DWORD AutoTypePlatformWin::qtToNativeKeyCode(Qt::Key key) case Qt::Key_Enter: case Qt::Key_Return: return VK_RETURN; // 0x0D + case Qt::Key_Shift: + return VK_SHIFT; // 0x10 case Qt::Key_Control: return VK_CONTROL; // 0x11 case Qt::Key_Pause: @@ -534,9 +536,17 @@ void AutoTypeExecutorWin::execClearField(AutoTypeClearField* action = nullptr) Q_UNUSED(action); m_platform->sendKey(Qt::Key_Control, true); - m_platform->sendKey(Qt::Key_A, true); - m_platform->sendKey(Qt::Key_A, false); + m_platform->sendKey(Qt::Key_Home, true); + m_platform->sendKey(Qt::Key_Home, false); m_platform->sendKey(Qt::Key_Control, false); + ::Sleep(25); + m_platform->sendKey(Qt::Key_Control, true); + m_platform->sendKey(Qt::Key_Shift, true); + m_platform->sendKey(Qt::Key_End, true); + m_platform->sendKey(Qt::Key_End, false); + m_platform->sendKey(Qt::Key_Shift, false); + m_platform->sendKey(Qt::Key_Control, false); + ::Sleep(25); m_platform->sendKey(Qt::Key_Backspace, true); m_platform->sendKey(Qt::Key_Backspace, false);