Skip to content

Commit d309fc3

Browse files
committed
Update sensitivity based on state of shift key
1 parent 3b84291 commit d309fc3

File tree

4 files changed

+69
-77
lines changed

4 files changed

+69
-77
lines changed

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ members = [ "tools", "ffi", "backend", "widgets" ]
1111
[dependencies]
1212
cascade = "1"
1313
futures = "0.3.13"
14-
# 3.24 is packaged by focal
15-
gtk = { version = "0.15.0", features = ["v3_24"] }
14+
gtk = { version = "0.15.0", features = ["v3_22"] }
1615
libc = "0.2"
1716
once_cell = "1.4"
1817
pangocairo = "0.15.0"

backend/src/layout/mod.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,14 @@ impl Layout {
174174
}
175175
Keycode::Basic(mods, keycode_name) => {
176176
if mods.is_empty() {
177-
self.keymap.get(keycode_name).copied()
178-
} else if let Some(mod_name) = mods.as_mod_str() {
179-
self.keymap.get(mod_name).copied()
180-
} else {
181-
let kc = *self.keymap.get(keycode_name)?;
182-
Some((mods.bits() << 8) | (kc & 0xff))
177+
return self.keymap.get(keycode_name).copied();
178+
} else if keycode_name == "NONE" {
179+
if let Some(mod_name) = mods.as_mod_str() {
180+
return self.keymap.get(mod_name).copied();
181+
}
183182
}
183+
let kc = *self.keymap.get(keycode_name)?;
184+
Some((mods.bits() << 8) | (kc & 0xff))
184185
}
185186
}
186187
}

layouts/picker.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -169,30 +169,30 @@
169169
"keysym": "LEFT_ALT",
170170
"label": "Left Alt"
171171
},
172-
{
173-
"keysym": "RIGHT_ALT",
174-
"label": "Right Alt"
175-
},
176172
{
177173
"keysym": "LEFT_CTRL",
178174
"label": "Left Ctrl"
179175
},
180-
{
181-
"keysym": "RIGHT_CTRL",
182-
"label": "Right Ctrl"
183-
},
184176
{
185177
"keysym": "LEFT_SHIFT",
186178
"label": "Left Shift"
187179
},
188-
{
189-
"keysym": "RIGHT_SHIFT",
190-
"label": "Right Shift"
191-
},
192180
{
193181
"keysym": "LEFT_SUPER",
194182
"label": "Left Super"
195183
},
184+
{
185+
"keysym": "RIGHT_ALT",
186+
"label": "Right Alt"
187+
},
188+
{
189+
"keysym": "RIGHT_CTRL",
190+
"label": "Right Ctrl"
191+
},
192+
{
193+
"keysym": "RIGHT_SHIFT",
194+
"label": "Right Shift"
195+
},
196196
{
197197
"keysym": "RIGHT_SUPER",
198198
"label": "Right Super"

src/picker/mod.rs

Lines changed: 49 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ pub static SCANCODE_LABELS: Lazy<HashMap<String, String>> = Lazy::new(|| {
4242
pub struct PickerInner {
4343
group_boxes: DerefCell<Vec<PickerGroupBox>>,
4444
keyboard: RefCell<Option<Keyboard>>,
45-
event_controller_key: RefCell<Option<gtk::EventControllerKey>>,
4645
selected: RefCell<Vec<Keycode>>,
4746
shift: Cell<bool>,
4847
tap_hold: DerefCell<TapHold>,
@@ -116,42 +115,27 @@ impl WidgetImpl for PickerInner {
116115
let window = widget
117116
.toplevel()
118117
.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+
}
150135
}
151136

152137
fn unrealize(&self, widget: &Self::Type) {
153138
self.parent_unrealize(widget);
154-
*self.event_controller_key.borrow_mut() = None;
155139
}
156140
}
157141

@@ -195,6 +179,8 @@ impl Picker {
195179
}
196180
self.inner().tap_hold.set_selected(scancode_names.clone());
197181
*self.inner().selected.borrow_mut() = scancode_names;
182+
183+
self.invalidate_sensitivity();
198184
}
199185

200186
fn key_pressed(&self, name: String, shift: bool) {
@@ -209,6 +195,9 @@ impl Picker {
209195
scancode_name.to_string(),
210196
));
211197
return;
198+
} else if scancode_name == &name && !mods.is_empty() {
199+
self.set_keycode(Keycode::Basic(*mods, "NONE".to_string()));
200+
return;
212201
} else if scancode_name == "NONE" {
213202
self.set_keycode(Keycode::Basic(*mods, name));
214203
return;
@@ -246,48 +235,51 @@ impl Picker {
246235
}
247236

248237
fn invalidate_sensitivity(&self) {
249-
return;
250-
251238
let shift = self.inner().shift.get();
252239

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;
256247

257248
if shift {
258249
let selected = self.inner().selected.borrow();
259250
if selected.len() == 1 {
260251
match &selected[0] {
261252
Keycode::Basic(mods, keycode) => {
262253
// 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());
270262
}
263+
Keycode::MT(..) | Keycode::LT(..) => {}
271264
}
272265
}
266+
} else {
267+
allow_left_mods = true;
268+
allow_right_mods = true;
269+
allow_basic = true;
270+
allow_non_basic = true;
273271
}
274272

275273
for group_box in self.inner().group_boxes.iter() {
276274
// TODO: What to allow?
277275
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)
289279
{
290-
allow_mods
280+
allow_right_mods
281+
} else if basic_keycode.as_deref() == Some(name) && !keycode_mods.is_empty() {
282+
true
291283
} else {
292284
allow_basic
293285
}

0 commit comments

Comments
 (0)