diff --git a/CHANGELOG.md b/CHANGELOG.md index 491adf5142..2db18d0db6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ Unreleased` header. - On Windows, macOS, X11, Wayland and Web, implement setting images as cursors. See the `custom_cursors.rs` example. - **Breaking:** Remove `Window::set_cursor_icon` - - Add `Window::set_cursor` which takes a `CursorIcon` or `CustomCursor` + - Add `WindowBuilder::with_cursor` and `Window::set_cursor` which takes a `CursorIcon` or `CustomCursor` - Add `CustomCursor` - Add `CustomCursor::from_rgba` to allow creating cursor images from RGBA data. - Add `CustomCursorExtWebSys::from_url` to allow loading cursor images from URLs. diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index e09fb54e23..2374ecf07a 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -169,6 +169,11 @@ impl Window { _ => (), }; + match attributes.cursor { + Cursor::Icon(icon) => window_state.set_cursor(icon), + Cursor::Custom(cursor) => window_state.set_custom_cursor(&cursor.inner.0), + } + // Activate the window when the token is passed. if let (Some(xdg_activation), Some(token)) = ( xdg_activation.as_ref(), diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index b701a3e7e0..a31780ff39 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -575,6 +575,8 @@ impl UnownedWindow { leap!(window.set_window_level_inner(window_attrs.window_level)).ignore_error(); } + window.set_cursor(window_attrs.cursor); + // Remove the startup notification if we have one. if let Some(startup) = pl_attribs.activation_token.as_ref() { leap!(xconn.remove_activation_token(xwindow, &startup._token)); diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index f1b51bc01f..e294a951c0 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -518,6 +518,8 @@ impl WinitWindow { } } + this.set_cursor(attrs.cursor); + let delegate = WinitWindowDelegate::new(&this, attrs.fullscreen.0.is_some()); // XXX Send `Focused(false)` right after creating the window delegate, so we won't diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index 04503bc262..650ed49418 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -64,6 +64,7 @@ impl Window { inner.set_maximized(attr.maximized); inner.set_visible(attr.visible); inner.set_window_icon(attr.window_icon); + inner.set_cursor(attr.cursor); let canvas = Rc::downgrade(&inner.canvas); let (dispatcher, runner) = Dispatcher::new(target.runner.main_thread(), inner).unwrap(); diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 7c9ba8c133..cd604b3b2a 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -1225,6 +1225,8 @@ impl<'a, T: 'static> InitData<'a, T> { win.set_content_protected(true); } + win.set_cursor(attributes.cursor); + // Set visible before setting the size to ensure the // attribute is correctly applied. win.set_visible(attributes.visible); diff --git a/src/window.rs b/src/window.rs index 4bb1942cfd..118a73f581 100644 --- a/src/window.rs +++ b/src/window.rs @@ -155,6 +155,7 @@ pub struct WindowAttributes { pub content_protected: bool, pub window_level: WindowLevel, pub active: bool, + pub cursor: Cursor, #[cfg(feature = "rwh_06")] pub(crate) parent_window: SendSyncWrapper>, pub(crate) fullscreen: SendSyncWrapper>, @@ -182,6 +183,7 @@ impl Default for WindowAttributes { preferred_theme: None, resize_increments: None, content_protected: false, + cursor: Cursor::default(), #[cfg(feature = "rwh_06")] parent_window: SendSyncWrapper(None), active: true, @@ -474,6 +476,17 @@ impl WindowBuilder { self } + /// Modifies the cursor icon of the window. + /// + /// The default is [`CursorIcon::Default`]. + /// + /// See [`Window::set_cursor()`] for more details. + #[inline] + pub fn with_cursor(mut self, cursor: impl Into) -> Self { + self.window.cursor = cursor.into(); + self + } + /// Build window with parent window. /// /// The default is `None`.