Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iterm2 rich keyboard protocol support #1610

Merged
merged 40 commits into from
Apr 14, 2023
Merged
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
b2b8cd3
highly experimental support for iTerm2 input mode
unxed Apr 9, 2023
16ba0fc
Merge branch 'elfmz:master' into iterm2
unxed Apr 9, 2023
0843c59
merge kittys-keys fix
unxed Apr 9, 2023
04f3cbe
add more sequences (fixes F1, F2, F4 under WezTerm)
unxed Apr 9, 2023
eb9c84f
behave better on terminal focus lose
unxed Apr 10, 2023
3ca3f49
formatting
unxed Apr 10, 2023
5e459d3
Merge branch 'elfmz:master' into iterm2
unxed Apr 10, 2023
2ae121f
formatting
unxed Apr 10, 2023
d8b3e98
Merge branch 'iterm2' of https://github.com/unxed/far2l into iterm2
unxed Apr 10, 2023
c2f90f0
Merge branch 'elfmz:master' into iterm2
unxed Apr 10, 2023
7492f08
ignore unsupported esc sequences
unxed Apr 10, 2023
948c65a
Merge branch 'iterm2' of https://github.com/unxed/far2l into iterm2
unxed Apr 10, 2023
c4198fa
add flags change seqs support; debug output added
unxed Apr 10, 2023
bd9fe7a
map forwarddelete to backspace
unxed Apr 10, 2023
bb725b7
better del handling
unxed Apr 10, 2023
0e9b133
trying to fix ctrl+numbers
unxed Apr 10, 2023
45e3b42
workaround keydown events does not arrive sometimes in iterm2
unxed Apr 10, 2023
f153da0
fix a typo
unxed Apr 10, 2023
29263d0
Merge branch 'elfmz:master' into iterm2
unxed Apr 10, 2023
f0923ac
map right Command to right Control
unxed Apr 10, 2023
7a1eb8c
Merge branch 'iterm2' of https://github.com/unxed/far2l into iterm2
unxed Apr 10, 2023
6742418
Merge branch 'elfmz:master' into iterm2
unxed Apr 10, 2023
7484c5c
more logging
unxed Apr 10, 2023
3cce5fc
instead of mapping right Command to right Control, use right Option f…
unxed Apr 11, 2023
a0c74c3
cmd+v not working in iterm2 in 1337 mode (looks like iterm2's bug). w…
unxed Apr 11, 2023
ac36104
fix some problems in iterm2 cmd+v workaround
unxed Apr 11, 2023
98737ca
naming
unxed Apr 11, 2023
593b53a
Merge branch 'elfmz:master' into iterm2
unxed Apr 11, 2023
9418d2d
cmd key state change is reproted by iterm2 not as keydown by as flags…
unxed Apr 12, 2023
837a43d
make iterm2 cmd+v hack more reliable
unxed Apr 12, 2023
cb72b6a
another try to fix iterm2 workaround
unxed Apr 12, 2023
138b9f7
add some logging
unxed Apr 12, 2023
3e59007
forgot to set go variable
unxed Apr 12, 2023
273bc92
debugging...
unxed Apr 12, 2023
07d1d72
another try to fix iterm2 workaround
unxed Apr 12, 2023
8b56ed0
remove debug stuff
unxed Apr 12, 2023
3c7e8ba
comment out debug stuff
unxed Apr 12, 2023
6437a8f
Merge branch 'elfmz:master' into iterm2
unxed Apr 12, 2023
a23df17
comments
unxed Apr 13, 2023
36a3354
Merge branch 'iterm2' of https://github.com/unxed/far2l into iterm2
unxed Apr 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add flags change seqs support; debug output added
unxed committed Apr 10, 2023
commit c4198fae75a1c90457e28f6f94516554c2fe8394
76 changes: 66 additions & 10 deletions WinPort/src/Backend/TTY/TTYInputSequenceParser.cpp
Original file line number Diff line number Diff line change
@@ -637,8 +637,16 @@ size_t TTYInputSequenceParser::TryParseAsWinTermEscapeSequence(const char *s, si
return n;
}

int flags_track = 0;

size_t TTYInputSequenceParser::TryParseAsiTerm2EscapeSequence(const char *s, size_t l)
{
fprintf(stderr, "iTerm2 parsing: ");
for (size_t i = 0; i < l && s[i] != '\0'; i++) {
fprintf(stderr, "%c", s[i]);
}
fprintf(stderr, "\n");

size_t len = 0;
while (1) {
if (len >= l) return TTY_PARSED_WANTMORE;
@@ -647,12 +655,55 @@ size_t TTYInputSequenceParser::TryParseAsiTerm2EscapeSequence(const char *s, siz
}
len++;

if (s[6] == 'f') { return len; } // flags change event unsupported for now, ignoring

unsigned int flags = 0;
unsigned int flags_length = 0;
sscanf(s + 8, "%i%n", &flags, &flags_length); // 8 is a fixed length of "]1337;d;"

flags -= 1;
unsigned int flags_win = 0;

// Flags changed event: esc ] 1337 ; f ; flags ^G
if (s[6] == 'f') {

bool go = false;
int vkc, vsc, kd, cks = 0;

if ((flags & 1) && !(flags_track & 1)) { go = 1; vkc = VK_SHIFT; kd = 1; cks |= SHIFT_PRESSED; }
if (!(flags & 1) && (flags_track & 1)) { go = 1; vkc = VK_SHIFT; kd = 0; }
if ((flags & 2) && !(flags_track & 2)) { go = 1; vkc = VK_SHIFT; kd = 1; cks |= SHIFT_PRESSED;
vsc = RIGHT_SHIFT_VSC; }
if (!(flags & 2) && (flags_track & 2)) { go = 1; vkc = VK_SHIFT; kd = 0; vsc = RIGHT_SHIFT_VSC; }

if ((flags & 4) && !(flags_track & 4)) { go = 1; vkc = VK_MENU; kd = 1; cks |= LEFT_ALT_PRESSED; }
if (!(flags & 4) && (flags_track & 4)) { go = 1; vkc = VK_MENU; kd = 0; }
if ((flags & 8) && !(flags_track & 8)) { go = 1; vkc = VK_MENU; kd = 1; cks |= RIGHT_ALT_PRESSED;
cks |= ENHANCED_KEY; }
if (!(flags & 8) && (flags_track & 8)) { go = 1; vkc = VK_MENU; kd = 0; cks |= ENHANCED_KEY; }

if ((flags & 16) && !(flags_track & 16)) { go = 1; vkc = VK_CONTROL; kd = 1; cks |= LEFT_CTRL_PRESSED; }
if (!(flags & 16) && (flags_track & 16)) { go = 1; vkc = VK_CONTROL; kd = 0; }
if ((flags & 32) && !(flags_track & 32)) { go = 1; vkc = VK_CONTROL; kd = 1; cks |= RIGHT_CTRL_PRESSED;
cks |= ENHANCED_KEY; }
if (!(flags & 32) && (flags_track & 32)) { go = 1; vkc = VK_CONTROL; kd = 0; cks |= ENHANCED_KEY; }

if (go) {
INPUT_RECORD ir = {0};
ir.EventType = KEY_EVENT;
ir.Event.KeyEvent.wVirtualKeyCode = vkc;
ir.Event.KeyEvent.wVirtualScanCode = vsc ? vsc :
WINPORT(MapVirtualKey)(ir.Event.KeyEvent.wVirtualKeyCode, MAPVK_VK_TO_VSC);
ir.Event.KeyEvent.bKeyDown = kd;
ir.Event.KeyEvent.dwControlKeyState = cks;
ir.Event.KeyEvent.wRepeatCount = 1;

_ir_pending.emplace_back(ir);
}

flags_track = flags;
return len;
}


wchar_t uni_char = 0;
unsigned char bytes[4] = {0};
int num_bytes = 0;
@@ -732,7 +783,7 @@ size_t TTYInputSequenceParser::TryParseAsiTerm2EscapeSequence(const char *s, siz
case 0x45: vkc = VK_ADD; break; // +
//case 0x47: vkc = ; break; // keypad "clear"
case 0x4B: vkc = VK_DIVIDE; break; // /
case 0x4C: vkc = VK_RETURN; break; // Enter // todo: set enhanced key flag
case 0x4C: vkc = VK_RETURN; break; // Enter
case 0x4E: vkc = VK_SUBTRACT; break; // -
//case 0x51: vkc = ; break; // keypad "equals"
case 0x52: vkc = 0x60; break; // 0
@@ -756,9 +807,9 @@ size_t TTYInputSequenceParser::TryParseAsiTerm2EscapeSequence(const char *s, siz
case 0x39: vkc = VK_CAPITAL; break; // CapsLock
case 0x3A: vkc = VK_MENU; break; // Option
case 0x3B: vkc = VK_CONTROL; break; // Control
case 0x3C: vkc = VK_SHIFT; break; // RightShift // todo: set special scan code
case 0x3D: vkc = VK_MENU; break; // RightOption // todo: set enhanced key flag
case 0x3E: vkc = VK_CONTROL; break; // RightControl // todo: set enhanced key flag
case 0x3C: vkc = VK_SHIFT; break; // RightShift
case 0x3D: vkc = VK_MENU; break; // RightOption
case 0x3E: vkc = VK_CONTROL; break; // RightControl
//case 0x3F: vkc = ; break; // Function
//case 0x40: vkc = ; break; // F17
//case 0x48: vkc = ; break; // VolumeUp
@@ -797,27 +848,32 @@ size_t TTYInputSequenceParser::TryParseAsiTerm2EscapeSequence(const char *s, siz

if (!vkc && uni_char) { vkc = VK_UNASSIGNED; }

flags -= 1;
unsigned int flags_win = 0;

if (flags & 1) { flags_win |= SHIFT_PRESSED; } // todo: LEFT_SHIFT_PRESSED
if (flags & 2) { flags_win |= SHIFT_PRESSED; } // todo: RIGHT_SHIFT_PRESSED
if (flags & 4) { flags_win |= LEFT_ALT_PRESSED; }
if (flags & 8) { flags_win |= RIGHT_ALT_PRESSED; }
if (flags & 16) { flags_win |= LEFT_CTRL_PRESSED; }
if (flags & 32) { flags_win |= RIGHT_CTRL_PRESSED; }

if (keycode == 0x3D) flags_win |= ENHANCED_KEY; // RightOption
if (keycode == 0x3E) flags_win |= ENHANCED_KEY; // RightControl
if (keycode == 0x4C) flags_win |= ENHANCED_KEY; // Numpad Enter

INPUT_RECORD ir = {};
ir.EventType = KEY_EVENT;
ir.Event.KeyEvent.wVirtualKeyCode = vkc;
ir.Event.KeyEvent.wVirtualScanCode = 0;
ir.Event.KeyEvent.wVirtualScanCode =
WINPORT(MapVirtualKey)(ir.Event.KeyEvent.wVirtualKeyCode, MAPVK_VK_TO_VSC);
ir.Event.KeyEvent.uChar.UnicodeChar = uni_char;
ir.Event.KeyEvent.bKeyDown = (s[6] == 'd' ? TRUE : FALSE);
ir.Event.KeyEvent.dwControlKeyState = flags_win;
ir.Event.KeyEvent.wRepeatCount = 1;

if (keycode == 0x3C) ir.Event.KeyEvent.wVirtualScanCode = RIGHT_SHIFT_VSC; // RightShift

_ir_pending.emplace_back(ir);

flags_track = flags;
return len;
}