mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 18:54:57 +00:00
Merge pull request #5734 from makzumi/fix/wayland-double-cursor
fix(ui): avoid duplicate cursor without Wayland theme
This commit is contained in:
@@ -460,11 +460,12 @@ fn canvas_cursor(app: &mut VectorcraftApp, ui: &Ui, view_info: vectorcraft_engin
|
||||
}
|
||||
Some(hp)
|
||||
if custom
|
||||
&& crate::cursors::paint_glyphs(crate::cursors::HIDES_ONLY_WHEN_KEY, ui.input(|i| i.focused))
|
||||
&& crate::cursors::paint_glyphs(crate::cursors::HIDES_ONLY_WHEN_KEY, ui.input(|i| i.focused), app.services.no_cursor_theme)
|
||||
&& crate::cursors::paint(&painter, c, hp, 1.0 / ui_scale) =>
|
||||
{
|
||||
// No cursor theme (Wayland): the glyph is painted, the system pointer stays (#2450).
|
||||
if crate::cursors::hide_system_pointer(app.services.no_cursor_theme) { egui::CursorIcon::None } else { cursor_icon(c) }
|
||||
// The painted glyph stands in for the hidden system pointer. Without a cursor theme
|
||||
// (Wayland) none is painted: the system pointer can't be hidden there (#2450).
|
||||
egui::CursorIcon::None
|
||||
}
|
||||
_ => cursor_icon(c),
|
||||
}
|
||||
|
||||
@@ -702,23 +702,17 @@ pub fn os_cursors(build: bool, wayland: bool) -> bool {
|
||||
build && !wayland
|
||||
}
|
||||
|
||||
/// Does the canvas hide the system pointer to show a painted tool glyph alone? Not when there is no
|
||||
/// cursor theme on Wayland ([`crate::Services::no_cursor_theme`]): winit sets no pointer then, and a
|
||||
/// hidden one would not come back over the panels (#2450). The system pointer stays beside the glyph.
|
||||
pub fn hide_system_pointer(no_cursor_theme: bool) -> bool {
|
||||
!no_cursor_theme
|
||||
}
|
||||
|
||||
/// Does the window hide the pointer only while it is the key window? macOS does: winit hides it with
|
||||
/// a cursor rect holding a transparent cursor, and macOS applies the rect only in the key window.
|
||||
/// Over a window behind another app or under a sheet, the system pointer shows (#2020).
|
||||
pub const HIDES_ONLY_WHEN_KEY: bool = cfg!(target_os = "macos");
|
||||
|
||||
/// Does the window paint the glyphs over a hidden pointer, `focused` or not? Not where the system
|
||||
/// shows its pointer over a window without the focus ([`HIDES_ONLY_WHEN_KEY`]): the system pointer
|
||||
/// shows alone there.
|
||||
pub fn paint_glyphs(hides_only_when_key: bool, focused: bool) -> bool {
|
||||
focused || !hides_only_when_key
|
||||
/// Does the window paint a glyph over a hidden pointer? Not where it cannot hide the system pointer
|
||||
/// (no cursor theme on Wayland, [`crate::Services::no_cursor_theme`]: winit sets no pointer then,
|
||||
/// and a hidden one would not come back over the panels, #2450), or where the system shows its pointer without the focus
|
||||
/// ([`HIDES_ONLY_WHEN_KEY`]): the system pointer shows alone there.
|
||||
pub fn paint_glyphs(hides_only_when_key: bool, focused: bool, no_cursor_theme: bool) -> bool {
|
||||
!no_cursor_theme && (focused || !hides_only_when_key)
|
||||
}
|
||||
|
||||
/// The cursor bitmaps handed to the OS, by (cursor, pixels per point): each glyph is rasterized
|
||||
|
||||
@@ -387,8 +387,6 @@ fn a_wayland_window_paints_the_tool_cursor() {
|
||||
/// Without a cursor theme the canvas keeps the system pointer visible (#2450).
|
||||
#[test]
|
||||
fn no_cursor_theme_keeps_the_system_pointer() {
|
||||
assert!(!hide_system_pointer(true));
|
||||
assert!(hide_system_pointer(false));
|
||||
let mut app = VectorcraftApp::new(Session::new(), crate::Services { wayland: true, no_cursor_theme: true, ..Default::default() });
|
||||
app.run("file.new", json!({"width": 400, "height": 300})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
@@ -472,9 +470,10 @@ fn wayland_windows_paint_the_glyphs() {
|
||||
|
||||
#[test]
|
||||
fn macos_windows_paint_the_glyphs_only_with_the_focus() {
|
||||
assert!(paint_glyphs(true, true), "macOS with the focus");
|
||||
assert!(!paint_glyphs(true, false), "macOS without the focus: the system pointer shows (#2020)");
|
||||
assert!(paint_glyphs(false, true) && paint_glyphs(false, false), "Wayland, the web: painted with the focus or without");
|
||||
assert!(paint_glyphs(true, true, false), "macOS with the focus");
|
||||
assert!(!paint_glyphs(true, false, false), "macOS without the focus: the system pointer shows (#2020)");
|
||||
assert!(paint_glyphs(false, true, false) && paint_glyphs(false, false, false), "Wayland, the web: painted with the focus or without");
|
||||
assert!(!paint_glyphs(false, true, true), "without a cursor theme, use the system pointer alone");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -150,7 +150,7 @@ pub struct Services {
|
||||
pub wayland: bool,
|
||||
/// On Wayland, no cursor theme can be loaded, so winit sets no pointer and the compositor's
|
||||
/// default one would never come back once the canvas hid it: the canvas keeps the system
|
||||
/// pointer visible next to the tool glyph ([`cursors::hide_system_pointer`], #2450).
|
||||
/// pointer and paints no tool glyph ([`cursors::paint_glyphs`], #2450).
|
||||
pub no_cursor_theme: bool,
|
||||
/// The pen pressure and pen end the host reads from the system itself (desktop Linux under
|
||||
/// X11 and XWayland, macOS and Windows). The canvas uses the pressure when a frame's events carry no touch force,
|
||||
|
||||
Reference in New Issue
Block a user