diff --git a/client/src/app.c b/client/src/app.c index 23ad6d6d..4c20610d 100644 --- a/client/src/app.c +++ b/client/src/app.c @@ -269,9 +269,9 @@ void app_handleFocusEvent(bool focused) if (g_state.focused == focused) return; - g_state.focused = focused; - g_cursor.motionValid = false; - const bool inputEnabled = core_inputEnabled(); + g_state.focused = focused; + g_cursor.motionValid = false; + const bool inputWasEnabled = core_inputEnabled(); // release any imgui buttons/keys if we lost focus if (!focused && app_isOverlayMode()) @@ -285,6 +285,15 @@ void app_handleFocusEvent(bool focused) core_setGrabQuiet(false); core_setCursorInView(false); } + else + { + if (g_params.captureOnFocus && !g_state.ignoreInput) + core_setGrab(true); + core_updateKeyboardGrab(); + } + + const bool inputEnabled = focused ? + core_inputEnabled() : inputWasEnabled; if (!inputEnabled) { @@ -304,10 +313,6 @@ void app_handleFocusEvent(bool focused) if (g_params.minimizeOnFocusLoss) g_state.ds->minimize(); } - else - if (g_params.captureOnFocus) - core_setGrab(true); - g_cursor.realign = true; g_state.ds->realignPointer(); } @@ -518,7 +523,8 @@ void app_handleKeyReleaseInternal(int sc) { if (g_state.escapeAction == -1) { - if (!g_state.escapeHelp && lgInput_available() && + if (!g_state.escapeHelp && + (g_cursor.grab || lgInput_available()) && !app_isOverlayMode()) core_setGrab(!g_cursor.grab); } diff --git a/client/src/core.c b/client/src/core.c index 4b411ffe..2537a862 100644 --- a/client/src/core.c +++ b/client/src/core.c @@ -137,14 +137,18 @@ bool core_inputEnabled(void) ((g_cursor.grab && g_params.captureInputOnly) || !g_params.captureInputOnly); } -static void updateKeyboardGrab(void) +void core_updateKeyboardGrab(void) { - const bool capture = g_cursor.grab && g_params.grabKeyboard; - const bool view = g_cursor.inView && g_params.grabKeyboardOnFocus; - const bool automatic = !g_cursor.grab && + const bool inputEnabled = core_inputEnabled(); + /* Explicit capture is local window state and must survive an input provider + * becoming unavailable or changing during startup. */ + const bool capture = g_cursor.grab && g_params.grabKeyboard && + !g_state.ignoreInput; + const bool view = g_cursor.inView && g_params.grabKeyboardOnFocus; + const bool automatic = !g_cursor.grab && g_cursor.autoCaptureActive && !g_params.captureInputOnly; - const bool active = g_state.focused && core_inputEnabled() && - !app_isOverlayMode() && (capture || view || automatic); + const bool active = g_state.focused && !app_isOverlayMode() && + (capture || (inputEnabled && (view || automatic))); if (active) g_state.ds->grabKeyboard(); @@ -162,7 +166,7 @@ static void setAutoCapture(bool active) MTRACE("auto capture active=%d old=%d", active, g_cursor.autoCaptureActive); g_cursor.autoCaptureActive = active; - updateKeyboardGrab(); + core_updateKeyboardGrab(); } static void applyView(bool active, bool force) @@ -175,7 +179,7 @@ static void applyView(bool active, bool force) if (!force && g_cursor.inView == active) { - updateKeyboardGrab(); + core_updateKeyboardGrab(); return; } @@ -204,7 +208,7 @@ static void applyView(bool active, bool force) g_state.ds->setPointer(LG_POINTER_SQUARE); } - updateKeyboardGrab(); + core_updateKeyboardGrab(); g_cursor.warpState = WARP_STATE_ON; } @@ -323,7 +327,7 @@ void core_setGrabQuiet(bool enable) g_state.ignoreInput = false; g_cursor.grab = true; g_cursor.autoCaptureActive = false; - updateKeyboardGrab(); + core_updateKeyboardGrab(); core_setCursorInView(true); /* ensure the local mouse is inside the window before we capture, this fixes @@ -331,7 +335,11 @@ void core_setGrabQuiet(bool enable) * was focused without the cursor being in window already */ if (warpSupport != LG_DS_WARP_NONE) { - struct DoublePoint local; + struct DoublePoint local = + { + .x = g_state.windowCX, + .y = g_state.windowCY, + }; const bool valid = util_guestCurToLocal(&local); MTRACE("grab align valid=%d", valid); core_warpPointer(local.x, local.y, true); @@ -345,7 +353,7 @@ void core_setGrabQuiet(bool enable) g_cursor.grab = false; g_cursor.autoCaptureActive = g_params.autoCapture && g_cursor.inView && !g_params.captureInputOnly; - updateKeyboardGrab(); + core_updateKeyboardGrab(); if (warpSupport == LG_DS_WARP_NONE) core_handleMouseAbsolute(); diff --git a/client/src/core.h b/client/src/core.h index 49e3e653..e33f4d79 100644 --- a/client/src/core.h +++ b/client/src/core.h @@ -24,6 +24,7 @@ #include bool core_inputEnabled(void); +void core_updateKeyboardGrab(void); void core_invalidatePointer(bool detectInView); void core_setCursorInView(bool enable); void core_handleGrabEvent(bool active); diff --git a/client/src/keybind.c b/client/src/keybind.c index 6da01f1b..96bca141 100644 --- a/client/src/keybind.c +++ b/client/src/keybind.c @@ -63,6 +63,7 @@ static void bind_input(int sc, void * opaque) core_setCursorInView(false); else g_state.ds->realignPointer(); + core_updateKeyboardGrab(); app_alert( LG_ALERT_INFO,