mirror of
https://github.com/wez/wezterm.git
synced 2024-09-20 11:17:15 +03:00
window: adjust xkb handling for future RawKeyEvent support
This moves the event dispatching into the keyboard processor, which will allow for the processor to skip feeding an event into the dead key/composition stuff if a key assignment is handled. It doesn't actually do that bit yet though, as the wayland key repeat processing was a bit more involved and I wanted to constrain the scope of this commit. refs: #877
This commit is contained in:
parent
d5726ba91a
commit
6feabb8178
@ -116,6 +116,12 @@ impl WindowState {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum WindowKeyEvent {
|
||||
RawKeyEvent(RawKeyEvent),
|
||||
KeyEvent(KeyEvent),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum WindowEvent {
|
||||
/// Called when the window close button is clicked.
|
||||
|
@ -6,7 +6,7 @@ use crate::os::wayland::connection::WaylandConnection;
|
||||
use crate::os::x11::keyboard::Keyboard;
|
||||
use crate::{
|
||||
Clipboard, Connection, Dimensions, MouseCursor, Point, ScreenPoint, Window, WindowEvent,
|
||||
WindowEventSender, WindowOps, WindowState,
|
||||
WindowEventSender, WindowKeyEvent, WindowOps, WindowState,
|
||||
};
|
||||
use anyhow::{anyhow, bail, Context};
|
||||
use async_io::Timer;
|
||||
@ -41,7 +41,7 @@ use wezterm_input_types::*;
|
||||
#[derive(Debug)]
|
||||
struct KeyRepeatState {
|
||||
when: Instant,
|
||||
key: KeyEvent,
|
||||
event: WindowKeyEvent,
|
||||
}
|
||||
|
||||
impl KeyRepeatState {
|
||||
@ -82,9 +82,8 @@ impl KeyRepeatState {
|
||||
}
|
||||
|
||||
let mut st = state.lock().unwrap();
|
||||
let mut event = st.key.clone();
|
||||
|
||||
event.repeat_count = 1;
|
||||
let mut repeat_count = 1;
|
||||
|
||||
let mut elapsed = st.when.elapsed();
|
||||
if initial {
|
||||
@ -96,10 +95,22 @@ impl KeyRepeatState {
|
||||
// gap, we need to inflate the repeat count to match
|
||||
// the intended rate
|
||||
while elapsed >= gap {
|
||||
event.repeat_count += 1;
|
||||
repeat_count += 1;
|
||||
elapsed -= gap;
|
||||
}
|
||||
inner.events.dispatch(WindowEvent::KeyEvent(event));
|
||||
|
||||
let event = match st.event.clone() {
|
||||
WindowKeyEvent::KeyEvent(mut key) => {
|
||||
key.repeat_count = repeat_count;
|
||||
WindowEvent::KeyEvent(key)
|
||||
}
|
||||
WindowKeyEvent::RawKeyEvent(mut raw) => {
|
||||
raw.repeat_count = repeat_count;
|
||||
WindowEvent::RawKeyEvent(raw)
|
||||
}
|
||||
};
|
||||
|
||||
inner.events.dispatch(event);
|
||||
|
||||
st.when = Instant::now();
|
||||
}
|
||||
@ -400,18 +411,15 @@ impl WaylandWindowInner {
|
||||
self.emit_focus(mapper, false);
|
||||
}
|
||||
WlKeyboardEvent::Key { key, state, .. } => {
|
||||
if let Some(event) = mapper.process_wayland_key(key, state == KeyState::Pressed) {
|
||||
if event.key_is_down && mapper.wayland_key_repeats(key) {
|
||||
let rep = Arc::new(Mutex::new(KeyRepeatState {
|
||||
when: Instant::now(),
|
||||
key: event.clone(),
|
||||
}));
|
||||
self.key_repeat.replace(Arc::clone(&rep));
|
||||
KeyRepeatState::schedule(rep, self.window_id);
|
||||
} else {
|
||||
self.key_repeat.take();
|
||||
}
|
||||
self.events.dispatch(WindowEvent::KeyEvent(event));
|
||||
if let Some(event) =
|
||||
mapper.process_wayland_key(key, state == KeyState::Pressed, &mut self.events)
|
||||
{
|
||||
let rep = Arc::new(Mutex::new(KeyRepeatState {
|
||||
when: Instant::now(),
|
||||
event,
|
||||
}));
|
||||
self.key_repeat.replace(Arc::clone(&rep));
|
||||
KeyRepeatState::schedule(rep, self.window_id);
|
||||
} else {
|
||||
self.key_repeat.take();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::os::xkeysyms::keysym_to_keycode;
|
||||
use crate::{KeyEvent, Modifiers};
|
||||
use crate::{KeyEvent, Modifiers, WindowEvent, WindowEventSender, WindowKeyEvent};
|
||||
use anyhow::{anyhow, ensure};
|
||||
use libc;
|
||||
use std::cell::RefCell;
|
||||
@ -146,18 +146,30 @@ impl Keyboard {
|
||||
self.keymap.borrow().key_repeats(code + 8)
|
||||
}
|
||||
|
||||
pub fn process_wayland_key(&self, code: u32, pressed: bool) -> Option<KeyEvent> {
|
||||
self.process_key_event_impl(code + 8, pressed)
|
||||
pub fn process_wayland_key(
|
||||
&self,
|
||||
code: u32,
|
||||
pressed: bool,
|
||||
events: &mut WindowEventSender,
|
||||
) -> Option<WindowKeyEvent> {
|
||||
let want_repeat = self.wayland_key_repeats(code);
|
||||
self.process_key_event_impl(code + 8, pressed, events, want_repeat)
|
||||
}
|
||||
|
||||
pub fn process_key_event(&self, xcb_ev: &xcb::KeyPressEvent) -> Option<KeyEvent> {
|
||||
pub fn process_key_event(&self, xcb_ev: &xcb::KeyPressEvent, events: &mut WindowEventSender) {
|
||||
let pressed = (xcb_ev.response_type() & !0x80) == xcb::KEY_PRESS;
|
||||
|
||||
let xcode = xkb::Keycode::from(xcb_ev.detail());
|
||||
self.process_key_event_impl(xcode, pressed)
|
||||
self.process_key_event_impl(xcode, pressed, events, false);
|
||||
}
|
||||
|
||||
fn process_key_event_impl(&self, xcode: xkb::Keycode, pressed: bool) -> Option<KeyEvent> {
|
||||
fn process_key_event_impl(
|
||||
&self,
|
||||
xcode: xkb::Keycode,
|
||||
pressed: bool,
|
||||
events: &mut WindowEventSender,
|
||||
want_repeat: bool,
|
||||
) -> Option<WindowKeyEvent> {
|
||||
let xsym = self.state.borrow().key_get_one_sym(xcode);
|
||||
|
||||
let mut kc = None;
|
||||
@ -216,19 +228,26 @@ impl Keyboard {
|
||||
(_, mods) => mods,
|
||||
};
|
||||
|
||||
Some(
|
||||
KeyEvent {
|
||||
key: kc,
|
||||
modifiers,
|
||||
raw_key: None,
|
||||
raw_modifiers,
|
||||
raw_code: Some(xcode),
|
||||
phys_code: self.phys_code_map.borrow().get(&xcode).copied(),
|
||||
repeat_count: 1,
|
||||
key_is_down: pressed,
|
||||
}
|
||||
.normalize_ctrl(),
|
||||
)
|
||||
let event = KeyEvent {
|
||||
key: kc,
|
||||
modifiers,
|
||||
raw_key: None,
|
||||
raw_modifiers,
|
||||
raw_code: Some(xcode),
|
||||
phys_code: self.phys_code_map.borrow().get(&xcode).copied(),
|
||||
repeat_count: 1,
|
||||
key_is_down: pressed,
|
||||
}
|
||||
.normalize_ctrl();
|
||||
|
||||
if pressed && want_repeat {
|
||||
events.dispatch(WindowEvent::KeyEvent(event.clone()));
|
||||
// Returns the event that should be repeated later
|
||||
Some(WindowKeyEvent::KeyEvent(event))
|
||||
} else {
|
||||
events.dispatch(WindowEvent::KeyEvent(event));
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn mod_is_active(&self, modifier: &str) -> bool {
|
||||
|
@ -269,10 +269,7 @@ impl XWindowInner {
|
||||
xcb::KEY_PRESS | xcb::KEY_RELEASE => {
|
||||
let key_press: &xcb::KeyPressEvent = unsafe { xcb::cast_event(event) };
|
||||
self.copy_and_paste.time = key_press.time();
|
||||
if let Some(key) = conn.keyboard.process_key_event(key_press) {
|
||||
let key = key.normalize_shift();
|
||||
self.events.dispatch(WindowEvent::KeyEvent(key));
|
||||
}
|
||||
conn.keyboard.process_key_event(key_press, &mut self.events);
|
||||
}
|
||||
|
||||
xcb::MOTION_NOTIFY => {
|
||||
|
Loading…
Reference in New Issue
Block a user