Compare commits

...

1 Commits

Author SHA1 Message Date
Leonard Hecker
4120b0aa01 wip 2024-01-22 14:03:42 +01:00
16 changed files with 141 additions and 269 deletions

View File

@@ -75,10 +75,12 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// If multiple peasants are added concurrently we keep trying to update
// until we get to set the new id.
uint64_t current;
uint64_t next;
do
{
current = _nextPeasantID.load(std::memory_order_relaxed);
} while (current <= providedID && !_nextPeasantID.compare_exchange_weak(current, providedID + 1, std::memory_order_relaxed));
next = std::max(current, providedID) + 1;
} while (!_nextPeasantID.compare_exchange_weak(current, next, std::memory_order_relaxed));
}
auto newPeasantsId = peasant.GetID();
@@ -111,7 +113,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TIL_KEYWORD_TRACE));
_WindowCreatedHandlers(nullptr, nullptr);
_WindowCreatedHandlers(*this, winrt::box_value(newPeasantsId));
return newPeasantsId;
}
catch (...)
@@ -207,7 +209,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
std::unique_lock lock{ _peasantsMutex };
_peasants.erase(peasantId);
}
_WindowClosedHandlers(nullptr, nullptr);
_WindowClosedHandlers(*this, winrt::box_value(peasantId));
}
// Method Description:

View File

