wayland: Implement cursor-shape-v1 (#11106)

Fixes wrong cursor icons and sizes on KDE 6 (and possibly other
compositors)

Gnome still doesn't support this protocol, so to fix cursor settings
there we'll need to read `gsettings`.

Before:

![image](https://github.com/zed-industries/zed/assets/71973804/f0c3dc1b-2bed-43f7-b579-df6c9c0b547f)

After:

![image](https://github.com/zed-industries/zed/assets/71973804/6de639f9-653d-4896-80ca-b7c69641eded)


Release Notes:

- N/A
This commit is contained in:
apricotbucket28 2024-04-29 20:06:18 -03:00 committed by GitHub
parent 089ea7852d
commit a765535557
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 136 additions and 98 deletions

View file

@ -8,9 +8,7 @@ use wayland_cursor::{CursorImageBuffer, CursorTheme};
pub(crate) struct Cursor {
theme: Option<CursorTheme>,
current_icon_name: Option<String>,
surface: WlSurface,
serial_id: u32,
}
impl Drop for Cursor {
@ -24,65 +22,39 @@ impl Cursor {
pub fn new(connection: &Connection, globals: &Globals, size: u32) -> Self {
Self {
theme: CursorTheme::load(&connection, globals.shm.clone(), size).log_err(),
current_icon_name: None,
surface: globals.compositor.create_surface(&globals.qh, ()),
serial_id: 0,
}
}
pub fn mark_dirty(&mut self) {
self.current_icon_name = None;
}
pub fn set_icon(&mut self, wl_pointer: &WlPointer, serial_id: u32, mut cursor_icon_name: &str) {
if let Some(theme) = &mut self.theme {
let mut buffer: Option<&CursorImageBuffer>;
pub fn set_serial_id(&mut self, serial_id: u32) {
self.serial_id = serial_id;
}
pub fn set_icon(&mut self, wl_pointer: &WlPointer, mut cursor_icon_name: &str) {
let need_update = self
.current_icon_name
.as_ref()
.map_or(true, |current_icon_name| {
current_icon_name != cursor_icon_name
});
if need_update {
if let Some(theme) = &mut self.theme {
let mut buffer: Option<&CursorImageBuffer>;
if let Some(cursor) = theme.get_cursor(&cursor_icon_name) {
buffer = Some(&cursor[0]);
} else if let Some(cursor) = theme.get_cursor("default") {
buffer = Some(&cursor[0]);
cursor_icon_name = "default";
log::warn!(
"Linux: Wayland: Unable to get cursor icon: {}. Using default cursor icon",
cursor_icon_name
);
} else {
buffer = None;
log::warn!("Linux: Wayland: Unable to get default cursor too!");
}
if let Some(buffer) = &mut buffer {
let (width, height) = buffer.dimensions();
let (hot_x, hot_y) = buffer.hotspot();
wl_pointer.set_cursor(
self.serial_id,
Some(&self.surface),
hot_x as i32,
hot_y as i32,
);
self.surface.attach(Some(&buffer), 0, 0);
self.surface.damage(0, 0, width as i32, height as i32);
self.surface.commit();
self.current_icon_name = Some(cursor_icon_name.to_string());
}
if let Some(cursor) = theme.get_cursor(&cursor_icon_name) {
buffer = Some(&cursor[0]);
} else if let Some(cursor) = theme.get_cursor("default") {
buffer = Some(&cursor[0]);
cursor_icon_name = "default";
log::warn!(
"Linux: Wayland: Unable to get cursor icon: {}. Using default cursor icon",
cursor_icon_name
);
} else {
log::warn!("Linux: Wayland: Unable to load cursor themes");
buffer = None;
log::warn!("Linux: Wayland: Unable to get default cursor too!");
}
if let Some(buffer) = &mut buffer {
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);
self.surface.attach(Some(&buffer), 0, 0);
self.surface.damage(0, 0, width as i32, height as i32);
self.surface.commit();
}
} else {
log::warn!("Linux: Wayland: Unable to load cursor themes");
}
}
}