@@ -5,6 +5,7 @@ use crate::{
55 state:: { BackendData , Data , State } ,
66 wayland:: protocols:: output_configuration:: OutputConfigurationState ,
77} ;
8+ use cosmic_config:: { ConfigGet , ConfigSet } ;
89use serde:: { Deserialize , Serialize } ;
910use smithay:: input:: Seat ;
1011pub use smithay:: {
@@ -34,6 +35,9 @@ pub use self::types::*;
3435pub struct Config {
3536 pub static_conf : StaticConfig ,
3637 pub dynamic_conf : DynamicConfig ,
38+ pub config : cosmic_config:: Config ,
39+ pub xkb : XkbConfig ,
40+ pub input_devices : HashMap < String , InputConfig > ,
3741}
3842
3943#[ derive( Debug , Deserialize ) ]
@@ -65,7 +69,6 @@ pub enum WorkspaceLayout {
6569#[ derive( Debug ) ]
6670pub struct DynamicConfig {
6771 outputs : ( Option < PathBuf > , OutputsConfig ) ,
68- inputs : ( Option < PathBuf > , InputsConfig ) ,
6972}
7073
7174#[ derive( Debug , Deserialize , Serialize ) ]
@@ -152,18 +155,22 @@ impl OutputConfig {
152155 }
153156}
154157
155- #[ derive( Debug , Deserialize , Serialize ) ]
156- pub struct InputsConfig {
157- xkb : XkbConfig ,
158- devices : HashMap < String , InputConfig > ,
159- }
160-
161158impl Config {
162- pub fn load ( ) -> Config {
159+ pub fn load ( loop_handle : & LoopHandle < ' _ , Data > ) -> Config {
160+ let config = cosmic_config:: Config :: new ( "com.system76.CosmicComp" , 1 ) . unwrap ( ) ;
161+ let source = cosmic_config:: calloop:: ConfigWatchSource :: new ( & config) . unwrap ( ) ;
162+ loop_handle
163+ . insert_source ( source, |( config, keys) , ( ) , shared_data| {
164+ config_changed ( config, keys, & mut shared_data. state ) ;
165+ } )
166+ . expect ( "Failed to add cosmic-config to the event loop" ) ;
163167 let xdg = xdg:: BaseDirectories :: new ( ) . ok ( ) ;
164168 Config {
165169 static_conf : Self :: load_static ( xdg. as_ref ( ) ) ,
166170 dynamic_conf : Self :: load_dynamic ( xdg. as_ref ( ) ) ,
171+ xkb : get_config ( & config, "xkb-config" ) ,
172+ input_devices : get_config ( & config, "input-devices" ) ,
173+ config,
167174 }
168175 }
169176
@@ -218,12 +225,8 @@ impl Config {
218225 xdg. and_then ( |base| base. place_state_file ( "cosmic-comp/outputs.ron" ) . ok ( ) ) ;
219226 let outputs = Self :: load_outputs ( & output_path) ;
220227
221- let input_path = xdg. and_then ( |base| base. place_state_file ( "cosmic-comp/inputs.ron" ) . ok ( ) ) ;
222- let inputs = Self :: load_inputs ( & input_path) ;
223-
224228 DynamicConfig {
225229 outputs : ( output_path, outputs) ,
226- inputs : ( input_path, inputs) ,
227230 }
228231 }
229232
@@ -247,27 +250,6 @@ impl Config {
247250 }
248251 }
249252
250- fn load_inputs ( path : & Option < PathBuf > ) -> InputsConfig {
251- if let Some ( path) = path. as_ref ( ) {
252- if path. exists ( ) {
253- match ron:: de:: from_reader ( OpenOptions :: new ( ) . read ( true ) . open ( path) . unwrap ( ) ) {
254- Ok ( config) => return config,
255- Err ( err) => {
256- warn ! ( ?err, "Failed to read input_config, resetting.." ) ;
257- if let Err ( err) = std:: fs:: remove_file ( path) {
258- error ! ( ?err, "Failed to remove input_config." ) ;
259- }
260- }
261- } ;
262- }
263- }
264-
265- InputsConfig {
266- xkb : XkbConfig :: default ( ) ,
267- devices : HashMap :: new ( ) ,
268- }
269- }
270-
271253 pub fn read_outputs (
272254 & mut self ,
273255 output_state : & mut OutputConfigurationState < State > ,
@@ -422,17 +404,23 @@ impl Config {
422404 }
423405
424406 pub fn xkb_config ( & self ) -> XkbConfig {
425- self . dynamic_conf . inputs ( ) . xkb . clone ( )
407+ self . xkb . clone ( )
426408 }
427409
428410 pub fn read_device ( & mut self , device : & mut InputDevice ) {
429411 use std:: collections:: hash_map:: Entry ;
430412
431- let mut inputs = self . dynamic_conf . inputs_mut ( ) ;
432- match inputs . devices . entry ( device. name ( ) . into ( ) ) {
413+ let mut config_changed = false ;
414+ match self . input_devices . entry ( device. name ( ) . into ( ) ) {
433415 Entry :: Occupied ( entry) => entry. get ( ) . update_device ( device) ,
434416 Entry :: Vacant ( entry) => {
435417 entry. insert ( InputConfig :: for_device ( device) ) ;
418+ config_changed = true ;
419+ }
420+ }
421+ if config_changed {
422+ if let Err ( err) = self . config . set ( "input-devices" , & self . input_devices ) {
423+ error ! ( ?err, "Failed to write config 'input-devices'" ) ;
436424 }
437425 }
438426 }
@@ -483,12 +471,45 @@ impl DynamicConfig {
483471 pub fn outputs_mut < ' a > ( & ' a mut self ) -> PersistenceGuard < ' a , OutputsConfig > {
484472 PersistenceGuard ( self . outputs . 0 . clone ( ) , & mut self . outputs . 1 )
485473 }
474+ }
486475
487- pub fn inputs ( & self ) -> & InputsConfig {
488- & self . inputs . 1
489- }
476+ fn get_config < T : Default + serde:: de:: DeserializeOwned > (
477+ config : & cosmic_config:: Config ,
478+ key : & str ,
479+ ) -> T {
480+ config. get ( key) . unwrap_or_else ( |err| {
481+ error ! ( ?err, "Failed to read config '{}'" , key) ;
482+ T :: default ( )
483+ } )
484+ }
490485
491- pub fn inputs_mut < ' a > ( & ' a mut self ) -> PersistenceGuard < ' a , InputsConfig > {
492- PersistenceGuard ( self . inputs . 0 . clone ( ) , & mut self . inputs . 1 )
486+ fn config_changed ( config : cosmic_config:: Config , keys : Vec < String > , state : & mut State ) {
487+ for key in & keys {
488+ match key. as_str ( ) {
489+ "xkb-config" => {
490+ let value = get_config :: < XkbConfig > ( & config, "xkb-config" ) ;
491+ for seat in state. common . seats ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) . iter ( ) {
492+ if let Some ( keyboard) = seat. get_keyboard ( ) {
493+ if let Err ( err) = keyboard. set_xkb_config ( state, ( & value) . into ( ) ) {
494+ error ! ( ?err, "Failed to load provided xkb config" ) ;
495+ // TODO Revert to default?
496+ }
497+ }
498+ }
499+ state. common . config . xkb = value;
500+ }
501+ "input-devices" => {
502+ let value = get_config :: < HashMap < String , InputConfig > > ( & config, "input-devices" ) ;
503+ if let BackendData :: Kms ( ref mut kms_state) = & mut state. backend {
504+ for ( name, device) in kms_state. input_devices . iter_mut ( ) {
505+ if let Some ( input_config) = value. get ( name) {
506+ input_config. update_device ( device) ;
507+ }
508+ }
509+ }
510+ state. common . config . input_devices = value;
511+ }
512+ _ => { }
513+ }
493514 }
494515}
0 commit comments