1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 21:32:13 +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)));
}
}
input_map
.lookup_key(key, mods, None)
.map(|entry| (entry, None))
None
}
pub fn did_process_key(&mut self) {
@ -148,6 +146,32 @@ impl super::TermWindow {
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(
&mut self,
pane: &Rc<dyn Pane>,
@ -180,11 +204,9 @@ impl super::TermWindow {
}
if is_down {
if let Some((entry, table_name)) = self.key_table_state.lookup_key(
&self.input_map,
&keycode,
raw_modifiers | leader_mod,
) {
if let Some((entry, table_name)) =
self.lookup_key(pane, &keycode, raw_modifiers | leader_mod)
{
if self.config.debug_key_events {
log::info!(
"{}{:?} {:?} -> perform {:?}",

View File

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