From 1a407a67b1177ce8c3397ad4b175a882179e4c27 Mon Sep 17 00:00:00 2001 From: Tudor Brindus Date: Sat, 13 Feb 2021 02:19:01 -0500 Subject: [PATCH] [client] input: add releaseKeysOnFocusLoss option This makes dealing with window manager shortcuts that overlap with guest keys more pleasant, while retaining the previous functionality for users who prefer it. For instance, previously, using Alt+Tab (or $mod as Alt in i3/sway movement commands) would result in the guest retaining Alt as pressed. When the guest regained focus, it would continue thinking Alt is pressed, leading to accidentally triggering obscure shortcuts. One had to remember to press Alt again to "unstick" things, which was suboptimal. --- client/README.md | 31 ++++++++++++++++--------------- client/src/app.c | 5 +++++ client/src/config.c | 30 +++++++++++++++++++----------- client/src/main.h | 1 + 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/client/README.md b/client/README.md index ee22ea8a..4fce8c55 100644 --- a/client/README.md +++ b/client/README.md @@ -145,21 +145,22 @@ Command line arguments will override any options loaded from the config files. | win:rotate | | 0 | Rotate the displayed image (0, 90, 180, 270) | |---------------------------------------------------------------------------------------------------------------------------------| -|----------------------------------------------------------------------------------------------------------------------------------------------| -| Long | Short | Value | Description | -|----------------------------------------------------------------------------------------------------------------------------------------------| -| input:grabKeyboard | -G | yes | Grab the keyboard in capture mode | -| input:grabKeyboardOnFocus | | yes | Grab the keyboard when focused | -| input:escapeKey | -m | 71 = ScrollLock | Specify the escape key, see https://wiki.libsdl.org/SDLScancodeLookup for valid values | -| input:ignoreWindowsKeys | | no | Do not pass events for the windows keys to the guest | -| input:hideCursor | -M | yes | Hide the local mouse cursor | -| input:mouseSens | | 0 | Initial mouse sensitivity when in capture mode (-9 to 9) | -| input:mouseSmoothing | | yes | Apply simple mouse smoothing when rawMouse is not in use (helps reduce aliasing) | -| input:rawMouse | | no | Use RAW mouse input when in capture mode (good for gaming) | -| input:mouseRedraw | | yes | Mouse movements trigger redraws (ignores FPS minimum) | -| input:autoCapture | | no | Try to keep the mouse captured when needed | -| input:captureOnly | | no | Only enable input via SPICE if in capture mode | -|----------------------------------------------------------------------------------------------------------------------------------------------| +|-----------------------------------------------------------------------------------------------------------------------------------------------| +| Long | Short | Value | Description | +|-----------------------------------------------------------------------------------------------------------------------------------------------| +| input:grabKeyboard | -G | no | Grab the keyboard in capture mode | +| input:grabKeyboardOnFocus | | no | Grab the keyboard when focused | +| input:releaseKeysOnFocusLoss | | yes | On focus loss, send key up events to guest for all held keys | +| input:escapeKey | -m | 70 = KEY_SCROLLLOCK | Specify the escape key, see for valid values | +| input:ignoreWindowsKeys | | no | Do not pass events for the windows keys to the guest | +| input:hideCursor | -M | yes | Hide the local mouse cursor | +| input:mouseSens | | 0 | Initial mouse sensitivity when in capture mode (-9 to 9) | +| input:mouseSmoothing | | yes | Apply simple mouse smoothing when rawMouse is not in use (helps reduce aliasing) | +| input:rawMouse | | no | Use RAW mouse input when in capture mode (good for gaming) | +| input:mouseRedraw | | yes | Mouse movements trigger redraws (ignores FPS minimum) | +| input:autoCapture | | no | Try to keep the mouse captured when needed | +| input:captureOnly | | no | Only enable input via SPICE if in capture mode | +|-----------------------------------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------------------------------------------------------------| | Long | Short | Value | Description | diff --git a/client/src/app.c b/client/src/app.c index 69d6e28c..2b893994 100644 --- a/client/src/app.c +++ b/client/src/app.c @@ -57,6 +57,11 @@ void app_handleFocusEvent(bool focused) { core_setGrabQuiet(false); core_setCursorInView(false); + + if (g_params.releaseKeysOnFocusLoss) + for (int key = 0; key < KEY_MAX; key++) + if (g_state.keyDown[key]) + app_handleKeyRelease(key); } g_cursor.realign = true; diff --git a/client/src/config.c b/client/src/config.c index c9b38910..954a1989 100644 --- a/client/src/config.c +++ b/client/src/config.c @@ -271,6 +271,13 @@ static struct Option options[] = .type = OPTION_TYPE_BOOL, .value.x_bool = true, }, + { + .module = "input", + .name = "releaseKeysOnFocusLoss", + .description = "On focus loss, send key up events to guest for all held keys", + .type = OPTION_TYPE_BOOL, + .value.x_bool = true + }, { .module = "input", .name = "escapeKey", @@ -512,17 +519,18 @@ bool config_load(int argc, char * argv[]) case 270: g_params.winRotate = LG_ROTATE_270; break; } - g_params.grabKeyboard = option_get_bool("input", "grabKeyboard" ); - g_params.grabKeyboardOnFocus = option_get_bool("input", "grabKeyboardOnFocus"); - g_params.escapeKey = option_get_int ("input", "escapeKey" ); - g_params.ignoreWindowsKeys = option_get_bool("input", "ignoreWindowsKeys" ); - g_params.hideMouse = option_get_bool("input", "hideCursor" ); - g_params.mouseSens = option_get_int ("input", "mouseSens" ); - g_params.mouseSmoothing = option_get_bool("input", "mouseSmoothing" ); - g_params.rawMouse = option_get_bool("input", "rawMouse" ); - g_params.mouseRedraw = option_get_bool("input", "mouseRedraw" ); - g_params.autoCapture = option_get_bool("input", "autoCapture" ); - g_params.captureInputOnly = option_get_bool("input", "captureOnly" ); + g_params.grabKeyboard = option_get_bool("input", "grabKeyboard" ); + g_params.grabKeyboardOnFocus = option_get_bool("input", "grabKeyboardOnFocus" ); + g_params.releaseKeysOnFocusLoss = option_get_bool("input", "releaseKeysOnFocusLoss"); + g_params.escapeKey = option_get_int ("input", "escapeKey" ); + g_params.ignoreWindowsKeys = option_get_bool("input", "ignoreWindowsKeys" ); + g_params.hideMouse = option_get_bool("input", "hideCursor" ); + g_params.mouseSens = option_get_int ("input", "mouseSens" ); + g_params.mouseSmoothing = option_get_bool("input", "mouseSmoothing" ); + g_params.rawMouse = option_get_bool("input", "rawMouse" ); + g_params.mouseRedraw = option_get_bool("input", "mouseRedraw" ); + g_params.autoCapture = option_get_bool("input", "autoCapture" ); + g_params.captureInputOnly = option_get_bool("input", "captureOnly" ); g_params.minimizeOnFocusLoss = option_get_bool("win", "minimizeOnFocusLoss"); diff --git a/client/src/main.h b/client/src/main.h index 6ebf6769..5ab22c75 100644 --- a/client/src/main.h +++ b/client/src/main.h @@ -128,6 +128,7 @@ struct AppParams bool grabKeyboardOnFocus; int escapeKey; bool ignoreWindowsKeys; + bool releaseKeysOnFocusLoss; bool showAlerts; bool captureOnStart; bool quickSplash;