From 9412c31e42d2b2105e8c75ae017b3926466fff0f Mon Sep 17 00:00:00 2001 From: Vasily Date: Sun, 17 May 2020 22:02:09 +0200 Subject: [PATCH] Refactor input_sender to have main logic be cross platform Previously logic was duplicated for Linux/Windows. Additionally, Linux was ```cpp if ( isModifier( token ) ) { sendKeyPress( token, KeyStatus::Down, display ); if ( noKeyUp ) { heldInputs.push_back( token ); } continue; } ``` while Windows was ```cpp if ( isModifier( token ) ) { inputs.push_back( createInputStruct( convertToVirtualKeycode( token ), KeyStatus::Down ) ); if ( !noKeyUp ) { heldInputs.push_back( token ); } continue; } ``` (notice difference in noKeyUp if statement which was a bug on Linux. Windows was the correct version and it has been kept. --- src/keyboard_input/input_sender.h | 67 ++++++++++++++++++- src/keyboard_input/input_sender_X11.cpp | 89 ++++++------------------- src/keyboard_input/input_sender_win.cpp | 76 ++++----------------- 3 files changed, 99 insertions(+), 133 deletions(-) diff --git a/src/keyboard_input/input_sender.h b/src/keyboard_input/input_sender.h index 6d04c87..94bf044 100644 --- a/src/keyboard_input/input_sender.h +++ b/src/keyboard_input/input_sender.h @@ -8,7 +8,72 @@ enum class KeyStatus Down, }; -void sendTokensAsInput( const std::vector tokens ); +void initOsSystems(); +void shutdownOsSystems(); + +void sendKeyPress( const Token token, const KeyStatus status ); + +inline void sendTokensAsInput( const std::vector tokens ) +{ + initOsSystems(); + + std::vector heldInputs = {}; + bool noKeyUp = false; + for ( const auto& token : tokens ) + { + if ( token == Token::TOKEN_NO_KEYUP_NEXT ) + { + noKeyUp = true; + continue; + } + + if ( isModifier( token ) ) + { + sendKeyPress( token, KeyStatus::Down ); + if ( !noKeyUp ) + { + heldInputs.push_back( token ); + } + continue; + } + + if ( token == Token::TOKEN_NEW_SEQUENCE ) + { + for ( const auto& h : heldInputs ) + { + sendKeyPress( h, KeyStatus::Up ); + } + heldInputs.clear(); + continue; + } + + if ( isLiteral( token ) ) + { + sendKeyPress( token, KeyStatus::Down ); + if ( !noKeyUp ) + { + sendKeyPress( token, KeyStatus::Up ); + } + continue; + } + + if ( token != Token::TOKEN_NO_KEYUP_NEXT ) + { + noKeyUp = false; + continue; + } + } + + if ( !heldInputs.empty() ) + { + for ( const auto& h : heldInputs ) + { + sendKeyPress( h, KeyStatus::Up ); + } + } + + shutdownOsSystems(); +} inline void sendStringAsInput( const std::string input ) { diff --git a/src/keyboard_input/input_sender_X11.cpp b/src/keyboard_input/input_sender_X11.cpp index f2e7bfd..0483d88 100644 --- a/src/keyboard_input/input_sender_X11.cpp +++ b/src/keyboard_input/input_sender_X11.cpp @@ -163,9 +163,24 @@ unsigned int tokenToKeySym( const Token token ) } } -void sendKeyPress( const Token token, - const KeyStatus status, - Display* const display ) +Display* getDisplay() +{ + static Display* display = XOpenDisplay( nullptr ); + return display; +} + +void initOsSystems() +{ + XTestGrabControl( getDisplay(), True ); +} + +void shutdownOsSystems() +{ + XSync( getDisplay(), False ); + XTestGrabControl( getDisplay(), False ); +} + +void sendKeyPress( const Token token, const KeyStatus status ) { bool keyDown = false; @@ -174,72 +189,8 @@ void sendKeyPress( const Token token, keyDown = true; } - XTestFakeKeyEvent( display, - XKeysymToKeycode( display, tokenToKeySym( token ) ), + XTestFakeKeyEvent( getDisplay(), + XKeysymToKeycode( getDisplay(), tokenToKeySym( token ) ), keyDown, 0 ); } - -void sendTokensAsInput( const std::vector tokens ) -{ - Display* const display = XOpenDisplay( nullptr ); - XTestGrabControl( display, True ); - - std::vector heldInputs = {}; - bool noKeyUp = false; - for ( const auto& token : tokens ) - { - if ( token == Token::TOKEN_NO_KEYUP_NEXT ) - { - noKeyUp = true; - continue; - } - - if ( isModifier( token ) ) - { - sendKeyPress( token, KeyStatus::Down, display ); - if ( noKeyUp ) - { - heldInputs.push_back( token ); - } - continue; - } - - if ( token == Token::TOKEN_NEW_SEQUENCE ) - { - for ( const auto& h : heldInputs ) - { - sendKeyPress( h, KeyStatus::Up, display ); - } - heldInputs.clear(); - continue; - } - - if ( isLiteral( token ) ) - { - sendKeyPress( token, KeyStatus::Down, display ); - if ( noKeyUp ) - { - sendKeyPress( token, KeyStatus::Up, display ); - } - continue; - } - - if ( token != Token::TOKEN_NO_KEYUP_NEXT ) - { - noKeyUp = false; - continue; - } - } - - if ( !heldInputs.empty() ) - { - for ( const auto& h : heldInputs ) - { - sendKeyPress( h, KeyStatus::Up, display ); - } - } - - XSync( display, False ); - XTestGrabControl( display, False ); -} diff --git a/src/keyboard_input/input_sender_win.cpp b/src/keyboard_input/input_sender_win.cpp index dfa436b..96d20ae 100644 --- a/src/keyboard_input/input_sender_win.cpp +++ b/src/keyboard_input/input_sender_win.cpp @@ -93,6 +93,15 @@ WORD convertToVirtualKeycode( const Token token ) return 0; } } +void initOsSystems() +{ + // Intentionally blank, no setup needed on Windows +} + +void shutdownOsSystems() +{ + // Intentionally blank, no shutdown needed on Windows +} INPUT createInputStruct( const WORD virtualKeyCode, const KeyStatus keyStatus ) noexcept @@ -163,68 +172,9 @@ void sendKeyboardInputRaw( std::vector inputs ) } } -void sendTokensAsInput( const std::vector tokens ) +void sendKeyPress( const Token token, const KeyStatus status ) { - std::vector inputs = {}; - std::vector heldInputs = {}; - bool noKeyUp = false; - for ( const auto& token : tokens ) - { - if ( token == Token::TOKEN_NO_KEYUP_NEXT ) - { - noKeyUp = true; - continue; - } - - if ( isModifier( token ) ) - { - inputs.push_back( createInputStruct( - convertToVirtualKeycode( token ), KeyStatus::Down ) ); - if ( !noKeyUp ) - { - heldInputs.push_back( token ); - } - continue; - } - - if ( token == Token::TOKEN_NEW_SEQUENCE ) - { - for ( const auto& h : heldInputs ) - { - inputs.push_back( createInputStruct( - convertToVirtualKeycode( h ), KeyStatus::Up ) ); - } - heldInputs.clear(); - continue; - } - - if ( isLiteral( token ) ) - { - inputs.push_back( createInputStruct( - convertToVirtualKeycode( token ), KeyStatus::Down ) ); - if ( !noKeyUp ) - { - inputs.push_back( createInputStruct( - convertToVirtualKeycode( token ), KeyStatus::Up ) ); - } - continue; - } - if ( token != Token::TOKEN_NO_KEYUP_NEXT ) - { - noKeyUp = false; - continue; - } - } - - if ( !heldInputs.empty() ) - { - for ( const auto& h : heldInputs ) - { - inputs.push_back( createInputStruct( convertToVirtualKeycode( h ), - KeyStatus::Up ) ); - } - } - - sendKeyboardInputRaw( inputs ); - // send inputs + std::vector v + = { createInputStruct( convertToVirtualKeycode( token ), status ) }; + sendKeyboardInputRaw( v ); }