1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-22 22:42:48 +03:00

When a modal is active, it gets first dibs on key processing

This fixes a surprising interaction between copy mode and the
command palette, but is also the root cause of another issue
with CharSelect mode.

refs: https://github.com/wez/wezterm/issues/2947
This commit is contained in:
Wez Furlong 2023-03-25 18:24:26 -07:00
parent 500934bc9c
commit d491c736ef
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387
6 changed files with 35 additions and 24 deletions

View File

@ -70,6 +70,9 @@ As features stabilize some brief notes about them will accumulate here.
* macOS: key assignments that were routed via the macOS menubar didn't guarantee
to invalidate the associated window, making it look like they had no effect
or hung. #3365
* `CTRL-SHIFT-R` assignment in `CharSelect` mode didn't cycle back through
the emoji categories as intended, but performed the global `ReloadConfiguration`
action instead. #2947
#### Updated
* Bundled JetBrainsMono to 2.304. #3362

View File

@ -554,7 +554,7 @@ impl Modal for CharSelector {
key: KeyCode,
mods: KeyModifiers,
term_window: &mut TermWindow,
) -> anyhow::Result<()> {
) -> anyhow::Result<bool> {
const CTRL_AND_SHIFT: Modifiers = KeyModifiers::CTRL.union(KeyModifiers::SHIFT);
match (key, mods) {
@ -603,10 +603,10 @@ impl Modal for CharSelector {
// Enter the selected character to the current pane
let selected_idx = *self.selected_row.borrow();
let alias_idx = match self.matches.borrow().as_ref() {
None => return Ok(()),
None => return Ok(true),
Some(results) => match results.matches.get(selected_idx) {
Some(i) => *i,
None => return Ok(()),
None => return Ok(true),
},
};
let item = &self.aliases[alias_idx];
@ -627,12 +627,12 @@ impl Modal for CharSelector {
pane.writer().write_all(glyph.as_bytes()).ok();
}
term_window.cancel_modal();
return Ok(());
return Ok(true);
}
_ => return Ok(()),
_ => return Ok(false),
}
term_window.invalidate_modal();
Ok(())
Ok(true)
}
fn computed_element(

View File

@ -287,6 +287,20 @@ impl super::TermWindow {
}
if is_down {
if let Some(modal) = self.get_modal() {
if let Key::Code(term_key) = self.win_key_code_to_termwiz_key_code(keycode) {
let tw_raw_modifiers = window_mods_to_termwiz_mods(raw_modifiers);
match modal.key_down(term_key, tw_raw_modifiers, self) {
Ok(true) => return true,
Ok(false) => {}
Err(err) => {
log::error!("Error dispatching key to modal: {err:#}");
return true;
}
}
}
}
if let Some((entry, table_name)) = self.lookup_key(
pane,
&keycode,
@ -371,13 +385,6 @@ impl super::TermWindow {
);
}
if let Some(modal) = self.get_modal() {
if is_down {
return modal.key_down(term_key, tw_raw_modifiers, self).is_ok();
}
return false;
}
let res = if is_down {
pane.key_down(term_key, tw_raw_modifiers)
} else {

View File

@ -19,7 +19,7 @@ pub trait Modal: Downcast {
key: KeyCode,
mods: KeyModifiers,
term_window: &mut TermWindow,
) -> anyhow::Result<()>;
) -> anyhow::Result<bool>;
fn computed_element(
&self,
term_window: &mut TermWindow,

View File

@ -533,7 +533,7 @@ impl Modal for CommandPalette {
key: KeyCode,
mods: KeyModifiers,
term_window: &mut TermWindow,
) -> anyhow::Result<()> {
) -> anyhow::Result<bool> {
match (key, mods) {
(KeyCode::Escape, KeyModifiers::NONE) | (KeyCode::Char('g'), KeyModifiers::CTRL) => {
term_window.cancel_modal();
@ -566,10 +566,10 @@ impl Modal for CommandPalette {
// Enter the selected character to the current pane
let selected_idx = *self.selected_row.borrow();
let alias_idx = match self.matches.borrow().as_ref() {
None => return Ok(()),
None => return Ok(true),
Some(results) => match results.matches.get(selected_idx) {
Some(i) => *i,
None => return Ok(()),
None => return Ok(true),
},
};
let item = &self.commands[alias_idx];
@ -583,12 +583,12 @@ impl Modal for CommandPalette {
log::error!("Error while performing {item:?}: {err:#}");
}
}
return Ok(());
return Ok(true);
}
_ => return Ok(()),
_ => return Ok(false),
}
term_window.invalidate_modal();
Ok(())
Ok(true)
}
fn computed_element(

View File

@ -190,7 +190,7 @@ impl Modal for PaneSelector {
key: KeyCode,
mods: KeyModifiers,
term_window: &mut TermWindow,
) -> anyhow::Result<()> {
) -> anyhow::Result<bool> {
match (key, mods) {
(KeyCode::Escape, KeyModifiers::NONE) | (KeyCode::Char('g'), KeyModifiers::CTRL) => {
term_window.cancel_modal();
@ -203,7 +203,8 @@ impl Modal for PaneSelector {
// and if we have a complete match, activate that pane
if let Some(pane_index) = self.labels.borrow().iter().position(|s| s == &*selection)
{
return self.perform_selection(pane_index, term_window);
self.perform_selection(pane_index, term_window)?;
return Ok(true);
}
}
(KeyCode::Backspace, KeyModifiers::NONE) => {
@ -216,9 +217,9 @@ impl Modal for PaneSelector {
let mut selection = self.selection.borrow_mut();
selection.clear();
}
_ => {}
_ => return Ok(false),
}
Ok(())
Ok(true)
}
fn computed_element(