Repository: microsoft/terminal (language: cpp)

Issue:
Light mode in settings UI only
# Description of the new feature/enhancement

Since my shells are all dark, it makes sense to use dark mode to get the dark title bar, however Windows' idea of dark mode design means the new settings UI is an eyesore. I would like to have the settings UI use light mode.


Discussion / hints:
Okay, sure. I'll slap this into the megathread for "theming", #3327. Something like `settingsUi.requestedTheme: light|dark|system`. Why not. 
> **Note**
> ## Walkthrough

* [ ] Start by adding a new Theme object for the settings UI:
  * [ ] `SettingsTheme` in `Theme.idl`, quite similar to `WindowTheme` in the same file
  * [ ] Add a single `ElementTheme RequestedTheme` to that `runtimeclass`. 
  * [ ] In `MTSMSettings.h`, define a new `MTSM_THEME_SETTINGS_SETTINGS`, again taking cues from the tab row version. The key for this one should just be `"settings"`
  * [ ] Add a `THEME_OBJECT(SettingsTheme, MTSM_THEME_SETTINGS_SETTINGS);` to `Theme.h`
  * [ ] Add the sui theme to the other places theme objects appear in Theme.cpp as well.
* [ ] Actually use this new setting
  * [ ] `MainPage::_UpdateBackgroundForMica` is probably the right place for this, as it's already trying to set the `RequestedTheme` for the settings page.
  * [ ] Instead, use the `settings.requestedTheme`, if it is set. 
Hello,

I am looking into this at the moment, but I hit a snag, where I am unsure if I should proceed or you might have some pointers to a better solution.

Just some background on my machine, I am running **Windows 11 Pro Version	10.0.22621 Build 22621**.
To make it work on my machine I had to remove the `isMicaAvailable` check in MainPage.cpp function ```::_UpdateBackgroundForMica()```. I tested to print out the value from the DwmGetWindowAttribute() and it always returns `DWMSBT_NONE`, therefore I removed the check for Mica.

I assume the `isMicaAvailable` check is there for a reason for backward compatibility?

Also I will remove the DebugOutputStringW() and the switch case, if we proceed with this.

> I assume the isMicaAvailable check is there for a reason for backward compatibility?

That was introduced in https://github.com/microsoft/terminal/pull/14675. That might have more context

(it's almost 5pm here so I can take a look deeper in the morning)

Fix patch:
diff --git a/src/cascadia/TerminalSettingsEditor/MainPage.cpp b/src/cascadia/TerminalSettingsEditor/MainPage.cpp
index ec48d7c7530..ea98ee83f12 100644
--- a/src/cascadia/TerminalSettingsEditor/MainPage.cpp
+++ b/src/cascadia/TerminalSettingsEditor/MainPage.cpp
@@ -699,17 +699,23 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
             }
         }
 
-        if (!isMicaAvailable)
-        {
-            return;
-        }
-
         const auto& theme = _settingsSource.GlobalSettings().CurrentTheme();
-        const auto& requestedTheme = _settingsSource.GlobalSettings().CurrentTheme().RequestedTheme();
+        const bool hasThemeForSettings{ theme.Settings() != nullptr };
+        const auto& appTheme = theme.RequestedTheme();
+        const auto& requestedTheme = (hasThemeForSettings) ? theme.Settings().RequestedTheme() : appTheme;
 
         RequestedTheme(requestedTheme);
 
-        const auto bgKey = (theme.Window() != nullptr && theme.Window().UseMica()) ?
+        // Mica gets it's appearance from the app's theme, not necessarily the
+        // Page's theme. In the case of dark app, light settings, mica will be a
+        // dark color, and the text will also be dark, making the UI _very_ hard
+        // to read. (and similarly in the inverse situation).
+        //
+        // To mitigate this, don't set the transparent background in the case
+        // that our theme is different than the app's.
+        const bool actuallyUseMica = isMicaAvailable && (appTheme == requestedTheme);
+
+        const auto bgKey = (theme.Window() != nullptr && theme.Window().UseMica()) && actuallyUseMica ?
                                L"SettingsPageMicaBackground" :
                                L"SettingsPageBackground";
 
diff --git a/src/cascadia/TerminalSettingsModel/MTSMSettings.h b/src/cascadia/TerminalSettingsModel/MTSMSettings.h
index f0e30684c53..95657d98d8e 100644
--- a/src/cascadia/TerminalSettingsModel/MTSMSettings.h
+++ b/src/cascadia/TerminalSettingsModel/MTSMSettings.h
@@ -136,9 +136,10 @@ Author(s):
 // * ForegroundKey, BackgroundKey, SelectionBackgroundKey, CursorColorKey: all optional colors
 // * Opacity: needs special parsing
 
-#define MTSM_THEME_SETTINGS(X)                                                             \
-    X(winrt::Microsoft::Terminal::Settings::Model::WindowTheme, Window, "window", nullptr) \
-    X(winrt::Microsoft::Terminal::Settings::Model::TabRowTheme, TabRow, "tabRow", nullptr) \
+#define MTSM_THEME_SETTINGS(X)                                                                   \
+    X(winrt::Microsoft::Terminal::Settings::Model::WindowTheme, Window, "window", nullptr)       \
+    X(winrt::Microsoft::Terminal::Settings::Model::SettingsTheme, Settings, "settings", nullptr) \
+    X(winrt::Microsoft::Terminal::Settings::Model::TabRowTheme, TabRow, "tabRow", nullptr)       \
     X(winrt::Microsoft::Terminal::Settings::Model::TabTheme, Tab, "tab", nullptr)
 
 #define MTSM_THEME_WINDOW_SETTINGS(X)                                                                                              \
