
Release Notes: - Fixed wayland cursor style handling In upcoming Gnome 46, cursor icon names are considerably changing. For example: this commit74e9b79471
removed/modified a lot of cursor names. Then some of the names were reintroduced in this commit6f64dc55dc
. I also tried upcoming KDE Plasma 6. Some of the cursor names are not used commonly between Gnome and KDE. From my analysis, these set of cursor names should be more widely available in both previous and upcoming release of Gnome and KDE. Also, If a cursor style is not available, let's fallback to default cursor style. This avoids scenarios where we get stuck with special cursor styles like IBeam/Resize* because the current cursor style is not available. This will lead to an unpleasant/broken experience. Falling back to default cursor seems to be more acceptable.
78 lines
2.8 KiB
Rust
78 lines
2.8 KiB
Rust
use crate::platform::linux::wayland::WaylandClientState;
|
|
use wayland_backend::client::InvalidId;
|
|
use wayland_client::protocol::wl_compositor::WlCompositor;
|
|
use wayland_client::protocol::wl_pointer::WlPointer;
|
|
use wayland_client::protocol::wl_shm::WlShm;
|
|
use wayland_client::protocol::wl_surface::WlSurface;
|
|
use wayland_client::{Connection, QueueHandle};
|
|
use wayland_cursor::{CursorImageBuffer, CursorTheme};
|
|
|
|
pub(crate) struct Cursor {
|
|
theme: Result<CursorTheme, InvalidId>,
|
|
current_icon_name: String,
|
|
surface: WlSurface,
|
|
serial_id: u32,
|
|
}
|
|
|
|
impl Cursor {
|
|
pub fn new(
|
|
connection: &Connection,
|
|
compositor: &WlCompositor,
|
|
qh: &QueueHandle<WaylandClientState>,
|
|
shm: &WlShm,
|
|
size: u32,
|
|
) -> Self {
|
|
Self {
|
|
theme: CursorTheme::load(&connection, shm.clone(), size),
|
|
current_icon_name: "".to_string(),
|
|
surface: compositor.create_surface(qh, ()),
|
|
serial_id: 0,
|
|
}
|
|
}
|
|
|
|
pub fn set_serial_id(&mut self, serial_id: u32) {
|
|
self.serial_id = serial_id;
|
|
}
|
|
|
|
pub fn set_icon(&mut self, wl_pointer: &WlPointer, cursor_icon_name: String) {
|
|
let mut cursor_icon_name = cursor_icon_name.clone();
|
|
if self.current_icon_name != cursor_icon_name {
|
|
if let Ok(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".to_string();
|
|
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 = cursor_icon_name;
|
|
}
|
|
} else {
|
|
log::warn!("Linux: Wayland: Unable to load cursor themes");
|
|
}
|
|
}
|
|
}
|
|
}
|