mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 15:11:31 +00:00
[client] input: fix focus capture startup
Capture-on-focus could consume the initial focus event before an input provider became available. The focused state then suppressed any later attempt to establish capture. Treat explicit capture as local window state, refresh keyboard ownership on focus and input-policy changes, and preserve pre-ungrab availability for key release. Fall back to the window center when guest cursor geometry is not ready.
This commit is contained in:
@@ -269,9 +269,9 @@ void app_handleFocusEvent(bool focused)
|
|||||||
if (g_state.focused == focused)
|
if (g_state.focused == focused)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_state.focused = focused;
|
g_state.focused = focused;
|
||||||
g_cursor.motionValid = false;
|
g_cursor.motionValid = false;
|
||||||
const bool inputEnabled = core_inputEnabled();
|
const bool inputWasEnabled = core_inputEnabled();
|
||||||
|
|
||||||
// release any imgui buttons/keys if we lost focus
|
// release any imgui buttons/keys if we lost focus
|
||||||
if (!focused && app_isOverlayMode())
|
if (!focused && app_isOverlayMode())
|
||||||
@@ -285,6 +285,15 @@ void app_handleFocusEvent(bool focused)
|
|||||||
core_setGrabQuiet(false);
|
core_setGrabQuiet(false);
|
||||||
core_setCursorInView(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)
|
if (!inputEnabled)
|
||||||
{
|
{
|
||||||
@@ -304,10 +313,6 @@ void app_handleFocusEvent(bool focused)
|
|||||||
if (g_params.minimizeOnFocusLoss)
|
if (g_params.minimizeOnFocusLoss)
|
||||||
g_state.ds->minimize();
|
g_state.ds->minimize();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (g_params.captureOnFocus)
|
|
||||||
core_setGrab(true);
|
|
||||||
|
|
||||||
g_cursor.realign = true;
|
g_cursor.realign = true;
|
||||||
g_state.ds->realignPointer();
|
g_state.ds->realignPointer();
|
||||||
}
|
}
|
||||||
@@ -518,7 +523,8 @@ void app_handleKeyReleaseInternal(int sc)
|
|||||||
{
|
{
|
||||||
if (g_state.escapeAction == -1)
|
if (g_state.escapeAction == -1)
|
||||||
{
|
{
|
||||||
if (!g_state.escapeHelp && lgInput_available() &&
|
if (!g_state.escapeHelp &&
|
||||||
|
(g_cursor.grab || lgInput_available()) &&
|
||||||
!app_isOverlayMode())
|
!app_isOverlayMode())
|
||||||
core_setGrab(!g_cursor.grab);
|
core_setGrab(!g_cursor.grab);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,14 +137,18 @@ bool core_inputEnabled(void)
|
|||||||
((g_cursor.grab && g_params.captureInputOnly) || !g_params.captureInputOnly);
|
((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 inputEnabled = core_inputEnabled();
|
||||||
const bool view = g_cursor.inView && g_params.grabKeyboardOnFocus;
|
/* Explicit capture is local window state and must survive an input provider
|
||||||
const bool automatic = !g_cursor.grab &&
|
* 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;
|
g_cursor.autoCaptureActive && !g_params.captureInputOnly;
|
||||||
const bool active = g_state.focused && core_inputEnabled() &&
|
const bool active = g_state.focused && !app_isOverlayMode() &&
|
||||||
!app_isOverlayMode() && (capture || view || automatic);
|
(capture || (inputEnabled && (view || automatic)));
|
||||||
|
|
||||||
if (active)
|
if (active)
|
||||||
g_state.ds->grabKeyboard();
|
g_state.ds->grabKeyboard();
|
||||||
@@ -162,7 +166,7 @@ static void setAutoCapture(bool active)
|
|||||||
MTRACE("auto capture active=%d old=%d", active,
|
MTRACE("auto capture active=%d old=%d", active,
|
||||||
g_cursor.autoCaptureActive);
|
g_cursor.autoCaptureActive);
|
||||||
g_cursor.autoCaptureActive = active;
|
g_cursor.autoCaptureActive = active;
|
||||||
updateKeyboardGrab();
|
core_updateKeyboardGrab();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void applyView(bool active, bool force)
|
static void applyView(bool active, bool force)
|
||||||
@@ -175,7 +179,7 @@ static void applyView(bool active, bool force)
|
|||||||
|
|
||||||
if (!force && g_cursor.inView == active)
|
if (!force && g_cursor.inView == active)
|
||||||
{
|
{
|
||||||
updateKeyboardGrab();
|
core_updateKeyboardGrab();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +208,7 @@ static void applyView(bool active, bool force)
|
|||||||
g_state.ds->setPointer(LG_POINTER_SQUARE);
|
g_state.ds->setPointer(LG_POINTER_SQUARE);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateKeyboardGrab();
|
core_updateKeyboardGrab();
|
||||||
g_cursor.warpState = WARP_STATE_ON;
|
g_cursor.warpState = WARP_STATE_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,7 +327,7 @@ void core_setGrabQuiet(bool enable)
|
|||||||
g_state.ignoreInput = false;
|
g_state.ignoreInput = false;
|
||||||
g_cursor.grab = true;
|
g_cursor.grab = true;
|
||||||
g_cursor.autoCaptureActive = false;
|
g_cursor.autoCaptureActive = false;
|
||||||
updateKeyboardGrab();
|
core_updateKeyboardGrab();
|
||||||
core_setCursorInView(true);
|
core_setCursorInView(true);
|
||||||
|
|
||||||
/* ensure the local mouse is inside the window before we capture, this fixes
|
/* 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 */
|
* was focused without the cursor being in window already */
|
||||||
if (warpSupport != LG_DS_WARP_NONE)
|
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);
|
const bool valid = util_guestCurToLocal(&local);
|
||||||
MTRACE("grab align valid=%d", valid);
|
MTRACE("grab align valid=%d", valid);
|
||||||
core_warpPointer(local.x, local.y, true);
|
core_warpPointer(local.x, local.y, true);
|
||||||
@@ -345,7 +353,7 @@ void core_setGrabQuiet(bool enable)
|
|||||||
g_cursor.grab = false;
|
g_cursor.grab = false;
|
||||||
g_cursor.autoCaptureActive = g_params.autoCapture &&
|
g_cursor.autoCaptureActive = g_params.autoCapture &&
|
||||||
g_cursor.inView && !g_params.captureInputOnly;
|
g_cursor.inView && !g_params.captureInputOnly;
|
||||||
updateKeyboardGrab();
|
core_updateKeyboardGrab();
|
||||||
|
|
||||||
if (warpSupport == LG_DS_WARP_NONE)
|
if (warpSupport == LG_DS_WARP_NONE)
|
||||||
core_handleMouseAbsolute();
|
core_handleMouseAbsolute();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
bool core_inputEnabled(void);
|
bool core_inputEnabled(void);
|
||||||
|
void core_updateKeyboardGrab(void);
|
||||||
void core_invalidatePointer(bool detectInView);
|
void core_invalidatePointer(bool detectInView);
|
||||||
void core_setCursorInView(bool enable);
|
void core_setCursorInView(bool enable);
|
||||||
void core_handleGrabEvent(bool active);
|
void core_handleGrabEvent(bool active);
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ static void bind_input(int sc, void * opaque)
|
|||||||
core_setCursorInView(false);
|
core_setCursorInView(false);
|
||||||
else
|
else
|
||||||
g_state.ds->realignPointer();
|
g_state.ds->realignPointer();
|
||||||
|
core_updateKeyboardGrab();
|
||||||
|
|
||||||
app_alert(
|
app_alert(
|
||||||
LG_ALERT_INFO,
|
LG_ALERT_INFO,
|
||||||
|
|||||||
Reference in New Issue
Block a user