Remove Monarch/Peasant & Make UI single-threaded#18215
Conversation
b39c5a7 to
7853853
Compare
|
|
||
| const auto canDragDrop = CanDragDrop(); | ||
|
|
||
| _tabRow.PointerMoved({ get_weak(), &TerminalPage::_RestorePointerCursorHandler }); |
There was a problem hiding this comment.
Moved into TerminalControl as a different workaround is needed for this functionality.
| void TerminalPage::IdentifyWindow() | ||
| { | ||
| auto weakThis{ get_weak() }; | ||
| co_await wil::resume_foreground(Dispatcher()); |
There was a problem hiding this comment.
No multi-threading = No problem. (Suppress whitespace in the diff.)
| <CurrentXamlPackage Include="@(AppxPackageRegistration)" | ||
| Condition="'%(AppxPackageRegistration.Architecture)'=='$(Platform)' AND | ||
| $([System.String]::new('%(AppxPackageRegistration.Filename)').StartsWith('Microsoft.UI.Xaml'))" /> | ||
| <CurrentXamlPackage Include="@(AppxPackageRegistration)" Condition="'%(AppxPackageRegistration.Architecture)'=='$(Platform)' AND
 $([System.String]::new('%(AppxPackageRegistration.Filename)').StartsWith('Microsoft.UI.Xaml'))" /> |
DHowett
left a comment
There was a problem hiding this comment.
86/154! It's easy to review deletions ;)
|
| auto isCurrentlyDark = Theme::IsSystemInDarkTheme(); | ||
| if (isCurrentlyDark != _currentSystemThemeIsDark) | ||
| { | ||
| _currentSystemThemeIsDark = isCurrentlyDark; |
There was a problem hiding this comment.
📝 DH - Guessing this moved to the Message Window; confirm
|
|
||
| // Method Description: | ||
| // - As above. | ||
| // BODGY: ARM64 BUILD FAILED WITH fatal error C1001: Internal compiler error |
There was a problem hiding this comment.
now that we got a new compiler, is this still valid
There was a problem hiding this comment.
it's not even a coroutine any longer, so we can probably dispense with the separation entirely...
| ScopedResourceLoader loader{ L"TerminalApp/ContextMenu" }; | ||
| const auto appNameLoc = loader.GetLocalizedString(L"AppName"); |
There was a problem hiding this comment.
📝 DH - Loading up somebody else's resources - probably moved to Emperor
| HWND GetMainWindow() const noexcept; | ||
| AppHost* GetWindowById(uint64_t id) const noexcept; | ||
| AppHost* GetWindowByName(std::wstring_view name) const noexcept; | ||
| void CreateNewWindow(winrt::TerminalApp::WindowRequestedArgs args); |
| bool _registerHotKey(const int index, const winrt::Microsoft::Terminal::Control::KeyChord& hotkey) noexcept; | ||
| void _unregisterHotKey(const int index) noexcept; | ||
| safe_void_coroutine _setupGlobalHotkeys(); | ||
| enum class TriBool : uint8_t |
There was a problem hiding this comment.
HAHAHAHAHAHAHAHAHAHAH
hahahahahaha
hahah
std::optional<bool>?
There was a problem hiding this comment.
std::optional<bool> is two bools in a trench coat, so... meh.
...but yeah I could do that.
| const auto absoluteWindowOrigin = CoreWindow::GetForCurrentThread().Bounds(); | ||
| // Get the offset (margin + tabs, etc..) of the control within the window | ||
| const auto controlOrigin = TransformToVisual(nullptr).TransformPoint({}); | ||
| const auto inverseScale = 1.0f / static_cast<float>(XamlRoot().RasterizationScale()); |
There was a problem hiding this comment.
these don't seem related to regicide
There was a problem hiding this comment.
CoreWindow::GetForCurrentThread().Bounds() won't work anymore, so this had to be rewritten. I also chose to use the technically correct way to get the rasterization scale (we do it incorrectly everywhere, according to the docs).
This comment has been minimized.
This comment has been minimized.
| // Once the loop exits, the app exits, and the message box will be closed. | ||
| _messageBoxCount += 1; | ||
| const auto decrement = wil::scope_exit([hwnd = _window.get()]() noexcept { | ||
| PostMessageW(hwnd, WM_MESSAGE_BOX_CLOSED, 0, 0); |
There was a problem hiding this comment.
FWIW the reason I went with PostMessageW instead of resume_foreground is because I think it's crucial that this does not fail so that the ref-count does not go out of sync. I think PostMessageW is fundamentally more robust in that regard.
zadjii-msft
left a comment
There was a problem hiding this comment.
161/164, but alas, the burrito screams
sometimes when I get that deep into a PR as big as this, I just assume the last couple files must be good too
| } | ||
|
|
||
| void WindowEmperor::WaitForWindows() | ||
| void WindowEmperor::CreateNewWindow(winrt::TerminalApp::WindowRequestedArgs args) |
| { | ||
| if (const auto interop = coreWindow.try_as<ICoreWindowInterop>()) | ||
| { | ||
| HWND coreHandle = nullptr; | ||
| if (SUCCEEDED(interop->get_WindowHandle(&coreHandle)) && coreHandle) |
There was a problem hiding this comment.
Do we need to do this before we start spawning windows (and CLI processes?)
There was a problem hiding this comment.
I think we could do this at any point. Do you have something in mind?
| else | ||
| { | ||
| winrt::TerminalApp::WindowRequestedArgs request{ windowId, std::move(args) }; | ||
| request.WindowName(std::move(windowName)); |
There was a problem hiding this comment.
Entirely sytlistically, it's a little weird that this isn't like window = _mostRecentWindowCurrentDesktop(); break;. It's the only early return in what is otherwise a very methodical function
There was a problem hiding this comment.
That's unfortunately necessary because _mostRecentWindowCurrentDesktop is a coroutine. We could of course turn this function into a coroutine as well and then do
window = co_await _mostRecentWindowCurrentDesktop();
break;
It's mostly a coincidence that I drew the boundary like that.
| } | ||
| } | ||
| else if (!args.WindowName.empty()) | ||
| { |
There was a problem hiding this comment.
📝: you know, the code is cleaner if it's one for loop with the if(args.WindowID) / else if (!args.WindowName.empty()) statement on the inside, but it's less efficient then. 🤷
There was a problem hiding this comment.
Nah, it'd would not really be a big difference (branch prediction + it usually never loops >10 times anyway). This is also not really intentional, and I'll just move the if condition inside.
There was a problem hiding this comment.
Eh, you know what, I'll leave this as-is for now, because it makes the window = _mostRecentWindow(); branch at the end easier to express. If anyone ever happens to change this code I would not mind at all.
| wchar_t guidStr[39]; | ||
| guidStr[0] = L'{'; | ||
| memcpy(&guidStr[1], name.data() + 7, 36 * sizeof(wchar_t)); | ||
| guidStr[37] = L'}'; |
There was a problem hiding this comment.
of course it can't be, that would be too easy
There was a problem hiding this comment.
In my defense, when I wrote that GuidFromPlainString didn't exist yet. 😅
It's quite ugly code indeed.
| class BaseWindow | ||
| { | ||
| public: | ||
| static constexpr UINT CM_UPDATE_TITLE = WM_USER + 0; |
There was a problem hiding this comment.
feels weird that this guy isnt with the others in WindowEmperor. ik its lt a message "for the emperor", just threw me
There was a problem hiding this comment.
WM_USER messages are technically per-window-class from what I know, so I felt like they should be defined in their respective window classes as well.
| QueryPerformanceFrequency(&freq); | ||
| QueryPerformanceCounter(&counter); | ||
|
|
||
| const auto period = freq.QuadPart * 4; |
There was a problem hiding this comment.
oh intriguing, all windows will have the same frame xolor now cool
There was a problem hiding this comment.
Oh, woops, I wanted to back out this change and submit it as a separate PR.
And yeah, that, and fixing floating imprecision once WT has run for a long time, were my intentions with this.
|
Thanks for linking all the issues! I tested them and all but the last one seems fixed. |
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 ✅

As before, a minor refactor:
it into and deduplicating its functionality with
WindowEmperor.a single instance), I wrote single-instance code with a NT mutex
and by yeeting data across processes with
WM_COPYDATA.way faster. The more I tried to solve them the deeper I had to dig,
because you can't just put a mutex around
CascadiaSettings.I then tried to seeif WinUI can run multiple windows on a single
thread and, as it turns out, it can.
So, I removed the multi- from the window threading.
So, to finish it up, I had to clean up the entire eventing system
around
WindowEmperor, cleaned up all the coroutines,and cleaned up all the callbacks.
Closes #16183
Closes #16221
Closes #16487
Closes #16532
Closes #16733
Closes #16755
Closes #17015
Closes #17360
Closes #17420
Closes #17457
Closes #17799
Closes #17976
Closes #18057
Closes #18084
Closes #18169
Closes #18176
Closes #18191
Validation Steps Performed