diff --git a/config/src/config.rs b/config/src/config.rs index 0db0b57f2..031556372 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -606,6 +606,12 @@ pub struct Config { #[serde(default)] pub default_workspace: Option, + + #[serde(default)] + pub xcursor_theme: Option, + + #[serde(default)] + pub xcursor_size: Option, } impl_lua_conversion!(Config); diff --git a/window/src/os/wayland/frame.rs b/window/src/os/wayland/frame.rs index dd90bf49b..cfbf2f4e9 100644 --- a/window/src/os/wayland/frame.rs +++ b/window/src/os/wayland/frame.rs @@ -2,9 +2,10 @@ //! in smithay_client_toolkit 0.11 which is Copyright (c) 2018 Victor Berger //! and provided under the terms of the MIT license. +use crate::os::wayland::pointer::make_theme_manager; use config::{ConfigHandle, RgbColor, WindowFrameConfig}; use smithay_client_toolkit::output::{add_output_listener, with_output_info, OutputListener}; -use smithay_client_toolkit::seat::pointer::{ThemeManager, ThemeSpec, ThemedPointer}; +use smithay_client_toolkit::seat::pointer::{ThemeManager, ThemedPointer}; use smithay_client_toolkit::shm::DoubleMemPool; use smithay_client_toolkit::window::{ButtonState, Frame, FrameRequest, State, WindowState}; use std::cell::RefCell; @@ -544,10 +545,7 @@ impl Frame for ConceptFrame { let (themer, theme_over_surface) = if let Some(theme_manager) = theme_manager { (theme_manager, false) } else { - ( - ThemeManager::init(ThemeSpec::System, compositor.clone(), shm.clone()), - true, - ) + (make_theme_manager(compositor.clone(), shm.clone()), true) }; let inner = Rc::new(RefCell::new(Inner { diff --git a/window/src/os/wayland/pointer.rs b/window/src/os/wayland/pointer.rs index 40bbd681d..4c059cd10 100644 --- a/window/src/os/wayland/pointer.rs +++ b/window/src/os/wayland/pointer.rs @@ -223,6 +223,31 @@ impl PendingMouse { } } +pub fn make_theme_manager( + compositor: Attached, + shm: Attached, +) -> ThemeManager { + let config = config::configuration(); + let name = config + .xcursor_theme + .as_ref() + .map(|s| s.to_string()) + .or_else(|| std::env::var("XCURSOR_THEME").ok()) + .unwrap_or_else(|| "default".to_string()); + let size = match config.xcursor_size { + Some(size) => size, + None => match std::env::var("XCURSOR_SIZE").ok() { + Some(size_str) => size_str.parse().ok(), + None => None, + } + .unwrap_or(24), + }; + + let theme = ThemeSpec::Precise { name: &name, size }; + + ThemeManager::init(theme, compositor, shm) +} + impl PointerDispatcher { pub fn register( seat: &WlSeat, @@ -240,7 +265,7 @@ impl PointerDispatcher { } }); - let themer = ThemeManager::init(ThemeSpec::System, compositor, shm); + let themer = make_theme_manager(compositor, shm); let auto_pointer = themer.theme_pointer(pointer.detach()); let data_device = dev_mgr.get_data_device(seat); diff --git a/window/src/os/x11/cursor.rs b/window/src/os/x11/cursor.rs index ffd331796..79c460c97 100644 --- a/window/src/os/x11/cursor.rs +++ b/window/src/os/x11/cursor.rs @@ -1,6 +1,7 @@ use crate::x11::XConnection; use crate::MouseCursor; use anyhow::{ensure, Context}; +use config::ConfigHandle; use std::collections::HashMap; use std::convert::TryInto; use std::ffi::OsStr; @@ -84,7 +85,11 @@ fn icon_path() -> Vec { std::env::split_paths(&path).map(tilde_expand).collect() } -fn cursor_size(map: &HashMap) -> u32 { +fn cursor_size(xcursor_size: &Option, map: &HashMap) -> u32 { + if let Some(size) = xcursor_size { + return *size; + } + if let Ok(size) = std::env::var("XCURSOR_SIZE") { if let Ok(size) = size.parse::() { return size; @@ -108,7 +113,7 @@ fn cursor_size(map: &HashMap) -> u32 { } impl CursorInfo { - pub fn new(conn: &Rc) -> Self { + pub fn new(config: &ConfigHandle, conn: &Rc) -> Self { let mut size = None; let mut theme = None; let mut pict_format_id = None; @@ -128,8 +133,12 @@ impl CursorInfo { { // 0.5 and later have the required support if (vers.major_version(), vers.minor_version()) >= (0, 5) { - size.replace(cursor_size(&*conn.xrm.borrow())); - theme = conn.xrm.borrow().get("Xcursor.theme").cloned(); + size.replace(cursor_size(&config.xcursor_size, &*conn.xrm.borrow())); + theme = config + .xcursor_theme + .as_ref() + .map(|s| s.to_string()) + .or_else(|| conn.xrm.borrow().get("Xcursor.theme").cloned()); // Locate the Pictformat corresponding to ARGB32 if let Ok(formats) = xcb::render::query_pict_formats(conn.conn()).get_reply() { diff --git a/window/src/os/x11/window.rs b/window/src/os/x11/window.rs index 3c56ee4b3..5a8b47317 100644 --- a/window/src/os/x11/window.rs +++ b/window/src/os/x11/window.rs @@ -858,7 +858,7 @@ impl XWindow { height: height.try_into()?, dpi: conn.default_dpi(), copy_and_paste: CopyAndPaste::default(), - cursors: CursorInfo::new(&conn), + cursors: CursorInfo::new(&config, &conn), config: config.clone(), has_focus: false, last_cursor_position: Rect::default(),