Add support for cursor confinement and lock settings independent of cursor visibility - #353
Open
Acissathar wants to merge 1 commit into
Open
Add support for cursor confinement and lock settings independent of cursor visibility#353Acissathar wants to merge 1 commit into
Acissathar wants to merge 1 commit into
Conversation
Contributor
|
Potential relevant, I think the plan was to switch to SDL at some point but we just never got to it? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds a Confined cursor mode and splits cursor visibility from lock state, inspired by Unity's CursorLockMode + Cursor.visible split. Previously Input.SetCursorVisible(false) mapped straight to GLFW's CursorMode.Disabled, so the only two reachable states were "normal" and "hidden and locked to center" — CursorMode.Hidden was never reachable at all. Now visibility and constraint are independent, so you can hide the cursor but keep it inside the window and draw your own:
Example
Video.Project.4.mp4
Notes
GLFW resolves visibility and constraint from a single input mode, so they can't be set independently. Everything is applied in one place: Locked → Disabled, everything else → Normal/Hidden. Input owns the state and handlers cache nothing — the applied mode is read back from GLFW, which also gives us the transition detection for the delta fix below.
There's no hidden-and-confined mode in GLFW. CURSOR_CAPTURED (3.4) is visible-only and can't confine to a sub-rect, so Confined is a per-frame clamp in DefaultInputHandler.LateUpdate. It runs before the position sample so the delta at a wall reads zero instead of a jump back, and it's skipped while unfocused so it doesn't fight you when alt-tabbing.
Confine bounds come off the lock context stack. GameViewPanel already pushes a PanelLockContext, so confining in the editor holds the cursor to the Game View image rather than the whole editor window. GetLockCenter() now derives from GetConfineBounds() by default, which let PanelLockContext drop its center override entirely.
Fixed a one-frame MouseDelta spike when leaving Locked that I think was pre-existing but is much easier to hit now. GLFW reports unbounded virtual coordinates while Disabled and restores the real position on release, so the cached positions still held the accumulated drift and the next delta was that entire jump. Now resynced on the transition out.
Exiting play mode didn't reset cursor state, so a game that set CursorVisible = false with no lock mode left the editor with a permanently invisible cursor, and Escape didn't help because UnlockCursor() does nothing when the mode is already None. Reset on stop and widened the Escape guard to cover hidden-without-a-mode.
OnCursorLocked now fires for any constraining mode so a confined cursor gets the same "press Escape" prompt. The toast still says "Cursor Locked" for it. We can use the cursor state to change it, but I wasn't sure if that was really meaningful.
Breaking: IInputHandler.SetCursorVisible is replaced by ApplyCursorState(bool, CursorLockMode). Input.SetCursorVisible also loses its miceIndex param since this state is global, not per-device and SetCursorVisible(false) now means hidden-and-free rather than locked. All four samples were relying on the old conflated behaviour to get FPS look and are updated to LockCursor()/UnlockCursor().
Limitations