Add adjustOpacity action (#12092)

Adds an action which can be used to change the opacity at runtime. This is a follow up to some of the other work I had been doing around opacity and settings previewing at the end of the year.

> edit: pseudo-spec
> 
> * `adjustOpacity`:
>   * `"opacity"`: (**required**) an integer number to set the opacity to.
>   * `"relative"`: (defaults to `true`)
>     * If false, set the opacity to the given value, which should be between [0, 100].
>     * If true, then use `opacity` as a relative adjustment to the current opacity. So the implementation would get the current opacity for this pane, then add this action's opacity to that value. Should be between [-100, 100]
> 
> This would allow both setting exactly 25% opacity with an action, and binding an action that increases/decreases the opacity one {amount}

It's preview-able too, which is neat. 

![adjust-opacity-preview-001](https://user-images.githubusercontent.com/18356694/140785805-5eecf6ec-0933-40e4-bcba-41b88d25b6a8.gif)



* [x] Closes #11205
* [x] I work here
* [x] Docs updated: https://github.com/MicrosoftDocs/terminal/pull/477
This commit is contained in:
Mike Griese
2022-01-12 13:06:31 -06:00
committed by GitHub
parent 2f688148eb
commit c3fd26a393
18 changed files with 224 additions and 16 deletions

View File

@@ -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"
}

View File

@@ -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 });
});

View File

@@ -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:
// - <none>
// Return Value:
// - <none>
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<int>(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<SetColorSchemeArgs>());
break;
}
case ShortcutAction::AdjustOpacity:
{
_PreviewAdjustOpacity(args.ActionAndArgs().Args().try_as<AdjustOpacityArgs>());
break;
}
}
// GH#9818 Other ideas for actions that could be preview-able:

View File

@@ -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<AdjustOpacityArgs>())
{
const auto res = _ApplyToActiveControls([&](auto& control) {
control.AdjustOpacity(realArgs.Opacity(), realArgs.Relative());
});
args.Handled(res);
}
}
}
}

View File

@@ -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<std::function<void()>> _restorePreviewFuncs{};

View File

@@ -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<double>(opacity) / 100.0;
if (relative)
{
AdjustOpacity(opacityAdjust);
}
else
{
_setOpacity(opacityAdjust);
}
}
bool ControlCore::_isBackgroundTransparent()
{
// If we're:

View File

@@ -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<til::point> terminalPosition);
void _setOpacity(const double opacity);
bool _isBackgroundTransparent();

View File

@@ -98,6 +98,8 @@ namespace Microsoft.Terminal.Control
String ReadEntireBuffer();
void AdjustOpacity(Int32 Opacity, Boolean relative);
event FontSizeChangedEventArgs FontSizeChanged;
event Windows.Foundation.TypedEventHandler<Object, CopyToClipboardEventArgs> CopyToClipboard;

View File

@@ -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<uint32_t>(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();
}
}

View File

@@ -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);

View File

@@ -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; };
}
}

View File

@@ -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") },
};
}();

View File

@@ -40,6 +40,7 @@
#include "ExportBufferArgs.g.cpp"
#include "ClearBufferArgs.g.cpp"
#include "MultipleActionsArgs.g.cpp"
#include "AdjustOpacityArgs.g.cpp"
#include <LibraryResources.h>
#include <WtExeUtils.h>
@@ -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())
};
}
}
}

View File

@@ -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);
}

View File

@@ -359,4 +359,11 @@ namespace Microsoft.Terminal.Settings.Model
MultipleActionsArgs();
Windows.Foundation.Collections.IVector<ActionAndArgs> Actions;
};
[default_interface] runtimeclass AdjustOpacityArgs : IActionArgs
{
AdjustOpacityArgs();
Int32 Opacity { get; };
Boolean Relative { get; };
};
}

View File

@@ -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)

View File

@@ -503,6 +503,21 @@
<data name="QuitCommandKey" xml:space="preserve">
<value>Quit the Terminal</value>
</data>
<data name="SetOpacityParentCommandName" xml:space="preserve">
<value>Set background opacity...</value>
</data>
<data name="IncreaseOpacityCommandKey" xml:space="preserve">
<value>Increase background opacity by {0}%</value>
<comment>A command to change how transparent the background of the window is</comment>
</data>
<data name="DecreaseOpacityCommandKey" xml:space="preserve">
<value>Decrease background opacity by {0}%</value>
<comment>A command to change how transparent the background of the window is</comment>
</data>
<data name="AdjustOpacityCommandKey" xml:space="preserve">
<value>Set background opacity to {0}%</value>
<comment>A command to change how transparent the background of the window is</comment>
</data>
<data name="RestoreLastClosedCommandKey" xml:space="preserve">
<value>Restore the last closed pane or tab</value>
</data>

View File

@@ -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 } }
]
},
]
}