diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index d4f972d9ede..437cc09c861 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -342,6 +342,7 @@ "toggleShaderEffects", "wt", "quit", + "adjustOpacity", "restoreLastClosed", "unbound" ], @@ -1385,6 +1386,34 @@ } ] }, + "AdjustOpacityAction": { + "description": "Changes the opacity of the active Terminal window. If `relative` is specified, then this action will increase/decrease relative to the current opacity.", + "allOf": [ + { + "$ref": "#/$defs/ShortcutAction" + }, + { + "properties": { + "action": { + "type": "string", + "const": "adjustOpacity" + }, + "opacity": { + "type": "integer", + "minimum": -100, + "maximum": 100, + "default": 0, + "description": "How opaque the terminal should become or how much the opacity should be changed by, depending on the value of `relative`" + }, + "relative": { + "type": "boolean", + "default": true, + "description": "If true, then adjust the current opacity by the given `opacity` parameter, additively. If false, set the opacity to exactly that value." + } + } + } + ] + }, "Keybinding": { "additionalProperties": false, "properties": { @@ -1493,6 +1522,9 @@ { "$ref": "#/$defs/QuakeModeAction" }, + { + "$ref": "#/$defs/AdjustOpacityAction" + }, { "type": "null" } diff --git a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp index 0deb0570e3c..424f0ddcdc0 100644 --- a/src/cascadia/LocalTests_TerminalApp/TabTests.cpp +++ b/src/cascadia/LocalTests_TerminalApp/TabTests.cpp @@ -1333,7 +1333,7 @@ namespace TerminalAppLocalTests Log::Comment(L"Emulate committing the SetColorScheme action"); SetColorSchemeArgs args{ L"Vintage" }; - page->_EndPreviewColorScheme(); + page->_EndPreview(); page->_HandleSetColorScheme(nullptr, ActionEventArgs{ args }); }); @@ -1395,7 +1395,7 @@ namespace TerminalAppLocalTests TestOnUIThread([&page]() { Log::Comment(L"Emulate dismissing the SetColorScheme action"); - page->_EndPreviewColorScheme(); + page->_EndPreview(); }); TestOnUIThread([&page]() { @@ -1469,7 +1469,7 @@ namespace TerminalAppLocalTests Log::Comment(L"Emulate committing the SetColorScheme action"); SetColorSchemeArgs args{ L"One Half Light" }; - page->_EndPreviewColorScheme(); + page->_EndPreview(); page->_HandleSetColorScheme(nullptr, ActionEventArgs{ args }); }); diff --git a/src/cascadia/TerminalApp/ActionPreviewHandlers.cpp b/src/cascadia/TerminalApp/ActionPreviewHandlers.cpp index 9965674f4e0..c43dcdf399a 100644 --- a/src/cascadia/TerminalApp/ActionPreviewHandlers.cpp +++ b/src/cascadia/TerminalApp/ActionPreviewHandlers.cpp @@ -49,8 +49,9 @@ namespace winrt::TerminalApp::implementation switch (_lastPreviewedCommand.ActionAndArgs().Action()) { case ShortcutAction::SetColorScheme: + case ShortcutAction::AdjustOpacity: { - _EndPreviewColorScheme(); + _RunRestorePreviews(); break; } } @@ -58,14 +59,13 @@ namespace winrt::TerminalApp::implementation } // Method Description: - // - Revert any changes from the preview on a SetColorScheme action. This - // will remove the preview TerminalSettings we inserted into the control's - // TerminalSettings graph, and update the control. + // - Revert any changes from the preview action. This will run the restore + // function that the preview added to _restorePreviewFuncs // Arguments: // - // Return Value: // - - void TerminalPage::_EndPreviewColorScheme() + void TerminalPage::_RunRestorePreviews() { // Apply the reverts in reverse order - If we had multiple previews // stacked on top of each other, then this will ensure the first one in @@ -111,6 +111,27 @@ namespace winrt::TerminalApp::implementation } } + void TerminalPage::_PreviewAdjustOpacity(const Settings::Model::AdjustOpacityArgs& args) + { + // Clear the saved preview funcs because we don't need to add a restore each time + // the preview changes, we only need to be able to restore the last one. + _restorePreviewFuncs.clear(); + + _ApplyToActiveControls([&](const auto& control) { + // Stash a copy of the original opacity. + auto originalOpacity{ control.BackgroundOpacity() }; + + // Apply the new opacity + control.AdjustOpacity(args.Opacity(), args.Relative()); + + _restorePreviewFuncs.emplace_back([=]() { + // On dismiss: + // Don't adjust relatively, just set outright. + control.AdjustOpacity(::base::saturated_cast(originalOpacity * 100), false); + }); + }); + } + // Method Description: // - Handler for the CommandPalette::PreviewAction event. The Command // Palette will raise this even when an action is selected, but _not_ @@ -142,6 +163,11 @@ namespace winrt::TerminalApp::implementation _PreviewColorScheme(args.ActionAndArgs().Args().try_as()); break; } + case ShortcutAction::AdjustOpacity: + { + _PreviewAdjustOpacity(args.ActionAndArgs().Args().try_as()); + break; + } } // GH#9818 Other ideas for actions that could be preview-able: diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 213d514b063..c8dbacbcbde 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -958,4 +958,19 @@ namespace winrt::TerminalApp::implementation } } } + + void TerminalPage::_HandleAdjustOpacity(const IInspectable& /*sender*/, + const ActionEventArgs& args) + { + if (args) + { + if (const auto& realArgs = args.ActionArgs().try_as()) + { + const auto res = _ApplyToActiveControls([&](auto& control) { + control.AdjustOpacity(realArgs.Opacity(), realArgs.Relative()); + }); + args.Handled(res); + } + } + } } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index bbe9e4f2ecb..91c76fd1040 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -398,8 +398,9 @@ namespace winrt::TerminalApp::implementation void _PreviewActionHandler(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::Command& args); void _EndPreview(); - void _EndPreviewColorScheme(); + void _RunRestorePreviews(); void _PreviewColorScheme(const Microsoft::Terminal::Settings::Model::SetColorSchemeArgs& args); + void _PreviewAdjustOpacity(const Microsoft::Terminal::Settings::Model::AdjustOpacityArgs& args); winrt::Microsoft::Terminal::Settings::Model::Command _lastPreviewedCommand{ nullptr }; std::vector> _restorePreviewFuncs{}; diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index f4eaf1c7554..7ec3056a6ab 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -445,11 +445,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation return; } - auto newOpacity = std::clamp(Opacity() + adjustment, - 0.0, - 1.0); + _setOpacity(Opacity() + adjustment); + } + + void ControlCore::_setOpacity(const double opacity) + { + const auto newOpacity = std::clamp(opacity, + 0.0, + 1.0); + + if (newOpacity == Opacity()) + { + return; + } - auto lock = _terminal->LockForWriting(); // Update our runtime opacity value Opacity(newOpacity); @@ -1701,6 +1710,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _settings->FocusedAppearance()->SetColorTableEntry(15, scheme.BrightWhite); _terminal->ApplyScheme(scheme); + _renderEngine->SetSelectionBackground(til::color{ _settings->SelectionBackground() }); _renderer->TriggerRedrawAll(); @@ -1712,6 +1722,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation return _settings->HasUnfocusedAppearance(); } + void ControlCore::AdjustOpacity(const int32_t& opacity, const bool& relative) + { + const double opacityAdjust = static_cast(opacity) / 100.0; + if (relative) + { + AdjustOpacity(opacityAdjust); + } + else + { + _setOpacity(opacityAdjust); + } + } + bool ControlCore::_isBackgroundTransparent() { // If we're: diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 0252b501221..38088a838d2 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -166,6 +166,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation static bool IsVintageOpacityAvailable() noexcept; + void AdjustOpacity(const int32_t& opacity, const bool& relative); + RUNTIME_SETTING(double, Opacity, _settings->Opacity()); RUNTIME_SETTING(bool, UseAcrylic, _settings->UseAcrylic()); @@ -269,6 +271,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); bool _isBackgroundTransparent(); diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index 2a4287f5a83..c23461412e2 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -98,6 +98,8 @@ namespace Microsoft.Terminal.Control String ReadEntireBuffer(); + void AdjustOpacity(Int32 Opacity, Boolean relative); + event FontSizeChangedEventArgs FontSizeChanged; event Windows.Foundation.TypedEventHandler CopyToClipboard; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index b6df41e3772..53206b16ed1 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -2001,7 +2001,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation const winrt::Windows::Foundation::Size minSize{ 1, 1 }; const double scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel(); const auto dpi = ::base::saturated_cast(USER_DEFAULT_SCREEN_DPI * scaleFactor); - return GetProposedDimensions(_core.Settings(), dpi, minSize); } } @@ -2708,4 +2707,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation { _core.ColorScheme(scheme); } + + void TermControl::AdjustOpacity(const int32_t& opacity, const bool& relative) + { + _core.AdjustOpacity(opacity, relative); + } + + // - You'd think this should just be "Opacity", but UIElement already + // defines an "Opacity", which we're actually not setting at all. We're + // not overriding or changing _that_ value. Callers that want the opacity + // set by the settings should call this instead. + double TermControl::BackgroundOpacity() const + { + return _core.Opacity(); + } } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index b84632a09f6..4c360913b4c 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -14,6 +14,7 @@ #include "SearchBoxControl.h" #include "ControlInteractivity.h" +#include "ControlSettings.h" namespace Microsoft::Console::VirtualTerminal { @@ -56,6 +57,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation int BufferHeight() const; bool BracketedPasteEnabled() const noexcept; + + double BackgroundOpacity() const; #pragma endregion void ScrollViewport(int viewTop); @@ -107,6 +110,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation winrt::Microsoft::Terminal::Core::Scheme ColorScheme() const noexcept; void ColorScheme(const winrt::Microsoft::Terminal::Core::Scheme& scheme) const noexcept; + void AdjustOpacity(const int32_t& opacity, const bool& relative); + // -------------------------------- WinRT Events --------------------------------- // clang-format off WINRT_CALLBACK(FontSizeChanged, Control::FontSizeChangedEventArgs); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index a87cdc8edbe..4862c408b3d 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -72,5 +72,14 @@ namespace Microsoft.Terminal.Control void ToggleReadOnly(); String ReadEntireBuffer(); + + void AdjustOpacity(Int32 Opacity, Boolean relative); + + // You'd think this should just be "Opacity", but UIElement already + // defines an "Opacity", which we're actually not setting at all. We're + // not overriding or changing _that_ value. Callers that want the + // opacity set by the settings should call this instead. + Double BackgroundOpacity { get; }; + } } diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index b6d8d2b1f3e..7abb6b33f7a 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -73,6 +73,7 @@ static constexpr std::string_view ExportBufferKey{ "exportBuffer" }; static constexpr std::string_view ClearBufferKey{ "clearBuffer" }; static constexpr std::string_view MultipleActionsKey{ "multipleActions" }; static constexpr std::string_view QuitKey{ "quit" }; +static constexpr std::string_view AdjustOpacityKey{ "adjustOpacity" }; static constexpr std::string_view RestoreLastClosedKey{ "restoreLastClosed" }; static constexpr std::string_view ActionKey{ "action" }; @@ -383,6 +384,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { ShortcutAction::ClearBuffer, L"" }, // Intentionally omitted, must be generated by GenerateName { ShortcutAction::MultipleActions, L"" }, // Intentionally omitted, must be generated by GenerateName { ShortcutAction::Quit, RS_(L"QuitCommandKey") }, + { ShortcutAction::AdjustOpacity, L"" }, // Intentionally omitted, must be generated by GenerateName { ShortcutAction::RestoreLastClosed, RS_(L"RestoreLastClosedCommandKey") }, }; }(); diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp index c13e0e42313..81387f4770f 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp @@ -40,6 +40,7 @@ #include "ExportBufferArgs.g.cpp" #include "ClearBufferArgs.g.cpp" #include "MultipleActionsArgs.g.cpp" +#include "AdjustOpacityArgs.g.cpp" #include #include @@ -769,4 +770,35 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { return L""; } + + winrt::hstring AdjustOpacityArgs::GenerateName() const + { + if (Relative()) + { + if (Opacity() >= 0) + { + // "Increase background opacity by {Opacity}%" + return winrt::hstring{ + fmt::format(std::wstring_view(RS_(L"IncreaseOpacityCommandKey")), + Opacity()) + }; + } + else + { + // "Decrease background opacity by {Opacity}%" + return winrt::hstring{ + fmt::format(std::wstring_view(RS_(L"DecreaseOpacityCommandKey")), + Opacity()) + }; + } + } + else + { + // "Set background opacity to {Opacity}%" + return winrt::hstring{ + fmt::format(std::wstring_view(RS_(L"AdjustOpacityCommandKey")), + Opacity()) + }; + } + } } diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.h b/src/cascadia/TerminalSettingsModel/ActionArgs.h index 2246d9baab5..05bd831a3ae 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.h @@ -42,6 +42,7 @@ #include "ExportBufferArgs.g.h" #include "ClearBufferArgs.g.h" #include "MultipleActionsArgs.g.h" +#include "AdjustOpacityArgs.g.h" #include "JsonUtils.h" #include "HashUtils.h" @@ -219,6 +220,11 @@ private: #define CLEAR_BUFFER_ARGS(X) \ X(winrt::Microsoft::Terminal::Control::ClearBufferType, Clear, "clear", false, winrt::Microsoft::Terminal::Control::ClearBufferType::All) +//////////////////////////////////////////////////////////////////////////////// +#define ADJUST_OPACITY_ARGS(X) \ + X(int32_t, Opacity, "opacity", false, 0) \ + X(bool, Relative, "relative", false, true) + //////////////////////////////////////////////////////////////////////////////// namespace winrt::Microsoft::Terminal::Settings::Model::implementation @@ -690,6 +696,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation return h.finalize(); } }; + + ACTION_ARGS_STRUCT(AdjustOpacityArgs, ADJUST_OPACITY_ARGS); + } namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation @@ -723,4 +732,5 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation BASIC_FACTORY(ExportBufferArgs); BASIC_FACTORY(ClearBufferArgs); BASIC_FACTORY(MultipleActionsArgs); + BASIC_FACTORY(AdjustOpacityArgs); } diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.idl b/src/cascadia/TerminalSettingsModel/ActionArgs.idl index bcbc63b1b6c..b3d0d5d3d94 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.idl +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.idl @@ -359,4 +359,11 @@ namespace Microsoft.Terminal.Settings.Model MultipleActionsArgs(); Windows.Foundation.Collections.IVector Actions; }; + + [default_interface] runtimeclass AdjustOpacityArgs : IActionArgs + { + AdjustOpacityArgs(); + Int32 Opacity { get; }; + Boolean Relative { get; }; + }; } diff --git a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h index 91154ffbfc5..32ba5d6b631 100644 --- a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h +++ b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h @@ -87,6 +87,7 @@ ON_ALL_ACTIONS(ClearBuffer) \ ON_ALL_ACTIONS(MultipleActions) \ ON_ALL_ACTIONS(Quit) \ + ON_ALL_ACTIONS(AdjustOpacity) \ ON_ALL_ACTIONS(RestoreLastClosed) #define ALL_SHORTCUT_ACTIONS_WITH_ARGS \ @@ -124,4 +125,5 @@ ON_ALL_ACTIONS_WITH_ARGS(FocusPane) \ ON_ALL_ACTIONS_WITH_ARGS(ExportBuffer) \ ON_ALL_ACTIONS_WITH_ARGS(ClearBuffer) \ - ON_ALL_ACTIONS_WITH_ARGS(MultipleActions) + ON_ALL_ACTIONS_WITH_ARGS(MultipleActions) \ + ON_ALL_ACTIONS_WITH_ARGS(AdjustOpacity) diff --git a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw index a055f4d150e..ef1a25c33ec 100644 --- a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw @@ -503,6 +503,21 @@ Quit the Terminal + + Set background opacity... + + + Increase background opacity by {0}% + A command to change how transparent the background of the window is + + + Decrease background opacity by {0}% + A command to change how transparent the background of the window is + + + Set background opacity to {0}% + A command to change how transparent the background of the window is + Restore the last closed pane or tab diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index 2c4f458ed64..89f78f630ff 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -454,6 +454,17 @@ ] } ] - } + }, + { + // Set opacity... + "name": { "key": "SetOpacityParentCommandName" }, + "commands": [ + { "command": { "action": "adjustOpacity", "opacity": 0, "relative": false } }, + { "command": { "action": "adjustOpacity", "opacity": 25, "relative": false } }, + { "command": { "action": "adjustOpacity", "opacity": 50, "relative": false } }, + { "command": { "action": "adjustOpacity", "opacity": 75, "relative": false } }, + { "command": { "action": "adjustOpacity", "opacity": 100, "relative": false } } + ] + }, ] }