mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-08 19:43:11 +00:00
Wayland: Keyboard input improvements (#7989)
Release Notes: - N/A --- Right now the Wayland backend is using `xkb::State::key_get_utf8` as the `key`, when it should be used as the `ime_key`. It also manages pressing/releasing modifiers manually when this should be managed by the display server. This allows modifier combinations to work in more cases, making it an alternative to https://github.com/zed-industries/zed/pull/7975, which interprets what is now only used as the `ime_key` value as a `key` value.
This commit is contained in:
parent
bd137b01ad
commit
2b56c43f2d
2 changed files with 41 additions and 81 deletions
|
@ -27,7 +27,6 @@ use xkbcommon::xkb::{Keycode, KEYMAP_COMPILE_NO_FLAGS};
|
|||
use crate::platform::linux::client::Client;
|
||||
use crate::platform::linux::wayland::window::WaylandWindow;
|
||||
use crate::platform::{LinuxPlatformInner, PlatformWindow};
|
||||
use crate::PlatformInput::KeyDown;
|
||||
use crate::ScrollDelta;
|
||||
use crate::{
|
||||
platform::linux::wayland::window::WaylandWindowState, AnyWindowHandle, DisplayId, KeyDownEvent,
|
||||
|
@ -394,14 +393,16 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
|
|||
group,
|
||||
..
|
||||
} => {
|
||||
state.keymap_state.as_mut().unwrap().update_mask(
|
||||
mods_depressed,
|
||||
mods_latched,
|
||||
mods_locked,
|
||||
0,
|
||||
0,
|
||||
group,
|
||||
);
|
||||
let keymap_state = state.keymap_state.as_mut().unwrap();
|
||||
keymap_state.update_mask(mods_depressed, mods_latched, mods_locked, 0, 0, group);
|
||||
state.modifiers.shift =
|
||||
keymap_state.mod_name_is_active(xkb::MOD_NAME_SHIFT, xkb::STATE_MODS_EFFECTIVE);
|
||||
state.modifiers.alt =
|
||||
keymap_state.mod_name_is_active(xkb::MOD_NAME_ALT, xkb::STATE_MODS_EFFECTIVE);
|
||||
state.modifiers.control =
|
||||
keymap_state.mod_name_is_active(xkb::MOD_NAME_CTRL, xkb::STATE_MODS_EFFECTIVE);
|
||||
state.modifiers.command =
|
||||
keymap_state.mod_name_is_active(xkb::MOD_NAME_LOGO, xkb::STATE_MODS_EFFECTIVE);
|
||||
}
|
||||
wl_keyboard::Event::Key {
|
||||
key,
|
||||
|
@ -409,81 +410,44 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
|
|||
..
|
||||
} => {
|
||||
let keymap_state = state.keymap_state.as_ref().unwrap();
|
||||
let key_utf8 = keymap_state.key_get_utf8(Keycode::from(key + MIN_KEYCODE));
|
||||
let key_sym = keymap_state.key_get_one_sym(Keycode::from(key + MIN_KEYCODE));
|
||||
let keycode = Keycode::from(key + MIN_KEYCODE);
|
||||
let key_utf32 = keymap_state.key_get_utf32(keycode);
|
||||
let key_utf8 = keymap_state.key_get_utf8(keycode);
|
||||
let key_sym = keymap_state.key_get_one_sym(keycode);
|
||||
let key = xkb::keysym_get_name(key_sym).to_lowercase();
|
||||
|
||||
let key = if matches!(
|
||||
key_sym,
|
||||
xkb::Keysym::BackSpace
|
||||
| xkb::Keysym::Left
|
||||
| xkb::Keysym::Right
|
||||
| xkb::Keysym::Down
|
||||
| xkb::Keysym::Up
|
||||
| xkb::Keysym::Super_L
|
||||
| xkb::Keysym::Super_R
|
||||
) {
|
||||
xkb::keysym_get_name(key_sym).to_lowercase()
|
||||
} else {
|
||||
key_utf8.clone()
|
||||
};
|
||||
// Ignore control characters (and DEL) for the purposes of ime_key,
|
||||
// but if key_utf32 is 0 then assume it isn't one
|
||||
let ime_key =
|
||||
(key_utf32 == 0 || (key_utf32 >= 32 && key_utf32 != 127)).then_some(key_utf8);
|
||||
|
||||
let focused_window = &state.keyboard_focused_window;
|
||||
if let Some(focused_window) = focused_window {
|
||||
match key_state {
|
||||
wl_keyboard::KeyState::Pressed => {
|
||||
if key_sym == xkb::Keysym::Shift_L || key_sym == xkb::Keysym::Shift_R {
|
||||
state.modifiers.shift = true;
|
||||
} else if key_sym == xkb::Keysym::Control_L
|
||||
|| key_sym == xkb::Keysym::Control_R
|
||||
{
|
||||
state.modifiers.control = true;
|
||||
} else if key_sym == xkb::Keysym::Alt_L || key_sym == xkb::Keysym::Alt_R
|
||||
{
|
||||
state.modifiers.alt = true;
|
||||
} else {
|
||||
focused_window.handle_input(KeyDown(KeyDownEvent {
|
||||
keystroke: Keystroke {
|
||||
modifiers: state.modifiers,
|
||||
key,
|
||||
ime_key: None,
|
||||
},
|
||||
is_held: false, // todo!(linux)
|
||||
}));
|
||||
}
|
||||
focused_window.handle_input(PlatformInput::KeyDown(KeyDownEvent {
|
||||
keystroke: Keystroke {
|
||||
modifiers: state.modifiers,
|
||||
key,
|
||||
ime_key,
|
||||
},
|
||||
is_held: false, // todo!(linux)
|
||||
}));
|
||||
}
|
||||
wl_keyboard::KeyState::Released => {
|
||||
if key_sym == xkb::Keysym::Shift_L || key_sym == xkb::Keysym::Shift_R {
|
||||
state.modifiers.shift = false;
|
||||
} else if key_sym == xkb::Keysym::Control_L
|
||||
|| key_sym == xkb::Keysym::Control_R
|
||||
{
|
||||
state.modifiers.control = false;
|
||||
} else if key_sym == xkb::Keysym::Alt_L || key_sym == xkb::Keysym::Alt_R
|
||||
{
|
||||
state.modifiers.alt = false;
|
||||
} else {
|
||||
focused_window.handle_input(PlatformInput::KeyUp(KeyUpEvent {
|
||||
keystroke: Keystroke {
|
||||
modifiers: state.modifiers,
|
||||
key,
|
||||
ime_key: None,
|
||||
},
|
||||
}));
|
||||
}
|
||||
focused_window.handle_input(PlatformInput::KeyUp(KeyUpEvent {
|
||||
keystroke: Keystroke {
|
||||
modifiers: state.modifiers,
|
||||
key,
|
||||
ime_key,
|
||||
},
|
||||
}));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
wl_keyboard::Event::Leave { .. } => {
|
||||
state.modifiers = Modifiers {
|
||||
control: false,
|
||||
alt: false,
|
||||
shift: false,
|
||||
command: false,
|
||||
function: false,
|
||||
};
|
||||
}
|
||||
wl_keyboard::Event::Leave { .. } => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -568,13 +532,7 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientState {
|
|||
focused_window.handle_input(PlatformInput::MouseUp(MouseUpEvent {
|
||||
button: linux_button_to_gpui(button),
|
||||
position: *mouse_location,
|
||||
modifiers: Modifiers {
|
||||
shift: false,
|
||||
control: false,
|
||||
alt: false,
|
||||
function: false,
|
||||
command: false,
|
||||
},
|
||||
modifiers: Modifiers::default(),
|
||||
click_count: 1,
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -71,8 +71,8 @@ impl WaylandWindowInner {
|
|||
bounds: Bounds<i32>,
|
||||
) -> Self {
|
||||
let raw = RawWindow {
|
||||
window: wl_surf.id().as_ptr() as *mut _,
|
||||
display: conn.backend().display_ptr() as *mut _,
|
||||
window: wl_surf.id().as_ptr().cast::<c_void>(),
|
||||
display: conn.backend().display_ptr().cast::<c_void>(),
|
||||
};
|
||||
let gpu = Arc::new(
|
||||
unsafe {
|
||||
|
@ -204,7 +204,9 @@ impl WaylandWindowState {
|
|||
if let PlatformInput::KeyDown(event) = input {
|
||||
let mut inner = self.inner.lock();
|
||||
if let Some(ref mut input_handler) = inner.input_handler {
|
||||
input_handler.replace_text_in_range(None, &event.keystroke.key);
|
||||
if let Some(ime_key) = &event.keystroke.ime_key {
|
||||
input_handler.replace_text_in_range(None, ime_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue