-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
Pump the message queue on frozen windows #16588
Changes from all commits
5511a11
4008a90
2244e60
2caa43a
0c6469a
b463df5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,11 @@ NonClientIslandWindow::NonClientIslandWindow(const ElementTheme& requestedTheme) | |
{ | ||
} | ||
|
||
NonClientIslandWindow::~NonClientIslandWindow() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just added redundancy? I don't think we've got any code that was removed that was calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, it's terrible... This change fixes a bug and you might already know what I mean when I say: But in my opinion this sorely belongs into the "only obvious in hindsight" category of arcane C++ footnukes (can't have enough of those in a language!), so let me explain in more detail:
In short, when |
||
{ | ||
Close(); | ||
} | ||
|
||
void NonClientIslandWindow::Close() | ||
{ | ||
// Avoid further callbacks into XAML/WinUI-land after we've Close()d the DesktopWindowXamlSource | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ | |
#include "pch.h" | ||
#include "WindowThread.h" | ||
|
||
using namespace winrt::Microsoft::Terminal::Remoting; | ||
|
||
WindowThread::WindowThread(winrt::TerminalApp::AppLogic logic, | ||
winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs args, | ||
winrt::Microsoft::Terminal::Remoting::WindowManager manager, | ||
|
@@ -81,17 +83,6 @@ void WindowThread::RundownForExit() | |
_pumpRemainingXamlMessages(); | ||
} | ||
|
||
void WindowThread::ThrowAway() | ||
{ | ||
// raise the signal to unblock KeepWarm. We won't have a host, so we'll drop | ||
// out of the message loop to eventually RundownForExit. | ||
// | ||
// This should only be called when the app is fully quitting. After this is | ||
// called on any thread, on win10, we won't be able to call into XAML | ||
// anymore. | ||
_microwaveBuzzer.notify_one(); | ||
} | ||
|
||
// Method Description: | ||
// - Check if we should keep this window alive, to try it's message loop again. | ||
// If we were refrigerated for later, then this will block the thread on the | ||
|
@@ -108,29 +99,24 @@ bool WindowThread::KeepWarm() | |
return true; | ||
} | ||
|
||
// If we're refrigerated, then wait on the microwave signal, which will be | ||
// raised when we get re-heated by another thread to reactivate us. | ||
|
||
if (_warmWindow != nullptr) | ||
// Even when the _host has been destroyed the HWND will continue receiving messages, in particular WM_DISPATCHNOTIFY at least once a second. This is important to Windows as it keeps your room warm. | ||
MSG msg; | ||
for (;;) | ||
{ | ||
std::unique_lock lock(_microwave); | ||
_microwaveBuzzer.wait(lock); | ||
|
||
// If ThrowAway() was called, then the buzzer will be signalled without | ||
// setting a new _host. In that case, the app is quitting, for real. We | ||
// just want to exit with false. | ||
const bool reheated = _host != nullptr; | ||
if (reheated) | ||
if (!GetMessageW(&msg, nullptr, 0, 0)) | ||
{ | ||
return false; | ||
} | ||
// We're using a single window message (WM_REFRIGERATE) to indicate both | ||
// state transitions. In this case, the window is actually being woken up. | ||
if (msg.message == AppHost::WM_REFRIGERATE) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fwiw mike referred to the act of waking back up as Microwaving; refrigerating is when it goes down to sleep There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I see - you have repurposed it to be a single flag. Transition between the states. etc There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I wasn't sure what to name it... "refrigerate" has the benefit that it only comes up in this context in the project, so it should be easier to find related code.
lhecker marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
_UpdateSettingsRequestedToken = _host->UpdateSettingsRequested([this]() { _UpdateSettingsRequestedHandlers(); }); | ||
// Re-initialize the host here, on the window thread | ||
_host->Initialize(); | ||
return true; | ||
} | ||
return reheated; | ||
} | ||
else | ||
{ | ||
return false; | ||
DispatchMessageW(&msg); | ||
} | ||
} | ||
|
||
|
@@ -154,24 +140,22 @@ void WindowThread::Refrigerate() | |
|
||
// Method Description: | ||
// - "Reheat" this thread for reuse. We'll build a new AppHost, and pass in the | ||
// existing window to it. We'll then trigger the _microwaveBuzzer, so KeepWarm | ||
// (which is on the UI thread) will get unblocked, and we can initialize this | ||
// window. | ||
void WindowThread::Microwave( | ||
winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs args, | ||
winrt::Microsoft::Terminal::Remoting::Peasant peasant) | ||
// existing window to it. We'll then wake up the thread stuck in KeepWarm(). | ||
void WindowThread::Microwave(WindowRequestedArgs args, Peasant peasant) | ||
{ | ||
const auto hwnd = _warmWindow->GetInteropHandle(); | ||
|
||
_peasant = std::move(peasant); | ||
_args = std::move(args); | ||
|
||
_host = std::make_shared<::AppHost>(_appLogic, | ||
_args, | ||
_manager, | ||
_peasant, | ||
std::move(_warmWindow)); | ||
_host = std::make_shared<AppHost>(_appLogic, | ||
_args, | ||
_manager, | ||
_peasant, | ||
std::move(_warmWindow)); | ||
|
||
// raise the signal to unblock KeepWarm and start the window message loop again. | ||
_microwaveBuzzer.notify_one(); | ||
PostMessageW(hwnd, AppHost::WM_REFRIGERATE, 0, 0); | ||
} | ||
|
||
winrt::TerminalApp::TerminalWindow WindowThread::Logic() | ||
|
@@ -198,6 +182,15 @@ int WindowThread::_messagePump() | |
|
||
while (GetMessageW(&message, nullptr, 0, 0)) | ||
{ | ||
// We're using a single window message (WM_REFRIGERATE) to indicate both | ||
// state transitions. In this case, the window is actually being refrigerated. | ||
// This will break us out of our main message loop we'll eventually start | ||
// the loop in WindowThread::KeepWarm to await a call to Microwave(). | ||
if (message.message == AppHost::WM_REFRIGERATE) | ||
lhecker marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
break; | ||
} | ||
|
||
// GH#638 (Pressing F7 brings up both the history AND a caret browsing message) | ||
// The Xaml input stack doesn't allow an application to suppress the "caret browsing" | ||
// dialog experience triggered when you press F7. Official recommendation from the Xaml | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very sus that this is just gone now - why? Is this related?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you expand the surrounding code in the diff viewer you'll notice that this block of code is a duplicate! I think it might have been an incorrect merge in the past.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh what the heck