Fix cursors on some GNOME installations (#12914)

This PR adds support for `org.gnome.desktop.interface`'s `cursor-theme`
setting on Wayland. This should fix cursors not showing up on some GNOME
installs. This PR also adds the wiring to watch the current cursor theme
value.

Thanks to @apricotbucket28 for helping debug the issue.

Release Notes:

- N/A
This commit is contained in:
Mikayla Maki 2024-06-11 17:39:25 -07:00 committed by GitHub
parent 4cb8d6f40e
commit ab41eddd8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 145 additions and 30 deletions

View file

@ -1,14 +1,18 @@
use crate::Globals;
use util::ResultExt;
use wayland_client::protocol::wl_pointer::WlPointer;
use wayland_client::protocol::wl_surface::WlSurface;
use wayland_client::protocol::{wl_pointer::WlPointer, wl_shm::WlShm};
use wayland_client::Connection;
use wayland_cursor::{CursorImageBuffer, CursorTheme};
pub(crate) struct Cursor {
theme: Option<CursorTheme>,
theme_name: Option<String>,
surface: WlSurface,
size: u32,
shm: WlShm,
connection: Connection,
}
impl Drop for Cursor {
@ -22,10 +26,49 @@ impl Cursor {
pub fn new(connection: &Connection, globals: &Globals, size: u32) -> Self {
Self {
theme: CursorTheme::load(&connection, globals.shm.clone(), size).log_err(),
theme_name: None,
surface: globals.compositor.create_surface(&globals.qh, ()),
shm: globals.shm.clone(),
connection: connection.clone(),
size,
}
}
pub fn set_theme(&mut self, theme_name: &str, size: Option<u32>) {
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()
{
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()
{
self.theme = Some(theme);
self.theme_name = None;
}
}
pub fn set_size(&mut self, size: u32) {
self.size = size;
self.theme = self
.theme_name
.as_ref()
.and_then(|name| {
CursorTheme::load_from_name(
&self.connection,
self.shm.clone(),
name.as_str(),
self.size,
)
.log_err()
})
.or_else(|| CursorTheme::load(&self.connection, self.shm.clone(), self.size).log_err());
}
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>;