Fix 3 different bugs in the WPF control (#6464)

* [wpf] WM_KEYUP crashes on x64 #6444
  - Turns out that doing the `(uint)lParam` cast worked fine for the
    keydowns, because the value of lParam usually didn't have super
    high-order bits set. That's not the case for keyups, where the 30th
    bit is _always_ set. This is fixed by explicitly getting the byte
    with the scancode in it.
* [wpf] WM_KEYUP generates wrong value in Win32 input mode #6445
  - This was fixed by basically the same thing as the above.
* [wpf] WPF control crashes on startup trying to render cursor #6446
  - This was a regression from #6337. I forgot to initialize the brush
    used to paint the cursor, because the UWP version always uses color
    (but the WPF one relies on the text foreground color).
* Also adds a minor change to the WPF test app, so that the user can
  actually exit `win32-input-mode`.

* #6337 regressed #6446 
* #6309 regressed the other two.

Closes #6444
Closes #6445
Closes #6446
This commit is contained in:
Mike Griese 2020-06-11 13:05:43 -05:00 committed by GitHub
parent bcdccc533e
commit db518c0b06
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 16 deletions

View file

@ -233,15 +233,24 @@ namespace Microsoft.Terminal.Wpf
NativeMethods.SetFocus(this.hwnd);
break;
case NativeMethods.WindowMessage.WM_KEYDOWN:
// WM_KEYDOWN lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keydown
NativeMethods.TerminalSetCursorVisible(this.terminal, true);
NativeMethods.TerminalSendKeyEvent(this.terminal, (ushort)wParam, (ushort)((uint)lParam >> 16), true);
this.blinkTimer?.Start();
break;
{
// WM_KEYDOWN lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keydown
NativeMethods.TerminalSetCursorVisible(this.terminal, true);
ulong scanCode = (((ulong)lParam) & 0x00FF0000) >> 16;
NativeMethods.TerminalSendKeyEvent(this.terminal, (ushort)wParam, (ushort)(scanCode), true);
this.blinkTimer?.Start();
break;
}
case NativeMethods.WindowMessage.WM_KEYUP:
// WM_KEYUP lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keyup
NativeMethods.TerminalSendKeyEvent(this.terminal, (ushort)wParam, (ushort)((uint)lParam >> 16), false);
break;
{
// WM_KEYUP lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keyup
ulong scanCode = (((ulong)lParam) & 0x00FF0000) >> 16;
NativeMethods.TerminalSendKeyEvent(this.terminal, (ushort)wParam, (ushort)(scanCode), false);
break;
}
case NativeMethods.WindowMessage.WM_CHAR:
// WM_CHAR lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-char
NativeMethods.TerminalSendCharEvent(this.terminal, (char)wParam, (ushort)((uint)lParam >> 16));

View file

@ -30,24 +30,37 @@ namespace WpfTerminalTestNetCore
public void WriteInput(string data)
{
if (data.Length > 0 && data[0] == '\x01') // ^A
if (data.Length == 0)
{
return;
}
if (data[0] == '\x01') // ^A
{
_escapeMode = !_escapeMode;
TerminalOutput.Invoke(this, new TerminalOutputEventArgs($"Printable ESC mode: {_escapeMode}\r\n"));
}
else if (data.Length > 0 && data[0] == '\x02') // ^B
else if (data[0] == '\x02') // ^B
{
_mouseMode = !_mouseMode;
var decSet = _mouseMode ? "h" : "l";
TerminalOutput.Invoke(this, new TerminalOutputEventArgs($"\x1b[?1003{decSet}\x1b[?1006{decSet}"));
TerminalOutput.Invoke(this, new TerminalOutputEventArgs($"SGR Mouse mode (1003, 1006): {_mouseMode}\r\n"));
}
else if (data.Length > 0 && data[0] == '\x03') // ^C
else if ((data[0] == '\x03') ||
(data == "\x1b[67;46;3;1;8;1_")) // ^C
{
_win32InputMode = !_win32InputMode;
var decSet = _win32InputMode ? "h" : "l";
TerminalOutput.Invoke(this, new TerminalOutputEventArgs($"\x1b[?9001{decSet}"));
TerminalOutput.Invoke(this, new TerminalOutputEventArgs($"Win32 input mode: {_win32InputMode}\r\n"));
// If escape mode isn't currently enabled, turn it on now.
if (_win32InputMode && !_escapeMode)
{
_escapeMode = true;
TerminalOutput.Invoke(this, new TerminalOutputEventArgs($"Printable ESC mode: {_escapeMode}\r\n"));
}
}
else
{

View file

@ -331,7 +331,7 @@ try
return E_NOTIMPL;
}
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> brush;
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> brush{ drawingContext.foregroundBrush };
if (options.fUseColor)
{

View file

@ -12,8 +12,8 @@ namespace Microsoft::Console::Render
struct DrawingContext
{
DrawingContext(ID2D1RenderTarget* renderTarget,
ID2D1Brush* foregroundBrush,
ID2D1Brush* backgroundBrush,
ID2D1SolidColorBrush* foregroundBrush,
ID2D1SolidColorBrush* backgroundBrush,
bool forceGrayscaleAA,
IDWriteFactory* dwriteFactory,
const DWRITE_LINE_SPACING spacing,
@ -33,8 +33,8 @@ namespace Microsoft::Console::Render
}
ID2D1RenderTarget* renderTarget;
ID2D1Brush* foregroundBrush;
ID2D1Brush* backgroundBrush;
ID2D1SolidColorBrush* foregroundBrush;
ID2D1SolidColorBrush* backgroundBrush;
bool forceGrayscaleAA;
IDWriteFactory* dwriteFactory;
DWRITE_LINE_SPACING spacing;