@@ -5,6 +5,7 @@ use crate::{
5
5
state:: { BackendData , Data , State } ,
6
6
wayland:: protocols:: output_configuration:: OutputConfigurationState ,
7
7
} ;
8
+ use cosmic_config:: { ConfigGet , ConfigSet } ;
8
9
use serde:: { Deserialize , Serialize } ;
9
10
use smithay:: input:: Seat ;
10
11
pub use smithay:: {
@@ -34,6 +35,9 @@ pub use self::types::*;
34
35
pub struct Config {
35
36
pub static_conf : StaticConfig ,
36
37
pub dynamic_conf : DynamicConfig ,
38
+ pub config : cosmic_config:: Config ,
39
+ pub xkb : XkbConfig ,
40
+ pub input_devices : HashMap < String , InputConfig > ,
37
41
}
38
42
39
43
#[ derive( Debug , Deserialize ) ]
@@ -65,7 +69,6 @@ pub enum WorkspaceLayout {
65
69
#[ derive( Debug ) ]
66
70
pub struct DynamicConfig {
67
71
outputs : ( Option < PathBuf > , OutputsConfig ) ,
68
- inputs : ( Option < PathBuf > , InputsConfig ) ,
69
72
}
70
73
71
74
#[ derive( Debug , Deserialize , Serialize ) ]
@@ -152,18 +155,22 @@ impl OutputConfig {
152
155
}
153
156
}
154
157
155
- #[ derive( Debug , Deserialize , Serialize ) ]
156
- pub struct InputsConfig {
157
- xkb : XkbConfig ,
158
- devices : HashMap < String , InputConfig > ,
159
- }
160
-
161
158
impl 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" ) ;
163
167
let xdg = xdg:: BaseDirectories :: new ( ) . ok ( ) ;
164
168
Config {
165
169
static_conf : Self :: load_static ( xdg. as_ref ( ) ) ,
166
170
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,
167
174
}
168
175
}
169
176
@@ -218,12 +225,8 @@ impl Config {
218
225
xdg. and_then ( |base| base. place_state_file ( "cosmic-comp/outputs.ron" ) . ok ( ) ) ;
219
226
let outputs = Self :: load_outputs ( & output_path) ;
220
227
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
-
224
228
DynamicConfig {
225
229
outputs : ( output_path, outputs) ,
226
- inputs : ( input_path, inputs) ,
227
230
}
228
231
}
229
232
@@ -247,27 +250,6 @@ impl Config {
247
250
}
248
251
}
249
252
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
-
271
253
pub fn read_outputs (
272
254
& mut self ,
273
255
output_state : & mut OutputConfigurationState < State > ,
@@ -422,17 +404,23 @@ impl Config {
422
404
}
423
405
424
406
pub fn xkb_config ( & self ) -> XkbConfig {
425
- self . dynamic_conf . inputs ( ) . xkb . clone ( )
407
+ self . xkb . clone ( )
426
408
}
427
409
428
410
pub fn read_device ( & mut self , device : & mut InputDevice ) {
429
411
use std:: collections:: hash_map:: Entry ;
430
412
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 ( ) ) {
433
415
Entry :: Occupied ( entry) => entry. get ( ) . update_device ( device) ,
434
416
Entry :: Vacant ( entry) => {
435
417
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'" ) ;
436
424
}
437
425
}
438
426
}
@@ -483,12 +471,45 @@ impl DynamicConfig {
483
471
pub fn outputs_mut < ' a > ( & ' a mut self ) -> PersistenceGuard < ' a , OutputsConfig > {
484
472
PersistenceGuard ( self . outputs . 0 . clone ( ) , & mut self . outputs . 1 )
485
473
}
474
+ }
486
475
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
+ }
490
485
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
+ }
493
514
}
494
515
}
0 commit comments