@@ -42,7 +42,6 @@ pub static SCANCODE_LABELS: Lazy<HashMap<String, String>> = Lazy::new(|| {
42
42
pub struct PickerInner {
43
43
group_boxes : DerefCell < Vec < PickerGroupBox > > ,
44
44
keyboard : RefCell < Option < Keyboard > > ,
45
- event_controller_key : RefCell < Option < gtk:: EventControllerKey > > ,
46
45
selected : RefCell < Vec < Keycode > > ,
47
46
shift : Cell < bool > ,
48
47
tap_hold : DerefCell < TapHold > ,
@@ -116,42 +115,27 @@ impl WidgetImpl for PickerInner {
116
115
let window = widget
117
116
. toplevel ( )
118
117
. and_then ( |x| x. downcast :: < gtk:: Window > ( ) . ok ( ) ) ;
119
- * self . event_controller_key . borrow_mut ( ) = window. map ( |window| {
120
- cascade ! {
121
- gtk:: EventControllerKey :: new( & window) ;
122
- ..connect_key_pressed( clone!( @weak widget => @default -return true , move |_, keyval, _, mods| {
123
- let key = gdk:: keys:: Key :: from( keyval) ;
124
- if key == gdk:: keys:: constants:: Shift_L || key == gdk:: keys:: constants:: Shift_R {
125
- println!( "Shift" ) ; // XXX what if only one is held?
126
- }
127
- true
128
- } ) ) ;
129
- ..connect_key_released( clone!( @weak widget => move |_, keyval, _, mods| {
130
- let key = gdk:: keys:: Key :: from( keyval) ;
131
- if key == gdk:: keys:: constants:: Shift_L || key == gdk:: keys:: constants:: Shift_R {
132
- println!( "Unshift" ) ; // XXX what if only one is held?
133
- }
134
- } ) ) ;
135
- ..connect_focus_out( clone!( @weak widget => move |_| {
136
- println!( "Unfocus" ) ;
137
- } ) ) ;
138
- ..connect_modifiers( clone!( @weak widget => @default -return true , move |_, mods| {
139
- println!( "Mods: {:?}" , mods) ;
140
- let shift = mods. contains( gdk:: ModifierType :: SHIFT_MASK ) ;
141
- //println!("Shift: {}", shift);
142
- if shift != widget. inner( ) . shift. get( ) {
143
- widget. inner( ) . shift. set( shift) ;
144
- widget. invalidate_sensitivity( ) ;
145
- }
146
- true
147
- } ) ) ;
148
- }
149
- } ) ;
118
+ if let Some ( window) = & window {
119
+ window. add_events ( gdk:: EventMask :: FOCUS_CHANGE_MASK ) ;
120
+ window. connect_event ( clone ! ( @weak widget => @default -return Inhibit ( false ) , move |_, evt| {
121
+ use gdk:: keys:: { Key , constants} ;
122
+ let is_shift_key = matches!( evt. keyval( ) . map( Key :: from) , Some ( constants:: Shift_L | constants:: Shift_R ) ) ;
123
+ // XXX Distinguish lshift, rshift if both are held?
124
+ let shift = match evt. event_type( ) {
125
+ gdk:: EventType :: KeyPress if is_shift_key => true ,
126
+ gdk:: EventType :: KeyRelease if is_shift_key => false ,
127
+ gdk:: EventType :: FocusChange => false ,
128
+ _ => { return Inhibit ( false ) ; }
129
+ } ;
130
+ widget. inner( ) . shift. set( shift) ;
131
+ widget. invalidate_sensitivity( ) ;
132
+ Inhibit ( false )
133
+ } ) ) ;
134
+ }
150
135
}
151
136
152
137
fn unrealize ( & self , widget : & Self :: Type ) {
153
138
self . parent_unrealize ( widget) ;
154
- * self . event_controller_key . borrow_mut ( ) = None ;
155
139
}
156
140
}
157
141
@@ -195,6 +179,8 @@ impl Picker {
195
179
}
196
180
self . inner ( ) . tap_hold . set_selected ( scancode_names. clone ( ) ) ;
197
181
* self . inner ( ) . selected . borrow_mut ( ) = scancode_names;
182
+
183
+ self . invalidate_sensitivity ( ) ;
198
184
}
199
185
200
186
fn key_pressed ( & self , name : String , shift : bool ) {
@@ -209,6 +195,9 @@ impl Picker {
209
195
scancode_name. to_string ( ) ,
210
196
) ) ;
211
197
return ;
198
+ } else if scancode_name == & name && !mods. is_empty ( ) {
199
+ self . set_keycode ( Keycode :: Basic ( * mods, "NONE" . to_string ( ) ) ) ;
200
+ return ;
212
201
} else if scancode_name == "NONE" {
213
202
self . set_keycode ( Keycode :: Basic ( * mods, name) ) ;
214
203
return ;
@@ -246,48 +235,51 @@ impl Picker {
246
235
}
247
236
248
237
fn invalidate_sensitivity ( & self ) {
249
- return ;
250
-
251
238
let shift = self . inner ( ) . shift . get ( ) ;
252
239
253
- let mut allow_mods = true ;
254
- let mut allow_basic = true ;
255
- let mut allow_non_basic = true ;
240
+ let mut allow_left_mods = false ;
241
+ let mut allow_right_mods = false ;
242
+ let mut allow_basic = false ;
243
+ let mut allow_non_basic = false ;
244
+
245
+ let mut keycode_mods = Mods :: empty ( ) ;
246
+ let mut basic_keycode = None ;
256
247
257
248
if shift {
258
249
let selected = self . inner ( ) . selected . borrow ( ) ;
259
250
if selected. len ( ) == 1 {
260
251
match & selected[ 0 ] {
261
252
Keycode :: Basic ( mods, keycode) => {
262
253
// Allow mods only if `keycode` is really basic?
263
- allow_basic = keycode == "NONE" ;
264
- allow_non_basic = false ;
265
- }
266
- Keycode :: MT ( ..) | Keycode :: LT ( ..) => {
267
- allow_mods = false ;
268
- allow_basic = false ;
269
- allow_non_basic = false ;
254
+ // Allow deselecting current key
255
+ let no_mod = mods. is_empty ( ) ;
256
+ let right = mods. contains ( Mods :: RIGHT ) ;
257
+ allow_left_mods = no_mod || !right;
258
+ allow_right_mods = no_mod || right;
259
+ allow_basic = keycode == "NONE" && !mods. is_empty ( ) ;
260
+ keycode_mods = * mods;
261
+ basic_keycode = Some ( keycode. clone ( ) ) ;
270
262
}
263
+ Keycode :: MT ( ..) | Keycode :: LT ( ..) => { }
271
264
}
272
265
}
266
+ } else {
267
+ allow_left_mods = true ;
268
+ allow_right_mods = true ;
269
+ allow_basic = true ;
270
+ allow_non_basic = true ;
273
271
}
274
272
275
273
for group_box in self . inner ( ) . group_boxes . iter ( ) {
276
274
// TODO: What to allow?
277
275
group_box. set_key_sensitivity ( |name| {
278
- if [
279
- "LEFT_SHIFT" ,
280
- "RIGHT_SHIFT" ,
281
- "LEFT_ALT" ,
282
- "RIGHT_ALT" ,
283
- "LEFT_CTRL" ,
284
- "RIGHT_CTRL" ,
285
- "LEFT_SUPER" ,
286
- "RIGHT_SUPER" ,
287
- ]
288
- . contains ( & name)
276
+ if [ "LEFT_SHIFT" , "LEFT_ALT" , "LEFT_CTRL" , "LEFT_SUPER" ] . contains ( & name) {
277
+ allow_left_mods
278
+ } else if [ "RIGHT_SHIFT" , "RIGHT_ALT" , "RIGHT_CTRL" , "RIGHT_SUPER" ] . contains ( & name)
289
279
{
290
- allow_mods
280
+ allow_right_mods
281
+ } else if basic_keycode. as_deref ( ) == Some ( name) && !keycode_mods. is_empty ( ) {
282
+ true
291
283
} else {
292
284
allow_basic
293
285
}
0 commit comments