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

When enabling opacity on win10, automatically enable acrylic #11372

Merged
11 commits merged into from
Oct 7, 2021
35 changes: 35 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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;
}
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
16 changes: 16 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Profiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Profiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 5 additions & 2 deletions src/cascadia/UnitTests_Control/ControlCoreTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
6 changes: 4 additions & 2 deletions src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down