From 229ba89c83426274191d8e3dea2fa5c68b3e7a3a Mon Sep 17 00:00:00 2001 From: Jaswir Date: Fri, 13 Oct 2023 22:43:38 +0200 Subject: [PATCH] Allow Opacity to be set differently in both focused and unfocused terminals (#15974) ## Summary of the Pull Request Closes #11092 Allowing `opacity `to be set differently in both focused and unfocused terminals ## References and Relevant Issues #11092 , references: #7158 ## Detailed Description of the Pull Request / Additional comments ### Allowing Opacity to be set differently in both focused and unfocused terminals: ![unfocused_opacity](https://github.com/microsoft/terminal/assets/15957528/1c38e40b-4678-43ec-b328-ad79d222579f) ![image](https://github.com/microsoft/terminal/assets/15957528/3e3342a8-7908-41db-9c37-26c89f7f2456) ![jolsen](https://github.com/microsoft/terminal/assets/15957528/68553507-d29e-4513-89ce-b1cd305d28b7) ![image](https://github.com/microsoft/terminal/assets/15957528/18864f60-91d0-4159-87da-2b2ee1637a4c) ## `_runtimeFocusedOpacity` Mike also had to say something about this: https://github.com/microsoft/terminal/issues/2531#issuecomment-1668442774 Initially I had something like ` _setOpacity(newAppearance->Opacity());` But with the introduction of unfocused opacity we encounter new challenges: When Adjusting the Opacity with **CTRL+SHIFT+Mouse Scroll Wheel** or **Set background opacity** in command pallette, the Runtime opacity changes, but when we go to unfocused and back to focused the opacity changes back to focused opacity in Settings. Also when adjusting opacity through the command palette the window becomes unfocused and then focused again after setting background opacity hence the ` _setOpacity(newAppearance->Opacity());` would override the changes made through command palette ![runtimeFocusedOpacity](https://github.com/microsoft/terminal/assets/15957528/4de63057-d658-4b5e-99ad-7db050834ade) ![command_pallette_focusswitches](https://github.com/microsoft/terminal/assets/15957528/372526eb-cf0c-40f8-a4e5-a0739f1f0e05) With the introduction of unfocused opacity we encounter new challenges. The runtime opacity stores both the unfocused opacity and focused opacity from settings at different moments. This all works well until we combine this with Adjusting the Opacity with **CTRL+SHIFT+Mouse Scroll Wheel** or **Set background opacity** in command pallette. This brings the need for a separate Focused Opacity. When we change the runtime opacity with scroll wheel or through command pallette this value needs to be stored separately from the one in settings. So we can change back to it when going to unfocused mode and back to focused instead of the focused opacity defined in settings. ## `skipUnfocusedOpacity` solves Opacity going from solid to unfocused to focused bug: ![skipUnfocusedOpacity_bug](https://github.com/microsoft/terminal/assets/15957528/ecc06dcf-fbef-4fef-a40f-68278fdbfb12) ## Validation Steps Performed - Checked if unfocused Opacity works well when adjusting opacity through Mouse Scroll Wheel or Command Palette and in combination with Acrylic as mentioned in "Detailed Description of the Pull Request / Additional comments" ## PR Checklist - [x] Closes #11092 - [ ] Tests added/passed - [x] Documentation updated - If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here:(https://github.com/MicrosoftDocs/terminal/pull/714) - [ ] Schema updated (if necessary) (cherry picked from commit 27e1081c8cc417fade9e053b7b6738a6c382f7b9) Service-Card-Id: 90949918 Service-Version: 1.19 --- doc/cascadia/profiles.schema.json | 7 ++++ src/cascadia/TerminalControl/ControlCore.cpp | 38 +++++++++++++++----- src/cascadia/TerminalControl/ControlCore.h | 3 +- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 9dc3a8afd58..f4b0d5e37c8 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -273,6 +273,13 @@ "useAcrylic":{ "description": "When set to true, the window will have an acrylic material background when unfocused. When set to false, the window will have a plain, untextured background when unfocused.", "type": "boolean" + }, + "opacity": { + "default": 100, + "description": "Sets the opacity of the window for the profile when unfocused. Accepts values from 0-100.", + "maximum": 100, + "minimum": 0, + "type": "number" } }, "type": "object" diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index a7609d29747..7925fc16eb8 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -680,7 +680,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation _setOpacity(Opacity() + adjustment); } - void ControlCore::_setOpacity(const double opacity) + // Method Description: + // - Updates the opacity of the terminal + // Arguments: + // - opacity: The new opacity to set. + // - focused (default == true): Whether the window is focused or unfocused. + // Return Value: + // - + void ControlCore::_setOpacity(const double opacity, bool focused) { const auto newOpacity = std::clamp(opacity, 0.0, @@ -694,6 +701,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Update our runtime opacity value _runtimeOpacity = newOpacity; + //Stores the focused runtime opacity separately from unfocused opacity + //to transition smoothly between the two. + _runtimeFocusedOpacity = focused ? newOpacity : _runtimeFocusedOpacity; + // Manually turn off acrylic if they turn off transparency. _runtimeUseAcrylic = newOpacity < 1.0 && _settings->UseAcrylic(); @@ -824,6 +835,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _cellWidth = CSSLengthPercentage::FromString(_settings->CellWidth().c_str()); _cellHeight = CSSLengthPercentage::FromString(_settings->CellHeight().c_str()); _runtimeOpacity = std::nullopt; + _runtimeFocusedOpacity = std::nullopt; // Manually turn off acrylic if they turn off transparency. _runtimeUseAcrylic = _settings->Opacity() < 1.0 && _settings->UseAcrylic(); @@ -874,21 +886,29 @@ namespace winrt::Microsoft::Terminal::Control::implementation _renderEngine->SetRetroTerminalEffect(newAppearance->RetroTerminalEffect()); _renderEngine->SetPixelShaderPath(newAppearance->PixelShaderPath()); + // Incase EnableUnfocusedAcrylic is disabled and Focused Acrylic is set to true, + // the terminal should ignore the unfocused opacity from settings. + // The Focused Opacity from settings should be ignored if overridden at runtime. + bool useFocusedRuntimeOpacity = focused || (!_settings->EnableUnfocusedAcrylic() && UseAcrylic()); + double newOpacity = useFocusedRuntimeOpacity ? + FocusedOpacity() : + newAppearance->Opacity(); + _setOpacity(newOpacity, focused); + // No need to update Acrylic if UnfocusedAcrylic is disabled if (_settings->EnableUnfocusedAcrylic()) { // Manually turn off acrylic if they turn off transparency. _runtimeUseAcrylic = Opacity() < 1.0 && newAppearance->UseAcrylic(); + } - // Update the renderer as well. It might need to fall back from - // cleartype -> grayscale if the BG is transparent / acrylic. - _renderEngine->EnableTransparentBackground(_isBackgroundTransparent()); - _renderer->NotifyPaintFrame(); - - auto eventArgs = winrt::make_self(Opacity()); + // Update the renderer as well. It might need to fall back from + // cleartype -> grayscale if the BG is transparent / acrylic. + _renderEngine->EnableTransparentBackground(_isBackgroundTransparent()); + _renderer->NotifyPaintFrame(); - _TransparencyChangedHandlers(*this, *eventArgs); - } + auto eventArgs = winrt::make_self(Opacity()); + _TransparencyChangedHandlers(*this, *eventArgs); _renderer->TriggerRedrawAll(true, true); } diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index c21730f4789..90cc5fca4d4 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -246,6 +246,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation bool ShouldShowSelectOutput(); RUNTIME_SETTING(double, Opacity, _settings->Opacity()); + RUNTIME_SETTING(double, FocusedOpacity, FocusedAppearance().Opacity()); RUNTIME_SETTING(bool, UseAcrylic, _settings->UseAcrylic()); // -------------------------------- WinRT Events --------------------------------- @@ -386,7 +387,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void _updateAntiAliasingMode(); void _connectionOutputHandler(const hstring& hstr); void _updateHoveredCell(const std::optional terminalPosition); - void _setOpacity(const double opacity); + void _setOpacity(const double opacity, const bool focused = true); bool _isBackgroundTransparent(); void _focusChanged(bool focused);