Skip to content

Commit 7cd46c0

Browse files
authored
Fix multiple regressions since #18215 (#18345)
Fixes * Cursor vanishing, because ```cpp CoreWindow::GetForCurrentThread().PointerCursor() ``` returned a non-null, but still invisible cursor. * Alt/F7 not dispatching to newly created windows, because the `WM_ACTIVATE` message now arrives before the `AppHost` is initialized. This caused the messages to be delivered to old windows. * Windows Terminal blocking expedited shutdown, because we return `FALSE` on non-`ENDSESSION_CLOSEAPP` messages. Closes #18331 Closes #18335 ## Validation Steps Performed * Cursor still doesn't really vanish for me in the first place ✅ * Alt/F7 work in new windows without triggering old ones ✅
1 parent c6e7f32 commit 7cd46c0

File tree

4 files changed

+49
-29
lines changed

4 files changed

+49
-29
lines changed

src/cascadia/TerminalControl/TermControl.cpp

+7-13
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ DEFINE_ENUM_FLAG_OPERATORS(winrt::Microsoft::Terminal::Control::MouseButtonState
5757
// the current foreground window, but still on top of another Terminal window in the background.
5858
static void hideCursorUntilMoved()
5959
{
60-
static CoreCursor previousCursor{ nullptr };
60+
static bool cursorIsHidden;
6161
static const auto shouldVanish = []() {
6262
BOOL shouldVanish = TRUE;
6363
SystemParametersInfoW(SPI_GETMOUSEVANISH, 0, &shouldVanish, 0);
@@ -68,16 +68,16 @@ static void hideCursorUntilMoved()
6868

6969
const auto window = CoreWindow::GetForCurrentThread();
7070
static constexpr auto releaseCapture = [](CoreWindow window, PointerEventArgs) {
71-
if (previousCursor)
71+
if (cursorIsHidden)
7272
{
7373
window.ReleasePointerCapture();
7474
}
7575
};
7676
static constexpr auto restoreCursor = [](CoreWindow window, PointerEventArgs) {
77-
if (previousCursor)
77+
if (cursorIsHidden)
7878
{
79-
window.PointerCursor(previousCursor);
80-
previousCursor = nullptr;
79+
cursorIsHidden = false;
80+
window.PointerCursor(CoreCursor{ CoreCursorType::Arrow, 0 });
8181
}
8282
};
8383

@@ -90,20 +90,14 @@ static void hideCursorUntilMoved()
9090
return true;
9191
}();
9292

93-
if (shouldVanish && !previousCursor)
93+
if (shouldVanish && !cursorIsHidden)
9494
{
9595
try
9696
{
9797
const auto window = CoreWindow::GetForCurrentThread();
98-
99-
previousCursor = window.PointerCursor();
100-
if (!previousCursor)
101-
{
102-
return;
103-
}
104-
10598
window.PointerCursor(nullptr);
10699
window.SetPointerCapture();
100+
cursorIsHidden = true;
107101
}
108102
catch (...)
109103
{

src/cascadia/WindowsTerminal/AppHost.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ void AppHost::_WindowActivated(bool activated)
815815
{
816816
_windowLogic.WindowActivated(activated);
817817

818-
if (activated && _isWindowInitialized != WindowInitializedState::NotInitialized)
818+
if (activated)
819819
{
820820
QueryPerformanceCounter(&_lastActivatedTime);
821821
_virtualDesktopId = {};

src/cascadia/WindowsTerminal/WindowEmperor.cpp

+40-15
Original file line numberDiff line numberDiff line change
@@ -413,13 +413,8 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
413413
// It almost seems like there's a pattern here...
414414
(msg.wParam == VK_SPACE && msg.message == WM_SYSKEYDOWN))
415415
{
416-
if (const auto w = _mostRecentWindow())
417-
{
418-
const auto vkey = gsl::narrow_cast<uint32_t>(msg.wParam);
419-
const auto scanCode = gsl::narrow_cast<uint8_t>(msg.lParam >> 16);
420-
w->OnDirectKeyEvent(vkey, scanCode, keyDown);
421-
continue;
422-
}
416+
_dispatchSpecialKey(msg);
417+
continue;
423418
}
424419
}
425420

@@ -442,6 +437,40 @@ void WindowEmperor::HandleCommandlineArgs(int nCmdShow)
442437
__assume(false);
443438
}
444439

440+
void WindowEmperor::_dispatchSpecialKey(MSG& msg) const
441+
{
442+
const auto hwnd = msg.hwnd;
443+
AppHost* window = nullptr;
444+
445+
// Just in case someone has targed a specific HWND,
446+
// we'll try to dispatch it to the corresponding class.
447+
// Usually this will not find anything because under WinUI the hidden CoreInput
448+
// window is responsible for all input handling (for whatever reason).
449+
for (const auto& h : _windows)
450+
{
451+
const auto w = h->GetWindow();
452+
if (w && w->GetHandle() == hwnd)
453+
{
454+
window = h.get();
455+
break;
456+
}
457+
}
458+
459+
if (!window)
460+
{
461+
window = _mostRecentWindow();
462+
if (!window)
463+
{
464+
return;
465+
}
466+
}
467+
468+
const auto vkey = gsl::narrow_cast<uint32_t>(msg.wParam);
469+
const auto scanCode = gsl::narrow_cast<uint8_t>(msg.lParam >> 16);
470+
const bool keyDown = msg.message & 1;
471+
window->OnDirectKeyEvent(vkey, scanCode, keyDown);
472+
}
473+
445474
void WindowEmperor::_dispatchCommandline(winrt::TerminalApp::CommandlineArgs args)
446475
{
447476
const auto exitCode = args.ExitCode();
@@ -826,14 +855,10 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c
826855
case WM_QUERYENDSESSION:
827856
// For WM_QUERYENDSESSION and WM_ENDSESSION, refer to:
828857
// https://docs.microsoft.com/en-us/windows/win32/rstmgr/guidelines-for-applications
829-
if (lParam == ENDSESSION_CLOSEAPP)
830-
{
831-
// ENDSESSION_CLOSEAPP: The application is using a file that must be replaced,
832-
// the system is being serviced, or system resources are exhausted.
833-
RegisterApplicationRestart(nullptr, RESTART_NO_CRASH | RESTART_NO_HANG);
834-
return TRUE;
835-
}
836-
return FALSE;
858+
// ENDSESSION_CLOSEAPP: The application is using a file that must be replaced,
859+
// the system is being serviced, or system resources are exhausted.
860+
RegisterApplicationRestart(nullptr, RESTART_NO_CRASH | RESTART_NO_HANG);
861+
return TRUE;
837862
case WM_ENDSESSION:
838863
_forcePersistence = true;
839864
PostQuitMessage(0);

src/cascadia/WindowsTerminal/WindowEmperor.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class WindowEmperor
5050
AppHost* _mostRecentWindow() const noexcept;
5151
bool _summonWindow(const SummonWindowSelectionArgs& args) const;
5252
void _summonAllWindows() const;
53+
void _dispatchSpecialKey(MSG& msg) const;
5354
void _dispatchCommandline(winrt::TerminalApp::CommandlineArgs args);
5455
safe_void_coroutine _dispatchCommandlineCurrentDesktop(winrt::TerminalApp::CommandlineArgs args);
5556
LRESULT _messageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam) noexcept;

0 commit comments

Comments
 (0)