@@ -148,6 +149,9 @@ Author(s):
     X(bool, RainbowFrame, "experimental.rainbowFrame", false)                                                                      \
     X(bool, UseMica, "useMica", false)
 
+#define MTSM_THEME_SETTINGS_SETTINGS(X) \
+    X(winrt::Windows::UI::Xaml::ElementTheme, RequestedTheme, "theme", winrt::Windows::UI::Xaml::ElementTheme::Default)
+
 #define MTSM_THEME_TABROW_SETTINGS(X)                                                             \
     X(winrt::Microsoft::Terminal::Settings::Model::ThemeColor, Background, "background", nullptr) \
     X(winrt::Microsoft::Terminal::Settings::Model::ThemeColor, UnfocusedBackground, "unfocusedBackground", nullptr)
diff --git a/src/cascadia/TerminalSettingsModel/Theme.cpp b/src/cascadia/TerminalSettingsModel/Theme.cpp
index 353f9df5992..52c283a7433 100644
--- a/src/cascadia/TerminalSettingsModel/Theme.cpp
+++ b/src/cascadia/TerminalSettingsModel/Theme.cpp
@@ -9,6 +9,7 @@
 #include "JsonUtils.h"
 #include "TerminalSettingsSerializationHelpers.h"
 
+#include "SettingsTheme.g.h"
 #include "ThemeColor.g.cpp"
 #include "WindowTheme.g.cpp"
 #include "TabRowTheme.g.cpp"
@@ -56,6 +57,7 @@ static constexpr wchar_t RegKeyAccentColor[] = L"AccentColor";
     }
 
 THEME_OBJECT(WindowTheme, MTSM_THEME_WINDOW_SETTINGS);
+THEME_OBJECT(SettingsTheme, MTSM_THEME_SETTINGS_SETTINGS);
 THEME_OBJECT(TabRowTheme, MTSM_THEME_TABROW_SETTINGS);
 THEME_OBJECT(TabTheme, MTSM_THEME_TAB_SETTINGS);
 
@@ -219,6 +221,7 @@ uint8_t ThemeColor::UnfocusedTabOpacity() const noexcept
     };
 
 THEME_OBJECT_CONVERTER(winrt::Microsoft::Terminal::Settings::Model, WindowTheme, MTSM_THEME_WINDOW_SETTINGS);
+THEME_OBJECT_CONVERTER(winrt::Microsoft::Terminal::Settings::Model, SettingsTheme, MTSM_THEME_SETTINGS_SETTINGS);
 THEME_OBJECT_CONVERTER(winrt::Microsoft::Terminal::Settings::Model, TabRowTheme, MTSM_THEME_TABROW_SETTINGS);
 THEME_OBJECT_CONVERTER(winrt::Microsoft::Terminal::Settings::Model, TabTheme, MTSM_THEME_TAB_SETTINGS);
 
@@ -251,6 +254,10 @@ winrt::com_ptr<Theme> Theme::Copy() const
     {
         theme->_Tab = *winrt::get_self<implementation::TabTheme>(_Tab)->Copy();
     }
+    if (_Settings)
+    {
+        theme->_Settings = *winrt::get_self<implementation::SettingsTheme>(_Settings)->Copy();
+    }
 
     return theme;
 }
diff --git a/src/cascadia/TerminalSettingsModel/Theme.h b/src/cascadia/TerminalSettingsModel/Theme.h
index ef0daa5d144..2c0ac139aa9 100644
--- a/src/cascadia/TerminalSettingsModel/Theme.h
+++ b/src/cascadia/TerminalSettingsModel/Theme.h
@@ -18,6 +18,7 @@ Author(s):
 
 #include "MTSMSettings.h"
 
+#include "SettingsTheme.g.h"
 #include "ThemeColor.g.h"
 #include "WindowTheme.g.h"
 #include "TabRowTheme.g.h"
@@ -81,6 +82,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
     };
 
     THEME_OBJECT(WindowTheme, MTSM_THEME_WINDOW_SETTINGS);
+    THEME_OBJECT(SettingsTheme, MTSM_THEME_SETTINGS_SETTINGS);
     THEME_OBJECT(TabRowTheme, MTSM_THEME_TABROW_SETTINGS);
     THEME_OBJECT(TabTheme, MTSM_THEME_TAB_SETTINGS);
 
diff --git a/src/cascadia/TerminalSettingsModel/Theme.idl b/src/cascadia/TerminalSettingsModel/Theme.idl
index 830bafef2a2..9cf0806f25d 100644
--- a/src/cascadia/TerminalSettingsModel/Theme.idl
+++ b/src/cascadia/TerminalSettingsModel/Theme.idl
@@ -53,6 +53,11 @@ namespace Microsoft.Terminal.Settings.Model
         UInt8 UnfocusedTabOpacity { get; };
     }
 
+    runtimeclass SettingsTheme
+    {
+        Windows.UI.Xaml.ElementTheme RequestedTheme { get; };
+    }
+
     runtimeclass WindowTheme {
         Windows.UI.Xaml.ElementTheme RequestedTheme { get; };
         Boolean UseMica { get; };
@@ -82,6 +87,9 @@ namespace Microsoft.Terminal.Settings.Model
         // window.* Namespace
         WindowTheme Window { get; };
 
+        // settings.* Namespace
+        SettingsTheme Settings { get; };
+            
         // tabRow.* Namespace
         TabRowTheme TabRow { get; };
 


Test patch: