1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 13:52:55 +03:00

overlays: improve key_table handling

This commit re-arranges the code so that an overlay can have a local
stack of key table activations; this allows copy_mode and search_mode
key tables to layer on top of the user's window level key tables.

Previously, we'd just stick the search_mode entry on top of the global
state, which worked, but had the undesirable side effect of hijacking
the Enter key when switching to another tab in the window.

refs: https://github.com/wez/wezterm/issues/993
This commit is contained in:
Wez Furlong 2022-05-06 17:57:55 -07:00
parent f56345cba4
commit 89e427bd79
2 changed files with 55 additions and 25 deletions

View File

@ -82,9 +82,7 @@ impl KeyTableState {
return Some((entry, Some(name))); return Some((entry, Some(name)));
} }
} }
input_map None
.lookup_key(key, mods, None)
.map(|entry| (entry, None))
} }
pub fn did_process_key(&mut self) { pub fn did_process_key(&mut self) {
@ -148,6 +146,32 @@ impl super::TermWindow {
key.encode_win32_input_mode() key.encode_win32_input_mode()
} }
fn lookup_key(
&mut self,
pane: &Rc<dyn Pane>,
keycode: &KeyCode,
mods: Modifiers,
) -> Option<(KeyTableEntry, Option<String>)> {
if let Some(overlay) = self.pane_state(pane.pane_id()).overlay.as_mut() {
if let Some((entry, table_name)) =
overlay
.key_table_state
.lookup_key(&self.input_map, keycode, mods)
{
return Some((entry, table_name.map(|s| s.to_string())));
}
}
if let Some((entry, table_name)) =
self.key_table_state
.lookup_key(&self.input_map, keycode, mods)
{
return Some((entry, table_name.map(|s| s.to_string())));
}
self.input_map
.lookup_key(keycode, mods, None)
.map(|entry| (entry, None))
}
fn process_key( fn process_key(
&mut self, &mut self,
pane: &Rc<dyn Pane>, pane: &Rc<dyn Pane>,
@ -180,11 +204,9 @@ impl super::TermWindow {
} }
if is_down { if is_down {
if let Some((entry, table_name)) = self.key_table_state.lookup_key( if let Some((entry, table_name)) =
&self.input_map, self.lookup_key(pane, &keycode, raw_modifiers | leader_mod)
&keycode, {
raw_modifiers | leader_mod,
) {
if self.config.debug_key_events { if self.config.debug_key_events {
log::info!( log::info!(
"{}{:?} {:?} -> perform {:?}", "{}{:?} {:?} -> perform {:?}",

View File

@ -161,7 +161,7 @@ pub struct SemanticZoneCache {
pub struct OverlayState { pub struct OverlayState {
pub pane: Rc<dyn Pane>, pub pane: Rc<dyn Pane>,
saved_key_table_state: KeyTableState, key_table_state: KeyTableState,
} }
#[derive(Default)] #[derive(Default)]
@ -2272,8 +2272,17 @@ impl TermWindow {
); );
self.assign_overlay_for_pane(pane.pane_id(), search); self.assign_overlay_for_pane(pane.pane_id(), search);
} }
self.key_table_state self.pane_state(pane.pane_id())
.activate("search_mode", None, replace_current, false); .overlay
.as_mut()
.map(|overlay| {
overlay.key_table_state.activate(
"search_mode",
None,
replace_current,
false,
);
});
} }
} }
QuickSelect => { QuickSelect => {
@ -2311,8 +2320,17 @@ impl TermWindow {
); );
self.assign_overlay_for_pane(pane.pane_id(), copy); self.assign_overlay_for_pane(pane.pane_id(), copy);
} }
self.key_table_state self.pane_state(pane.pane_id())
.activate("copy_mode", None, replace_current, false); .overlay
.as_mut()
.map(|overlay| {
overlay.key_table_state.activate(
"copy_mode",
None,
replace_current,
false,
);
});
} }
} }
AdjustPaneSize(direction, amount) => { AdjustPaneSize(direction, amount) => {
@ -2815,14 +2833,9 @@ impl TermWindow {
return; return;
} }
} }
let mut key_table = None;
if let Some(overlay) = self.tab_state(tab_id).overlay.take() { if let Some(overlay) = self.tab_state(tab_id).overlay.take() {
key_table.replace(overlay.saved_key_table_state);
Mux::get().unwrap().remove_pane(overlay.pane.pane_id()); Mux::get().unwrap().remove_pane(overlay.pane.pane_id());
} }
if let Some(key_table) = key_table.take() {
self.key_table_state = key_table;
}
if let Some(window) = self.window.as_ref() { if let Some(window) = self.window.as_ref() {
window.invalidate(); window.invalidate();
} }
@ -2833,7 +2846,6 @@ impl TermWindow {
} }
fn cancel_overlay_for_pane(&mut self, pane_id: PaneId) { fn cancel_overlay_for_pane(&mut self, pane_id: PaneId) {
let mut key_table = None;
if let Some(overlay) = self.pane_state(pane_id).overlay.take() { if let Some(overlay) = self.pane_state(pane_id).overlay.take() {
// Ungh, when I built the CopyOverlay, its pane doesn't get // Ungh, when I built the CopyOverlay, its pane doesn't get
// added to the mux and instead it reports the overlaid // added to the mux and instead it reports the overlaid
@ -2842,10 +2854,6 @@ impl TermWindow {
if pane_id != overlay.pane.pane_id() { if pane_id != overlay.pane.pane_id() {
Mux::get().unwrap().remove_pane(overlay.pane.pane_id()); Mux::get().unwrap().remove_pane(overlay.pane.pane_id());
} }
key_table.replace(overlay.saved_key_table_state);
}
if let Some(key_table) = key_table.take() {
self.key_table_state = key_table;
} }
if let Some(window) = self.window.as_ref() { if let Some(window) = self.window.as_ref() {
window.invalidate(); window.invalidate();
@ -2860,7 +2868,7 @@ impl TermWindow {
self.cancel_overlay_for_pane(pane_id); self.cancel_overlay_for_pane(pane_id);
self.pane_state(pane_id).overlay.replace(OverlayState { self.pane_state(pane_id).overlay.replace(OverlayState {
pane, pane,
saved_key_table_state: self.key_table_state.clone(), key_table_state: KeyTableState::default(),
}); });
self.update_title(); self.update_title();
} }
@ -2869,7 +2877,7 @@ impl TermWindow {
self.cancel_overlay_for_tab(tab_id, None); self.cancel_overlay_for_tab(tab_id, None);
self.tab_state(tab_id).overlay.replace(OverlayState { self.tab_state(tab_id).overlay.replace(OverlayState {
pane: overlay, pane: overlay,
saved_key_table_state: self.key_table_state.clone(), key_table_state: KeyTableState::default(),
}); });
self.update_title(); self.update_title();
} }