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

[Mica] Fix crash accessing BaseWindowHandler::m_capabilities from Capabilities::Changed handler #6288

Merged
merged 3 commits into from
Nov 15, 2021
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion dev/Materials/Backdrop/MicaController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ bool MicaController::SetTarget(winrt::Windows::UI::Xaml::Window const& xamlWindo
return false;
}

m_windowHandler = std::make_unique<SystemBackdropComponentInternal::XamlWindowHandler>(this, xamlWindow);
m_windowHandler = winrt::make_self<SystemBackdropComponentInternal::XamlWindowHandler>(this, xamlWindow);

// Ensure we are in the correct policy state only *after* creating the appropriate WindowHandler.
// If we start in high contrast mode, the controller will query the window handler for the correct system fallback color.
Expand Down
2 changes: 1 addition & 1 deletion dev/Materials/Backdrop/MicaController.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct MicaController : winrt::implementation::MicaControllerT<MicaController>,
winrt::CompositionBrush m_currentBrush{ nullptr };
winrt::Windows::UI::Composition::Compositor m_compositor{ nullptr };
winrt::weak_ref<winrt::Microsoft::UI::Private::Controls::ICompositionSupportsSystemBackdrop> m_target{ nullptr };
std::unique_ptr<SystemBackdropComponentInternal::BaseWindowHandler> m_windowHandler{ nullptr };
com_ptr<SystemBackdropComponentInternal::BaseWindowHandler> m_windowHandler{ nullptr };

bool m_isActive{ false };
bool m_isExplicitFallbackColorSet{ false };
Expand Down
61 changes: 33 additions & 28 deletions dev/Materials/Backdrop/SystemBackdropWindowHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,65 +31,70 @@ namespace SystemBackdropComponentInternal

m_policy = std::make_unique<SystemBackdropPolicyStateMachine>(SystemBackdropPolicyState::Active);

m_powerManagerEventRevoker = winrt::Windows::System::Power::PowerManager::EnergySaverStatusChanged(winrt::auto_revoke, [&](auto&&, auto&&)
m_powerManagerEventRevoker = winrt::Windows::System::Power::PowerManager::EnergySaverStatusChanged(winrt::auto_revoke,
[weakThis = get_weak(), dispatcherQueue = m_dispatcherQueue](auto&&, auto&&)
{
m_dispatcherQueue.TryEnqueue([&]()
dispatcherQueue.TryEnqueue([weakThis]()
{
if (winrt::Windows::System::Power::PowerManager::EnergySaverStatus() == winrt::Windows::System::Power::EnergySaverStatus::On)
{
m_policy->SetPowerSavingMode(true);
}
else
auto strongThis = weakThis.get();
if (strongThis)
{
m_policy->SetPowerSavingMode(false);
}
if (winrt::Windows::System::Power::PowerManager::EnergySaverStatus() == winrt::Windows::System::Power::EnergySaverStatus::On)
{
strongThis->m_policy->SetPowerSavingMode(true);
}
else
{
strongThis->m_policy->SetPowerSavingMode(false);
}

ActivateOrDeactivateController();
strongThis->ActivateOrDeactivateController();
}
});
});

m_capabilities = winrt::Windows::UI::Composition::CompositionCapabilities::GetForCurrentView();
m_capabilitiesEventRevoker = { m_capabilities, m_capabilities.Changed([&](auto&&, auto&&)
m_capabilitiesEventRevoker = { m_capabilities, m_capabilities.Changed(
[weakThis = get_weak(), dispatcherQueue = m_dispatcherQueue](auto&&, auto&&)
{
auto capabilitiesWeakRef = winrt::make_weak(m_capabilities);

m_dispatcherQueue.TryEnqueue([capabilitiesWeakRef, this]()
dispatcherQueue.TryEnqueue([weakThis]()
{
if (auto capabilities = capabilitiesWeakRef.get())
auto strongThis= weakThis.get();
if (strongThis)
{
if (capabilities.AreEffectsFast())
if (strongThis->m_capabilities.AreEffectsFast())
{
m_policy->SetIncompatibleGraphicsDevice(false);
strongThis->m_policy->SetIncompatibleGraphicsDevice(false);
}
else
{
m_policy->SetIncompatibleGraphicsDevice(true);
strongThis->m_policy->SetIncompatibleGraphicsDevice(true);
}

ActivateOrDeactivateController();
strongThis->ActivateOrDeactivateController();
}
});
}) };

m_uiSettings = winrt::Windows::UI::ViewManagement::UISettings();
m_uiSettingsEventRevoker = m_uiSettings.AdvancedEffectsEnabledChanged(winrt::auto_revoke, [&](auto&&, auto&&)
m_uiSettingsEventRevoker = m_uiSettings.AdvancedEffectsEnabledChanged(winrt::auto_revoke,
[weakThis = get_weak(), dispatcherQueue = m_dispatcherQueue](auto&&, auto&&)
{
auto uiSettingsWeakRef = winrt::make_weak(m_uiSettings);

m_dispatcherQueue.TryEnqueue([uiSettingsWeakRef, this]()
dispatcherQueue.TryEnqueue([weakThis]()
{
if (auto uiSettings = uiSettingsWeakRef.get())
auto strongThis = weakThis.get();
if (strongThis)
{
if (uiSettings.AdvancedEffectsEnabled())
if (strongThis->m_uiSettings.AdvancedEffectsEnabled())
{
m_policy->SetTransparencyDisabled(false);
strongThis->m_policy->SetTransparencyDisabled(false);
}
else
{
m_policy->SetTransparencyDisabled(true);
strongThis->m_policy->SetTransparencyDisabled(true);
}

ActivateOrDeactivateController();
strongThis->ActivateOrDeactivateController();
}
});
});
Expand Down
2 changes: 1 addition & 1 deletion dev/Materials/Backdrop/SystemBackdropWindowHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ namespace SystemBackdropComponentInternal
winrt::event_token m_token{};
};

struct BaseWindowHandler
struct BaseWindowHandler : public winrt::implements<BaseWindowHandler, winrt::IInspectable>
{
virtual ~BaseWindowHandler()
{
Expand Down