Compare commits
61 Commits
main
...
dev/migrie
Author | SHA1 | Date |
---|---|---|
Mike Griese | d675fd824a | |
Mike Griese | b421ee6ca0 | |
Mike Griese | a1bfa332f3 | |
Mike Griese | 8313987490 | |
Mike Griese | efdc0909e8 | |
Mike Griese | 7bb8975953 | |
Mike Griese | 8532dd692e | |
Mike Griese | a338ca168c | |
Mike Griese | 5adb327703 | |
Mike Griese | 1a7649ce21 | |
Mike Griese | a9e706c573 | |
Mike Griese | 2a18d7dae3 | |
Mike Griese | ae833a77bd | |
Mike Griese | 88f2e64bb3 | |
Mike Griese | 6e8a2adbd9 | |
Mike Griese | 59c193c22a | |
Mike Griese | 713f72e1e5 | |
Mike Griese | 5cd8096d42 | |
Mike Griese | 147101f833 | |
Mike Griese | 5173ea30f5 | |
Mike Griese | 9eeea4a9d0 | |
Mike Griese | d51c2cff35 | |
Mike Griese | 83e7aead57 | |
Mike Griese | 6da5d79d47 | |
Mike Griese | 51486a4168 | |
Mike Griese | f111c6d72d | |
Mike Griese | f087dd8236 | |
Mike Griese | bf9bf0e138 | |
Mike Griese | 7c288517a5 | |
Mike Griese | 8c7ce77811 | |
Mike Griese | 01cef2f3dc | |
Mike Griese | 4a700cd1cc | |
Mike Griese | 217742c1ff | |
Mike Griese | 48ca704816 | |
Mike Griese | 634b6854dc | |
Mike Griese | 28cbad1470 | |
Mike Griese | 94f4ef5601 | |
Mike Griese | 6babb4e73a | |
Mike Griese | 282c03c374 | |
Mike Griese | 916096643e | |
Mike Griese | e3a50cfdee | |
Mike Griese | 1aa2849d94 | |
Mike Griese | 17829f438b | |
Mike Griese | 888e1572d2 | |
Mike Griese | 4912b65967 | |
Mike Griese | 03711944f1 | |
Mike Griese | 70b9f8ce5f | |
Mike Griese | a9de82e4ee | |
Mike Griese | 4f7e883673 | |
Mike Griese | 31e799859f | |
Mike Griese | 1413d0145a | |
Mike Griese | fbba74e89b | |
Mike Griese | 4a1baf0006 | |
Mike Griese | c26dd6b1db | |
Mike Griese | c7536edfa8 | |
Mike Griese | 7fc2f10bbd | |
Mike Griese | 4b18bb415e | |
Mike Griese | d6989ec9d1 | |
Mike Griese | 981d8cc9c8 | |
Mike Griese | dad065e0fe | |
Mike Griese | 43ec102343 |
|
@ -55,8 +55,12 @@ namespace SettingsModelLocalTests
|
|||
TerminalSettings settings;
|
||||
VERIFY_IS_NOT_NULL(settings);
|
||||
auto oldFontSize = settings.FontSize();
|
||||
settings.FontSize(oldFontSize + 5);
|
||||
auto newFontSize = settings.FontSize();
|
||||
|
||||
auto selfSettings = winrt::make_self<implementation::TerminalSettings>();
|
||||
VERIFY_ARE_EQUAL(oldFontSize, selfSettings->FontSize());
|
||||
|
||||
selfSettings->FontSize(oldFontSize + 5);
|
||||
auto newFontSize = selfSettings->FontSize();
|
||||
VERIFY_ARE_NOT_EQUAL(oldFontSize, newFontSize);
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@ namespace TerminalAppLocalTests
|
|||
TEST_METHOD(TestWindowRenameSuccessful);
|
||||
TEST_METHOD(TestWindowRenameFailure);
|
||||
|
||||
TEST_METHOD(TestControlSettingsHasParent);
|
||||
TEST_METHOD(TestPreviewCommitScheme);
|
||||
TEST_METHOD(TestPreviewDismissScheme);
|
||||
TEST_METHOD(TestPreviewSchemeWhilePreviewing);
|
||||
|
@ -134,10 +133,6 @@ namespace TerminalAppLocalTests
|
|||
// Just creating it is enough to know that everything is working.
|
||||
TerminalSettings settings;
|
||||
VERIFY_IS_NOT_NULL(settings);
|
||||
auto oldFontSize = settings.FontSize();
|
||||
settings.FontSize(oldFontSize + 5);
|
||||
auto newFontSize = settings.FontSize();
|
||||
VERIFY_ARE_NOT_EQUAL(oldFontSize, newFontSize);
|
||||
}
|
||||
|
||||
void TabTests::TryCreateConnectionType()
|
||||
|
@ -1297,25 +1292,6 @@ namespace TerminalAppLocalTests
|
|||
});
|
||||
}
|
||||
|
||||
void TabTests::TestControlSettingsHasParent()
|
||||
{
|
||||
Log::Comment(L"Ensure that when we create a control, it always has a parent TerminalSettings");
|
||||
|
||||
auto page = _commonSetup();
|
||||
VERIFY_IS_NOT_NULL(page);
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
});
|
||||
}
|
||||
|
||||
void TabTests::TestPreviewCommitScheme()
|
||||
{
|
||||
Log::Comment(L"Preview a color scheme. Make sure it's applied, then committed accordingly");
|
||||
|
@ -1327,12 +1303,9 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
|
||||
});
|
||||
|
||||
|
@ -1346,17 +1319,12 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& previewSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(previewSettings);
|
||||
|
||||
const auto& originalSettings = previewSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed to the preview");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
|
||||
|
||||
// And we should have stored a function to revert the change.
|
||||
VERIFY_ARE_EQUAL(1u, page->_restorePreviewFuncs.size());
|
||||
});
|
||||
|
@ -1373,20 +1341,22 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
const auto& grandparentSettings = originalSettings.GetParent();
|
||||
VERIFY_IS_NULL(grandparentSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
|
||||
|
||||
// After preview there should be no more restore functions to execute.
|
||||
VERIFY_ARE_EQUAL(0u, page->_restorePreviewFuncs.size());
|
||||
});
|
||||
|
||||
Log::Comment(L"Sleep to let events propagate");
|
||||
// If you don't do this, we will _sometimes_ crash as we're tearing down
|
||||
// the control from this test as we start the next one. We crash
|
||||
// somewhere in the CursorPositionChanged handler. It's annoying, but
|
||||
// this works.
|
||||
Sleep(250);
|
||||
}
|
||||
|
||||
void TabTests::TestPreviewDismissScheme()
|
||||
|
@ -1400,12 +1370,9 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
|
||||
});
|
||||
|
||||
|
@ -1419,15 +1386,9 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& previewSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(previewSettings);
|
||||
|
||||
const auto& originalSettings = previewSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed to the preview");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
|
||||
});
|
||||
|
@ -1441,18 +1402,14 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
const auto& grandparentSettings = originalSettings.GetParent();
|
||||
VERIFY_IS_NULL(grandparentSettings);
|
||||
|
||||
Log::Comment(L"Color should be the same as it originally was");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
|
||||
});
|
||||
Log::Comment(L"Sleep to let events propagate");
|
||||
Sleep(250);
|
||||
}
|
||||
|
||||
void TabTests::TestPreviewSchemeWhilePreviewing()
|
||||
|
@ -1468,12 +1425,9 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
|
||||
});
|
||||
|
||||
|
@ -1487,15 +1441,9 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& previewSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(previewSettings);
|
||||
|
||||
const auto& originalSettings = previewSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed to the preview");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
|
||||
});
|
||||
|
@ -1510,15 +1458,9 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& previewSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(previewSettings);
|
||||
|
||||
const auto& originalSettings = previewSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed to the preview");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xffFAFAFA }, controlSettings.DefaultBackground());
|
||||
});
|
||||
|
@ -1535,18 +1477,14 @@ namespace TerminalAppLocalTests
|
|||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
const auto& controlSettings = activeControl.Settings();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
const auto& grandparentSettings = originalSettings.GetParent();
|
||||
VERIFY_IS_NULL(grandparentSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xffFAFAFA }, controlSettings.DefaultBackground());
|
||||
});
|
||||
Log::Comment(L"Sleep to let events propagate");
|
||||
Sleep(250);
|
||||
}
|
||||
|
||||
void TabTests::TestClampSwitchToTab()
|
||||
|
|
|
@ -67,8 +67,12 @@ namespace winrt::TerminalApp::implementation
|
|||
// - <none>
|
||||
void TerminalPage::_EndPreviewColorScheme()
|
||||
{
|
||||
for (const auto& f : _restorePreviewFuncs)
|
||||
// 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
|
||||
// is the last one out.
|
||||
for (auto i{ _restorePreviewFuncs.rbegin() }; i < _restorePreviewFuncs.rend(); i++)
|
||||
{
|
||||
auto f = *i;
|
||||
f();
|
||||
}
|
||||
_restorePreviewFuncs.clear();
|
||||
|
@ -90,59 +94,18 @@ namespace winrt::TerminalApp::implementation
|
|||
{
|
||||
if (const auto& scheme{ _settings.GlobalSettings().ColorSchemes().TryLookup(args.SchemeName()) })
|
||||
{
|
||||
// Clear the saved preview funcs because we don't need to add a restore each time
|
||||
// the preview color changes, we only need to be able to restore the last one.
|
||||
_restorePreviewFuncs.clear();
|
||||
|
||||
_ApplyToActiveControls([&](const auto& control) {
|
||||
// Get the settings of the focused control and stash them
|
||||
const auto& controlSettings = control.Settings().as<TerminalSettings>();
|
||||
// Make sure to recurse up to the root - if you're doing
|
||||
// this while you're currently previewing a SetColorScheme
|
||||
// action, then the parent of the control's settings is _the
|
||||
// last preview TerminalSettings we inserted! We don't want
|
||||
// to save that one!
|
||||
auto originalSettings = controlSettings.GetParent();
|
||||
while (originalSettings.GetParent() != nullptr)
|
||||
{
|
||||
originalSettings = originalSettings.GetParent();
|
||||
}
|
||||
// Create a new child for those settings
|
||||
TerminalSettingsCreateResult fake{ originalSettings };
|
||||
const auto& childStruct = TerminalSettings::CreateWithParent(fake);
|
||||
// Modify the child to have the applied color scheme
|
||||
childStruct.DefaultSettings().ApplyColorScheme(scheme);
|
||||
// Stash a copy of the current scheme.
|
||||
auto originalScheme{ control.ColorScheme() };
|
||||
|
||||
// Insert that new child as the parent of the control's settings
|
||||
controlSettings.SetParent(childStruct.DefaultSettings());
|
||||
control.UpdateSettings();
|
||||
// Apply the new scheme.
|
||||
control.ColorScheme(scheme.ToCoreScheme());
|
||||
|
||||
// Take a copy of the inputs, since they are pointers anyways.
|
||||
// Each control will emplace a revert into the
|
||||
// _restorePreviewFuncs for itself.
|
||||
_restorePreviewFuncs.emplace_back([=]() {
|
||||
// Get the runtime settings of the focused control
|
||||
const auto& controlSettings{ control.Settings().as<TerminalSettings>() };
|
||||
|
||||
// Get the control's root settings, the ones that we actually
|
||||
// assigned to it.
|
||||
auto parentSettings{ controlSettings.GetParent() };
|
||||
while (parentSettings.GetParent() != nullptr)
|
||||
{
|
||||
parentSettings = parentSettings.GetParent();
|
||||
}
|
||||
|
||||
// If the root settings are the same as the ones we stashed,
|
||||
// then reset the parent of the runtime settings to the stashed
|
||||
// settings. This condition might be false if the settings
|
||||
// hot-reloaded while the palette was open. In that case, we
|
||||
// don't want to reset the settings to what they were _before_
|
||||
// the hot-reload.
|
||||
if (originalSettings == parentSettings)
|
||||
{
|
||||
// Set the original settings as the parent of the control's settings
|
||||
control.Settings().as<TerminalSettings>().SetParent(originalSettings);
|
||||
}
|
||||
|
||||
control.UpdateSettings();
|
||||
// On dismiss, restore the original scheme.
|
||||
control.ColorScheme(originalScheme);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -451,28 +451,7 @@ namespace winrt::TerminalApp::implementation
|
|||
if (const auto scheme = _settings.GlobalSettings().ColorSchemes().TryLookup(realArgs.SchemeName()))
|
||||
{
|
||||
const auto res = _ApplyToActiveControls([&](auto& control) {
|
||||
// Start by getting the current settings of the control
|
||||
auto controlSettings = control.Settings().as<TerminalSettings>();
|
||||
auto parentSettings = controlSettings;
|
||||
// Those are the _runtime_ settings however. What we
|
||||
// need to do is:
|
||||
//
|
||||
// 1. Blow away any colors set in the runtime settings.
|
||||
// 2. Apply the color scheme to the parent settings.
|
||||
//
|
||||
// 1 is important to make sure that the effects of
|
||||
// something like `colortool` are cleared when setting
|
||||
// the scheme.
|
||||
if (controlSettings.GetParent() != nullptr)
|
||||
{
|
||||
parentSettings = controlSettings.GetParent();
|
||||
}
|
||||
|
||||
// ApplyColorScheme(nullptr) will clear the old color scheme.
|
||||
controlSettings.ApplyColorScheme(nullptr);
|
||||
parentSettings.ApplyColorScheme(scheme);
|
||||
|
||||
control.UpdateSettings();
|
||||
control.ColorScheme(scheme.ToCoreScheme());
|
||||
});
|
||||
args.Handled(res);
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ NewTerminalArgs Pane::GetTerminalArgsForPane() const
|
|||
assert(_IsLeaf());
|
||||
|
||||
NewTerminalArgs args{};
|
||||
auto controlSettings = _control.Settings().as<TerminalSettings>();
|
||||
auto controlSettings = _control.Settings();
|
||||
|
||||
args.Profile(controlSettings.ProfileName());
|
||||
// If we know the user's working directory use it instead of the profile.
|
||||
|
@ -156,16 +156,13 @@ NewTerminalArgs Pane::GetTerminalArgsForPane() const
|
|||
args.TabColor(winrt::Windows::Foundation::IReference<winrt::Windows::UI::Color>(c));
|
||||
}
|
||||
|
||||
if (controlSettings.AppliedColorScheme())
|
||||
{
|
||||
auto name = controlSettings.AppliedColorScheme().Name();
|
||||
// Only save the color scheme if it is different than the profile color
|
||||
// scheme to not override any other profile appearance choices.
|
||||
if (_profile.DefaultAppearance().ColorSchemeName() != name)
|
||||
{
|
||||
args.ColorScheme(name);
|
||||
}
|
||||
}
|
||||
// TODO:GH#9800 - we used to be able to persist the color scheme that a
|
||||
// TermControl was initialized with, by name. With the change to having the
|
||||
// control own its own copy of its settings, this isn't possible anymore.
|
||||
//
|
||||
// We may be able to get around this by storing the Name in the Core::Scheme
|
||||
// object. That would work for schemes set by the Terminal, but not ones set
|
||||
// by VT, but that seems good enough.
|
||||
|
||||
return args;
|
||||
}
|
||||
|
@ -1459,21 +1456,8 @@ void Pane::UpdateSettings(const TerminalSettingsCreateResult& settings, const Pr
|
|||
assert(_IsLeaf());
|
||||
|
||||
_profile = profile;
|
||||
auto controlSettings = _control.Settings().as<TerminalSettings>();
|
||||
// Update the parent of the control's settings object (and not the object itself) so
|
||||
// that any overrides made by the control don't get affected by the reload
|
||||
controlSettings.SetParent(settings.DefaultSettings());
|
||||
auto unfocusedSettings{ settings.UnfocusedSettings() };
|
||||
if (unfocusedSettings)
|
||||
{
|
||||
// Note: the unfocused settings needs to be entirely unchanged _except_ we need to
|
||||
// set its parent to the settings object that lives in the control. This is because
|
||||
// the overrides made by the control live in that settings object, so we want to make
|
||||
// sure the unfocused settings inherit from that.
|
||||
unfocusedSettings.SetParent(controlSettings);
|
||||
}
|
||||
_control.UnfocusedAppearance(unfocusedSettings);
|
||||
_control.UpdateSettings();
|
||||
|
||||
_control.UpdateControlSettings(settings.DefaultSettings(), settings.UnfocusedSettings());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
|
@ -2123,13 +2123,10 @@ namespace winrt::TerminalApp::implementation
|
|||
|
||||
TermControl TerminalPage::_InitControl(const TerminalSettingsCreateResult& settings, const ITerminalConnection& connection)
|
||||
{
|
||||
// Give term control a child of the settings so that any overrides go in the child
|
||||
// This way, when we do a settings reload we just update the parent and the overrides remain
|
||||
const auto child = TerminalSettings::CreateWithParent(settings);
|
||||
TermControl term{ child.DefaultSettings(), connection };
|
||||
|
||||
term.UnfocusedAppearance(child.UnfocusedSettings()); // It is okay for the unfocused settings to be null
|
||||
|
||||
// Do any initialization that needs to apply to _every_ TermControl we
|
||||
// create here.
|
||||
// TermControl will copy the settings out of the settings passed to it.
|
||||
TermControl term{ settings.DefaultSettings(), settings.UnfocusedSettings(), connection };
|
||||
return term;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
--*/
|
||||
#pragma once
|
||||
#include "../../inc/cppwinrt_utils.h"
|
||||
#include "../../inc/ControlProperties.h"
|
||||
|
||||
#include <DefaultSettings.h>
|
||||
#include <conattrs.hpp>
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
struct ControlAppearance : public winrt::implements<ControlAppearance, Microsoft::Terminal::Core::ICoreAppearance, Microsoft::Terminal::Control::IControlAppearance>
|
||||
{
|
||||
#define SETTINGS_GEN(type, name, ...) WINRT_PROPERTY(type, name, __VA_ARGS__);
|
||||
CORE_APPEARANCE_SETTINGS(SETTINGS_GEN)
|
||||
CONTROL_APPEARANCE_SETTINGS(SETTINGS_GEN)
|
||||
#undef SETTINGS_GEN
|
||||
|
||||
private:
|
||||
// Color Table is special because it's an array
|
||||
std::array<winrt::Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE> _ColorTable;
|
||||
|
||||
public:
|
||||
winrt::Microsoft::Terminal::Core::Color GetColorTableEntry(int32_t index) noexcept
|
||||
{
|
||||
return _ColorTable.at(index);
|
||||
}
|
||||
void SetColorTableEntry(int32_t index,
|
||||
winrt::Microsoft::Terminal::Core::Color color) noexcept
|
||||
{
|
||||
_ColorTable.at(index) = color;
|
||||
}
|
||||
|
||||
ControlAppearance(Control::IControlAppearance appearance)
|
||||
{
|
||||
#define COPY_SETTING(type, name, ...) _##name = appearance.name();
|
||||
CORE_APPEARANCE_SETTINGS(COPY_SETTING)
|
||||
CONTROL_APPEARANCE_SETTINGS(COPY_SETTING)
|
||||
#undef COPY_SETTING
|
||||
|
||||
for (size_t i = 0; i < _ColorTable.size(); i++)
|
||||
{
|
||||
_ColorTable[i] = appearance.GetColorTableEntry(static_cast<int32_t>(i));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -56,15 +56,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
return initialized;
|
||||
}
|
||||
|
||||
ControlCore::ControlCore(IControlSettings settings,
|
||||
ControlCore::ControlCore(Control::IControlSettings settings,
|
||||
Control::IControlAppearance unfocusedAppearance,
|
||||
TerminalConnection::ITerminalConnection connection) :
|
||||
_connection{ connection },
|
||||
_settings{ settings },
|
||||
_desiredFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, { 0, DEFAULT_FONT_SIZE }, CP_UTF8 },
|
||||
_actualFont{ DEFAULT_FONT_FACE, 0, DEFAULT_FONT_WEIGHT, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false }
|
||||
{
|
||||
_EnsureStaticInitialization();
|
||||
|
||||
_settings = winrt::make_self<implementation::ControlSettings>(settings, unfocusedAppearance);
|
||||
|
||||
_terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>();
|
||||
|
||||
// Subscribe to the connection's disconnected event and call our connection closed handlers.
|
||||
|
@ -80,7 +82,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
});
|
||||
|
||||
// GH#8969: pre-seed working directory to prevent potential races
|
||||
_terminal->SetWorkingDirectory(_settings.StartingDirectory());
|
||||
_terminal->SetWorkingDirectory(_settings->StartingDirectory());
|
||||
|
||||
auto pfnCopyToClipboard = std::bind(&ControlCore::_terminalCopyToClipboard, this, std::placeholders::_1);
|
||||
_terminal->SetCopyToClipboardCallback(pfnCopyToClipboard);
|
||||
|
@ -187,7 +189,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
}
|
||||
});
|
||||
|
||||
UpdateSettings(settings);
|
||||
UpdateSettings(settings, unfocusedAppearance);
|
||||
}
|
||||
|
||||
ControlCore::~ControlCore()
|
||||
|
@ -226,7 +228,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
return false;
|
||||
}
|
||||
|
||||
if (Feature_AtlasEngine::IsEnabled() && _settings.UseAtlasEngine())
|
||||
if (Feature_AtlasEngine::IsEnabled() && _settings->UseAtlasEngine())
|
||||
{
|
||||
_renderEngine = std::make_unique<::Microsoft::Console::Render::AtlasEngine>();
|
||||
}
|
||||
|
@ -252,7 +254,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
LOG_IF_FAILED(_renderEngine->SetWindowSize({ viewInPixels.Width(), viewInPixels.Height() }));
|
||||
|
||||
// Update DxEngine's SelectionBackground
|
||||
_renderEngine->SetSelectionBackground(til::color{ _settings.SelectionBackground() });
|
||||
_renderEngine->SetSelectionBackground(til::color{ _settings->SelectionBackground() });
|
||||
|
||||
const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);
|
||||
const auto width = vp.Width();
|
||||
|
@ -260,10 +262,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
_connection.Resize(height, width);
|
||||
|
||||
// Override the default width and height to match the size of the swapChainPanel
|
||||
_settings.InitialCols(width);
|
||||
_settings.InitialRows(height);
|
||||
_settings->InitialCols(width);
|
||||
_settings->InitialRows(height);
|
||||
|
||||
_terminal->CreateFromSettings(_settings, *_renderer);
|
||||
_terminal->CreateFromSettings(*_settings, *_renderer);
|
||||
|
||||
// IMPORTANT! Set this callback up sooner than later. If we do it
|
||||
// after Enable, then it'll be possible to paint the frame once
|
||||
|
@ -275,18 +277,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// We do this after we initially set the swapchain so as to avoid unnecessary callbacks (and locking problems)
|
||||
_renderEngine->SetCallback(std::bind(&ControlCore::_renderEngineSwapChainChanged, this));
|
||||
|
||||
_renderEngine->SetRetroTerminalEffect(_settings.RetroTerminalEffect());
|
||||
_renderEngine->SetPixelShaderPath(_settings.PixelShaderPath());
|
||||
_renderEngine->SetForceFullRepaintRendering(_settings.ForceFullRepaintRendering());
|
||||
_renderEngine->SetSoftwareRendering(_settings.SoftwareRendering());
|
||||
_renderEngine->SetIntenseIsBold(_settings.IntenseIsBold());
|
||||
_renderEngine->SetRetroTerminalEffect(_settings->RetroTerminalEffect());
|
||||
_renderEngine->SetPixelShaderPath(_settings->PixelShaderPath());
|
||||
_renderEngine->SetForceFullRepaintRendering(_settings->ForceFullRepaintRendering());
|
||||
_renderEngine->SetSoftwareRendering(_settings->SoftwareRendering());
|
||||
_renderEngine->SetIntenseIsBold(_settings->IntenseIsBold());
|
||||
|
||||
_updateAntiAliasingMode();
|
||||
|
||||
// GH#5098: Inform the engine of the opacity of the default text background.
|
||||
// GH#11315: Always do this, even if they don't have acrylic on.
|
||||
const auto backgroundIsOpaque = _settings.Opacity() == 1.0 && _settings.BackgroundImage().empty();
|
||||
_renderEngine->SetDefaultTextBackgroundOpacity(static_cast<float>(backgroundIsOpaque));
|
||||
_renderEngine->EnableTransparentBackground(_isBackgroundTransparent());
|
||||
|
||||
THROW_IF_FAILED(_renderEngine->Enable());
|
||||
|
||||
|
@ -444,14 +445,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
return;
|
||||
}
|
||||
|
||||
auto newOpacity = std::clamp(_settings.Opacity() + adjustment,
|
||||
auto newOpacity = std::clamp(Opacity() + adjustment,
|
||||
0.0,
|
||||
1.0);
|
||||
|
||||
// GH#5098: Inform the engine of the new opacity of the default text background.
|
||||
SetBackgroundOpacity(::base::saturated_cast<float>(newOpacity));
|
||||
|
||||
_settings.Opacity(newOpacity);
|
||||
auto lock = _terminal->LockForWriting();
|
||||
// Update our runtime opacity value
|
||||
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
|
||||
|
@ -461,7 +461,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// is what the Terminal did prior to 1.12.
|
||||
if (!IsVintageOpacityAvailable())
|
||||
{
|
||||
_settings.UseAcrylic(newOpacity < 1.0);
|
||||
_runtimeUseAcrylic = newOpacity < 1.0;
|
||||
}
|
||||
|
||||
// Update the renderer as well. It might need to fall back from
|
||||
// cleartype -> grayscale if the BG is transparent / acrylic.
|
||||
if (_renderEngine)
|
||||
{
|
||||
_renderEngine->EnableTransparentBackground(_isBackgroundTransparent());
|
||||
}
|
||||
|
||||
auto eventArgs = winrt::make_self<TransparencyChangedEventArgs>(newOpacity);
|
||||
|
@ -476,7 +483,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// specify a custom pixel shader, manually enable the legacy retro
|
||||
// effect first. This will ensure that a toggle off->on will still work,
|
||||
// even if they currently have retro effect off.
|
||||
if (_settings.PixelShaderPath().empty() && !_renderEngine->GetRetroTerminalEffect())
|
||||
if (_settings->PixelShaderPath().empty() && !_renderEngine->GetRetroTerminalEffect())
|
||||
{
|
||||
// SetRetroTerminalEffect to true will enable the effect. In this
|
||||
// case, the shader effect will already be disabled (because neither
|
||||
|
@ -586,24 +593,27 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// Method Description:
|
||||
// - Updates the settings of the current terminal.
|
||||
// - INVARIANT: This method can only be called if the caller DOES NOT HAVE writing lock on the terminal.
|
||||
void ControlCore::UpdateSettings(const IControlSettings& settings)
|
||||
void ControlCore::UpdateSettings(const IControlSettings& settings, const IControlAppearance& newAppearance)
|
||||
{
|
||||
_settings = winrt::make_self<implementation::ControlSettings>(settings, newAppearance);
|
||||
|
||||
auto lock = _terminal->LockForWriting();
|
||||
|
||||
_settings = settings;
|
||||
_runtimeOpacity = std::nullopt;
|
||||
_runtimeUseAcrylic = std::nullopt;
|
||||
|
||||
// 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);
|
||||
_runtimeUseAcrylic = true;
|
||||
}
|
||||
|
||||
// Initialize our font information.
|
||||
const auto fontFace = _settings.FontFace();
|
||||
const short fontHeight = ::base::saturated_cast<short>(_settings.FontSize());
|
||||
const auto fontWeight = _settings.FontWeight();
|
||||
const auto fontFace = _settings->FontFace();
|
||||
const short fontHeight = ::base::saturated_cast<short>(_settings->FontSize());
|
||||
const auto fontWeight = _settings->FontWeight();
|
||||
// The font width doesn't terribly matter, we'll only be using the
|
||||
// height to look it up
|
||||
// The other params here also largely don't matter.
|
||||
|
@ -615,7 +625,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
_desiredFont = { _actualFont };
|
||||
|
||||
// Update the terminal core with its new Core settings
|
||||
_terminal->UpdateSettings(_settings);
|
||||
_terminal->UpdateSettings(*_settings);
|
||||
|
||||
if (!_initializedTerminal)
|
||||
{
|
||||
|
@ -624,8 +634,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
return;
|
||||
}
|
||||
|
||||
_renderEngine->SetForceFullRepaintRendering(_settings.ForceFullRepaintRendering());
|
||||
_renderEngine->SetSoftwareRendering(_settings.SoftwareRendering());
|
||||
_renderEngine->SetForceFullRepaintRendering(_settings->ForceFullRepaintRendering());
|
||||
_renderEngine->SetSoftwareRendering(_settings->SoftwareRendering());
|
||||
// Inform the renderer of our opacity
|
||||
_renderEngine->EnableTransparentBackground(_isBackgroundTransparent());
|
||||
|
||||
_updateAntiAliasingMode();
|
||||
|
||||
|
@ -642,21 +654,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// Method Description:
|
||||
// - Updates the appearance of the current terminal.
|
||||
// - INVARIANT: This method can only be called if the caller DOES NOT HAVE writing lock on the terminal.
|
||||
void ControlCore::UpdateAppearance(const IControlAppearance& newAppearance)
|
||||
void ControlCore::ApplyAppearance(const bool& focused)
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
|
||||
const auto& newAppearance{ focused ? _settings->FocusedAppearance() : _settings->UnfocusedAppearance() };
|
||||
// Update the terminal core with its new Core settings
|
||||
_terminal->UpdateAppearance(newAppearance);
|
||||
_terminal->UpdateAppearance(*newAppearance);
|
||||
|
||||
// Update DxEngine settings under the lock
|
||||
if (_renderEngine)
|
||||
{
|
||||
// Update DxEngine settings under the lock
|
||||
_renderEngine->SetSelectionBackground(til::color{ newAppearance.SelectionBackground() });
|
||||
_renderEngine->SetRetroTerminalEffect(newAppearance.RetroTerminalEffect());
|
||||
_renderEngine->SetPixelShaderPath(newAppearance.PixelShaderPath());
|
||||
_renderEngine->SetIntenseIsBold(_settings.IntenseIsBold());
|
||||
_renderEngine->SetSelectionBackground(til::color{ newAppearance->SelectionBackground() });
|
||||
_renderEngine->SetRetroTerminalEffect(newAppearance->RetroTerminalEffect());
|
||||
_renderEngine->SetPixelShaderPath(newAppearance->PixelShaderPath());
|
||||
_renderEngine->SetIntenseIsBold(_settings->IntenseIsBold());
|
||||
_renderer->TriggerRedrawAll();
|
||||
}
|
||||
}
|
||||
|
@ -664,8 +676,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
void ControlCore::_updateAntiAliasingMode()
|
||||
{
|
||||
D2D1_TEXT_ANTIALIAS_MODE mode;
|
||||
|
||||
switch (_settings.AntialiasingMode())
|
||||
// Update DxEngine's AntialiasingMode
|
||||
switch (_settings->AntialiasingMode())
|
||||
{
|
||||
case TextAntialiasingMode::Cleartype:
|
||||
mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
|
@ -701,7 +713,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
if (_renderEngine)
|
||||
{
|
||||
std::unordered_map<std::wstring_view, uint32_t> featureMap;
|
||||
if (const auto fontFeatures = _settings.FontFeatures())
|
||||
if (const auto fontFeatures = _settings->FontFeatures())
|
||||
{
|
||||
featureMap.reserve(fontFeatures.Size());
|
||||
|
||||
|
@ -711,7 +723,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
}
|
||||
}
|
||||
std::unordered_map<std::wstring_view, float> axesMap;
|
||||
if (const auto fontAxes = _settings.FontAxes())
|
||||
if (const auto fontAxes = _settings->FontAxes())
|
||||
{
|
||||
axesMap.reserve(fontAxes.Size());
|
||||
|
||||
|
@ -753,8 +765,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
{
|
||||
// Make sure we have a non-zero font size
|
||||
const auto newSize = std::max<short>(gsl::narrow_cast<short>(fontSize), 1);
|
||||
const auto fontFace = _settings.FontFace();
|
||||
const auto fontWeight = _settings.FontWeight();
|
||||
const auto fontFace = _settings->FontFace();
|
||||
const auto fontWeight = _settings->FontWeight();
|
||||
_actualFont = { fontFace, 0, fontWeight.Weight, { 0, newSize }, CP_UTF8, false };
|
||||
_actualFontFaceName = { fontFace };
|
||||
_desiredFont = { _actualFont };
|
||||
|
@ -779,7 +791,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// - none
|
||||
void ControlCore::ResetFontSize()
|
||||
{
|
||||
_setFontSize(_settings.FontSize());
|
||||
_setFontSize(_settings->FontSize());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -991,7 +1003,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
TextBuffer::GenHTML(bufferData,
|
||||
_actualFont.GetUnscaledSize().Y,
|
||||
_actualFont.GetFaceName(),
|
||||
til::color{ _settings.DefaultBackground() }) :
|
||||
til::color{ _settings->DefaultBackground() }) :
|
||||
"";
|
||||
|
||||
// convert to RTF format
|
||||
|
@ -999,10 +1011,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
TextBuffer::GenRTF(bufferData,
|
||||
_actualFont.GetUnscaledSize().Y,
|
||||
_actualFont.GetFaceName(),
|
||||
til::color{ _settings.DefaultBackground() }) :
|
||||
til::color{ _settings->DefaultBackground() }) :
|
||||
"";
|
||||
|
||||
if (!_settings.CopyOnSelect())
|
||||
if (!_settings->CopyOnSelect())
|
||||
{
|
||||
_terminal->ClearSelection();
|
||||
_renderer->TriggerSelection();
|
||||
|
@ -1089,7 +1101,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
til::color ControlCore::BackgroundColor() const
|
||||
{
|
||||
return _terminal->GetDefaultBackground();
|
||||
// The Terminal internally stores it's BG with 0 opacity, so as to allow
|
||||
// DX to paint the BG color transparently. We however don't want to leak
|
||||
// that implementation detail.
|
||||
return _terminal->GetDefaultBackground().with_alpha(0xff);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -1246,7 +1261,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
bool ControlCore::CopyOnSelect() const
|
||||
{
|
||||
return _settings.CopyOnSelect();
|
||||
return _settings->CopyOnSelect();
|
||||
}
|
||||
|
||||
Windows::Foundation::Collections::IVector<winrt::hstring> ControlCore::SelectedText(bool trimTrailingWhitespace) const
|
||||
|
@ -1304,16 +1319,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
}
|
||||
}
|
||||
|
||||
void ControlCore::SetBackgroundOpacity(const double opacity)
|
||||
{
|
||||
if (_renderEngine)
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
const auto backgroundIsOpaque = opacity == 1.0 && _settings.BackgroundImage().empty();
|
||||
_renderEngine->SetDefaultTextBackgroundOpacity(static_cast<float>(backgroundIsOpaque));
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Asynchronously close our connection. The Connection will likely wait
|
||||
// until the attached process terminates before Close returns. If that's
|
||||
|
@ -1599,4 +1604,125 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
return VerifyVersionInfoW(&osver, VER_BUILDNUMBER, dwlConditionMask) != FALSE;
|
||||
}
|
||||
|
||||
Core::Scheme ControlCore::ColorScheme() const noexcept
|
||||
{
|
||||
Core::Scheme s;
|
||||
|
||||
// This part is definitely a hack.
|
||||
//
|
||||
// This function is usually used by the "Preview Color Scheme"
|
||||
// functionality in TerminalPage. If we've got an unfocused appearance,
|
||||
// then we've applied that appearance before this is even getting called
|
||||
// (because the command palette is open with focus on top of us). If we
|
||||
// return the _current_ colors now, we'll return out the _unfocused_
|
||||
// colors. If we do that, and the user dismisses the command palette,
|
||||
// then the scheme that will get restored is the _unfocused_ one, which
|
||||
// is not what we want.
|
||||
//
|
||||
// So if that's the case, then let's grab the colors from the focused
|
||||
// appearance as the scheme instead. We'll lose any current runtime
|
||||
// changes to the color table, but those were already blown away when we
|
||||
// switched to an unfocused appearance.
|
||||
//
|
||||
// IF WE DON'T HAVE AN UNFOCUSED APPEARANCE: then just ask the Terminal
|
||||
// for it's current color table. That way, we can restore those colors
|
||||
// back.
|
||||
if (HasUnfocusedAppearance())
|
||||
{
|
||||
s.Foreground = _settings->FocusedAppearance()->DefaultForeground();
|
||||
s.Background = _settings->FocusedAppearance()->DefaultBackground();
|
||||
|
||||
s.CursorColor = _settings->FocusedAppearance()->CursorColor();
|
||||
|
||||
s.Black = _settings->FocusedAppearance()->GetColorTableEntry(0);
|
||||
s.Red = _settings->FocusedAppearance()->GetColorTableEntry(1);
|
||||
s.Green = _settings->FocusedAppearance()->GetColorTableEntry(2);
|
||||
s.Yellow = _settings->FocusedAppearance()->GetColorTableEntry(3);
|
||||
s.Blue = _settings->FocusedAppearance()->GetColorTableEntry(4);
|
||||
s.Purple = _settings->FocusedAppearance()->GetColorTableEntry(5);
|
||||
s.Cyan = _settings->FocusedAppearance()->GetColorTableEntry(6);
|
||||
s.White = _settings->FocusedAppearance()->GetColorTableEntry(7);
|
||||
s.BrightBlack = _settings->FocusedAppearance()->GetColorTableEntry(8);
|
||||
s.BrightRed = _settings->FocusedAppearance()->GetColorTableEntry(9);
|
||||
s.BrightGreen = _settings->FocusedAppearance()->GetColorTableEntry(10);
|
||||
s.BrightYellow = _settings->FocusedAppearance()->GetColorTableEntry(11);
|
||||
s.BrightBlue = _settings->FocusedAppearance()->GetColorTableEntry(12);
|
||||
s.BrightPurple = _settings->FocusedAppearance()->GetColorTableEntry(13);
|
||||
s.BrightCyan = _settings->FocusedAppearance()->GetColorTableEntry(14);
|
||||
s.BrightWhite = _settings->FocusedAppearance()->GetColorTableEntry(15);
|
||||
}
|
||||
else
|
||||
{
|
||||
s = _terminal->GetColorScheme();
|
||||
}
|
||||
|
||||
// This might be a tad bit of a hack. This event only gets called by set
|
||||
// color scheme / preview color scheme, and in that case, we know the
|
||||
// control _is_ focused.
|
||||
s.SelectionBackground = _settings->FocusedAppearance()->SelectionBackground();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Apply the given color scheme to this control. We'll take the colors out
|
||||
// of it and apply them to our focused appearance, and update the terminal
|
||||
// buffer with the new color table.
|
||||
// - This is here to support the Set Color Scheme action, and the ability to
|
||||
// preview schemes in the control.
|
||||
// Arguments:
|
||||
// - scheme: the collection of colors to apply.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void ControlCore::ColorScheme(const Core::Scheme& scheme)
|
||||
{
|
||||
auto l{ _terminal->LockForWriting() };
|
||||
|
||||
_settings->FocusedAppearance()->DefaultForeground(scheme.Foreground);
|
||||
_settings->FocusedAppearance()->DefaultBackground(scheme.Background);
|
||||
_settings->FocusedAppearance()->CursorColor(scheme.CursorColor);
|
||||
_settings->FocusedAppearance()->SelectionBackground(scheme.SelectionBackground);
|
||||
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(0, scheme.Black);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(1, scheme.Red);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(2, scheme.Green);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(3, scheme.Yellow);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(4, scheme.Blue);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(5, scheme.Purple);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(6, scheme.Cyan);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(7, scheme.White);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(8, scheme.BrightBlack);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(9, scheme.BrightRed);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(10, scheme.BrightGreen);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(11, scheme.BrightYellow);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(12, scheme.BrightBlue);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(13, scheme.BrightPurple);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(14, scheme.BrightCyan);
|
||||
_settings->FocusedAppearance()->SetColorTableEntry(15, scheme.BrightWhite);
|
||||
|
||||
_terminal->ApplyScheme(scheme);
|
||||
_renderEngine->SetSelectionBackground(til::color{ _settings->SelectionBackground() });
|
||||
|
||||
_renderer->TriggerRedrawAll();
|
||||
_BackgroundColorChangedHandlers(*this, nullptr);
|
||||
}
|
||||
|
||||
bool ControlCore::HasUnfocusedAppearance() const
|
||||
{
|
||||
return _settings->HasUnfocusedAppearance();
|
||||
}
|
||||
|
||||
bool ControlCore::_isBackgroundTransparent()
|
||||
{
|
||||
// If we're:
|
||||
// * Not fully opaque
|
||||
// * On an acrylic background (of any opacity)
|
||||
// * rendering on top of an image
|
||||
//
|
||||
// then the renderer should not render "default background" text with a
|
||||
// fully opaque background. Doing that would cover up our nice
|
||||
// transparency, or our acrylic, or our image.
|
||||
return Opacity() < 1.0f || UseAcrylic() || !_settings->BackgroundImage().empty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,23 +16,35 @@
|
|||
#pragma once
|
||||
|
||||
#include "ControlCore.g.h"
|
||||
#include "ControlSettings.h"
|
||||
#include "../../renderer/base/Renderer.hpp"
|
||||
#include "../../cascadia/TerminalCore/Terminal.hpp"
|
||||
#include "../buffer/out/search.h"
|
||||
#include "cppwinrt_utils.h"
|
||||
|
||||
#include <til/ticket_lock.h>
|
||||
|
||||
namespace ControlUnitTests
|
||||
{
|
||||
class ControlCoreTests;
|
||||
class ControlInteractivityTests;
|
||||
};
|
||||
|
||||
#define RUNTIME_SETTING(type, name, setting) \
|
||||
private: \
|
||||
std::optional<type> _runtime##name{ std::nullopt }; \
|
||||
void name(const type newValue) { _runtime##name = newValue; } \
|
||||
\
|
||||
public: \
|
||||
type name() const { return til::coalesce_value(_runtime##name, setting); }
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
struct ControlCore : ControlCoreT<ControlCore>
|
||||
{
|
||||
public:
|
||||
ControlCore(IControlSettings settings,
|
||||
ControlCore(Control::IControlSettings settings,
|
||||
Control::IControlAppearance unfocusedAppearance,
|
||||
TerminalConnection::ITerminalConnection connection);
|
||||
~ControlCore();
|
||||
|
||||
|
@ -41,8 +53,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
const double compositionScale);
|
||||
void EnablePainting();
|
||||
|
||||
void UpdateSettings(const IControlSettings& settings);
|
||||
void UpdateAppearance(const IControlAppearance& newAppearance);
|
||||
void UpdateSettings(const Control::IControlSettings& settings, const IControlAppearance& newAppearance);
|
||||
void ApplyAppearance(const bool& focused);
|
||||
Control::IControlSettings Settings() { return *_settings; };
|
||||
Control::IControlAppearance FocusedAppearance() const { return *_settings->FocusedAppearance(); };
|
||||
Control::IControlAppearance UnfocusedAppearance() const { return *_settings->UnfocusedAppearance(); };
|
||||
bool HasUnfocusedAppearance() const;
|
||||
|
||||
winrt::Microsoft::Terminal::Core::Scheme ColorScheme() const noexcept;
|
||||
void ColorScheme(const winrt::Microsoft::Terminal::Core::Scheme& scheme);
|
||||
|
||||
void SizeChanged(const double width, const double height);
|
||||
void ScaleChanged(const double scale);
|
||||
uint64_t SwapChainHandle() const;
|
||||
|
@ -57,7 +77,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
uint16_t FontWeight() const noexcept;
|
||||
|
||||
til::color BackgroundColor() const;
|
||||
void SetBackgroundOpacity(const double opacity);
|
||||
|
||||
void SendInput(const winrt::hstring& wstr);
|
||||
void PasteText(const winrt::hstring& hstr);
|
||||
|
@ -148,6 +167,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
static bool IsVintageOpacityAvailable() noexcept;
|
||||
|
||||
RUNTIME_SETTING(double, Opacity, _settings->Opacity());
|
||||
RUNTIME_SETTING(bool, UseAcrylic, _settings->UseAcrylic());
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
// clang-format off
|
||||
WINRT_CALLBACK(FontSizeChanged, Control::FontSizeChangedEventArgs);
|
||||
|
@ -178,6 +200,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
event_token _connectionOutputEventToken;
|
||||
TerminalConnection::ITerminalConnection::StateChanged_revoker _connectionStateChangedRevoker;
|
||||
|
||||
winrt::com_ptr<ControlSettings> _settings{ nullptr };
|
||||
|
||||
std::unique_ptr<::Microsoft::Terminal::Core::Terminal> _terminal{ nullptr };
|
||||
|
||||
// NOTE: _renderEngine must be ordered before _renderer.
|
||||
|
@ -188,8 +212,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
std::unique_ptr<::Microsoft::Console::Render::IRenderEngine> _renderEngine{ nullptr };
|
||||
std::unique_ptr<::Microsoft::Console::Render::Renderer> _renderer{ nullptr };
|
||||
|
||||
IControlSettings _settings{ nullptr };
|
||||
|
||||
FontInfoDesired _desiredFont;
|
||||
FontInfo _actualFont;
|
||||
winrt::hstring _actualFontFaceName;
|
||||
|
@ -249,6 +271,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
void _connectionOutputHandler(const hstring& hstr);
|
||||
void _updateHoveredCell(const std::optional<til::point> terminalPosition);
|
||||
|
||||
bool _isBackgroundTransparent();
|
||||
|
||||
inline bool _IsClosing() const noexcept
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -33,20 +33,27 @@ namespace Microsoft.Terminal.Control
|
|||
[default_interface] runtimeclass ControlCore : ICoreState
|
||||
{
|
||||
ControlCore(IControlSettings settings,
|
||||
IControlAppearance unfocusedAppearance,
|
||||
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||
|
||||
Boolean Initialize(Double actualWidth,
|
||||
Double actualHeight,
|
||||
Double compositionScale);
|
||||
|
||||
void UpdateSettings(IControlSettings settings);
|
||||
void UpdateAppearance(IControlAppearance appearance);
|
||||
void UpdateSettings(IControlSettings settings, IControlAppearance appearance);
|
||||
void ApplyAppearance(Boolean focused);
|
||||
|
||||
IControlSettings Settings { get; };
|
||||
IControlAppearance FocusedAppearance { get; };
|
||||
IControlAppearance UnfocusedAppearance { get; };
|
||||
Boolean HasUnfocusedAppearance();
|
||||
|
||||
UInt64 SwapChainHandle { get; };
|
||||
|
||||
Windows.Foundation.Size FontSize { get; };
|
||||
String FontFaceName { get; };
|
||||
UInt16 FontWeight { get; };
|
||||
Double Opacity { get; };
|
||||
|
||||
Boolean TrySendKeyEvent(Int16 vkey,
|
||||
Int16 scanCode,
|
||||
|
@ -75,7 +82,6 @@ namespace Microsoft.Terminal.Control
|
|||
void BlinkAttributeTick();
|
||||
void UpdatePatternLocations();
|
||||
void Search(String text, Boolean goForward, Boolean caseSensitive);
|
||||
void SetBackgroundOpacity(Double opacity);
|
||||
Microsoft.Terminal.Core.Color BackgroundColor { get; };
|
||||
|
||||
Boolean HasSelection { get; };
|
||||
|
|
|
@ -39,13 +39,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
}
|
||||
|
||||
ControlInteractivity::ControlInteractivity(IControlSettings settings,
|
||||
Control::IControlAppearance unfocusedAppearance,
|
||||
TerminalConnection::ITerminalConnection connection) :
|
||||
_touchAnchor{ std::nullopt },
|
||||
_lastMouseClickTimestamp{},
|
||||
_lastMouseClickPos{},
|
||||
_selectionNeedsToBeCopied{ false }
|
||||
{
|
||||
_core = winrt::make_self<ControlCore>(settings, connection);
|
||||
_core = winrt::make_self<ControlCore>(settings, unfocusedAppearance, connection);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -641,4 +642,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
return _core->GetUiaData();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Used by the TermControl to know if it should translate drag-dropped
|
||||
// paths into WSL-friendly paths.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - true if the connection we were created with was a WSL profile.
|
||||
bool ControlInteractivity::ManglePathsForWsl()
|
||||
{
|
||||
return _core->Settings().ProfileSource() == L"Windows.Terminal.Wsl";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
{
|
||||
public:
|
||||
ControlInteractivity(IControlSettings settings,
|
||||
Control::IControlAppearance unfocusedAppearance,
|
||||
TerminalConnection::ITerminalConnection connection);
|
||||
|
||||
void GotFocus();
|
||||
|
@ -83,6 +84,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
const Windows::Foundation::IReference<CopyFormat>& formats);
|
||||
void RequestPasteTextFromClipboard();
|
||||
void SetEndSelectionPoint(const til::point pixelPosition);
|
||||
bool ManglePathsForWsl();
|
||||
|
||||
TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs);
|
||||
TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Microsoft.Terminal.Control
|
|||
[default_interface] runtimeclass ControlInteractivity
|
||||
{
|
||||
ControlInteractivity(IControlSettings settings,
|
||||
IControlAppearance unfocusedAppearance,
|
||||
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||
|
||||
ControlCore Core { get; };
|
||||
|
@ -58,6 +59,8 @@ namespace Microsoft.Terminal.Control
|
|||
|
||||
void UpdateScrollbar(Double newValue);
|
||||
|
||||
Boolean ManglePathsForWsl { get; };
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, OpenHyperlinkEventArgs> OpenHyperlink;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ScrollPositionChangedArgs> ScrollPositionChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, PasteFromClipboardEventArgs> PasteFromClipboard;
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
--*/
|
||||
#pragma once
|
||||
#include "../../inc/cppwinrt_utils.h"
|
||||
#include "../../inc/ControlProperties.h"
|
||||
|
||||
#include <DefaultSettings.h>
|
||||
#include <conattrs.hpp>
|
||||
#include "ControlAppearance.h"
|
||||
|
||||
using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap<winrt::hstring, uint32_t>;
|
||||
using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap<winrt::hstring, float>;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
struct ControlSettings : public winrt::implements<ControlSettings, Microsoft::Terminal::Control::IControlSettings, Microsoft::Terminal::Control::IControlAppearance, Microsoft::Terminal::Core::ICoreSettings, Microsoft::Terminal::Core::ICoreAppearance>
|
||||
{
|
||||
// Getters and setters for each *Setting member. We're not using
|
||||
// WINRT_PROPERTY for these, because they actually exist inside the
|
||||
// _focusedAppearance member. We don't need to reserve another member to
|
||||
// hold them.
|
||||
#define SETTINGS_GEN(type, name, ...) WINRT_PROPERTY(type, name, __VA_ARGS__);
|
||||
CORE_SETTINGS(SETTINGS_GEN)
|
||||
CONTROL_SETTINGS(SETTINGS_GEN)
|
||||
#undef SETTINGS_GEN
|
||||
|
||||
private:
|
||||
winrt::com_ptr<ControlAppearance> _unfocusedAppearance{ nullptr };
|
||||
winrt::com_ptr<ControlAppearance> _focusedAppearance{ nullptr };
|
||||
bool _hasUnfocusedAppearance{ false };
|
||||
|
||||
public:
|
||||
ControlSettings(const Control::IControlSettings& settings,
|
||||
const Control::IControlAppearance& unfocusedAppearance)
|
||||
{
|
||||
_hasUnfocusedAppearance = unfocusedAppearance != nullptr;
|
||||
|
||||
_focusedAppearance = winrt::make_self<implementation::ControlAppearance>(settings);
|
||||
_unfocusedAppearance = unfocusedAppearance ?
|
||||
winrt::make_self<implementation::ControlAppearance>(unfocusedAppearance) :
|
||||
_focusedAppearance;
|
||||
|
||||
// Copy every value from the passed in settings, into us.
|
||||
#define COPY_SETTING(type, name, ...) _##name = settings.name();
|
||||
CORE_SETTINGS(COPY_SETTING)
|
||||
CONTROL_SETTINGS(COPY_SETTING)
|
||||
#undef COPY_SETTING
|
||||
}
|
||||
|
||||
winrt::com_ptr<ControlAppearance> UnfocusedAppearance() { return _unfocusedAppearance; }
|
||||
winrt::com_ptr<ControlAppearance> FocusedAppearance() { return _focusedAppearance; }
|
||||
bool HasUnfocusedAppearance() { return _hasUnfocusedAppearance; }
|
||||
|
||||
// Getters and setters for each Appearance member. We're not using
|
||||
// WINRT_PROPERTY for these, because they actually exist inside the
|
||||
// _focusedAppearance member. We don't need to reserve another member to
|
||||
// hold them.
|
||||
//
|
||||
// The Appearance members (including GetColorTableEntry below) are used
|
||||
// when this ControlSettings is cast to a IControlAppearance or
|
||||
// ICoreAppearance. In those cases, we'll always return the Focused
|
||||
// appearance's version of the member. Callers who care about which
|
||||
// appearance is being used should be more careful. Fortunately, this
|
||||
// situation is generally only used when a control is first created, or
|
||||
// when calling UpdateSettings.
|
||||
#define APPEARANCE_GEN(type, name, ...) \
|
||||
type name() const noexcept { return _focusedAppearance->name(); } \
|
||||
void name(const type& value) noexcept { _focusedAppearance->name(value); }
|
||||
|
||||
CORE_APPEARANCE_SETTINGS(APPEARANCE_GEN)
|
||||
CONTROL_APPEARANCE_SETTINGS(APPEARANCE_GEN)
|
||||
#undef APPEARANCE_GEN
|
||||
|
||||
winrt::Microsoft::Terminal::Core::Color GetColorTableEntry(int32_t index) noexcept
|
||||
{
|
||||
return _focusedAppearance->GetColorTableEntry(index);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -5,18 +5,18 @@ namespace Microsoft.Terminal.Control
|
|||
{
|
||||
interface IControlAppearance requires Microsoft.Terminal.Core.ICoreAppearance
|
||||
{
|
||||
Microsoft.Terminal.Core.Color SelectionBackground;
|
||||
String BackgroundImage;
|
||||
Double BackgroundImageOpacity;
|
||||
Windows.UI.Xaml.Media.Stretch BackgroundImageStretchMode;
|
||||
Windows.UI.Xaml.HorizontalAlignment BackgroundImageHorizontalAlignment;
|
||||
Windows.UI.Xaml.VerticalAlignment BackgroundImageVerticalAlignment;
|
||||
Boolean IntenseIsBold;
|
||||
Microsoft.Terminal.Core.Color SelectionBackground { get; };
|
||||
String BackgroundImage { get; };
|
||||
Double BackgroundImageOpacity { get; };
|
||||
Windows.UI.Xaml.Media.Stretch BackgroundImageStretchMode { get; };
|
||||
Windows.UI.Xaml.HorizontalAlignment BackgroundImageHorizontalAlignment { get; };
|
||||
Windows.UI.Xaml.VerticalAlignment BackgroundImageVerticalAlignment { get; };
|
||||
Boolean IntenseIsBold { get; };
|
||||
// IntenseIsBright is in Core Appearance
|
||||
Double Opacity;
|
||||
Double Opacity { get; };
|
||||
|
||||
// Experimental settings
|
||||
Boolean RetroTerminalEffect;
|
||||
String PixelShaderPath;
|
||||
Boolean RetroTerminalEffect { get; };
|
||||
String PixelShaderPath { get; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -24,34 +24,37 @@ namespace Microsoft.Terminal.Control
|
|||
// TermControl's behavior. In these settings there is both the entirety
|
||||
// of the Core ITerminalSettings interface, and any additional settings
|
||||
// for specifically the control.
|
||||
interface IControlSettings requires Microsoft.Terminal.Core.ICoreSettings, Microsoft.Terminal.Control.IControlAppearance
|
||||
interface IControlSettings requires Microsoft.Terminal.Core.ICoreSettings,
|
||||
Microsoft.Terminal.Control.IControlAppearance
|
||||
{
|
||||
String ProfileName;
|
||||
String ProfileSource;
|
||||
|
||||
Boolean UseAcrylic;
|
||||
ScrollbarState ScrollState;
|
||||
Boolean UseAtlasEngine;
|
||||
String FontFace;
|
||||
Int32 FontSize;
|
||||
Windows.UI.Text.FontWeight FontWeight;
|
||||
String Padding;
|
||||
Windows.Foundation.Collections.IMap<String, UInt32> FontFeatures;
|
||||
Windows.Foundation.Collections.IMap<String, Single> FontAxes;
|
||||
Boolean UseAcrylic { get; };
|
||||
ScrollbarState ScrollState { get; };
|
||||
|
||||
Microsoft.Terminal.Control.IKeyBindings KeyBindings;
|
||||
Boolean UseAtlasEngine { get; };
|
||||
|
||||
Boolean CopyOnSelect;
|
||||
Boolean FocusFollowMouse;
|
||||
String FontFace { get; };
|
||||
Int32 FontSize { get; };
|
||||
Windows.UI.Text.FontWeight FontWeight { get; };
|
||||
String Padding { get; };
|
||||
Windows.Foundation.Collections.IMap<String, UInt32> FontFeatures { get; };
|
||||
Windows.Foundation.Collections.IMap<String, Single> FontAxes { get; };
|
||||
|
||||
String Commandline;
|
||||
String StartingDirectory;
|
||||
String EnvironmentVariables;
|
||||
Microsoft.Terminal.Control.IKeyBindings KeyBindings { get; };
|
||||
|
||||
TextAntialiasingMode AntialiasingMode;
|
||||
Boolean CopyOnSelect { get; };
|
||||
Boolean FocusFollowMouse { get; };
|
||||
|
||||
String Commandline { get; };
|
||||
String StartingDirectory { get; };
|
||||
String EnvironmentVariables { get; };
|
||||
|
||||
TextAntialiasingMode AntialiasingMode { get; };
|
||||
|
||||
// Experimental Settings
|
||||
Boolean ForceFullRepaintRendering;
|
||||
Boolean SoftwareRendering;
|
||||
Boolean ForceFullRepaintRendering { get; };
|
||||
Boolean SoftwareRendering { get; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -22,5 +22,7 @@ namespace Microsoft.Terminal.Control
|
|||
Boolean BracketedPasteEnabled { get; };
|
||||
|
||||
Microsoft.Terminal.TerminalConnection.ConnectionState ConnectionState { get; };
|
||||
|
||||
Microsoft.Terminal.Core.Scheme ColorScheme { get; set; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -48,8 +48,8 @@ DEFINE_ENUM_FLAG_OPERATORS(winrt::Microsoft::Terminal::Control::MouseButtonState
|
|||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
TermControl::TermControl(IControlSettings settings,
|
||||
Control::IControlAppearance unfocusedAppearance,
|
||||
TerminalConnection::ITerminalConnection connection) :
|
||||
_settings{ settings },
|
||||
_isInternalScrollBarUpdate{ false },
|
||||
_autoScrollVelocity{ 0 },
|
||||
_autoScrollingPointerPoint{ std::nullopt },
|
||||
|
@ -61,7 +61,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
_interactivity = winrt::make<implementation::ControlInteractivity>(settings, connection);
|
||||
_interactivity = winrt::make<implementation::ControlInteractivity>(settings, unfocusedAppearance, connection);
|
||||
_core = _interactivity.Core();
|
||||
|
||||
// These events might all be triggered by the connection, but that
|
||||
|
@ -77,7 +77,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// These callbacks can only really be triggered by UI interactions. So
|
||||
// they don't need weak refs - they can't be triggered unless we're
|
||||
// alive.
|
||||
_core.BackgroundColorChanged({ this, &TermControl::_BackgroundColorChangedHandler });
|
||||
_core.BackgroundColorChanged({ this, &TermControl::_coreBackgroundColorChanged });
|
||||
_core.FontSizeChanged({ this, &TermControl::_coreFontSizeChanged });
|
||||
_core.TransparencyChanged({ this, &TermControl::_coreTransparencyChanged });
|
||||
_core.RaiseNotice({ this, &TermControl::_coreRaisedNotice });
|
||||
|
@ -144,7 +144,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
_autoScrollTimer.Interval(AutoScrollUpdateInterval);
|
||||
_autoScrollTimer.Tick({ this, &TermControl::_UpdateAutoScroll });
|
||||
|
||||
_ApplyUISettings(_settings);
|
||||
_ApplyUISettings();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -229,11 +229,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
this->Focus(FocusState::Programmatic);
|
||||
}
|
||||
|
||||
winrt::fire_and_forget TermControl::UpdateControlSettings(IControlSettings settings)
|
||||
{
|
||||
return UpdateControlSettings(settings, _core.UnfocusedAppearance());
|
||||
}
|
||||
// Method Description:
|
||||
// - Given Settings having been updated, applies the settings to the current terminal.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
winrt::fire_and_forget TermControl::UpdateSettings()
|
||||
winrt::fire_and_forget TermControl::UpdateControlSettings(IControlSettings settings, IControlAppearance unfocusedAppearance)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
|
@ -241,21 +245,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// terminal.
|
||||
co_await winrt::resume_foreground(Dispatcher());
|
||||
|
||||
_UpdateSettingsFromUIThread(_settings);
|
||||
_core.UpdateSettings(settings, unfocusedAppearance);
|
||||
|
||||
auto appearance = _settings.try_as<IControlAppearance>();
|
||||
if (!_focused && _UnfocusedAppearance)
|
||||
{
|
||||
appearance = _UnfocusedAppearance;
|
||||
}
|
||||
_UpdateAppearanceFromUIThread(appearance);
|
||||
_UpdateSettingsFromUIThread();
|
||||
|
||||
_UpdateAppearanceFromUIThread(_focused ? _core.FocusedAppearance() : _core.UnfocusedAppearance());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Dispatches a call to the UI thread and updates the appearance
|
||||
// Arguments:
|
||||
// - newAppearance: the new appearance to set
|
||||
winrt::fire_and_forget TermControl::UpdateAppearance(const IControlAppearance newAppearance)
|
||||
winrt::fire_and_forget TermControl::UpdateAppearance(IControlAppearance newAppearance)
|
||||
{
|
||||
// Dispatch a call to the UI thread
|
||||
co_await winrt::resume_foreground(Dispatcher());
|
||||
|
@ -271,17 +272,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// - INVARIANT: This method must be called from the UI thread.
|
||||
// Arguments:
|
||||
// - newSettings: the new settings to set
|
||||
void TermControl::_UpdateSettingsFromUIThread(IControlSettings newSettings)
|
||||
void TermControl::_UpdateSettingsFromUIThread()
|
||||
{
|
||||
if (_IsClosing())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_core.UpdateSettings(_settings);
|
||||
|
||||
// Update our control settings
|
||||
_ApplyUISettings(_settings);
|
||||
_ApplyUISettings();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -289,7 +288,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// - INVARIANT: This method must be called from the UI thread.
|
||||
// Arguments:
|
||||
// - newAppearance: the new appearance to set
|
||||
void TermControl::_UpdateAppearanceFromUIThread(IControlAppearance newAppearance)
|
||||
void TermControl::_UpdateAppearanceFromUIThread(Control::IControlAppearance newAppearance)
|
||||
{
|
||||
if (_IsClosing())
|
||||
{
|
||||
|
@ -300,6 +299,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
// Update our control settings
|
||||
const auto bg = newAppearance.DefaultBackground();
|
||||
|
||||
// In the future, this might need to be changed to a
|
||||
// _InitializeBackgroundBrush call instead, because we may need to
|
||||
// switch from a solid color brush to an acrylic one.
|
||||
_changeBackgroundColor(bg);
|
||||
|
||||
// Set TSF Foreground
|
||||
|
@ -307,7 +310,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
foregroundBrush.Color(static_cast<til::color>(newAppearance.DefaultForeground()));
|
||||
TSFInputControl().Foreground(foregroundBrush);
|
||||
|
||||
_core.UpdateAppearance(newAppearance);
|
||||
_core.ApplyAppearance(_focused);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -331,7 +334,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
}
|
||||
|
||||
// Method Description:
|
||||
// - Style our UI elements based on the values in our _settings, and set up
|
||||
// - Style our UI elements based on the values in our settings, and set up
|
||||
// other control-specific settings. This method will be called whenever
|
||||
// the settings are reloaded.
|
||||
// * Calls _InitializeBackgroundBrush to set up the Xaml brush responsible
|
||||
|
@ -342,21 +345,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TermControl::_ApplyUISettings(const IControlSettings& newSettings)
|
||||
void TermControl::_ApplyUISettings()
|
||||
{
|
||||
_InitializeBackgroundBrush();
|
||||
|
||||
const auto bg = newSettings.DefaultBackground();
|
||||
_changeBackgroundColor(bg);
|
||||
// settings might be out-of-proc in the future
|
||||
auto settings{ _core.Settings() };
|
||||
|
||||
// Apply padding as swapChainPanel's margin
|
||||
const auto newMargin = ParseThicknessFromPadding(newSettings.Padding());
|
||||
const auto newMargin = ParseThicknessFromPadding(settings.Padding());
|
||||
SwapChainPanel().Margin(newMargin);
|
||||
|
||||
TSFInputControl().Margin(newMargin);
|
||||
|
||||
// Apply settings for scrollbar
|
||||
if (newSettings.ScrollState() == ScrollbarState::Hidden)
|
||||
if (settings.ScrollState() == ScrollbarState::Hidden)
|
||||
{
|
||||
// In the scenario where the user has turned off the OS setting to automatically hide scrollbars, the
|
||||
// Terminal scrollbar would still be visible; so, we need to set the control's visibility accordingly to
|
||||
|
@ -440,16 +443,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// use bgcolor as acrylic's tint
|
||||
// - Avoids image flickering and acrylic brush redraw if settings are changed
|
||||
// but the appropriate brush is still in place.
|
||||
// - Does not apply background color outside of acrylic mode;
|
||||
// _BackgroundColorChanged must be called to do so.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TermControl::_InitializeBackgroundBrush()
|
||||
{
|
||||
auto appearance = _settings.try_as<IControlAppearance>();
|
||||
if (_settings.UseAcrylic())
|
||||
auto settings{ _core.Settings() };
|
||||
auto bgColor = til::color{ _core.FocusedAppearance().DefaultBackground() }.with_alpha(0xff);
|
||||
if (settings.UseAcrylic())
|
||||
{
|
||||
// See if we've already got an acrylic background brush
|
||||
// to avoid the flicker when setting up a new one
|
||||
|
@ -464,65 +466,83 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
// see GH#1082: Initialize background color so we don't get a
|
||||
// fade/flash when _BackgroundColorChanged is called
|
||||
auto bgColor = til::color{ _settings.DefaultBackground() }.with_alpha(0xff);
|
||||
|
||||
acrylic.FallbackColor(bgColor);
|
||||
acrylic.TintColor(bgColor);
|
||||
|
||||
// Apply brush settings
|
||||
acrylic.TintOpacity(appearance.Opacity());
|
||||
acrylic.TintOpacity(_core.Opacity());
|
||||
|
||||
// Apply brush to control if it's not already there
|
||||
if (RootGrid().Background() != acrylic)
|
||||
{
|
||||
RootGrid().Background(acrylic);
|
||||
}
|
||||
|
||||
// GH#5098: Inform the engine of the new opacity of the default text background.
|
||||
_core.SetBackgroundOpacity(appearance.Opacity());
|
||||
}
|
||||
else
|
||||
{
|
||||
Media::SolidColorBrush solidColor{};
|
||||
solidColor.Opacity(_settings.Opacity());
|
||||
RootGrid().Background(solidColor);
|
||||
solidColor.Opacity(_core.Opacity());
|
||||
solidColor.Color(bgColor);
|
||||
|
||||
// GH#5098: Inform the engine of the new opacity of the default text background.
|
||||
_core.SetBackgroundOpacity(appearance.Opacity());
|
||||
RootGrid().Background(solidColor);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Style the background of the control with the provided background color
|
||||
// - Handler for the core's BackgroundColorChanged event. Updates the color
|
||||
// of our background brush to match.
|
||||
// - Hops over to the UI thread to do this work.
|
||||
// Arguments:
|
||||
// - color: The background color to use as a uint32 (aka DWORD COLORREF)
|
||||
// <unused>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TermControl::_BackgroundColorChangedHandler(const IInspectable& /*sender*/,
|
||||
const IInspectable& /*args*/)
|
||||
{
|
||||
til::color newBgColor{ _core.BackgroundColor() };
|
||||
_changeBackgroundColor(newBgColor);
|
||||
}
|
||||
|
||||
winrt::fire_and_forget TermControl::_changeBackgroundColor(const til::color bg)
|
||||
winrt::fire_and_forget TermControl::_coreBackgroundColorChanged(const IInspectable& /*sender*/,
|
||||
const IInspectable& /*args*/)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
co_await winrt::resume_foreground(Dispatcher());
|
||||
|
||||
if (auto control{ weakThis.get() })
|
||||
{
|
||||
if (auto acrylic = RootGrid().Background().try_as<Media::AcrylicBrush>())
|
||||
{
|
||||
acrylic.FallbackColor(bg);
|
||||
acrylic.TintColor(bg);
|
||||
}
|
||||
else if (auto solidColor = RootGrid().Background().try_as<Media::SolidColorBrush>())
|
||||
{
|
||||
const auto originalOpacity = solidColor.Opacity();
|
||||
solidColor.Color(bg);
|
||||
solidColor.Opacity(originalOpacity);
|
||||
}
|
||||
til::color newBgColor{ _core.BackgroundColor() };
|
||||
_changeBackgroundColor(newBgColor);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update the color of the background brush we're using. This does _not_
|
||||
// update the opacity, or what type of brush it is.
|
||||
// - INVARIANT: This needs to be called on the UI thread.
|
||||
// Arguments:
|
||||
// - bg: the new color to use as the background color.
|
||||
void TermControl::_changeBackgroundColor(const til::color bg)
|
||||
{
|
||||
if (auto acrylic = RootGrid().Background().try_as<Media::AcrylicBrush>())
|
||||
{
|
||||
acrylic.FallbackColor(bg);
|
||||
acrylic.TintColor(bg);
|
||||
}
|
||||
else if (auto solidColor = RootGrid().Background().try_as<Media::SolidColorBrush>())
|
||||
{
|
||||
const auto originalOpacity = solidColor.Opacity();
|
||||
solidColor.Color(bg);
|
||||
solidColor.Opacity(originalOpacity);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update the opacity of the background brush we're using. This does _not_
|
||||
// update the color, or what type of brush it is.
|
||||
// - INVARIANT: This needs to be called on the UI thread.
|
||||
void TermControl::_changeBackgroundOpacity()
|
||||
{
|
||||
const auto opacity{ _core.Opacity() };
|
||||
if (auto acrylic = RootGrid().Background().try_as<Media::AcrylicBrush>())
|
||||
{
|
||||
acrylic.TintOpacity(opacity);
|
||||
}
|
||||
else if (auto solidColor = RootGrid().Background().try_as<Media::SolidColorBrush>())
|
||||
{
|
||||
solidColor.Opacity(opacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,7 +638,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr)
|
||||
{
|
||||
message = { fmt::format(std::wstring_view{ RS_(L"PixelShaderNotFound") },
|
||||
_settings.PixelShaderPath()) };
|
||||
(_focused ? _core.FocusedAppearance() : _core.UnfocusedAppearance()).PixelShaderPath()) };
|
||||
}
|
||||
else if (D2DERR_SHADER_COMPILE_FAILED == hr)
|
||||
{
|
||||
|
@ -740,7 +760,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
}
|
||||
|
||||
// Now that the renderer is set up, update the appearance for initialization
|
||||
_UpdateAppearanceFromUIThread(_settings);
|
||||
_UpdateAppearanceFromUIThread(_core.FocusedAppearance());
|
||||
|
||||
_initializedTerminal = true;
|
||||
|
||||
|
@ -812,7 +832,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// This is required as part of GH#638.
|
||||
// Or do so for alt+space; only send to terminal when explicitly unbound
|
||||
// That is part of #GH7125
|
||||
auto bindings{ _settings.KeyBindings() };
|
||||
auto bindings{ _core.Settings().KeyBindings() };
|
||||
bool isUnbound = false;
|
||||
const KeyChord kc = {
|
||||
modifiers.IsCtrlPressed(),
|
||||
|
@ -957,7 +977,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// - modifiers: The ControlKeyStates representing the modifier key states.
|
||||
bool TermControl::_TryHandleKeyBinding(const WORD vkey, const WORD scanCode, ::Microsoft::Terminal::Core::ControlKeyStates modifiers) const
|
||||
{
|
||||
auto bindings = _settings.KeyBindings();
|
||||
// TODO: GH#5000
|
||||
// The Core owning the keybindings is weird. That's for sure. In the
|
||||
// future, we may want to pass the keybindings into the control
|
||||
// separately, so the control can have a pointer to an in-proc
|
||||
// Keybindings object, rather than routing through the ControlCore.
|
||||
// (see GH#5000)
|
||||
auto bindings = _core.Settings().KeyBindings();
|
||||
if (!bindings)
|
||||
{
|
||||
return false;
|
||||
|
@ -1136,7 +1162,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
const auto pixelPosition = _toTerminalOrigin(cursorPosition);
|
||||
const auto type = ptr.PointerDeviceType();
|
||||
|
||||
if (!_focused && _settings.FocusFollowMouse())
|
||||
if (!_focused && _core.Settings().FocusFollowMouse())
|
||||
{
|
||||
_FocusFollowMouseRequestedHandlers(*this, nullptr);
|
||||
}
|
||||
|
@ -1304,7 +1330,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
// - Called in response to the core's TransparencyChanged event. We'll use
|
||||
// this to update our background brush.
|
||||
// - The Core should have already updated the TintOpacity and UseAcrylic
|
||||
// properties in the _settings.
|
||||
// properties in the _settings->
|
||||
// Arguments:
|
||||
// - <unused>
|
||||
// Return Value:
|
||||
|
@ -1315,9 +1341,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
co_await resume_foreground(Dispatcher());
|
||||
try
|
||||
{
|
||||
_InitializeBackgroundBrush();
|
||||
const auto bg = _settings.DefaultBackground();
|
||||
_changeBackgroundColor(bg);
|
||||
_changeBackgroundOpacity();
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
@ -1524,12 +1548,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
_blinkTimer->Start();
|
||||
}
|
||||
|
||||
// Only update the appearance here if an unfocused config exists -
|
||||
// if an unfocused config does not exist then we never would have switched
|
||||
// appearances anyway so there's no need to switch back upon gaining focus
|
||||
if (_UnfocusedAppearance)
|
||||
// Only update the appearance here if an unfocused config exists - if an
|
||||
// unfocused config does not exist then we never would have switched
|
||||
// appearances anyway so there's no need to switch back upon gaining
|
||||
// focus
|
||||
if (_core.HasUnfocusedAppearance())
|
||||
{
|
||||
UpdateAppearance(_settings);
|
||||
UpdateAppearance(_core.FocusedAppearance());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1571,9 +1596,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
// Check if there is an unfocused config we should set the appearance to
|
||||
// upon losing focus
|
||||
if (_UnfocusedAppearance)
|
||||
if (_core.HasUnfocusedAppearance())
|
||||
{
|
||||
UpdateAppearance(_UnfocusedAppearance);
|
||||
UpdateAppearance(_core.UnfocusedAppearance());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1722,7 +1747,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
hstring TermControl::GetProfileName() const
|
||||
{
|
||||
return _settings.ProfileName();
|
||||
return _core.Settings().ProfileName();
|
||||
}
|
||||
|
||||
hstring TermControl::WorkingDirectory() const
|
||||
|
@ -1944,7 +1969,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
double width = fontSize.Width;
|
||||
double height = fontSize.Height;
|
||||
// Reserve additional space if scrollbar is intended to be visible
|
||||
if (_settings.ScrollState() == ScrollbarState::Visible)
|
||||
if (_core.Settings().ScrollState() == ScrollbarState::Visible)
|
||||
{
|
||||
width += ScrollBar().ActualWidth();
|
||||
}
|
||||
|
@ -1965,7 +1990,8 @@ 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(_settings, dpi, minSize);
|
||||
|
||||
return GetProposedDimensions(_core.Settings(), dpi, minSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1987,7 +2013,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
padding.Left + padding.Right :
|
||||
padding.Top + padding.Bottom);
|
||||
|
||||
if (widthOrHeight && _settings.ScrollState() == ScrollbarState::Visible)
|
||||
if (widthOrHeight && _core.Settings().ScrollState() == ScrollbarState::Visible)
|
||||
{
|
||||
nonTerminalArea += gsl::narrow_cast<float>(ScrollBar().ActualWidth());
|
||||
}
|
||||
|
@ -2270,7 +2296,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
std::wstring fullPath{ item.Path() };
|
||||
|
||||
// Fix path for WSL
|
||||
if (_settings.ProfileSource() == L"Windows.Terminal.Wsl")
|
||||
// In the fullness of time, we should likely plumb this up
|
||||
// to the TerminalApp layer, and have it make the decision
|
||||
// if this control should have it's path mangled (and do the
|
||||
// mangling), rather than exposing the source concept to the
|
||||
// Control layer.
|
||||
//
|
||||
// However, it's likely that the control layer may need to
|
||||
// know about the source anyways in the future, to support
|
||||
// GH#3158
|
||||
if (_interactivity.ManglePathsForWsl())
|
||||
{
|
||||
std::replace(fullPath.begin(), fullPath.end(), L'\\', L'/');
|
||||
|
||||
|
@ -2417,12 +2452,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
IControlSettings TermControl::Settings() const
|
||||
{
|
||||
return _settings;
|
||||
}
|
||||
|
||||
void TermControl::Settings(IControlSettings newSettings)
|
||||
{
|
||||
_settings = newSettings;
|
||||
// TODO: GH#5000
|
||||
// We still need this in a couple places:
|
||||
// - Pane.cpp uses this for parsing out the StartingTitle, Commandline,
|
||||
// etc for Pane::GetTerminalArgsForPane.
|
||||
// - TerminalTab::_CreateToolTipTitle uses the ProfileName for the
|
||||
// tooltip for the tab.
|
||||
//
|
||||
// These both happen on the UI thread right now. In the future, when we
|
||||
// have to hop across the process boundary to get at the core settings,
|
||||
// it may make sense to cache these values inside the TermControl
|
||||
// itself, so it can do the hop once when it's first setup, rather than
|
||||
// when it's needed by the UI thread.
|
||||
return _core.Settings();
|
||||
}
|
||||
|
||||
Windows::Foundation::IReference<winrt::Windows::UI::Color> TermControl::TabColor() noexcept
|
||||
|
@ -2645,4 +2687,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
{
|
||||
return _core.ReadEntireBuffer();
|
||||
}
|
||||
|
||||
Core::Scheme TermControl::ColorScheme() const noexcept
|
||||
{
|
||||
return _core.ColorScheme();
|
||||
}
|
||||
|
||||
void TermControl::ColorScheme(const Core::Scheme& scheme) const noexcept
|
||||
{
|
||||
_core.ColorScheme(scheme);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
{
|
||||
struct TermControl : TermControlT<TermControl>
|
||||
{
|
||||
TermControl(IControlSettings settings, TerminalConnection::ITerminalConnection connection);
|
||||
TermControl(IControlSettings settings,
|
||||
Control::IControlAppearance unfocusedAppearance,
|
||||
TerminalConnection::ITerminalConnection connection);
|
||||
|
||||
winrt::fire_and_forget UpdateSettings();
|
||||
winrt::fire_and_forget UpdateAppearance(const IControlAppearance newAppearance);
|
||||
winrt::fire_and_forget UpdateControlSettings(Control::IControlSettings settings);
|
||||
winrt::fire_and_forget UpdateControlSettings(Control::IControlSettings settings, Control::IControlAppearance unfocusedAppearance);
|
||||
IControlSettings Settings() const;
|
||||
|
||||
hstring GetProfileName() const;
|
||||
|
||||
|
@ -88,9 +91,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||
const Windows::UI::Xaml::Thickness GetPadding();
|
||||
|
||||
IControlSettings Settings() const;
|
||||
void Settings(IControlSettings newSettings);
|
||||
|
||||
static Windows::Foundation::Size GetProposedDimensions(IControlSettings const& settings, const uint32_t dpi);
|
||||
static Windows::Foundation::Size GetProposedDimensions(IControlSettings const& settings, const uint32_t dpi, const winrt::Windows::Foundation::Size& initialSizeInChars);
|
||||
|
||||
|
@ -105,6 +105,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
hstring ReadEntireBuffer() const;
|
||||
|
||||
winrt::Microsoft::Terminal::Core::Scheme ColorScheme() const noexcept;
|
||||
void ColorScheme(const winrt::Microsoft::Terminal::Core::Scheme& scheme) const noexcept;
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
// clang-format off
|
||||
WINRT_CALLBACK(FontSizeChanged, Control::FontSizeChangedEventArgs);
|
||||
|
@ -127,8 +130,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
TYPED_EVENT(WarningBell, IInspectable, IInspectable);
|
||||
// clang-format on
|
||||
|
||||
WINRT_PROPERTY(IControlAppearance, UnfocusedAppearance);
|
||||
|
||||
private:
|
||||
friend struct TermControlT<TermControl>; // friend our parent so it can bind private event handlers
|
||||
|
||||
|
@ -146,7 +147,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
|
||||
winrt::com_ptr<SearchBoxControl> _searchBox;
|
||||
|
||||
IControlSettings _settings;
|
||||
bool _closing{ false };
|
||||
bool _focused{ false };
|
||||
bool _initializedTerminal{ false };
|
||||
|
@ -193,14 +193,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||
return _closing;
|
||||
}
|
||||
|
||||
void _UpdateSettingsFromUIThread(IControlSettings newSettings);
|
||||
void _UpdateAppearanceFromUIThread(IControlAppearance newAppearance);
|
||||
void _ApplyUISettings(const IControlSettings&);
|
||||
void _UpdateSettingsFromUIThread();
|
||||
void _UpdateAppearanceFromUIThread(Control::IControlAppearance newAppearance);
|
||||
void _ApplyUISettings();
|
||||
winrt::fire_and_forget UpdateAppearance(Control::IControlAppearance newAppearance);
|
||||
void _SetBackgroundImage(const IControlAppearance& newAppearance);
|
||||
|
||||
void _InitializeBackgroundBrush();
|
||||
void _BackgroundColorChangedHandler(const IInspectable& sender, const IInspectable& args);
|
||||
winrt::fire_and_forget _changeBackgroundColor(const til::color bg);
|
||||
winrt::fire_and_forget _coreBackgroundColorChanged(const IInspectable& sender, const IInspectable& args);
|
||||
void _changeBackgroundColor(const til::color bg);
|
||||
void _changeBackgroundOpacity();
|
||||
|
||||
bool _InitializeTerminal();
|
||||
void _SetFontSize(int fontSize);
|
||||
|
|
|
@ -17,14 +17,15 @@ namespace Microsoft.Terminal.Control
|
|||
ICoreState
|
||||
{
|
||||
TermControl(IControlSettings settings,
|
||||
IControlAppearance unfocusedAppearance,
|
||||
Microsoft.Terminal.TerminalConnection.ITerminalConnection connection);
|
||||
|
||||
static Windows.Foundation.Size GetProposedDimensions(IControlSettings settings, UInt32 dpi);
|
||||
|
||||
void UpdateSettings();
|
||||
void UpdateControlSettings(IControlSettings settings);
|
||||
void UpdateControlSettings(IControlSettings settings, IControlAppearance unfocusedAppearance);
|
||||
|
||||
Microsoft.Terminal.Control.IControlSettings Settings;
|
||||
Microsoft.Terminal.Control.IControlAppearance UnfocusedAppearance;
|
||||
Microsoft.Terminal.Control.IControlSettings Settings { get; };
|
||||
|
||||
event FontSizeChangedEventArgs FontSizeChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
|
||||
|
|
|
@ -50,6 +50,37 @@ namespace Microsoft.Terminal.Core
|
|||
UInt32 Value;
|
||||
};
|
||||
|
||||
struct Scheme
|
||||
{
|
||||
Microsoft.Terminal.Core.Color Foreground;
|
||||
Microsoft.Terminal.Core.Color Background;
|
||||
|
||||
Microsoft.Terminal.Core.Color SelectionBackground;
|
||||
|
||||
Microsoft.Terminal.Core.Color CursorColor;
|
||||
|
||||
// Table: A WinRT struct doesn't allow pointers (READ: doesn't allow
|
||||
// array members) in structs, but we very much would like this object to
|
||||
// be a struct. So we'll call out each color individually. There's only
|
||||
// 16, it's not that bad.
|
||||
Microsoft.Terminal.Core.Color Black;
|
||||
Microsoft.Terminal.Core.Color Red;
|
||||
Microsoft.Terminal.Core.Color Green;
|
||||
Microsoft.Terminal.Core.Color Yellow;
|
||||
Microsoft.Terminal.Core.Color Blue;
|
||||
Microsoft.Terminal.Core.Color Purple;
|
||||
Microsoft.Terminal.Core.Color Cyan;
|
||||
Microsoft.Terminal.Core.Color White;
|
||||
Microsoft.Terminal.Core.Color BrightBlack;
|
||||
Microsoft.Terminal.Core.Color BrightRed;
|
||||
Microsoft.Terminal.Core.Color BrightGreen;
|
||||
Microsoft.Terminal.Core.Color BrightYellow;
|
||||
Microsoft.Terminal.Core.Color BrightBlue;
|
||||
Microsoft.Terminal.Core.Color BrightPurple;
|
||||
Microsoft.Terminal.Core.Color BrightCyan;
|
||||
Microsoft.Terminal.Core.Color BrightWhite;
|
||||
};
|
||||
|
||||
declare
|
||||
{
|
||||
// Forward declare this parameterized specialization so that it lives
|
||||
|
|
|
@ -170,13 +170,14 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
|||
// - appearance: an ICoreAppearance with new settings values for us to use.
|
||||
void Terminal::UpdateAppearance(const ICoreAppearance& appearance)
|
||||
{
|
||||
_intenseIsBright = appearance.IntenseIsBright();
|
||||
_adjustIndistinguishableColors = appearance.AdjustIndistinguishableColors();
|
||||
|
||||
// Set the default background as transparent to prevent the
|
||||
// DX layer from overwriting the background image or acrylic effect
|
||||
til::color newBackgroundColor{ appearance.DefaultBackground() };
|
||||
_defaultBg = newBackgroundColor.with_alpha(0);
|
||||
_defaultFg = appearance.DefaultForeground();
|
||||
_intenseIsBright = appearance.IntenseIsBright();
|
||||
_adjustIndistinguishableColors = appearance.AdjustIndistinguishableColors();
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
|
@ -1290,3 +1291,67 @@ const size_t Microsoft::Terminal::Core::Terminal::GetTaskbarProgress() const noe
|
|||
{
|
||||
return _taskbarProgress;
|
||||
}
|
||||
|
||||
Scheme Terminal::GetColorScheme() const noexcept
|
||||
{
|
||||
Scheme s;
|
||||
|
||||
s.Foreground = til::color{ _defaultFg };
|
||||
// Don't leak the implementation detail that our _defaultBg is stored
|
||||
// internally without alpha.
|
||||
s.Background = til::color{ _defaultBg.with_alpha(0xff) };
|
||||
|
||||
// SelectionBackground is stored in the ControlAppearance
|
||||
s.CursorColor = til::color{ _buffer->GetCursor().GetColor() };
|
||||
|
||||
s.Black = til::color{ _colorTable[0] };
|
||||
s.Red = til::color{ _colorTable[1] };
|
||||
s.Green = til::color{ _colorTable[2] };
|
||||
s.Yellow = til::color{ _colorTable[3] };
|
||||
s.Blue = til::color{ _colorTable[4] };
|
||||
s.Purple = til::color{ _colorTable[5] };
|
||||
s.Cyan = til::color{ _colorTable[6] };
|
||||
s.White = til::color{ _colorTable[7] };
|
||||
s.BrightBlack = til::color{ _colorTable[8] };
|
||||
s.BrightRed = til::color{ _colorTable[9] };
|
||||
s.BrightGreen = til::color{ _colorTable[10] };
|
||||
s.BrightYellow = til::color{ _colorTable[11] };
|
||||
s.BrightBlue = til::color{ _colorTable[12] };
|
||||
s.BrightPurple = til::color{ _colorTable[13] };
|
||||
s.BrightCyan = til::color{ _colorTable[14] };
|
||||
s.BrightWhite = til::color{ _colorTable[15] };
|
||||
return s;
|
||||
}
|
||||
|
||||
void Terminal::ApplyScheme(const Scheme& colorScheme)
|
||||
{
|
||||
_defaultFg = colorScheme.Foreground;
|
||||
// Set the default background as transparent to prevent the
|
||||
// DX layer from overwriting the background image or acrylic effect
|
||||
til::color newBackgroundColor{ colorScheme.Background };
|
||||
_defaultBg = newBackgroundColor.with_alpha(0);
|
||||
|
||||
_colorTable[0] = til::color{ colorScheme.Black };
|
||||
_colorTable[1] = til::color{ colorScheme.Red };
|
||||
_colorTable[2] = til::color{ colorScheme.Green };
|
||||
_colorTable[3] = til::color{ colorScheme.Yellow };
|
||||
_colorTable[4] = til::color{ colorScheme.Blue };
|
||||
_colorTable[5] = til::color{ colorScheme.Purple };
|
||||
_colorTable[6] = til::color{ colorScheme.Cyan };
|
||||
_colorTable[7] = til::color{ colorScheme.White };
|
||||
_colorTable[8] = til::color{ colorScheme.BrightBlack };
|
||||
_colorTable[9] = til::color{ colorScheme.BrightRed };
|
||||
_colorTable[10] = til::color{ colorScheme.BrightGreen };
|
||||
_colorTable[11] = til::color{ colorScheme.BrightYellow };
|
||||
_colorTable[12] = til::color{ colorScheme.BrightBlue };
|
||||
_colorTable[13] = til::color{ colorScheme.BrightPurple };
|
||||
_colorTable[14] = til::color{ colorScheme.BrightCyan };
|
||||
_colorTable[15] = til::color{ colorScheme.BrightWhite };
|
||||
|
||||
_buffer->GetCursor().SetColor(til::color{ colorScheme.CursorColor });
|
||||
|
||||
if (_adjustIndistinguishableColors)
|
||||
{
|
||||
_MakeAdjustedColorArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace winrt::Microsoft::Terminal::Core
|
|||
{
|
||||
struct ICoreSettings;
|
||||
struct ICoreAppearance;
|
||||
struct Scheme;
|
||||
}
|
||||
|
||||
namespace Microsoft::Terminal::Core
|
||||
|
@ -214,6 +215,9 @@ public:
|
|||
const std::optional<til::color> GetTabColor() const noexcept;
|
||||
til::color GetDefaultBackground() const noexcept;
|
||||
|
||||
winrt::Microsoft::Terminal::Core::Scheme GetColorScheme() const noexcept;
|
||||
void ApplyScheme(const winrt::Microsoft::Terminal::Core::Scheme& scheme);
|
||||
|
||||
Microsoft::Console::Render::BlinkingState& GetBlinkingState() const noexcept;
|
||||
|
||||
const size_t GetTaskbarState() const noexcept;
|
||||
|
|
|
@ -350,7 +350,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
}
|
||||
|
||||
Profiles::Profiles() :
|
||||
_previewControl{ Control::TermControl(Model::TerminalSettings{}, make<PreviewConnection>()) }
|
||||
_previewControl{ Control::TermControl(Model::TerminalSettings{}, nullptr, make<PreviewConnection>()) }
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
|
@ -405,26 +405,23 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
|||
{
|
||||
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"CurrentScrollState" });
|
||||
}
|
||||
_previewControl.Settings(_State.Profile().TermSettings());
|
||||
_previewControl.UpdateSettings();
|
||||
_previewControl.UpdateControlSettings(_State.Profile().TermSettings());
|
||||
});
|
||||
|
||||
// The Appearances object handles updating the values in the settings UI, but
|
||||
// we still need to listen to the changes here just to update the preview control
|
||||
_AppearanceViewModelChangedRevoker = _State.Profile().DefaultAppearance().PropertyChanged(winrt::auto_revoke, [=](auto&&, const PropertyChangedEventArgs& /*args*/) {
|
||||
_previewControl.Settings(_State.Profile().TermSettings());
|
||||
_previewControl.UpdateSettings();
|
||||
_previewControl.UpdateControlSettings(_State.Profile().TermSettings());
|
||||
});
|
||||
|
||||
// Navigate to the pivot in the provided navigation state
|
||||
ProfilesPivot().SelectedIndex(static_cast<int>(_State.LastActivePivot()));
|
||||
|
||||
_previewControl.Settings(_State.Profile().TermSettings());
|
||||
// There is a possibility that the control has not fully initialized yet,
|
||||
// so wait for it to initialize before updating the settings (so we know
|
||||
// that the renderer is set up)
|
||||
_previewControl.Initialized([&](auto&& /*s*/, auto&& /*e*/) {
|
||||
_previewControl.UpdateSettings();
|
||||
_previewControl.UpdateControlSettings(_State.Profile().TermSettings());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -147,3 +147,30 @@ void ColorScheme::SetColorTableEntry(uint8_t index, const Core::Color& value) no
|
|||
THROW_HR_IF(E_INVALIDARG, index >= _table.size());
|
||||
_table[index] = value;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Core::Scheme ColorScheme::ToCoreScheme() const noexcept
|
||||
{
|
||||
winrt::Microsoft::Terminal::Core::Scheme coreScheme{};
|
||||
|
||||
coreScheme.Foreground = Foreground();
|
||||
coreScheme.Background = Background();
|
||||
coreScheme.CursorColor = CursorColor();
|
||||
coreScheme.SelectionBackground = SelectionBackground();
|
||||
coreScheme.Black = Table()[0];
|
||||
coreScheme.Red = Table()[1];
|
||||
coreScheme.Green = Table()[2];
|
||||
coreScheme.Yellow = Table()[3];
|
||||
coreScheme.Blue = Table()[4];
|
||||
coreScheme.Purple = Table()[5];
|
||||
coreScheme.Cyan = Table()[6];
|
||||
coreScheme.White = Table()[7];
|
||||
coreScheme.BrightBlack = Table()[8];
|
||||
coreScheme.BrightRed = Table()[9];
|
||||
coreScheme.BrightGreen = Table()[10];
|
||||
coreScheme.BrightYellow = Table()[11];
|
||||
coreScheme.BrightBlue = Table()[12];
|
||||
coreScheme.BrightPurple = Table()[13];
|
||||
coreScheme.BrightCyan = Table()[14];
|
||||
coreScheme.BrightWhite = Table()[15];
|
||||
return coreScheme;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
static com_ptr<ColorScheme> FromJson(const Json::Value& json);
|
||||
Json::Value ToJson() const;
|
||||
|
||||
winrt::Microsoft::Terminal::Core::Scheme ToCoreScheme() const noexcept;
|
||||
|
||||
com_array<Core::Color> Table() const noexcept;
|
||||
void SetColorTableEntry(uint8_t index, const Core::Color& value) noexcept;
|
||||
|
||||
|
|
|
@ -19,5 +19,7 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
// we expose the getter as a function.
|
||||
Microsoft.Terminal.Core.Color[] Table();
|
||||
void SetColorTableEntry(UInt8 index, Microsoft.Terminal.Core.Color value);
|
||||
|
||||
Microsoft.Terminal.Core.Scheme ToCoreScheme();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -206,59 +206,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
_Opacity = appearance.Opacity();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates a TerminalSettingsCreateResult from a parent TerminalSettingsCreateResult
|
||||
// - The returned defaultSettings inherits from the parent's defaultSettings, and the
|
||||
// returned unfocusedSettings inherits from the returned defaultSettings
|
||||
// - Note that the unfocused settings needs to be entirely unchanged _except_ we need to
|
||||
// set its parent to the other settings object that we return. This is because the overrides
|
||||
// made by the control will live in that other settings object, so we want to make
|
||||
// sure the unfocused settings inherit from that.
|
||||
// - Another way to think about this is that initially we have UnfocusedSettings inherit
|
||||
// from DefaultSettings. This function simply adds another TerminalSettings object
|
||||
// in the middle of these two, so UnfocusedSettings now inherits from the new object
|
||||
// and the new object inherits from the DefaultSettings. And this new object is what
|
||||
// the control can put overrides in.
|
||||
// Arguments:
|
||||
// - parent: the TerminalSettingsCreateResult that we create a new one from
|
||||
// Return Value:
|
||||
// - A TerminalSettingsCreateResult object that contains a defaultSettings that inherits
|
||||
// from parent's defaultSettings, and contains an unfocusedSettings that inherits from
|
||||
// its defaultSettings
|
||||
Model::TerminalSettingsCreateResult TerminalSettings::CreateWithParent(const Model::TerminalSettingsCreateResult& parent)
|
||||
{
|
||||
THROW_HR_IF_NULL(E_INVALIDARG, parent);
|
||||
|
||||
auto defaultImpl{ get_self<TerminalSettings>(parent.DefaultSettings()) };
|
||||
auto defaultChild = defaultImpl->CreateChild();
|
||||
if (parent.UnfocusedSettings())
|
||||
{
|
||||
parent.UnfocusedSettings().SetParent(*defaultChild);
|
||||
}
|
||||
return winrt::make<TerminalSettingsCreateResult>(*defaultChild, parent.UnfocusedSettings());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets our parent to the provided TerminalSettings
|
||||
// Arguments:
|
||||
// - parent: our new parent
|
||||
void TerminalSettings::SetParent(const Model::TerminalSettings& parent)
|
||||
{
|
||||
ClearParents();
|
||||
com_ptr<TerminalSettings> parentImpl;
|
||||
parentImpl.copy_from(get_self<TerminalSettings>(parent));
|
||||
InsertParent(parentImpl);
|
||||
}
|
||||
|
||||
Model::TerminalSettings TerminalSettings::GetParent()
|
||||
{
|
||||
if (_parents.size() > 0)
|
||||
{
|
||||
return *_parents.at(0);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Apply Profile settings, as well as any colors from our color scheme, if we have one.
|
||||
// Arguments:
|
||||
|
|
|
@ -64,12 +64,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
const Model::NewTerminalArgs& newTerminalArgs,
|
||||
const Control::IKeyBindings& keybindings);
|
||||
|
||||
static Model::TerminalSettingsCreateResult CreateWithParent(const Model::TerminalSettingsCreateResult& parent);
|
||||
|
||||
Model::TerminalSettings GetParent();
|
||||
|
||||
void SetParent(const Model::TerminalSettings& parent);
|
||||
|
||||
void ApplyColorScheme(const Model::ColorScheme& scheme);
|
||||
|
||||
// --------------------------- Core Settings ---------------------------
|
||||
|
@ -95,7 +89,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
INHERITABLE_SETTING(Model::TerminalSettings, uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT);
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS);
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, CopyOnSelect, false);
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, InputServiceWarning, true);
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, FocusFollowMouse, false);
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, TrimBlockSelection, false);
|
||||
INHERITABLE_SETTING(Model::TerminalSettings, bool, DetectURLs, true);
|
||||
|
|
|
@ -28,12 +28,16 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
|
||||
static TerminalSettingsCreateResult CreateWithProfile(CascadiaSettings appSettings, Profile profile, Microsoft.Terminal.Control.IKeyBindings keybindings);
|
||||
static TerminalSettingsCreateResult CreateWithNewTerminalArgs(CascadiaSettings appSettings, NewTerminalArgs newTerminalArgs, Microsoft.Terminal.Control.IKeyBindings keybindings);
|
||||
static TerminalSettingsCreateResult CreateWithParent(TerminalSettingsCreateResult parent);
|
||||
|
||||
void SetParent(TerminalSettings parent);
|
||||
TerminalSettings GetParent();
|
||||
void ApplyColorScheme(ColorScheme scheme);
|
||||
|
||||
ColorScheme AppliedColorScheme;
|
||||
|
||||
// The getters for these are already defined in IControlSettings. So
|
||||
// we're just adding the setters here, because TerminalApp likes to be
|
||||
// able to change these at runtime (e.g. when duplicating a pane).
|
||||
String Commandline { set; };
|
||||
String StartingDirectory { set; };
|
||||
String EnvironmentVariables { set; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace ControlUnitTests
|
|||
{
|
||||
Log::Comment(L"Create ControlCore object");
|
||||
|
||||
auto core = winrt::make_self<Control::implementation::ControlCore>(settings, conn);
|
||||
auto core = winrt::make_self<Control::implementation::ControlCore>(settings, settings, conn);
|
||||
core->_inUnitTests = true;
|
||||
return core;
|
||||
}
|
||||
|
@ -128,13 +128,14 @@ namespace ControlUnitTests
|
|||
double expectedOpacity = 0.5;
|
||||
auto opacityCallback = [&](auto&&, Control::TransparencyChangedEventArgs args) mutable {
|
||||
VERIFY_ARE_EQUAL(expectedOpacity, args.Opacity());
|
||||
VERIFY_ARE_EQUAL(expectedOpacity, settings->Opacity());
|
||||
VERIFY_ARE_EQUAL(expectedOpacity, core->_settings.Opacity());
|
||||
VERIFY_ARE_EQUAL(expectedOpacity, core->Opacity());
|
||||
// The Settings object's opacity shouldn't be changed
|
||||
VERIFY_ARE_EQUAL(0.5, settings->Opacity());
|
||||
|
||||
if (expectedOpacity < 1.0)
|
||||
{
|
||||
VERIFY_IS_TRUE(settings->UseAcrylic());
|
||||
VERIFY_IS_TRUE(core->_settings.UseAcrylic());
|
||||
VERIFY_IS_TRUE(core->_settings->UseAcrylic());
|
||||
}
|
||||
|
||||
// GH#603: Adjusting opacity shouldn't change whether or not we
|
||||
|
@ -142,8 +143,8 @@ namespace ControlUnitTests
|
|||
|
||||
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());
|
||||
VERIFY_ARE_EQUAL(expectedUseAcrylic, core->UseAcrylic());
|
||||
VERIFY_ARE_EQUAL(true, core->_settings->UseAcrylic());
|
||||
};
|
||||
core->TransparencyChanged(opacityCallback);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace ControlUnitTests
|
|||
TerminalConnection::ITerminalConnection conn)
|
||||
{
|
||||
Log::Comment(L"Create ControlInteractivity object");
|
||||
auto interactivity = winrt::make_self<Control::implementation::ControlInteractivity>(settings, conn);
|
||||
auto interactivity = winrt::make_self<Control::implementation::ControlInteractivity>(settings, settings, conn);
|
||||
VERIFY_IS_NOT_NULL(interactivity);
|
||||
auto core = interactivity->_core;
|
||||
core->_inUnitTests = true;
|
||||
|
@ -116,13 +116,14 @@ namespace ControlUnitTests
|
|||
double expectedOpacity = 0.5;
|
||||
auto opacityCallback = [&](auto&&, Control::TransparencyChangedEventArgs args) mutable {
|
||||
VERIFY_ARE_EQUAL(expectedOpacity, args.Opacity());
|
||||
VERIFY_ARE_EQUAL(expectedOpacity, settings->Opacity());
|
||||
VERIFY_ARE_EQUAL(expectedOpacity, core->_settings.Opacity());
|
||||
VERIFY_ARE_EQUAL(expectedOpacity, core->Opacity());
|
||||
// The Settings object's opacity shouldn't be changed
|
||||
VERIFY_ARE_EQUAL(0.5, settings->Opacity());
|
||||
|
||||
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());
|
||||
VERIFY_ARE_EQUAL(useAcrylic, settings->UseAcrylic());
|
||||
VERIFY_ARE_EQUAL(expectedUseAcrylic, core->UseAcrylic());
|
||||
};
|
||||
core->TransparencyChanged(opacityCallback);
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace ControlUnitTests
|
|||
WINRT_PROPERTY(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT);
|
||||
WINRT_PROPERTY(winrt::hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS);
|
||||
WINRT_PROPERTY(bool, CopyOnSelect, false);
|
||||
WINRT_PROPERTY(bool, InputServiceWarning, true);
|
||||
WINRT_PROPERTY(bool, FocusFollowMouse, false);
|
||||
|
||||
WINRT_PROPERTY(winrt::Windows::Foundation::IReference<winrt::Microsoft::Terminal::Core::Color>, TabColor, nullptr);
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
// --------------------------- Core Appearance ---------------------------
|
||||
// All of these settings are defined in ICoreAppearance.
|
||||
#define CORE_APPEARANCE_SETTINGS(X) \
|
||||
X(til::color, DefaultForeground, DEFAULT_FOREGROUND) \
|
||||
X(til::color, DefaultBackground, DEFAULT_BACKGROUND) \
|
||||
X(til::color, CursorColor, DEFAULT_CURSOR_COLOR) \
|
||||
X(winrt::Microsoft::Terminal::Core::CursorStyle, CursorShape, winrt::Microsoft::Terminal::Core::CursorStyle::Vintage) \
|
||||
X(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT) \
|
||||
X(bool, IntenseIsBright, true) \
|
||||
X(bool, AdjustIndistinguishableColors, true)
|
||||
|
||||
// --------------------------- Control Appearance ---------------------------
|
||||
// All of these settings are defined in IControlSettings.
|
||||
#define CONTROL_APPEARANCE_SETTINGS(X) \
|
||||
X(til::color, SelectionBackground, DEFAULT_FOREGROUND) \
|
||||
X(double, Opacity, 1.0) \
|
||||
X(winrt::hstring, BackgroundImage) \
|
||||
X(double, BackgroundImageOpacity, 1.0) \
|
||||
X(winrt::Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill) \
|
||||
X(winrt::Windows::UI::Xaml::HorizontalAlignment, BackgroundImageHorizontalAlignment, winrt::Windows::UI::Xaml::HorizontalAlignment::Center) \
|
||||
X(winrt::Windows::UI::Xaml::VerticalAlignment, BackgroundImageVerticalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment::Center) \
|
||||
X(bool, IntenseIsBold) \
|
||||
X(bool, RetroTerminalEffect, false) \
|
||||
X(winrt::hstring, PixelShaderPath)
|
||||
|
||||
// --------------------------- Core Settings ---------------------------
|
||||
// All of these settings are defined in ICoreSettings.
|
||||
#define CORE_SETTINGS(X) \
|
||||
X(int32_t, HistorySize, DEFAULT_HISTORY_SIZE) \
|
||||
X(int32_t, InitialRows, 30) \
|
||||
X(int32_t, InitialCols, 80) \
|
||||
X(bool, SnapOnInput, true) \
|
||||
X(bool, AltGrAliasing, true) \
|
||||
X(winrt::hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS) \
|
||||
X(bool, CopyOnSelect, false) \
|
||||
X(bool, FocusFollowMouse, false) \
|
||||
X(winrt::Windows::Foundation::IReference<winrt::Microsoft::Terminal::Core::Color>, TabColor, nullptr) \
|
||||
X(winrt::Windows::Foundation::IReference<winrt::Microsoft::Terminal::Core::Color>, StartingTabColor, nullptr) \
|
||||
X(bool, TrimBlockSelection, false) \
|
||||
X(bool, DetectURLs, true)
|
||||
|
||||
// --------------------------- Control Settings ---------------------------
|
||||
// All of these settings are defined in IControlSettings.
|
||||
#define CONTROL_SETTINGS(X) \
|
||||
X(winrt::hstring, ProfileName) \
|
||||
X(winrt::hstring, ProfileSource) \
|
||||
X(bool, UseAcrylic, false) \
|
||||
X(winrt::hstring, Padding, DEFAULT_PADDING) \
|
||||
X(winrt::hstring, FontFace, L"Consolas") \
|
||||
X(int32_t, FontSize, DEFAULT_FONT_SIZE) \
|
||||
X(winrt::Windows::UI::Text::FontWeight, FontWeight) \
|
||||
X(IFontFeatureMap, FontFeatures) \
|
||||
X(IFontAxesMap, FontAxes) \
|
||||
X(winrt::Microsoft::Terminal::Control::IKeyBindings, KeyBindings, nullptr) \
|
||||
X(winrt::hstring, Commandline) \
|
||||
X(winrt::hstring, StartingDirectory) \
|
||||
X(winrt::hstring, StartingTitle) \
|
||||
X(bool, SuppressApplicationTitle) \
|
||||
X(winrt::hstring, EnvironmentVariables) \
|
||||
X(winrt::Microsoft::Terminal::Control::ScrollbarState, ScrollState, winrt::Microsoft::Terminal::Control::ScrollbarState::Visible) \
|
||||
X(winrt::Microsoft::Terminal::Control::TextAntialiasingMode, AntialiasingMode, winrt::Microsoft::Terminal::Control::TextAntialiasingMode::Grayscale) \
|
||||
X(bool, ForceFullRepaintRendering, false) \
|
||||
X(bool, SoftwareRendering, false) \
|
||||
X(bool, ForceVTInput, false) \
|
||||
X(bool, UseAtlasEngine, false)
|
|
@ -324,9 +324,9 @@ void AtlasEngine::SetCallback(std::function<void()> pfn) noexcept
|
|||
_api.swapChainChangedCallback = std::move(pfn);
|
||||
}
|
||||
|
||||
void AtlasEngine::SetDefaultTextBackgroundOpacity(const float opacity) noexcept
|
||||
void AtlasEngine::EnableTransparentBackground(const bool isTransparent) noexcept
|
||||
{
|
||||
const auto mixin = opacity == 1.0f ? 0xff000000 : 0x00000000;
|
||||
const auto mixin = !isTransparent ? 0xff000000 : 0x00000000;
|
||||
if (_api.backgroundOpaqueMixin != mixin)
|
||||
{
|
||||
_api.backgroundOpaqueMixin = mixin;
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace Microsoft::Console::Render
|
|||
// DxRenderer - setter
|
||||
void SetAntialiasingMode(D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept override;
|
||||
void SetCallback(std::function<void()> pfn) noexcept override;
|
||||
void SetDefaultTextBackgroundOpacity(float opacity) noexcept override;
|
||||
void EnableTransparentBackground(const bool isTransparent) noexcept override;
|
||||
void SetForceFullRepaintRendering(bool enable) noexcept override;
|
||||
[[nodiscard]] HRESULT SetHwnd(HWND hwnd) noexcept override;
|
||||
void SetPixelShaderPath(std::wstring_view value) noexcept override;
|
||||
|
|
|
@ -88,7 +88,7 @@ DxEngine::DxEngine() :
|
|||
_forceFullRepaintRendering{ false },
|
||||
_softwareRendering{ false },
|
||||
_antialiasingMode{ D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE },
|
||||
_defaultTextBackgroundOpacity{ 1.0f },
|
||||
_defaultBackgroundIsTransparent{ true },
|
||||
_hwndTarget{ static_cast<HWND>(INVALID_HANDLE_VALUE) },
|
||||
_sizeTarget{},
|
||||
_dpi{ USER_DEFAULT_SCREEN_DPI },
|
||||
|
@ -911,7 +911,7 @@ void DxEngine::_ReleaseDeviceResources() noexcept
|
|||
// someone has chosen the slower ClearType antialiasing (versus the faster
|
||||
// grayscale antialiasing)
|
||||
const bool usingCleartype = _antialiasingMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
const bool usingTransparency = _defaultTextBackgroundOpacity != 1.0f;
|
||||
const bool usingTransparency = _defaultBackgroundIsTransparent;
|
||||
// Another way of naming "bgIsDefault" is "bgHasTransparency"
|
||||
const auto bgIsDefault = (_backgroundColor.a == _defaultBackgroundColor.a) &&
|
||||
(_backgroundColor.r == _defaultBackgroundColor.r) &&
|
||||
|
@ -1927,20 +1927,16 @@ CATCH_RETURN()
|
|||
const bool /*usingSoftFont*/,
|
||||
const bool isSettingDefaultBrushes) noexcept
|
||||
{
|
||||
// GH#5098: If we're rendering with cleartype text, we need to always render
|
||||
// onto an opaque background. If our background's opacity is 1.0f, that's
|
||||
// great, we can actually use cleartype in that case. In that scenario
|
||||
// (cleartype && opacity == 1.0), we'll force the opacity bits of the
|
||||
// COLORREF to 0xff so we draw as cleartype. In any other case, leave the
|
||||
// opacity bits unchanged. PaintBufferLine will later do some logic to
|
||||
// determine if we should paint the text as grayscale or not.
|
||||
const bool usingCleartype = _antialiasingMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
const bool usingTransparency = _defaultTextBackgroundOpacity != 1.0f;
|
||||
const bool forceOpaqueBG = usingCleartype && !usingTransparency;
|
||||
|
||||
const auto [colorForeground, colorBackground] = pData->GetAttributeColors(textAttributes);
|
||||
|
||||
const bool usingCleartype = _antialiasingMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
const bool usingTransparency = _defaultBackgroundIsTransparent;
|
||||
const bool forceOpaqueBG = usingCleartype && !usingTransparency;
|
||||
|
||||
_foregroundColor = _ColorFFromColorRef(OPACITY_OPAQUE | colorForeground);
|
||||
// October 2021: small changes were made to the way BG color interacts with
|
||||
// grayscale AA, esp. with regards to acrylic and GH#5098. See comment in
|
||||
// _ShouldForceGrayscaleAA for more details.
|
||||
_backgroundColor = _ColorFFromColorRef((forceOpaqueBG ? OPACITY_OPAQUE : 0) | colorBackground);
|
||||
|
||||
_d2dBrushForeground->SetColor(_foregroundColor);
|
||||
|
@ -2237,14 +2233,19 @@ CATCH_LOG()
|
|||
// rendering onto a transparent surface (like acrylic), then cleartype won't
|
||||
// work correctly, and will actually just additively blend with the
|
||||
// background. This is here to support GH#5098.
|
||||
// - We'll use this, along with whether cleartype was requested, to manually set
|
||||
// the alpha channel of the background brush to 1.0. We need to do that to
|
||||
// make cleartype work without blending. However, we don't want to do that too
|
||||
// often - if we do that on top of a transparent BG, then the entire swap
|
||||
// chain will be fully opaque.
|
||||
// Arguments:
|
||||
// - opacity: the new opacity of our background, on [0.0f, 1.0f]
|
||||
// - isTransparent: true if our BG is transparent (acrylic, or anything that's not fully opaque)
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void DxEngine::SetDefaultTextBackgroundOpacity(const float opacity) noexcept
|
||||
void DxEngine::EnableTransparentBackground(const bool isTransparent) noexcept
|
||||
try
|
||||
{
|
||||
_defaultTextBackgroundOpacity = opacity;
|
||||
_defaultBackgroundIsTransparent = isTransparent;
|
||||
|
||||
// Make sure we redraw all the cells, to update whether they're actually
|
||||
// drawn with cleartype or not.
|
||||
|
|
|
@ -128,7 +128,7 @@ namespace Microsoft::Console::Render
|
|||
|
||||
void SetSelectionBackground(const COLORREF color, const float alpha = 0.5f) noexcept override;
|
||||
void SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept override;
|
||||
void SetDefaultTextBackgroundOpacity(const float opacity) noexcept override;
|
||||
void EnableTransparentBackground(const bool isTransparent) noexcept override;
|
||||
void SetIntenseIsBold(const bool opacity) noexcept override;
|
||||
|
||||
void UpdateHyperlinkHoveredId(const uint16_t hoveredId) noexcept override;
|
||||
|
@ -257,7 +257,7 @@ namespace Microsoft::Console::Render
|
|||
|
||||
D2D1_TEXT_ANTIALIAS_MODE _antialiasingMode;
|
||||
|
||||
float _defaultTextBackgroundOpacity;
|
||||
bool _defaultBackgroundIsTransparent;
|
||||
bool _intenseIsBold;
|
||||
|
||||
// DirectX constant buffers need to be a multiple of 16; align to pad the size.
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace Microsoft::Console::Render
|
|||
// DxRenderer - setter
|
||||
virtual void SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept {}
|
||||
virtual void SetCallback(std::function<void()> pfn) noexcept {}
|
||||
virtual void SetDefaultTextBackgroundOpacity(const float opacity) noexcept {}
|
||||
virtual void EnableTransparentBackground(const bool isTransparent) noexcept {}
|
||||
virtual void SetForceFullRepaintRendering(bool enable) noexcept {}
|
||||
virtual [[nodiscard]] HRESULT SetHwnd(const HWND hwnd) noexcept { return E_NOTIMPL; }
|
||||
virtual void SetPixelShaderPath(std::wstring_view value) noexcept {}
|
||||
|
|
Loading…
Reference in New Issue