Merge pull request #427 from weslly/feature/autotype-clearfield

Add auto-type {CLEARFIELD}
This commit is contained in:
Jonathan White 2017-04-09 11:56:40 -04:00 committed by GitHub
commit c0f62e5633
7 changed files with 122 additions and 14 deletions

View File

@ -90,6 +90,4 @@ void AutoTypeExecutor::execDelay(AutoTypeDelay* action)
void AutoTypeExecutor::execClearField(AutoTypeClearField* action)
{
Q_UNUSED(action);
// TODO: implement
}

View File

@ -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)
void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown, Qt::KeyboardModifiers modifiers = 0)
{
uint16 keyCode = qtToNativeKeyCode(key);
if (keyCode == INVALID_KEYCODE) {
@ -209,7 +209,9 @@ void AutoTypePlatformMac::sendKey(Qt::Key key, bool isKeyDown)
}
CGEventRef keyEvent = ::CGEventCreateKeyboardEvent(nullptr, keyCode, isKeyDown);
CGEventFlags nativeModifiers = qtToNativeModifiers(modifiers, true);
if (keyEvent != nullptr) {
::CGEventSetFlags(keyEvent, nativeModifiers);
::CGEventPost(kCGSessionEventTap, keyEvent);
::CFRelease(keyEvent);
}
@ -317,6 +319,10 @@ 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:
return kVK_Delete;
case Qt::Key_Tab:
@ -395,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;
@ -488,3 +507,25 @@ void AutoTypeExecutorMac::execKey(AutoTypeKey* action)
m_platform->sendKey(action->key, false);
usleep(25 * 1000);
}
void AutoTypeExecutorMac::execClearField(AutoTypeClearField* action = nullptr)
{
Q_UNUSED(action);
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);
}

View File

@ -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, 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);
@ -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;

View File

@ -189,6 +189,10 @@ 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:
return VK_PAUSE; // 0x13
case Qt::Key_CapsLock:
@ -527,3 +531,24 @@ void AutoTypeExecutorWin::execKey(AutoTypeKey* action)
::Sleep(25);
}
void AutoTypeExecutorWin::execClearField(AutoTypeClearField* action = nullptr)
{
Q_UNUSED(action);
m_platform->sendKey(Qt::Key_Control, true);
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);
::Sleep(25);
}

View File

@ -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;

View File

@ -473,6 +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);
@ -723,6 +729,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 +814,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 +855,31 @@ void AutoTypeExecutorX11::execKey(AutoTypeKey* action)
m_platform->SendKeyPressedEvent(m_platform->keyToKeySym(action->key));
}
void AutoTypeExecutorX11::execClearField(AutoTypeClearField* action = nullptr)
{
Q_UNUSED(action);
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);
}
int AutoTypePlatformX11::initialTimeout()
{
return 500;

View File

@ -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;