@@ -12,6 +12,8 @@ use cosmic_config::{ConfigGet, CosmicConfigEntry};
1212use cosmic_settings_config:: window_rules:: ApplicationException ;
1313use cosmic_settings_config:: { shortcuts, window_rules, Shortcuts } ;
1414use serde:: { Deserialize , Serialize } ;
15+ use smithay:: utils:: { Clock , Monotonic } ;
16+ use smithay:: wayland:: xdg_activation:: XdgActivationState ;
1517pub use smithay:: {
1618 backend:: input:: KeyState ,
1719 input:: keyboard:: { keysyms as KeySyms , Keysym , ModifiersState } ,
@@ -25,10 +27,6 @@ pub use smithay::{
2527 } ,
2628 utils:: { Logical , Physical , Point , Size , Transform } ,
2729} ;
28- use smithay:: {
29- utils:: { Clock , Monotonic } ,
30- wayland:: xdg_activation:: XdgActivationState ,
31- } ;
3230use std:: {
3331 cell:: RefCell ,
3432 collections:: { BTreeMap , HashMap } ,
@@ -46,7 +44,8 @@ mod types;
4644pub use self :: types:: * ;
4745use cosmic:: config:: CosmicTk ;
4846use cosmic_comp_config:: {
49- input:: InputConfig , workspace:: WorkspaceConfig , CosmicCompConfig , TileBehavior , XkbConfig ,
47+ input:: InputConfig , workspace:: WorkspaceConfig , CosmicCompConfig , KeyboardConfig , TileBehavior ,
48+ XkbConfig ,
5049} ;
5150
5251#[ derive( Debug ) ]
@@ -68,6 +67,7 @@ pub struct Config {
6867#[ derive( Debug ) ]
6968pub struct DynamicConfig {
7069 outputs : ( Option < PathBuf > , OutputsConfig ) ,
70+ numlock : ( Option < PathBuf > , NumlockStateConfig ) ,
7171}
7272
7373#[ derive( Debug , Deserialize , Serialize ) ]
@@ -93,6 +93,11 @@ impl From<Output> for OutputInfo {
9393 }
9494}
9595
96+ #[ derive( Default , Debug , Deserialize , Serialize ) ]
97+ pub struct NumlockStateConfig {
98+ pub last_state : bool ,
99+ }
100+
96101#[ derive( Debug , Deserialize , Serialize , Clone , PartialEq ) ]
97102#[ serde( rename_all = "lowercase" ) ]
98103pub enum OutputState {
@@ -323,9 +328,13 @@ impl Config {
323328 let output_path =
324329 xdg. and_then ( |base| base. place_state_file ( "cosmic-comp/outputs.ron" ) . ok ( ) ) ;
325330 let outputs = Self :: load_outputs ( & output_path) ;
331+ let numlock_path =
332+ xdg. and_then ( |base| base. place_state_file ( "cosmic-comp/numlock.ron" ) . ok ( ) ) ;
333+ let numlock = Self :: load_numlock ( & numlock_path) ;
326334
327335 DynamicConfig {
328336 outputs : ( output_path, outputs) ,
337+ numlock : ( numlock_path, numlock) ,
329338 }
330339 }
331340
@@ -373,6 +382,24 @@ impl Config {
373382 }
374383 }
375384
385+ fn load_numlock ( path : & Option < PathBuf > ) -> NumlockStateConfig {
386+ path. as_deref ( )
387+ . filter ( |path| path. exists ( ) )
388+ . and_then ( |path| {
389+ ron:: de:: from_reader :: < _ , NumlockStateConfig > (
390+ OpenOptions :: new ( ) . read ( true ) . open ( path) . unwrap ( ) ,
391+ )
392+ . map_err ( |err| {
393+ warn ! ( ?err, "Failed to read numlock.ron, resetting.." ) ;
394+ if let Err ( err) = std:: fs:: remove_file ( path) {
395+ error ! ( ?err, "Failed to remove numlock.ron." ) ;
396+ }
397+ } )
398+ . ok ( )
399+ } )
400+ . unwrap_or_default ( )
401+ }
402+
376403 pub fn shortcut_for_action ( & self , action : & shortcuts:: Action ) -> Option < String > {
377404 self . shortcuts . shortcut_for_action ( action)
378405 }
@@ -639,6 +666,14 @@ impl DynamicConfig {
639666 pub fn outputs_mut ( & mut self ) -> PersistenceGuard < ' _ , OutputsConfig > {
640667 PersistenceGuard ( self . outputs . 0 . clone ( ) , & mut self . outputs . 1 )
641668 }
669+
670+ pub fn numlock ( & self ) -> & NumlockStateConfig {
671+ & self . numlock . 1
672+ }
673+
674+ pub fn numlock_mut ( & mut self ) -> PersistenceGuard < ' _ , NumlockStateConfig > {
675+ PersistenceGuard ( self . numlock . 0 . clone ( ) , & mut self . numlock . 1 )
676+ }
642677}
643678
644679fn get_config < T : Default + serde:: de:: DeserializeOwned > (
@@ -688,6 +723,14 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
688723 state. common . atspi_ei . update_keymap ( value. clone ( ) ) ;
689724 state. common . config . cosmic_conf . xkb_config = value;
690725 }
726+ "keyboard_config" => {
727+ let value = get_config :: < KeyboardConfig > ( & config, "keyboard_config" ) ;
728+ state. common . config . cosmic_conf . keyboard_config = value;
729+ let shell = state. common . shell . read ( ) . unwrap ( ) ;
730+ let seat = shell. seats . last_active ( ) ;
731+ state. common . config . dynamic_conf . numlock_mut ( ) . last_state =
732+ seat. get_keyboard ( ) . unwrap ( ) . modifier_state ( ) . num_lock ;
733+ }
691734 "input_default" => {
692735 let value = get_config :: < InputConfig > ( & config, "input_default" ) ;
693736 state. common . config . cosmic_conf . input_default = value;
0 commit comments