mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-09 03:57:39 +00:00
wayland: don't dispatch modifier key events (#9027)
Modifier keys are dispatched as events on wayland, unlike macos. This prevents pending bindings from matching, because something like e.g. `g shift-e` is received by the key matcher as `g shift shift-e`.
This commit is contained in:
parent
27518f4280
commit
9068911eb4
1 changed files with 41 additions and 13 deletions
|
@ -41,9 +41,9 @@ use crate::platform::linux::wayland::window::{WaylandDecorationState, WaylandWin
|
||||||
use crate::platform::{LinuxPlatformInner, PlatformWindow};
|
use crate::platform::{LinuxPlatformInner, PlatformWindow};
|
||||||
use crate::{
|
use crate::{
|
||||||
platform::linux::wayland::window::WaylandWindowState, AnyWindowHandle, CursorStyle, DisplayId,
|
platform::linux::wayland::window::WaylandWindowState, AnyWindowHandle, CursorStyle, DisplayId,
|
||||||
KeyDownEvent, KeyUpEvent, Keystroke, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent,
|
KeyDownEvent, KeyUpEvent, Keystroke, Modifiers, ModifiersChangedEvent, MouseButton,
|
||||||
MouseUpEvent, NavigationDirection, Pixels, PlatformDisplay, PlatformInput, Point, ScrollDelta,
|
MouseDownEvent, MouseMoveEvent, MouseUpEvent, NavigationDirection, Pixels, PlatformDisplay,
|
||||||
ScrollWheelEvent, TouchPhase, WindowOptions,
|
PlatformInput, Point, ScrollDelta, ScrollWheelEvent, TouchPhase, WindowOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Used to convert evdev scancode to xkb scancode
|
/// Used to convert evdev scancode to xkb scancode
|
||||||
|
@ -681,6 +681,7 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
|
||||||
let Some(focused_window) = focused_window else {
|
let Some(focused_window) = focused_window else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
let focused_window = focused_window.clone();
|
||||||
|
|
||||||
let keymap_state = state.keymap_state.as_ref().unwrap();
|
let keymap_state = state.keymap_state.as_ref().unwrap();
|
||||||
let keycode = Keycode::from(key + MIN_KEYCODE);
|
let keycode = Keycode::from(key + MIN_KEYCODE);
|
||||||
|
@ -688,12 +689,20 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
|
||||||
|
|
||||||
match key_state {
|
match key_state {
|
||||||
wl_keyboard::KeyState::Pressed => {
|
wl_keyboard::KeyState::Pressed => {
|
||||||
let input = PlatformInput::KeyDown(KeyDownEvent {
|
let input = if keysym.is_modifier_key() {
|
||||||
keystroke: Keystroke::from_xkb(keymap_state, state.modifiers, keycode),
|
PlatformInput::ModifiersChanged(ModifiersChangedEvent {
|
||||||
is_held: false, // todo(linux)
|
modifiers: state.modifiers,
|
||||||
});
|
})
|
||||||
|
} else {
|
||||||
focused_window.handle_input(input.clone());
|
PlatformInput::KeyDown(KeyDownEvent {
|
||||||
|
keystroke: Keystroke::from_xkb(
|
||||||
|
keymap_state,
|
||||||
|
state.modifiers,
|
||||||
|
keycode,
|
||||||
|
),
|
||||||
|
is_held: false, // todo(linux)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
if !keysym.is_modifier_key() {
|
if !keysym.is_modifier_key() {
|
||||||
state.repeat.current_id += 1;
|
state.repeat.current_id += 1;
|
||||||
|
@ -706,6 +715,7 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
|
||||||
|
|
||||||
let timer = Timer::from_duration(delay);
|
let timer = Timer::from_duration(delay);
|
||||||
let state_ = Rc::clone(&this.client_state_inner);
|
let state_ = Rc::clone(&this.client_state_inner);
|
||||||
|
let input_ = input.clone();
|
||||||
state
|
state
|
||||||
.loop_handle
|
.loop_handle
|
||||||
.insert_source(timer, move |event, _metadata, shared_data| {
|
.insert_source(timer, move |event, _metadata, shared_data| {
|
||||||
|
@ -723,21 +733,39 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
|
||||||
|
|
||||||
drop(state_);
|
drop(state_);
|
||||||
|
|
||||||
focused_window.handle_input(input.clone());
|
focused_window.handle_input(input_.clone());
|
||||||
|
|
||||||
TimeoutAction::ToDuration(Duration::from_secs(1) / rate)
|
TimeoutAction::ToDuration(Duration::from_secs(1) / rate)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop(state);
|
||||||
|
|
||||||
|
focused_window.handle_input(input);
|
||||||
}
|
}
|
||||||
wl_keyboard::KeyState::Released => {
|
wl_keyboard::KeyState::Released => {
|
||||||
focused_window.handle_input(PlatformInput::KeyUp(KeyUpEvent {
|
let input = if keysym.is_modifier_key() {
|
||||||
keystroke: Keystroke::from_xkb(keymap_state, state.modifiers, keycode),
|
PlatformInput::ModifiersChanged(ModifiersChangedEvent {
|
||||||
}));
|
modifiers: state.modifiers,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
PlatformInput::KeyUp(KeyUpEvent {
|
||||||
|
keystroke: Keystroke::from_xkb(
|
||||||
|
keymap_state,
|
||||||
|
state.modifiers,
|
||||||
|
keycode,
|
||||||
|
),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
if !keysym.is_modifier_key() {
|
if !keysym.is_modifier_key() {
|
||||||
state.repeat.current_keysym = None;
|
state.repeat.current_keysym = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop(state);
|
||||||
|
|
||||||
|
focused_window.handle_input(input);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue