When enabling opacity on win10, automatically enable acrylic (#11372)

In #11180 we made `opacity` independent from `useAcrylic`. We also changed the mouse wheel behavior to only change opacity, and not mess with acrylic.

However, on Windows 10, vintage opacity doesn't work at all. So there, we still need to manually enable acrylic when the user requests opacity.

* [x] Closes #11285

SUI changes in action:

![auto-acrylic-win10](https://user-images.githubusercontent.com/18356694/136281935-db9a10f4-e0ad-4422-950b-0a01dc3e12c0.gif)
This commit is contained in:
Mike Griese 2021-10-07 06:39:20 -05:00 committed by GitHub
parent bd8bfa13bb
commit 694c6b263f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 4 deletions

View File

@ -442,6 +442,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_settings.Opacity(newOpacity);
// GH#11285 - If the user is on Windows 10, and they changed the
// transparency of the control s.t. it should be partially opaque, then
// opt them in to acrylic. It's the only way to have transparency on
// Windows 10.
// We'll also turn the acrylic back off when they're fully opaque, which
// is what the Terminal did prior to 1.12.
if (!IsVintageOpacityAvailable())
{
_settings.UseAcrylic(newOpacity < 1.0);
}
auto eventArgs = winrt::make_self<TransparencyChangedEventArgs>(newOpacity);
_TransparencyChangedHandlers(*this, *eventArgs);
}
@ -570,6 +581,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_settings = settings;
// GH#11285 - If the user is on Windows 10, and they wanted opacity, but
// didn't explicitly request acrylic, then opt them in to acrylic.
// On Windows 11+, this isn't needed, because we can have vintage opacity.
if (!IsVintageOpacityAvailable() && _settings.Opacity() < 1.0 && !_settings.UseAcrylic())
{
_settings.UseAcrylic(true);
}
// Initialize our font information.
const auto fontFace = _settings.FontFace();
const short fontHeight = ::base::saturated_cast<short>(_settings.FontSize());
@ -1545,4 +1564,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return hstring(ss.str());
}
// Helper to check if we're on Windows 11 or not. This is used to check if
// we need to use acrylic to achieve transparency, because vintage opacity
// doesn't work in islands on win10.
// Remove when we can remove the rest of GH#11285
bool ControlCore::IsVintageOpacityAvailable() noexcept
{
OSVERSIONINFOEXW osver{};
osver.dwOSVersionInfoSize = sizeof(osver);
osver.dwBuildNumber = 22000;
DWORDLONG dwlConditionMask = 0;
VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
return VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE;
}
}

View File

@ -149,6 +149,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
hstring ReadEntireBuffer() const;
static bool IsVintageOpacityAvailable() noexcept;
// -------------------------------- WinRT Events ---------------------------------
// clang-format off
WINRT_CALLBACK(FontSizeChanged, Control::FontSizeChangedEventArgs);

View File

@ -47,6 +47,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// NOTE: this is similar to what is done with BackgroundImagePath above
_NotifyChanges(L"UseParentProcessDirectory", L"UseCustomStartingDirectory");
}
else if (viewModelProperty == L"UseAcrylic")
{
// GH#11372: If we're on Windows 10, and someone turns off
// acrylic, we're going to disable opacity for them. Opacity
// doesn't work without acrylic on Windows 10.
//
// BODGY: CascadiaSettings's function IsDefaultTerminalAvailable
// is basically a "are we on Windows 11" check, because defterm
// only works on Win11. So we'll use that.
//
// Remove when we can remove the rest of GH#11285
if (!UseAcrylic() && !CascadiaSettings::IsDefaultTerminalAvailable())
{
Opacity(1.0);
}
}
});
// Do the same for the starting directory

View File

@ -23,6 +23,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void SetAcrylicOpacityPercentageValue(double value)
{
Opacity(winrt::Microsoft::Terminal::Settings::Editor::Converters::PercentageValueToPercentage(value));
// GH#11372: If we're on Windows 10, and someone wants opacity, then
// we'll turn acrylic on for them. Opacity doesn't work without
// acrylic on Windows 10.
//
// BODGY: CascadiaSettings's function IsDefaultTerminalAvailable
// is basically a "are we on Windows 11" check, because defterm
// only works on Win11. So we'll use that.
//
// Remove when we can remove the rest of GH#11285
if (value < 100.0 && winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings::IsDefaultTerminalAvailable())
{
UseAcrylic(true);
}
};
void SetPadding(double value)

View File

@ -139,8 +139,11 @@ namespace ControlUnitTests
// GH#603: Adjusting opacity shouldn't change whether or not we
// requested acrylic.
VERIFY_IS_TRUE(settings->UseAcrylic());
VERIFY_IS_TRUE(core->_settings.UseAcrylic());
auto expectedUseAcrylic = winrt::Microsoft::Terminal::Control::implementation::ControlCore::IsVintageOpacityAvailable() ? true :
(expectedOpacity < 1.0 ? true : false);
VERIFY_ARE_EQUAL(expectedUseAcrylic, settings->UseAcrylic());
VERIFY_ARE_EQUAL(expectedUseAcrylic, core->_settings.UseAcrylic());
};
core->TransparencyChanged(opacityCallback);

View File

@ -119,8 +119,10 @@ namespace ControlUnitTests
VERIFY_ARE_EQUAL(expectedOpacity, settings->Opacity());
VERIFY_ARE_EQUAL(expectedOpacity, core->_settings.Opacity());
VERIFY_ARE_EQUAL(useAcrylic, settings->UseAcrylic());
VERIFY_ARE_EQUAL(useAcrylic, core->_settings.UseAcrylic());
auto expectedUseAcrylic = winrt::Microsoft::Terminal::Control::implementation::ControlCore::IsVintageOpacityAvailable() ? useAcrylic :
(expectedOpacity < 1.0 ? true : false);
VERIFY_ARE_EQUAL(expectedUseAcrylic, settings->UseAcrylic());
VERIFY_ARE_EQUAL(expectedUseAcrylic, core->_settings.UseAcrylic());
};
core->TransparencyChanged(opacityCallback);