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

Implement Cursor Locking and input focus checks for it #9697

Merged
merged 1 commit into from
May 27, 2021

Conversation

Filoppi
Copy link
Contributor

@Filoppi Filoppi commented May 9, 2021

Add mouse cursor lock/capture setting to render widget on Qt (disabled by default):
When clicking on the render widget, the mouse get "trapped" inside of in, making the widget gain what is defined as "Full Focus". The mouse lock area follows the game aspect ratio, so the wiimote cursor won't accidentally get outside of the "listen" range.
There is also a hotkey to release/unlock the mouse, but ALT+TAB (or any window focus loss trigger) also does it.
Also added tooltips explaining the new setting and related ones.

The main advantages of cursor locking are:

  • There is no risk for the OS cursor (which is often bound to the wiimote cursor or any other input) to lose focus of the render widget because of an accidental outer click
  • If cursor locking is enabled and background input is disabled, input will now only be listened to if the mouse is locked within the game window, just like games usually do. This is called "Full Focus", which means the render widget is in the foreground (the topmost in the OS) and that the cursor has been captured by it
  • If cursor hiding is enabled, it will be hidden immediately on mouse capture
  • Also works in "Fullscreen", so if we have a multi monitor set up and Dolphin is full screen on one monitor only (assuming it doesn't have exclusive Fullscreen), the mouse won't be able to escape the render widget anyway
  • Can also lock the cursor in Fullscreen, so if your monitor doesn't have the same aspect ration of a game, your cursor will follow the game aspect ratio without going over it (same applies to a render window of any aspect ratio)

Bug fixes:

  • Fix host render widget HasFocus() check being a bit late compared to the actual event of its focus change, causing inputs that caused a focus loss to be accepted by dolphin, and inputs that caught dolphin's focus to be missed by dolphin
  • "Fix" emulation exit/stop confirmation message box being opened as a child window of the main window even if the render window had focus, causing an annoying and useless change of focus (which is now more relevant due to the new focus checks) (thoroughly tested under every possible dolphin render widget setting. This does not affect how the exit/stop hotkey works in full screen). The cursor is now automatically caught again when the stop confirmation message is closed with a NO.

Additional notes:

  • All of the code is independent by the Qt platform/OS, except the mouse locking itself (the code that "traps" the cursor within the widget). That is only implemented on Windows at the moment, so the Mouse Locking settings are hidden on other platforms and won't have any consequences. Anyone is welcome to implement them on Linux And Mac OS X. Unreal Engine has got an open source implementation of mouse locking on both of these platforms. Android does not use Qt so we don't need any code for the "Full Focus" capture. Mouse capturing is also not implemented in "No GUI" dolphin, so Full Focus just goes alongside the normal focus there.
  • I've had this code for over a year, been using it on my work branches for Audio and Input during the whole time, and I never had any problem. I've been extensively testing every single render widget setting I could find, and things like trying to stop the emulation and fullscreen.
  • The focus checks will be improved even more in my upcoming other input PRs, which for example will include the ability to completely ignore the mouse click down which made dolphin gain focus (as that was the purpose of the user, and they likely did not want that input to be processed by the game). This is something a lot of windowed videogames do as well.
  • Hotkeys do not require "Full Focus" even if Cursor Locking is enabled.

116816729-d185f680-ab6b-11eb-9eca-68fb5fedbf96

"Fixes":

@MayImilae
Copy link
Contributor

Lock Mouse Cursor is disabled by default, right?

@Filoppi
Copy link
Contributor Author

Filoppi commented May 9, 2021

Lock Mouse Cursor is disabled by default, right?

Yes

@JMC47
Copy link
Contributor

JMC47 commented May 19, 2021

This works extremely well in practice with always hide mouse cursor and no matter how hard I tried to break it, I couldn't manage to get out of the window.

@Filoppi Filoppi force-pushed the cursor_locking branch 2 times, most recently from f6d7be9 to 81b4017 Compare May 20, 2021 22:41
Copy link
Contributor

@SirMangler SirMangler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good implementation for locking the cursor and seems to deal with all the issues I've encountered when handling the cursor in a locked area, such as accounting for aspect ratio. You can't really get any better than the OS call ClipCursor. I recommend merging this.

Copy link
Member

@leoetlino leoetlino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes seem sane to me

@JMC47
Copy link
Contributor

JMC47 commented May 27, 2021

I attempted to break this in every way I knew how. Render to Main also tested. Wii and GC games, though I'm not sure why you'd want to lock the cursor in GC games maybe some people use mouse for c-stick.

@JMC47 JMC47 merged commit 45a5c9c into dolphin-emu:master May 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
6 participants