Skip to content

Commit cb3da65

Browse files
james-lawrencemaan2003
authored andcommitted
fixes #2112 - shift modifier becomes locked
repeated events on wayland improperly updated the xkb state for modifiers. if we're processing a repeat event do not update the state.
1 parent 4afed1c commit cb3da65

File tree

4 files changed

+27
-32
lines changed

4 files changed

+27
-32
lines changed

druid-shell/src/backend/shared/xkb/mod.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,29 +191,30 @@ impl State {
191191
}
192192
}
193193

194-
pub fn key_event(&mut self, scancode: u32, state: KeyState) -> KeyEvent {
194+
pub fn key_event(&mut self, scancode: u32, state: KeyState, repeat: bool) -> KeyEvent {
195195
let code = u16::try_from(scancode)
196196
.map(hardware_keycode_to_code)
197197
.unwrap_or(Code::Unidentified);
198198
let key = self.get_logical_key(scancode);
199199
// TODO this is lazy - really should use xkb i.e. augment the get_logical_key method.
200200
let location = code_to_location(code);
201201

202-
let repeat = false;
203202
// TODO not sure how to get this
204203
let is_composing = false;
205204

206205
let mut mods = Modifiers::empty();
207206
// Update xkb's state (e.g. return capitals if we've pressed shift)
208207
unsafe {
209-
xkb_state_update_key(
210-
self.state,
211-
scancode,
212-
match state {
213-
KeyState::Down => XKB_KEY_DOWN,
214-
KeyState::Up => XKB_KEY_UP,
215-
},
216-
);
208+
if !repeat {
209+
xkb_state_update_key(
210+
self.state,
211+
scancode,
212+
match state {
213+
KeyState::Down => XKB_KEY_DOWN,
214+
KeyState::Up => XKB_KEY_UP,
215+
},
216+
);
217+
}
217218
// compiler will unroll this loop
218219
// FIXME(msrv): remove .iter().cloned() when msrv is >= 1.53
219220
for (idx, mod_) in [

druid-shell/src/backend/wayland/keyboard.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,12 @@ impl Keyboard {
113113
_ => panic!("unrecognised key event"),
114114
};
115115

116-
let mut event = self
117-
.xkb_state
118-
.borrow_mut()
119-
.as_mut()
120-
.unwrap()
121-
.key_event(keystroke.key, keystate);
116+
let mut event = self.xkb_state.borrow_mut().as_mut().unwrap().key_event(
117+
keystroke.key,
118+
keystate,
119+
keystroke.repeat,
120+
);
122121
event.mods = self.xkb_mods.get();
123-
event.repeat = keystroke.repeat;
124122

125123
if let Err(cause) = keystroke.queue.send(event) {
126124
tracing::error!("failed to send druid key event: {:?}", cause);
@@ -355,10 +353,7 @@ impl Manager {
355353
}
356354

357355
// TODO turn struct into a calloop event source.
358-
pub(super) fn events<'a>(
359-
&self,
360-
handle: &'a calloop::LoopHandle<std::sync::Arc<Data>>,
361-
) {
356+
pub(super) fn events<'a>(&self, handle: &'a calloop::LoopHandle<std::sync::Arc<Data>>) {
362357
let rx = self.inner.apprx.borrow_mut().take().unwrap();
363358
handle
364359
.insert_source(rx, {

druid-shell/src/backend/wayland/window.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ use wayland_protocols::xdg_shell::client::xdg_positioner;
1919
use wayland_protocols::xdg_shell::client::xdg_surface;
2020

2121
use super::application::{self, Timer};
22-
use super::{
23-
error::Error,
24-
menu::Menu,
25-
outputs, surfaces,
26-
};
22+
use super::{error::Error, menu::Menu, outputs, surfaces};
2723

2824
use crate::{
2925
dialog::FileDialogOptions,

druid-shell/src/backend/x11/application.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -544,9 +544,11 @@ impl Application {
544544
.context("KEY_PRESS - failed to get window")?;
545545
let hw_keycode = ev.detail;
546546
let mut state = borrow_mut!(self.state)?;
547-
let key_event = state
548-
.xkb_state
549-
.key_event(hw_keycode as _, keyboard_types::KeyState::Down);
547+
let key_event = state.xkb_state.key_event(
548+
hw_keycode as _,
549+
keyboard_types::KeyState::Down,
550+
false,
551+
);
550552

551553
w.handle_key_event(key_event);
552554
}
@@ -556,9 +558,10 @@ impl Application {
556558
.context("KEY_PRESS - failed to get window")?;
557559
let hw_keycode = ev.detail;
558560
let mut state = borrow_mut!(self.state)?;
559-
let key_event = state
560-
.xkb_state
561-
.key_event(hw_keycode as _, keyboard_types::KeyState::Up);
561+
let key_event =
562+
state
563+
.xkb_state
564+
.key_event(hw_keycode as _, keyboard_types::KeyState::Up, false);
562565

563566
w.handle_key_event(key_event);
564567
}

0 commit comments

Comments
 (0)