1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 22:01:47 +03:00

termwiz/term: introduce KeyboardEncoding enum, existence of win32-input-mode

This is a baby step that formalizes the different encoding schemes into
an enum, and hooks up the decset sequence for win32-input-mode.

It doesn't change any of the actual encoding at this time.

refs: #1509
This commit is contained in:
Wez Furlong 2022-01-06 07:50:49 -07:00
parent ca0e358262
commit 51aec27ec2
5 changed files with 54 additions and 11 deletions

View File

@ -1,8 +1,17 @@
use crate::input::*; use crate::input::*;
use crate::TerminalState; use crate::TerminalState;
use termwiz::input::KeyCodeEncodeModes; use termwiz::input::{KeyCodeEncodeModes, KeyboardEncoding};
impl TerminalState { impl TerminalState {
fn effective_keyboard_encoding(&self) -> KeyboardEncoding {
match self.keyboard_encoding {
KeyboardEncoding::Xterm if self.config.enable_csi_u_key_encoding() => {
KeyboardEncoding::CsiU
}
enc => enc,
}
}
/// Processes a key_down event generated by the gui/render layer /// Processes a key_down event generated by the gui/render layer
/// that is embedding the Terminal. This method translates the /// that is embedding the Terminal. This method translates the
/// keycode into a sequence of bytes to send to the slave end /// keycode into a sequence of bytes to send to the slave end
@ -11,7 +20,7 @@ impl TerminalState {
let to_send = key.encode( let to_send = key.encode(
mods, mods,
KeyCodeEncodeModes { KeyCodeEncodeModes {
enable_csi_u_key_encoding: self.config.enable_csi_u_key_encoding(), encoding: self.effective_keyboard_encoding(),
newline_mode: self.newline_mode, newline_mode: self.newline_mode,
application_cursor_keys: self.application_cursor_keys, application_cursor_keys: self.application_cursor_keys,
}, },

View File

@ -17,6 +17,7 @@ use termwiz::escape::csi::{
}; };
use termwiz::escape::{OneBased, OperatingSystemCommand, CSI}; use termwiz::escape::{OneBased, OperatingSystemCommand, CSI};
use termwiz::image::ImageData; use termwiz::image::ImageData;
use termwiz::input::KeyboardEncoding;
use termwiz::surface::{CursorShape, CursorVisibility, SequenceNo}; use termwiz::surface::{CursorShape, CursorVisibility, SequenceNo};
use url::Url; use url::Url;
@ -314,6 +315,7 @@ pub struct TerminalState {
last_mouse_move: Option<MouseEvent>, last_mouse_move: Option<MouseEvent>,
cursor_visible: bool, cursor_visible: bool,
keyboard_encoding: KeyboardEncoding,
/// Support for US, UK, and DEC Special Graphics /// Support for US, UK, and DEC Special Graphics
g0_charset: CharSet, g0_charset: CharSet,
g1_charset: CharSet, g1_charset: CharSet,
@ -469,6 +471,7 @@ impl TerminalState {
bracketed_paste: false, bracketed_paste: false,
focus_tracking: false, focus_tracking: false,
mouse_encoding: MouseEncoding::X10, mouse_encoding: MouseEncoding::X10,
keyboard_encoding: KeyboardEncoding::Xterm,
sixel_scrolls_right: false, sixel_scrolls_right: false,
any_event_mouse: false, any_event_mouse: false,
button_event_mouse: false, button_event_mouse: false,
@ -1211,6 +1214,22 @@ impl TerminalState {
// We leave key repeat to the GUI layer prefs // We leave key repeat to the GUI layer prefs
} }
Mode::SetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::Win32InputMode)) => {
self.keyboard_encoding = KeyboardEncoding::Win32;
}
Mode::ResetDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::Win32InputMode)) => {
self.keyboard_encoding = KeyboardEncoding::Xterm;
}
Mode::QueryDecPrivateMode(DecPrivateMode::Code(DecPrivateModeCode::Win32InputMode)) => {
self.decqrm_response(
mode,
true,
self.keyboard_encoding == KeyboardEncoding::Win32,
);
}
Mode::SetDecPrivateMode(DecPrivateMode::Code( Mode::SetDecPrivateMode(DecPrivateMode::Code(
DecPrivateModeCode::ReverseWraparound, DecPrivateModeCode::ReverseWraparound,
)) => { )) => {

View File

@ -17,6 +17,7 @@ use termwiz::escape::osc::{
use termwiz::escape::{ use termwiz::escape::{
Action, ControlCode, DeviceControlMode, Esc, EscCode, OperatingSystemCommand, CSI, Action, ControlCode, DeviceControlMode, Esc, EscCode, OperatingSystemCommand, CSI,
}; };
use termwiz::input::KeyboardEncoding;
use url::Url; use url::Url;
/// A helper struct for implementing `vtparse::VTActor` while compartmentalizing /// A helper struct for implementing `vtparse::VTActor` while compartmentalizing
@ -516,6 +517,7 @@ impl<'a> Performer<'a> {
self.bracketed_paste = false; self.bracketed_paste = false;
self.focus_tracking = false; self.focus_tracking = false;
self.mouse_encoding = MouseEncoding::X10; self.mouse_encoding = MouseEncoding::X10;
self.keyboard_encoding = KeyboardEncoding::Xterm;
self.sixel_scrolls_right = false; self.sixel_scrolls_right = false;
self.any_event_mouse = false; self.any_event_mouse = false;
self.button_event_mouse = false; self.button_event_mouse = false;

View File

@ -757,6 +757,10 @@ pub enum DecPrivateModeCode {
/// xterm: adjust cursor positioning after emitting sixel /// xterm: adjust cursor positioning after emitting sixel
SixelScrollsRight = 8452, SixelScrollsRight = 8452,
/// Windows Terminal: win32-input-mode
/// <https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md>
Win32InputMode = 9001,
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]

View File

@ -15,11 +15,20 @@ use std::fmt::Write;
pub const CSI: &str = "\x1b["; pub const CSI: &str = "\x1b[";
pub const SS3: &str = "\x1bO"; pub const SS3: &str = "\x1bO";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyboardEncoding {
Xterm,
/// <http://www.leonerd.org.uk/hacks/fixterms/>
CsiU,
/// <https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md>
Win32,
}
/// Specifies terminal modes/configuration that can influence how a KeyCode /// Specifies terminal modes/configuration that can influence how a KeyCode
/// is encoded when being sent to and application via the pty. /// is encoded when being sent to and application via the pty.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct KeyCodeEncodeModes { pub struct KeyCodeEncodeModes {
pub enable_csi_u_key_encoding: bool, pub encoding: KeyboardEncoding,
pub application_cursor_keys: bool, pub application_cursor_keys: bool,
pub newline_mode: bool, pub newline_mode: bool,
} }
@ -275,12 +284,12 @@ impl KeyCode {
Char(c) Char(c)
if is_ambiguous_ascii_ctrl(c) if is_ambiguous_ascii_ctrl(c)
&& mods.contains(Modifiers::CTRL) && mods.contains(Modifiers::CTRL)
&& modes.enable_csi_u_key_encoding => && modes.encoding == KeyboardEncoding::CsiU =>
{ {
csi_u_encode(&mut buf, c, mods, modes.enable_csi_u_key_encoding)?; csi_u_encode(&mut buf, c, mods, modes.encoding)?;
} }
Char(c) if c.is_ascii_uppercase() && mods.contains(Modifiers::CTRL) => { Char(c) if c.is_ascii_uppercase() && mods.contains(Modifiers::CTRL) => {
csi_u_encode(&mut buf, c, mods, modes.enable_csi_u_key_encoding)?; csi_u_encode(&mut buf, c, mods, modes.encoding)?;
} }
Char(c) if mods.contains(Modifiers::CTRL) && ctrl_mapping(c).is_some() => { Char(c) if mods.contains(Modifiers::CTRL) && ctrl_mapping(c).is_some() => {
@ -314,7 +323,7 @@ impl KeyCode {
_ => unreachable!(), _ => unreachable!(),
}; };
if mods.contains(Modifiers::SHIFT) || mods.contains(Modifiers::CTRL) { if mods.contains(Modifiers::SHIFT) || mods.contains(Modifiers::CTRL) {
csi_u_encode(&mut buf, c, mods, modes.enable_csi_u_key_encoding)?; csi_u_encode(&mut buf, c, mods, modes.encoding)?;
} else { } else {
if mods.contains(Modifiers::ALT) { if mods.contains(Modifiers::ALT) {
buf.push(0x1b as char); buf.push(0x1b as char);
@ -346,7 +355,7 @@ impl KeyCode {
if mods.is_empty() { if mods.is_empty() {
buf.push(c); buf.push(c);
} else { } else {
csi_u_encode(&mut buf, c, mods, modes.enable_csi_u_key_encoding)?; csi_u_encode(&mut buf, c, mods, modes.encoding)?;
} }
} }
@ -555,9 +564,9 @@ fn csi_u_encode(
buf: &mut String, buf: &mut String,
c: char, c: char,
mods: Modifiers, mods: Modifiers,
enable_csi_u_key_encoding: bool, encoding: KeyboardEncoding,
) -> Result<()> { ) -> Result<()> {
if enable_csi_u_key_encoding { if encoding == KeyboardEncoding::CsiU {
write!(buf, "\x1b[{};{}u", c as u32, 1 + encode_modifiers(mods))?; write!(buf, "\x1b[{};{}u", c as u32, 1 + encode_modifiers(mods))?;
} else { } else {
let c = if mods.contains(Modifiers::CTRL) && ctrl_mapping(c).is_some() { let c = if mods.contains(Modifiers::CTRL) && ctrl_mapping(c).is_some() {
@ -1522,7 +1531,7 @@ mod test {
#[test] #[test]
fn encode_issue_892() { fn encode_issue_892() {
let mode = KeyCodeEncodeModes { let mode = KeyCodeEncodeModes {
enable_csi_u_key_encoding: false, encoding: KeyboardEncoding::Xterm,
newline_mode: false, newline_mode: false,
application_cursor_keys: false, application_cursor_keys: false,
}; };