@@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize};
1515use smithay:: utils:: { Clock , Monotonic } ;
1616use smithay:: wayland:: xdg_activation:: XdgActivationState ;
1717pub use smithay:: {
18- backend:: input:: KeyState ,
18+ backend:: input:: { self as smithay_input , KeyState } ,
1919 input:: keyboard:: { keysyms as KeySyms , Keysym , ModifiersState } ,
2020 output:: { Mode , Output } ,
2121 reexports:: {
@@ -25,7 +25,7 @@ pub use smithay::{
2525 TapButtonMap ,
2626 } ,
2727 } ,
28- utils:: { Logical , Physical , Point , Size , Transform } ,
28+ utils:: { Logical , Physical , Point , Size , Transform , SERIAL_COUNTER } ,
2929} ;
3030use std:: {
3131 cell:: RefCell ,
@@ -694,6 +694,30 @@ fn update_input(state: &mut State) {
694694 }
695695}
696696
697+ pub fn change_modifier_state (
698+ keyboard : & smithay:: input:: keyboard:: KeyboardHandle < State > ,
699+ scan_code : u32 ,
700+ state : & mut State ,
701+ ) {
702+ /// Offset used to convert Linux scancode to X11 keycode.
703+ const X11_KEYCODE_OFFSET : u32 = 8 ;
704+
705+ let mut input = |key_state, scan_code| {
706+ let time = state. common . clock . now ( ) . as_millis ( ) ;
707+ let _ = keyboard. input (
708+ state,
709+ smithay_input:: Keycode :: new ( scan_code + X11_KEYCODE_OFFSET ) ,
710+ key_state,
711+ SERIAL_COUNTER . next_serial ( ) ,
712+ time,
713+ |_, _, _| smithay:: input:: keyboard:: FilterResult :: < ( ) > :: Forward ,
714+ ) ;
715+ } ;
716+
717+ input ( smithay_input:: KeyState :: Pressed , scan_code) ;
718+ input ( smithay_input:: KeyState :: Released , scan_code) ;
719+ }
720+
697721fn config_changed ( config : cosmic_config:: Config , keys : Vec < String > , state : & mut State ) {
698722 for key in & keys {
699723 match key. as_str ( ) {
@@ -710,6 +734,7 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
710734 . collect :: < Vec < _ > > ( ) ;
711735 for seat in seats. into_iter ( ) {
712736 if let Some ( keyboard) = seat. get_keyboard ( ) {
737+ let old_modifier_state = keyboard. modifier_state ( ) ;
713738 keyboard. change_repeat_info (
714739 ( value. repeat_rate as i32 ) . abs ( ) , // Negative values are illegal
715740 ( value. repeat_delay as i32 ) . abs ( ) ,
@@ -718,6 +743,16 @@ fn config_changed(config: cosmic_config::Config, keys: Vec<String>, state: &mut
718743 error ! ( ?err, "Failed to load provided xkb config" ) ;
719744 // TODO Revert to default?
720745 }
746+
747+ // Press and release the numlock key to update modifiers.
748+ if old_modifier_state. num_lock != keyboard. modifier_state ( ) . num_lock {
749+ const NUMLOCK_SCANCODE : u32 = 69 ;
750+ change_modifier_state ( & keyboard, NUMLOCK_SCANCODE , state) ;
751+ }
752+ if old_modifier_state. caps_lock != keyboard. modifier_state ( ) . caps_lock {
753+ const CAPSLOCK_SCANCODE : u32 = 58 ;
754+ change_modifier_state ( & keyboard, CAPSLOCK_SCANCODE , state) ;
755+ }
721756 }
722757 }
723758 state. common . atspi_ei . update_keymap ( value. clone ( ) ) ;
0 commit comments