diff --git a/Cargo.toml b/Cargo.toml index f9846b0..74632cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ wayland-protocols = { version = "0.32.2", features = ["client", "staging", "unst wayland-protocols-wlr = { version = "0.3.2", features = ["client"] } wayland-scanner = "0.31.3" xkeysym = "0.2.0" +yaml-rust2 = "0.8.1" zbus = { version = "4.4.0", default-features = false, features = ["tokio"] } [build-dependencies] diff --git a/src/core/button.rs b/src/core/button.rs index dfac21e..b76889c 100644 --- a/src/core/button.rs +++ b/src/core/button.rs @@ -3,6 +3,7 @@ * Copyright (c) 2024, Richard Acayan. All rights reserved. */ +use crate::core::Configuration; use crate::core::Display; use crate::core::Graphics; use crate::core::Layout; @@ -164,7 +165,8 @@ const ANGLE_PARTS: [[usize; 4]; 16] = [ const NO_PRESS: Option = None; impl Button { - pub fn new(mut layout: Layout, mut kbd: K, + pub fn new(cfg: &Configuration, + mut layout: Layout, mut kbd: K, gfx: Arc>>) -> Button { kbd.change_layout(&layout); @@ -179,8 +181,8 @@ impl Button { modifiers: [ModState::Released; MODIFIERS_MAX], timers: VecDeque::with_capacity(PRESSES_MAX), - longpress: Duration::from_millis(600), - repeat: Duration::from_millis(25), + longpress: Duration::from_millis(cfg.longpress_ms()), + repeat: Duration::from_millis(cfg.repeat_ms()), r_square: 0.25, } } diff --git a/src/core/layout.rs b/src/core/layout.rs index 843b988..a854c1a 100644 --- a/src/core/layout.rs +++ b/src/core/layout.rs @@ -3,8 +3,9 @@ * Copyright (c) 2024, Richard Acayan. All rights reserved. */ +use crate::core::Configuration; use crate::core::Keyboard; -use crate::core::button::ModState; +use crate::core::ModState; use crate::core::expat; use std::cmp::Ordering; use std::collections::HashMap; @@ -634,7 +635,7 @@ impl Layout { } } - pub fn load(dir: &Path, filename: &str) -> Result + pub fn load(cfg: &Configuration) -> Result { let mut layout = Layout { rows: Vec::new(), @@ -645,8 +646,10 @@ impl Layout { text_supp: false, }; + let dir = Path::new("/usr/share/unfettered-keyboard/layouts"); + let mut vec = Vec::new(); - let path = dir.join(filename); + let path = dir.join(cfg.layout()); let mut file = File::open(path)?; file.read_to_end(&mut vec)?; diff --git a/src/core/mod.rs b/src/core/mod.rs index 01acac1..2dd41e9 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -4,6 +4,7 @@ */ mod button; +mod config; mod expat; mod graphics; mod layout; @@ -11,6 +12,7 @@ mod layout; pub use self::button::Button; pub use self::button::Keyboard; pub use self::button::ModState; +pub use self::config::Configuration; pub use self::graphics::Display; pub use self::graphics::Graphics; pub use self::layout::Layout; diff --git a/src/ufkbd_gnome.rs b/src/ufkbd_gnome.rs index 6e94c01..a66b3a4 100644 --- a/src/ufkbd_gnome.rs +++ b/src/ufkbd_gnome.rs @@ -7,7 +7,7 @@ mod core; mod dbus; mod wayland; -use crate::core::Layout; +use crate::core::Configuration; use crate::dbus::session; use crate::dbus::osk::OSK0; use crate::wayland::Dispatcher; @@ -15,7 +15,6 @@ use polling::Event; use polling::Events; use polling::Poller; use std::future::pending; -use std::path::Path; use std::sync::Arc; use std::time::Instant; use tokio::task; @@ -44,10 +43,9 @@ async fn main() let (globals, mut queue) = globals::registry_queue_init::(&conn_wl) .expect("Registry required"); - let layouts = Path::new("/usr/share/unfettered-keyboard/layouts"); - let layout = Layout::load(layouts, "latn_qwerty_us.xml") - .expect("Layout should be loadable"); - let mut dispatcher = Dispatcher::new(layout, queue.handle(), &globals).unwrap(); + let config = Configuration::load().unwrap(); + + let mut dispatcher = Dispatcher::new(&config, queue.handle(), &globals).unwrap(); let wl_evt = Event::readable(0); diff --git a/src/ufkbd_sxmo.rs b/src/ufkbd_sxmo.rs index 433809e..5989609 100644 --- a/src/ufkbd_sxmo.rs +++ b/src/ufkbd_sxmo.rs @@ -6,13 +6,12 @@ mod core; mod wayland; -use crate::core::Layout; +use crate::core::Configuration; use crate::wayland::Dispatcher; use polling::Event; use polling::Events; use polling::Poller; use std::mem; -use std::path::Path; use std::time::Instant; use wayland_client::globals; @@ -32,10 +31,9 @@ fn main() let (globals, mut queue) = globals::registry_queue_init::(&conn) .expect("Registry required"); - let layouts = Path::new("/usr/share/unfettered-keyboard/layouts"); - let layout = Layout::load(layouts, "latn_qwerty_us.xml") - .expect("Layout should be loadable"); - let mut dispatcher = Dispatcher::new(layout, queue.handle(), &globals).unwrap(); + let config = Configuration::load().unwrap(); + + let mut dispatcher = Dispatcher::new(&config, queue.handle(), &globals).unwrap(); dispatcher.set_osk(VisibilityManager()); let gfx = dispatcher.graphics(); diff --git a/src/ufkbd_wl.rs b/src/ufkbd_wl.rs index 426155b..b3f472f 100644 --- a/src/ufkbd_wl.rs +++ b/src/ufkbd_wl.rs @@ -6,12 +6,11 @@ mod core; mod wayland; -use crate::core::Layout; +use crate::core::Configuration; use crate::wayland::Dispatcher; use polling::Event; use polling::Events; use polling::Poller; -use std::path::Path; use std::time::Instant; use wayland_client::globals; @@ -31,10 +30,9 @@ fn main() let (globals, mut queue) = globals::registry_queue_init::(&conn) .expect("Registry required"); - let layouts = Path::new("/usr/share/unfettered-keyboard/layouts"); - let layout = Layout::load(layouts, "latn_qwerty_us.xml") - .expect("Layout should be loadable"); - let mut dispatcher = Dispatcher::new(layout, queue.handle(), &globals).unwrap(); + let config = Configuration::load().unwrap(); + + let mut dispatcher = Dispatcher::new(&config, queue.handle(), &globals).unwrap(); let wl_evt = Event::readable(0); diff --git a/src/wayland/dispatcher.rs b/src/wayland/dispatcher.rs index 9f836e8..74b96e6 100644 --- a/src/wayland/dispatcher.rs +++ b/src/wayland/dispatcher.rs @@ -5,6 +5,7 @@ use crate::VisibilityManager; use crate::core::Button; +use crate::core::Configuration; use crate::core::Display; use crate::core::Graphics; use crate::core::Layout; @@ -51,7 +52,7 @@ pub struct Dispatcher { } impl Dispatcher { - pub fn new(layout: Layout, queue: QueueHandle, globals: &GlobalList) -> Result + pub fn new(cfg: &Configuration, queue: QueueHandle, globals: &GlobalList) -> Result { let shm = globals.bind(&queue, 1..=1, ()) .expect("Compositor must implement wl_shm"); @@ -85,16 +86,17 @@ impl Dispatcher { Err(_) => None, }; - let disp = Surface::new(queue.clone(), + let disp = Surface::new(cfg, queue.clone(), &shm, compositor, layer_shell, - frac_scale_man, vper, 185)?; + frac_scale_man, vper)?; let gfx = Graphics::new(disp); let gfx = Mutex::new(gfx); let gfx = Arc::new(gfx); let vk = VirtualKeyboard::new(&queue, &vk_man, &im_man, &seat); - let seat = Seat::new(layout, vk, gfx.clone(), queue.clone(), seat); + let layout = Layout::load(cfg)?; + let seat = Seat::new(cfg, layout, vk, gfx.clone(), queue.clone(), seat); Ok(Dispatcher { seat, diff --git a/src/wayland/seat.rs b/src/wayland/seat.rs index ca31954..8a8a71f 100644 --- a/src/wayland/seat.rs +++ b/src/wayland/seat.rs @@ -4,6 +4,7 @@ */ use crate::core::Button; +use crate::core::Configuration; use crate::core::Display; use crate::core::Graphics; use crate::core::Keyboard; @@ -49,11 +50,12 @@ impl + Dispatch + 'static> Seat { - pub fn new(layout: Layout, kbd: K, gfx: Arc>>, + pub fn new(cfg: &Configuration, + layout: Layout, kbd: K, gfx: Arc>>, queue: QueueHandle, seat: wl_seat::WlSeat) -> Seat { let actions = Vec::new(); - let button = Button::new(layout, kbd, gfx); + let button = Button::new(cfg, layout, kbd, gfx); Seat { seat, diff --git a/src/wayland/surface.rs b/src/wayland/surface.rs index d3867ec..01010c8 100644 --- a/src/wayland/surface.rs +++ b/src/wayland/surface.rs @@ -3,6 +3,7 @@ * Copyright (c) 2024, Richard Acayan. All rights reserved. */ +use crate::core::Configuration; use crate::core::Display; use crate::wayland::Buffer; use crate::wayland::fractional_scale_v1::wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1; @@ -54,16 +55,18 @@ impl + Dispatch + Dispatch + 'static> Surface { - pub fn new(queue: QueueHandle, shm: &WlShm, comp: WlCompositor, + pub fn new(cfg: &Configuration, queue: QueueHandle, + shm: &WlShm, comp: WlCompositor, layer_shell: zwlr_layer_shell_v1::ZwlrLayerShellV1, fsm: Option, - vper: Option, - height: i32) + vper: Option) -> Result, Error> { let buf1 = Buffer::new(queue.clone(), shm, 0)?; let buf2 = Buffer::new(queue.clone(), shm, 1)?; + let height = cfg.wayland_height(); + Ok(Surface { bufs: [buf1, buf2],