From dbf581182d60602d35b1e92a505483a78c1036cf Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Wed, 5 Aug 2026 01:56:52 +0200 Subject: [PATCH 1/5] New Ottosson Dark/Light themes --- doc/theme_colors.html | 646 ++++++++++++++++++ .../CascadiaSettingsSerialization.cpp | 7 + .../TerminalSettingsModel/defaults.json | 63 +- 3 files changed, 695 insertions(+), 21 deletions(-) create mode 100644 doc/theme_colors.html diff --git a/doc/theme_colors.html b/doc/theme_colors.html new file mode 100644 index 00000000000..3c9fe19e542 --- /dev/null +++ b/doc/theme_colors.html @@ -0,0 +1,646 @@ + + + + + + + Terminal Color Schemes + + + + + + +
+
+ + + + +
+
+ +
+ Add a scheme +
+ + + +
+
+ +
+
+ + + + + diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp index af32e4e955f..e1c199bd1c4 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp @@ -651,6 +651,13 @@ bool SettingsLoader::FixupUserSettings() auto fixedUp = userSettings.fixupsAppliedDuringLoad; fixedUp = userSettings.globals->FixupsAppliedDuringLoad() || fixedUp; + // Terminal 1.26: "Ottosson" was replaced by "Ottosson Dark" and "Ottosson Light". + // If the user kept a scheme of their own under the old name, it still resolves and we leave it alone. + if (const hstring ottosson{ L"Ottosson" }; !userSettings.colorSchemes.contains(ottosson)) + { + userSettings.colorSchemeRemappings.emplace(ottosson, hstring{ L"Ottosson Dark" }); + } + fixedUp = RemapColorSchemeForProfile(userSettings.baseLayerProfile) || fixedUp; for (const auto& profile : userSettings.profiles) { diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index 8971d3d3992..e9faae6a72f 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -40,7 +40,6 @@ "name": "Windows PowerShell", "commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "icon": "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png", - "colorScheme": "Campbell", "antialiasingMode": "grayscale", "closeOnExit": "automatic", "cursorShape": "bar", @@ -59,7 +58,6 @@ "name": "Command Prompt", "commandline": "%SystemRoot%\\System32\\cmd.exe", "icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png", - "colorScheme": "Campbell", "antialiasingMode": "grayscale", "closeOnExit": "automatic", "cursorShape": "bar", @@ -104,27 +102,50 @@ "brightWhite": "#DEE3E4" }, { - "name": "Ottosson", + "name": "Ottosson Dark", "background": "#000000", - "foreground": "#bebebe", - "cursorColor": "#ffffff", - "selectionBackground": "#92a4fd", + "foreground": "#D1D1D1", + "cursorColor": "#D1D1D1", + "selectionBackground": "#325D7A", "black": "#000000", - "red": "#be2c21", - "green": "#3fae3a", - "yellow": "#be9a4a", - "blue": "#204dbe", - "purple": "#bb54be", - "cyan": "#00a7b2", - "white": "#bebebe", - "brightBlack": "#808080", - "brightRed": "#ff3e30", - "brightGreen": "#58ea51", - "brightYellow": "#ffc944", - "brightBlue": "#2f6aff", - "brightPurple": "#fc74ff", - "brightCyan": "#00e1f0", - "brightWhite": "#ffffff" + "red": "#AE2A1D", + "green": "#009041", + "yellow": "#AD8900", + "blue": "#455AAE", + "purple": "#AE48A8", + "cyan": "#359DAE", + "white": "#D1D1D1", + "brightBlack": "#8D8D8D", + "brightRed": "#FF422F", + "brightGreen": "#00D463", + "brightYellow": "#FECA00", + "brightBlue": "#6887FF", + "brightPurple": "#FF6DF6", + "brightCyan": "#52E7FF", + "brightWhite": "#FFFFFF" + }, + { + "name": "Ottosson Light", + "background": "#FFFFFF", + "foreground": "#090909", + "cursorColor": "#090909", + "selectionBackground": "#C4EEFF", + "black": "#FFFFFF", + "red": "#AE2A1D", + "green": "#009041", + "yellow": "#AD8900", + "blue": "#455AAE", + "purple": "#AE48A8", + "cyan": "#359DAE", + "white": "#090909", + "brightBlack": "#3C3C3C", + "brightRed": "#FF422F", + "brightGreen": "#00D463", + "brightYellow": "#FECA00", + "brightBlue": "#6887FF", + "brightPurple": "#FF6DF6", + "brightCyan": "#52E7FF", + "brightWhite": "#000000" }, { "name": "Campbell", From 9a21260dc55b776943a82240a2e7043d667b03ec Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Wed, 5 Aug 2026 15:43:17 +0200 Subject: [PATCH 2/5] Improve Light, Optimize migration --- .github/actions/spelling/allow/names.txt | 2 +- doc/theme_colors.html | 19 +++++++++----- .../TerminalSettingsModel/CascadiaSettings.h | 2 +- .../CascadiaSettingsSerialization.cpp | 20 +++++++------- .../TerminalSettingsModel/defaults.json | 26 +++++++++---------- 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/.github/actions/spelling/allow/names.txt b/.github/actions/spelling/allow/names.txt index 1b52d13a22a..6d6554c4a84 100644 --- a/.github/actions/spelling/allow/names.txt +++ b/.github/actions/spelling/allow/names.txt @@ -40,7 +40,7 @@ niksa nvaccess nvda osgwiki -Ottosson +ottosson pabhojwa Panos paulcam diff --git a/doc/theme_colors.html b/doc/theme_colors.html index 3c9fe19e542..224212135cd 100644 --- a/doc/theme_colors.html +++ b/doc/theme_colors.html @@ -372,13 +372,18 @@ }; })(); - // Ideally, for the light theme we would darken all colors to give more contrast against the light background, - // but bright yellow with anything less than 0.86 lightness simply looks like shit. const ottossonLight = (() => { - const colors = ottossonDark.colors.slice(); + const colors = new Array(16); + // Darken all colors by 10% lightness (absolute). + for (const i in ottossonDark.colors) { + const c = ottossonDark.colors[i]; + colors[i] = new Color("oklch", [c.l - 0.1, c.c, c.h]); + } + + // ...except for grays, which are inverted. for (const i of [0, 7, 8, 15]) { - const c = colors[i]; + const c = ottossonDark.colors[i]; colors[i] = new Color("oklch", [1 - c.l, c.c, c.h]); } @@ -386,8 +391,10 @@ colors, background: colors[0], foreground: colors[7], - // 0.93 is in between the lightest color (0.86) and the background (1) - selectionBackground: new Color("oklch(0.93 0.068 240)"), + // l=0.86 at 240deg is already close to the gamut boundary. + // I wanted to brighten it further such that it looks lighter than any regular color (= distinct). + // To get it in-gamut at 0.93 (in between 0.86 and 1), I reduced the chroma by half. + selectionBackground: new Color("oklch(0.93 0.04 240)"), }; })(); diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettings.h b/src/cascadia/TerminalSettingsModel/CascadiaSettings.h index cebf8174df3..57d6b33abc1 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettings.h +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettings.h @@ -72,7 +72,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation std::vector> profiles; std::unordered_map> profilesByGuid; std::unordered_map> colorSchemes; - std::unordered_map colorSchemeRemappings; bool fixupsAppliedDuringLoad{ false }; std::set themesChangeLog; @@ -100,6 +99,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation ParsedSettings inboxSettings; ParsedSettings userSettings; std::unordered_map> extensionPackageMap; + std::unordered_map colorSchemeRemappings; bool duplicateProfile = false; bool sshProfilesGenerated = false; diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp index e1c199bd1c4..857728659e6 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp @@ -605,7 +605,7 @@ bool winrt::Microsoft::Terminal::Settings::Model::implementation::SettingsLoader { if (auto schemeName{ appearance.LightColorSchemeName() }; !schemeName.empty()) { - if (auto found{ userSettings.colorSchemeRemappings.find(schemeName) }; found != userSettings.colorSchemeRemappings.end()) + if (auto found{ colorSchemeRemappings.find(schemeName) }; found != colorSchemeRemappings.end()) { appearance.LightColorSchemeName(found->second); modified = true; @@ -614,7 +614,7 @@ bool winrt::Microsoft::Terminal::Settings::Model::implementation::SettingsLoader if (auto schemeName{ appearance.DarkColorSchemeName() }; !schemeName.empty()) { - if (auto found{ userSettings.colorSchemeRemappings.find(schemeName) }; found != userSettings.colorSchemeRemappings.end()) + if (auto found{ colorSchemeRemappings.find(schemeName) }; found != colorSchemeRemappings.end()) { appearance.DarkColorSchemeName(found->second); modified = true; @@ -648,16 +648,18 @@ bool SettingsLoader::FixupUserSettings() std::wstring_view{ L"ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png" }, }; - auto fixedUp = userSettings.fixupsAppliedDuringLoad; - fixedUp = userSettings.globals->FixupsAppliedDuringLoad() || fixedUp; - // Terminal 1.26: "Ottosson" was replaced by "Ottosson Dark" and "Ottosson Light". - // If the user kept a scheme of their own under the old name, it still resolves and we leave it alone. - if (const hstring ottosson{ L"Ottosson" }; !userSettings.colorSchemes.contains(ottosson)) + // Can be removed in ~1.28. + static winrt::param::hstring ottosson{ L"Ottosson" }; + static winrt::param::hstring ottossonDark{ L"Ottosson Dark" }; + if (!userSettings.colorSchemes.contains(ottosson)) { - userSettings.colorSchemeRemappings.emplace(ottosson, hstring{ L"Ottosson Dark" }); + colorSchemeRemappings.emplace(ottosson, ottossonDark); } + auto fixedUp = userSettings.fixupsAppliedDuringLoad; + fixedUp = userSettings.globals->FixupsAppliedDuringLoad() || fixedUp; + fixedUp = RemapColorSchemeForProfile(userSettings.baseLayerProfile) || fixedUp; for (const auto& profile : userSettings.profiles) { @@ -1161,7 +1163,7 @@ bool SettingsLoader::_addOrMergeUserColorScheme(const winrt::com_ptrName(newName); - userSettings.colorSchemeRemappings.emplace(newScheme->Name(), newName); + colorSchemeRemappings.emplace(newScheme->Name(), newName); // And re-add it to the end. userSettings.colorSchemes.emplace(newName, std::move(existingScheme)); return true; diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index e9faae6a72f..4dd50e9d768 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -129,22 +129,22 @@ "background": "#FFFFFF", "foreground": "#090909", "cursorColor": "#090909", - "selectionBackground": "#C4EEFF", + "selectionBackground": "#D1ECFF", "black": "#FFFFFF", - "red": "#AE2A1D", - "green": "#009041", - "yellow": "#AD8900", - "blue": "#455AAE", - "purple": "#AE48A8", - "cyan": "#359DAE", + "red": "#8B0000", + "green": "#007123", + "yellow": "#8D6B00", + "blue": "#2C3D8E", + "purple": "#8D2788", + "cyan": "#007F8F", "white": "#090909", "brightBlack": "#3C3C3C", - "brightRed": "#FF422F", - "brightGreen": "#00D463", - "brightYellow": "#FECA00", - "brightBlue": "#6887FF", - "brightPurple": "#FF6DF6", - "brightCyan": "#52E7FF", + "brightRed": "#DA0A00", + "brightGreen": "#00B343", + "brightYellow": "#DCAA00", + "brightBlue": "#4D68DC", + "brightPurple": "#DC4AD4", + "brightCyan": "#1CC6DE", "brightWhite": "#000000" }, { From b413e3558babda2b4b53a3f255dc7e97ab1a8914 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Wed, 5 Aug 2026 17:37:12 +0200 Subject: [PATCH 3/5] Improved contrast for grays --- doc/theme_colors.html | 103 ++++++++---------- .../TerminalSettingsModel/defaults.json | 32 +++--- 2 files changed, 64 insertions(+), 71 deletions(-) diff --git a/doc/theme_colors.html b/doc/theme_colors.html index 224212135cd..c878d14309f 100644 --- a/doc/theme_colors.html +++ b/doc/theme_colors.html @@ -308,13 +308,6 @@