From cc33212479b5c9e75ff6ceb16f7a817ddf9950f2 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sun, 17 Dec 2023 18:49:45 +0100 Subject: [PATCH] On Web, fix setting cursor icon overriding cursor visibility (#3269) --- CHANGELOG.md | 1 + src/platform_impl/web/cursor.rs | 21 +++++++++++++++++---- src/platform_impl/web/window.rs | 16 ++++++++++++---- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bbde75e..b7bacfef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Unreleased` header. - On X11, fix `Xft.dpi` detection from Xresources. - On Windows, fix consecutive calls to `window.set_fullscreen(Some(Fullscreen::Borderless(None)))` resulting in losing previous window state when eventually exiting fullscreen using `window.set_fullscreen(None)`. - On Web, remove queuing fullscreen request in absence of transient activation. +- On Web, fix setting cursor icon overriding cursor visibility. # 0.29.4 diff --git a/src/platform_impl/web/cursor.rs b/src/platform_impl/web/cursor.rs index 22ae3b24..e2a265a0 100644 --- a/src/platform_impl/web/cursor.rs +++ b/src/platform_impl/web/cursor.rs @@ -1,5 +1,5 @@ use std::{ - cell::RefCell, + cell::{Cell, RefCell}, ops::Deref, rc::{Rc, Weak}, }; @@ -44,6 +44,7 @@ impl WebCustomCursor { document: &Document, style: &Style, previous: SelectedCursor, + cursor_visible: Rc>, ) -> SelectedCursor { let previous = previous.into(); @@ -54,6 +55,7 @@ impl WebCustomCursor { style.clone(), image, previous, + cursor_visible, )), WebCustomCursor::Url { url, @@ -61,7 +63,11 @@ impl WebCustomCursor { hotspot_y, } => { let value = previous.style_with_url(url, *hotspot_x, *hotspot_y); - style.set("cursor", &value); + + if cursor_visible.get() { + style.set("cursor", &value); + } + SelectedCursor::Url { style: value, previous, @@ -200,6 +206,7 @@ impl From for Previous { pub enum CursorImageState { Loading { style: Style, + cursor_visible: Rc>, previous: Previous, hotspot_x: u16, hotspot_y: u16, @@ -219,6 +226,7 @@ impl CursorImageState { style: Style, image: &CursorImage, previous: Previous, + cursor_visible: Rc>, ) -> Rc>> { // Can't create array directly when backed by SharedArrayBuffer. // Adapted from https://github.com/rust-windowing/softbuffer/blob/ab7688e2ed2e2eca51b3c4e1863a5bd7fe85800e/src/web.rs#L196-L223 @@ -261,6 +269,7 @@ impl CursorImageState { let state = Rc::new(RefCell::new(Some(Self::Loading { style, + cursor_visible, previous, hotspot_x: image.hotspot_x, hotspot_y: image.hotspot_y, @@ -305,7 +314,7 @@ impl CursorImageState { }; let mut state = state.borrow_mut(); // Extract old state. - let CursorImageState::Loading { style, previous, hotspot_x, hotspot_y, .. } = state.take().unwrap() else { + let CursorImageState::Loading { style, cursor_visible, previous, hotspot_x, hotspot_y, .. } = state.take().unwrap() else { unreachable!("found invalid state") }; @@ -316,7 +325,11 @@ impl CursorImageState { let data_url = Url::create_object_url_with_blob(&blob).unwrap(); let value = previous.style_with_url(&data_url, hotspot_x, hotspot_y); - style.set("cursor", &value); + + if cursor_visible.get() { + style.set("cursor", &value); + } + *state = Some( CursorImageState::Ready { style: value, diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index 882db237..03990e92 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -13,7 +13,7 @@ use super::r#async::Dispatcher; use super::{backend, monitor::MonitorHandle, EventLoopWindowTarget, Fullscreen}; use web_sys::HtmlCanvasElement; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::collections::VecDeque; use std::rc::Rc; @@ -26,6 +26,7 @@ pub struct Inner { pub window: web_sys::Window, canvas: Rc>, selected_cursor: RefCell, + cursor_visible: Rc>, destroy_fn: Option>, } @@ -55,6 +56,7 @@ impl Window { window: window.clone(), canvas, selected_cursor: Default::default(), + cursor_visible: Rc::new(Cell::new(true)), destroy_fn: Some(destroy_fn), }; @@ -197,7 +199,10 @@ impl Inner { #[inline] pub fn set_cursor_icon(&self, cursor: CursorIcon) { *self.selected_cursor.borrow_mut() = SelectedCursor::Named(cursor); - self.canvas.borrow().style().set("cursor", cursor.name()); + + if self.cursor_visible.get() { + self.canvas.borrow().style().set("cursor", cursor.name()); + } } #[inline] @@ -208,6 +213,7 @@ impl Inner { canvas.document(), canvas.style(), self.selected_cursor.take(), + self.cursor_visible.clone(), ); *self.selected_cursor.borrow_mut() = new_cursor; } @@ -235,12 +241,14 @@ impl Inner { #[inline] pub fn set_cursor_visible(&self, visible: bool) { - if !visible { + if !visible && self.cursor_visible.get() { self.canvas.borrow().style().set("cursor", "none"); - } else { + self.cursor_visible.set(false); + } else if visible && !self.cursor_visible.get() { self.selected_cursor .borrow() .set_style(self.canvas.borrow().style()); + self.cursor_visible.set(true); } }