From 93831f1bbc98b30192ef8782636038b7f0c062e7 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 29 Sep 2021 15:22:08 -0500 Subject: [PATCH 1/8] When enabling opacity on win10, automatically enable acrylic 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 --- src/cascadia/TerminalControl/ControlCore.cpp | 42 ++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 53486269823..2ebb1feb5b5 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -35,6 +35,22 @@ constexpr const auto UpdatePatternLocationsInterval = std::chrono::milliseconds( namespace winrt::Microsoft::Terminal::Control::implementation { + // 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 + static bool _isVintageOpacityAvailable() noexcept + { + OSVERSIONINFOEXW osver{}; + osver.dwOSVersionInfoSize = sizeof(osver); + osver.dwBuildNumber = 22000; // TODO! switch me to 22000 + + DWORDLONG dwlConditionMask = 0; + VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); + + return VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE; + } + // Helper static function to ensure that all ambiguous-width glyphs are reported as narrow. // See microsoft/terminal#2066 for more info. static bool _IsGlyphWideForceNarrowFallback(const std::wstring_view /* glyph */) @@ -444,6 +460,24 @@ 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()) + { + if (newOpacity < 1.0) + { + _settings.UseAcrylic(true); + } + else + { + _settings.UseAcrylic(false); + } + } + auto eventArgs = winrt::make_self(newOpacity); _TransparencyChangedHandlers(*this, *eventArgs); } @@ -572,6 +606,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(_settings.FontSize()); From 28055574310442568effcfebf43482297fd5d51d Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 6 Oct 2021 12:18:55 -0500 Subject: [PATCH 2/8] these were pr nits --- src/cascadia/TerminalControl/ControlCore.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index d2846e201c8..3d4c7576b00 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -43,7 +43,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { OSVERSIONINFOEXW osver{}; osver.dwOSVersionInfoSize = sizeof(osver); - osver.dwBuildNumber = 22000; // TODO! switch me to 22000 + osver.dwBuildNumber = 22000; DWORDLONG dwlConditionMask = 0; VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); @@ -466,14 +466,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // is what the Terminal did prior to 1.12. if (!_isVintageOpacityAvailable()) { - if (newOpacity < 1.0) - { - _settings.UseAcrylic(true); - } - else - { - _settings.UseAcrylic(false); - } + _settings.UseAcrylic(newOpacity < 1.0); } auto eventArgs = winrt::make_self(newOpacity); From 2e509d3aeee3f5f0e0e287136364727a05c70af1 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 6 Oct 2021 15:43:25 -0500 Subject: [PATCH 3/8] this does the auto-opacity thing, but does it on all versions --- src/cascadia/TerminalSettingsEditor/Profiles.cpp | 7 +++++++ src/cascadia/TerminalSettingsEditor/Profiles.h | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/src/cascadia/TerminalSettingsEditor/Profiles.cpp b/src/cascadia/TerminalSettingsEditor/Profiles.cpp index 8e43f9b10fc..d4a4ddbc1fa 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles.cpp @@ -47,6 +47,13 @@ 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") + { + if (!UseAcrylic()) + { + Opacity(1.0); + } + } }); // Do the same for the starting directory diff --git a/src/cascadia/TerminalSettingsEditor/Profiles.h b/src/cascadia/TerminalSettingsEditor/Profiles.h index 74c31e49a16..6e5379da7dc 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles.h +++ b/src/cascadia/TerminalSettingsEditor/Profiles.h @@ -23,6 +23,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void SetAcrylicOpacityPercentageValue(double value) { Opacity(winrt::Microsoft::Terminal::Settings::Editor::Converters::PercentageValueToPercentage(value)); + if (value < 100.0) + { + UseAcrylic(true); + } }; void SetPadding(double value) From 3347d9c0b9b55e856249a1371da5408dbf22c0a2 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 6 Oct 2021 15:48:27 -0500 Subject: [PATCH 4/8] fix the sui for @carlos-zamora --- src/cascadia/TerminalSettingsEditor/Profiles.cpp | 11 ++++++++++- src/cascadia/TerminalSettingsEditor/Profiles.h | 12 +++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalSettingsEditor/Profiles.cpp b/src/cascadia/TerminalSettingsEditor/Profiles.cpp index d4a4ddbc1fa..6c507ecf456 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles.cpp +++ b/src/cascadia/TerminalSettingsEditor/Profiles.cpp @@ -49,7 +49,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } else if (viewModelProperty == L"UseAcrylic") { - if (!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); } diff --git a/src/cascadia/TerminalSettingsEditor/Profiles.h b/src/cascadia/TerminalSettingsEditor/Profiles.h index 6e5379da7dc..49747895ee9 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles.h +++ b/src/cascadia/TerminalSettingsEditor/Profiles.h @@ -23,7 +23,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void SetAcrylicOpacityPercentageValue(double value) { Opacity(winrt::Microsoft::Terminal::Settings::Editor::Converters::PercentageValueToPercentage(value)); - if (value < 100.0) + + // 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 && CascadiaSettings::IsDefaultTerminalAvailable()) { UseAcrylic(true); } From 2ea7f4b4a2f89a35953f168b39717608b94b880b Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 6 Oct 2021 16:13:11 -0500 Subject: [PATCH 5/8] sometimes I don't always buid the code --- src/cascadia/TerminalSettingsEditor/Profiles.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cascadia/TerminalSettingsEditor/Profiles.h b/src/cascadia/TerminalSettingsEditor/Profiles.h index 49747895ee9..161f84e39f1 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles.h +++ b/src/cascadia/TerminalSettingsEditor/Profiles.h @@ -33,7 +33,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation // only works on Win11. So we'll use that. // // Remove when we can remove the rest of GH#11285 - if (value < 100.0 && CascadiaSettings::IsDefaultTerminalAvailable()) + if (value < 100.0 && winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings::IsDefaultTerminalAvailable()) { UseAcrylic(true); } From a3cbc30ec18ebacd48057ffc35f4c7333df36d10 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 6 Oct 2021 16:44:59 -0500 Subject: [PATCH 6/8] yea of course this is it' --- src/cascadia/TerminalControl/ControlCore.cpp | 2 +- .../ControlInteractivityTests.cpp | 22 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 3d4c7576b00..d5aa3184622 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -43,7 +43,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { OSVERSIONINFOEXW osver{}; osver.dwOSVersionInfoSize = sizeof(osver); - osver.dwBuildNumber = 22000; + osver.dwBuildNumber = 24000; DWORDLONG dwlConditionMask = 0; VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); diff --git a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp index db1e0743580..9cc86c59faa 100644 --- a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp @@ -19,6 +19,22 @@ using namespace ::Microsoft::Console::VirtualTerminal; namespace ControlUnitTests { + // 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 + static bool _isVintageOpacityAvailable() noexcept + { + OSVERSIONINFOEXW osver{}; + osver.dwOSVersionInfoSize = sizeof(osver); + osver.dwBuildNumber = 24000; + + DWORDLONG dwlConditionMask = 0; + VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); + + return VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE; + } + class ControlInteractivityTests { BEGIN_TEST_CLASS(ControlInteractivityTests) @@ -119,8 +135,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 = _isVintageOpacityAvailable() ? useAcrylic : + (expectedOpacity < 1.0 ? true : false); + VERIFY_ARE_EQUAL(expectedUseAcrylic, settings->UseAcrylic()); + VERIFY_ARE_EQUAL(expectedUseAcrylic, core->_settings.UseAcrylic()); }; core->TransparencyChanged(opacityCallback); From 0b6d428ecad44e2866b0c5e6cfb5adf2b18cd43e Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 6 Oct 2021 16:59:28 -0500 Subject: [PATCH 7/8] this should fix the tests --- src/cascadia/TerminalControl/ControlCore.cpp | 36 +++++++++---------- src/cascadia/TerminalControl/ControlCore.h | 2 ++ .../UnitTests_Control/ControlCoreTests.cpp | 7 ++-- .../ControlInteractivityTests.cpp | 20 ++--------- 4 files changed, 27 insertions(+), 38 deletions(-) diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index d5aa3184622..c2f88fb5105 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -35,22 +35,6 @@ constexpr const auto UpdatePatternLocationsInterval = std::chrono::milliseconds( namespace winrt::Microsoft::Terminal::Control::implementation { - // 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 - static bool _isVintageOpacityAvailable() noexcept - { - OSVERSIONINFOEXW osver{}; - osver.dwOSVersionInfoSize = sizeof(osver); - osver.dwBuildNumber = 24000; - - DWORDLONG dwlConditionMask = 0; - VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); - - return VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE; - } - // Helper static function to ensure that all ambiguous-width glyphs are reported as narrow. // See microsoft/terminal#2066 for more info. static bool _IsGlyphWideForceNarrowFallback(const std::wstring_view /* glyph */) @@ -464,7 +448,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // 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()) + if (!IsVintageOpacityAvailable()) { _settings.UseAcrylic(newOpacity < 1.0); } @@ -600,7 +584,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // 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()) + if (!IsVintageOpacityAvailable() && _settings.Opacity() < 1.0 && !_settings.UseAcrylic()) { _settings.UseAcrylic(true); } @@ -1580,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; + } } diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index a04032ef78e..9b96f6c7e48 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -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); diff --git a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp index 9e4a19e7b50..06bea9dc141 100644 --- a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp @@ -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); diff --git a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp index 9cc86c59faa..a249eb37c42 100644 --- a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp @@ -19,22 +19,6 @@ using namespace ::Microsoft::Console::VirtualTerminal; namespace ControlUnitTests { - // 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 - static bool _isVintageOpacityAvailable() noexcept - { - OSVERSIONINFOEXW osver{}; - osver.dwOSVersionInfoSize = sizeof(osver); - osver.dwBuildNumber = 24000; - - DWORDLONG dwlConditionMask = 0; - VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); - - return VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE; - } - class ControlInteractivityTests { BEGIN_TEST_CLASS(ControlInteractivityTests) @@ -135,8 +119,8 @@ namespace ControlUnitTests VERIFY_ARE_EQUAL(expectedOpacity, settings->Opacity()); VERIFY_ARE_EQUAL(expectedOpacity, core->_settings.Opacity()); - auto expectedUseAcrylic = _isVintageOpacityAvailable() ? useAcrylic : - (expectedOpacity < 1.0 ? true : false); + 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()); }; From fd9cf2cd972d24f058496d3a4930fb06a1857be5 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Wed, 6 Oct 2021 17:04:58 -0500 Subject: [PATCH 8/8] i loathe you entirely VS --- src/cascadia/UnitTests_Control/ControlCoreTests.cpp | 2 +- src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp index 06bea9dc141..4c090b27e71 100644 --- a/src/cascadia/UnitTests_Control/ControlCoreTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlCoreTests.cpp @@ -141,7 +141,7 @@ namespace ControlUnitTests // requested acrylic. auto expectedUseAcrylic = winrt::Microsoft::Terminal::Control::implementation::ControlCore::IsVintageOpacityAvailable() ? true : - (expectedOpacity < 1.0 ? true : false); + (expectedOpacity < 1.0 ? true : false); VERIFY_ARE_EQUAL(expectedUseAcrylic, settings->UseAcrylic()); VERIFY_ARE_EQUAL(expectedUseAcrylic, core->_settings.UseAcrylic()); }; diff --git a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp index a249eb37c42..51a2215e915 100644 --- a/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp +++ b/src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp @@ -120,7 +120,7 @@ namespace ControlUnitTests VERIFY_ARE_EQUAL(expectedOpacity, core->_settings.Opacity()); auto expectedUseAcrylic = winrt::Microsoft::Terminal::Control::implementation::ControlCore::IsVintageOpacityAvailable() ? useAcrylic : - (expectedOpacity < 1.0 ? true : false); + (expectedOpacity < 1.0 ? true : false); VERIFY_ARE_EQUAL(expectedUseAcrylic, settings->UseAcrylic()); VERIFY_ARE_EQUAL(expectedUseAcrylic, core->_settings.UseAcrylic()); };