[client] add input:captureOnly to disable input when not captured

This commit is contained in:
Geoffrey McRae 2021-01-09 18:01:08 +11:00
parent 5e9cfb9033
commit f47c8cb806
4 changed files with 43 additions and 18 deletions

View File

@ -141,6 +141,7 @@ Command line arguments will override any options loaded from the config files.
| input:rawMouse | | no | Use RAW mouse input when in capture mode (good for gaming) | | 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:mouseRedraw | | yes | Mouse movements trigger redraws (ignores FPS minimum) |
| input:autoCapture | | no | Try to keep the mouse captured when needed | | input:autoCapture | | no | Try to keep the mouse captured when needed |
| input:captureOnly | | no | Only enable input via SPICE if in capture mode |
|----------------------------------------------------------------------------------------------------------------------------------------------| |----------------------------------------------------------------------------------------------------------------------------------------------|
|------------------------------------------------------------------------------------------------------------------| |------------------------------------------------------------------------------------------------------------------|

View File

@ -310,6 +310,13 @@ static struct Option options[] =
.type = OPTION_TYPE_BOOL, .type = OPTION_TYPE_BOOL,
.value.x_bool = false .value.x_bool = false
}, },
{
.module = "input",
.name = "captureOnly",
.description = "Only enable input via SPICE if in capture mode",
.type = OPTION_TYPE_BOOL,
.value.x_bool = false
},
// spice options // spice options
{ {
@ -478,6 +485,7 @@ bool config_load(int argc, char * argv[])
params.rawMouse = option_get_bool("input", "rawMouse" ); params.rawMouse = option_get_bool("input", "rawMouse" );
params.mouseRedraw = option_get_bool("input", "mouseRedraw" ); params.mouseRedraw = option_get_bool("input", "mouseRedraw" );
params.autoCapture = option_get_bool("input", "autoCapture" ); params.autoCapture = option_get_bool("input", "autoCapture" );
params.captureInputOnly = option_get_bool("input", "captureOnly" );
params.minimizeOnFocusLoss = option_get_bool("win", "minimizeOnFocusLoss"); params.minimizeOnFocusLoss = option_get_bool("win", "minimizeOnFocusLoss");

View File

@ -100,10 +100,15 @@ static void lgInit()
g_cursor.guest.valid = false; g_cursor.guest.valid = false;
} }
static bool inputEnabled()
{
return params.useSpiceInput && !g_state.ignoreInput &&
((g_cursor.grab && params.captureInputOnly) || !params.captureInputOnly);
}
static void alignToGuest() static void alignToGuest()
{ {
if (!params.useSpiceInput || g_cursor.grab || if (SDL_HasEvent(e_SDLEvent))
SDL_HasEvent(e_SDLEvent))
return; return;
SDL_Event event; SDL_Event event;
@ -390,7 +395,8 @@ static int cursorThread(void * unused)
g_cursor.guest.y = cursor->y; g_cursor.guest.y = cursor->y;
g_cursor.guest.valid = true; g_cursor.guest.valid = true;
if (valid != true) // if the state just became valid
if (valid != true && inputEnabled())
alignToGuest(); alignToGuest();
} }
@ -1085,7 +1091,9 @@ static void handleResizeEvent(unsigned int w, unsigned int h)
g_state.windowCX = w / 2; g_state.windowCX = w / 2;
g_state.windowCY = h / 2; g_state.windowCY = h / 2;
updatePositionInfo(); updatePositionInfo();
alignToGuest();
if (inputEnabled())
alignToGuest();
} }
static void handleWindowLeave() static void handleWindowLeave()
@ -1093,7 +1101,7 @@ static void handleWindowLeave()
g_cursor.inWindow = false; g_cursor.inWindow = false;
g_cursor.inView = false; g_cursor.inView = false;
if (!params.useSpiceInput) if (!inputEnabled())
return; return;
if (!params.alwaysShowCursor) if (!params.alwaysShowCursor)
@ -1105,7 +1113,7 @@ static void handleWindowLeave()
static void handleWindowEnter() static void handleWindowEnter()
{ {
g_cursor.inWindow = true; g_cursor.inWindow = true;
if (!params.useSpiceInput) if (!inputEnabled())
return; return;
g_cursor.draw = true; g_cursor.draw = true;
@ -1144,16 +1152,20 @@ static void keyboardUngrab()
static void setGrab(bool enable) static void setGrab(bool enable)
{ {
/* we always do this so that at init the cursor is in the right state */
if (params.captureInputOnly && params.hideMouse)
SDL_ShowCursor(enable ? SDL_DISABLE : SDL_ENABLE);
if (g_cursor.grab == enable) if (g_cursor.grab == enable)
return; return;
g_cursor.grab = enable; g_cursor.grab = enable;
if (g_state.wminfo.subsystem != SDL_SYSWM_X11) if (g_state.wminfo.subsystem != SDL_SYSWM_X11)
SDL_SetWindowGrab(g_state.window, g_cursor.grab); SDL_SetWindowGrab(g_state.window, enable);
else else
{ {
if (g_cursor.grab) if (enable)
{ {
XGrabPointer( XGrabPointer(
g_state.wminfo.info.x11.display, g_state.wminfo.info.x11.display,
@ -1187,6 +1199,10 @@ static void setGrab(bool enable)
} }
} }
// if exiting capture when input on capture only, we want to show the cursor
if (!enable && (params.captureInputOnly || !params.hideMouse))
alignToGuest();
if (g_cursor.grab) if (g_cursor.grab)
g_cursor.inView = true; g_cursor.inView = true;
@ -1294,7 +1310,7 @@ int eventFilter(void * userdata, SDL_Event * event)
/* support movements via XInput2 */ /* support movements via XInput2 */
case GenericEvent: case GenericEvent:
{ {
if (!params.useSpiceInput || g_state.ignoreInput) if (!inputEnabled())
break; break;
XGenericEventCookie *cookie = (XGenericEventCookie*)&xe.xcookie; XGenericEventCookie *cookie = (XGenericEventCookie*)&xe.xcookie;
@ -1417,7 +1433,7 @@ int eventFilter(void * userdata, SDL_Event * event)
case FocusIn: case FocusIn:
g_state.focused = true; g_state.focused = true;
if (!params.useSpiceInput) if (!inputEnabled())
break; break;
if (xe.xfocus.mode == NotifyNormal || if (xe.xfocus.mode == NotifyNormal ||
@ -1428,7 +1444,7 @@ int eventFilter(void * userdata, SDL_Event * event)
case FocusOut: case FocusOut:
g_state.focused = false; g_state.focused = false;
if (!params.useSpiceInput) if (!inputEnabled())
break; break;
if (xe.xfocus.mode == NotifyNormal || if (xe.xfocus.mode == NotifyNormal ||
@ -1476,7 +1492,7 @@ int eventFilter(void * userdata, SDL_Event * event)
break; break;
} }
if (g_state.ignoreInput || !params.useSpiceInput) if (!inputEnabled())
break; break;
if (params.ignoreWindowsKeys && if (params.ignoreWindowsKeys &&
@ -1525,7 +1541,7 @@ int eventFilter(void * userdata, SDL_Event * event)
g_state.escapeActive = false; g_state.escapeActive = false;
} }
if (g_state.ignoreInput || !params.useSpiceInput) if (!inputEnabled())
break; break;
// avoid sending key up events when we didn't send a down // avoid sending key up events when we didn't send a down
@ -1551,7 +1567,7 @@ int eventFilter(void * userdata, SDL_Event * event)
} }
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
if (g_state.ignoreInput || !params.useSpiceInput || !g_cursor.inView) if (!inputEnabled() || !g_cursor.inView)
break; break;
if ( if (
@ -1566,7 +1582,7 @@ int eventFilter(void * userdata, SDL_Event * event)
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
{ {
if (g_state.ignoreInput || !params.useSpiceInput || !g_cursor.inView) if (!inputEnabled() || !g_cursor.inView)
break; break;
int button = event->button.button; int button = event->button.button;
@ -1583,7 +1599,7 @@ int eventFilter(void * userdata, SDL_Event * event)
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
{ {
if (g_state.ignoreInput || !params.useSpiceInput || !g_cursor.inView) if (!inputEnabled() || !g_cursor.inView)
break; break;
int button = event->button.button; int button = event->button.button;
@ -2049,8 +2065,7 @@ static int lg_run()
* we start checking for a valid session */ * we start checking for a valid session */
SDL_WaitEventTimeout(NULL, 200); SDL_WaitEventTimeout(NULL, 200);
if (params.captureOnStart) setGrab(params.captureOnStart);
setGrab(true);
uint32_t udataSize; uint32_t udataSize;
KVMFR *udata; KVMFR *udata;

View File

@ -141,6 +141,7 @@ struct AppParams
bool mouseSmoothing; bool mouseSmoothing;
bool rawMouse; bool rawMouse;
bool autoCapture; bool autoCapture;
bool captureInputOnly;
}; };
struct CBRequest struct CBRequest