1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 21:32:13 +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::TerminalState;
use termwiz::input::KeyCodeEncodeModes;
use termwiz::input::{KeyCodeEncodeModes, KeyboardEncoding};
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
/// that is embedding the Terminal. This method translates the
/// keycode into a sequence of bytes to send to the slave end
@ -11,7 +20,7 @@ impl TerminalState {
let to_send = key.encode(
mods,
KeyCodeEncodeModes {
enable_csi_u_key_encoding: self.config.enable_csi_u_key_encoding(),
encoding: self.effective_keyboard_encoding(),
newline_mode: self.newline_mode,
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::image::ImageData;
use termwiz::input::KeyboardEncoding;
use termwiz::surface::{CursorShape, CursorVisibility, SequenceNo};
use url::Url;
@ -314,6 +315,7 @@ pub struct TerminalState {
last_mouse_move: Option<MouseEvent>,
cursor_visible: bool,
keyboard_encoding: KeyboardEncoding,
/// Support for US, UK, and DEC Special Graphics
g0_charset: CharSet,
g1_charset: CharSet,
@ -469,6 +471,7 @@ impl TerminalState {
bracketed_paste: false,
focus_tracking: false,
mouse_encoding: MouseEncoding::X10,
keyboard_encoding: KeyboardEncoding::Xterm,
sixel_scrolls_right: false,
any_event_mouse: false,
button_event_mouse: false,
@ -1211,6 +1214,22 @@ impl TerminalState {
// 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(
DecPrivateModeCode::ReverseWraparound,
)) => {

View File

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

View File

@ -757,6 +757,10 @@ pub enum DecPrivateModeCode {
/// xterm: adjust cursor positioning after emitting sixel
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)]

View File

@ -15,11 +15,20 @@ use std::fmt::Write;
pub const CSI: &str = "\x1b[";
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
/// is encoded when being sent to and application via the pty.
#[derive(Debug, Clone, Copy)]
pub struct KeyCodeEncodeModes {
pub enable_csi_u_key_encoding: bool,
pub encoding: KeyboardEncoding,
pub application_cursor_keys: bool,
pub newline_mode: bool,
}
@ -275,12 +284,12 @@ impl KeyCode {
Char(c)
if is_ambiguous_ascii_ctrl(c)
&& 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) => {
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() => {
@ -314,7 +323,7 @@ impl KeyCode {
_ => unreachable!(),
};
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 {
if mods.contains(Modifiers::ALT) {
buf.push(0x1b as char);
@ -346,7 +355,7 @@ impl KeyCode {
if mods.is_empty() {
buf.push(c);
} 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,
c: char,
mods: Modifiers,
enable_csi_u_key_encoding: bool,
encoding: KeyboardEncoding,
) -> Result<()> {
if enable_csi_u_key_encoding {
if encoding == KeyboardEncoding::CsiU {
write!(buf, "\x1b[{};{}u", c as u32, 1 + encode_modifiers(mods))?;
} else {
let c = if mods.contains(Modifiers::CTRL) && ctrl_mapping(c).is_some() {
@ -1522,7 +1531,7 @@ mod test {
#[test]
fn encode_issue_892() {
let mode = KeyCodeEncodeModes {
enable_csi_u_key_encoding: false,
encoding: KeyboardEncoding::Xterm,
newline_mode: false,
application_cursor_keys: false,
};