wpf: make the cursor blink (#3415)
This commit is contained in:
parent
a4c24f82e6
commit
6f36f8b23f
|
@ -396,3 +396,20 @@ HRESULT _stdcall TerminalResize(void* terminal, COORD dimensions)
|
|||
|
||||
return publicTerminal->_terminal->UserResize(dimensions);
|
||||
}
|
||||
|
||||
void _stdcall TerminalBlinkCursor(void* terminal)
|
||||
{
|
||||
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
||||
if (!publicTerminal->_terminal->IsCursorBlinkingAllowed() && publicTerminal->_terminal->IsCursorVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
publicTerminal->_terminal->SetCursorVisible(!publicTerminal->_terminal->IsCursorVisible());
|
||||
}
|
||||
|
||||
void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible)
|
||||
{
|
||||
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
||||
publicTerminal->_terminal->SetCursorVisible(visible);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ __declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalThe
|
|||
__declspec(dllexport) void _stdcall TerminalRegisterWriteCallback(void* terminal, const void __stdcall callback(wchar_t*));
|
||||
__declspec(dllexport) void _stdcall TerminalSendKeyEvent(void* terminal, WPARAM wParam);
|
||||
__declspec(dllexport) void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch);
|
||||
__declspec(dllexport) void _stdcall TerminalBlinkCursor(void* terminal);
|
||||
__declspec(dllexport) void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
|
||||
};
|
||||
|
||||
struct HwndTerminal
|
||||
|
@ -69,5 +71,7 @@ private:
|
|||
friend void _stdcall TerminalSendKeyEvent(void* terminal, WPARAM wParam);
|
||||
friend void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch);
|
||||
friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
|
||||
friend void _stdcall TerminalBlinkCursor(void* terminal);
|
||||
friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
|
||||
void _UpdateFont(int newDpi);
|
||||
};
|
||||
|
|
|
@ -21,6 +21,16 @@ namespace Microsoft.Terminal.Wpf
|
|||
|
||||
public enum WindowMessage : int
|
||||
{
|
||||
/// <summary>
|
||||
/// The WM_SETFOCUS message is sent to a window after it has gained the keyboard focus.
|
||||
/// </summary>
|
||||
WM_SETFOCUS = 0x0007,
|
||||
|
||||
/// <summary>
|
||||
/// The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus.
|
||||
/// </summary>
|
||||
WM_KILLFOCUS = 0x0008,
|
||||
|
||||
/// <summary>
|
||||
/// The WM_MOUSEACTIVATE message is sent when the cursor is in an inactive window and the user presses a mouse button. The parent window receives this message only if the child window passes it to the DefWindowProc function.
|
||||
/// </summary>
|
||||
|
@ -202,12 +212,24 @@ namespace Microsoft.Terminal.Wpf
|
|||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern void TerminalSetTheme(IntPtr terminal, [MarshalAs(UnmanagedType.Struct)] TerminalTheme theme, string fontFamily, short fontSize, int newDpi);
|
||||
|
||||
[DllImport("PublicTerminalCore.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern void TerminalBlinkCursor(IntPtr terminal);
|
||||
|
||||
[DllImport("PublicTerminalCore.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern void TerminalSetCursorVisible(IntPtr terminal, bool visible);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr SetFocus(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr GetFocus();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern short GetKeyState(int keyCode);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern uint GetCaretBlinkTime();
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct WINDOWPOS
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Microsoft.Terminal.Wpf
|
|||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
|
||||
/// <summary>
|
||||
/// The container class that hosts the native hwnd terminal.
|
||||
|
@ -22,7 +23,7 @@ namespace Microsoft.Terminal.Wpf
|
|||
private ITerminalConnection connection;
|
||||
private IntPtr hwnd;
|
||||
private IntPtr terminal;
|
||||
|
||||
private DispatcherTimer blinkTimer;
|
||||
private NativeMethods.ScrollCallback scrollCallback;
|
||||
private NativeMethods.WriteCallback writeCallback;
|
||||
|
||||
|
@ -34,6 +35,21 @@ namespace Microsoft.Terminal.Wpf
|
|||
this.MessageHook += this.TerminalContainer_MessageHook;
|
||||
this.GotFocus += this.TerminalContainer_GotFocus;
|
||||
this.Focusable = true;
|
||||
|
||||
var blinkTime = NativeMethods.GetCaretBlinkTime();
|
||||
|
||||
if (blinkTime != uint.MaxValue)
|
||||
{
|
||||
this.blinkTimer = new DispatcherTimer();
|
||||
this.blinkTimer.Interval = TimeSpan.FromMilliseconds(blinkTime);
|
||||
this.blinkTimer.Tick += (_, __) =>
|
||||
{
|
||||
if (this.terminal != IntPtr.Zero)
|
||||
{
|
||||
NativeMethods.TerminalBlinkCursor(this.terminal);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -171,6 +187,15 @@ namespace Microsoft.Terminal.Wpf
|
|||
NativeMethods.TerminalDpiChanged(this.terminal, (int)dpiScale.PixelsPerInchX);
|
||||
}
|
||||
|
||||
if (NativeMethods.GetFocus() == this.hwnd)
|
||||
{
|
||||
this.blinkTimer?.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeMethods.TerminalSetCursorVisible(this.terminal, false);
|
||||
}
|
||||
|
||||
return new HandleRef(this, this.hwnd);
|
||||
}
|
||||
|
||||
|
@ -193,6 +218,13 @@ namespace Microsoft.Terminal.Wpf
|
|||
{
|
||||
switch ((NativeMethods.WindowMessage)msg)
|
||||
{
|
||||
case NativeMethods.WindowMessage.WM_SETFOCUS:
|
||||
this.blinkTimer?.Start();
|
||||
break;
|
||||
case NativeMethods.WindowMessage.WM_KILLFOCUS:
|
||||
this.blinkTimer?.Stop();
|
||||
NativeMethods.TerminalSetCursorVisible(this.terminal, false);
|
||||
break;
|
||||
case NativeMethods.WindowMessage.WM_MOUSEACTIVATE:
|
||||
this.Focus();
|
||||
NativeMethods.SetFocus(this.hwnd);
|
||||
|
@ -215,8 +247,10 @@ namespace Microsoft.Terminal.Wpf
|
|||
this.MouseMoveHandler((int)wParam, (int)lParam);
|
||||
break;
|
||||
case NativeMethods.WindowMessage.WM_KEYDOWN:
|
||||
NativeMethods.TerminalSetCursorVisible(this.terminal, true);
|
||||
NativeMethods.TerminalClearSelection(this.terminal);
|
||||
NativeMethods.TerminalSendKeyEvent(this.terminal, wParam);
|
||||
this.blinkTimer?.Start();
|
||||
break;
|
||||
case NativeMethods.WindowMessage.WM_CHAR:
|
||||
NativeMethods.TerminalSendCharEvent(this.terminal, (char)wParam);
|
||||
|
|
Loading…
Reference in a new issue