From 419f68af1999158e85db4b54013c024b4724081c Mon Sep 17 00:00:00 2001 From: Sergio Nonide <60042926+senonide@users.noreply.github.com> Date: Mon, 9 Sep 2024 23:44:02 +0200 Subject: [PATCH] Fix blurry cursor on Wayland at a scale other than 100% (#17496) Closes #13258 Release Notes: - Fixed blurry mouse cursor on wayland when the screen scale is other than 100% Before: ![Screenshot from 2024-09-06 14-38-30](https://github.com/user-attachments/assets/e4553503-ecea-4b53-b80d-43732d34fa62) After: ![Screenshot from 2024-09-06 14-38-56](https://github.com/user-attachments/assets/ce563d3a-2b44-44b9-9f59-f0042609924e) --- .../gpui/src/platform/linux/wayland/client.rs | 3 +- .../gpui/src/platform/linux/wayland/cursor.rs | 33 +++++++++++++++---- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/crates/gpui/src/platform/linux/wayland/client.rs b/crates/gpui/src/platform/linux/wayland/client.rs index 67cd1dcbd43b70..57c43a7e46a0c0 100644 --- a/crates/gpui/src/platform/linux/wayland/client.rs +++ b/crates/gpui/src/platform/linux/wayland/client.rs @@ -476,7 +476,8 @@ impl WaylandClient { .as_ref() .map(|primary_selection_manager| primary_selection_manager.get_device(&seat, &qh, ())); - let mut cursor = Cursor::new(&conn, &globals, 24); + // FIXME: Determine the scaling factor dynamically by the compositor + let mut cursor = Cursor::new(&conn, &globals, 24, 2); handle .insert_source(XDPEventSource::new(&common.background_executor), { diff --git a/crates/gpui/src/platform/linux/wayland/cursor.rs b/crates/gpui/src/platform/linux/wayland/cursor.rs index 6a527650429a4e..ea29eee73c71f4 100644 --- a/crates/gpui/src/platform/linux/wayland/cursor.rs +++ b/crates/gpui/src/platform/linux/wayland/cursor.rs @@ -11,6 +11,7 @@ pub(crate) struct Cursor { theme_name: Option, surface: WlSurface, size: u32, + scale: u32, shm: WlShm, connection: Connection, } @@ -23,7 +24,7 @@ impl Drop for Cursor { } impl Cursor { - pub fn new(connection: &Connection, globals: &Globals, size: u32) -> Self { + pub fn new(connection: &Connection, globals: &Globals, size: u32, scale: u32) -> Self { Self { theme: CursorTheme::load(&connection, globals.shm.clone(), size).log_err(), theme_name: None, @@ -31,6 +32,7 @@ impl Cursor { shm: globals.shm.clone(), connection: connection.clone(), size, + scale, } } @@ -38,14 +40,18 @@ impl Cursor { if let Some(size) = size { self.size = size; } - if let Some(theme) = - CursorTheme::load_from_name(&self.connection, self.shm.clone(), theme_name, self.size) - .log_err() + if let Some(theme) = CursorTheme::load_from_name( + &self.connection, + self.shm.clone(), + theme_name, + self.size * self.scale, + ) + .log_err() { self.theme = Some(theme); self.theme_name = Some(theme_name.to_string()); } else if let Some(theme) = - CursorTheme::load(&self.connection, self.shm.clone(), self.size).log_err() + CursorTheme::load(&self.connection, self.shm.clone(), self.size * self.scale).log_err() { self.theme = Some(theme); self.theme_name = None; @@ -91,9 +97,22 @@ impl Cursor { let (width, height) = buffer.dimensions(); let (hot_x, hot_y) = buffer.hotspot(); - wl_pointer.set_cursor(serial_id, Some(&self.surface), hot_x as i32, hot_y as i32); + let scaled_width = width / self.scale; + let scaled_height = height / self.scale; + let scaled_hot_x = hot_x / self.scale; + let scaled_hot_y = hot_y / self.scale; + + self.surface.set_buffer_scale(self.scale as i32); + + wl_pointer.set_cursor( + serial_id, + Some(&self.surface), + scaled_hot_x as i32, + scaled_hot_y as i32, + ); self.surface.attach(Some(&buffer), 0, 0); - self.surface.damage(0, 0, width as i32, height as i32); + self.surface + .damage(0, 0, scaled_width as i32, scaled_height as i32); self.surface.commit(); } } else {