diff --git a/README.md b/README.md index 128089123f..1024178126 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ meson install -C build/ --skip-subprojects * **Super + O** : Decrease FSR sharpness by 1 * **Super + S** : Take screenshot (currently goes to `/tmp/gamescope_$DATE.png`) * **Super + G** : Toggle keyboard grab +* **Super + M** : Toggle mouse grab * **Super + C** : Update clipboard ## Examples diff --git a/src/main.cpp b/src/main.cpp index 220ee15836..b599fbc747 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -71,6 +71,7 @@ const struct option *gamescope_options = (struct option[]){ { "fullscreen", no_argument, nullptr, 'f' }, { "grab", no_argument, nullptr, 'g' }, { "force-grab-cursor", no_argument, nullptr, 0 }, + { "never-grab-cursor", no_argument, nullptr, 0 }, // embedded mode options { "disable-layers", no_argument, nullptr, 0 }, @@ -188,6 +189,7 @@ const char usage[] = " -f, --fullscreen make the window fullscreen\n" " -g, --grab grab the keyboard\n" " --force-grab-cursor always use relative mouse mode instead of flipping dependent on cursor visibility.\n" + " --never-grab-cursor never use relative mouse mode instead of flipping dependent on cursor visibility.\n" "\n" "Embedded mode options:\n" " -O, --prefer-output list of connectors in order of preference\n" @@ -245,6 +247,7 @@ const char usage[] = " Super + O decrease FSR sharpness by 1\n" " Super + S take a screenshot\n" " Super + G toggle keyboard grab\n" + " Super + M toggle mouse grab\n" ""; std::atomic< bool > g_bRun{true}; @@ -260,7 +263,7 @@ int g_nOutputRefresh = 0; bool g_bOutputHDREnabled = false; bool g_bFullscreen = false; -bool g_bForceRelativeMouse = false; +ForceRelativeMouseMode g_forceRelativeMouse = ForceRelativeMouseMode::OFF; bool g_bIsNested = false; bool g_bHeadless = false; @@ -633,7 +636,9 @@ int main(int argc, char **argv) } else if (strcmp(opt_name, "immediate-flips") == 0) { g_nAsyncFlipsEnabled = 1; } else if (strcmp(opt_name, "force-grab-cursor") == 0) { - g_bForceRelativeMouse = true; + g_forceRelativeMouse = ForceRelativeMouseMode::FORCE_ON; + } else if (strcmp(opt_name, "never-grab-cursor") == 0) { + g_forceRelativeMouse = ForceRelativeMouseMode::FORCE_OFF; } else if (strcmp(opt_name, "adaptive-sync") == 0) { s_bInitialWantsVRREnabled = true; } else if (strcmp(opt_name, "expose-wayland") == 0) { @@ -763,7 +768,7 @@ int main(int argc, char **argv) if ( !BIsNested() ) { - g_bForceRelativeMouse = false; + g_forceRelativeMouse = ForceRelativeMouseMode::OFF; } #if HAVE_OPENVR diff --git a/src/main.hpp b/src/main.hpp index 7d8e9f1bee..eee9dddc95 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -43,6 +43,13 @@ enum class GamescopeUpscaleScaler : uint32_t STRETCH, }; +enum class ForceRelativeMouseMode : uint32_t +{ + OFF, + FORCE_OFF, + FORCE_ON, +}; + extern GamescopeUpscaleFilter g_upscaleFilter; extern GamescopeUpscaleScaler g_upscaleScaler; extern GamescopeUpscaleFilter g_wantedUpscaleFilter; diff --git a/src/sdlwindow.cpp b/src/sdlwindow.cpp index 78912e15a5..80c4bcab23 100644 --- a/src/sdlwindow.cpp +++ b/src/sdlwindow.cpp @@ -104,7 +104,7 @@ void updateOutputRefresh( void ) } } -extern bool g_bForceRelativeMouse; +extern ForceRelativeMouseMode g_forceRelativeMouse; static std::string gamescope_str = DEFAULT_TITLE; @@ -163,7 +163,7 @@ void inputSDLThreadRun( void ) g_nOutputHeight = height; } - if ( g_bForceRelativeMouse ) + if ( g_forceRelativeMouse == ForceRelativeMouseMode::FORCE_ON ) { SDL_SetRelativeMouseMode( SDL_TRUE ); bRelativeMouse = true; @@ -265,6 +265,9 @@ void inputSDLThreadRun( void ) g_bFullscreen = !g_bFullscreen; SDL_SetWindowFullscreen( g_SDLWindow, g_bFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0 ); break; + case KEY_M: + sdlwindow_grab( !SDL_GetRelativeMouseMode() ); + break; case KEY_N: g_wantedUpscaleFilter = GamescopeUpscaleFilter::PIXEL; break; @@ -559,7 +562,7 @@ void sdlwindow_grab( bool bGrab ) if ( !BIsSDLSession() ) return; - if ( g_bForceRelativeMouse ) + if ( g_forceRelativeMouse == ForceRelativeMouseMode::FORCE_ON ) return; static bool s_bWasGrabbed = false; @@ -580,7 +583,7 @@ void sdlwindow_cursor(std::shared_ptr> pixels, uint32_t wi if ( !BIsSDLSession() ) return; - if ( g_bForceRelativeMouse ) + if ( g_forceRelativeMouse == ForceRelativeMouseMode::FORCE_ON ) return; { diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp index 7c8d2eeafe..e581d8a97c 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp @@ -671,7 +671,7 @@ constexpr const T& clamp( const T& x, const T& min, const T& max ) return x < min ? min : max < x ? max : x; } -extern bool g_bForceRelativeMouse; +extern ForceRelativeMouseMode g_forceRelativeMouse; bool bSteamCompMgrGrab = false; CommitDoneList_t g_steamcompmgr_xdg_done_commits; @@ -1887,7 +1887,7 @@ bool MouseCursor::getTexture() m_texture = nullptr; // Assume the cursor is fully translucent unless proven otherwise. - bool bNoCursor = true; + bool bNoCursor = g_forceRelativeMouse != ForceRelativeMouseMode::FORCE_OFF; std::shared_ptr> cursorBuffer = nullptr; @@ -1949,7 +1949,7 @@ bool MouseCursor::getTexture() m_imageEmpty = bNoCursor; - if ( !g_bForceRelativeMouse ) + if ( g_forceRelativeMouse == ForceRelativeMouseMode::OFF ) { sdlwindow_grab( m_imageEmpty ); bSteamCompMgrGrab = BIsNested() && m_imageEmpty; @@ -7766,7 +7766,7 @@ steamcompmgr_main(int argc, char **argv) // Reset getopt() state optind = 1; - bSteamCompMgrGrab = BIsNested() && g_bForceRelativeMouse; + bSteamCompMgrGrab = BIsNested() && g_forceRelativeMouse == ForceRelativeMouseMode::FORCE_ON; int o; int opt_index = -1;