@@ -354,8 +354,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
args.ShowWindowCommand(),
args.CurrentEnvironment()));
_monarch.AddPeasant(*p);
p->GetWindowLayoutRequested({ get_weak(), &WindowManager::_GetWindowLayoutRequestedHandlers });
TraceLoggingWrite(g_hRemotingProvider,
@@ -367,6 +365,14 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
return *p;
}
void WindowManager::AddPeasant(const Remoting::Peasant& peasant) const
{
if (_monarch)
{
_monarch.AddPeasant(peasant);
}
}
void WindowManager::SignalClose(const Remoting::Peasant& peasant)
{
if (_monarch)

View File

@@ -31,6 +31,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::Microsoft::Terminal::Remoting::ProposeCommandlineResult ProposeCommandline(const winrt::Microsoft::Terminal::Remoting::CommandlineArgs& args, const bool isolatedMode);
Remoting::Peasant CreatePeasant(const Remoting::WindowRequestedArgs& args);
void AddPeasant(const Remoting::Peasant& peasant) const;
void SignalClose(const Remoting::Peasant& peasant);
void SummonWindow(const Remoting::SummonWindowSelectionArgs& args);
void SummonAllWindows();

View File

@@ -11,6 +11,7 @@ namespace Microsoft.Terminal.Remoting
ProposeCommandlineResult ProposeCommandline(CommandlineArgs args, Boolean isolatedMode);
Peasant CreatePeasant(WindowRequestedArgs args);
void AddPeasant(Peasant p);
void SignalClose(Peasant p);
void UpdateActiveTabTitle(String title, Peasant p);

View File

@@ -166,7 +166,8 @@ void AppHost::_HandleCommandlineArgs(const Remoting::WindowRequestedArgs& window
if (_windowLogic.ShouldExitEarly())
{
ExitThread(result);
TerminateProcess(GetCurrentProcess(), gsl::narrow_cast<UINT>(result));
__assume(false);
}
}
}
@@ -538,23 +539,10 @@ void AppHost::LastTabClosed(const winrt::Windows::Foundation::IInspectable& /*se
{
_windowLogic.ClearPersistedWindowState();
}
// If the user closes the last tab, in the last window, _by closing the tab_
// (not by closing the whole window), we need to manually persist an empty
// window state here. That will cause the terminal to re-open with the usual
// settings (not the persisted state)
if (args.ClearPersistedState() &&
_windowManager.GetNumberOfPeasants() == 1)
{
_windowLogic.ClearPersistedWindowState();
}
// Remove ourself from the list of peasants so that we aren't included in
// any future requests. This will also mean we block until any existing
// event handler finishes.
_windowManager.SignalClose(_peasant);
PostQuitMessage(0);
}
LaunchPosition AppHost::_GetWindowLaunchPosition()

View File

@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "pch.h"
#include "NonClientIslandWindow.h"
#include "NotificationIcon.h"

View File

@@ -77,7 +77,7 @@ void IslandWindow::Refrigerate() noexcept
_pfnCreateCallback = nullptr;
_pfnSnapDimensionCallback = nullptr;
_rootGrid.Children().Clear();
ShowWindow(_window.get(), SW_HIDE);
}

View File

@@ -26,6 +26,11 @@ NonClientIslandWindow::NonClientIslandWindow(const ElementTheme& requestedTheme)
{
}
NonClientIslandWindow::~NonClientIslandWindow()
{
Close();
}
void NonClientIslandWindow::Close()
{
// Avoid further callbacks into XAML/WinUI-land after we've Close()d the DesktopWindowXamlSource

View File

@@ -30,6 +30,7 @@ public:
static constexpr const int topBorderVisibleHeight = 1;
NonClientIslandWindow(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme) noexcept;
~NonClientIslandWindow() override;
void Refrigerate() noexcept override;

View File

@@ -5,14 +5,10 @@
#include "WindowEmperor.h"
#include "../inc/WindowingBehavior.h"
#include "../../types/inc/utils.hpp"
#include "../WinRTUtils/inc/WtExeUtils.h"
#include "resource.h"
#include "NotificationIcon.h"
#include <til/env.h>
using namespace winrt;
using namespace winrt::Microsoft::Terminal;
@@ -38,20 +34,6 @@ WindowEmperor::WindowEmperor() noexcept :
});
_dispatcher = winrt::Windows::System::DispatcherQueue::GetForCurrentThread();
// BODGY
//
// There's a mysterious crash in XAML on Windows 10 if you just let the App
// get dtor'd. By all accounts, it doesn't make sense. To mitigate this, we
// need to intentionally leak a reference to our App. Crazily, if you just
// let the app get cleaned up with the rest of the process when the process
// exits, then it doesn't crash. But if you let it get explicitly dtor'd, it
// absolutely will crash on exit.
//
// GH#15410 has more details.
auto a{ _app };
::winrt::detach_abi(a);
}
WindowEmperor::~WindowEmperor()
@@ -82,7 +64,7 @@ void _buildArgsFromCommandline(std::vector<winrt::hstring>& args)
}
}
bool WindowEmperor::HandleCommandlineArgs()
bool WindowEmperor::HandleCommandlineArgs(int nCmdShow)
{
std::vector<winrt::hstring> args;
_buildArgsFromCommandline(args);
@@ -98,28 +80,16 @@ bool WindowEmperor::HandleCommandlineArgs()
}
}
// Get the requested initial state of the window from our startup info. For
// something like `start /min`, this will set the wShowWindow member to
// SW_SHOWMINIMIZED. We'll need to make sure is bubbled all the way through,
// so we can open a new window with the same state.
STARTUPINFOW si;
GetStartupInfoW(&si);
const uint32_t showWindow = WI_IsFlagSet(si.dwFlags, STARTF_USESHOWWINDOW) ? si.wShowWindow : SW_SHOW;
const auto currentEnv{ til::env::from_current_environment() };
Remoting::CommandlineArgs eventArgs{ { args }, { cwd }, showWindow, winrt::hstring{ currentEnv.to_string() } };
const Remoting::CommandlineArgs eventArgs{ args, cwd, gsl::narrow_cast<uint32_t>(nCmdShow), GetEnvironmentStringsW() };
const auto isolatedMode{ _app.Logic().IsolatedMode() };
const auto result = _manager.ProposeCommandline(eventArgs, isolatedMode);
int exitCode = 0;
const bool makeWindow = result.ShouldCreateWindow();
if (makeWindow)
if (result.ShouldCreateWindow())
{
_createNewWindowThread(Remoting::WindowRequestedArgs{ result, eventArgs });
_becomeMonarch();
WaitForWindows();
}
else
{
@@ -127,11 +97,12 @@ bool WindowEmperor::HandleCommandlineArgs()
if (!res.Message.empty())
{
AppHost::s_DisplayMessageBox(res);
std::quick_exit(res.ExitCode);
}
exitCode = res.ExitCode;
}
return makeWindow;
TerminateProcess(GetCurrentProcess(), gsl::narrow_cast<UINT>(exitCode));
__assume(false);
}
void WindowEmperor::WaitForWindows()
@@ -146,7 +117,6 @@ void WindowEmperor::WaitForWindows()
void WindowEmperor::_createNewWindowThread(const Remoting::WindowRequestedArgs& args)
{
Remoting::Peasant peasant{ _manager.CreatePeasant(args) };
std::shared_ptr<WindowThread> window{ nullptr };
// FIRST: Attempt to reheat an existing window that we refrigerated for
@@ -168,7 +138,7 @@ void WindowEmperor::_createNewWindowThread(const Remoting::WindowRequestedArgs&
// Cool! Let's increment the number of active windows, and re-heat it.
_windowThreadInstances.fetch_add(1, std::memory_order_relaxed);
window->Microwave(args, peasant);
window->Microwave(args);
// This will unblock the event we're waiting on in KeepWarm, and the
// window thread (started below) will continue through it's loop
return;
@@ -177,9 +147,7 @@ void WindowEmperor::_createNewWindowThread(const Remoting::WindowRequestedArgs&
// At this point, there weren't any pending refrigerated threads we could
// just use. That's fine. Let's just go create a new one.
window = std::make_shared<WindowThread>(_app.Logic(), args, _manager, peasant);
std::weak_ptr<WindowEmperor> weakThis{ weak_from_this() };
window = std::make_shared<WindowThread>(_app.Logic(), _manager);
// Increment our count of window instances _now_, immediately. We're
// starting a window now, we shouldn't exit (due to having 0 windows) till
@@ -196,70 +164,31 @@ void WindowEmperor::_createNewWindowThread(const Remoting::WindowRequestedArgs&
// Hence: increment the number of total windows now.
_windowThreadInstances.fetch_add(1, std::memory_order_relaxed);
std::thread t([weakThis, window]() {
std::thread t([weakThis = weak_from_this(), window = std::move(window), args = std::move(args)]() {
try
{
window->CreateHost();
winrt::init_apartment(winrt::apartment_type::single_threaded);
window->CreateHost(std::move(args));
if (auto self{ weakThis.lock() })
{
self->_windowStartedHandlerPostXAML(window);
}
while (window->KeepWarm())
// Now that the window is ready to go, we can add it to our list of windows,
// because we know it will be well behaved.
//
// Be sure to only modify the list of windows under lock.
if (auto self{ weakThis.lock() })
{
// Now that the window is ready to go, we can add it to our list of windows,
// because we know it will be well behaved.
//
// Be sure to only modify the list of windows under lock.
if (auto self{ weakThis.lock() })
{
auto lockedWindows{ self->_windows.lock() };
lockedWindows->push_back(window);
}
auto removeWindow = wil::scope_exit([&]() {
if (auto self{ weakThis.lock() })
{
self->_removeWindow(window->PeasantID());
}
});
auto decrementWindowCount = wil::scope_exit([&]() {
if (auto self{ weakThis.lock() })
{
self->_decrementWindowCount();
}
});
window->RunMessagePump();
// Manually trigger the cleanup callback. This will ensure that we
// remove the window from our list of windows, before we release the
// AppHost (and subsequently, the host's Logic() member that we use
// elsewhere).
removeWindow.reset();
// On Windows 11, we DONT want to refrigerate the window. There,
// we can just close it like normal. Break out of the loop, so
// we don't try to put this window in the fridge.
if (Utils::IsWindows11())
{
decrementWindowCount.reset();
break;
}
else
{
window->Refrigerate();
decrementWindowCount.reset();
if (auto self{ weakThis.lock() })
{
auto fridge{ self->_oldThreads.lock() };
fridge->push_back(window);
}
}
auto lockedWindows{ self->_windows.lock() };
lockedWindows->push_back(window);
}
window->RunMessagePump();
// Now that we no longer care about this thread's window, let it
// release it's app host and flush the rest of the XAML queue.
window->RundownForExit();
@@ -294,17 +223,6 @@ void WindowEmperor::_windowStartedHandlerPostXAML(const std::shared_ptr<WindowTh
// before we make the window visible.
}
void WindowEmperor::_removeWindow(uint64_t senderID)
{
auto lockedWindows{ _windows.lock() };
// find the window in _windows who's peasant's Id matches the peasant's Id
// and remove it
std::erase_if(*lockedWindows, [&](const auto& w) {
return w->PeasantID() == senderID;
});
}
void WindowEmperor::_decrementWindowCount()
{
// When we run out of windows, exit our process if and only if:
@@ -358,8 +276,8 @@ void WindowEmperor::_becomeMonarch()
// Set the number of open windows (so we know if we are the last window)
// and subscribe for updates if there are any changes to that number.
_revokers.WindowCreated = _manager.WindowCreated(winrt::auto_revoke, { this, &WindowEmperor::_numberOfWindowsChanged });
_revokers.WindowClosed = _manager.WindowClosed(winrt::auto_revoke, { this, &WindowEmperor::_numberOfWindowsChanged });
_revokers.WindowCreated = _manager.WindowCreated(winrt::auto_revoke, { this, &WindowEmperor::_windowCreated });
_revokers.WindowClosed = _manager.WindowClosed(winrt::auto_revoke, { this, &WindowEmperor::_windowClosed });
// If the monarch receives a QuitAll event it will signal this event to be
// ran before each peasant is closed.
@@ -371,9 +289,49 @@ void WindowEmperor::_becomeMonarch()
_getWindowLayoutThrottler.value()();
}
// sender and args are always nullptr
void WindowEmperor::_numberOfWindowsChanged(const winrt::Windows::Foundation::IInspectable&,
const winrt::Windows::Foundation::IInspectable&)
void WindowEmperor::_windowCreated(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&)
{
_numberOfWindowsChanged();
}
void WindowEmperor::_windowClosed(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable& value)
{
const auto peasantID = winrt::unbox_value<uint64_t>(value);
std::shared_ptr<WindowThread> window;
// Below we'll lock _oldThreads. It would be possible to do it within this block so that we can avoid the window variable above.
// But holding both locks simultaneously may result in an ABBA deadlock. Bumping reference counts is cheap and so this is a good solution.
{
const auto windows = _windows.lock();
const auto it = std::find_if(windows->begin(), windows->end(), [&](const auto& w) {
return w->PeasantID() == peasantID;
});
if (it == windows->end())
{
return;
}
window = *it;
windows->erase(it);
}
_decrementWindowCount();
if (Utils::IsWindows11())
{
PostQuitMessage(0);
}
else
{
window->Refrigerate();
_oldThreads.lock()->push_back(std::move(window));
}
_numberOfWindowsChanged();
}
void WindowEmperor::_numberOfWindowsChanged()
{
if (_getWindowLayoutThrottler)
{
@@ -584,15 +542,6 @@ LRESULT WindowEmperor::_messageHandler(UINT const message, WPARAM const wParam,
// we'll undoubtedly crash.
winrt::fire_and_forget WindowEmperor::_close()
{
{
auto fridge{ _oldThreads.lock() };
for (auto& window : *fridge)
{
window->ThrowAway();
}
fridge->clear();
}
// Important! Switch back to the main thread for the emperor. That way, the
// quit will go to the emperor's message pump.
co_await wil::resume_foreground(_dispatcher);

View File

@@ -27,7 +27,7 @@ public:
~WindowEmperor();
void WaitForWindows();
bool HandleCommandlineArgs();
bool HandleCommandlineArgs(int nCmdShow);
private:
void _createNewWindowThread(const winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs& args);
@@ -57,11 +57,12 @@ private:
bool _quitting{ false };
void _windowStartedHandlerPostXAML(const std::shared_ptr<WindowThread>& sender);
void _removeWindow(uint64_t senderID);
void _decrementWindowCount();
void _becomeMonarch();
void _numberOfWindowsChanged(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&);
void _windowCreated(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&);
void _windowClosed(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&);
void _numberOfWindowsChanged();
void _quitAllRequested(const winrt::Windows::Foundation::IInspectable&,
const winrt::Microsoft::Terminal::Remoting::QuitAllRequestedArgs&);

View File

@@ -4,38 +4,30 @@
#include "pch.h"
#include "WindowThread.h"
WindowThread::WindowThread(winrt::TerminalApp::AppLogic logic,
winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs args,
winrt::Microsoft::Terminal::Remoting::WindowManager manager,
winrt::Microsoft::Terminal::Remoting::Peasant peasant) :
_peasant{ std::move(peasant) },
using namespace winrt::Microsoft::Terminal::Remoting;
WindowThread::WindowThread(winrt::TerminalApp::AppLogic logic, WindowManager manager) :
_appLogic{ std::move(logic) },
_args{ std::move(args) },
_manager{ std::move(manager) }
{
// DO NOT start the AppHost here in the ctor, as that will start XAML on the wrong thread!
}
void WindowThread::CreateHost()
void WindowThread::CreateHost(WindowRequestedArgs args)
{
// Calling this while refrigerated won't work.
// * We can't re-initialize our winrt apartment.
// * AppHost::Initialize has to be done on the "UI" thread.
assert(_warmWindow == nullptr);
winrt::init_apartment(winrt::apartment_type::single_threaded);
// Start the AppHost HERE, on the actual thread we want XAML to run on
_host = std::make_shared<::AppHost>(_appLogic,
_args,
_manager,
_peasant);
_peasant = _manager.CreatePeasant(args);
_host = std::make_shared<::AppHost>(_appLogic, std::move(args), _manager, _peasant);
_UpdateSettingsRequestedToken = _host->UpdateSettingsRequested([this]() { _UpdateSettingsRequestedHandlers(); });
winrt::init_apartment(winrt::apartment_type::single_threaded);
// Initialize the xaml content. This must be called AFTER the
// WindowsXamlManager is initialized.
_host->Initialize();
_dispatcher = winrt::Windows::System::DispatcherQueue::GetForCurrentThread();
}
int WindowThread::RunMessagePump()
@@ -81,59 +73,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
// _microwaveBuzzer. We'll sit there like that till the emperor decides if
// they want to re-use this window thread for a new window.
// Return Value:
// - true IFF we should enter this thread's message loop
// INVARIANT: This must be called on our "ui thread", our window thread.
bool WindowThread::KeepWarm()
{
if (_host != nullptr)
{
// We're currently hot
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)
{
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)
{
_UpdateSettingsRequestedToken = _host->UpdateSettingsRequested([this]() { _UpdateSettingsRequestedHandlers(); });
// Re-initialize the host here, on the window thread
_host->Initialize();
}
return reheated;
}
else
{
return false;
}
}
// Method Description:
// - "Refrigerate" this thread for later reuse. This will refrigerate the window
// itself, and tear down our current app host. We'll save our window for
@@ -143,12 +82,8 @@ bool WindowThread::KeepWarm()
void WindowThread::Refrigerate()
{
_host->UpdateSettingsRequested(_UpdateSettingsRequestedToken);
// keep a reference to the HWND and DesktopWindowXamlSource alive.
_warmWindow = std::move(_host->Refrigerate());
// rundown remaining messages before destructing the app host
_pumpRemainingXamlMessages();
_host = nullptr;
}
@@ -157,21 +92,14 @@ void WindowThread::Refrigerate()
// 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)
void WindowThread::Microwave(WindowRequestedArgs args)
{
_peasant = std::move(peasant);
_args = std::move(args);
_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();
_dispatcher.TryEnqueue(winrt::Windows::System::DispatcherQueuePriority::Normal, [this, args = std::move(args)]() {
_peasant = _manager.CreatePeasant(args);
_host = std::make_shared<::AppHost>(_appLogic, std::move(args), _manager, _peasant, std::move(_warmWindow));
_UpdateSettingsRequestedToken = _host->UpdateSettingsRequested([this]() { _UpdateSettingsRequestedHandlers(); });
_host->Initialize();
});
}
winrt::TerminalApp::TerminalWindow WindowThread::Logic()

View File

@@ -7,33 +7,25 @@
class WindowThread : public std::enable_shared_from_this<WindowThread>
{
public:
WindowThread(winrt::TerminalApp::AppLogic logic,
winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs args,
winrt::Microsoft::Terminal::Remoting::WindowManager manager,
winrt::Microsoft::Terminal::Remoting::Peasant peasant);
WindowThread(winrt::TerminalApp::AppLogic logic, winrt::Microsoft::Terminal::Remoting::WindowManager manager);
winrt::TerminalApp::TerminalWindow Logic();
void CreateHost();
void CreateHost(winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs args);
int RunMessagePump();
void RundownForExit();
bool KeepWarm();
void Refrigerate();
void Microwave(
winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs args,
winrt::Microsoft::Terminal::Remoting::Peasant peasant);
void ThrowAway();
void Microwave(winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs args);
uint64_t PeasantID();
WINRT_CALLBACK(UpdateSettingsRequested, winrt::delegate<void()>);
private:
winrt::Microsoft::Terminal::Remoting::Peasant _peasant{ nullptr };
winrt::TerminalApp::AppLogic _appLogic{ nullptr };
winrt::Microsoft::Terminal::Remoting::WindowRequestedArgs _args{ nullptr };
winrt::Microsoft::Terminal::Remoting::WindowManager _manager{ nullptr };
winrt::Microsoft::Terminal::Remoting::Peasant _peasant{ nullptr };
winrt::Windows::System::DispatcherQueue _dispatcher{ nullptr };
// This is a "shared_ptr", but it should be treated as a unique, owning ptr.
// It's shared, because there are edge cases in refrigeration where internal
@@ -43,8 +35,6 @@ private:
winrt::event_token _UpdateSettingsRequestedToken;
std::unique_ptr<::IslandWindow> _warmWindow{ nullptr };
std::mutex _microwave;
std::condition_variable _microwaveBuzzer;
int _messagePump();
void _pumpRemainingXamlMessages();

View File

@@ -83,7 +83,7 @@ static void EnsureNativeArchitecture()
}
}
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int nCmdShow)
{
TraceLoggingRegister(g_hWindowsTerminalProvider);
::Microsoft::Console::ErrorReporting::EnableFallbackFailureReporting(g_hWindowsTerminalProvider);
@@ -115,8 +115,5 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
winrt::init_apartment(winrt::apartment_type::single_threaded);
const auto emperor = std::make_shared<::WindowEmperor>();
if (emperor->HandleCommandlineArgs())
{
emperor->WaitForWindows();
}
emperor->HandleCommandlineArgs(nCmdShow);
}

View File

@@ -48,7 +48,7 @@ Abstract:
#include <wil/cppwinrt.h>
// Needed just for XamlIslands to work at all:
#include <winrt/Windows.system.h>
#include <winrt/Windows.System.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
@@ -63,7 +63,7 @@ Abstract:
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
#include <winrt/Windows.UI.Xaml.Data.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.UI.Xaml.Media.h>
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.ApplicationModel.Resources.Core.h>
#include <winrt/Windows.UI.Composition.h>

View File

@@ -855,19 +855,20 @@ std::wstring Utils::EvaluateStartingDirectory(
bool Utils::IsWindows11() noexcept
{
static const bool isWindows11 = []() noexcept {
OSVERSIONINFOEXW osver{};
osver.dwOSVersionInfoSize = sizeof(osver);
osver.dwBuildNumber = 22000;
DWORDLONG dwlConditionMask = 0;
VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
if (VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE)
{
return true;
}
return false;
}();
return isWindows11;
//static const bool isWindows11 = []() noexcept {
// OSVERSIONINFOEXW osver{};
// osver.dwOSVersionInfoSize = sizeof(osver);
// osver.dwBuildNumber = 22000;
//
// DWORDLONG dwlConditionMask = 0;
// VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
//
// if (VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE)
// {
// return true;
// }
// return false;
//}();
//return isWindows11;
return false;
}