Skip to content

Commit

Permalink
config/input: add cursor section
Browse files Browse the repository at this point in the history
This should allow users to configure theme and size for the cursor,
as well as automatically set `XCURSOR_THEME` and `XCURSOR_SIZE` env
variables.
  • Loading branch information
kchibisov authored and YaLTeR committed Oct 1, 2023
1 parent 8d443c2 commit d8a511b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 8 deletions.
7 changes: 7 additions & 0 deletions resources/default-config.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ focus-ring {
inactive-color 0.3 0.3 0.3 1.0
}

cursor {
// Change the theme and size of the cursor as well as set the
// `XCURSOR_THEME` and `XCURSOR_SIZE` env variables.
// xcursor-theme "default"
// xcursor-size 24
}

// Uncomment this line to ask the clients to omit their client-side decorations if possible.
// If the client will specifically ask for CSD, the request will be honored.
// prefer-no-csd
Expand Down
28 changes: 28 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub struct Config {
#[knuffel(child, default)]
pub prefer_no_csd: bool,
#[knuffel(child, default)]
pub cursor: Cursor,
#[knuffel(child, default)]
pub binds: Binds,
#[knuffel(child, default)]
pub debug: DebugConfig,
Expand Down Expand Up @@ -152,6 +154,23 @@ impl From<Color> for [f32; 4] {
}
}

#[derive(knuffel::Decode, Debug, PartialEq)]
pub struct Cursor {
#[knuffel(child, unwrap(argument), default = String::from("default"))]
pub xcursor_theme: String,
#[knuffel(child, unwrap(argument), default = 24)]
pub xcursor_size: u8,
}

impl Default for Cursor {
fn default() -> Self {
Self {
xcursor_theme: String::from("default"),
xcursor_size: 24,
}
}
}

#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)]
pub struct Binds(#[knuffel(children)] pub Vec<Bind>);

Expand Down Expand Up @@ -366,6 +385,11 @@ mod tests {
prefer-no-csd
cursor {
xcursor-theme "breeze_cursors"
xcursor-size 16
}
binds {
Mod+T { spawn "alacritty"; }
Mod+Q { close-window; }
Expand Down Expand Up @@ -421,6 +445,10 @@ mod tests {
},
},
prefer_no_csd: true,
cursor: Cursor {
xcursor_theme: String::from("breeze_cursors"),
xcursor_size: 16,
},
binds: Binds(vec![
Bind {
key: Key {
Expand Down
19 changes: 13 additions & 6 deletions src/cursor.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::Read;

Expand All @@ -10,17 +11,22 @@ use smithay::utils::{Physical, Point, Transform};
use xcursor::parser::{parse_xcursor, Image};
use xcursor::CursorTheme;

const CURSOR_SIZE: i32 = 24;
static FALLBACK_CURSOR_DATA: &[u8] = include_bytes!("../resources/cursor.rgba");

pub struct Cursor {
images: Vec<Image>,
size: i32,
cache: HashMap<i32, (TextureBuffer<GlesTexture>, Point<i32, Physical>)>,
}

impl Cursor {
pub fn load() -> Self {
let images = match load_xcursor() {
/// Load the said theme as well as set the `XCURSOR_THEME` and `XCURSOR_SIZE`
/// env variables.
pub fn load(theme: &str, size: u8) -> Self {
env::set_var("XCURSOR_THEME", theme);
env::set_var("XCURSOR_SIZE", size.to_string());

let images = match load_xcursor(theme) {
Ok(images) => images,
Err(err) => {
warn!("error loading xcursor default cursor: {err:?}");
Expand All @@ -40,6 +46,7 @@ impl Cursor {

Self {
images,
size: size as i32,
cache: HashMap::new(),
}
}
Expand All @@ -54,7 +61,7 @@ impl Cursor {
.or_insert_with_key(|scale| {
let _span = tracy_client::span!("create cursor texture");

let size = CURSOR_SIZE * scale;
let size = self.size * scale;

let nearest_image = self
.images
Expand Down Expand Up @@ -86,10 +93,10 @@ impl Cursor {
}
}

fn load_xcursor() -> anyhow::Result<Vec<Image>> {
fn load_xcursor(theme: &str) -> anyhow::Result<Vec<Image>> {
let _span = tracy_client::span!();

let theme = CursorTheme::load("default");
let theme = CursorTheme::load(theme);
let path = theme
.load_icon("default")
.ok_or_else(|| anyhow!("no default icon"))?;
Expand Down
16 changes: 14 additions & 2 deletions src/niri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,18 @@ impl State {
}
};

*self.niri.config.borrow_mut() = config;
let mut old_config = self.niri.config.borrow_mut();

if config.cursor != old_config.cursor {
self.niri.default_cursor =
Cursor::load(&config.cursor.xcursor_theme, config.cursor.xcursor_size);
}

*old_config = config;

// Release the borrow.
drop(old_config);

self.niri.queue_redraw_all();
// FIXME: apply output scale and whatnot.
// FIXME: apply libinput device settings.
Expand Down Expand Up @@ -329,7 +340,8 @@ impl Niri {
.unwrap();
seat.add_pointer();

let default_cursor = Cursor::load();
let default_cursor =
Cursor::load(&config_.cursor.xcursor_theme, config_.cursor.xcursor_size);

let socket_source = ListeningSocketSource::new_auto().unwrap();
let socket_name = socket_source.socket_name().to_os_string();
Expand Down

0 comments on commit d8a511b

Please sign in to comment.