linux: wayland cursor fixes (#9047)

Release Notes:

- Fixed wayland cursor style handling


In upcoming Gnome 46, cursor icon names are considerably changing. For
example: this commit
74e9b79471
removed/modified a lot of cursor names. Then some of the names were
reintroduced in this commit
6f64dc55dc.
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.
This commit is contained in:
Joel Selvaraj 2024-03-11 10:38:52 -05:00 committed by GitHub
parent f066dd268f
commit 20d5f5e8da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 27 deletions

View File

@ -268,26 +268,30 @@ impl Client for WaylandClient {
}
fn set_cursor_style(&self, style: CursorStyle) {
// Based on cursor names from https://gitlab.gnome.org/GNOME/adwaita-icon-theme (GNOME)
// and https://github.com/KDE/breeze (KDE). Both of them seem to be also derived from
// Web CSS cursor names: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#values
let cursor_icon_name = match style {
CursorStyle::Arrow => "arrow".to_string(),
CursorStyle::IBeam => "text".to_string(),
CursorStyle::Crosshair => "crosshair".to_string(),
CursorStyle::ClosedHand => "grabbing".to_string(),
CursorStyle::OpenHand => "openhand".to_string(),
CursorStyle::PointingHand => "hand".to_string(),
CursorStyle::ResizeLeft => "w-resize".to_string(),
CursorStyle::ResizeRight => "e-resize".to_string(),
CursorStyle::ResizeLeftRight => "ew-resize".to_string(),
CursorStyle::ResizeUp => "n-resize".to_string(),
CursorStyle::ResizeDown => "s-resize".to_string(),
CursorStyle::ResizeUpDown => "ns-resize".to_string(),
CursorStyle::DisappearingItem => "grabbing".to_string(), // todo(linux) - couldn't find equivalent icon in linux
CursorStyle::IBeamCursorForVerticalLayout => "vertical-text".to_string(),
CursorStyle::OperationNotAllowed => "not-allowed".to_string(),
CursorStyle::DragLink => "dnd-link".to_string(),
CursorStyle::DragCopy => "dnd-copy".to_string(),
CursorStyle::ContextualMenu => "context-menu".to_string(),
};
CursorStyle::Arrow => "arrow",
CursorStyle::IBeam => "text",
CursorStyle::Crosshair => "crosshair",
CursorStyle::ClosedHand => "grabbing",
CursorStyle::OpenHand => "grab",
CursorStyle::PointingHand => "pointer",
CursorStyle::ResizeLeft => "w-resize",
CursorStyle::ResizeRight => "e-resize",
CursorStyle::ResizeLeftRight => "ew-resize",
CursorStyle::ResizeUp => "n-resize",
CursorStyle::ResizeDown => "s-resize",
CursorStyle::ResizeUpDown => "ns-resize",
CursorStyle::DisappearingItem => "grabbing", // todo(linux) - couldn't find equivalent icon in linux
CursorStyle::IBeamCursorForVerticalLayout => "vertical-text",
CursorStyle::OperationNotAllowed => "not-allowed",
CursorStyle::DragLink => "alias",
CursorStyle::DragCopy => "copy",
CursorStyle::ContextualMenu => "context-menu",
}
.to_string();
let mut cursor_state = self.state.cursor_state.borrow_mut();
cursor_state.cursor_icon_name = cursor_icon_name;

View File

@ -35,10 +35,26 @@ impl Cursor {
}
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 self.theme.is_ok() {
if let Some(cursor) = self.theme.as_mut().unwrap().get_cursor(&cursor_icon_name) {
let buffer: &CursorImageBuffer = &cursor[0];
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();
@ -53,11 +69,6 @@ impl Cursor {
self.surface.commit();
self.current_icon_name = cursor_icon_name;
} else {
log::warn!(
"Linux: Wayland: Unable to get cursor icon: {}",
cursor_icon_name
);
}
} else {
log::warn!("Linux: Wayland: Unable to load cursor themes");