Skip to content
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

Initialize Windows Terminal in STA #4505

Merged
2 commits merged into from
Feb 10, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions src/cascadia/WindowsTerminal/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,25 +91,22 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
// Make sure to call this so we get WM_POINTER messages.
EnableMouseInPointer(true);

// !!! LOAD BEARING !!!
// We must initialize the main thread as a single-threaded apartment before
// constructing any Xaml objects. Failing to do so will cause some issues
// in accessibility somewhere down the line when a UIAutomation object will
// be queried on the wrong thread at the wrong time.
// We used to initialize as STA only _after_ initializing the application
// host, which loaded the settings. The settings needed to be loaded in MTA
// because we were using the Windows.Storage APIs. Since we're no longer
// doing that, we can safely init as STA before any WinRT dispatches.
winrt::init_apartment(winrt::apartment_type::single_threaded);

// Create the AppHost object, which will create both the window and the
// Terminal App. This MUST BE constructed before the Xaml manager as TermApp
// provides an implementation of Windows.UI.Xaml.Application.
AppHost host;

// !!! LOAD BEARING !!!
// This is _magic_. Do the initial loading of our settings *BEFORE* we
// initialize our COM apartment type. This is because the Windows.Storage
// APIs require a MTA. However, other api's (notably the clipboard ones)
// require that the main thread is an STA. During startup, we don't yet have
// a dispatcher to background any async work, and we don't want to - we want
// to load the settings synchronously. Fortunately, WinRT will assume we're
// in a MTA until we explicitly call init_apartment. We can only call
// init_apartment _once_, so we'll do the settings loading first, in the
// implicit MTA, then set our apartment type to STA. The AppHost ctor will
// load the settings for us, as it constructs the window.
// This works because Kenny Kerr said it would, and he wrote cpp/winrt, so he knows.
winrt::init_apartment(winrt::apartment_type::single_threaded);

// Initialize the xaml content. This must be called AFTER the
// WindowsXamlManager is initalized.
host.Initialize();
Expand Down