wayland: Avoid reloading cursor theme on every cursor style change (#32832)
Release Notes: - N/A
This commit is contained in:
parent
c95e2a2f1d
commit
2539d57ac7
2 changed files with 61 additions and 50 deletions
|
@ -537,7 +537,7 @@ impl WaylandClient {
|
|||
XDPEvent::CursorTheme(theme) => {
|
||||
if let Some(client) = client.0.upgrade() {
|
||||
let mut client = client.borrow_mut();
|
||||
client.cursor.set_theme(theme.as_str());
|
||||
client.cursor.set_theme(theme);
|
||||
}
|
||||
}
|
||||
XDPEvent::CursorSize(size) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::Globals;
|
||||
use crate::platform::linux::{DEFAULT_CURSOR_ICON_NAME, log_cursor_icon_warning};
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{Context as _, anyhow};
|
||||
use util::ResultExt;
|
||||
|
||||
use wayland_client::Connection;
|
||||
|
@ -9,75 +9,85 @@ use wayland_client::protocol::{wl_pointer::WlPointer, wl_shm::WlShm};
|
|||
use wayland_cursor::{CursorImageBuffer, CursorTheme};
|
||||
|
||||
pub(crate) struct Cursor {
|
||||
theme: Option<CursorTheme>,
|
||||
theme_name: Option<String>,
|
||||
theme_size: u32,
|
||||
surface: WlSurface,
|
||||
loaded_theme: Option<LoadedTheme>,
|
||||
size: u32,
|
||||
scaled_size: u32,
|
||||
surface: WlSurface,
|
||||
shm: WlShm,
|
||||
connection: Connection,
|
||||
}
|
||||
|
||||
pub(crate) struct LoadedTheme {
|
||||
theme: CursorTheme,
|
||||
name: Option<String>,
|
||||
scaled_size: u32,
|
||||
}
|
||||
|
||||
impl Drop for Cursor {
|
||||
fn drop(&mut self) {
|
||||
self.theme.take();
|
||||
self.loaded_theme.take();
|
||||
self.surface.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
theme_size: size,
|
||||
let mut this = Self {
|
||||
loaded_theme: None,
|
||||
size,
|
||||
scaled_size: size,
|
||||
surface: globals.compositor.create_surface(&globals.qh, ()),
|
||||
shm: globals.shm.clone(),
|
||||
connection: connection.clone(),
|
||||
size,
|
||||
}
|
||||
};
|
||||
this.set_theme_internal(None);
|
||||
this
|
||||
}
|
||||
|
||||
pub fn set_theme(&mut self, theme_name: &str) {
|
||||
if let Some(theme) = CursorTheme::load_from_name(
|
||||
&self.connection,
|
||||
self.shm.clone(),
|
||||
theme_name,
|
||||
self.theme_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.theme_size).log_err()
|
||||
{
|
||||
self.theme = Some(theme);
|
||||
self.theme_name = None;
|
||||
fn set_theme_internal(&mut self, theme_name: Option<String>) {
|
||||
if let Some(loaded_theme) = self.loaded_theme.as_ref() {
|
||||
if loaded_theme.name == theme_name && loaded_theme.scaled_size == self.scaled_size {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_theme_size(&mut self, theme_size: u32) {
|
||||
self.theme = self
|
||||
.theme_name
|
||||
.as_ref()
|
||||
.and_then(|name| {
|
||||
CursorTheme::load_from_name(
|
||||
&self.connection,
|
||||
self.shm.clone(),
|
||||
name.as_str(),
|
||||
theme_size,
|
||||
)
|
||||
.log_err()
|
||||
})
|
||||
.or_else(|| {
|
||||
CursorTheme::load(&self.connection, self.shm.clone(), theme_size).log_err()
|
||||
let result = if let Some(theme_name) = theme_name.as_ref() {
|
||||
CursorTheme::load_from_name(
|
||||
&self.connection,
|
||||
self.shm.clone(),
|
||||
theme_name,
|
||||
self.scaled_size,
|
||||
)
|
||||
} else {
|
||||
CursorTheme::load(&self.connection, self.shm.clone(), self.scaled_size)
|
||||
};
|
||||
if let Some(theme) = result
|
||||
.context("Wayland: Failed to load cursor theme")
|
||||
.log_err()
|
||||
{
|
||||
self.loaded_theme = Some(LoadedTheme {
|
||||
theme,
|
||||
name: theme_name.map(|name| name.to_string()),
|
||||
scaled_size: self.scaled_size,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_theme(&mut self, theme_name: String) {
|
||||
self.set_theme_internal(Some(theme_name));
|
||||
}
|
||||
|
||||
fn set_scaled_size(&mut self, scaled_size: u32) {
|
||||
self.scaled_size = scaled_size;
|
||||
let theme_name = self
|
||||
.loaded_theme
|
||||
.as_ref()
|
||||
.and_then(|loaded_theme| loaded_theme.name.clone());
|
||||
self.set_theme_internal(theme_name);
|
||||
}
|
||||
|
||||
pub fn set_size(&mut self, size: u32) {
|
||||
self.size = size;
|
||||
self.set_theme_size(size);
|
||||
self.set_scaled_size(size);
|
||||
}
|
||||
|
||||
pub fn set_icon(
|
||||
|
@ -87,12 +97,13 @@ impl Cursor {
|
|||
mut cursor_icon_names: &[&str],
|
||||
scale: i32,
|
||||
) {
|
||||
self.set_theme_size(self.size * scale as u32);
|
||||
self.set_scaled_size(self.size * scale as u32);
|
||||
|
||||
let Some(theme) = &mut self.theme else {
|
||||
let Some(loaded_theme) = &mut self.loaded_theme else {
|
||||
log::warn!("Wayland: Unable to load cursor themes");
|
||||
return;
|
||||
};
|
||||
let mut theme = &mut loaded_theme.theme;
|
||||
|
||||
let mut buffer: &CursorImageBuffer;
|
||||
'outer: {
|
||||
|
@ -115,7 +126,7 @@ impl Cursor {
|
|||
log_cursor_icon_warning(anyhow!(
|
||||
"wayland: Unable to fallback on default cursor icon '{}' for theme '{}'",
|
||||
DEFAULT_CURSOR_ICON_NAME,
|
||||
self.theme_name.as_deref().unwrap_or("default")
|
||||
loaded_theme.name.as_deref().unwrap_or("default")
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue