Skip to content

Commit

Permalink
Add cursor grab for web target (#2025)
Browse files Browse the repository at this point in the history
* Add cursor grab

* Update feature matrix, changelog and platform information

* Add proper error propagation

* Remove "expect" from fallible code

    code would crash if handling pointer capture outside of winit on
    every mouse click

    we swallow the error since we could not think of a case where this
    would fail in a way that would want to handle that it fails

* Remove unnecessary implementation comment

Co-authored-by: Will Crichton <wcrichto@cs.stanford.edu>
  • Loading branch information
TotalKrill and willcrichton committed Jan 5, 2022
1 parent 25ff30e commit c5c99d2
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -1,5 +1,6 @@
# Unreleased

- On Web, implement cursor grabbing through the pointer lock API.
- On X11, add mappings for numpad comma, numpad enter, numlock and pause.
- On macOS, fix Pinyin IME input by reverting a change that intended to improve IME.
- On Windows, fix a crash with transparent windows on Windows 11.
Expand Down
2 changes: 1 addition & 1 deletion FEATURES.md
Expand Up @@ -197,7 +197,7 @@ Legend:
|----------------------- | ----- | ---- | ------- | ----------- | ----- | ----- | -------- |
|Mouse events |✔️ |[#63] |✔️ |✔️ |**N/A**|**N/A**|✔️ |
|Mouse set location |✔️ |✔️ |✔️ ||**N/A**|**N/A**|**N/A**|
|Cursor grab |✔️ |[#165] |[#242] |✔️ |**N/A**|**N/A**| |
|Cursor grab |✔️ |[#165] |[#242] |✔️ |**N/A**|**N/A**|✔️ |
|Cursor icon |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|✔️ |
|Touch events |✔️ ||✔️ |✔️ |✔️ |✔️ ||
|Touch pressure |✔️ |||||✔️ ||
Expand Down
14 changes: 14 additions & 0 deletions src/platform_impl/web/web_sys/canvas.rs
Expand Up @@ -89,6 +89,20 @@ impl Canvas {
})
}

pub fn set_cursor_grab(&self, grab: bool) -> Result<(), RootOE> {
if grab {
self.raw().request_pointer_lock();
} else {
let window = web_sys::window()
.ok_or(os_error!(OsError("Failed to obtain window".to_owned())))?;
let document = window
.document()
.ok_or(os_error!(OsError("Failed to obtain document".to_owned())))?;
document.exit_pointer_lock();
}
Ok(())
}

pub fn set_attribute(&self, attribute: &str, value: &str) {
self.common
.raw
Expand Down
8 changes: 5 additions & 3 deletions src/platform_impl/web/web_sys/canvas/pointer_handler.rs
Expand Up @@ -79,9 +79,11 @@ impl PointerHandler {
event::mouse_button(&event),
event::mouse_modifiers(&event),
);
canvas
.set_pointer_capture(event.pointer_id())
.expect("Failed to set pointer capture");

// Error is swallowed here since the error would occur every time the mouse is
// clicked when the cursor is grabbed, and there is probably not a situation where
// this could fail, that we care if it fails.
let _e = canvas.set_pointer_capture(event.pointer_id());
},
));
}
Expand Down
7 changes: 5 additions & 2 deletions src/platform_impl/web/window.rs
Expand Up @@ -207,8 +207,11 @@ impl Window {
}

#[inline]
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
Err(ExternalError::NotSupported(NotSupportedError::new()))
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
self.canvas
.borrow()
.set_cursor_grab(grab)
.map_err(|e| ExternalError::Os(e))
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/window.rs
Expand Up @@ -877,7 +877,7 @@ impl Window {
/// ## Platform-specific
///
/// - **macOS:** This locks the cursor in a fixed location, which looks visually awkward.
/// - **iOS / Android / Web:** Always returns an [`ExternalError::NotSupported`].
/// - **iOS / Android:** Always returns an [`ExternalError::NotSupported`].
#[inline]
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
self.window.set_cursor_grab(grab)
Expand Down

0 comments on commit c5c99d2

Please sign in to comment.