diff --git a/Cargo.lock b/Cargo.lock index 586ae7abc..66a7dc331 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -324,7 +324,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -481,6 +481,7 @@ dependencies = [ "bitflags 1.3.2", "bytemuck", "calloop", + "cosmic-config", "cosmic-protocols", "edid-rs", "egui", @@ -524,9 +525,10 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "atomicwrites", + "calloop", "cosmic-config-derive", "dirs 5.0.1", "iced_futures", @@ -538,7 +540,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "quote", "syn 1.0.109", @@ -578,7 +580,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "anyhow", "cosmic-config", @@ -709,7 +711,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -720,7 +722,7 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -751,7 +753,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -829,7 +831,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -1372,7 +1374,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -1733,7 +1735,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.22", + "syn 2.0.27", "unic-langid", ] @@ -1753,7 +1755,7 @@ dependencies = [ [[package]] name = "iced" version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "iced_core", "iced_futures", @@ -1766,7 +1768,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "bitflags 1.3.2", "instant", @@ -1779,7 +1781,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.6.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "futures", "iced_core", @@ -1791,7 +1793,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.8.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1808,7 +1810,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -1820,7 +1822,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "iced_core", "iced_futures", @@ -1830,7 +1832,7 @@ dependencies = [ [[package]] name = "iced_style" version = "0.8.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "iced_core", "once_cell", @@ -1840,7 +1842,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "bytemuck", "cosmic-text", @@ -1858,7 +1860,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.10.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1879,7 +1881,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "iced_renderer", "iced_runtime", @@ -2174,7 +2176,7 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic/?rev=42d7baf#42d7baf0d5cb14ab476120be9dfcaea9bd1d0be4" +source = "git+https://github.com/pop-os/libcosmic/?rev=4895b0c#4895b0c9bda9e46fc7db173e239d155dac957186" dependencies = [ "apply", "cosmic-config", @@ -2193,6 +2195,7 @@ dependencies = [ "lazy_static", "palette", "slotmap", + "thiserror", "tracing", ] @@ -2921,7 +2924,7 @@ checksum = "3c02bfa6b3ba8af5434fa0531bf5701f750d983d4260acd6867faca51cdc4484" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -3008,7 +3011,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -3043,7 +3046,7 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -3209,9 +3212,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5907a1b7c277254a8b15170f6e7c97cfa60ee7872a3217663bb81151e48184bb" dependencies = [ "proc-macro2", ] @@ -3494,7 +3497,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.22", + "syn 2.0.27", "walkdir", ] @@ -3637,7 +3640,7 @@ checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -3957,9 +3960,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.22" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -4001,22 +4004,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -4190,7 +4193,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", ] [[package]] @@ -4531,7 +4534,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", "wasm-bindgen-shared", ] @@ -4565,7 +4568,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.27", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index 02227c8e2..f9cc84309 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,9 +30,10 @@ ron = "0.7" libsystemd = { version = "0.5", optional = true } wayland-backend = "0.1.0" wayland-scanner = "0.30.0" +cosmic-config = { git = "https://github.com/pop-os/libcosmic/", rev = "4895b0c", features = ["calloop"] } cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] } -libcosmic = { git = "https://github.com/pop-os/libcosmic/", rev = "42d7baf", default-features = false } -iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic/", rev = "42d7baf" } +libcosmic = { git = "https://github.com/pop-os/libcosmic/", rev = "4895b0c", default-features = false } +iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic/", rev = "4895b0c" } tiny-skia = "0.9" ordered-float = "3.0" glow = "0.11.2" diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index f857539ef..b284630f0 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -57,7 +57,7 @@ use smithay::{ control::{connector, crtc, Device as ControlDevice, ModeTypeFlags}, Device as _, }, - input::Libinput, + input::{self, Libinput}, nix::{fcntl::OFlag, sys::stat::dev_t}, wayland_protocols::wp::{ linux_dmabuf::zv1::server::zwp_linux_dmabuf_feedback_v1, @@ -97,6 +97,7 @@ const MIN_RENDER_TIME: Duration = Duration::from_millis(3); #[derive(Debug)] pub struct KmsState { devices: HashMap, + pub input_devices: HashMap, pub api: GpuManager>, pub primary: DrmNode, session: LibSeatSession, @@ -171,8 +172,15 @@ pub fn init_backend( let libinput_event_source = event_loop .handle() .insert_source(libinput_backend, move |mut event, _, data| { - if let &mut InputEvent::DeviceAdded { ref mut device } = &mut event { + if let InputEvent::DeviceAdded { ref mut device } = &mut event { data.state.common.config.read_device(device); + data.state + .backend + .kms() + .input_devices + .insert(device.name().into(), device.clone()); + } else if let InputEvent::DeviceRemoved { device } = &event { + data.state.backend.kms().input_devices.remove(device.name()); } data.state.process_input_event(event, true); for output in data.state.common.shell.outputs() { @@ -362,6 +370,7 @@ pub fn init_backend( primary, session, devices: HashMap::new(), + input_devices: HashMap::new(), }); // Create relative pointer global diff --git a/src/config/mod.rs b/src/config/mod.rs index 832724a94..5b56bad78 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -5,6 +5,7 @@ use crate::{ state::{BackendData, Data, State}, wayland::protocols::output_configuration::OutputConfigurationState, }; +use cosmic_config::{ConfigGet, ConfigSet}; use serde::{Deserialize, Serialize}; use smithay::input::Seat; pub use smithay::{ @@ -34,6 +35,9 @@ pub use self::types::*; pub struct Config { pub static_conf: StaticConfig, pub dynamic_conf: DynamicConfig, + pub config: cosmic_config::Config, + pub xkb: XkbConfig, + pub input_devices: HashMap, } #[derive(Debug, Deserialize)] @@ -65,7 +69,6 @@ pub enum WorkspaceLayout { #[derive(Debug)] pub struct DynamicConfig { outputs: (Option, OutputsConfig), - inputs: (Option, InputsConfig), } #[derive(Debug, Deserialize, Serialize)] @@ -152,18 +155,22 @@ impl OutputConfig { } } -#[derive(Debug, Deserialize, Serialize)] -pub struct InputsConfig { - xkb: XkbConfig, - devices: HashMap, -} - impl Config { - pub fn load() -> Config { + pub fn load(loop_handle: &LoopHandle<'_, Data>) -> Config { + let config = cosmic_config::Config::new("com.system76.CosmicComp", 1).unwrap(); + let source = cosmic_config::calloop::ConfigWatchSource::new(&config).unwrap(); + loop_handle + .insert_source(source, |(config, keys), (), shared_data| { + config_changed(config, keys, &mut shared_data.state); + }) + .expect("Failed to add cosmic-config to the event loop"); let xdg = xdg::BaseDirectories::new().ok(); Config { static_conf: Self::load_static(xdg.as_ref()), dynamic_conf: Self::load_dynamic(xdg.as_ref()), + xkb: get_config(&config, "xkb-config"), + input_devices: get_config(&config, "input-devices"), + config, } } @@ -218,12 +225,8 @@ impl Config { xdg.and_then(|base| base.place_state_file("cosmic-comp/outputs.ron").ok()); let outputs = Self::load_outputs(&output_path); - let input_path = xdg.and_then(|base| base.place_state_file("cosmic-comp/inputs.ron").ok()); - let inputs = Self::load_inputs(&input_path); - DynamicConfig { outputs: (output_path, outputs), - inputs: (input_path, inputs), } } @@ -247,27 +250,6 @@ impl Config { } } - fn load_inputs(path: &Option) -> InputsConfig { - if let Some(path) = path.as_ref() { - if path.exists() { - match ron::de::from_reader(OpenOptions::new().read(true).open(path).unwrap()) { - Ok(config) => return config, - Err(err) => { - warn!(?err, "Failed to read input_config, resetting.."); - if let Err(err) = std::fs::remove_file(path) { - error!(?err, "Failed to remove input_config."); - } - } - }; - } - } - - InputsConfig { - xkb: XkbConfig::default(), - devices: HashMap::new(), - } - } - pub fn read_outputs( &mut self, output_state: &mut OutputConfigurationState, @@ -422,17 +404,23 @@ impl Config { } pub fn xkb_config(&self) -> XkbConfig { - self.dynamic_conf.inputs().xkb.clone() + self.xkb.clone() } pub fn read_device(&mut self, device: &mut InputDevice) { use std::collections::hash_map::Entry; - let mut inputs = self.dynamic_conf.inputs_mut(); - match inputs.devices.entry(device.name().into()) { + let mut config_changed = false; + match self.input_devices.entry(device.name().into()) { Entry::Occupied(entry) => entry.get().update_device(device), Entry::Vacant(entry) => { entry.insert(InputConfig::for_device(device)); + config_changed = true; + } + } + if config_changed { + if let Err(err) = self.config.set("input-devices", &self.input_devices) { + error!("Failed to write config 'input-devices': {:?}", err); } } } @@ -483,12 +471,45 @@ impl DynamicConfig { pub fn outputs_mut<'a>(&'a mut self) -> PersistenceGuard<'a, OutputsConfig> { PersistenceGuard(self.outputs.0.clone(), &mut self.outputs.1) } +} - pub fn inputs(&self) -> &InputsConfig { - &self.inputs.1 - } +fn get_config( + config: &cosmic_config::Config, + key: &str, +) -> T { + config.get(key).unwrap_or_else(|err| { + error!("Failed to read config '{}': {:?}", key, err); + T::default() + }) +} - pub fn inputs_mut<'a>(&'a mut self) -> PersistenceGuard<'a, InputsConfig> { - PersistenceGuard(self.inputs.0.clone(), &mut self.inputs.1) +fn config_changed(config: cosmic_config::Config, keys: Vec, state: &mut State) { + for key in &keys { + match key.as_str() { + "xkb-config" => { + let value = get_config::(&config, "xkb-config"); + for seat in state.common.seats().cloned().collect::>().iter() { + if let Some(keyboard) = seat.get_keyboard() { + if let Err(err) = keyboard.set_xkb_config(state, (&value).into()) { + warn!(?err, "Failed to load provided xkb config.",); + // TODO Revert to default? + } + } + } + state.common.config.xkb = value; + } + "input-devices" => { + let value = get_config::>(&config, "input-devices"); + if let BackendData::Kms(ref mut kms_state) = &mut state.backend { + for (name, device) in kms_state.input_devices.iter_mut() { + if let Some(input_config) = value.get(name) { + input_config.update_device(device); + } + } + } + state.common.config.input_devices = value; + } + _ => {} + } } } diff --git a/src/state.rs b/src/state.rs index 4ec871191..9a983d993 100644 --- a/src/state.rs +++ b/src/state.rs @@ -274,7 +274,7 @@ impl State { .unwrap(); let clock = Clock::new().expect("Failed to initialize clock"); - let config = Config::load(); + let config = Config::load(&handle); let compositor_state = CompositorState::new::(dh); let data_device_state = DataDeviceState::new::(dh); let dmabuf_state = DmabufState::new();