Skip to content
This repository was archived by the owner on Oct 5, 2022. It is now read-only.

Commit 37bdcea

Browse files
committed
updated winpty
1 parent d5a1ff3 commit 37bdcea

File tree

5 files changed

+68
-20
lines changed

5 files changed

+68
-20
lines changed

deps/winpty/RELEASES.md

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
# Next Version
2+
3+
Input handling changes:
4+
5+
* Improve Ctrl-C handling with programs that use unprocessed input. (e.g.
6+
Ctrl-C now cancels input with PowerShell on Windows 10.)
7+
[#116](https://github.com/rprichard/winpty/issues/116)
8+
* Fix a theoretical issue with input event ordering.
9+
[#117](https://github.com/rprichard/winpty/issues/117)
10+
* Ctrl/Shift+{Arrow,Home,End} keys now work with IntelliJ.
11+
[#118](https://github.com/rprichard/winpty/issues/118)
12+
113
# Version 0.4.3 (2017-05-17)
214

315
Input handling changes:

deps/winpty/VERSION.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.4.3
1+
0.4.4-dev

deps/winpty/src/agent/ConsoleInput.cc

+45-13
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,38 @@ void ConsoleInput::doWrite(bool isEof)
343343
idx += charSize;
344344
}
345345
m_byteQueue.erase(0, idx);
346+
flushInputRecords(records);
347+
}
348+
349+
void ConsoleInput::flushInputRecords(std::vector<INPUT_RECORD> &records)
350+
{
351+
if (records.size() == 0) {
352+
return;
353+
}
346354
DWORD actual = 0;
347-
if (records.size() > 0) {
348-
if (!WriteConsoleInputW(m_conin, records.data(), records.size(), &actual)) {
349-
trace("WriteConsoleInputW failed");
350-
}
355+
if (!WriteConsoleInputW(m_conin, records.data(), records.size(), &actual)) {
356+
trace("WriteConsoleInputW failed");
351357
}
358+
records.clear();
359+
}
360+
361+
// This behavior isn't strictly correct, because the keypresses (probably?)
362+
// adopt the keyboard state (e.g. Ctrl/Alt/Shift modifiers) of the current
363+
// window station's keyboard, which has no necessary relationship to the winpty
364+
// instance. It's unlikely to be an issue in practice, but it's conceivable.
365+
// (Imagine a foreground SSH server, where the local user holds down Ctrl,
366+
// while the remote user tries to use WSL navigation keys.) I suspect using
367+
// the BackgroundDesktop mechanism in winpty would fix the problem.
368+
//
369+
// https://github.com/rprichard/winpty/issues/116
370+
static void sendKeyMessage(HWND hwnd, bool isKeyDown, uint16_t virtualKey)
371+
{
372+
uint32_t scanCode = MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC);
373+
if (scanCode > 255) {
374+
scanCode = 0;
375+
}
376+
SendMessage(hwnd, isKeyDown ? WM_KEYDOWN : WM_KEYUP, virtualKey,
377+
(scanCode << 16) | 1u | (isKeyDown ? 0u : 0xc0000000u));
352378
}
353379

354380
int ConsoleInput::scanInput(std::vector<INPUT_RECORD> &records,
@@ -359,9 +385,20 @@ int ConsoleInput::scanInput(std::vector<INPUT_RECORD> &records,
359385
ASSERT(inputSize >= 1);
360386

361387
// Ctrl-C.
388+
//
389+
// In processed mode, use GenerateConsoleCtrlEvent so that Ctrl-C handlers
390+
// are called. GenerateConsoleCtrlEvent unfortunately doesn't interrupt
391+
// ReadConsole calls[1]. Using WM_KEYDOWN/UP fixes the ReadConsole
392+
// problem, but breaks in background window stations/desktops.
393+
//
394+
// In unprocessed mode, there's an entry for Ctrl-C in the SimpleEncoding
395+
// table in DefaultInputMap.
396+
//
397+
// [1] https://github.com/rprichard/winpty/issues/116
362398
if (input[0] == '\x03' && (inputConsoleMode() & ENABLE_PROCESSED_INPUT)) {
399+
flushInputRecords(records);
363400
trace("Ctrl-C");
364-
BOOL ret = GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
401+
const BOOL ret = GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
365402
trace("GenerateConsoleCtrlEvent: %d", ret);
366403
return 1;
367404
}
@@ -652,17 +689,12 @@ void ConsoleInput::appendKeyPress(std::vector<INPUT_RECORD> &records,
652689
virtualKey == VK_HOME ||
653690
virtualKey == VK_END) &&
654691
!ctrl && !leftAlt && !rightAlt && !shift) {
692+
flushInputRecords(records);
655693
if (hasDebugInput) {
656694
trace("sending keypress to console HWND");
657695
}
658-
uint32_t scanCode = MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC);
659-
if (scanCode > 255) {
660-
scanCode = 0;
661-
}
662-
SendMessage(m_console.hwnd(), WM_KEYDOWN, virtualKey,
663-
(scanCode << 16) | 1u);
664-
SendMessage(m_console.hwnd(), WM_KEYUP, virtualKey,
665-
(scanCode << 16) | (1u | (1u << 30) | (1u << 31)));
696+
sendKeyMessage(m_console.hwnd(), true, virtualKey);
697+
sendKeyMessage(m_console.hwnd(), false, virtualKey);
666698
return;
667699
}
668700

deps/winpty/src/agent/ConsoleInput.h

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class ConsoleInput
4848

4949
private:
5050
void doWrite(bool isEof);
51+
void flushInputRecords(std::vector<INPUT_RECORD> &records);
5152
int scanInput(std::vector<INPUT_RECORD> &records,
5253
const char *input,
5354
int inputSize,

deps/winpty/src/agent/DefaultInputMap.cc

+9-6
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@ const int kSuffixBoth = kSuffixCtrl | kSuffixShift;
6565

6666
static const EscapeEncoding escapeLetterEncodings[] = {
6767
// Conventional arrow keys
68-
{ true, '[', 'A', kBare | kSemiMod, { VK_UP, '\0', 0 } },
69-
{ true, '[', 'B', kBare | kSemiMod, { VK_DOWN, '\0', 0 } },
70-
{ true, '[', 'C', kBare | kSemiMod, { VK_RIGHT, '\0', 0 } },
71-
{ true, '[', 'D', kBare | kSemiMod, { VK_LEFT, '\0', 0 } },
68+
// kBareMod: Ubuntu /etc/inputrc and IntelliJ/JediTerm use escapes like: ESC [ n ABCD
69+
{ true, '[', 'A', kBare | kBareMod | kSemiMod, { VK_UP, '\0', 0 } },
70+
{ true, '[', 'B', kBare | kBareMod | kSemiMod, { VK_DOWN, '\0', 0 } },
71+
{ true, '[', 'C', kBare | kBareMod | kSemiMod, { VK_RIGHT, '\0', 0 } },
72+
{ true, '[', 'D', kBare | kBareMod | kSemiMod, { VK_LEFT, '\0', 0 } },
7273

7374
// putty. putty uses this sequence for Ctrl-Arrow, Shift-Arrow, and
7475
// Ctrl-Shift-Arrow, but I can only decode to one choice, so I'm just
@@ -102,8 +103,9 @@ static const EscapeEncoding escapeLetterEncodings[] = {
102103

103104
// Home/End, letter version
104105
// * gnome-terminal uses `ESC O [HF]`. I never saw it modified.
105-
{ true, '[', 'H', kBare | kSemiMod, { VK_HOME, '\0', 0 } },
106-
{ true, '[', 'F', kBare | kSemiMod, { VK_END, '\0', 0 } },
106+
// kBareMod: IntelliJ/JediTerm uses escapes like: ESC [ n HF
107+
{ true, '[', 'H', kBare | kBareMod | kSemiMod, { VK_HOME, '\0', 0 } },
108+
{ true, '[', 'F', kBare | kBareMod | kSemiMod, { VK_END, '\0', 0 } },
107109
{ true, 'O', 'H', kBare, { VK_HOME, '\0', 0 } },
108110
{ true, 'O', 'F', kBare, { VK_END, '\0', 0 } },
109111

@@ -235,6 +237,7 @@ static void addSimpleEntries(InputMap &inputMap) {
235237

236238
{ "\x7F", { VK_BACK, '\x08', 0, } },
237239
{ ESC "\x7F", { VK_BACK, '\x08', LEFT_ALT_PRESSED, } },
240+
{ "\x03", { 'C', '\x03', LEFT_CTRL_PRESSED, } },
238241

239242
// Handle special F1-F5 for TERM=linux and TERM=cygwin.
240243
{ ESC "[[A", { VK_F1, '\0', 0 } },

0 commit comments

Comments
 (0)