Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

steamcompmgr: Add an option to disable automatic relative mouse #1098

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

luk1337
Copy link

@luk1337 luk1337 commented Jan 13, 2024

Additionally, make relative mode togglable during runtime by Super+M key
bind.

@luk1337
Copy link
Author

luk1337 commented Jan 13, 2024

Let me know if this is acceptable at all and if I should perhaps convert it to option instead.

@misyltoad
Copy link
Collaborator

Launch option would be preferable

@luk1337
Copy link
Author

luk1337 commented Jan 13, 2024

Launch option would be preferable

What would you name such an option, and how would you describe it in --help?

@luk1337
Copy link
Author

luk1337 commented Jan 13, 2024

Launch option would be preferable

What would you name such an option, and how would you describe it in --help?

Would something like this be ok?

"  --never-grab-cursor            never use relative mouse mode instead of flipping dependent on cursor visibility.\n"

@luk1337
Copy link
Author

luk1337 commented Jan 13, 2024

Anyway, here's an alternative patch in case an option is preferred here.

diff --git a/src/main.cpp b/src/main.cpp
index 220ee15..4c99038 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"
@@ -260,7 +262,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 +635,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 +767,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 7d8e9f1..eee9ddd 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 78912e1..83929c2 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;
@@ -559,7 +559,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 +580,7 @@ void sdlwindow_cursor(std::shared_ptr<std::vector<uint32_t>> 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 7c8d2ee..e581d8a 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<std::vector<uint32_t>> 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;

@luk1337 luk1337 changed the title Add env variable to force disable cursor grabbing steamcompmgr: Add env variable to force disable cursor grabbing Jan 13, 2024
@R1kaB3rN
Copy link

In the above patch, I believe you meant to write --disable-cursor instead of --disable-disable-cursor. Also, out of curiosity, what VNs specifically did you have in mind with this patch?

@luk1337
Copy link
Author

luk1337 commented Jan 14, 2024

In the above patch, I believe you meant to write --disable-cursor instead of --disable-disable-cursor.

I fixed the diff.

Also, out of curiosity, what VNs specifically did you have in mind with this patch?

I'm using this patch with Symphonic Rain, since it's disabling OS cursor and drawing its own (a music note seen in the screenshot below).
Screenshot_20240114_203629

@l12436
Copy link

l12436 commented Jan 15, 2024

I was wonder if we can also change this through the hotkey, there are maybe some situation that I want to grab the mouse and sometimes not. especially with steam

@l12436
Copy link

l12436 commented Jan 15, 2024

It seems missing modify in main.cpp:74. command line show it did not recognize the --never-grab-cursor

@luk1337
Copy link
Author

luk1337 commented Jan 15, 2024

I was wonder if we can also change this through the hotkey, there are maybe some situation that I want to grab the mouse and sometimes not. especially with steam

Something like this seems to work:

diff --git a/src/sdlwindow.cpp b/src/sdlwindow.cpp
index 83929c2..824daa4 100644
--- a/src/sdlwindow.cpp
+++ b/src/sdlwindow.cpp
@@ -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;

It seems missing modify in main.cpp:74. command line show it did not recognize the --never-grab-cursor

Fixed ^^

@l12436
Copy link

l12436 commented Jan 16, 2024

Remember add hotkey describe in the help :)

by the way, It work great on some app as well, I have using waydroid on weston and gamescope, it always hide cursor on some situation. this will help to show cursor on host.

@luk1337
Copy link
Author

luk1337 commented Jan 16, 2024

Sure, I can do all that, but can someone with merge perms tell me what I actually would have to do to get this feature in?

--option + hotkey is ok? If so, I'll force push the branch with that and document it in --help+README.

@misyltoad
Copy link
Collaborator

Sure, go for it

@luk1337 luk1337 force-pushed the luk/cursor_no_grab branch 2 times, most recently from 0dca87c to d8350ca Compare January 20, 2024 09:20
@luk1337 luk1337 changed the title steamcompmgr: Add env variable to force disable cursor grabbing steamcompmgr: Add an option to disable automatic relative mouse Jan 20, 2024
@luk1337
Copy link
Author

luk1337 commented Jan 20, 2024

Sure, go for it

done ^^

Additionally, make relative mode togglable during runtime by Super+M key
bind.
@l12436
Copy link

l12436 commented Jan 21, 2024

I have benefit from this patch, there are some game will has no cursor when capture the mouse, but if I force disable the grab mouse, the camera no longer work. This patch is helping me to switch between these two situation.

@l12436
Copy link

l12436 commented Jan 21, 2024

I found some weird of Meta+M, I have the game that original will auto detect the cursor and determine it will show or not. after I add --never-grab-cursor as default. the cursor did not appear even menu is shown. I need to manually release the grab mouse.
I mean gamescope default is auto detect. but If i switch the grab mouse by using meta + M, it seems break the default behavior

Is there any possble that could switch the behavior of code by Meta+M not just sdl grab mouse, instead return the the behavior that program did not add --never-grab-cursor

I tested on "Little Witch Nobeta" in steam with desktop enabled.

@luk1337
Copy link
Author

luk1337 commented Jan 21, 2024

Replying to #1098 (comment)

Can't you just start a game w/o any arguments and use super+m whenever you need to grab/ungrab?

@luk1337
Copy link
Author

luk1337 commented Jan 21, 2024

Replying to #1098 (comment)

Additionally, I guess you could apply this diff:

diff --git a/src/sdlwindow.cpp b/src/sdlwindow.cpp
index 80c4bca..5f55cac 100644
--- a/src/sdlwindow.cpp
+++ b/src/sdlwindow.cpp
@@ -565,13 +565,9 @@ void sdlwindow_grab( bool bGrab )
 	if ( g_forceRelativeMouse == ForceRelativeMouseMode::FORCE_ON )
 		return;
 
-	static bool s_bWasGrabbed = false;
-
-	if ( s_bWasGrabbed == bGrab )
+	if ( bGrab == SDL_GetRelativeMouseMode() )
 		return;
 
-	s_bWasGrabbed = bGrab;
-
 	SDL_Event event;
 	event.type = g_unSDLUserEventID + USER_EVENT_GRAB;
 	event.user.code = bGrab ? 1 : 0;

@l12436
Copy link

l12436 commented Jan 22, 2024

Replying to #1098 (comment)

Can't you just start a game w/o any arguments and use super+m whenever you need to grab/ungrab?

OK so you you mean not add --never-grab-mouse, just click super+m will also work ?
I have try that, It action weird so I though It is not work? maybe I could tested again.

--- update ----
I have tried that, It is working as expect if not given --never-grab-cursor as default

@l12436
Copy link

l12436 commented Jan 22, 2024

Replying to #1098 (comment)

This seems work same as not applied. If you has tested and it working, I may test again later.

@l12436
Copy link

l12436 commented Jan 23, 2024

I accidentally found that this patch also solve one of my special usage of gamescope. I used to use weston to run waydroid. To stretch the screen I use the gamescope to do it, but it will always no sending the mouse when I use nomachine to remote control it. It seems if I using --never-grab-mouse. the mouse working again.

@l12436
Copy link

l12436 commented Feb 17, 2024

This MR need to rebase to master, although I have rebase by myself. I am now using this feature.

---update----
master has issue that mouse will not working at all. so I stick with old implement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants