Panel split background ignores requestedTheme, follows system app mode #5513

Closed
opened 2026-01-31 00:15:08 +00:00 by claunia · 10 comments
Owner

Originally created by @dreadnaut on GitHub (Dec 11, 2019).

Originally assigned to: @zadjii-msft on GitHub.

Environment

Windows build number: 10.0.18362.476
Windows Terminal version (if applicable): 0.7.3382.0

Steps to reproduce

Have Windows configured in "light mode", and configure Terminal with requestedTheme set to dark. Split a tab in two or more panels.

Expected behavior

The split background should be dark, matching the tabs. The current panel is highlighted with the accent colour.

Actual behavior

The split background is light, matching the system theme (in particular the "app mode" setting), and ignores the requestedTheme Terminal setting. Next to a light grey line, the accent colour is less visible.

The opposite is also true: set windows to "dark mode", Terminal to "light mode", and the splits will follow the system settings.

image

Originally created by @dreadnaut on GitHub (Dec 11, 2019). Originally assigned to: @zadjii-msft on GitHub. # Environment ```none Windows build number: 10.0.18362.476 Windows Terminal version (if applicable): 0.7.3382.0 ``` # Steps to reproduce Have Windows configured in "light mode", and configure Terminal with `requestedTheme` set to `dark`. Split a tab in two or more panels. # Expected behavior The split background should be dark, matching the tabs. The current panel is highlighted with the accent colour. # Actual behavior The split background is light, matching the system theme (in particular the "app mode" setting), and ignores the `requestedTheme` Terminal setting. Next to a light grey line, the accent colour is less visible. The opposite is also true: set windows to "dark mode", Terminal to "light mode", and the splits will follow the system settings. ![image](https://user-images.githubusercontent.com/584584/70645288-9c0dff80-1c3c-11ea-948a-785e9c30e5c8.png)
Author
Owner

@zadjii-msft commented on GitHub (Dec 11, 2019):

Wow, yea it sure does. Thanks for the report!

@zadjii-msft commented on GitHub (Dec 11, 2019): Wow, yea it sure does. Thanks for the report!
Author
Owner

@dreadnaut commented on GitHub (Mar 1, 2020):

For reference:

@dreadnaut commented on GitHub (Mar 1, 2020): For reference: - colors are defined in [`App.xml > ThemeDictionaries`, ~line 41](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/App.xaml#L41) - pane borders are assigned in [`Pane.cpp#Pane::_SetupResources`, ~line 1510](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/Pane.cpp#L1510)
Author
Owner

@DHowett commented on GitHub (Nov 26, 2020):

I am assigning myself as a reminder: i have a long and sad e-mail thread with the Xaml team about this, and I need to summarize it to explain why we have so much trouble fixing this bug.

@DHowett commented on GitHub (Nov 26, 2020): I am assigning myself as a reminder: i have a long and sad e-mail thread with the Xaml team about this, and I need to summarize it to explain why we have so much trouble fixing this bug.
Author
Owner

@DHowett commented on GitHub (Dec 1, 2020):

@sweihub peddle your wares elsewhere.

@DHowett commented on GitHub (Dec 1, 2020): @sweihub peddle your wares elsewhere.
Author
Owner

@DHowett commented on GitHub (Dec 1, 2020):

This is the e-mail I sent to the Xaml folks (April 2, 2020)

Requested Themes, a saga

Windows Terminal is built as an application hosting a Xaml Island, with its own Windows.UI.Xaml.Application composed subclass.

Terminal also allows its users to select a light or a dark application theme independent of the active system theme.

The most straightforward way to do this and have it apply globally to the application is to set Application.RequestedTheme on startup.

Application.RequestedTheme(Dark)

Per the documentation, it is impossible to set an application’s requested theme after it’s been initialized. This means that Terminal will have to set RequestedTheme in its App’s constructor.

This works perfectly for applications that undergo normal CoreApplication activation: the composing parent class of App is initialized, registers itself with the framework, and RequestedTheme ends up being set before initialization has completed (and it’s locked out.)

In a Xaml island, however, one of two things happen:

  1. The App is initialized before the Xaml Island boots up its CoreWindow/Application integration

    1. The call to put_RequestedTheme fails with an access violation.

    2. This causes a crash.

  2. The App is initialized after Xaml Island startup

    1. WindowsXamlManager creates its own FrameworkApplication

    2. That application loads App.xbf

    3. The loading of an App.xbf locks out RequestedTheme()

    4. This causes an invalid argument HR/exception (depending on language)

Conclusion: It is impossible to set RequestedTheme in a Xaml Islands application.

How else could we set the theme?

ElementThemes

It is possible to set an ElementTheme on the root Page of an application. This works “alright” for Terminal, save for a couple issues ranging from minor to significant:

  • Dialogs do not live under the root Page of the application; they are presented in a different visual tree by the dialog API.
    • We try to set the ElementTheme on our dialogs, and this works:
    • Our dialogs mostly follow the ElementTheme we requested, except their primary buttons and context menus reflect the system/application theme, which we couldn’t change (#5195, #3654)
    • image
    • image
      • The primary button of the dialog is in that circle.
  • Terminal implements split panes as Grids containing Borders.
    • Those borders are either Accent or SystemChromeLow color.
    • We’re loading SystemChromeLow at runtime(1), because panes are not Xaml controls.
    • It appears that we’re unable to get the active ElementTheme version of SystemChromeLow because we’re using the Application’s resource dictionary, and that reflects the system/application theme (which we couldn’t change) (#3917)
    • image
      • To the left of the purple line should be a white line, not a gray one

1: what I wanted to ask was “is it possible for me to create a brush, or otherwise get something that will change color based on the theme of the element it’s placed inside, at runtime?”

 

Maybe we can fix the pane one by making it a Xaml control with visual states and theme resource dictionaries? It seemed like it would be a good idea to use visual states to indicate which pane was active and let Xaml handle switching the resources off for us anyway.

We ended up writing a Xaml fragment for the Border inside the pane, giving it theme resources and visual states, and letting it go.

It turns out that a Border cannot move between visual states because you cannot call GoToState on something that isn’t a Control.

We ended up putting the Grid in the Xaml fragment containing the Border as well.

It turns out that a Grid cannot move between visual states because you cannot call GoToState on something that isn’t a Control.

We ended up putting a UserControl around the entire thing, because that’s the only empty Control we could create, to house the Grid and the border. It’s now more complex than just making the controls at runtime.

And, after all that the issue still remains: the border has the wrong color when the application theme doesn’t match the system theme.

Conclusion: This is actually impossible.

The response:

So there may in fact be no answer here now for WinUI 2/XAML Islands v1.

@DHowett commented on GitHub (Dec 1, 2020): This is the e-mail I sent to the Xaml folks (April 2, 2020) ## Requested Themes, a saga Windows Terminal is built as an application hosting a Xaml Island, with its own Windows.UI.Xaml.Application composed subclass. Terminal *also* allows its users to select a light or a dark application theme independent of the active system theme. The most straightforward way to do this and have it apply globally to the application is to set **Application.RequestedTheme** on startup. ### Application.RequestedTheme(Dark) Per the [documentation], it is impossible to set an application’s requested theme after it’s been initialized. This means that Terminal will have to set RequestedTheme in its App’s constructor. This works perfectly for applications that undergo normal CoreApplication activation: the composing parent class of App is initialized, registers itself with the framework, and RequestedTheme ends up being set before initialization has completed (and it’s locked out.) In a Xaml island, however, one of two things happen: 1. The App is initialized before the Xaml Island boots up its CoreWindow/Application integration 1. The call to **put\_RequestedTheme** fails with an access violation. 2. This causes a crash. 2. The App is initialized **after** Xaml Island startup 1. WindowsXamlManager creates its own FrameworkApplication 2. That application loads **App.xbf** 3. The loading of an App.xbf locks out RequestedTheme() 4. This causes an invalid argument HR/exception (depending on language) **Conclusion**: It is impossible to set RequestedTheme in a Xaml Islands application. ## How else could we set the theme? ### ElementThemes It is possible to set an ElementTheme on the root Page of an application. This works “alright” for Terminal, save for a couple issues ranging from minor to significant: - Dialogs do not live under the root Page of the application; they are presented in a different visual tree by the dialog API. - We try to set the ElementTheme on our dialogs, and this works: - Our dialogs mostly follow the ElementTheme we requested, except their *primary buttons* and *context menus* reflect the system/application theme, which we couldn’t change (#5195, #3654) - ![image](https://user-images.githubusercontent.com/189190/100683824-f9a7ca00-332d-11eb-807a-7ab52a85cee5.png) - ![image](https://user-images.githubusercontent.com/189190/100683856-0a584000-332e-11eb-9334-5b3959c87002.png) - The primary button of the dialog is in that circle. - Terminal implements split panes as Grids containing Borders. - Those borders are either Accent or SystemChromeLow color. - We’re loading SystemChromeLow at runtime(1), because panes are not Xaml controls. - It appears that we’re unable to get the active ElementTheme version of SystemChromeLow because we’re using the Application’s resource dictionary, and that reflects the system/application theme (which we couldn’t change) (#3917) - ![image](https://user-images.githubusercontent.com/189190/100683868-117f4e00-332e-11eb-9aa5-bd9b4a955618.png) - To the left of the purple line should be a white line, not a gray one 1: what I wanted to ask was “is it possible for me to create a brush, or otherwise get something that will change color based on the theme of the element it’s placed inside, **at runtime**?”   Maybe we can fix the pane one by making it a Xaml control with visual states and theme resource dictionaries? It seemed like it would be a good idea to use visual states to indicate which pane was active and let Xaml handle switching the resources off for us anyway. We ended up writing a Xaml fragment for the Border inside the pane, giving it theme resources and visual states, and letting it go. *It turns out that a Border cannot move between visual states because you cannot call GoToState on something that isn’t a Control.* We ended up putting the Grid in the Xaml fragment containing the Border as well. *It turns out that a **Grid** cannot move between visual states because you cannot call GoToState on something that isn’t a Control.* We ended up putting a UserControl around the entire thing, because that’s the only empty Control we could create, to house the Grid and the border. It’s now more complex than just making the controls at runtime. *And*, after all that the issue still remains: the border has the wrong color when the application theme doesn’t match the system theme. **Conclusion**: This is actually impossible. [documentation]: https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.application.requestedtheme?view=winrt-19041 The response: > So there may in fact be no answer here now for WinUI 2/XAML Islands v1.
Author
Owner

@zadjii-msft commented on GitHub (Feb 10, 2022):

https://github.com/microsoft/terminal/issues/12356 has a variation of this bug. That one's a hotter fix, so I went with a hack to fix it. However, the branches for that issue have a lot of history that might be valuable.

@zadjii-msft commented on GitHub (Feb 10, 2022): https://github.com/microsoft/terminal/issues/12356 has a variation of this bug. That one's a hotter fix, so I went with a hack to fix it. However, the branches for that issue have a lot of history that might be valuable.
Author
Owner

@zadjii-msft commented on GitHub (Dec 2, 2022):

IF ONLY WE HAD A HELPER FOR GETTING A RESOURCE OUT OF THE RESOURCES FOR A SPECIFIC THEME

@zadjii-msft commented on GitHub (Dec 2, 2022): IF ONLY WE HAD A HELPER FOR GETTING A RESOURCE OUT OF THE RESOURCES FOR A SPECIFIC THEME
Author
Owner

@ghost commented on GitHub (Jan 24, 2023):

:tada:This issue was addressed in #14486, which has now been successfully released as Windows Terminal Preview v1.17.1023.🎉

Handy links:

@ghost commented on GitHub (Jan 24, 2023): :tada:This issue was addressed in #14486, which has now been successfully released as `Windows Terminal Preview v1.17.1023`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v1.17.1023) * [Store Download](https://www.microsoft.com/store/apps/9n8g5rfz9xk3?cid=storebadge&ocid=badge)
Author
Owner

@dreadnaut commented on GitHub (Jan 24, 2023):

Thank you all 🙇

@dreadnaut commented on GitHub (Jan 24, 2023): Thank you all 🙇
Author
Owner

@DHowett commented on GitHub (Jan 24, 2023):

Thank you all 🙇

Sorry it took literal years and us rewriting a large portion of the theming code to figure it out! :D

@DHowett commented on GitHub (Jan 24, 2023): > Thank you all 🙇 Sorry it took literal years and us rewriting a large portion of the theming code to figure it out! :D
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#5513