Last active
March 5, 2026 14:12
-
-
Save DerekZiemba/deffec696f35768438d508fd3e2e9b1f to your computer and use it in GitHub Desktop.
[windows-11-taskbar-styler.wh.cpp] feat: extend taskbar styler with css style advanced selectors, custom theme, and performance improvements
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==WindhawkMod== | |
| // @id taskbar-stye-fork | |
| // @name Windows 11 Taskbar Styler - Fork - Fork | |
| // @description Customize the taskbar with themes contributed by others or create your own | |
| // @version 1.5.2 | |
| // @author m417z | |
| // @github https://gist.github.com/DerekZiemba/deffec696f35768438d508fd3e2e9b1f | |
| // @twitter https://twitter.com/m417z | |
| // @homepage https://m417z.com/ | |
| // @include explorer.exe | |
| // @architecture x86-64 | |
| // @compilerOptions -lcomctl32 -lole32 -loleaut32 -lruntimeobject -O2 -Wl,--export-all-symbols | |
| // ==/WindhawkMod== | |
| // Source code is published under The GNU General Public License v3.0. | |
| // | |
| // For bug reports and feature requests, please open an issue here: | |
| // https://github.com/ramensoftware/windhawk-mods/issues | |
| // | |
| // For pull requests, development takes place here: | |
| // https://gist.github.com/DerekZiemba/deffec696f35768438d508fd3e2e9b1f | |
| // https://github.com/m417z/my-windhawk-mods | |
| // ==WindhawkModReadme== | |
| /* | |
| # Windows 11 Taskbar Styler | |
| Customize the taskbar with themes contributed by others or create your own. | |
| Also check out the **Windows 11 Start Menu Styler**, **Windows 11 Notification | |
| Center Styler** mods. | |
| ## Themes | |
| Themes are collections of styles. The following themes are integrated into the | |
| mod and can be selected in the settings: | |
| [ | |
| \ | |
| TranslucentTaskbar](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/TranslucentTaskbar/README.md) | |
| [ | |
| \ | |
| DockLike](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/DockLike/README.md) | |
| [ | |
| \ | |
| SimplyTransparent](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/SimplyTransparent/README.md) | |
| [ | |
| \ | |
| Squircle](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Squircle/README.md) | |
| [ | |
| \ | |
| Matter](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Matter/README.md) | |
| [ | |
| \ | |
| WinXP](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/WinXP/README.md) | |
| [ | |
| \ | |
| Bubbles](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Bubbles/README.md) | |
| [ | |
| \ | |
| RosePine](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/RosePine/README.md) | |
| [ | |
| \ | |
| WinVista](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/WinVista/README.md) | |
| [ | |
| \ | |
| CleanSlate](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/CleanSlate/README.md) | |
| [ | |
| \ | |
| Lucent](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Lucent/README.md) | |
| [ | |
| \ | |
| SunValley](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/SunValley/README.md) | |
| [ | |
| \ | |
| SunValley | |
| (Legacy)](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/21996Taskbar/README.md) | |
| [ | |
| \ | |
| BottomDensy](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/BottomDensy/README.md) | |
| [ | |
| \ | |
| TaskbarXII](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/TaskbarXII/README.md) | |
| [ | |
| \ | |
| xdark](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/xdark/README.md) | |
| [ | |
| \ | |
| Windows7](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Windows7/README.md) | |
| [ | |
| \ | |
| Aeris](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Aeris/README.md) | |
| [ | |
| \ | |
| Plasma](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Plasma/README.md) | |
| [ | |
| \ | |
| WindowGlass](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/WindowGlass/README.md) | |
| [ | |
| \ | |
| Surface](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Surface/README.md) | |
| [ | |
| \ | |
| Oversimplified&Accentuated](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Oversimplified&Accentuated/README.md) | |
| [ | |
| \ | |
| Luminosity](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/Themes/Luminosity/README.md) | |
| More themes can be found in the **Themes** section of [The Windows 11 taskbar | |
| styling | |
| guide](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/README.md#themes). | |
| Contributions of new themes are welcome! | |
| ## Advanced styling | |
| Aside from themes, the settings have two sections: control styles and resource | |
| variables. Control styles allow to override styles, such as size and color, for | |
| the target elements. Resource variables allow to override predefined variables. | |
| For a more detailed explanation and examples, refer to the sections below. | |
| The taskbar's XAML resources can help find out which elements and resource | |
| variables can be customized. To the best of my knowledge, there are no public | |
| tools that are able to decode the resource files of recent Windows versions, but | |
| here are XAML resources which were obtained via other means for your | |
| convenience: [TaskbarResources.xbf and | |
| SystemTrayResources.xbf](https://gist.github.com/m417z/ad0ab39351aca905f1d186b1f1c3d8c7). | |
| The [UWPSpy](https://ramensoftware.com/uwpspy) tool can be used to inspect the | |
| taskbar's control elements in real time, and experiment with various styles. | |
| For a collection of commonly requested taskbar styling customizations, check out | |
| [The Windows 11 taskbar styling | |
| guide](https://github.com/ramensoftware/windows-11-taskbar-styling-guide/blob/main/README.md). | |
| ### Control styles | |
| Each entry has a target control and a list of styles. | |
| The target control is written as `Class` or `Class#Name`, i.e. the target | |
| control class name (the tag name in XAML resource files), such as | |
| `Taskbar.TaskListButton` or `Rectangle`, optionally followed by `#` and the | |
| target control's name (`x:Name` attribute in XAML resource files). The target | |
| control can also include: | |
| * Child control index, for example: `Class#Name[2]` will only match the relevant | |
| control that's also the second child among all of its parent's child controls. | |
| * Control properties, for example: | |
| `Class#Name[Property1=Value1][Property2=Value2]`. | |
| * Parent controls, separated by `>`, for example: `ParentClass#ParentName > | |
| Class#Name`. | |
| * Visual state group name, for example: `Class#Name@VisualStateGroupName`. It | |
| can be specified for the target control or for a parent control, but can be | |
| specified only once per target. The visual state group can be used in styles | |
| as specified below. | |
| **Note**: The target is evaluated only once. If, for example, the index or the | |
| properties of a control change, the target conditions aren't evaluated again. | |
| Each style is written as `Style=Value`, for example: `Height=5`. The `:=` syntax | |
| can be used to use XAML syntax, for example: `Fill:=<SolidColorBrush | |
| Color="Red"/>`. Specifying an empty value with the XAML syntax will clear the | |
| property value, for example: `Fill:=`. In addition, a visual state can be | |
| specified as following: `Style@VisualState=Value`, in which case the style will | |
| only apply when the visual state group specified in the target matches the | |
| specified visual state. | |
| For the XAML syntax, in addition to the built-in taskbar objects, the mod | |
| provides a built-in blur brush via the `WindhawkBlur` object, which supports the | |
| `BlurAmount`, `TintColor`, and `TintOpacity` properties. For example: | |
| `Fill:=<WindhawkBlur BlurAmount="10" TintColor="#80FF00FF"/>`. Theme resources | |
| are also supported, for example: `Fill:=<WindhawkBlur BlurAmount="18" | |
| TintColor="{ThemeResource SystemAccentColorDark1}" TintOpacity="0.5"/>`. | |
| Targets and styles starting with two slashes (`//`) are ignored. This can be | |
| useful for temporarily disabling a target or style. | |
| A couple of practical examples: | |
| #### Task list button corner radius | |
|  | |
| * Target: `Taskbar.TaskListButton` | |
| * Style: `CornerRadius=0` | |
| #### Running indicator size and color | |
|  | |
| * Target: `Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > | |
| Rectangle#RunningIndicator` | |
| * Styles: | |
| * `Fill=#FFED7014` | |
| * `Height=2` | |
| * `Width=12` | |
| * `Fill@ActiveRunningIndicator=Red` | |
| * `Width@ActiveRunningIndicator=20` | |
| #### Task list button background gradient | |
|  | |
| * Targets: | |
| * `Taskbar.TaskListButtonPanel > Border#BackgroundElement` | |
| * `Taskbar.TaskListLabeledButtonPanel > Border#BackgroundElement` | |
| * Style: `Background:=<LinearGradientBrush StartPoint="0.5,0" | |
| EndPoint="0.5,1"><GradientStop Offset="0" Color="DodgerBlue"/><GradientStop | |
| Offset="1" Color="Yellow"/></LinearGradientBrush>` | |
| #### Hide the start button | |
| * Target: | |
| `Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton]` | |
| * Style: `Visibility=Collapsed` | |
| #### Hide the network notification icon | |
| * Target: `SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > | |
| ItemsPresenter > StackPanel > ContentPresenter[1] > SystemTray.IconView > | |
| Grid > Grid` | |
| * Style: `Visibility=Collapsed` | |
| **Note**: To hide the volume notification icon instead, use `[2]` instead of | |
| `[1]`. | |
| ### Resource variables | |
| Some variables, such as size and padding for various controls, colors, and | |
| brushes, are defined as resource variables. You can override existing resources | |
| or define new theme-aware resources. | |
| #### Overriding existing resources | |
| Use `key=value` to override an existing resource, for example: | |
| * `TaskbarContextMenuMargin=4`: The margin between the taskbar and the start | |
| button context menu. | |
| * `ContextMenuMargin=8`: The margin between the taskbar and the tray area | |
| context menu. | |
| * `MediumTaskbarButtonExtent=48`: The width of the taskbar buttons. | |
| #### Defining theme-aware resources | |
| Use `Key@Dark=value` and `Key@Light=value` to define new resources with | |
| different values for dark and light themes. These can then be referenced in | |
| styles using `{ThemeResource key}`. | |
| For example, to define a custom accent color that automatically adjusts based on | |
| the system theme: | |
| ``` | |
| AutoAccent@Dark={ThemeResource SystemAccentColorDark1} | |
| AutoAccent@Light={ThemeResource SystemAccentColorLight2} | |
| ``` | |
| Then use it in a style: | |
| ``` | |
| Background:=<SolidColorBrush Color="{ThemeResource AutoAccent}" /> | |
| ``` | |
| The value will automatically update when the system accent color changes. | |
| ## XAML diagnostics consumer handling | |
| This mod uses XAML diagnostics to inspect and customize the taskbar. However, | |
| there can only be one XAML diagnostics consumer at a time. If another program | |
| (such as ExplorerBlurMica or TranslucentTB) tries to use XAML diagnostics while | |
| this mod is running, there will be a conflict. | |
| The **XAML diagnostics consumer handling** setting controls how this mod handles | |
| such conflicts: | |
| * **Alert**: When another program tries to use XAML diagnostics, a message box | |
| will appear asking whether to block it. This allows you to decide on a | |
| case-by-case basis. | |
| * **Block**: Automatically block other programs from using XAML diagnostics. | |
| This ensures this mod works correctly, but might break the other program. | |
| * **Allow**: Allow other programs to use XAML diagnostics. This might break this | |
| mod's styling, but allows the other program to work. | |
| ## Implementation notes | |
| The VisualTreeWatcher implementation is based on the | |
| [ExplorerTAP](https://github.com/TranslucentTB/TranslucentTB/tree/develop/ExplorerTAP) | |
| code from the **TranslucentTB** project. | |
| The `WindhawkBlur` brush object implementation is based on | |
| [XamlBlurBrush](https://github.com/TranslucentTB/TranslucentTB/blob/release/ExplorerTAP/XamlBlurBrush.cpp) | |
| from the **TranslucentTB** project. | |
| */ | |
| // ==/WindhawkModReadme== | |
| // ==WindhawkModSettings== | |
| /* | |
| - theme: "" | |
| $name: Theme | |
| $description: >- | |
| Themes are collections of styles. For details about the themes below, or for | |
| information about submitting your own theme, refer to the relevant section | |
| in the mod details. | |
| $options: | |
| - "": None | |
| - TranslucentTaskbar: TranslucentTaskbar | |
| - DockLike: DockLike | |
| - SimplyTransparent: SimplyTransparent | |
| - Squircle: Squircle | |
| - Matter: Matter | |
| - WinXP: WinXP | |
| - WinXP_variant_Zune: WinXP (Zune) | |
| - Bubbles: Bubbles | |
| - RosePine: RosePine | |
| - WinVista: WinVista | |
| - CleanSlate: CleanSlate | |
| - Lucent: Lucent (Accented Bar) | |
| - Lucent_variant_Light: Lucent (Light Bar) | |
| - SunValley: SunValley | |
| - 21996Taskbar: SunValley (Legacy) | |
| - BottomDensy: BottomDensy | |
| - BottomDensy_variant_NoInd: BottomDensy (NoInd) | |
| - TaskbarXII: TaskbarXII | |
| - xdark: xdark | |
| - Windows7: Windows7 | |
| - Aeris: Aeris | |
| - Plasma: Plasma | |
| - WindowGlass: WindowGlass | |
| - Surface: Surface | |
| - Oversimplified&Accentuated: Oversimplified&Accentuated | |
| - Luminosity_variant_Dock: Luminosity (Dock) | |
| - Luminosity_variant_Classic: Luminosity (Classic) | |
| - Luminosity_variant_Compact: Luminosity (Compact) | |
| - Derek: Derek's custom theme | |
| - controlStyles: | |
| - - target: "" | |
| $name: Target | |
| - styles: [""] | |
| $name: Styles | |
| $name: Control styles | |
| - styleConstants: [""] | |
| $name: Style constants | |
| $description: >- | |
| Constants which can be defined once and used in multiple styles. | |
| Each entry contains a style name and value, separated by '=', for example: | |
| mainColor=#fafad2 | |
| The constant can then be used in style definitions by prepending '$', for | |
| example: | |
| Fill=$mainColor | |
| Background:=<AcrylicBrush TintColor="$mainColor" TintOpacity="0.3" /> | |
| - themeResourceVariables: [""] | |
| $name: Resource variables | |
| $description: >- | |
| Use "Key=Value" to override an existing resource with a new value. | |
| Use "Key@Dark=Value" or "Key@Light=Value" to define theme-aware resources | |
| that can be referenced with {ThemeResource Key} in styles. | |
| - xamlDiagnosticsHandling: alert | |
| $name: XAML diagnostics consumer handling | |
| $description: >- | |
| How to handle other programs that try to use XAML diagnostics. There can | |
| only be one consumer at a time. Block will prevent other programs from using | |
| it, which might break them. Allow will let them use it, which might break | |
| this mod. | |
| $options: | |
| - alert: Alert (prompt before blocking) | |
| - block: Block other consumers | |
| - allow: Allow other consumers | |
| */ | |
| // ==/WindhawkModSettings== | |
| #define WIN32_LEAN_AND_MEAN | |
| #define NOMINMAX | |
| #define NOCRYPT | |
| #define NOSERVICE | |
| #define NOMCX | |
| #define NOHELP | |
| #include <atomic> | |
| #include <commctrl.h> | |
| #include <vector> | |
| #include <xamlom.h> | |
| #undef GetCurrentTime | |
| #include <stdlib.h> | |
| #include <winnt.h> | |
| #include <list> | |
| #include <mutex> | |
| #include <optional> | |
| // #include <sstream> | |
| #include <string> | |
| #include <string_view> | |
| #include <unordered_map> | |
| #include <unordered_set> | |
| #include <variant> | |
| #include <windhawk_utils.h> | |
| #include <winrt/Windows.UI.Xaml.h> | |
| struct ThemeTargetStyles { | |
| std::variant<PCWSTR, std::vector<PCWSTR>> target; // Single target or multiple targets | |
| std::vector<PCWSTR> styles; | |
| }; | |
| struct Theme { | |
| std::vector<ThemeTargetStyles> targetStyles; | |
| std::vector<PCWSTR> styleConstants; | |
| }; | |
| // clang-format off | |
| static const auto g_Themes = [] { | |
| const struct { | |
| const Theme TranslucentTaskbar = { | |
| { | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=$CommonBgBrush"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=$CommonBgBrush"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter > Border", { | |
| L"Background=$CommonBgBrush", | |
| L"BorderThickness=0,0,0,0", | |
| L"CornerRadius=14", | |
| L"Padding=3,4,3,4"}}, | |
| ThemeTargetStyles{L"Border#OverflowFlyoutBackgroundBorder", { | |
| L"Background=$CommonBgBrush", | |
| L"BorderThickness=0,0,0,0", | |
| L"CornerRadius=15", | |
| L"Margin=-2,-2,-2,-2"}}, | |
| ThemeTargetStyles{L"Grid#ConfirmatorMainGrid", { | |
| L"Background=$CommonBgBrush", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.TextInput.Common.InputSwitcher > ContentControl > ContentPresenter > Grid", { | |
| L"Background:=<WindhawkBlur BlurAmount=\"25\" TintColor=\"#25323232\"/>", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.TextInput.Common.InputSwitcher > ContentControl > ContentPresenter > Grid > Grid", { | |
| L"Background:=<SolidColorBrush Color=\"Transparent\"/>"}}, | |
| }, { | |
| L"CommonBgBrush=<WindhawkBlur BlurAmount=\"18\" TintColor=\"#25323232\"/>", | |
| }}; | |
| const Theme DockLike = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame", { | |
| L"Width=Auto", | |
| L"HorizontalAlignment=Center", | |
| L"Margin=250,0,250,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeAltHighColor}\" TintOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeLowColor}\" />", | |
| L"Padding=6,0,6,0", | |
| L"CornerRadius=8,8,0,0", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SurfaceStrokeColorDefault}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel", { | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeAltHighColor}\" TintOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeLowColor}\" />", | |
| L"Margin=-4,-8,-4,-8", | |
| L"CornerRadius=10", | |
| L"BorderThickness=12,12,12,12", | |
| L"BackgroundSizing=InnerBorderEdge"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"SystemTray.CopilotIcon", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > systemtray:IconView#SystemTrayIcon > Grid", { | |
| L"Padding=4,0,4,0"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Grid#ContainerGrid > ContentPresenter#ContentPresenter > Grid#ContentGrid > SystemTray.TextIconContent > Grid#ContainerGrid", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"SystemTray.StackListView#IconStack > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"Margin=0,-4,-12,-4"}}, | |
| ThemeTargetStyles{L"Taskbar.Gripper#GripperControl", { | |
| L"Width=Auto", | |
| L"MinWidth=24"}}, | |
| }}; | |
| const Theme SimplyTransparent = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Border#OverflowFlyoutBackgroundBorder", { | |
| L"Background=Transparent"}}, | |
| }}; | |
| const Theme Squircle = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=#CC222222"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"CornerRadius=5", | |
| L"Background:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" FallbackColor=\"#BB222222\" />", | |
| L"Background@InactivePointerOver:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" FallbackColor=\"#CC222222\" />", | |
| L"Background@ActivePointerOver:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.9\" FallbackColor=\"#CC222222\" />", | |
| L"Background@ActiveNormal:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" FallbackColor=\"#CC222222\" />", | |
| L"Background@InactiveNormal:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.7\" FallbackColor=\"#BB222222\" />", | |
| L"Background@InactivePressed:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" FallbackColor=\"#CC222222\" />", | |
| L"Background@ActivePressed:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" FallbackColor=\"#CC222222\" />"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" FallbackColor=\"#BB222222\"/>", | |
| L"CornerRadius=5", | |
| L"Margin=0,5,14,5", | |
| L"Padding=10,0,0,0"}}, | |
| ThemeTargetStyles{L"Rectangle#RunningIndicator", { | |
| L"Fill=Transparent", | |
| L"RadiusX=5", | |
| L"RadiusY=5", | |
| L"Height=38", | |
| L"Width=40"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > TextBlock#LabelControl", { | |
| L"Margin=4,0,0,0", | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton", { | |
| L"Foreground=White", | |
| L"Margin=-11,0,0,0"}}, | |
| ThemeTargetStyles{L"TextBlock#SearchBoxTextBlock", { | |
| L"FontSize=12", | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Grid", { | |
| L"RequestedTheme=2"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton[AutomationProperties.Name=Copilot] > Taskbar.TaskListLabeledButtonPanel#IconPanel > Border#BackgroundElement", { | |
| L"Background:=<AcrylicBrush TintColor=\"Red\" TintOpacity=\"0.8\" />"}}, | |
| ThemeTargetStyles{L"Border#BackgroundBorder", { | |
| L"Margin=0,3,0,3", | |
| L"CornerRadius=5"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Border#BackgroundElement@CommonStates", { | |
| L"Background@InactivePointerOver:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0\" />", | |
| L"Background:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" FallbackColor=\"#BB222222\" />"}}, | |
| ThemeTargetStyles{L"Border#MultiWindowElement", { | |
| L"Background:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" FallbackColor=\"#CC222222\" />"}}, | |
| ThemeTargetStyles{L"TextBlock#TimeInnerTextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"TextBlock#DateInnerTextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid > SystemTray.AdaptiveTextBlock#Base > TextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Border#BackgroundElement", { | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton", { | |
| L"Margin=-11,0,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.Name=Task View]", { | |
| L"Margin=-12,0,0,0"}}, | |
| ThemeTargetStyles{L"taskbar:TaskListLabeledButtonPanel@RunningIndicatorStates > Border", { | |
| L"Background@ActiveRunningIndicator:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" />", | |
| L"Background@InactiveRunningIndicator:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" />", | |
| L"Background@InactiveRunningIndicatorPointerOver:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"Background@InactivePointerOver:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#DD222222\"/>", | |
| L"Background@ActivePointerOver:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#EE222222\"/>", | |
| L"Background@InactiveNormal:=<AcrylicBrush TintOpacity=\"0.2\" TintColor=\"Black\" FallbackColor=\"#BB222222\"/>", | |
| L"Background@ActiveNormal:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#CC222222\"/>", | |
| L"Background@ActivePressed:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"#333333\" FallbackColor=\"#BB333333\" />", | |
| L"Background@InactivePressed:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"#333333\" FallbackColor=\"#BB333333\" />", | |
| L"CornerRadius=5", | |
| L"Margin=1"}}, | |
| }}; | |
| const Theme Squircle_variant_WeatherOnTheRight = {{ | |
| ThemeTargetStyles{L"Rectangle#BackgroundFill", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border#BackgroundElement", { | |
| L"Background@NoRunningIndicator:=<AcrylicBrush TintOpacity=\"0.2\" TintColor=\"#222222\" FallbackColor=\"#DD222222\" />", | |
| L"Background:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#DD222222\" />", | |
| L"Margin=0", | |
| L"BorderThickness@NoRunningIndicator=1", | |
| L"Background@InactiveRunningIndicator:=<AcrylicBrush TintOpacity=\"0.7\" TintColor=\"Black\" FallbackColor=\"#DD222222\" />", | |
| L"Background@ActiveRunningIndicator:=<AcrylicBrush TintOpacity=\"1\" TintColor=\"Black\" FallbackColor=\"#DD222222\" />"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#BB222222\" />", | |
| L"Margin=0,5,18,5", | |
| L"Padding=10,0,0,0", | |
| L"CornerRadius=5"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton", { | |
| L"Margin=0,-2,0,0"}}, | |
| ThemeTargetStyles{L"Border#MultiWindowElement", { | |
| L"Height=0"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#BB222222\" />"}}, | |
| ThemeTargetStyles{L"Grid", { | |
| L"RequestedTheme=2"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Border#BackgroundElement@CommonStates", { | |
| L"Background:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#BB222222\" />", | |
| L"Width=125", | |
| L"BorderBrush=Transparent"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid ", { | |
| L"Background:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#BB222222\" />", | |
| L"Padding=0", | |
| L"Margin=0,0,0,12", | |
| L"CornerRadius=5"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton > Taskbar.TaskListButtonPanel > Border", { | |
| L"Background:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#BB222222\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton", { | |
| L"Margin=20,1,-20,1"}}, | |
| ThemeTargetStyles{L"Grid#AugmentedEntryPointContentGrid", { | |
| L"Margin=10,0,-5,0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.Name=Task View] > Taskbar.TaskListButtonPanel > Border", { | |
| L"CornerRadius=0,5,5,0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton", { | |
| L"Background:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#BB333333\" />"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid > Border", { | |
| L"Opacity=0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid", { | |
| L"Background:=<AcrylicBrush TintOpacity=\"0.8\" TintColor=\"Black\" FallbackColor=\"#BB222222\" />", | |
| L"MinWidth=0", | |
| L"CornerRadius=0,5,5,0", | |
| L"Margin=0,4,2,4"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton#SearchBox > SearchUx.SearchUI.SearchButtonRootGrid@CommonStates > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"Margin=14,0,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.Name=Start] > Taskbar.TaskListButtonPanel > Border", { | |
| L"Margin=1,0,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.Name=Start] > Taskbar.TaskListButtonPanel", { | |
| L"RenderTransform:=<TranslateTransform X=\"5\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.Name=Task View] > Taskbar.TaskListButtonPanel", { | |
| L"RenderTransform:=<TranslateTransform X=\"-9\" />"}}, | |
| ThemeTargetStyles{L"Border#BackgroundBorder", { | |
| L"Margin=0,3,0,3"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<WindhawkBlur BlurAmount=\"12\" TintColor=\"#00000000\" />"}}, | |
| ThemeTargetStyles{L"Border#BackgroundElement", { | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"BorderBrush=Transparent", | |
| L"BorderBrush@ActivePointerOver:=<AcrylicBrush TintOpacity=\"0.2\" TintColor=\"Black\" FallbackColor=\"#DD222222\" />", | |
| L"BorderBrush@InactivePointerOver:=<AcrylicBrush TintOpacity=\"0.2\" TintColor=\"Black\" FallbackColor=\"#DD222222\" />", | |
| L"CornerRadius=5"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Rectangle#RunningIndicator", { | |
| L"Fill=Transparent", | |
| L"Fill@ActivePointerOver:=<AcrylicBrush TintOpacity=\"0.4\" TintColor=\"#88444444\" FallbackColor=\"#BB222222\" />", | |
| L"Fill@InactivePointerOver:=<AcrylicBrush TintOpacity=\"0.2\" TintColor=\"#88444444\" FallbackColor=\"#BB222222\" />", | |
| L"Fill@MultiWindowNormal=#22AAAABB", | |
| L"Fill@MultiWindowPointerOver=#88AAAABB", | |
| L"Fill@MultiWindowActive=#88AAAABB", | |
| L"Fill@MultiWindowPressed=#88AAAABB", | |
| L"Fill@RequestingAttention:=<SolidColorBrush Opacity=\"0.4\" Color=\"DarkOrange\" />", | |
| L"Fill@RequestingAttentionPointerOver:=<SolidColorBrush Opacity=\"0.4\" Color=\"Orange\" />", | |
| L"RadiusX=5", | |
| L"RadiusY=5", | |
| L"Height=38", | |
| L"Width=39", | |
| L"MinWidth=Auto"}}, | |
| }}; | |
| const Theme Matter = { | |
| { | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill := $transparent"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill := $transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl", { | |
| L"Fill:=$base", | |
| L"CornerRadius = $mainRadius"}}, | |
| ThemeTargetStyles{L" Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton", { | |
| L"Margin=-1,1,1,1"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"CornerRadius = $mainRadius", | |
| L"Background :=$base", | |
| L"Background@InactivePointerOver :=$overlay2", | |
| L"Background@ActivePointerOver:=$overlay", | |
| L"Background@ActiveNormal :=$active"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.Name=Task View]", { | |
| L"Margin=0,0,2,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton[AutomationProperties.Name=Copilot] > Taskbar.TaskListLabeledButtonPanel#IconPanel > Border#BackgroundElement", { | |
| L"Visibility = 1"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton", { | |
| L"Margin=0,0,2,0"}}, | |
| ThemeTargetStyles{L"Border#BackgroundElement", { | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"Background@InactiveNormal :=$base", | |
| L"Background@ActiveNormal :=$active", | |
| L"Background@InactivePointerOver :=$overlay2", | |
| L"Background@ActivePointerOver:=$overlay", | |
| L"CornerRadius = $mainRadius", | |
| L"Margin = 1,0,1,0", | |
| L"Background@MultiWindowNormal:=$base", | |
| L"Background@MultiWindowPointerOver:=$overlay2", | |
| L"Background@MultiWindowActive:=$active", | |
| L"Background@MultiWindowPressed:=$overlay"}}, | |
| ThemeTargetStyles{L"Border#MultiWindowElement", { | |
| L"CornerRadius = $mainRadius", | |
| L"Padding = 7,0,8,0", | |
| L"Background :=$accentColor"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > TextBlock#LabelControl", { | |
| L"Margin=0,0,2,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Rectangle#RunningIndicator", { | |
| L"Fill := $inverseBW", | |
| L"RadiusX=1.5", | |
| L"RadiusY=1.5", | |
| L"Height=4", | |
| L"Width=12", | |
| L"Fill@ActiveRunningIndicator :=$accentColor", | |
| L"Width@ActiveRunningIndicator=21"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=$base", | |
| L"CornerRadius = $mainRadius", | |
| L"Margin=0,5,12,5", | |
| L"Padding=5,0,0,0"}}, | |
| ThemeTargetStyles{L"Border#BackgroundBorder", { | |
| L"Margin=2,5,2,5", | |
| L"CornerRadius=8", | |
| L"BorderThickness = 0"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background:=$base", | |
| L"Shadow :=", | |
| L"CornerRadius = 14"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#HorizontalTrackRect", { | |
| L"Height = 8", | |
| L"Margin = 0", | |
| L"Fill := $overlay"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#HorizontalDecreaseRect", { | |
| L"Height = 8"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.TextBlock#volumeLevelText", { | |
| L"FontFamily = Tektur", | |
| L"Margin = 0,-2,0,0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#VolumeConfirmator", { | |
| L"Padding = 8,0,3,0", | |
| L"CornerRadius = 20"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ConfirmatorMainGrid", { | |
| L"Background :=$base", | |
| L"CornerRadius = 14", | |
| L"BorderThickness = 0", | |
| L"Margin = 0,0,0,10", | |
| L"Shadow :="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#BrightnessConfirmator", { | |
| L"Padding = 15,0,17,0", | |
| L"CornerRadius = 20"}}, | |
| ThemeTargetStyles{L"Microsoft.UI.Xaml.Controls.AnimatedIcon#BrightnessIcon", { | |
| L"Margin = 0,-1,12,0"}}, | |
| ThemeTargetStyles{L"Microsoft.UI.Xaml.Controls.ProgressBar#ProgressIndicator", { | |
| L"Margin = 0,0,0,1"}}, | |
| ThemeTargetStyles{L" Windows.UI.Xaml.Shapes.Rectangle#ProgressBarTrack", { | |
| L"Fill := $inverseBW", | |
| L"RadiusX = 1.5", | |
| L"RadiusY = 1.5"}}, | |
| ThemeTargetStyles{L" Windows.UI.Xaml.Shapes.Rectangle#DeterminateProgressBarIndicator", { | |
| L"Fill :=$accentColor"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton > Taskbar.TaskListLabeledButtonPanel#IconPanel > Microsoft.UI.Xaml.Controls.ProgressBar#ProgressIndicator", { | |
| L"MinHeight = 4", | |
| L"Width = 26"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ContentPresenter#ContentPresenter", { | |
| L"BorderThickness = 0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.Name=Start]", { | |
| L"Margin = 0,0,2,0"}}, | |
| ThemeTargetStyles{L"Taskbar.Badge#BadgeControl", { | |
| L"Height = 14", | |
| L"MinWidth = 14", | |
| L"Margin = 0,0,0,0", | |
| L"CornerRadius = 20"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#BackgroundRect", { | |
| L"RadiusX = 4", | |
| L"RadiusY = 4"}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter", { | |
| L"Background := $base", | |
| L"Shadow :=", | |
| L"CornerRadius = 8"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid@CommonStates > Border#BackgroundElement", { | |
| L"Background@InactiveNormal :=$base", | |
| L"CornerRadius = 8"}}, | |
| }, { | |
| L"mainRadius = 8", | |
| L"transparent = <SolidColorBrush Color=\"Transparent\"/>", | |
| L"base = <AcrylicBrush TintColor=\"{ThemeResource SystemAltLowColor}\" TintOpacity=\"1\" TintLuminosityOpacity=\"0.7\" FallbackColor=\"{ThemeResource SystemChromeLowColor}\" />", | |
| L"overlay = <AcrylicBrush TintColor=\"{ThemeResource SystemAltLowColor}\" TintOpacity=\"1\" TintLuminosityOpacity=\"0.8\" FallbackColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" />", | |
| L"overlay2 = <AcrylicBrush TintColor=\"{ThemeResource SystemAltLowColor}\" TintOpacity=\"1\" TintLuminosityOpacity=\"0.5\" FallbackColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" />", | |
| L"accentColor = <SolidColorBrush Color=\"{ThemeResource SystemAccentColor}\" Opacity = \"1\" />", | |
| L"inverseBW = <SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" Opacity = \"1\" />", | |
| L"active = <AcrylicBrush TintColor=\"{ThemeResource SystemAltLowColor}\" TintOpacity=\"1\" TintLuminosityOpacity=\"1\" FallbackColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" />", | |
| }}; | |
| const Theme WinXP = { | |
| { | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill:=<LinearGradientBrush StartPoint=\"0.5,0\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#3168d5\" Offset=\"0.0\" /> <GradientStop Color=\"#4993E6\" Offset=\"0.1\" /> <GradientStop Color=\"#2157D7\" Offset=\"0.35\" /> <GradientStop Color=\"#2663E0\" Offset=\"0.8\" /> <GradientStop Color=\"#1941A5\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"VerticalAlignment=Stretch", | |
| L"Height=Auto"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<LinearGradientBrush StartPoint=\"0.5,0\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#3168d5\" Offset=\"0.0\" /> <GradientStop Color=\"#4993E6\" Offset=\"0.1\" /> <GradientStop Color=\"#2157D7\" Offset=\"0.35\" /> <GradientStop Color=\"#2663E0\" Offset=\"0.8\" /> <GradientStop Color=\"#1941A5\" Offset=\"1.0\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton]", { | |
| L"CornerRadius=0", | |
| L"Margin=0,0,4,0", | |
| L"MaxWidth=48"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel", { | |
| L"Padding=0", | |
| L"Background:=<LinearGradientBrush StartPoint=\"0.5,0\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#388238\" Offset=\"0.0\" /> <GradientStop Color=\"#71B571\" Offset=\"0.1\" /> <GradientStop Color=\"#71B571\" Offset=\"0.35\" /> <GradientStop Color=\"#47AA47\" Offset=\"0.8\" /> <GradientStop Color=\"#307443\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"MaxWidth=48"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Border#BackgroundElement", { | |
| L"Background:=<ImageBrush Stretch=\"None\" ImageSource=\"https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/WinXP/Assets/orb.png\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"TextBlock#LabelControl", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Rectangle#RunningIndicator", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"TextBlock#TimeInnerTextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"TextBlock#DateInnerTextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid > SystemTray.AdaptiveTextBlock#Base > TextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border#BackgroundElement", { | |
| L"Background@NoRunningIndicator=Transparent", | |
| L"Background@ActiveRunningIndicator:=<LinearGradientBrush StartPoint=\"0.5,0\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#1B67D7\" Offset=\"0.0\" /> <GradientStop Color=\"#1542A8\" Offset=\"0.1\" /> <GradientStop Color=\"#1951BA\" Offset=\"0.15\" /> <GradientStop Color=\"#1951BA\" Offset=\"0.95\" /> <GradientStop Color=\"#1542A8\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"Background:=<LinearGradientBrush StartPoint=\"0.5,0\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#3358B5\" Offset=\"0.0\" /> <GradientStop Color=\"#8AC4FD\" Offset=\"0.1\" /> <GradientStop Color=\"#56A3FF\" Offset=\"0.2\" /> <GradientStop Color=\"#56A3FF\" Offset=\"0.85\" /> <GradientStop Color=\"#378DF6\" Offset=\"0.9\" /> <GradientStop Color=\"#163E95\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"BorderThickness@ActiveRunningIndicator=1", | |
| L"BorderBrush@NoRunningIndicator=Transparent", | |
| L"BorderBrush@ActiveRunningIndicator=#1B67D7", | |
| L"BorderBrush=#3358B5"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"Margin=-1.5"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=<LinearGradientBrush StartPoint=\"0.5,0\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#16ADF0\" Offset=\"0.0\" /> <GradientStop Color=\"#19B9F3\" Offset=\"0.1\" /> <GradientStop Color=\"#118FE9\" Offset=\"0.35\" /> <GradientStop Color=\"#0E9EF0\" Offset=\"0.8\" /> <GradientStop Color=\"#1580D9\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"BorderThickness=1,1,0,1", | |
| L"BorderBrush=#095BC9", | |
| L"Padding=4,0,0,0"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background:=<LinearGradientBrush StartPoint=\"0.5,0\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#3168d5\" Offset=\"0.0\" /> <GradientStop Color=\"#4993E6\" Offset=\"0.1\" /> <GradientStop Color=\"#2157D7\" Offset=\"0.35\" /> <GradientStop Color=\"#2663E0\" Offset=\"0.8\" /> <GradientStop Color=\"#1941A5\" Offset=\"1.0\" /></LinearGradientBrush>"}}, | |
| } | |
| }; | |
| const Theme WinXP_variant_Zune = {{ | |
| ThemeTargetStyles{L"Rectangle#BackgroundFill", { | |
| L"Fill:=<LinearGradientBrush StartPoint=\"0.5,0.5\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#656565\" Offset=\"0.0\" /> <GradientStop Color=\"#363636\" Offset=\"0.1\" /> <GradientStop Color=\"#363636\" Offset=\"0.35\" /> <GradientStop Color=\"#363636\" Offset=\"0.8\" /> <GradientStop Color=\"#363636\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"VerticalAlignment=Stretch", | |
| L"Height=Auto"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton]", { | |
| L"CornerRadius=0", | |
| L"Margin=-4,0,4,0", | |
| L"MaxWidth=48"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel", { | |
| L"Padding=0", | |
| L"Background:=<LinearGradientBrush StartPoint=\"0.5,0.5\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#D76A27\" Offset=\"0.05\" /> <GradientStop Color=\"#B44704\" Offset=\"0.1\" /> <GradientStop Color=\"#772E01\" Offset=\"0.5\" /> <GradientStop Color=\"#772E01\" Offset=\"1\" /> <GradientStop Color=\"#AA4201\" Offset=\"1\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Border#BackgroundElement", { | |
| L"Background:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/WinXP/Assets/orb.png\" />", | |
| L"Height=32"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"TextBlock#LabelControl", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Rectangle#RunningIndicator", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"TextBlock#TimeInnerTextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"TextBlock#DateInnerTextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid > SystemTray.AdaptiveTextBlock#Base > TextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border#BackgroundElement", { | |
| L"Background@ActiveRunningIndicator:=<LinearGradientBrush StartPoint=\"0.5,0.5\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#6B6B6B\" Offset=\"0.0\" /> <GradientStop Color=\"#434343\" Offset=\"0.1\" /> <GradientStop Color=\"#434343\" Offset=\"0.35\" /> <GradientStop Color=\"#434343\" Offset=\"0.8\" /> <GradientStop Color=\"#434343\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"Background:=<LinearGradientBrush StartPoint=\"0.5,0.5\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#6B6B6B\" Offset=\"0.0\" /> <GradientStop Color=\"#434343\" Offset=\"0.1\" /> <GradientStop Color=\"#434343\" Offset=\"0.35\" /> <GradientStop Color=\"#434343\" Offset=\"0.8\" /> <GradientStop Color=\"#434343\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"BorderThickness=1", | |
| L"BorderBrush@NoRunningIndicator=Transparent", | |
| L"CornerRadius=3"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border", { | |
| L"BorderThickness=1", | |
| L"CornerRadius=2", | |
| L"BorderBrush@NoRunningIndicator=Transparent", | |
| L"Margin=-2,-1,-2,-1"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border#BackgroundElement", { | |
| L"BorderBrush=#BB4B4B4B", | |
| L"Margin=1", | |
| L"BorderThickness=1", | |
| L"Background:=<LinearGradientBrush StartPoint=\"0.5,0.42\" EndPoint=\"0.5,0.75\"> <GradientStop Color=\"#6B6B6B\" Offset=\"0.0\" /> <GradientStop Color=\"#363636\" Offset=\"0.5\" /> <GradientStop Color=\"#363636\" Offset=\"0.35\" /> <GradientStop Color=\"#363636\" Offset=\"0.8\" /> <GradientStop Color=\"#363636\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"BorderBrush@NoRunningIndicator=Transparent", | |
| L"Background@NoRunningIndicator=Transparent"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill=#858585"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=<LinearGradientBrush StartPoint=\"0.5,0.42\" EndPoint=\"0.5,0.75\"> <GradientStop Color=\"#454545\" Offset=\"0.0\" /> <GradientStop Color=\"#313131\" Offset=\"0.5\" /> <GradientStop Color=\"#363636\" Offset=\"0.35\" /> <GradientStop Color=\"#1D1D1D\" Offset=\"0.8\" /> <GradientStop Color=\"#1D1D1D\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"BorderThickness=1,0,0,0", | |
| L"BorderBrush=#222222", | |
| L"Padding=4,0,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton > Taskbar.TaskListLabeledButtonPanel#IconPanel@RunningIndicatorStates > Windows.UI.Xaml.Controls.Image#Icon", { | |
| L"Height@NoRunningIndicator=16"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton > Taskbar.TaskListLabeledButtonPanel#IconPanel@RunningIndicatorStates", { | |
| L"Margin@NoRunningIndicator=-7,0,-7,0", | |
| L"Padding@NoRunningIndicator=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"Margin=-1.5"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background:=<LinearGradientBrush StartPoint=\"0.5,0.5\" EndPoint=\"0.5,1\"> <GradientStop Color=\"#656565\" Offset=\"0.0\" /> <GradientStop Color=\"#363636\" Offset=\"0.1\" /> <GradientStop Color=\"#363636\" Offset=\"0.35\" /> <GradientStop Color=\"#363636\" Offset=\"0.8\" /> <GradientStop Color=\"#363636\" Offset=\"1.0\" /></LinearGradientBrush>"}}, | |
| }}; | |
| const Theme Bubbles = {{ | |
| ThemeTargetStyles{L"Rectangle#BackgroundFill", { | |
| L"Fill:=<SolidColorBrush x:Name=\"SystemChromeLow\" Color=\"{ThemeResource SystemChromeLowColor}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border#BackgroundElement", { | |
| L"CornerRadius=20", | |
| L"Background@NoRunningIndicator:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.18\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"Background:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.15\" Color=\"{ThemeResource SearchPillButtonForeground}\" />", | |
| L"BorderThickness=1.5", | |
| L"BorderBrush:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.25\" Color=\"{ThemeResource SearchPillButtonForeground}\" />", | |
| L"BorderThickness@NoRunningIndicator=1", | |
| L"BorderBrush@NoRunningIndicator:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.15\" Color=\"{ThemeResource SearchPillButtonForeground}\" />", | |
| L"Margin=1"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"Background:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.3\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"BorderBrush:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.6\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"Background@ActivePointerOver:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.8\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"Background@InactivePointerOver:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.8\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"Background@ActivePressed:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"1\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"Background@InactivePressed:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"1\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"BorderBrush@InactivePressed:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.8\" Color=\"{ThemeResource SystemAccentColor}\" />", | |
| L"CornerRadius=20", | |
| L"BorderThickness@InactivePressed=3", | |
| L"BorderThickness=2"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.6\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"CornerRadius=20", | |
| L"Margin=-5,5,8,5", | |
| L"Padding=10,0,-10,0", | |
| L"BorderBrush:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.9\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"BorderThickness=1.5"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Rectangle#RunningIndicator", { | |
| L"Stroke@InactivePointerOver=#75A8E6", | |
| L"Stroke@InactivePressed=#7CB1F2", | |
| L"Stroke@ActiveNormal=#5F87B9", | |
| L"Stroke@ActivePointerOver=#75A8E6", | |
| L"Stroke@ActivePressed=#7CB1F2", | |
| L"Fill=Transparent", | |
| L"RadiusX=20", | |
| L"RadiusY=20", | |
| L"StrokeThickness=3", | |
| L"Stroke@MultiWindowPointerOver=#CCCCDD", | |
| L"Stroke@MultiWindowPressed=White", | |
| L"Stroke@MultiWindowActive=#BBBBCC", | |
| L"Fill@MultiWindowNormal=#88AAAABB", | |
| L"Fill@MultiWindowPointerOver=#88AAAABB", | |
| L"Fill@MultiWindowActive=#88AAAABB", | |
| L"Fill@MultiWindowPressed=#88AAAABB", | |
| L"Stroke@RequestingAttention=Crimson", | |
| L"Stroke@RequestingAttentionPointerOver=Red", | |
| L"Fill@RequestingAttention:=<SolidColorBrush Opacity=\"0.4\" Color=\"DarkOrange\" />", | |
| L"Fill@RequestingAttentionPointerOver:=<SolidColorBrush Opacity=\"0.4\" Color=\"Orange\" />", | |
| L"StrokeThickness@RequestingAttention=2.5", | |
| L"StrokeThickness@RequestingAttentionPointerOver=2.5", | |
| L"Height=39", | |
| L"Width=39", | |
| L"MinWidth=Auto"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > TextBlock#LabelControl", { | |
| L"Margin=4,0,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton", { | |
| L"Height=48", | |
| L"Margin=0,-2,0,0"}}, | |
| ThemeTargetStyles{L"Border#MultiWindowElement", { | |
| L"Height=0"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.8\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"BorderBrush:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.1\" Color=\"{ThemeResource SearchPillButtonForeground}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"Margin=1,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"Padding=5,0,5,0", | |
| L"Margin=2,0,10,0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#ShowDesktopPipe", { | |
| L"MinWidth=4", | |
| L"RadiusX=2", | |
| L"RadiusY=2", | |
| L"Margin=-5,0,5,0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NotifyIconStack > Windows.UI.Xaml.Controls.Grid > SystemTray.StackListView > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.ChevronIconView > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=16,5,5,16", | |
| L"Margin=-3,4,0,4"}}, | |
| ThemeTargetStyles{L"TextBlock#InnerTextBlock", { | |
| L"Foreground:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Color=\"{ThemeResource SearchPillButtonForeground}\" />"}}, | |
| ThemeTargetStyles{L"TextBlock#LabelControl", { | |
| L"Foreground:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Color=\"{ThemeResource SearchPillButtonForeground}\" />"}}, | |
| ThemeTargetStyles{L"TextBlock#TimeInnerTextBlock", { | |
| L"Foreground:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Color=\"{ThemeResource SearchPillButtonForeground}\" />", | |
| L"Margin=0,2.5,0,-2.5"}}, | |
| ThemeTargetStyles{L"TextBlock#DateInnerTextBlock", { | |
| L"Foreground:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Color=\"{ThemeResource SearchPillButtonForeground}\" />", | |
| L"Margin=0,-1,0,2"}}, | |
| ThemeTargetStyles{L"Grid#ContainerGrid@ > Border#BackgroundBorder ", { | |
| L"Background@PointerOver:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.2\" Color=\"{ThemeResource SearchPillButtonForeground}\" />", | |
| L"CornerRadius=20", | |
| L"Margin=-1", | |
| L"Height=28", | |
| L"Width=28", | |
| L"BorderBrush=Transparent"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView > Grid#ContainerGrid@ > Border#BackgroundBorder", { | |
| L"CornerRadius=20", | |
| L"Background@PointerOver:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.15\" Color=\"{ThemeResource SearchPillButtonForeground}\" />", | |
| L"Height=34", | |
| L"Width=34"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Grid@CommonStates > Border#BackgroundBorder", { | |
| L"CornerRadius=20", | |
| L"Width=75", | |
| L"Margin=-2,1,-2,1", | |
| L"Background@PointerOver:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.15\" Color=\"{ThemeResource SearchPillButtonForeground}\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid@CommonStates > Border#BackgroundBorder", { | |
| L"CornerRadius=20", | |
| L"Background@PointerOver:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.15\" Color=\"{ThemeResource SearchPillButtonForeground}\" />", | |
| L"Margin=1"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton > Taskbar.TaskListButtonPanel@CommonStates ", { | |
| L"Background:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.6\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"BorderBrush:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.9\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"BorderThickness=1.5", | |
| L"Margin=5", | |
| L"Background@InactivePointerOver:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"1\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"Padding=-1.5,-1,-1.5,-1", | |
| L"CornerRadius=20"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid ", { | |
| L"Background:=<SolidColorBrush x:Name=\"SystemChromeHigh\" Opacity=\"0.5\" Color=\"{ThemeResource SystemChromeHighColor}\" />", | |
| L"Padding=0", | |
| L"Margin=0,0,0,12", | |
| L"CornerRadius=8"}}, | |
| ThemeTargetStyles{L"Rectangle#LeftDropInsertionMarker", { | |
| L"Fill:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />"}}, | |
| ThemeTargetStyles{L"Rectangle#RightDropInsertionMarker", { | |
| L"Fill:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton > Taskbar.TaskListButtonPanel > Border", { | |
| L"CornerRadius=20", | |
| L"Background:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.15\" Color=\"{ThemeResource SearchPillButtonForeground}\" />", | |
| L"BorderBrush:=<SolidColorBrush x:Name=\"SearchBoxTextBlock\" Opacity=\"0.25\" Color=\"{ThemeResource SearchPillButtonForeground}\" />"}}, | |
| }}; | |
| const Theme RosePine = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"CornerRadius=3"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > TextBlock#InnerTextBlock", { | |
| L"FontSize=16"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"MinWidth=25"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter[1] > SystemTray.IconView > Grid > Grid", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid#ContainerGrid", { | |
| L"Padding=2"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"MinWidth=27"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon > Grid > Grid > SystemTray.TextIconContent", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Border#BackgroundElement", { | |
| L"Background:=#302d47", | |
| L"CornerRadius=6"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=#302d47", | |
| L"CornerRadius=6", | |
| L"Margin=0,5,4,4", | |
| L"Padding=3,0,-8,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Rectangle#RunningIndicator", { | |
| L"Height=27", | |
| L"RadiusX=5", | |
| L"RadiusY=5", | |
| L"StrokeThickness=2", | |
| L"Stroke@InactivePointerOver=#ebbcba", | |
| L"Stroke@InactivePressed=#ebbcba", | |
| L"Stroke@ActiveNormal=#ebbcba", | |
| L"Stroke@ActivePointerOver=#ebbcba", | |
| L"Stroke@ActivePressed=#ebbcba", | |
| L"Fill=Transparent", | |
| L"Width=37", | |
| L"VerticalAlignment=1", | |
| L"Canvas.ZIndex=1"}}, | |
| ThemeTargetStyles{L"SystemTray.ImageIconContent > Grid#ContainerGrid > Image", { | |
| L"Width=13"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > TextBlock#InnerTextBlock", { | |
| L"FontSize=14"}}, | |
| ThemeTargetStyles{L"TextBlock#LabelControl", { | |
| L"FontFamily=JetBrainsMono NF", | |
| L"Foreground=#e0def4", | |
| L"Padding=2,0,8,0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton]", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock[Text=\uE971]", { | |
| L"Text=\uE712"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=#302d47"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Border#BackgroundElement", { | |
| L"Background=#302d47"}}, | |
| ThemeTargetStyles{L"TextBlock#DateInnerTextBlock", { | |
| L"Margin=0,0,0,-2"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background=#302d47"}}, | |
| }}; | |
| const Theme WinVista = {{ | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton", { | |
| L"CornerRadius=2"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton", { | |
| L"CornerRadius=2"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"CornerRadius=2"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Rectangle#RunningIndicator", { | |
| L"Height=2", | |
| L"Width@ActiveRunningIndicator=30", | |
| L"Width@InactiveRunningIndicator=8", | |
| L"Fill@ActiveRunningIndicator=#00BEE0", | |
| L"Fill@InactiveRunningIndicator=#DDDDDD"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundFill", { | |
| L"Fill:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\" Opacity=\"0.7\"><GradientStop Color=\"#B5B9BC\" Offset=\"0.0\" /><GradientStop Color=\"#B5B9BC\" Offset=\"0.03125\" /><GradientStop Color=\"#909296\" Offset=\"0.03125\" /><GradientStop Color=\"#464B51\" Offset=\"0.5\" /><GradientStop Color=\"#060F15\" Offset=\"0.5\" /><GradientStop Color=\"#040C11\" Offset=\"0.96875\" /><GradientStop Color=\"#000000\" Offset=\"0.96875\" /><GradientStop Color=\"#000000\" Offset=\"1.0\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border", { | |
| L"Background@ActiveRunningIndicator:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\" Opacity=\"0.2\"><GradientStop Color=\"#111111\" Offset=\"0.0\" /><GradientStop Color=\"#111111\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"CornerRadius=2", | |
| L"Background@RequestingAttentionRunningIndicator:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\" Opacity=\"0.2\"><GradientStop Color=\"#D53300\" Offset=\"0.0\" /><GradientStop Color=\"#111111\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"BorderBrush=#33101010", | |
| L"BorderThickness=1", | |
| L"BorderBrush@NoRunningIndicator=Transparent", | |
| L"Background@NoRunningIndicator=Transparent", | |
| L"Background@ActiveRunningIndicator=#55BBBBBB", | |
| L"BorderBrush@ActiveRunningIndicator=#55212121"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"Margin=0,0,0,2", | |
| L"BorderThickness=1", | |
| L"Background@ActivePointerOver=#88DDDDDD", | |
| L"Background@ActiveNormal=#33BBBBBB", | |
| L"Background@InactivePointerOver=#33BBBBBB", | |
| L"BorderBrush@ActiveNormal=#44AAAAAA", | |
| L"BorderBrush@ActivePointerOver=#FF888888", | |
| L"BorderBrush@InactiveNormal=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > TextBlock", { | |
| L"FontFamily=Segoe UI"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#LanguageInnerTextBlock > TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe UI"}}, | |
| ThemeTargetStyles{L"TextBlock#TimeInnerTextBlock", { | |
| L"FontFamily=Segoe UI"}}, | |
| ThemeTargetStyles{L"Grid", { | |
| L"RequestedTheme=2"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#BackgroundControl > Grid", { | |
| L"Background:=<AcrylicBrush TintColor=\"Transparent\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.1\" Opacity=\"1\" />"}}, | |
| ThemeTargetStyles{L"Border#MultiWindowElement", { | |
| L"Background=#BB212121", | |
| L"BorderThickness=0", | |
| L"Margin=0,2,1,4"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\" Opacity=\"0.7\"><GradientStop Color=\"#B5B9BC\" Offset=\"0.0\" /><GradientStop Color=\"#B5B9BC\" Offset=\"0.03125\" /><GradientStop Color=\"#909296\" Offset=\"0.03125\" /><GradientStop Color=\"#464B51\" Offset=\"0.5\" /><GradientStop Color=\"#060F15\" Offset=\"0.5\" /><GradientStop Color=\"#040C11\" Offset=\"0.96875\" /><GradientStop Color=\"#000000\" Offset=\"0.96875\" /><GradientStop Color=\"#000000\" Offset=\"1.0\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid", { | |
| L"Background:=<AcrylicBrush TintColor=\"Transparent\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.1\" Opacity=\"1\" />", | |
| L"Padding=-1", | |
| L"Margin=0,6,0,6", | |
| L"CornerRadius=8"}}, | |
| }}; | |
| const Theme CleanSlate = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark1}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"CornerRadius=100", | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"Background@InactivePointerOver:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\"/>", | |
| L"Background@ActivePointerOver:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.6\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"Background@ActiveNormal:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.6\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\"/>", | |
| L"Background@InactivePressed:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.6\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"Background@ActivePressed:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" />"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.5\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"CornerRadius=5", | |
| L"Margin=0,5,5,5", | |
| L"Padding=1,0,-10,0"}}, | |
| ThemeTargetStyles{L"Rectangle#RunningIndicator", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > TextBlock#LabelControl", { | |
| L"Margin=8,0,0,0", | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton ", { | |
| L"Padding=8", | |
| L"Margin=4,0,4,0"}}, | |
| ThemeTargetStyles{L"TextBlock#SearchBoxTextBlock", { | |
| L"FontSize=12"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton[AutomationProperties.Name=Copilot] > Taskbar.TaskListLabeledButtonPanel#IconPanel > Border#BackgroundElement", { | |
| L"Background:=<AcrylicBrush TintColor=\"Black\" TintOpacity=\"0.8\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView > Grid > Border#BackgroundBorder", { | |
| L"Margin=0,3,0,3"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Border#BackgroundElement@CommonStates", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"CornerRadius=20", | |
| L"Margin=0,1,0,1"}}, | |
| ThemeTargetStyles{L"TextBlock#TimeInnerTextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"TextBlock#DateInnerTextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid > SystemTray.AdaptiveTextBlock#Base > TextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Border#BackgroundElement", { | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border#BackgroundElement", { | |
| L"Background@InactiveRunningIndicator:=<SolidColorBrush Color=\"Black\" Opacity=\"0.4\" />", | |
| L"Background@InactiveRunningIndicator:=<SolidColorBrush Color=\"Black\" Opacity=\"0.4\" />", | |
| L"Background@ActiveRunningIndicator:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorDark2}\" Opacity=\"0.4\" />", | |
| L"Background@RequestingAttentionRunningIndicator:=<SolidColorBrush Color=\"#ffdf5e\" Opacity=\"0.4\" />"}}, | |
| ThemeTargetStyles{L"Rectangle#ShowDesktopPipe", { | |
| L"Width=12", | |
| L"Height=38", | |
| L"Margin=-6,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"Width=12"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel", { | |
| L"Margin=-3,0,0,0"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark1}\" />", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColor}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid > Border", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark3}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark1}\" />", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColor}\" />", | |
| L"BorderThickness=1", | |
| L"CornerRadius=5"}}, | |
| ThemeTargetStyles{L"Border#ProgressBarRoot > Border > Grid > Rectangle", { | |
| L"Fill:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />"}}, | |
| ThemeTargetStyles{L"Border#ProgressBarRoot > Border > Grid > Rectangle#ProgressBarTrack", { | |
| L"Fill:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorDark3}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"BorderBrush@InactivePointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />", | |
| L"BorderBrush@ActiveNormal:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\" />", | |
| L"BorderBrush@ActivePointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />", | |
| L"BorderBrush@MultiWindowPointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />", | |
| L"BorderThickness@ActiveNormal=1", | |
| L"BorderThickness@ActivePointerOver=1", | |
| L"BorderThickness@MultiWindowActive=2", | |
| L"BorderThickness@MultiWindowNormal=2", | |
| L"BorderThickness@MultiWindowPointerOver=2.5", | |
| L"BorderBrush@MultiWindowActive:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />", | |
| L"BorderBrush@MultiWindowNormal:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />", | |
| L"Margin@MultiWindowNormal=0", | |
| L"Margin@MultiWindowPointerOver=0", | |
| L"Margin@MultiWindowPressed=0"}}, | |
| ThemeTargetStyles{L"ToolTip", { | |
| L"Background:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Border#MultiWindowElement", { | |
| L"Background=Transparent", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton > Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"CornerRadius=5", | |
| L"CornerRadius@InactiveNormal_SearchIcon=100", | |
| L"CornerRadius@InactivePointerOver_SearchIcon=100", | |
| L"CornerRadius@InactivePressed_SearchIcon=100", | |
| L"CornerRadius@ActiveNormal_SearchIcon=100", | |
| L"CornerRadius@ActivePointerOver_SearchIcon=100", | |
| L"CornerRadius@ActivePressed_SearchIcon=100", | |
| L"Background@InactiveNormal_SearchIcon:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"Background@InactivePointerOver_SearchIcon:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark1}\" />", | |
| L"Background@InactivePressed_SearchIcon:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark1}\" />", | |
| L"Background@ActiveNormal_SearchIcon:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"Background@ActivePointerOver_SearchIcon:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark1}\" />", | |
| L"Background@ActivePressed_SearchIcon:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark1}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.OverflowToggleButton", { | |
| L"Margin=8,0,8,0", | |
| L"Background:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorDark2}\" />"}}, | |
| ThemeTargetStyles{L"Rectangle#RightOverflowButtonDivider", { | |
| L"Fill:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\" />", | |
| L"Margin=8,4,-8,4"}}, | |
| ThemeTargetStyles{L"Taskbar.OverflowToggleButton > Taskbar.TaskListButtonPanel@CommonStates > Border", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"Background@InactivePointerOver:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark1}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel", { | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchIconButton > SearchUx.SearchUI.SearchButtonRootGrid@CommonStates > Border#BackgroundElement", { | |
| L"CornerRadius=100", | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid", { | |
| L"Margin=0,0,3,0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid > Border#BackgroundElement", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />"}}, | |
| ThemeTargetStyles{L"Border#SearchPillBackgroundElement", { | |
| L"BorderBrush:=<AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark2}\" TintOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />", | |
| L"BorderThickness=16", | |
| L"CornerRadius=8"}}, | |
| }}; | |
| const Theme Lucent = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#00000000\" Offset=\"0.3\" /><GradientStop Color=\"#AA000000\" Offset=\"0.9\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<LinearGradientBrush StartPoint=\"0,0.5\" EndPoint=\"0,1\"><GradientStop Color=\"#ee000000\" Offset=\"0.1\" /><GradientStop Color=\"{ThemeResource SystemAccentColorDark2}\" Offset=\"0.9\" /><GradientStop Color=\"#AAFFFFFF\" Offset=\"1.0\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Rectangle#RunningIndicator", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border#BackgroundElement", { | |
| L"Background@InactiveRunningIndicator:=<LinearGradientBrush StartPoint=\"0,0.5\" EndPoint=\"0,1\"><GradientStop Color=\"#3300290c\" Offset=\"0.1\" /><GradientStop Color=\"{ThemeResource SystemAccentColorDark2}\" Offset=\"0.9\" /><GradientStop Color=\"#AAFFFFFF\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"Margin=0,-1,0,-1"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > TextBlock#LabelControl", { | |
| L"Foreground@ActiveNormal=Black", | |
| L"Foreground@ActivePointerOver=Black", | |
| L"Margin=0,0,3,0", | |
| L"Foreground@ActivePressed=#BFBFBF"}}, | |
| ThemeTargetStyles{L"SystemTray.SystemTrayFrame > Grid", { | |
| L"Background:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#50000000\" Offset=\"0.3\" /><GradientStop Color=\"#EE000000\" Offset=\"0.9\" /></LinearGradientBrush>", | |
| L"Margin=0", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"Padding=2"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel", { | |
| L"CornerRadius=0", | |
| L"BorderThickness=0", | |
| L"MaxWidth=48", | |
| L"Margin=0", | |
| L"Padding=0", | |
| L"Background:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#80000000\" Offset=\"0.0\" /><GradientStop Color=\"#FF000000\" Offset=\"1.0\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Grid", { | |
| L"RequestedTheme=2"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#50000000\" Offset=\"0.3\" /><GradientStop Color=\"#EE000000\" Offset=\"0.9\" /></LinearGradientBrush>", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton", { | |
| L"Margin=10,0,-10,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates", { | |
| L"Background@ActiveNormal:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"Background@ActivePointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\"/>", | |
| L"Background@InactivePointerOver=#EBEBEB", | |
| L"Background@InactivePressed=#BBBBBB", | |
| L"Background@ActivePressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>", | |
| L"Background@RequestingAttention=#FFE9AFAA", | |
| L"Background@RequestingAttentionPointerOver=#FFF8E7E5", | |
| L"Background@RequestingAttentionPressed=#FFFEEEF0", | |
| L"Background@MultiWindowPointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\"/>", | |
| L"Background@MultiWindowActive:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"Background@MultiWindowPressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Border", { | |
| L"BorderThickness=0", | |
| L"Margin=-2,-4,-2,-4", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel@CommonStates > Border", { | |
| L"CornerRadius=0", | |
| L"Background@InactivePointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"Background@InactivePressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\"/>", | |
| L"Background@ActiveNormal:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"Background@ActivePointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"Background@ActivePressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>", | |
| L"Margin=-3,-10,-3,-10", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Grid#ContainerGrid@", { | |
| L"Background@PointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid@CommonStates > Border#BackgroundBorder", { | |
| L"Margin=0", | |
| L"Padding=0", | |
| L"CornerRadius=0", | |
| L"Background=Transparent", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton > Grid@CommonStates", { | |
| L"Background@PointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"Background@Pressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>", | |
| L"Background@Checked:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\"/>", | |
| L"Background@CheckedPointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"Background@CheckedPressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>"}}, | |
| ThemeTargetStyles{L"Rectangle#ShowDesktopPipe", { | |
| L"Opacity=0"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Grid@", { | |
| L"Background@Pressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>", | |
| L"Background@CheckedPressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>", | |
| L"Background@PointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"Background@CheckedNormal:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\"/>", | |
| L"Background@CheckedPointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NonActivatableStack > Grid > SystemTray.StackListView > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView > Grid@ ", { | |
| L"Background@Pressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>", | |
| L"Background@CheckedPressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>", | |
| L"Background@PointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\"/>", | |
| L"Background@CheckedNormal:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\"/>", | |
| L"Background@CheckedPointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Windows.UI.Xaml.Controls.ItemsControl > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.WrapGrid > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.NotifyIconView > Grid@", { | |
| L"CornerRadius=0", | |
| L"Margin=2,-5,2,-5"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Border", { | |
| L"Width=48"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Border#MultiWindowElement", { | |
| L"Height=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Rectangle", { | |
| L"StrokeThickness=3", | |
| L"Stroke@MultiWindowNormal:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight3}\"/>", | |
| L"Stroke@MultiWindowPointerOver:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\"/>", | |
| L"Stroke@MultiWindowActive:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>", | |
| L"Stroke@MultiWindowPressed:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\"/>", | |
| L"Width=Auto", | |
| L"RadiusX=0", | |
| L"Margin=-2,0,-2,-3"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Grid > Border", { | |
| L"BorderThickness=0", | |
| L"Background=Transparent"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton > Grid > Border", { | |
| L"BorderThickness=0", | |
| L"Background=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton > Taskbar.TaskListButtonPanel@CommonStates", { | |
| L"Background@InactivePointerOver_SearchIcon=#BEBEBE", | |
| L"Background@InactivePressed_SearchIcon=#DDDDDD", | |
| L"Background@ActiveNormal_SearchIcon=#BEBEBE", | |
| L"Background@ActivePointerOver_SearchIcon=#DDDDDD", | |
| L"Background@ActivePressed_SearchIcon=#EEEEEE"}}, | |
| }}; | |
| const Theme Lucent_variant_Light = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#00000000\" Offset=\"0.3\" /><GradientStop Color=\"#AA000000\" Offset=\"0.9\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<LinearGradientBrush StartPoint=\"0,0.5\" EndPoint=\"0,1\"><GradientStop Color=\"#ee000000\" Offset=\"0.1\" /><GradientStop Color=\"#EBEBEB\" Offset=\"0.9\" /><GradientStop Color=\"#AAFFFFFF\" Offset=\"1.0\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Rectangle#RunningIndicator", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border#BackgroundElement", { | |
| L"Background@InactiveRunningIndicator:=<LinearGradientBrush StartPoint=\"0,0.5\" EndPoint=\"0,1\"><GradientStop Color=\"#33000000\" Offset=\"0.1\" /><GradientStop Color=\"#33EBEBEB\" Offset=\"0.9\" /><GradientStop Color=\"#AAFFFFFF\" Offset=\"1.0\" /></LinearGradientBrush>", | |
| L"Margin=0,-1,0,-1"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > TextBlock#LabelControl", { | |
| L"Foreground@ActiveNormal=Black", | |
| L"Foreground@ActivePointerOver=Black", | |
| L"Margin=0,0,3,0", | |
| L"Foreground@ActivePressed=#424242"}}, | |
| ThemeTargetStyles{L"SystemTray.SystemTrayFrame > Grid", { | |
| L"Background:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#50000000\" Offset=\"0.3\" /><GradientStop Color=\"#EE000000\" Offset=\"0.9\" /></LinearGradientBrush>", | |
| L"Margin=0", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"Padding=2"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel", { | |
| L"CornerRadius=0", | |
| L"BorderThickness=0", | |
| L"MaxWidth=48", | |
| L"Margin=0", | |
| L"Padding=0", | |
| L"Background:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#80000000\" Offset=\"0.0\" /><GradientStop Color=\"#FF000000\" Offset=\"1.0\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Grid", { | |
| L"RequestedTheme=2"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Border", { | |
| L"Background:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#50000000\" Offset=\"0.3\" /><GradientStop Color=\"#EE000000\" Offset=\"0.9\" /></LinearGradientBrush>", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton", { | |
| L"Margin=10,0,-10,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates", { | |
| L"Background@ActiveNormal=#FCFCFC", | |
| L"Background@ActivePointerOver=#BBBBBB", | |
| L"Background@InactivePointerOver=#BBBBBB", | |
| L"Background@InactivePressed=#EBEBEB", | |
| L"Background@ActivePressed=#EBEBEB", | |
| L"Background@RequestingAttention=#FFE9AFAA", | |
| L"Background@RequestingAttentionPointerOver=#FFF8E7E5", | |
| L"Background@RequestingAttentionPressed=#FFFEEEF0", | |
| L"Background@MultiWindowPointerOver=#BBBBBB", | |
| L"Background@MultiWindowActive=#BBBBBB", | |
| L"Background@MultiWindowPressed=#EBEBEB"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Border", { | |
| L"BorderThickness=0", | |
| L"Margin=-2,-4,-2,-4", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel@CommonStates > Border", { | |
| L"CornerRadius=0", | |
| L"Background@InactivePointerOver=#BBBBBB", | |
| L"Background@InactivePressed=#EBEBEB", | |
| L"Background@ActiveNormal=#BBBBBB", | |
| L"Background@ActivePointerOver=#BBBBBB", | |
| L"Background@ActivePressed=#EBEBEB", | |
| L"Margin=-3,-10,-3,-10", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Grid#ContainerGrid@", { | |
| L"Background@PointerOver=#BBBBBB", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid@CommonStates > Border#BackgroundBorder", { | |
| L"Background@PointerOver=#BBBBBB", | |
| L"Margin=0", | |
| L"Padding=0", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton > Grid@CommonStates", { | |
| L"Background@PointerOver=#BBBBBB", | |
| L"Background@Pressed=#EBEBEB", | |
| L"Background@Checked=#BBBBBB", | |
| L"Background@CheckedPointerOver=#BBBBBB", | |
| L"Background@CheckedPressed=#EBEBEB"}}, | |
| ThemeTargetStyles{L"Rectangle#ShowDesktopPipe", { | |
| L"Opacity=0"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Grid@", { | |
| L"Background@Pressed=#EBEBEB", | |
| L"Background@CheckedPressed=#EBEBEB", | |
| L"Background@PointerOver=#BBBBBB", | |
| L"Background@CheckedNormal=#BBBBBB", | |
| L"Background@CheckedPointerOver=#EBEBEB"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NonActivatableStack > Grid > SystemTray.StackListView > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView > Grid@ ", { | |
| L"Background@Pressed=#EBEBEB", | |
| L"Background@CheckedPressed=#EBEBEB", | |
| L"Background@PointerOver=#BBBBBB", | |
| L"Background@CheckedNormal=#BBBBBB", | |
| L" Background@CheckedPointerOver=#EBEBEB"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid > Windows.UI.Xaml.Controls.ItemsControl > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.WrapGrid > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.NotifyIconView > Grid@", { | |
| L"CornerRadius=0", | |
| L"Margin=2,-5,2,-5"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Border", { | |
| L"Width=48"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Border#MultiWindowElement", { | |
| L"Height=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Rectangle", { | |
| L"StrokeThickness=3", | |
| L"Stroke@MultiWindowNormal=#BBBBBB", | |
| L"Stroke@MultiWindowPointerOver=#EBEBEB", | |
| L"Stroke@MultiWindowPressed=#EBEBEB", | |
| L"Stroke@MultiWindowActive=#EBEBEB", | |
| L"Width=Auto", | |
| L"RadiusX=0", | |
| L"Margin=-2,0,-2,-3"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Grid > Border", { | |
| L"BorderThickness=0", | |
| L"Background=Transparent"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton > Grid > Border", { | |
| L"BorderThickness=0", | |
| L"Background=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton > Taskbar.TaskListButtonPanel@CommonStates", { | |
| L"Background@InactivePointerOver_SearchIcon=#BEBEBE", | |
| L"Background@ActiveNormal_SearchIcon=#BEBEBE", | |
| L"Background@ActivePointerOver_SearchIcon=#EBEBEB"}}, | |
| }}; | |
| const Theme SunValley = {{ | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton#SearchBoxButton > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=4", | |
| L"BorderThickness=0,1,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton", { | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon > Grid > Grid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid > SystemTray.AdaptiveTextBlock#Base > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"Text=\u200E \u200E\u200E\u200E\uE7E7 ", | |
| L"FontSize=17.3", | |
| L"Width=30", | |
| L"FontWeight=ExtraLight", | |
| L"Foreground:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" />"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.FontIcon#SearchBoxFontIcon", { | |
| L"FontFamily=Segoe Fluent Icons"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton#SearchBox > SearchUx.SearchUI.SearchButtonRootGrid#SearchBoxButtonRootPanel > Windows.UI.Xaml.Controls.TextBlock#SearchBoxTextBlock", { | |
| L"Text=Type here to search", | |
| L"FontSize=15", | |
| L"FontFamily=Segoe UI Variable Text", | |
| L"Margin=35,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"CornerRadius=3", | |
| L"Height=Auto", | |
| L"Margin=0,0,0,0", | |
| L"Padding=0,4,0,2", | |
| L"BorderThickness=0,1,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"CornerRadius=3", | |
| L"Height=Auto", | |
| L"Width=24", | |
| L"BorderThickness=0,1,0,0", | |
| L"Padding=0,2,0,2"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Button#GleamEntryPointButton > Windows.UI.Xaml.Controls.Border", { | |
| L"CornerRadius=4"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#DynamicSearchBoxGleamContainer", { | |
| L"CornerRadius=3"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton", { | |
| L"CornerRadius=3", | |
| L"Padding=0,2,0,2", | |
| L"Margin=0,0,5,0", | |
| L"BorderThickness=0,1,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NonActivatableStack", { | |
| L"Height=Auto", | |
| L"CornerRadius=3", | |
| L"Margin=0,0,0,0", | |
| L"Padding=0,2,0,2", | |
| L"BorderThickness=0,1,0,0", | |
| L"Grid.Column=4"}}, | |
| ThemeTargetStyles{L"Rectangle#ShowDesktopPipe@CommonStates", { | |
| L"Width=9", | |
| L"Margin=0,0,-10,0", | |
| L"Height=500", | |
| L"Fill@Active:=<AcrylicBrush TintColor=\"{ThemeResource SystemBaseLowColor}\" TintOpacity=\"0.5\" Opacity=\"0\"/>", | |
| L"Stroke:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" Opacity=\"0.3\"/>"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton", { | |
| L"Padding=0,2,0,2", | |
| L"CornerRadius=3", | |
| L"Margin=0,0,0,0", | |
| L"BorderThickness=0,1,0,0", | |
| L"Grid.Column=3"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#LanguageInnerTextBlock > TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe UI Variable Text", | |
| L"Margin=-8,0,0,0", | |
| L"FontSize=12"}}, | |
| ThemeTargetStyles{L"SystemTray.SystemTrayFrame > Windows.UI.Xaml.Controls.Grid#SystemTrayFrameGrid > SystemTray.Stack#NotifyIconStack > Windows.UI.Xaml.Controls.Grid#Content > SystemTray.StackListView#IconStack > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.ChevronIconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.ContentPresenter#ContentPresenter > Windows.UI.Xaml.Controls.Grid#ContentGrid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe Fluent Icons", | |
| L"FontSize=12.4", | |
| L"Foreground:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.SystemTrayFrame > Windows.UI.Xaml.Controls.Grid#SystemTrayFrameGrid > SystemTray.Stack#NotifyIconStack > Windows.UI.Xaml.Controls.Grid#Content > SystemTray.StackListView#IconStack > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter", { | |
| L"Width=30"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#Base > Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe Fluent Icons", | |
| L"Foreground:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#AccentOverlay > Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe Fluent Icons"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#Underlay > Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe Fluent Icons"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter[1] > SystemTray.IconView > Grid > Grid", { | |
| L"Margin=-3,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#MainStack > Windows.UI.Xaml.Controls.Grid#Content", { | |
| L"CornerRadius=3", | |
| L"Height=Auto", | |
| L"Margin=0,0,0,0", | |
| L"Padding=0,4,0,4", | |
| L"BorderThickness=0,1,0,0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.TextBlock#TimeInnerTextBlock", { | |
| L"FontFamily=Segoe UI Variable Display", | |
| L"TextAlignment=0", | |
| L"FontSize=12", | |
| L"Margin=0,1,0,0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.TextBlock#DateInnerTextBlock", { | |
| L"FontFamily=Segoe UI Variable", | |
| L"TextAlignment=0", | |
| L"FontSize=12", | |
| L"Margin=0,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaIcons#NotificationAreaIcons > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter", { | |
| L"Width=23", | |
| L"Margin=0,-2,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaIcons#NotificationAreaIcons > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.NotifyIconView#NotifyItemIcon > Windows.UI.Xaml.Controls.Grid#ContainerGrid", { | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"0\" TranslateX=\"0\" />", | |
| L"HorizontalAlignment=0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NotifyIconStack", { | |
| L"Width=24"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon > Grid > Grid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid > SystemTray.AdaptiveTextBlock > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"FontSize=16", | |
| L"Margin=0,-1,-0,0", | |
| L"FontWeight=0"}}, | |
| ThemeTargetStyles{L"SystemTray.CopilotIcon#CopilotIcon", { | |
| L"Visibility=Visible", | |
| L"Padding=2", | |
| L"Height=61"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaOverflow > Windows.UI.Xaml.Controls.Grid#OverflowRootGrid > Windows.UI.Xaml.Controls.Border#OverflowFlyoutBackgroundBorder", { | |
| L"CornerRadius=7", | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"Margin=0,0,0,0", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.5\" />", | |
| L"BorderThickness=1"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaOverflow > Windows.UI.Xaml.Controls.Grid#OverflowRootGrid > Windows.UI.Xaml.Controls.ItemsControl > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.WrapGrid", { | |
| L"Margin=0,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView", { | |
| L"CornerRadius=3"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ScrollViewer > Windows.UI.Xaml.Controls.ScrollContentPresenter > Windows.UI.Xaml.Controls.Border > SystemTray.NotificationAreaOverflow", { | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"0\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton", { | |
| L"Visibility=Visible"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#BackgroundControl > Grid", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeAltHighColor}\" TintOpacity=\"0.4\" TintLuminosityOpacity=\"0.4\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#BackgroundControl > Grid > Windows.UI.Xaml.Shapes.Rectangle#BackgroundFill", { | |
| L"Opacity=0.5"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#BackgroundStroke", { | |
| L"Opacity=0.5"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter[3] > SystemTray.IconView > Grid > Grid", { | |
| L"Margin=2,0,-4,0", | |
| L"RenderTransform:=<ScaleTransform ScaleX=\"1\" /> "}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ContentPresenter#HoverFlyoutContent", { | |
| L"CornerRadius=7", | |
| L"Margin=0,0,0,0", | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.5\" />", | |
| L"BorderThickness=1"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid > TextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"FontSize=12", | |
| L"Margin=3,0,8,8"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Windows.UI.Xaml.Controls.Grid > Microsoft.UI.Xaml.Controls.ItemsRepeater > Windows.UI.Xaml.Controls.Image", { | |
| L"Margin=0,-7,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid > Button > ContentPresenter > TextBlock", { | |
| L"FontFamily=Segoe Fluent Icons"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid > Button", { | |
| L"CornerRadius=4", | |
| L"Height=31", | |
| L"Margin=0,0,0,8", | |
| L"Width=31"}}, | |
| ThemeTargetStyles{L"Grid#DetailedViewGrid", { | |
| L"Margin=0,-7,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid > Border", { | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" Opacity=\"0.5\" />", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.Grid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid > SystemTray.AdaptiveTextBlock#Base > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"Text=\u200E\uE7E7", | |
| L"FontWeight=Light", | |
| L"FontSize=17.3", | |
| L"Foreground:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" />", | |
| L"Margin=-0.5,0,1,0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView", { | |
| L"CornerRadius=0", | |
| L"Padding=0,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.DateTimeIconContent > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"TextAlignment=Center"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter[2] > SystemTray.IconView > Grid > Grid", { | |
| L"Margin=0,0,-3,0"}}, | |
| ThemeTargetStyles{L"Taskbar.ThumbBarButton > ContentPresenter", { | |
| L"CornerRadius=4", | |
| L"Background:=<SolidColorBrush Color=\"{ThemeResource SystemChromeMediumHighColor}\" Opacity=\"0.3\" />", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.3\" />", | |
| L"BorderThickness=1"}}, | |
| ThemeTargetStyles{L"Taskbar.ThumbBarButton > ContentPresenter > Image", { | |
| L"Height=15", | |
| L"Width=15"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid > Border", { | |
| L"CornerRadius=4"}}, | |
| ThemeTargetStyles{L"TextBlock#BatteryTextBlock", { | |
| L"FontFamily=Segoe UI Variable Text", | |
| L"Margin=2,0,-2,0"}}, | |
| ThemeTargetStyles{L"SystemTray.BatteryIconContent > Grid > Windows.UI.Xaml.Controls.StackPanel > Grid > TextBlock", { | |
| L"RenderTransform:=<ScaleTransform ScaleX=\"1\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Grid#ContainerGrid > Border#BackgroundBorder", { | |
| L"CornerRadius=0", | |
| L"Opacity=0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Button#GleamEntryPointButton > Windows.UI.Xaml.Controls.Border > Windows.UI.Xaml.Controls.ContentPresenter", { | |
| L"CornerRadius=3"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid ", { | |
| L"Margin=2,0,2,0"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Grid > ContentPresenter", { | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"-1\" TranslateX=\"2\" />", | |
| L"HorizontalAlignment=0"}}, | |
| ThemeTargetStyles{L"Border#SearchPillBackgroundElement", { | |
| L"CornerRadius=4"}}, | |
| ThemeTargetStyles{L"Grid#ConfirmatorMainGrid", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.5\" />", | |
| L"CornerRadius=6", | |
| L"BorderThickness=1"}}, | |
| ThemeTargetStyles{L"Slider > Grid > Grid > Grid > Windows.UI.Xaml.Controls.Primitives.Thumb#HorizontalThumb", { | |
| L"Visibility=Visible", | |
| L"Height=18", | |
| L"Width=18"}}, | |
| ThemeTargetStyles{L"Slider > Grid > Grid > Grid > Windows.UI.Xaml.Controls.Primitives.Thumb#HorizontalThumb > Border", { | |
| L"BorderBrush:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeLowColor}\" TintOpacity=\"0.7\" TintLuminosityOpacity=\"0.7\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderThickness=4", | |
| L"Background:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />", | |
| L"CornerRadius=10"}}, | |
| ThemeTargetStyles{L"Slider > Grid > Grid > Grid > Rectangle#HorizontalDecreaseRect", { | |
| L"Fill:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />"}}, | |
| ThemeTargetStyles{L"Slider > Grid > Grid > Grid > Windows.UI.Xaml.Controls.Primitives.Thumb#HorizontalThumb", { | |
| L"BorderBrush:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeHighColor}\" TintOpacity=\"0.7\" TintLuminosityOpacity=\"0.7\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderThickness=0,1,0,0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton", { | |
| L"Width=340"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton > SearchUx.SearchUI.SearchButtonRootGrid", { | |
| L"Width=340", | |
| L"Margin=-5,-6,-4,-6"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton > SearchUx.SearchUI.SearchButtonRootGrid > Grid", { | |
| L"Margin=0,-1,-1,-1", | |
| L"Width=80", | |
| L"Transitions:=<TransitionCollection> <ContentThemeTransition/> </TransitionCollection> "}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton > SearchUx.SearchUI.SearchButtonRootGrid > Grid > Grid > Image", { | |
| L"Width=80", | |
| L"Height=40"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel", { | |
| L"Width=48", | |
| L"Background:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/SunValley/Assets/start.png\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"ToolTip > ContentPresenter > TextBlock", { | |
| L"FontFamily=Segoe UI Variable Text", | |
| L"FontSize=13", | |
| L"Margin=0,1,0,-2"}}, | |
| ThemeTargetStyles{L"ToolTip > ContentPresenter > StackPanel > TextBlock", { | |
| L"FontFamily=Segoe UI Variable Text", | |
| L"FontSize=13", | |
| L"Margin=0,1,0,-2"}}, | |
| ThemeTargetStyles{L"ToolTip", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.5\" />", | |
| L"BorderThickness=1"}}, | |
| ThemeTargetStyles{L"ToolTip > ContentPresenter", { | |
| L"Transitions:=<TransitionCollection> <ContentThemeTransition VerticalOffset=\"60\" /> </TransitionCollection> "}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton[AutomationProperties.AutomationId=WidgetsButton] > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel", { | |
| L"Padding=0,2,0,2"}}, | |
| ThemeTargetStyles{L"TextBlock#VirtualDesktopNameBlock", { | |
| L"FontFamily=Segoe UI Variable Text", | |
| L"FontSize=13"}}, | |
| ThemeTargetStyles{L"Grid#RootGrid > Grid#TitleGrid > TextBlock#DisplayName", { | |
| L"FontFamily=Segoe UI Variable Text", | |
| L"FontSize=13"}}, | |
| ThemeTargetStyles{L"Grid#MainGrid > TextBlock", { | |
| L"FontFamily=Segoe UI Variable Text", | |
| L"FontSize=13"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#BackgroundDimmingLayer", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.7\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=TaskViewButton] > Taskbar.TaskListButtonPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"RenderTransform:=<ScaleTransform ScaleX=\"1.1\" ScaleY=\"0.9\" />", | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"2\" TranslateX=\"-2\" />", | |
| L"FlowDirection=1"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ModalRootGrid > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0.2\" TintLuminosityOpacity=\"0.9\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"Transitions:=<TransitionCollection> <ContentThemeTransition VerticalOffset=\"-1000\" /> </TransitionCollection> "}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton > SearchUx.SearchUI.SearchButtonRootGrid > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer", { | |
| L"Height=18", | |
| L"Width=18", | |
| L"Transform3D:=<CompositeTransform3D TranslateX=\"0\" />"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchPillButton > SearchUx.SearchUI.SearchButtonRootGrid", { | |
| L"Margin=-3,-6,-3,-6", | |
| L"Width=346"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchPillButton > SearchUx.SearchUI.SearchButtonRootGrid > Grid#SearchBoxContentGrid", { | |
| L"HorizontalAlignment=0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchPillButton > SearchUx.SearchUI.SearchButtonRootGrid > Grid#SearchBoxContentGrid > FontIcon", { | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"-1\" TranslateX=\"-10.5\" />", | |
| L"FontSize=19.4", | |
| L"FontFamily=Segoe Fluent Icons", | |
| L"FontWeight=SemiLight", | |
| L"Opacity=0.7", | |
| L"Grid.Column=0", | |
| L"HorizontalAlignment=0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchPillButton > SearchUx.SearchUI.SearchButtonRootGrid > Grid#SearchBoxContentGrid > TextBlock", { | |
| L"Transform3D:=<CompositeTransform3D TranslateX=\"-5\" />", | |
| L"FontFamily=Segoe UI", | |
| L"Opacity=0.7", | |
| L"Text=Type here to search", | |
| L"Grid.Column=1", | |
| L"HorizontalAlignment=0", | |
| L"FontSize=15"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchPillButton > SearchUx.SearchUI.SearchButtonRootGrid > Border#SearchPillBackgroundElement", { | |
| L"CornerRadius=4", | |
| L"BorderThickness=1", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.7\" />"}}, | |
| ThemeTargetStyles{L"Grid#SearchBoxContentGrid", { | |
| L"Visibility=Visible"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton > Taskbar.TaskListLabeledButtonPanel#IconPanel", { | |
| L"Padding=2", | |
| L"Margin=2,0,2,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton > Taskbar.TaskListLabeledButtonPanel > Rectangle", { | |
| L"RadiusX=2", | |
| L"Margin=0,0,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton > Taskbar.TaskListButtonPanel", { | |
| L"Padding=2", | |
| L"Margin=1,0,2,0"}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter", { | |
| L"CornerRadius=7"}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter > Border", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0.3\" TintLuminosityOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"Transitions:=<TransitionCollection> <ContentThemeTransition VerticalOffset=\"100\" /> </TransitionCollection> ", | |
| L"BorderThickness=1", | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.5\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Image#OverlayIcon", { | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"15\" TranslateX=\"-2\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Taskbar.Badge", { | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"15\" TranslateX=\"-2\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Taskbar.Badge > Grid > Rectangle", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Taskbar.Badge > Grid", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0,7\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderBrush:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.5\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderThickness=0,1,0,0", | |
| L"CornerRadius=15"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Taskbar.Badge > Grid > TextBlock", { | |
| L"Foreground:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" />", | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"-1\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Taskbar.Badge", { | |
| L"Height=17", | |
| L"Width=17"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchIconButton > SearchUx.SearchUI.SearchButtonRootGrid", { | |
| L"Padding=0,2,2,2", | |
| L"Width=48"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton > SearchUx.SearchUI.SearchButtonRootGrid > TextBlock", { | |
| L"Transform3D:=<CompositeTransform3D TranslateX=\"5\" TranslateY=\"1\" />"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid#SearchV2ButtonRootPanel", { | |
| L"Padding=0,2,0,2"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchV2Button", { | |
| L"CornerRadius=4", | |
| L"Width=346"}}, | |
| ThemeTargetStyles{L"Grid#SearchV2ButtonInactiveUIGrid", { | |
| L"MaxWidth=346", | |
| L"MinWidth=346"}}, | |
| ThemeTargetStyles{L"Grid#SearchV2ButtonActiveUIGridWithAnimations", { | |
| L"Width=346"}}, | |
| ThemeTargetStyles{L"Grid#SearchV2ButtonActiveUIGridWithAnimations > StackPanel", { | |
| L"HorizontalAlignment=0", | |
| L"Margin=13,0,0,0"}}, | |
| ThemeTargetStyles{L"Grid#SearchV2ButtonInactiveUIGrid > Button", { | |
| L"Height=40", | |
| L"Width=30", | |
| L"CornerRadius=4"}}, | |
| ThemeTargetStyles{L"TextBlock#SearchV2OnTaskbarButtonText", { | |
| L"FontFamily=Segoe UI", | |
| L"FontSize=15", | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"-1\" />", | |
| L"Text=Ask me anything"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=TaskViewButton] > Taskbar.TaskListButtonPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=TaskViewButton] > Taskbar.TaskListButtonPanel@CommonStates", { | |
| L"Background:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/SunValley/Assets/taskview.png\" />", | |
| L"Width=48"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchIconButton > SearchUx.SearchUI.SearchButtonRootGrid > Grid#SearchBoxContentGrid > FontIcon > Grid > TextBlock", { | |
| L"FontWeight=Light"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaOverflow > Windows.UI.Xaml.Controls.Grid#OverflowRootGrid", { | |
| L"Margin=7,0,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton > Taskbar.TaskListLabeledButtonPanel#IconPanel > Border#BackgroundElement", { | |
| L"Margin=-3,0,-3,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton > Taskbar.TaskListLabeledButtonPanel#IconPanel@RunningIndicatorStates > Rectangle", { | |
| L"Width@ActiveRunningIndicator=40", | |
| L"RadiusX=2", | |
| L"RadiusY=2", | |
| L"Width@InactiveRunningIndicator=35"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton > Taskbar.TaskListButtonPanel > Border", { | |
| L"Margin=-3,0,-3,0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchIconButton > SearchUx.SearchUI.SearchButtonRootGrid > Border", { | |
| L"Margin=-1,0,-1,0", | |
| L"Opacity=0.5"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton > Taskbar.TaskListLabeledButtonPanel#IconPanel@CommonStates > Border#MultiWindowElement", { | |
| L"Margin=-4,0,-4,0", | |
| L"Opacity=0.5"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Border", { | |
| L"Opacity=0.5"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Border#BackgroundElement", { | |
| L"Opacity=0.5"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchPillButton > SearchUx.SearchUI.SearchButtonRootGrid > Grid#SearchBoxContentGrid", { | |
| L"Width=344"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchBoxButton > SearchUx.SearchUI.SearchButtonRootGrid@CommonStates > Border", { | |
| L"BorderBrush@InactiveNormal_SearchBox_Wave3:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.7\" />", | |
| L"Background@InactiveNormal_SearchBox_Wave3:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" Opacity=\"0.06\" />", | |
| L"Background@InactivePointerOver_SearchBox_Wave3:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.2\" />", | |
| L"Background@InactivePressed_SearchBox_Wave3:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.05\" />", | |
| L"BorderThickness@InactivePointerOver_SearchBox_Wave3=2", | |
| L"BorderThickness@InactivePressed_SearchBox_Wave3=2", | |
| L"BorderThickness@InactiveNormal_SearchBox_Wave3=1", | |
| L"Background@ActivePointerOver_SearchBox_Wave3:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0\" />", | |
| L"Background@ActivePressed_SearchBox_Wave3:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0\" />", | |
| L"Background@ActiveNormal_SearchBox_Wave3:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0\" />", | |
| L"BorderBrush@InactivePointerOver_SearchBox_Wave3:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.7\" />", | |
| L"BorderBrush@InactivePressed_SearchBox_Wave3:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.7\" />", | |
| L"BorderThickness@InactivePointerOver_SearchBoxCustomTheme=2", | |
| L"BorderThickness@InactivePressed_SearchBoxCustomTheme=2", | |
| L"BorderThickness@InactiveNormal_SearchBoxCustomTheme=1", | |
| L"BorderBrush@InactiveNormal_SearchBoxCustomTheme:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.7\" />", | |
| L"BorderBrush@InactivePointerOver_SearchBoxCustomTheme:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.7\" />", | |
| L"BorderBrush@InactivePressed_SearchBoxCustomTheme:=<SolidColorBrush Color=\"{ThemeResource SystemChromeHighColor}\" Opacity=\"0.7\" />", | |
| L"Background@InactivePointerOver_SearchBoxCustomTheme:=<SolidColorBrush Color=\"White\" Opacity=\"1\" />", | |
| L"Background@InactiveNormal_SearchBoxCustomTheme:=<SolidColorBrush Color=\"White\" Opacity=\"0.9\" />", | |
| L"Background@InactivePressed_SearchBoxCustomTheme:=<SolidColorBrush Color=\"White\" Opacity=\"0.7\" />"}}, | |
| }}; | |
| const Theme Taskbar21996 = {{ | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton#SearchBoxButton > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=4", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton", { | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon > Grid > Grid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid > SystemTray.AdaptiveTextBlock > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"Visibility=Visible", | |
| L"Text=\u200E \u200E\u200E\u200E\uE91C ", | |
| L"FontSize=16.4", | |
| L"FontFamily=Segoe MDL2 Assets", | |
| L"Width=30", | |
| L"FontWeight=ExtraLight", | |
| L"Foreground:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" />"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.FontIcon#SearchBoxFontIcon", { | |
| L"FontFamily=Segoe Fluent Icons"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.TextBlock#SearchBoxTextBlock", { | |
| L"Text=Type here to search", | |
| L"FontSize=14"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"CornerRadius=0", | |
| L"Height=Auto", | |
| L"Margin=0,0,0,0", | |
| L"Padding=0", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"CornerRadius=0", | |
| L"Height=Auto", | |
| L"Width=24", | |
| L"BorderThickness=0", | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Button#GleamEntryPointButton > Windows.UI.Xaml.Controls.Border", { | |
| L"CornerRadius=4"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#DynamicSearchBoxGleamContainer", { | |
| L"CornerRadius=4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton", { | |
| L"CornerRadius=0", | |
| L"Padding=0,0,0,0", | |
| L"Margin=0,0,0,0", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NonActivatableStack", { | |
| L"Height=Auto", | |
| L"CornerRadius=0", | |
| L"Margin=0,0,0,0", | |
| L"Padding=0", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Rectangle#ShowDesktopPipe@CommonStates", { | |
| L"Width=9", | |
| L"Margin=0,0,-10,0", | |
| L"Height=500", | |
| L"Fill@Active:=<AcrylicBrush TintColor=\"{ThemeResource SystemBaseLowColor}\" TintOpacity=\"0.5\" Opacity=\"0\"/>", | |
| L"Stroke:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" Opacity=\"0.5\"/>"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton", { | |
| L"Padding=0", | |
| L"CornerRadius=0", | |
| L"Margin=0,0,0,0", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#LanguageInnerTextBlock > TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"Margin=-8,0,0,0", | |
| L"FontSize=12"}}, | |
| ThemeTargetStyles{L"SystemTray.SystemTrayFrame > Windows.UI.Xaml.Controls.Grid#SystemTrayFrameGrid > SystemTray.Stack#NotifyIconStack > Windows.UI.Xaml.Controls.Grid#Content > SystemTray.StackListView#IconStack > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.ChevronIconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.ContentPresenter#ContentPresenter > Windows.UI.Xaml.Controls.Grid#ContentGrid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe MDL2 Assets", | |
| L"FontSize=12.4", | |
| L"Foreground:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.SystemTrayFrame > Windows.UI.Xaml.Controls.Grid#SystemTrayFrameGrid > SystemTray.Stack#NotifyIconStack > Windows.UI.Xaml.Controls.Grid#Content > SystemTray.StackListView#IconStack > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter", { | |
| L"Width=30"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#Base > Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe MDL2 Assets", | |
| L"Foreground:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#AccentOverlay > Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe MDL2 Assets"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#Underlay > Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe MDL2 Assets"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter[1] > SystemTray.IconView > Grid > Grid", { | |
| L"Margin=-6,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#MainStack > Windows.UI.Xaml.Controls.Grid#Content", { | |
| L"CornerRadius=0", | |
| L"Height=Auto", | |
| L"Margin=0,0,0,0", | |
| L"Padding=0", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.TextBlock#TimeInnerTextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"TextAlignment=0", | |
| L"FontSize=12", | |
| L"Margin=0,-1,0,0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.TextBlock#DateInnerTextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"TextAlignment=0", | |
| L"FontSize=12", | |
| L"Margin=0,2,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaIcons#NotificationAreaIcons > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter", { | |
| L"Width=23", | |
| L"Margin=0,-2,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaIcons#NotificationAreaIcons > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.NotifyIconView#NotifyItemIcon > Windows.UI.Xaml.Controls.Grid#ContainerGrid", { | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"0\" TranslateX=\"0\" />", | |
| L"HorizontalAlignment=0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NotifyIconStack", { | |
| L"Width=24"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon > Grid > Grid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid > SystemTray.AdaptiveTextBlock > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"FontSize=16", | |
| L"Margin=0,-1,-0,0", | |
| L"FontWeight=0"}}, | |
| ThemeTargetStyles{L"SystemTray.CopilotIcon#CopilotIcon", { | |
| L"Visibility=Visible", | |
| L"Margin=0,-7,0,0", | |
| L"Height=61"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaOverflow > Windows.UI.Xaml.Controls.Grid#OverflowRootGrid > Windows.UI.Xaml.Controls.Border#OverflowFlyoutBackgroundBorder", { | |
| L"CornerRadius=0", | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAltHighColor}\" TintOpacity=\"0.7\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaOverflow > Windows.UI.Xaml.Controls.Grid#OverflowRootGrid > Windows.UI.Xaml.Controls.ItemsControl > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.WrapGrid", { | |
| L"Margin=0,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView", { | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ScrollViewer > Windows.UI.Xaml.Controls.ScrollContentPresenter > Windows.UI.Xaml.Controls.Border > SystemTray.NotificationAreaOverflow", { | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"13\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton", { | |
| L"Visibility=Visible"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#BackgroundControl > Grid", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#BackgroundControl > Grid > Windows.UI.Xaml.Shapes.Rectangle#BackgroundFill", { | |
| L"Opacity=0.5"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter[3] > SystemTray.IconView > Grid > Grid", { | |
| L"Margin=2,0,-8,0", | |
| L"RenderTransform:=<ScaleTransform ScaleX=\"0.86\" /> "}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ContentPresenter#HoverFlyoutContent", { | |
| L"CornerRadius=0", | |
| L"Margin=0,0,0,-15", | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemAltHighColor}\" TintOpacity=\"0.7\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid > TextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"FontSize=12", | |
| L"Margin=3,0,8,8"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Windows.UI.Xaml.Controls.Grid > Microsoft.UI.Xaml.Controls.ItemsRepeater > Windows.UI.Xaml.Controls.Image", { | |
| L"Margin=0,-7,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid > Button > ContentPresenter > TextBlock", { | |
| L"FontFamily=Segoe MDL2 Assets"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid > Button", { | |
| L"CornerRadius=0", | |
| L"Height=32", | |
| L"Margin=0,0,0,9", | |
| L"Width=32"}}, | |
| ThemeTargetStyles{L"Grid#DetailedViewGrid", { | |
| L"Margin=0,-7,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid > Border", { | |
| L"BorderBrush:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" Opacity=\"0.5\" />", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.Grid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid > SystemTray.AdaptiveTextBlock#Base > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"Text=\u200E\uE91C", | |
| L"FontWeight=Light", | |
| L"FontSize=16.4", | |
| L"Foreground:=<SolidColorBrush Color=\"{ThemeResource SystemBaseHighColor}\" />", | |
| L"Margin=-1,0,1,0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView", { | |
| L"CornerRadius=0", | |
| L"Padding=0,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.DateTimeIconContent > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"TextAlignment=Center"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter[2] > SystemTray.IconView > Grid > Grid", { | |
| L"Margin=0,0,-3,0"}}, | |
| ThemeTargetStyles{L"Taskbar.ThumbBarButton > ContentPresenter", { | |
| L"CornerRadius=0", | |
| L"Background:=<SolidColorBrush Opacity=\"0.5\" />", | |
| L"BorderBrush:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeLowColor}\" FallbackColor=\"{ThemeResource SystemChromeLowColor}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.ThumbBarButton > ContentPresenter > Image", { | |
| L"Height=15", | |
| L"Width=15"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid > Border", { | |
| L"CornerRadius=4"}}, | |
| ThemeTargetStyles{L"TextBlock#BatteryTextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"Margin=2,0,-2,0"}}, | |
| ThemeTargetStyles{L"SystemTray.BatteryIconContent > Grid > Windows.UI.Xaml.Controls.StackPanel > Grid > TextBlock", { | |
| L"RenderTransform:=<ScaleTransform ScaleX=\"1\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Grid#ContainerGrid > Border#BackgroundBorder", { | |
| L"CornerRadius=0", | |
| L"Opacity=0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Button#GleamEntryPointButton > Windows.UI.Xaml.Controls.Border > Windows.UI.Xaml.Controls.ContentPresenter", { | |
| L"CornerRadius=3"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid ", { | |
| L"Margin=2,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Grid > ContentPresenter", { | |
| L"Transform3D:=<CompositeTransform3D TranslateY=\"-1\" TranslateX=\"2\" />", | |
| L"HorizontalAlignment=0"}}, | |
| ThemeTargetStyles{L"Border#SearchPillBackgroundElement", { | |
| L"CornerRadius=4"}}, | |
| ThemeTargetStyles{L"Grid#ConfirmatorMainGrid", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeMediumHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderBrush:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeHighColor}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.3\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"CornerRadius=6", | |
| L"BorderThickness=0,1,0,0"}}, | |
| ThemeTargetStyles{L"Slider > Grid > Grid > Grid > Windows.UI.Xaml.Controls.Primitives.Thumb#HorizontalThumb", { | |
| L"Visibility=Visible", | |
| L"Height=18", | |
| L"Width=18"}}, | |
| ThemeTargetStyles{L"Slider > Grid > Grid > Grid > Windows.UI.Xaml.Controls.Primitives.Thumb#HorizontalThumb > Border", { | |
| L"BorderBrush:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeLowColor}\" TintOpacity=\"0.7\" TintLuminosityOpacity=\"0.7\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderThickness=4", | |
| L"Background:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />", | |
| L"CornerRadius=10"}}, | |
| ThemeTargetStyles{L"Slider > Grid > Grid > Grid > Rectangle#HorizontalDecreaseRect", { | |
| L"Fill:=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" />"}}, | |
| ThemeTargetStyles{L"Slider > Grid > Grid > Grid > Windows.UI.Xaml.Controls.Primitives.Thumb#HorizontalThumb", { | |
| L"BorderBrush:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeHighColor}\" TintOpacity=\"0.7\" TintLuminosityOpacity=\"0.7\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"BorderThickness=0,1,0,0"}}, | |
| }}; | |
| const Theme BottomDensy = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Rectangle#RunningIndicator", { | |
| L"Fill=#8f8f8f", | |
| L"Fill@ActiveRunningIndicator=#fef9f0", | |
| L"Width=2", | |
| L"Height=2", | |
| L"Margin=0,-2,0,0", | |
| L"Width@ActiveRunningIndicator=32"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > muxc:ProgressBar#ProgressIndicator", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Rectangle#RunningIndicator", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Border#ProgressBarRoot", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Rectangle#IndeterminateProgressBarIndicator", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Rectangle#IndeterminateProgressBarIndicator2", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel", { | |
| L"Padding=2,0,2,0", | |
| L"VerticalAlignment=2"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton]", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"Width=1"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#ShowDesktopPipe", { | |
| L"HorizontalAlignment=0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaIcons#NotificationAreaIcons > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.NotifyIconView#NotifyItemIcon > Grid#ContainerGrid > ContentPresenter#ContentPresenter > Grid#ContentGrid > SystemTray.ImageIconContent > Grid#ContainerGrid > Image", { | |
| L"Width=20", | |
| L"Height=20"}}, | |
| ThemeTargetStyles{L"WrapGrid > ContentPresenter > SystemTray.NotifyIconView > Grid#ContainerGrid > ContentPresenter#ContentPresenter > Grid#ContentGrid > SystemTray.ImageIconContent > Grid#ContainerGrid > Image", { | |
| L"Width=20", | |
| L"Height=20"}}, | |
| }}; | |
| const Theme BottomDensy_variant_NoInd = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Rectangle#RunningIndicator", { | |
| L"Fill=#8f8f8f", | |
| L"Fill@ActiveRunningIndicator=#fef9f0", | |
| L"Width=0", | |
| L"Height=0", | |
| L"Margin=0,0,0,0", | |
| L"Width@ActiveRunningIndicator=32", | |
| L"Height@ActiveRunningIndicator=2", | |
| L"Margin@ActiveRunningIndicator=0,-2,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > muxc:ProgressBar#ProgressIndicator", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Rectangle#RunningIndicator", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Border#ProgressBarRoot", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Rectangle#IndeterminateProgressBarIndicator", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Rectangle#IndeterminateProgressBarIndicator2", { | |
| L"VerticalAlignment=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel", { | |
| L"Padding=2,0,2,0", | |
| L"VerticalAlignment=2"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton]", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"Width=1"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#ShowDesktopPipe", { | |
| L"HorizontalAlignment=0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaIcons#NotificationAreaIcons > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.NotifyIconView#NotifyItemIcon > Grid#ContainerGrid > ContentPresenter#ContentPresenter > Grid#ContentGrid > SystemTray.ImageIconContent > Grid#ContainerGrid > Image", { | |
| L"Width=20", | |
| L"Height=20"}}, | |
| ThemeTargetStyles{L"WrapGrid > ContentPresenter > SystemTray.NotifyIconView > Grid#ContainerGrid > ContentPresenter#ContentPresenter > Grid#ContentGrid > SystemTray.ImageIconContent > Grid#ContainerGrid > Image", { | |
| L"Width=20", | |
| L"Height=20"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Image#Icon", { | |
| L"Width@ActiveRunningIndicator=30", | |
| L"Height@ActiveRunningIndicator=30", | |
| L"Width@NoRunningIndicator=26", | |
| L"Height@NoRunningIndicator=26", | |
| L"Margin@NoRunningIndicator=0,6,0,0"}}, | |
| }}; | |
| const Theme TaskbarXII = {{ | |
| ThemeTargetStyles{L"ScrollViewer > ScrollContentPresenter > Border > Grid", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemListLowColor}\" TintOpacity=\"0.1\" FallbackColor=\"{ThemeResource SystemChromeHighColor}\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame#TaskbarFrame", { | |
| L"HorizontalAlignment=Right", | |
| L"Width=Auto", | |
| L"Height=56", | |
| L"Grid.Column=0", | |
| L"Margin=0,0,2,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame#TaskbarFrame > Grid", { | |
| L"Height=48", | |
| L"CornerRadius=4"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#BackgroundControl", { | |
| L"Height=48", | |
| L"Opacity=0.7"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground > Grid", { | |
| L"CornerRadius=4", | |
| L"Opacity=1"}}, | |
| ThemeTargetStyles{L"Microsoft.UI.Xaml.Controls.ItemsRepeater#TaskbarFrameRepeater", { | |
| L"Margin=0,0,3,0"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton > Taskbar.TaskListButtonPanel", { | |
| L"Margin=2,0,6,0"}}, | |
| ThemeTargetStyles{L"TextBlock#SearchBoxTextBlock", { | |
| L"Text=\u2726 Meow"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Border#LargeTicker1", { | |
| L"Margin=0,2,4,0"}}, | |
| ThemeTargetStyles{L"Border#LargeTicker1 > AdaptiveCards.Rendering.Uwp.WholeItemsPanel > Image", { | |
| L"MaxHeight=27", | |
| L"MaxWidth=27"}}, | |
| ThemeTargetStyles{L"Border#LargeTicker1 > AdaptiveCards.Rendering.Uwp.WholeItemsPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer", { | |
| L"MaxHeight=27", | |
| L"MaxWidth=27"}}, | |
| ThemeTargetStyles{L"SystemTray.SystemTrayFrame", { | |
| L"HorizontalAlignment=Left", | |
| L"Grid.Column=1", | |
| L"Margin=2,0,0,0"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background:=<SolidColorBrush Color=\"{ThemeResource SystemChromeAltHighColor}\" Opacity=\"0.6\" />", | |
| L"CornerRadius=4", | |
| L"Padding=8,3,0,3"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#SecondaryClockStack", { | |
| L"Grid.Column=8"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton", { | |
| L"Grid.Column=4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton", { | |
| L"Grid.Column=5"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#MainStack", { | |
| L"Grid.Column=6"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"Grid.Column=7"}}, | |
| ThemeTargetStyles{L"SystemTray.DateTimeIconContent > Grid > StackPanel", { | |
| L"Orientation=Horizontal", | |
| L"Spacing=12"}}, | |
| ThemeTargetStyles{L"TextBlock#InnerTextBlock[Text=\uE971]", { | |
| L"Text=\uED14"}}, | |
| ThemeTargetStyles{L"TextBlock#TimeInnerTextBlock", { | |
| L"FontSize=15", | |
| L"FontWeight=Bold"}}, | |
| ThemeTargetStyles{L"TextBlock#DateInnerTextBlock", { | |
| L"FontSize=15", | |
| L"FontWeight=SemiBold"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ScrollViewer > Windows.UI.Xaml.Controls.ScrollContentPresenter > Windows.UI.Xaml.Controls.Border > Windows.UI.Xaml.Controls.Grid", { | |
| L"ColumnDefinitions:=<ColumnDefinitionCollection><ColumnDefinition Width=\"*\"/><ColumnDefinition Width=\"*\"/></ColumnDefinitionCollection>"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton > Taskbar.TaskListButtonPanel", { | |
| L"Margin=0"}}, | |
| }}; | |
| const Theme xdark = {{ | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"CornerRadius=13", | |
| L"Padding=6,0,6,0", | |
| L"HorizontalContentAlignment=Left"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > TextBlock#InnerTextBlock", { | |
| L"FontSize=16", | |
| L"Foreground=#facc15"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"MinWidth=25"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter[1] > SystemTray.IconView > Grid > Grid", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid#ContainerGrid", { | |
| L"Padding=2"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"MinWidth=27"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon > Grid > Grid > SystemTray.TextIconContent", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Border#BackgroundElement", { | |
| L"Background=#000000"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Background=#000000", | |
| L"CornerRadius=13", | |
| L"Margin=0,5,4,5", | |
| L"Padding=2,0,-18,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton > Grid > Rectangle#RunningIndicator", { | |
| L"Height=3", | |
| L"RadiusX=1.5", | |
| L"RadiusY=1.5", | |
| L"Fill@ActiveNormal=#facc15", | |
| L"VerticalAlignment=Bottom", | |
| L"Margin=16,0,16,4", | |
| L"StrokeThickness=0"}}, | |
| ThemeTargetStyles{L"SystemTray.ImageIconContent > Grid#ContainerGrid > Image", { | |
| L"Width=13"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > TextBlock#InnerTextBlock", { | |
| L"FontSize=13", | |
| L"Foreground=#facc15"}}, | |
| ThemeTargetStyles{L"TextBlock#LabelControl", { | |
| L"FontFamily=Segoe UI Medium", | |
| L"Foreground=#facc15", | |
| L"Margin=1,0,0,0", | |
| L"VerticalAlignment=Center", | |
| L"TextWrapping=NoWrap"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton]", { | |
| L"Visibility=Visible"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock[Text=\uE971]", { | |
| L"Text=\uE712", | |
| L"Foreground=#facc15"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > TextBlock#InnerTextBlock", { | |
| L"Foreground=#facc15"}}, | |
| }}; | |
| const Theme Windows7 = { | |
| { | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"Background@InactiveNormal:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandInactiveNormal\" />", | |
| L"Background@InactivePointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandInactivePointerOver\" />", | |
| L"Background@ActiveNormal:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandActiveNormal\" />", | |
| L"Background@ActivePressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandActivePressed\" />", | |
| L"Background@ActivePointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandActivePointerOver\" />", | |
| L"Background@InactivePressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandInactivePressed\" />", | |
| L"BorderThickness=0", | |
| L"Background@MultiWindowNormal:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandInactiveNormal\" />", | |
| L"Background@MultiWindowActive:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandActiveNormal\" />", | |
| L"Background@MultiWindowPressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandActivePressed\" />", | |
| L"Background@MultiWindowPointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandActivePointerOver\" />", | |
| L"Background@RequestingAttention:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandRequestingAttention\" />", | |
| L"Background@RequestingAttentionPointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandRequestingAttention\" />", | |
| L"Background@RequestingAttentionPressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandRequestingAttention\" />", | |
| L"Background@RequestingAttentionMulti:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandRequestingAttention\" />", | |
| L"Background@RequestingAttentionMultiPointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandRequestingAttention\" />", | |
| L"Background@RequestingAttentionMultiPressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandRequestingAttention\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel", { | |
| L"Padding=0,0,0,0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#RunningIndicator", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Image", { | |
| L"RenderTransform:=<TranslateTransform X=\"2\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"Opacity@NoRunningIndicator=0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"Background@InactiveNormal:=<ImageBrush Stretch=\"None\" ImageSource=\"$orbNormal\" />", | |
| L"Background@InactivePointerOver:=<ImageBrush Stretch=\"None\" ImageSource=\"$orbPointerOver\" />", | |
| L"Background@InactivePressed:=<ImageBrush Stretch=\"None\" ImageSource=\"$orbPressed\" />", | |
| L"Background@ActiveNormal:=<ImageBrush Stretch=\"None\" ImageSource=\"$orbPressed\" />", | |
| L"Background@ActivePointerOver:=<ImageBrush Stretch=\"None\" ImageSource=\"$orbPointerOver\" />", | |
| L"Background@ActivePressed:=<ImageBrush Stretch=\"None\" ImageSource=\"$orbPressed\" />", | |
| L"BorderThickness=0", | |
| L"Width=54"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel", { | |
| L"Padding=0,0,0,0", | |
| L"MinWidth=55", | |
| L"Margin=0,0,5,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid", { | |
| L"Background:=<WindhawkBlur BlurAmount=\"3\" TintOpacity=\"$aeroOpacity\" TintColor=\"$aeroColor\" />"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#BackgroundStroke", { | |
| L"Fill:=<ImageBrush Stretch=\"UniformtoFill\" ImageSource=\"$reflection\" />", | |
| L"Height=39"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbarBackground\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"Margin=1,0,1,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Windows.UI.Xaml.Controls.Border#MultiWindowElement", { | |
| L"Background@MultiWindowNormal:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandInactiveNormal\" />", | |
| L"Background@MultiWindowActive:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandActiveNormal\" />", | |
| L"Background@MultiWindowPointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandActiveNormal\" />", | |
| L"BorderThickness=0", | |
| L"RenderTransform:=<TranslateTransform X=\"2\" />", | |
| L"Background@MultiWindowPressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandActiveNormal\" />", | |
| L"Background@RequestingAttentionMulti:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandRequestingAttention\" />", | |
| L"Background@RequestingAttentionMultiPointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandRequestingAttention\" />", | |
| L"Background@RequestingAttentionMultiPressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$taskbandRequestingAttention\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.ContentPresenter", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid@ > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background@Normal:=<ImageBrush Stretch=\"None\" ImageSource=\"$overflowNormal\" />", | |
| L"Background@PointerOver:=<ImageBrush Stretch=\"None\" ImageSource=\"$overflowPointerOver\" />", | |
| L"Background@Pressed:=<ImageBrush Stretch=\"None\" ImageSource=\"$overflowPressed\" />", | |
| L"Background@CheckedNormal:=<ImageBrush Stretch=\"None\" ImageSource=\"$overflowPressed\" />", | |
| L"Background@CheckedPointerOver:=<ImageBrush Stretch=\"None\" ImageSource=\"$overflowPressed\" />", | |
| L"Background@CheckedPressed:=<ImageBrush Stretch=\"None\" ImageSource=\"$overflowPressed\" />", | |
| L"BorderThickness=0", | |
| L"Width=21", | |
| L"Height=20"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid@CommonStates > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background@Normal=Transparent", | |
| L"Background@PointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPointerOver\" />", | |
| L"Background@Pressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPressed\" />", | |
| L"BorderThickness=0", | |
| L"Margin=0", | |
| L"MinWidth=68", | |
| L"Background@Checked:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPointerOver\" />", | |
| L"Background@CheckedPointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPointerOver\" />", | |
| L"Background@CheckedPressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPressed\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.DateTimeIconContent > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"TextAlignment=0", | |
| L"Foreground=White", | |
| L"FontFamily=Segoe UI", | |
| L"FlowDirection=0", | |
| L"Typography.StylisticSet1=true"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Windows.UI.Xaml.Controls.Grid@CommonStates > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background@Normal=Transparent", | |
| L"Background@PointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPointerOver\" />", | |
| L"Background@Pressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPressed\" />", | |
| L"BorderThickness=0", | |
| L"Margin=0", | |
| L"Background@Checked:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPointerOver\" />", | |
| L"Background@CheckedPointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPointerOver\" />", | |
| L"Background@CheckedPressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPressed\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon > Windows.UI.Xaml.Controls.Grid#ContainerGrid@ > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background@Normal=Transparent", | |
| L"Background@PointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$trayPointerOver\" />", | |
| L"BorderThickness=0", | |
| L"Margin=0", | |
| L"Width=24"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaIcons > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter", { | |
| L"Width=24", | |
| L"Padding=-2,0,-2,0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Grid#ContentGrid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid#ContainerGrid > SystemTray.AdaptiveTextBlock[2] > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"FontFamily=Segoe MDL2 Assets", | |
| L"Text=\uE81B"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel", { | |
| L"FlowDirection=1"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ContainerGrid@ > Windows.UI.Xaml.Shapes.Rectangle#ShowDesktopPipe", { | |
| L"Fill@Normal:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$desktopNormal\" />", | |
| L"Height=39", | |
| L"Width=$desktopWidth", | |
| L"RadiusX=0", | |
| L"RadiusY=0", | |
| L"Fill@PointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$desktopPointerOver\" />", | |
| L"Fill@Pressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$desktopPressed\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"Width=$desktopWidth"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack > Windows.UI.Xaml.Controls.Grid > SystemTray.StackListView > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter", { | |
| L"Width=$desktopWidth"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack > Windows.UI.Xaml.Controls.Grid > SystemTray.StackListView > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView", { | |
| L"Width=$desktopWidth"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView#SystemTrayIcon > Windows.UI.Xaml.Controls.Grid#ContainerGrid", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton", { | |
| L"Margin=3,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#MainStack > Windows.UI.Xaml.Controls.Grid > SystemTray.StackListView > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid@ > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background@Normal=Transparent", | |
| L"Background@PointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$trayPointerOver\" />", | |
| L"Background@Pressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$trayPressed\" />", | |
| L"BorderThickness=0", | |
| L"Margin=0", | |
| L"Background@Checked:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$trayPointerOver\" />", | |
| L"Background@CheckedPointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$trayPointerOver\" />", | |
| L"Background@CheckedPressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$trayPressed\" />", | |
| L"Width=24"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel@RunningIndicatorStates > Windows.UI.Xaml.Shapes.Rectangle#DefaultIcon", { | |
| L"Visibility=Collapsed", | |
| L"Visibility@NoRunningIndicator=Visible"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel@CommonStates > Windows.UI.Xaml.Shapes.Rectangle#DefaultIcon", { | |
| L"Fill=Transparent", | |
| L"Width=54", | |
| L"Height=54", | |
| L"Fill@InactivePointerOver:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPointerOver\" />", | |
| L"Fill@InactivePressed:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPressed\" />", | |
| L"Transform3D:=<CompositeTransform3D ScaleY=\"1.1\" ScaleX=\"1.04\" TranslateY=\"1\" CenterY=\"27\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#LanguageInnerTextBlock > TextBlock#InnerTextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"Typography.StylisticSet1=true"}}, | |
| ThemeTargetStyles{L"Border#SearchPillBackgroundElement", { | |
| L"BorderBrush=#4F222222", | |
| L"BorderThickness=1"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=TaskViewButton] > Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"BorderBrush@InactivePointerOver:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPointerOver\" />", | |
| L"BorderThickness=2", | |
| L"Background:=<ImageBrush Stretch=\"None\" ImageSource=\"$taskviewIcon\" />", | |
| L"BorderBrush@InactivePressed:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPressed\" />", | |
| L"BorderBrush@ActivePressed:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPressed\" />", | |
| L"BorderBrush@ActivePointerOver:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPointerOver\" />", | |
| L"BorderBrush@ActiveNormal=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=TaskViewButton] > Taskbar.TaskListButtonPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton#SearchBoxButton[AutomationProperties.AutomationId=SearchButton] > Taskbar.TaskListButtonPanel@CommonStates > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"BorderBrush@InactivePointerOver_SearchIcon:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPointerOver\" />", | |
| L"BorderBrush@InactivePressed_SearchIcon:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPressed\" />", | |
| L"BorderBrush@ActivePressed_SearchIcon:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPressed\" />", | |
| L"BorderBrush@ActivePointerOver_SearchIcon:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$taskbandNotRunningPointerOver\" />", | |
| L"BorderBrush@ActiveNormal_SearchIcon=Transparent", | |
| L"BorderThickness@InactivePointerOver_SearchIcon=2", | |
| L"BorderThickness@InactivePressed_SearchIcon=2", | |
| L"BorderThickness@ActivePressed_SearchIcon=2", | |
| L"BorderThickness@ActivePointerOver_SearchIcon=2", | |
| L"Background@ActiveNormal_SearchIcon:=<ImageBrush Stretch=\"None\" ImageSource=\"$searchIcon\" />", | |
| L"Background@InactivePointerOver_SearchIcon:=<ImageBrush Stretch=\"None\" ImageSource=\"$searchIcon\" />", | |
| L"Background@InactivePressed_SearchIcon:=<ImageBrush Stretch=\"None\" ImageSource=\"$searchIcon\" />", | |
| L"Background@ActivePressed_SearchIcon:=<ImageBrush Stretch=\"None\" ImageSource=\"$searchIcon\" />", | |
| L"Background@ActivePointerOver_SearchIcon:=<ImageBrush Stretch=\"None\" ImageSource=\"$searchIcon\" />", | |
| L"Background@InactiveNormal_SearchIcon:=<ImageBrush Stretch=\"None\" ImageSource=\"$searchIcon\" />", | |
| L"Height=30", | |
| L"Height@ActiveNormal_SearchIcon=Auto", | |
| L"Height@InactivePointerOver_SearchIcon=Auto", | |
| L"Height@InactivePressed_SearchIcon=Auto", | |
| L"Height@ActivePressed_SearchIcon=Auto", | |
| L"Height@ActivePointerOver_SearchIcon=Auto", | |
| L"Height@InactiveNormal_SearchIcon=Auto"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton#SearchBoxButton[AutomationProperties.AutomationId=SearchButton] > Taskbar.TaskListButtonPanel@CommonStates > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer", { | |
| L"Visibility@ActiveNormal_SearchIcon=Collapsed", | |
| L"Visibility@InactivePointerOver_SearchIcon=Collapsed", | |
| L"Visibility@InactivePressed_SearchIcon=Collapsed", | |
| L"Visibility@ActivePressed_SearchIcon=Collapsed", | |
| L"Visibility@ActivePointerOver_SearchIcon=Collapsed", | |
| L"Visibility@InactiveNormal_SearchIcon=Collapsed"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView > Windows.UI.Xaml.Controls.Grid@ > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background@CheckedPressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPressed\" />", | |
| L"Background@CheckedPointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPointerOver\" />", | |
| L"Background@CheckedNormal:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPointerOver\" />", | |
| L"BorderThickness=0", | |
| L"Background@Pressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPressed\" />", | |
| L"Background@PointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$clockPointerOver\" />", | |
| L"Background@Normal=Transparent", | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NonActivatableStack", { | |
| L"Margin=4,0,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton[AutomationProperties.AutomationId=WidgetsButton] > Taskbar.TaskListButtonPanel@CommonStates > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"Background@InactivePointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$widgetsPointerOver\" />", | |
| L"Background@InactivePressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$widgetsPressed\" />", | |
| L"Background@ActivePointerOver:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$widgetsPointerOver\" />", | |
| L"Background@ActivePressed:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$widgetsPressed\" />", | |
| L"Background@ActiveNormal:=<ImageBrush Stretch=\"Fill\" ImageSource=\"$widgetsPointerOver\" />", | |
| L"BorderThickness=0", | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel", { | |
| L"Width=54"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ToolTip > Windows.UI.Xaml.Controls.ContentPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"FontFamily=Segoe UI", | |
| L"Typography.StylisticSet1=true"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.TextBlock#LabelControl", { | |
| L"FontFamily=Segoe UI", | |
| L"Typography.StylisticSet1=true", | |
| L"Foreground=White"}}, | |
| }, { | |
| L"orbNormal=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/orbNormal.png", | |
| L"orbPointerOver=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/orbHover.png", | |
| L"orbPressed=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/orbPressed.png", | |
| L"aeroColor={ThemeResource SystemAccentColor}", | |
| L"aeroOpacity=0.3", | |
| L"reflection=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/AeroPeek.png", | |
| L"taskbandInactiveNormal=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/InactiveNormal.png", | |
| L"taskbandInactivePointerOver=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/InactivePointerOver.png", | |
| L"taskbandInactivePressed=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/ActiveNormal.png", | |
| L"taskbandActiveNormal=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/ActiveNormal.png", | |
| L"taskbandActivePointerOver=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/ActiveNormal.png", | |
| L"taskbandActivePressed=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/ActiveNormal.png", | |
| L"overflowNormal=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/overflowNormal.png", | |
| L"overflowPointerOver=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/overflowPointerOver.png", | |
| L"overflowPressed=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/overflowPressed.png", | |
| L"clockPointerOver=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/clockPointerOver.png", | |
| L"clockPressed=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/clockPressed.png", | |
| L"trayPointerOver=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/trayPointerOver.png", | |
| L"trayPressed=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/trayPressed.png", | |
| L"desktopNormal=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/desktopNormal.png", | |
| L"desktopPointerOver=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/desktopPointerOver.png", | |
| L"desktopPressed=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/desktopPressed.png", | |
| L"desktopWidth=15", | |
| L"taskbandRequestingAttention=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/requestingAttention.png", | |
| L"taskbandNotRunningPointerOver=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/notRunningPointerOver.png", | |
| L"taskbandNotRunningPressed=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/notRunningPressed.png", | |
| L"taskbarBackground=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/taskbarBackground.png", | |
| L"taskviewIcon=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/taskview.png", | |
| L"searchIcon=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/search.png", | |
| L"widgetsPointerOver=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/widgetsPointerOver.png", | |
| L"widgetsPressed=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Windows7/ThemeResources/widgetsPressed.png", | |
| }}; | |
| const Theme Aeris = { | |
| { | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid", { | |
| L"Background:=$taskbarBackground"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid", { | |
| L"Background:=<WindhawkBlur BlurAmount=\"$taskbarBlurIncreace\" TintColor=\"#00000000\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<SolidColorBrush Color=\"$themeColor\" Opacity=\"$themeColorOpacity\"/>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed", | |
| L"Fill:=<SolidColorBrush Color=\"$primaryColor\" Opacity=\"0.05\"/>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel@CommonStates", { | |
| L"Padding=0", | |
| L"Margin=$taskListMargin,0,$taskListMargin,0", | |
| L"Background@ActiveNormal:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>", | |
| L"Background@ActivePointerOver:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>", | |
| L"Background@ActivePressed:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"Background:=$transparent", | |
| L"Background@InactivePointerOver:=$pointerOver", | |
| L"Background@InactivePressed:=$pressed", | |
| L"Background@ActivePointerOver:=$pointerOver", | |
| L"Background@ActivePressed:=$pressed", | |
| L"BorderThickness=0", | |
| L"CornerRadius=0", | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton > Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates", { | |
| L"Padding=0", | |
| L"Margin=$taskListMargin,0,$taskListMargin,0", | |
| L"Background@NoRunningIndicator:=$transparent", | |
| L"Background@InactiveRunningIndicator:=<SolidColorBrush Color=\"$primaryColor\" Opacity=\"0.1\"/>", | |
| L"Background@ActiveRunningIndicator:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>", | |
| L"Background:=<SolidColorBrush Color=\"$requestAttentionColor\" Opacity=\"0.5\"/>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton > Taskbar.TaskListLabeledButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"Background:=$transparent", | |
| L"Background@InactivePointerOver:=$pointerOver", | |
| L"Background@InactivePressed:=$pressed", | |
| L"Background@ActivePointerOver:=$pointerOver", | |
| L"Background@ActivePressed:=$pressed", | |
| L"Background@MultiWindowPointerOver:=$pointerOver", | |
| L"Background@MultiWindowPressed:=$pressed", | |
| L"Background@RequestingAttentionPointerOver:=$pointerOver", | |
| L"Background@RequestingAttentionPressed:=$pressed", | |
| L"Background@RequestingAttentionMultiPointerOver:=$pointerOver", | |
| L"Background@RequestingAttentionMultiPressed:=$pressed", | |
| L"BorderThickness=0", | |
| L"CornerRadius=0", | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Border#MultiWindowElement", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Rectangle#RunningIndicator", { | |
| L"Visibility=Collapsed", | |
| L"Fill:=<SolidColorBrush Color=\"$primaryColor\" Opacity=\"0.2\"/>", | |
| L"VerticalAlignment=0", | |
| L"HorizontalAlignment=Stretch", | |
| L"Margin=0,0,-4,0", | |
| L"Width=Auto", | |
| L"Height=3", | |
| L"RadiusX=0", | |
| L"RadiusY=0", | |
| L"Visibility@MultiWindowNormal=Visible", | |
| L"Visibility@MultiWindowActive=Visible", | |
| L"Visibility@MultiWindowPointerOver=Visible", | |
| L"Visibility@MultiWindowPressed=Visible", | |
| L"Visibility@RequestingAttentionMulti=Visible", | |
| L"Visibility@RequestingAttentionMultiPointerOver=Visible", | |
| L"Visibility@RequestingAttentionMultiPressed=Visible"}}, | |
| ThemeTargetStyles{L"Microsoft.UI.Xaml.Controls.ProgressBar#ProgressIndicator", { | |
| L"VerticalAlignment=Stretch", | |
| L"HorizontalAlignment=Stretch", | |
| L"Margin=0,0,-4,0", | |
| L"Width=Auto", | |
| L"Height=Auto", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"Border#ProgressBarRoot > Border > Grid", { | |
| L"Height=Auto"}}, | |
| ThemeTargetStyles{L"Grid#LayoutRoot@CommonStates > Border#ProgressBarRoot > Border > Grid > Rectangle#ProgressBarTrack", { | |
| L"Margin=0", | |
| L"RadiusX=0", | |
| L"RadiusY=0", | |
| L"Fill:=<SolidColorBrush Color=\"$progressColor\" Opacity=\"0.15\"/>", | |
| L"Fill@Paused:=<SolidColorBrush Color=\"$progressPausedColor\" Opacity=\"0.15\"/>"}}, | |
| ThemeTargetStyles{L"Grid#LayoutRoot@CommonStates > Border#ProgressBarRoot > Border > Grid > Rectangle#DeterminateProgressBarIndicator", { | |
| L"RadiusX=0", | |
| L"RadiusY=0", | |
| L"Fill:=<SolidColorBrush Color=\"$progressColor\" Opacity=\"0.4\"/>", | |
| L"Fill@Paused:=<SolidColorBrush Color=\"$progressPausedColor\" Opacity=\"0.4\"/>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Image", { | |
| L"Transform3D:=<CompositeTransform3D TranslateX=\"2\" TranslateY=\"1\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel > Rectangle#DefaultIcon", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel > AnimatedVisualPlayer", { | |
| L"Transform3D:=<CompositeTransform3D TranslateX=\"0\" TranslateY=\"1\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel", { | |
| L"MinWidth=60", | |
| L"Margin=0,0,$taskListMargin,0"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton > Taskbar.TaskListButtonPanel@CommonStates", { | |
| L"Padding=0", | |
| L"Margin=$taskListMargin,0,$taskListMargin,0", | |
| L"Background@ActiveNormal_SearchIcon:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>", | |
| L"Background@ActivePointerOver_SearchIcon:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>", | |
| L"Background@ActivePressed_SearchIcon:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxLaunchListButton > Taskbar.TaskListButtonPanel", { | |
| L"Padding=0", | |
| L"Margin=$taskListMargin,0,$taskListMargin,0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid@CommonStates", { | |
| L"Padding=0", | |
| L"Margin=$taskListMargin,0,$taskListMargin,0", | |
| L"Background@ActiveNormal:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>", | |
| L"Background@ActivePointerOver:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>", | |
| L"Background@ActivePressed:=<SolidColorBrush Color=\"$activeColor\" Opacity=\"0.5\"/>"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxButton > Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"BorderThickness=0", | |
| L"CornerRadius=0", | |
| L"Margin=0", | |
| L"Background@InactiveNormal_SearchIcon:=$transparent", | |
| L"Background@InactivePointerOver_SearchIcon:=$pointerOver", | |
| L"Background@InactivePressed_SearchIcon:=$pressed", | |
| L"Background@ActiveNormal_SearchIcon:=$transparent", | |
| L"Background@ActivePointerOver_SearchIcon:=$pointerOver", | |
| L"Background@ActivePressed_SearchIcon:=$pressed"}}, | |
| ThemeTargetStyles{L"Taskbar.SearchBoxLaunchListButton > Taskbar.TaskListButtonPanel > Border#BackgroundElement", { | |
| L"BorderThickness=0", | |
| L"CornerRadius=0", | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid@CommonStates > Border#BackgroundElement", { | |
| L"BorderThickness=0", | |
| L"CornerRadius=0", | |
| L"Margin=0", | |
| L"Background@InactiveNormal:=$transparent", | |
| L"Background@InactivePointerOver:=$pointerOver", | |
| L"Background@InactivePressed:=$pressed", | |
| L"Background@ActiveNormal:=$transparent", | |
| L"Background@ActivePointerOver:=$pointerOver", | |
| L"Background@ActivePressed:=$pressed"}}, | |
| ThemeTargetStyles{L"Border#SearchPillBackgroundElement", { | |
| L"BorderThickness=0", | |
| L"CornerRadius=0", | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"Grid#DynamicSearchBoxGleamContainer", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Grid@ > Border#BackgroundBorder", { | |
| L"Padding=0", | |
| L"CornerRadius=0", | |
| L"Margin=0", | |
| L"BorderThickness=0", | |
| L"Background@PointerOver:=$pointerOver", | |
| L"Background@Pressed:=$pressed"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton > Grid@CommonStates > Border#BackgroundBorder", { | |
| L"Background@PointerOver:=$pointerOver", | |
| L"Background@Pressed:=$pressed"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"MinWidth=$showDesktopWidth", | |
| L"MaxWidth=$showDesktopWidth"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack > Grid > SystemTray.StackListView > Windows.UI.Xaml.Controls.ItemsPresenter > Windows.UI.Xaml.Controls.StackPanel > Windows.UI.Xaml.Controls.ContentPresenter > SystemTray.IconView", { | |
| L"MinWidth=$showDesktopWidth", | |
| L"MaxWidth=$showDesktopWidth"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Grid#ContainerGrid@ > Rectangle#ShowDesktopPipe", { | |
| L"VerticalAlignment=Stretch", | |
| L"HorizontalAlignment=Stretch", | |
| L"Height=Auto", | |
| L"Width=Auto", | |
| L"Fill@PointerOver:=$pointerOver", | |
| L"Fill@Pressed:=$pressed"}}, | |
| }, { | |
| L"themeColor={ThemeResource SystemAccentColorDark1}", | |
| L"themeColorOpacity=0", | |
| L"primaryColor={ThemeResource TextFillColorPrimary}", | |
| L"activeColor=#33AAFF", | |
| L"requestAttentionColor=#FF7788", | |
| L"progressColor=#44CC66", | |
| L"progressPausedColor=#EECC44", | |
| L"taskbarBackground=<AcrylicBrush TintColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" FallbackColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" TintOpacity=\"0\" TintLuminosityOpacity=\"0.8\" Opacity=\"1\"/>", | |
| L"taskbarBlurIncreace=0", | |
| L"taskListMargin=2", | |
| L"showDesktopWidth=10", | |
| L"transparent=<SolidColorBrush Color=\"{ThemeResource TextFillColorPrimary}\" Opacity=\"0\"/>", | |
| L"pointerOver=<SolidColorBrush Color=\"{ThemeResource TextFillColorPrimary}\" Opacity=\"0.075\"/>", | |
| L"pressed=<SolidColorBrush Color=\"{ThemeResource TextFillColorPrimary}\" Opacity=\"0.05\"/>", | |
| }}; | |
| const Theme Plasma = { | |
| { | |
| ThemeTargetStyles{L"Taskbar.TaskListButton > Taskbar.TaskListLabeledButtonPanel", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton > Taskbar.TaskListLabeledButtonPanel@CommonStates > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=0", | |
| L"BorderThickness=1,0,1,0", | |
| L"BorderBrush=Transparent", | |
| L"Background@ActiveNormal:=$taskbandActive", | |
| L"Background@InactiveNormal:=$taskbandInactiveNormal", | |
| L"Background@ActivePointerOver:=$taskbandPointerOver", | |
| L"Background@MultiWindowNormal:=$taskbandInactiveNormal", | |
| L"Background@MultiWindowPointerOver:=$taskbandPointerOver", | |
| L"Background@InactivePointerOver:=$taskbandPointerOver", | |
| L"Background@ActivePressed:=$taskbandPointerOver", | |
| L"Background@InactivePressed:=$taskbandPointerOver", | |
| L"Margin=0", | |
| L"Background@MultiWindowPressed:=$taskbandPointerOver", | |
| L"Background@MultiWindowActive:=$taskbandActive", | |
| L"Background@RequestingAttention:=$taskbandAttention", | |
| L"Background@RequestingAttentionPointerOver:=$taskbandPointerOver", | |
| L"Background@RequestingAttentionPressed:=$taskbandPointerOver", | |
| L"Background@RequestingAttentionMulti:=$taskbandAttention", | |
| L"Background@RequestingAttentionMultiPointerOver:=$taskbandPointerOver", | |
| L"Background@RequestingAttentionMultiPressed:=$taskbandPointerOver"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton > Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"Opacity@NoRunningIndicator=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Windows.UI.Xaml.Controls.Image#Icon", { | |
| L"RenderTransform:=<TranslateTransform X=\"2\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Windows.UI.Xaml.Shapes.Rectangle#RunningIndicator", { | |
| L"Width=50", | |
| L"RadiusX=0", | |
| L"RadiusY=0", | |
| L"Height=3", | |
| L"VerticalAlignment=Top", | |
| L"RenderTransform:=<TranslateTransform X=\"2\" />", | |
| L"Margin=-1,0,-1,0", | |
| L"Fill@ActiveNormal:=$indicatorActive", | |
| L"Fill@ActivePointerOver:=$indicatorPointerOver", | |
| L"Fill:=$indicatorInactive", | |
| L"Fill@InactivePointerOver:=$indicatorPointerOver", | |
| L"Fill@ActivePressed:=$indicatorPointerOver", | |
| L"Fill@InactivePressed:=$indicatorPointerOver", | |
| L"Fill@MultiWindowNormal:=$indicatorInactive", | |
| L"Fill@MultiWindowPointerOver:=$indicatorPointerOver", | |
| L"Fill@MultiWindowPressed:=$indicatorPointerOver", | |
| L"Fill@MultiWindowActive:=$indicatorActive", | |
| L"Fill@RequestingAttention:=$indicatorAttention", | |
| L"Fill@RequestingAttentionPointerOver:=$indicatorPointerOver", | |
| L"Fill@RequestingAttentionPressed:=$indicatorPointerOver", | |
| L"Fill@RequestingAttentionMulti:=$indicatorAttention", | |
| L"Fill@RequestingAttentionMultiPointerOver:=$indicatorPointerOver", | |
| L"Fill@RequestingAttentionMultiPressed:=$indicatorPointerOver"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=$WindhawkBlur"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#MultiWindowElement", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Windows.UI.Xaml.Shapes.Rectangle#DefaultIcon", { | |
| L"Fill:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"$plusIndicator\" />", | |
| L"Width=11", | |
| L"Height=11", | |
| L"RadiusX=0", | |
| L"RadiusY=0", | |
| L"VerticalAlignment=Bottom", | |
| L"RenderTransform:=<TranslateTransform X=\"1\" />", | |
| L"Visibility@MultiWindowNormal=Visible", | |
| L"Visibility@MultiWindowActive=Visible", | |
| L"Visibility@MultiWindowPointerOver=Visible", | |
| L"HorizontalAlignment=Center", | |
| L"Visibility@MultiWindowPressed=Visible", | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel", { | |
| L"Padding=0", | |
| L"Width=50"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel@CommonStates > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=0", | |
| L"BorderThickness=0", | |
| L"Width=32", | |
| L"Background=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel@CommonStates", { | |
| L"BorderThickness@ActiveNormal=0,3,0,0", | |
| L"Width=50", | |
| L"BorderBrush:=$selectionBorder", | |
| L"BorderThickness@ActivePointerOver=0,3,0,0", | |
| L"BorderThickness@ActivePressed=0,3,0,0"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton#LaunchListButton[AutomationProperties.AutomationId=StartButton] > Taskbar.TaskListButtonPanel > Border#BackgroundElement", { | |
| L"Background:=<ImageBrush Stretch=\"Uniform\" ImageSource=\"https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Plasma/ThemeResources/$StartButton.png\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton[AutomationProperties.AutomationId=WidgetsButton] > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel", { | |
| L"Width=Auto"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NotifyIconStack", { | |
| L"Grid.Column=5"}}, | |
| ThemeTargetStyles{L"SystemTray.NotificationAreaIcons#NotificationAreaIcons", { | |
| L"Grid.Column=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton", { | |
| L"Grid.Column=1"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background=Transparent", | |
| L"Margin=1,0,1,0", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ContainerGrid@ > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"BorderBrush@CheckedNormal:=$selectionBorderExtended", | |
| L"BorderThickness@CheckedNormal:=0,3,0,0", | |
| L"BorderBrush@CheckedPointerOver:=$selectionBorderExtended", | |
| L"BorderThickness@CheckedPointerOver:=0,3,0,0", | |
| L"BorderBrush@CheckedPressed:=$selectionBorderExtended", | |
| L"BorderThickness@CheckedPressed:=0,3,0,0", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton > Windows.UI.Xaml.Controls.Grid@CommonStates > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"BorderBrush@Checked:=$selectionBorderExtended", | |
| L"BorderThickness@Checked:=0,3,0,0", | |
| L"BorderBrush@CheckedPointerOver:=$selectionBorderExtended", | |
| L"BorderThickness@CheckedPointerOver:=0,3,0,0", | |
| L"BorderBrush@CheckedPressed:=$selectionBorderExtended", | |
| L"BorderThickness@CheckedPressed:=0,3,0,0", | |
| L"BorderThickness=0"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.TextBlock#TimeInnerTextBlock", { | |
| L"FontSize=17.33", | |
| L"TextAlignment=Center", | |
| L"FontFamily=Noto Sans, Segoe UI", | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.TextBlock#DateInnerTextBlock", { | |
| L"FontSize=13.33", | |
| L"TextAlignment=Center", | |
| L"FontFamily=Noto Sans, Segoe UI", | |
| L"Margin=0,-5,0,0", | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"SystemTray.DateTimeIconContent > Windows.UI.Xaml.Controls.Grid#ContainerGrid", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.ContentPresenter#ContentPresenter > Windows.UI.Xaml.Controls.Grid#ContentGrid > SystemTray.TextIconContent > Windows.UI.Xaml.Controls.Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > Windows.UI.Xaml.Controls.TextBlock#InnerTextBlock", { | |
| L"FontSize=17.33", | |
| L"Foreground=White"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"Margin=-5,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"MinWidth=28"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"Width=48", | |
| L"Height=Auto"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView[AutomationProperties.Name=Show Desktop]", { | |
| L"Width=48"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#ShowDesktopPipe", { | |
| L"Width=48", | |
| L"Height=50", | |
| L"Fill:=<ImageBrush Stretch=\"None\" ImageSource=\"$desktopButton\" />"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background=Transparent", | |
| L"Margin=1,0,1,0", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background=Transparent", | |
| L"Margin=1,0,1,0", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#NonActivatableStack", { | |
| L"Grid.Column=3"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Background=Transparent", | |
| L"Margin=1,0,1,0", | |
| L"CornerRadius=0"}}, | |
| ThemeTargetStyles{L"SystemTray.StackListView[AutomationProperties.AutomationId=Main]", { | |
| L"Margin=-8,0,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.AdaptiveTextBlock#LanguageInnerTextBlock > Windows.UI.Xaml.Controls.TextBlock", { | |
| L"FontFamily=Noto Sans, Segoe UI"}}, | |
| }, { | |
| L"taskbandInactiveNormal=<SolidColorBrush Color=\"Gray\" Opacity=\"0.25\" />", | |
| L"taskbandPointerOver=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" Opacity=\"0.4\" />", | |
| L"taskbandActive=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight1}\" Opacity=\"0.5\" />", | |
| L"indicatorActive=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\" Opacity=\"0.7\" />", | |
| L"indicatorInactive=<SolidColorBrush Color=\"Gray\" Opacity=\"0.7\" />", | |
| L"indicatorPointerOver=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\" Opacity=\"0.8\" />", | |
| L"taskbandAttention=<SolidColorBrush Color=\"#ce640c\" Opacity=\"0.5\" />", | |
| L"indicatorAttention=<SolidColorBrush Color=\"#ce640c\" Opacity=\"0.9\" />", | |
| L"selectionBorder=<LinearGradientBrush StartPoint='0,0' EndPoint='1,0'><GradientStop Color='Transparent' Offset='0.0' /><GradientStop Color='Transparent' Offset='0.2' /><GradientStop Color='{ThemeResource SystemAccentColorLight2}' Offset='0.2' /><GradientStop Color='{ThemeResource SystemAccentColorLight2}' Offset='0.8' /><GradientStop Color='Transparent' Offset='0.8' /><GradientStop Color='Transparent' Offset='1.0' /></LinearGradientBrush>", | |
| L"selectionBorderExtended=<SolidColorBrush Color=\"{ThemeResource SystemAccentColorLight2}\" />", | |
| L"desktopButton=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Plasma/ThemeResources/desktop.png", | |
| L"plusIndicator=https://raw.githubusercontent.com/ramensoftware/windows-11-taskbar-styling-guide/refs/heads/main/Themes/Plasma/ThemeResources/plus.png", | |
| L"StartButton=default", | |
| L"WindhawkBlur=<WindhawkBlur BlurAmount=\"30\" TintColor=\"#cc2a2e32\" />", | |
| L"Acrylic=<AcrylicBrush TintColor=\"#2a2e32\" TintOpacity=\"0.8\" FallbackColor=\"#2a2e32\" />", | |
| }}; | |
| const Theme WindowGlass = { | |
| { | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame#TaskbarFrame", { | |
| L"MaxWidth:=900", | |
| L"HorizontalAlignment=Auto", | |
| L"Width=Auto", | |
| L"MinWidth:=500"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame#TaskbarFrame > Grid#RootGrid", { | |
| L"Margin=30,0,30,5", | |
| L"BorderThickness=$BorderThickness", | |
| L"BorderBrush:=$BorderBrush", | |
| L"CornerRadius=$CornerRadius", | |
| L"Background:=Transparent"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundFill", { | |
| L"Visibility=Visible", | |
| L"Fill:=$Background"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton > Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel", { | |
| L"Margin=4", | |
| L"Background:=$ElementBG", | |
| L"CornerRadius=12"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Margin=0,7,20,7", | |
| L"RenderTransform:=<TranslateTransform X=\"-105\" Y=\"-2\"/>", | |
| L"Padding=0", | |
| L"Background:=$ElementBG", | |
| L"CornerRadius=12"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"Padding=$TrayPadding", | |
| L"CornerRadius=10"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"Padding=$TrayPadding", | |
| L"CornerRadius=10"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton", { | |
| L"Padding=$TrayPadding", | |
| L"CornerRadius=10"}}, | |
| ThemeTargetStyles{L"SystemTray.CopilotIcon", { | |
| L"Padding=$TrayPadding"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > systemtray:IconView#SystemTrayIcon > Grid", { | |
| L"Padding=$TrayPadding"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Grid#ContainerGrid > ContentPresenter#ContentPresenter > Grid#ContentGrid > SystemTray.TextIconContent > Grid#ContainerGrid", { | |
| L"Padding=10", | |
| L"CornerRadius=10"}}, | |
| ThemeTargetStyles{L"SystemTray.StackListView#IconStack > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon", { | |
| L"Padding=0"}}, | |
| ThemeTargetStyles{L"SystemTray.Stack#ShowDesktopStack", { | |
| L"Visibility=Visible"}}, | |
| ThemeTargetStyles{L"Taskbar.Gripper#GripperControl", { | |
| L"Width=Auto", | |
| L"MinWidth=24"}}, | |
| ThemeTargetStyles{L"SystemTray.SystemTrayFrame", { | |
| L"HorizontalAlignment=1", | |
| L"RenderTransform:=<TranslateTransform X=\"399\" />"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#AugmentedEntryPointContentGrid", { | |
| L"Margin=4,0,0,0", | |
| L"HorizontalAlignment=Left"}}, | |
| ThemeTargetStyles{L"TextBlock#TimeInnerTextBlock", { | |
| L"FontSize=13", | |
| L"FontFamily=vivo Sans EN VF", | |
| L"Margin=0", | |
| L"Padding=0", | |
| L"RenderTransform:=<TranslateTransform X=\"0\" Y=\"0\" />"}}, | |
| ThemeTargetStyles{L"TextBlock#DateInnerTextBlock", { | |
| L"Visibility=Collapsed", | |
| L"RenderTransform:=<TranslateTransform X=\"0\" Y=\"-9\" />", | |
| L"FontSize=11", | |
| L"FontFamily=vivo Sans EN VF"}}, | |
| ThemeTargetStyles{L"TextBlock#InnerTextBlock[Text=\uE971]", { | |
| L"Text=\uED14"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ConfirmatorMainGrid", { | |
| L"CornerRadius=22", | |
| L"BorderThickness=$BorderThickness", | |
| L"BorderBrush:=$BorderBrush", | |
| L"Background:=$Background"}}, | |
| ThemeTargetStyles{L"TextBlock#SearchBoxTextBlock", { | |
| L"Text=Search This Precision", | |
| L"FontSize=10", | |
| L"FontFamily=vivo Sans EN VF"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Grid > ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon > Grid > Grid > SystemTray.TextIconContent", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Button", { | |
| L"BorderThickness=$BorderThickness"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#OverflowFlyoutBackgroundBorder", { | |
| L"BorderThickness=$BorderThickness", | |
| L"BorderBrush:=$BorderBrush", | |
| L"Background:=$Background", | |
| L"CornerRadius=$CornerRadius"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.AltTab > Windows.UI.Xaml.Controls.Grid#ModalRootGrid > Border", { | |
| L"BorderThickness=$BorderThickness", | |
| L"BorderBrush:=$BorderBrush", | |
| L"Background:=<AcrylicBrush TintColor=\"#10000020\"/>", | |
| L"CornerRadius=20"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.VirtualDesktopBarElement#VirtualDesktopBar", { | |
| L"CornerRadius=$CornerRadius", | |
| L"Background:=$Background"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#BackgroundDimmingLayer", { | |
| L"Background:=$Background"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=10"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton#TaskListButton", { | |
| L"CornerRadius=10"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SnapBarBorder", { | |
| L"Background:=$Background", | |
| L"BorderBrush:=$BorderBrush", | |
| L"CornerRadius=$CornerRadius", | |
| L"BorderThickness=$BorderThickness", | |
| L"RenderTransform:=<TranslateTransform X=\"0\" Y=\"10\" />", | |
| L"Margin=0,0,0,-10"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SnapPickerBorder", { | |
| L"Background:=$Background", | |
| L"BorderBrush:=$BorderBrush", | |
| L"CornerRadius=$CornerRadius", | |
| L"BorderThickness=$BorderThickness"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SearchPillBackgroundElement", { | |
| L"BorderBrush:=$ElementBorderBrush", | |
| L"CornerRadius=$ElementCornerRadius", | |
| L"BorderThickness=$ElementBorderThickness", | |
| L"Margin=0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarExtensionElement", { | |
| L"RenderTransform:=<TranslateTransform X=\"0\" Y=\"0\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel", { | |
| L"RenderTransform:=<TranslateTransform X=\"0\" Y=\"0\" />"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ToolTip > Windows.UI.Xaml.Controls.ContentPresenter#LayoutRoot", { | |
| L"Background:=$Background", | |
| L"BorderBrush:=$BorderBrush", | |
| L"BorderThickness:=$BorderThickness", | |
| L"CornerRadius=12"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonControl", { | |
| L"MaxWidth=130", | |
| L"Margin=-1,0,-1,0"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.VirtualDesktopBarElement > Windows.UI.Xaml.Controls.Grid#GridElement > Windows.UI.Xaml.Controls.Border#VirtualDesktopSwitcherBackground", { | |
| L"BorderBrush:=$BorderBrush", | |
| L"BorderThickness=$BorderThickness", | |
| L"CornerRadius=$CornerRadius", | |
| L"Background=Transparent"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.SwitchItemListViewItem > Grid > Border", { | |
| L"Background:=<AcrylicBrush TintColor=\"#10000020\"/>"}}, | |
| ThemeTargetStyles{L"Border#VirtualDesktopBarBackground", { | |
| L"Background:=<AcrylicBrush TintColor=\"#10000020\"/>", | |
| L"BorderBrush:=$BorderBrush", | |
| L"BorderThickness=$BorderThickness", | |
| L"CornerRadius=$CornerRadius"}}, | |
| }, { | |
| L"Background=<WindhawkBlur BlurAmount=\"15\" TintColor=\"#10808080\"/>", | |
| L"BorderBrush2=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"{ThemeResource SystemChromeHighColor}\" Offset=\"0.0\" /><GradientStop Color=\"{ThemeResource SystemChromeLowColor}\" Offset=\"0.25\" /><GradientStop Color=\"{ThemeResource SystemChromeHighColor}\" Offset=\"1\" /></LinearGradientBrush>", | |
| L"BorderThickness=0.3,1,0.3,0.3", | |
| L"CornerRadius=15", | |
| L"BorderBrush=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#50808080\" Offset=\"0.0\" /><GradientStop Color=\"#50404040\" Offset=\"0.25\" /><GradientStop Color=\"#50808080\" Offset=\"1\" /></LinearGradientBrush>", | |
| L"Background2=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeAltHighColor}\" TintOpacity=\"0.3\" FallbackColor=\"{ThemeResource SystemChromeAltHighColor}\" />", | |
| L"TrayPadding=2", | |
| L"ElementBG=<SolidColorBrush Color=\"{ThemeResource SystemChromeAltHighColor}\" Opacity=\"0.3\" />", | |
| L"ElementBorderThickness=0.3,0.3,0.3,1", | |
| L"ElementBorderBrush=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\"><GradientStop Color=\"#50808080\" Offset=\"1\" /><GradientStop Color=\"#50606060\" Offset=\"0.15\" /></LinearGradientBrush>", | |
| L"ElementCornerRadius=12", | |
| }}; | |
| const Theme Surface = {{ | |
| ThemeTargetStyles{L"Grid#RootGrid > Taskbar.TaskbarBackground > Grid", { | |
| L"CornerRadius=20", | |
| L"BorderThickness=1", | |
| L"Margin=-20,0,-20,0", | |
| L"BorderBrush=#40FFFFFF", | |
| L"Padding=-1"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame", { | |
| L"Width=Auto", | |
| L"HorizontalAlignment=Center"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid", { | |
| L"Visibility=Visible", | |
| L"Margin=0,0,0,10", | |
| L"Padding=20,0,20,0"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Margin=0,0,0,10", | |
| L"CornerRadius=20,0,0,20", | |
| L"BorderThickness=1,1,0,1", | |
| L"BorderBrush=#66FFFFFF", | |
| L"Padding=10,5,0,5", | |
| L"Background:=<WindhawkBlur BlurAmount=\"5\" TintColor=\"{ThemeResource SystemChromeAltHighColor}\" TintOpacity=\"0.5\" />", | |
| L"Visibility=Visible"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=<WindhawkBlur BlurAmount=\"5\" TintColor=\"#12FFFFFF\"/>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Border#BackgroundElement", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeAltHighColor}\" TintOpacity=\"0.9\" FallbackColor=\"{ThemeResource SystemChromeMediumColor}\" />", | |
| L"Margin=-1,5.5,1,4", | |
| L"CornerRadius=12", | |
| L"BorderThickness=2,1,0.5,2", | |
| L"BorderBrush:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0.5,1\"><GradientStop Color=\"#00000000\" Offset=\"0\" /><GradientStop Color=\"#33000000\" Offset=\"1.5\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Border#BackgroundElement", { | |
| L"Background:=<AcrylicBrush TintColor=\"{ThemeResource SystemChromeAltHighColor}\" TintOpacity=\"0.8\" FallbackColor=\"{ThemeResource SystemChromeLowColor}\" />", | |
| L"CornerRadius=12", | |
| L"Margin=-1,5.5,2.5,4", | |
| L"BorderThickness=2,1,0.5,2", | |
| L"BorderBrush:=<LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0.5,1\"><GradientStop Color=\"#00000000\" Offset=\"0\" /><GradientStop Color=\"#33000000\" Offset=\"1.5\" /></LinearGradientBrush>"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@CommonStates > Rectangle#RunningIndicator", { | |
| L"Margin=0,0,0,8"}}, | |
| ThemeTargetStyles{L"Border#MultiWindowElement", { | |
| L"Height=0"}}, | |
| }}; | |
| const Theme Oversimplified_Accentuated = { | |
| { | |
| ThemeTargetStyles{L"MenuFlyoutPresenter", { | |
| L"Background:=$DarkAccent", | |
| L"BorderBrush=Transparent", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"ToolTip > ContentPresenter#LayoutRoot", { | |
| L"Background:=$DarkAccent", | |
| L"BorderBrush=Transparent", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=$Alt"}}, | |
| ThemeTargetStyles{L"Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Grid > ContentPresenter#ContentPresenter > ItemsPresenter > StackPanel > ContentPresenter > SystemTray.IconView#SystemTrayIcon > Grid#ContainerGrid > Grid#ContentGrid > SystemTray.TextIconContent > Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > TextBlock#InnerTextBlock", { | |
| L"FontSize=22"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel@RunningIndicatorStates > Rectangle#RunningIndicator", { | |
| L"Fill@ActiveRunningIndicator:=$SolidAccent", | |
| L"Height=4", | |
| L"Width@ActiveRunningIndicator=25"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton > Taskbar.TaskListLabeledButtonPanel > Microsoft.UI.Xaml.Controls.ProgressBar#ProgressIndicator", { | |
| L"MinHeight=4", | |
| L"Width=25"}}, | |
| ThemeTargetStyles{L"Grid#LayoutRoot@CommonStates > Border#ProgressBarRoot > Border > Grid > Rectangle#DeterminateProgressBarIndicator", { | |
| L"Fill@Updating:= <SolidColorBrush Color=\"Green\" Opacity=\"1\" />", | |
| L"Fill@Determinate:= <SolidColorBrush Color=\"Green\" Opacity=\"1\" />", | |
| L"Fill@Paused:= <SolidColorBrush Color=\"Orange\" Opacity=\"1\" />", | |
| L"Fill@Error:= <SolidColorBrush Color=\"Red\" Opacity=\"1\" />", | |
| L"Fill@UpdatingError:= <SolidColorBrush Color=\"Red\" Opacity=\"1\" />"}}, | |
| ThemeTargetStyles{L"Rectangle#ProgressBarTrack", { | |
| L"Fill=Transparent"}}, | |
| ThemeTargetStyles{L"Canvas#HoverFlyoutCanvas > Grid#HoverFlyoutGrid > Border#HoverFlyoutBackground", { | |
| L"BorderBrush=Transparent", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Windows.UI.Xaml.Shapes.Rectangle#BackgroundFill", { | |
| L"Fill:=$DarkAccent"}}, | |
| ThemeTargetStyles{L"Grid#OverflowRootGrid", { | |
| L"Padding:="}}, | |
| ThemeTargetStyles{L"Border#OverflowFlyoutBackgroundBorder", { | |
| L"Background:=$Alt", | |
| L"Shadow:=", | |
| L"BorderThickness:="}}, | |
| ThemeTargetStyles{L"SystemTray.ImageIconContent > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Image", { | |
| L"Height=20", | |
| L"Width=20"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.TextInput.Common.InputSwitcher > ContentControl > ContentPresenter > Grid", { | |
| L"Background:=$DarkAccent", | |
| L"BorderBrush=Transparent", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.TextInput.Common.InputSwitcher > ContentControl > ContentPresenter > Grid > Grid#OverlayPanel", { | |
| L"Background=Transparent", | |
| L"BorderBrush=Transparent"}}, | |
| ThemeTargetStyles{L"Grid > HyperlinkButton#Footer", { | |
| L"HorizontalContentAlignment = 1"}}, | |
| ThemeTargetStyles{L"Grid#ConfirmatorMainGrid", { | |
| L"Background:=$DarkAccent", | |
| L"BorderBrush=Transparent", | |
| L"CornerRadius=15", | |
| L"Margin=0,0,0,5", | |
| L"Padding=4,0,0,0", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Grid#BrightnessConfirmator", { | |
| L"Padding=6,0,16,0"}}, | |
| ThemeTargetStyles{L"Microsoft.UI.Xaml.Controls.AnimatedIcon#BrightnessIcon", { | |
| L"Height=30", | |
| L"Width=30", | |
| L"Margin=0,-1,12,0"}}, | |
| ThemeTargetStyles{L"Microsoft.UI.Xaml.Controls.AnimatedIcon#VolumeIcon", { | |
| L"Height=30", | |
| L"Width=30"}}, | |
| ThemeTargetStyles{L"TextBlock#volumeLevelText", { | |
| L"FontSize=15"}}, | |
| ThemeTargetStyles{L"Rectangle#HorizontalDecreaseRect", { | |
| L"Height=6", | |
| L"Margin= 0,2,0,0"}}, | |
| ThemeTargetStyles{L"Rectangle#HorizontalTrackRect", { | |
| L"Fill=Transparent", | |
| L"Height=6"}}, | |
| ThemeTargetStyles{L"Grid#HorizontalTemplate > Rectangle#HorizontalDecreaseRect", { | |
| L"Fill:= <AcrylicBrush TintColor=\"{ThemeResource SystemAccentColor}\" TintOpacity=\"1\" TintLuminosityOpacity=\"1\" FallbackColor=\"{ThemeResource SystemAccentColorDark2}\" />"}}, | |
| ThemeTargetStyles{L"Grid#ModalRootGrid > Border#BackgroundElement", { | |
| L"Background:=$DarkAccent", | |
| L"BorderBrush=Transparent", | |
| L"CornerRadius=20", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Border#BackgroundDimmingLayer", { | |
| L"Background:= <WindhawkBlur BlurAmount=\"30\" TintColor=\"#00000080\" />"}}, | |
| ThemeTargetStyles{L"Border#VirtualDesktopBarBackground", { | |
| L"Background:= <SolidColorBrush Color=\"{ThemeResource SystemAccentColorDark1}\" Opacity=\"0.4\" />", | |
| L"BorderBrush=Transparent"}}, | |
| }, { | |
| L"Alt= <AcrylicBrush TintColor=\"{ThemeResource SystemAltHighColor}\" TintOpacity=\"0.6\" TintLuminosityOpacity=\"0.6\" FallbackColor=\"{ThemeResource SystemAltHighColor}\" />", | |
| L"Accent = <AcrylicBrush TintColor=\"{ThemeResource SystemAccentColor}\" TintOpacity=\"0.6\" TintLuminosityOpacity=\"0.6\" FallbackColor=\"{ThemeResource SystemAccentColor}\" />", | |
| L"DarkAccent = <AcrylicBrush TintColor=\"{ThemeResource SystemAccentColorDark1}\" TintOpacity=\"0.6\" TintLuminosityOpacity=\"0.3\" FallbackColor=\"{ThemeResource SystemAccentColorDark1}\" />", | |
| L"SolidAccent = <SolidColorBrush Color=\"{ThemeResource SystemAccentColor}\" Opacity=\"1\" />", | |
| L"Reveal= <RevealBorderBrush Color=\"Transparent\" TargetTheme=\"1\" Opacity=\"1\" />", | |
| }}; | |
| const Theme Luminosity_variant_Dock = { | |
| { | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=$mbg"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid#SearchBoxButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SearchPillBackgroundElement", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#MultiWindowElement", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=0,1,0,1"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=0,0,2,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"Border#OverflowFlyoutBackgroundBorder", { | |
| L"Background:=$mbg", | |
| L"CornerRadius:=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ConfirmatorMainGrid", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#HorizontalTrackRect", { | |
| L"Fill:=#10FFFFFF"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=$t"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#HoverFlyoutGrid > Windows.UI.Xaml.Controls.Border#HoverFlyoutBackground", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid@CommonStates > Border#BackgroundBorder", { | |
| L"Background=$t", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness@Normal=0", | |
| L"BorderBrush@Normal=$t", | |
| L"BorderThickness@PointerOver=0.05,0,0.05,2", | |
| L"BorderBrush@PointerOver:=<SolidColorBrush Color=\"{StaticResource SystemAccentColor}\" Opacity=\"0.8\" />"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Button#CloseButton", { | |
| L"CornerRadius=$mcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ContentPresenter#BorderElement", { | |
| L"CornerRadius=16", | |
| L"Margin=-1,-1,-1,-1"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ModalRootGrid > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#BackgroundDimmingLayer", { | |
| L"Background:=<WindhawkBlur BlurAmount=\"0\" TintColor=\"#00000000\" />"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.VirtualDesktopBarElement#VirtualDesktopBar > Grid > Border", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.VirtualDesktopBarElement#VirtualDesktopBar", { | |
| L"MaxWidth:=900", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#MainGrid", { | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Button#VirtualDesktopElementCloseButton", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SnapBarBorder", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"RenderTransform:=<TranslateTransform X=\"0\" Y=\"-20\" />", | |
| L"Margin=0,0,0,-10", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SnapPickerBorder", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.FlyoutPresenter > Border", { | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter", { | |
| L"CornerRadius=$mcr", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter > Border", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.MenuFlyoutItem", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.MenuFlyoutSubItem", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ToolTip > Windows.UI.Xaml.Controls.ContentPresenter#LayoutRoot", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"ScrollViewer#MenuFlyoutPresenterScrollViewer > Border > Grid > ScrollContentPresenter > ItemsPresenter > StackPanel", { | |
| L"ChildrenTransitions:=$AnimationSettings"}}, | |
| ThemeTargetStyles{L"Grid#LayoutRoot", { | |
| L"BackgroundTransition:=<BrushTransition Duration=\"0:0:0.100\" />"}}, | |
| ThemeTargetStyles{L"Border#BackgroundBorder", { | |
| L"BackgroundTransition:=<BrushTransition Duration=\"0:0:0.100\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame#TaskbarFrame", { | |
| L"Height=53", | |
| L"Margin=250,0,250,0"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame#TaskbarFrame > Grid#RootGrid", { | |
| L"Background:=$mbg", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush:=$bb", | |
| L"CornerRadius=$mcr", | |
| L"Margin=0,0,500,5"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#BackgroundControl > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Shapes.Rectangle#BackgroundStroke", { | |
| L"Visibility=Collapsed"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Margin=-307,-2,250,4", | |
| L"HorizontalAlignment=Right"}}, | |
| }, { | |
| L"mbg=<AcrylicBrush TintColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" FallbackColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" TintOpacity=\"0.0\" TintLuminosityOpacity=\"1.0\" Opacity=\"1\"/>", | |
| L"bcr=10", | |
| L"wcr=20", | |
| L"mcr=15", | |
| L"t=Transparent", | |
| L"bb=#20FFFFFF", | |
| L"bt=1", | |
| L"AnimationSettings=<TransitionCollection><EntranceThemeTransition IsStaggeringEnabled=\"True\" FromHorizontalOffset=\"-50\" FromVerticalOffset=\"50\" /></TransitionCollection>", | |
| }}; | |
| const Theme Luminosity_variant_Classic = { | |
| { | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=$mbg"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid#SearchBoxButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SearchPillBackgroundElement", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#MultiWindowElement", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=0,1,0,1"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=0,0,2,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"Border#OverflowFlyoutBackgroundBorder", { | |
| L"Background:=$mbg", | |
| L"CornerRadius:=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ConfirmatorMainGrid", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#HorizontalTrackRect", { | |
| L"Fill:=#10FFFFFF"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=$t"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#HoverFlyoutGrid > Windows.UI.Xaml.Controls.Border#HoverFlyoutBackground", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid@CommonStates > Border#BackgroundBorder", { | |
| L"Background=$t", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness@Normal=0", | |
| L"BorderBrush@Normal=$t", | |
| L"BorderThickness@PointerOver=0.05,0,0.05,2", | |
| L"BorderBrush@PointerOver:=<SolidColorBrush Color=\"{StaticResource SystemAccentColor}\" Opacity=\"0.8\" />"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Button#CloseButton", { | |
| L"CornerRadius=$mcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ContentPresenter#BorderElement", { | |
| L"CornerRadius=16", | |
| L"Margin=-1,-1,-1,-1"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ModalRootGrid > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#BackgroundDimmingLayer", { | |
| L"Background:=<WindhawkBlur BlurAmount=\"0\" TintColor=\"#00000000\" />"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.VirtualDesktopBarElement#VirtualDesktopBar > Grid > Border", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.VirtualDesktopBarElement#VirtualDesktopBar", { | |
| L"MaxWidth:=900", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#MainGrid", { | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Button#VirtualDesktopElementCloseButton", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SnapBarBorder", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"RenderTransform:=<TranslateTransform X=\"0\" Y=\"-20\" />", | |
| L"Margin=0,0,0,-10", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SnapPickerBorder", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.FlyoutPresenter > Border", { | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter", { | |
| L"CornerRadius=$mcr", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter > Border", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.MenuFlyoutItem", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.MenuFlyoutSubItem", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ToolTip > Windows.UI.Xaml.Controls.ContentPresenter#LayoutRoot", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"ScrollViewer#MenuFlyoutPresenterScrollViewer > Border > Grid > ScrollContentPresenter > ItemsPresenter > StackPanel", { | |
| L"ChildrenTransitions:=$AnimationSettings"}}, | |
| ThemeTargetStyles{L"Grid#LayoutRoot", { | |
| L"BackgroundTransition:=<BrushTransition Duration=\"0:0:0.100\" />"}}, | |
| ThemeTargetStyles{L"Border#BackgroundBorder", { | |
| L"BackgroundTransition:=<BrushTransition Duration=\"0:0:0.100\" />"}}, | |
| ThemeTargetStyles{L"Microsoft.UI.Xaml.Controls.ItemsRepeater#TaskbarFrameRepeater", { | |
| L"Margin=0,1,0,0"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"Margin=0,1,2,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Margin=2,5,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Margin=2,5,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Margin=2,5,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"Margin=2,5,2,4"}}, | |
| }, { | |
| L"mbg=<AcrylicBrush TintColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" FallbackColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" TintOpacity=\"0.0\" TintLuminosityOpacity=\"1.0\" Opacity=\"1\"/>", | |
| L"bcr=10", | |
| L"wcr=20", | |
| L"mcr=15", | |
| L"t=Transparent", | |
| L"bb=#20FFFFFF", | |
| L"bt=1", | |
| L"AnimationSettings=<TransitionCollection><EntranceThemeTransition IsStaggeringEnabled=\"True\" FromHorizontalOffset=\"-50\" FromVerticalOffset=\"50\" /></TransitionCollection>", | |
| }}; | |
| const Theme Luminosity_variant_Compact = { | |
| { | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame > Grid#RootGrid > Taskbar.TaskbarBackground > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=$mbg"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid#SearchBoxButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SearchPillBackgroundElement", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#MultiWindowElement", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=0,1,0,1"}}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=0,0,2,0"}}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.IconView#SystemTrayIcon > Windows.UI.Xaml.Controls.Grid#ContainerGrid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#ControlCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"SystemTray.OmniButton#NotificationCenterButton > Windows.UI.Xaml.Controls.Grid > Windows.UI.Xaml.Controls.Border#BackgroundBorder", { | |
| L"CornerRadius=$bcr", | |
| L"Margin=2,4,2,4"}}, | |
| ThemeTargetStyles{L"Border#OverflowFlyoutBackgroundBorder", { | |
| L"Background:=$mbg", | |
| L"CornerRadius:=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ConfirmatorMainGrid", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Shapes.Rectangle#HorizontalTrackRect", { | |
| L"Fill:=#10FFFFFF"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#HoverFlyoutBackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Fill:=$t"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#HoverFlyoutGrid > Windows.UI.Xaml.Controls.Border#HoverFlyoutBackground", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Taskbar.TaskItemThumbnailView > Grid@CommonStates > Border#BackgroundBorder", { | |
| L"Background=$t", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness@Normal=0", | |
| L"BorderBrush@Normal=$t", | |
| L"BorderThickness@PointerOver=0.05,0,0.05,2", | |
| L"BorderBrush@PointerOver:=<SolidColorBrush Color=\"{StaticResource SystemAccentColor}\" Opacity=\"0.8\" />"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Button#CloseButton", { | |
| L"CornerRadius=$mcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ContentPresenter#BorderElement", { | |
| L"CornerRadius=16", | |
| L"Margin=-1,-1,-1,-1"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#ModalRootGrid > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#BackgroundDimmingLayer", { | |
| L"Background:=<WindhawkBlur BlurAmount=\"0\" TintColor=\"#00000000\" />"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.VirtualDesktopBarElement#VirtualDesktopBar > Grid > Border", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$wcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"WindowsInternal.ComposableShell.Experiences.Switcher.VirtualDesktopBarElement#VirtualDesktopBar", { | |
| L"MaxWidth:=900", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Grid#MainGrid", { | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Button#VirtualDesktopElementCloseButton", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SnapBarBorder", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"RenderTransform:=<TranslateTransform X=\"0\" Y=\"-20\" />", | |
| L"Margin=0,0,0,-10", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#SnapPickerBorder", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.FlyoutPresenter > Border", { | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter", { | |
| L"CornerRadius=$mcr", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"MenuFlyoutPresenter > Border", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.MenuFlyoutItem", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.MenuFlyoutSubItem", { | |
| L"CornerRadius=$bcr"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.ToolTip > Windows.UI.Xaml.Controls.ContentPresenter#LayoutRoot", { | |
| L"Background:=$mbg", | |
| L"CornerRadius=$mcr", | |
| L"BorderThickness=$bt", | |
| L"BorderBrush=$bb", | |
| L"Shadow:="}}, | |
| ThemeTargetStyles{L"ScrollViewer#MenuFlyoutPresenterScrollViewer > Border > Grid > ScrollContentPresenter > ItemsPresenter > StackPanel", { | |
| L"ChildrenTransitions:=$AnimationSettings"}}, | |
| ThemeTargetStyles{L"Grid#LayoutRoot", { | |
| L"BackgroundTransition:=<BrushTransition Duration=\"0:0:0.100\" />"}}, | |
| ThemeTargetStyles{L"Border#BackgroundBorder", { | |
| L"BackgroundTransition:=<BrushTransition Duration=\"0:0:0.100\" />"}}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarFrame#TaskbarFrame", { | |
| L"Height=30"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Border#LargeTicker1", { | |
| L"Margin=1,-7,0,0", | |
| L"RenderTransform:=<ScaleTransform ScaleX=\"0.75\" ScaleY=\"0.75\" />"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonRootGrid#SearchBoxButtonRootPanel > Windows.UI.Xaml.Controls.Border#BackgroundElement", { | |
| L"Margin=0,4,0,4"}}, | |
| ThemeTargetStyles{L"SearchUx.SearchUI.SearchButtonControl", { | |
| L"Margin=0,-4,0,-4"}}, | |
| ThemeTargetStyles{L"Microsoft.UI.Xaml.Controls.AnimatedVisualPlayer#Icon", { | |
| L"Width=16", | |
| L"Height=16"}}, | |
| ThemeTargetStyles{L"Windows.UI.Xaml.Controls.Image#Icon", { | |
| L"Width=16", | |
| L"Height=16"}}, | |
| ThemeTargetStyles{L"Grid#SystemTrayFrameGrid", { | |
| L"Margin=0,0,0,18"}}, | |
| ThemeTargetStyles{L"SystemTray.TextIconContent > Grid#ContainerGrid > SystemTray.AdaptiveTextBlock#Base > TextBlock#InnerTextBlock", { | |
| L"FontSize=14"}}, | |
| ThemeTargetStyles{L"SystemTray.ImageIconContent > Grid#ContainerGrid > Image", { | |
| L"Width=14", | |
| L"Height=14"}}, | |
| }, { | |
| L"mbg=<AcrylicBrush TintColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" FallbackColor=\"{ThemeResource CardStrokeColorDefaultSolid}\" TintOpacity=\"0.0\" TintLuminosityOpacity=\"1.0\" Opacity=\"1\"/>", | |
| L"bcr=10", | |
| L"wcr=20", | |
| L"mcr=15", | |
| L"t=Transparent", | |
| L"bb=#20FFFFFF", | |
| L"bt=1", | |
| L"AnimationSettings=<TransitionCollection><EntranceThemeTransition IsStaggeringEnabled=\"True\" FromHorizontalOffset=\"-50\" FromVerticalOffset=\"50\" /></TransitionCollection>", | |
| }}; | |
| const Theme Derek = {{ | |
| ThemeTargetStyles{std::vector<PCWSTR>{ | |
| L"Taskbar.SearchBoxButton", | |
| L"Taskbar.SearchBoxLaunchListButton", | |
| L"SearchUx.SearchUI.SearchButtonRootGrid", | |
| L"Border#SearchPillBackgroundElement", | |
| L"Grid#DynamicSearchBoxGleamContainer", | |
| L"SystemTray.CopilotIcon" | |
| }, { | |
| L"Visibility=$SEARCH_Visibility" | |
| } | |
| }, | |
| ThemeTargetStyles{std::vector<PCWSTR>{ | |
| L"SystemTray.OmniButton#ControlCenterButton SystemTray.IconView#SystemTrayIcon[AutomationProperties.Name=Power]", | |
| L"SystemTrayFrame:has(NotificationAreaIcons NotifyIconView[AutomationProperties.Name^=EarTrumpet]) OmniButton#ControlCenterButton IconView#SystemTrayIcon[AutomationProperties.Name^=Volume Speakers]", | |
| L"Taskbar.AugmentedEntryPointButton[AutomationProperties.AutomationId=WidgetsButton]" | |
| }, { | |
| L"Visibility=Collapsed" | |
| } | |
| }, | |
| // Only show on secondary monitors that are at least 1920 wide (ie: not Portrait mounted) | |
| ThemeTargetStyles{L"TaskbarFrame[@Width>=1920] > Grid > ItemsRepeater > AugmentedEntryPointButton", { | |
| L"Visibility=Visible" | |
| }}, | |
| // Don't show on main monitor because the SystemTray already takes a lot of space | |
| ThemeTargetStyles{L"Grid:has(> SystemTrayFrame > Grid > Stack#NotifyIconStack ChevronIconView) > TaskbarFrame > Grid > ItemsRepeater > AugmentedEntryPointButton", { | |
| L"Visibility=Collapsed" | |
| }}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon", { | |
| L"MinWidth=$ICONTRAY_SZ" | |
| }}, | |
| ThemeTargetStyles{L"SystemTray.NotifyIconView#NotifyItemIcon > Grid > ContentPresenter > Grid > SystemTray.ImageIconContent > Grid", { | |
| L"Margin=0", | |
| L"Padding=0" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#BackgroundControl > Grid", { | |
| L"Background:=<WindhawkBlur TintColor=\"{ThemeResource SystemAccentColorDark3}\" BlurAmount=\"2.5\" TintOpacity=\"$Opacity\" />" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskbarBackground#BackgroundControl > Grid > Rectangle#BackgroundFill", { | |
| L"Opacity=$Opacity" | |
| }}, | |
| ThemeTargetStyles{L"SystemTray.ChevronIconView", { | |
| L"Margin=-2,0,0,0", | |
| L"MinWidth=16", | |
| L"MinHeight=16", | |
| L"Width=24", | |
| L"Height=24", | |
| L"Transform3D:=<CompositeTransform3D TranslateY='-6' TranslateX='0' />" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButton", { | |
| L"Height=$BTN_Height", | |
| L"MinWidth=$BTN_Width" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel", { | |
| L"Padding=0", | |
| L"Margin=2,0,2,0", | |
| L"Width=Auto", | |
| L"CornerRadius=4", | |
| L"Background:=<SolidColorBrush Color='{ThemeResource SystemAccentColorDark2}' Opacity='0.5'/>" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Rectangle#RunningIndicator", { | |
| L"Height=$Height", | |
| L"Width=$Height", | |
| L"Margin=0,0,-5,0" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Image#Icon", { | |
| L"Height=$Height", | |
| L"Width=Auto", | |
| L"Stretch=0", | |
| L"Transform3D:=<CompositeTransform3D TranslateY='0' TranslateX='4' />" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Image#OverlayIcon", { | |
| L"Height=$ICONOVERLAY_SZ", | |
| L"Transform3D:=<CompositeTransform3D TranslateY='-4' TranslateX='-2' />" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > Taskbar.Badge", { | |
| L"Height=$ICONOVERLAY_SZ", | |
| L"Transform3D:=<CompositeTransform3D TranslateY='11' TranslateX='-2' />" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel > TextBlock#LabelControl", { | |
| L"Margin=0", | |
| L"MaxWidth=$BTN_MaxWidth", | |
| L"Transform3D:=<CompositeTransform3D TranslateY='0' TranslateX='8' />" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel@CommonStates > Border#BackgroundElement", { | |
| L"Background@InactiveNormal:=<SolidColorBrush Color='{ThemeResource SystemAccentColorDark2}' Opacity='0.6'/>", | |
| L"Background@ActiveNormal:=<SolidColorBrush Color='#1179FF' Opacity='0.45'/>", | |
| L"Background@ActivePointerOver:=<SolidColorBrush Color='#2299FF' Opacity='0.5'/>", | |
| L"Background@ActivePressed:=<SolidColorBrush Color='{ThemeResource SystemAccentColorDark1}' Opacity='0.4'/>", | |
| L"Background@InactivePointerOver:=<SolidColorBrush Color='#00aa33' Opacity='0.3'/>", | |
| L"Background@InactivePressed:=<SolidColorBrush Color='{ThemeResource SystemAccentColorDark2}' Opacity='0.32'/>", | |
| L"Background@RequestingAttention:=<SolidColorBrush Color='#FF7788' Opacity='0.4'/>", | |
| L"Background@RequestingAttentionPointerOver:=<SolidColorBrush Color='#FF7788' Opacity='0.65'/>", | |
| L"Background@RequestingAttentionPressed:=<SolidColorBrush Color='#FF7788' Opacity='0.5'/>", | |
| L"Background@WindowSharingNormal:=<SolidColorBrush Color='#EECC44' Opacity='0.25'/>", | |
| L"Background@WindowSharingActive:=<SolidColorBrush Color='#EECC44' Opacity='0.4'/>", | |
| L"Background@WindowSharingPointerOver:=<SolidColorBrush Color='#EECC44' Opacity='0.5'/>" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel@CommonStates:not-has( > Rectangle#RunningIndicator) > Border#BackgroundElement", { | |
| L"Background@InactiveNormal:=<SolidColorBrush Color='#000000' Opacity='0.5'/>", | |
| L"Margin@InactiveNormal=0,0,-4,0", | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListLabeledButtonPanel#IconPanel@CommonStates > Rectangle#RunningIndicator", { | |
| // L"Fill:=<SolidColorBrush Color='{ThemeResource SystemAccentColorDark1}' Opacity='0.6'/>", | |
| L"Fill@InactiveNormal:=<SolidColorBrush Color='{ThemeResource SystemAccentColorDark1}' Opacity='0.66'/>", | |
| L"Fill@ActiveNormal:=<SolidColorBrush Color='#001177' Opacity='0.55'/>", | |
| L"Fill@ActivePointerOver:=<SolidColorBrush Color='#002299' Opacity='0.85'/>", | |
| L"Fill@PointerOver:=<SolidColorBrush Color='{ThemeResource SystemAccentColorDark2}' Opacity='0.85'/>", | |
| L"Fill@InactivePointerOver:=<SolidColorBrush Color='#00aa33' Opacity='0.4'/>", | |
| L"Fill@RequestingAttentionPointerOver:=<SolidColorBrush Color='#FF3344' Opacity='0.65'/>", | |
| L"Fill@RequestingAttentionPressed:=<SolidColorBrush Color='#FF3344' Opacity='0.5'/>" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel@CommonStates > Border#BackgroundElement", { | |
| L"Background@InactiveNormal:=<SolidColorBrush Color='#33AAFF' Opacity='0.15'/>", | |
| L"Background@InactivePointerOver:=<SolidColorBrush Color='#33AAFF' Opacity='0.6'/>", | |
| L"Background@InactivePressed:=<SolidColorBrush Color='#44CC66' Opacity='0.4'/>", | |
| L"Background@ActiveNormal:=<SolidColorBrush Color='#33AAFF' Opacity='0.3'/>", | |
| L"Background@ActivePointerOver:=<SolidColorBrush Color='#44CC66' Opacity='0.6'/>", | |
| L"Background@ActivePressed:=<SolidColorBrush Color='#EECC44' Opacity='0.6'/>" | |
| }}, | |
| ThemeTargetStyles{std::vector<PCWSTR>{ | |
| L"SystemTray.OmniButton > Grid@CommonStates", | |
| L"SystemTray.NotifyIconView > Grid@" | |
| }, { | |
| L"Background@PointerOver:=<SolidColorBrush Color='#33AAFF' Opacity='0.25'/>", | |
| L"Background@Pressed:=<SolidColorBrush Color='#33AAFF' Opacity='0.35'/>", | |
| L"Background@Checked:=<SolidColorBrush Color='#33AAFF' Opacity='0.6'/>", | |
| L"Background@CheckedPointerOver:=<SolidColorBrush Color='#44CC66' Opacity='0.5'/>", | |
| L"Background@CheckedPressed:=<SolidColorBrush Color='#44CC66' Opacity='0.4'/>", | |
| L"Background@CheckedNormal:=<SolidColorBrush Color='#44CC66' Opacity='0.3'/>", | |
| L"Background@Unchecked:=<SolidColorBrush Color='#FFAAFF' Opacity='0.6'/>", | |
| L"Background@Dragging:=<SolidColorBrush Color='#EECC44' Opacity='0.3'/>", | |
| L"Background@DraggedPlaceholder:=<SolidColorBrush Color='#EECC44' Opacity='0.4'/>", | |
| } | |
| }, | |
| ThemeTargetStyles{L"Taskbar.TaskListButtonPanel#ExperienceToggleButtonRootPanel", { | |
| L"Width=Auto", | |
| L"Padding=0" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton[AutomationProperties.AutomationId=WidgetsButton]", { | |
| L"Margin=-4", | |
| L"MaxWidth=$WIDGET_MaxWidth", | |
| L"MinWidth=$WIDGET_MinWidth" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.AugmentedEntryPointButton#AugmentedEntryPointButton[AutomationProperties.AutomationId=WidgetsButton] > Taskbar.TaskListButtonPanel", { | |
| L"Padding=0", | |
| L"Height=$Height", | |
| L"MaxWidth=$WIDGET_MaxWidth", | |
| L"MinWidth=$WIDGET_MinWidth" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton[AutomationProperties.AutomationId=StartButton]", { | |
| L"Width=44", | |
| L"Margin=6,1,0,1" | |
| }}, | |
| ThemeTargetStyles{L"Taskbar.ExperienceToggleButton[AutomationProperties.AutomationId=TaskViewButton]", { | |
| L"Width=32", | |
| L"Margin=0,2,5,2" | |
| }}, | |
| ThemeTargetStyles{L"ProgressBar#ProgressIndicator", { | |
| L"VerticalAlignment=Stretch", | |
| L"HorizontalAlignment=Stretch", | |
| // L"Margin=0,0,-$WIDGET_MaxWidth,0", | |
| L"Grid.ColumnSpan=3", | |
| L"Width=Auto", | |
| L"Height=$Height", | |
| L"CornerRadius=0" | |
| }}, | |
| ThemeTargetStyles{L"Border#ProgressBarRoot > Border > Grid", { | |
| L"Height=$Height" | |
| }}, | |
| ThemeTargetStyles{L"Grid#LayoutRoot@CommonStates > Border#ProgressBarRoot > Border > Grid > Rectangle#ProgressBarTrack", { | |
| L"Margin=0", | |
| L"RadiusX=0", | |
| L"RadiusY=0", | |
| L"Fill:=<SolidColorBrush Color='#22AA44' Opacity='0.25'/>", | |
| L"Fill@Paused:=<SolidColorBrush Color='#EECC44' Opacity='0.25'/>", | |
| L"Fill@Error:=<SolidColorBrush Color='#EE4444' Opacity='0.25'/>", | |
| }}, | |
| ThemeTargetStyles{L"Grid#LayoutRoot@CommonStates > Border#ProgressBarRoot > Border > Grid > Rectangle#DeterminateProgressBarIndicator", { | |
| L"Fill@Updating:= <SolidColorBrush Color='Green' Opacity='1' />", | |
| L"Fill@Determinate:= <SolidColorBrush Color='Green' Opacity='1' />", | |
| L"Fill@Paused:= <SolidColorBrush Color='Orange' Opacity='1' />", | |
| L"Fill@Error:= <SolidColorBrush Color='Red' Opacity='1' />", | |
| L"Fill@UpdatingError:= <SolidColorBrush Color='Red' Opacity='1' />" | |
| }}, | |
| }, { | |
| L"Opacity=0.25", | |
| L"Height=30", | |
| L"BTN_Height=28", | |
| L"BTN_MaxWidth=200", | |
| L"BTN_Width=36", | |
| L"ICONTRAY_SZ=20", | |
| L"ICONOVERLAY_SZ=12", | |
| L"WIDGET_MinWidth=60", | |
| L"WIDGET_MaxWidth=150", | |
| L"SEARCH_Visibility=Collapsed", | |
| } | |
| }; | |
| } allThemesStruct; | |
| return allThemesStruct; | |
| // clang-format on | |
| }(); | |
| std::atomic<bool> g_initialized; | |
| thread_local bool g_initializedForThread; | |
| HANDLE g_restartExplorerPromptThread; | |
| std::atomic<HWND> g_restartExplorerPromptWindow; | |
| constexpr WCHAR kRestartExplorerPromptTitle[] = L"Windows 11 Taskbar Styler - Windhawk"; | |
| constexpr WCHAR kRestartExplorerPromptTextFormat[] = L"Restarting Explorer is required for the mod to activate.\n\nDo " | |
| L"you want to restart Explorer now?\n\nStatus code: 0x%08X"; | |
| constexpr WCHAR kRestartExplorerCommand[] = LR"(cmd /c "echo Terminating Explorer...)" | |
| LR"( & taskkill /f /im explorer.exe)" | |
| LR"( & timeout /t 1 /nobreak >nul)" | |
| LR"( & start explorer.exe)" | |
| LR"( & echo Starting Explorer...)" | |
| LR"( & timeout /t 3 /nobreak >nul")"; | |
| void PromptToRestartExplorer(HRESULT statusCode) { | |
| if(g_restartExplorerPromptThread) { | |
| if(WaitForSingleObject(g_restartExplorerPromptThread, 0) != WAIT_OBJECT_0) { return; } | |
| CloseHandle(g_restartExplorerPromptThread); | |
| } | |
| g_restartExplorerPromptThread = CreateThread( | |
| nullptr, 0, | |
| [](LPVOID lpParameter) -> DWORD { | |
| HRESULT statusCode = static_cast<HRESULT>(reinterpret_cast<ULONG_PTR>(lpParameter)); | |
| WCHAR promptText[256]; | |
| _snwprintf_s(promptText, _TRUNCATE, kRestartExplorerPromptTextFormat, statusCode); | |
| TASKDIALOGCONFIG taskDialogConfig{ | |
| .cbSize = sizeof(taskDialogConfig), | |
| .dwFlags = TDF_ALLOW_DIALOG_CANCELLATION, | |
| .dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON, | |
| .pszWindowTitle = kRestartExplorerPromptTitle, | |
| .pszMainIcon = TD_INFORMATION_ICON, | |
| .pszContent = promptText, | |
| .pfCallback = [](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData) -> HRESULT { | |
| switch(msg) { | |
| case TDN_CREATED: | |
| g_restartExplorerPromptWindow = hwnd; | |
| SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); | |
| break; | |
| case TDN_DESTROYED: | |
| g_restartExplorerPromptWindow = nullptr; | |
| break; | |
| } | |
| return S_OK; | |
| }, | |
| }; | |
| int button; | |
| if(SUCCEEDED(TaskDialogIndirect(&taskDialogConfig, &button, nullptr, nullptr)) && button == IDYES) { | |
| WCHAR commandLine[ARRAYSIZE(kRestartExplorerCommand)]; | |
| memcpy(commandLine, kRestartExplorerCommand, sizeof(kRestartExplorerCommand)); | |
| STARTUPINFO si = { | |
| .cb = sizeof(si), | |
| }; | |
| PROCESS_INFORMATION pi{}; | |
| if(CreateProcess(nullptr, commandLine, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi)) { | |
| CloseHandle(pi.hThread); | |
| CloseHandle(pi.hProcess); | |
| } | |
| } | |
| return 0; | |
| }, | |
| reinterpret_cast<LPVOID>(static_cast<ULONG_PTR>(statusCode)), 0, nullptr); | |
| } | |
| void ApplyCustomizations(InstanceHandle handle, | |
| winrt::Windows::UI::Xaml::FrameworkElement element, | |
| PCWSTR fallbackClassName); | |
| void CleanupCustomizations(InstanceHandle handle); | |
| void ScheduleHasReevaluation(); | |
| void ReevaluateHasSelectors(); | |
| HMODULE GetCurrentModuleHandle() { | |
| HMODULE module; | |
| if(!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L"", | |
| &module)) { | |
| return nullptr; | |
| } | |
| return module; | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| #pragma region LIBS | |
| //////////////////////////////////////////////////////////////////////////////// | |
| #pragma region winrt_hpp | |
| #include <Unknwn.h> | |
| #include <winrt/base.h> | |
| // forward declare namespaces we alias | |
| namespace winrt | |
| { | |
| namespace Windows | |
| { | |
| namespace Foundation | |
| {} | |
| namespace UI::Xaml | |
| {} | |
| } | |
| } | |
| // alias some long namespaces for convenience | |
| namespace wf = winrt::Windows::Foundation; | |
| namespace wux = winrt::Windows::UI::Xaml; | |
| #pragma endregion // winrt_hpp | |
| #pragma region visualtreewatcher_hpp | |
| #include <winrt/Windows.UI.Xaml.h> | |
| class VisualTreeWatcher : public winrt::implements<VisualTreeWatcher, IVisualTreeServiceCallback2, winrt::non_agile> { | |
| public: | |
| VisualTreeWatcher(winrt::com_ptr<IUnknown> site); | |
| VisualTreeWatcher(const VisualTreeWatcher&) = delete; | |
| VisualTreeWatcher& operator=(const VisualTreeWatcher&) = delete; | |
| VisualTreeWatcher(VisualTreeWatcher&&) = delete; | |
| VisualTreeWatcher& operator=(VisualTreeWatcher&&) = delete; | |
| ~VisualTreeWatcher(); | |
| void UnadviseVisualTreeChange(); | |
| private: | |
| HRESULT STDMETHODCALLTYPE OnVisualTreeChange(ParentChildRelation relation, | |
| VisualElement element, | |
| VisualMutationType mutationType) override; | |
| HRESULT STDMETHODCALLTYPE OnElementStateChanged(InstanceHandle element, | |
| VisualElementState elementState, | |
| LPCWSTR context) noexcept override; | |
| wf::IInspectable FromHandle(InstanceHandle handle) { | |
| wf::IInspectable obj; | |
| winrt::check_hresult( | |
| m_XamlDiagnostics->GetIInspectableFromHandle(handle, reinterpret_cast<::IInspectable**>(winrt::put_abi(obj)))); | |
| return obj; | |
| } | |
| winrt::com_ptr<IXamlDiagnostics> m_XamlDiagnostics = nullptr; | |
| }; | |
| #pragma endregion // visualtreewatcher_hpp | |
| #pragma region visualtreewatcher_cpp | |
| VisualTreeWatcher::VisualTreeWatcher(winrt::com_ptr<IUnknown> site) | |
| : m_XamlDiagnostics(site.as<IXamlDiagnostics>()) { | |
| Wh_Log(L"Constructing VisualTreeWatcher"); | |
| // winrt::check_hresult(m_XamlDiagnostics.as<IVisualTreeService3>()->AdviseVisualTreeChange(this)); | |
| // Calling AdviseVisualTreeChange from the current thread causes the app to | |
| // hang in Advising::RunOnUIThread sometimes. Creating a new thread and | |
| // calling it from there fixes it. | |
| AddRef(); // Must precede CreateThread to prevent Release() racing ahead | |
| HANDLE thread = CreateThread( | |
| nullptr, 0, | |
| [](LPVOID lpParam) -> DWORD { | |
| VisualTreeWatcher* watcher = reinterpret_cast<VisualTreeWatcher*>(lpParam); | |
| HRESULT hr = watcher->m_XamlDiagnostics.as<IVisualTreeService3>()->AdviseVisualTreeChange(watcher); | |
| watcher->Release(); | |
| if(FAILED(hr)) { | |
| Wh_Log(L"AdviseVisualTreeChange failed with error %08X", hr); | |
| PromptToRestartExplorer(hr); | |
| } | |
| return 0; | |
| }, | |
| this, 0, nullptr); | |
| if(thread) { | |
| CloseHandle(thread); | |
| } else { | |
| Release(); // CreateThread failed, undo the AddRef | |
| } | |
| } | |
| VisualTreeWatcher::~VisualTreeWatcher() { Wh_Log(L"Destructing VisualTreeWatcher"); } | |
| void VisualTreeWatcher::UnadviseVisualTreeChange() { | |
| Wh_Log(L"UnadviseVisualTreeChange VisualTreeWatcher"); | |
| HRESULT hr = m_XamlDiagnostics.as<IVisualTreeService3>()->UnadviseVisualTreeChange(this); | |
| if(FAILED(hr)) { Wh_Log(L"UnadviseVisualTreeChange failed with error %08X", hr); } | |
| } | |
| HRESULT | |
| VisualTreeWatcher::OnVisualTreeChange(ParentChildRelation, VisualElement element, VisualMutationType mutationType) { | |
| if(!g_initializedForThread) { Wh_Log(L"NOTE: Not initialized for thread %u", GetCurrentThreadId()); } | |
| try { | |
| if(mutationType == Add) { | |
| const wf::IInspectable inspectable = FromHandle(element.Handle); | |
| wux::FrameworkElement frameworkElement = inspectable.try_as<wux::FrameworkElement>(); | |
| if(frameworkElement) { | |
| // Wh_Log(L"%s %s", element.Type, frameworkElement.Name().c_str()); | |
| ApplyCustomizations(element.Handle, frameworkElement, element.Type); | |
| } | |
| } else if(mutationType == Remove) { | |
| CleanupCustomizations(element.Handle); | |
| } | |
| // Schedule deferred :has() re-evaluation when descendants change. | |
| ScheduleHasReevaluation(); | |
| return S_OK; | |
| } catch(...) { | |
| HRESULT hr = winrt::to_hresult(); | |
| Wh_Log(L"Error %08X", hr); | |
| // Returning an error prevents (some?) further messages, always return | |
| // success. | |
| // return hr; | |
| return S_OK; | |
| } | |
| } | |
| HRESULT VisualTreeWatcher::OnElementStateChanged(InstanceHandle, VisualElementState, LPCWSTR) noexcept { return S_OK; } | |
| #pragma endregion // visualtreewatcher_cpp | |
| #pragma region tap_hpp | |
| #include <ocidl.h> | |
| winrt::com_ptr<VisualTreeWatcher> g_visualTreeWatcher; | |
| // {C85D8CC7-5463-40E8-A432-F5916B6427E5} | |
| static constexpr CLSID CLSID_WindhawkTAP = { 0xc85d8cc7, 0x5463, 0x40e8, { 0xa4, 0x32, 0xf5, 0x91, 0x6b, 0x64, 0x27, 0xe5 } }; | |
| class WindhawkTAP : public winrt::implements<WindhawkTAP, IObjectWithSite, winrt::non_agile> { | |
| public: | |
| HRESULT STDMETHODCALLTYPE SetSite(IUnknown* pUnkSite) override; | |
| HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void** ppvSite) noexcept override; | |
| private: | |
| winrt::com_ptr<IUnknown> site; | |
| }; | |
| #pragma endregion // tap_hpp | |
| #pragma region tap_cpp | |
| HRESULT WindhawkTAP::SetSite(IUnknown* pUnkSite) try { | |
| // Only ever 1 VTW at once. | |
| if(g_visualTreeWatcher) { | |
| g_visualTreeWatcher->UnadviseVisualTreeChange(); | |
| g_visualTreeWatcher = nullptr; | |
| } | |
| site.copy_from(pUnkSite); | |
| if(site) { | |
| // Decrease refcount increased by InitializeXamlDiagnosticsEx. | |
| FreeLibrary(GetCurrentModuleHandle()); | |
| g_visualTreeWatcher = winrt::make_self<VisualTreeWatcher>(site); | |
| } | |
| return S_OK; | |
| } catch(...) { | |
| HRESULT hr = winrt::to_hresult(); | |
| Wh_Log(L"Error %08X", hr); | |
| return hr; | |
| } | |
| HRESULT WindhawkTAP::GetSite(REFIID riid, void** ppvSite) noexcept { return site.as(riid, ppvSite); } | |
| #pragma endregion // tap_cpp | |
| #pragma region simplefactory_hpp | |
| #include <Unknwn.h> | |
| template<class T> | |
| struct SimpleFactory : winrt::implements<SimpleFactory<T>, IClassFactory, winrt::non_agile> { | |
| HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject) override try { | |
| if(!pUnkOuter) { | |
| *ppvObject = nullptr; | |
| return winrt::make<T>().as(riid, ppvObject); | |
| } else { | |
| return CLASS_E_NOAGGREGATION; | |
| } | |
| } catch(...) { | |
| HRESULT hr = winrt::to_hresult(); | |
| Wh_Log(L"Error %08X", hr); | |
| return hr; | |
| } | |
| HRESULT STDMETHODCALLTYPE LockServer(BOOL) noexcept override { return S_OK; } | |
| }; | |
| #pragma endregion // simplefactory_hpp | |
| #pragma region module_cpp | |
| #include <combaseapi.h> | |
| #pragma clang diagnostic push | |
| #pragma clang diagnostic ignored "-Wdll-attribute-on-redeclaration" | |
| __declspec(dllexport) _Use_decl_annotations_ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) try { | |
| if(rclsid == CLSID_WindhawkTAP) { | |
| *ppv = nullptr; | |
| return winrt::make<SimpleFactory<WindhawkTAP>>().as(riid, ppv); | |
| } else { | |
| return CLASS_E_CLASSNOTAVAILABLE; | |
| } | |
| } catch(...) { | |
| HRESULT hr = winrt::to_hresult(); | |
| Wh_Log(L"Error %08X", hr); | |
| return hr; | |
| } | |
| __declspec(dllexport) _Use_decl_annotations_ STDAPI DllCanUnloadNow(void) { | |
| if(winrt::get_module_lock()) { | |
| return S_FALSE; | |
| } else { | |
| return S_OK; | |
| } | |
| } | |
| #pragma clang diagnostic pop | |
| #pragma endregion // module_cpp | |
| #pragma region api_cpp | |
| bool g_inInjectWindhawkTAP = false; | |
| using PFN_INITIALIZE_XAML_DIAGNOSTICS_EX = decltype(&InitializeXamlDiagnosticsEx); | |
| HRESULT InjectWindhawkTAP() noexcept { | |
| HMODULE module = GetCurrentModuleHandle(); | |
| if(!module) { return HRESULT_FROM_WIN32(GetLastError()); } | |
| WCHAR location[MAX_PATH]; | |
| switch(GetModuleFileName(module, location, ARRAYSIZE(location))) { | |
| case 0: | |
| case ARRAYSIZE(location): | |
| return HRESULT_FROM_WIN32(GetLastError()); | |
| } | |
| const HMODULE wux(LoadLibraryEx(L"Windows.UI.Xaml.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32)); | |
| if(!wux) [[unlikely]] { return HRESULT_FROM_WIN32(GetLastError()); } | |
| const auto ixde = reinterpret_cast<PFN_INITIALIZE_XAML_DIAGNOSTICS_EX>(GetProcAddress(wux, "InitializeXamlDiagnostics" | |
| "Ex")); | |
| if(!ixde) [[unlikely]] { | |
| FreeLibrary(wux); | |
| return HRESULT_FROM_WIN32(GetLastError()); | |
| } | |
| // I didn't find a better way than trying many connections until one works. | |
| // Reference: | |
| // https://github.com/microsoft/microsoft-ui-xaml/blob/d74a0332cf0d5e58f12eddce1070fa7a79b4c2db/src/dxaml/xcp/dxaml/lib/DXamlCore.cpp#L2782 | |
| g_inInjectWindhawkTAP = true; | |
| HRESULT hr; | |
| for(int i = 0; i < 10000; i++) { | |
| WCHAR connectionName[256]; | |
| swprintf_s(connectionName, ARRAYSIZE(connectionName), L"VisualDiagConnection%d", i + 1); | |
| hr = ixde(connectionName, GetCurrentProcessId(), L"", location, CLSID_WindhawkTAP, nullptr); | |
| if(hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) { break; } | |
| } | |
| g_inInjectWindhawkTAP = false; | |
| FreeLibrary(wux); | |
| return hr; | |
| } | |
| #pragma endregion // api_cpp | |
| //////////////////////////////////////////////////////////////////////////////// | |
| #pragma endregion // LIBS | |
| using namespace std::string_view_literals; | |
| #include <roapi.h> | |
| #include <sdkddkver.h> | |
| #include <winstring.h> | |
| #include <winrt/Windows.Foundation.Collections.h> | |
| #include <winrt/Windows.Foundation.Numerics.h> | |
| #include <winrt/Windows.Foundation.h> | |
| #include <winrt/Windows.Networking.Connectivity.h> | |
| #include <windows.graphics.effects.h> | |
| #include <winrt/Windows.Graphics.Effects.h> | |
| #include <winrt/Windows.System.h> | |
| #include <winrt/Windows.UI.Composition.h> | |
| #include <winrt/Windows.UI.Core.h> | |
| #include <winrt/Windows.UI.Text.h> | |
| #include <winrt/Windows.UI.ViewManagement.h> | |
| #include <winrt/Windows.UI.Xaml.Controls.h> | |
| #include <winrt/Windows.UI.Xaml.Hosting.h> | |
| #include <winrt/Windows.UI.Xaml.Markup.h> | |
| #include <winrt/Windows.UI.Xaml.Media.Imaging.h> | |
| #include <winrt/Windows.UI.Xaml.Media.h> | |
| #include <winrt/Windows.UI.Xaml.Shapes.h> | |
| #include <winrt/Windows.UI.Xaml.h> | |
| // alias some long namespaces for convenience | |
| namespace wui = winrt::Windows::UI; | |
| namespace wuc = winrt::Windows::UI::Composition; | |
| namespace wux = winrt::Windows::UI::Xaml; | |
| namespace wuxh = winrt::Windows::UI::Xaml::Hosting; | |
| namespace wuxm = winrt::Windows::UI::Xaml::Media; | |
| namespace wg = winrt::Windows::Graphics; | |
| namespace wge = winrt::Windows::Graphics::Effects; | |
| namespace awge = ABI::Windows::Graphics::Effects; | |
| using namespace winrt::Windows::UI::Xaml; | |
| enum class XamlDiagnosticsHandling { | |
| kAlert, | |
| kBlock, | |
| kAllow, | |
| }; | |
| struct { | |
| XamlDiagnosticsHandling xamlDiagnosticsHandling; | |
| } g_settings; | |
| // https://stackoverflow.com/a/51274008 | |
| template<auto fn> | |
| struct deleter_from_fn { | |
| template<typename T> | |
| constexpr void operator()(T* arg) const { | |
| fn(arg); | |
| } | |
| }; | |
| using string_setting_unique_ptr = std::unique_ptr<const WCHAR[], deleter_from_fn<Wh_FreeStringSetting>>; | |
| enum class AttrMatchMode { | |
| Exact, // [Prop=Value] | |
| NotEqual, // [Prop!=Value] | |
| StartsWith, // [Prop^=Value] | |
| EndsWith, // [Prop$=Value] | |
| Contains, // [Prop*=Value] | |
| GreaterOrEqual, // [Prop>=Value] | |
| LessOrEqual, // [Prop<=Value] | |
| }; | |
| struct PropertyValueUnresolved { | |
| std::wstring key; | |
| std::wstring value; | |
| AttrMatchMode matchMode = AttrMatchMode::Exact; | |
| bool isDynamic = false; // @Prop — use GetValue (actual/computed) instead of ReadLocalValue | |
| }; | |
| struct PropertyValueResolved { | |
| DependencyProperty property{ nullptr }; | |
| wf::IInspectable value{ nullptr }; | |
| AttrMatchMode matchMode = AttrMatchMode::Exact; | |
| bool isDynamic = false; | |
| std::wstring key; // original property name for logging | |
| }; | |
| struct StyleRule { | |
| public: | |
| std::wstring name; | |
| std::wstring visualState; | |
| std::wstring value; | |
| bool isXamlValue = false; | |
| const std::wstring toString() const; | |
| }; | |
| using PropertyValues = std::vector<PropertyValueResolved>; | |
| using PropertyValuesUnresolved = std::vector<PropertyValueUnresolved>; | |
| using PropertyValuesMaybeUnresolved = std::variant<PropertyValuesUnresolved, PropertyValues>; | |
| using PropertyOverridesUnresolved = std::vector<StyleRule>; | |
| using OptionalVisualStateGroup = std::optional<winrt::weak_ref<VisualStateGroup>>; | |
| struct XamlBlurBrushParams { | |
| float blurAmount; | |
| winrt::Windows::UI::Color tint; | |
| std::optional<uint8_t> tintOpacity; | |
| std::wstring tintThemeResourceKey; // Empty if not from ThemeResource | |
| }; | |
| using PropertyOverrideValue = std::variant<wf::IInspectable, XamlBlurBrushParams>; | |
| // Property -> visual state -> value. | |
| using PropertyOverrides = std::unordered_map<DependencyProperty, std::unordered_map<std::wstring, PropertyOverrideValue>>; | |
| using PropertyOverridesMaybeUnresolved = std::variant<PropertyOverridesUnresolved, PropertyOverrides>; | |
| struct TargetToken { | |
| public: | |
| std::wstring_view text; | |
| bool isDirectChild; // relationship to the NEXT (child) token | |
| static std::vector<TargetToken> Tokenize(std::wstring_view target); | |
| }; | |
| struct SelectorChain; // forward declaration | |
| struct ElementMatcher { | |
| public: | |
| const std::wstring* type = nullptr; | |
| std::wstring name; | |
| std::optional<std::wstring> visualStateGroupName; | |
| PropertyValuesMaybeUnresolved propertyValues; | |
| std::vector<SelectorChain> hasSelectors; // :has() conditions — element must have a descendant matching each | |
| std::vector<SelectorChain> notHasSelectors; // :not-has() conditions — element must have a descendant matching each | |
| int oneBasedIndex = 0; | |
| bool isDescendant = false; // true = any ancestor (space), false = direct parent (>) | |
| const std::wstring toString() const; | |
| bool Equals(const ElementMatcher& other) const { return Equals(*this, other); } | |
| static bool Equals(const ElementMatcher& a, const ElementMatcher& b); | |
| static ElementMatcher FromString(std::wstring_view str); | |
| }; | |
| // A :has() selector chain: the innermost target and its ancestor matchers. | |
| // E.g. :has(A B[C^=D]) → targetMatcher = B[C^=D], ancestorMatchers = [A] | |
| struct SelectorChain { | |
| public: | |
| ElementMatcher targetMatcher; | |
| std::vector<ElementMatcher> ancestorMatchers; // nearest ancestor first, outermost last | |
| const std::wstring toString() const; | |
| bool Equals(const SelectorChain& other) const { return Equals(*this, other); } | |
| static bool Equals(const SelectorChain& a, const SelectorChain& b); | |
| }; | |
| struct ElementCustomizationRules { | |
| public: | |
| ElementMatcher elementMatcher; | |
| std::vector<ElementMatcher> parentElementMatchers; | |
| PropertyOverridesMaybeUnresolved propertyOverrides; | |
| const std::wstring toString() const; | |
| bool Equals(const ElementCustomizationRules& other) const { return Equals(*this, other); } | |
| static bool Equals(const ElementCustomizationRules& a, const ElementCustomizationRules& b); | |
| }; | |
| struct ElementPropertyCustomizationState { | |
| std::optional<wf::IInspectable> originalValue; | |
| std::optional<PropertyOverrideValue> customValue; | |
| int64_t propertyChangedToken = 0; | |
| }; | |
| struct ElementCustomizationStateForVisualStateGroup { | |
| std::unordered_map<DependencyProperty, ElementPropertyCustomizationState> propertyCustomizationStates; | |
| winrt::event_token visualStateGroupCurrentStateChangedToken; | |
| }; | |
| struct ElementCustomizationState { | |
| winrt::weak_ref<FrameworkElement> element; | |
| // Use list to avoid reallocations on insertion, as pointers to items are captured in callbacks and stored. | |
| std::list<std::pair<OptionalVisualStateGroup, ElementCustomizationStateForVisualStateGroup>> perVisualStateGroup; | |
| }; | |
| // Global list to track ImageBrushes with failed loads for retry on network | |
| // reconnection. | |
| struct ImageBrushFailedLoadInfo { | |
| winrt::weak_ref<Media::ImageBrush> brush; | |
| winrt::hstring imageSource; | |
| Media::ImageBrush::ImageFailed_revoker imageFailedRevoker; | |
| Media::ImageBrush::ImageOpened_revoker imageOpenedRevoker; | |
| }; | |
| struct FailedImageBrushesForThread { | |
| std::list<ImageBrushFailedLoadInfo> failedImageBrushes; | |
| winrt::Windows::System::DispatcherQueue dispatcher{ nullptr }; | |
| }; | |
| // :has() re-evaluation tracking. | |
| // When any rule uses :has(), we track all elements that were processed by | |
| // ApplyCustomizations so we can re-evaluate them when the visual tree changes. | |
| struct HasReevalEntry { | |
| winrt::weak_ref<FrameworkElement> element; | |
| std::wstring fallbackClassName; | |
| }; | |
| enum class ResourceVariableTheme { | |
| None, | |
| Dark, | |
| Light, | |
| }; | |
| struct ResourceVariableEntry { | |
| std::wstring key; | |
| std::wstring value; | |
| ResourceVariableTheme theme; | |
| }; | |
| // Global registry of all threads that have failed image brushes. | |
| std::mutex g_failedImageBrushesRegistryMutex; | |
| std::vector<winrt::weak_ref<winrt::Windows::System::DispatcherQueue>> g_failedImageBrushesRegistry; | |
| winrt::event_token g_networkStatusChangedToken; | |
| // Shared template of parsed (but unresolved) customization rules. | |
| // Built once, then copied to each thread's local for per-thread XAML resolution. | |
| std::mutex g_sharedRulesMutex; | |
| std::vector<ElementCustomizationRules> g_sharedRulesTemplate; | |
| bool g_sharedRulesBuilt = false; | |
| thread_local bool g_elementPropertyModifying; | |
| thread_local bool g_anyRuleUsesHas = false; | |
| thread_local bool g_hasReevalScheduled = false; | |
| thread_local std::vector<ElementCustomizationRules> g_elementsCustomizationRules; | |
| thread_local std::unordered_map<InstanceHandle, ElementCustomizationState> g_elementsCustomizationState; | |
| thread_local std::unordered_map<InstanceHandle, HasReevalEntry> g_hasReevalElements; | |
| thread_local std::list<std::pair<winrt::weak_ref<DependencyObject>, wf::IAsyncOperation<bool>>> g_delayedBackgroundFillSet; | |
| // Track original resource values for restoration (per-thread since Application::Current().Resources() is per-thread). | |
| thread_local std::unordered_map<std::wstring, wf::IInspectable> g_originalResourceValues; | |
| // Track our merged theme dictionary for cleanup (per-thread). | |
| thread_local ResourceDictionary g_resourceVariablesThemeDict{ nullptr }; | |
| // Track theme resource entries that reference {ThemeResource ...} for refresh (per-thread). | |
| thread_local std::vector<ResourceVariableEntry> g_themeResourceEntries; | |
| // For listening to theme color changes (per-thread). | |
| thread_local winrt::Windows::UI::ViewManagement::UISettings g_uiSettings{ nullptr }; | |
| thread_local winrt::event_token g_colorValuesChangedToken; | |
| thread_local FailedImageBrushesForThread g_failedImageBrushesForThread; | |
| // Thread-local intern pool for dynamically constructed type names. | |
| // Returns a stable pointer — two calls with the same content return the same address. | |
| thread_local std::unordered_map<std::wstring_view, std::wstring> g_InternedTypeNames; | |
| static const std::wstring* InternTypeName(std::wstring_view sv) { | |
| auto [it, _] = g_InternedTypeNames.try_emplace(sv, sv); | |
| return &it->second; | |
| } | |
| // namespace StrFmt { | |
| // static std::wstring toString(const std::variant<PCWSTR, std::vector<PCWSTR>>& oneOrMany); | |
| // static std::wstring toString(const StyleRule& a); | |
| // static std::wstring toString(const SelectorChain& chain); | |
| // static std::wstring toString(const ElementMatcher& a); | |
| // static std::wstring toString(const ElementCustomizationRules& A); | |
| // static const std::wstring* InternTypeName(std::wstring_view sv); | |
| // static std::wstring_view TrimStringView(std::wstring_view s); | |
| // } | |
| namespace StrFmt { | |
| static std::wstring DescribeIInspectable(const wf::IInspectable& v) { | |
| if(!v) { return L"<null>"; } | |
| // ---------- Color ---------- | |
| wui::Color colorValue; | |
| if(v.try_as(colorValue)) { | |
| wchar_t buf[64]; | |
| swprintf_s(buf, L"Color(#%02X%02X%02X%02X) A=%u R=%u G=%u B=%u", colorValue.A, colorValue.R, colorValue.G, | |
| colorValue.B, colorValue.A, colorValue.R, colorValue.G, colorValue.B); | |
| return std::wstring(buf); | |
| } | |
| // ---------- SolidColorBrush ---------- | |
| wuxm::SolidColorBrush brushValue{ nullptr }; | |
| if(v.try_as(brushValue)) { | |
| wui::Color c = brushValue.Color(); | |
| wchar_t buf[64]; | |
| swprintf_s(buf, L"SolidColorBrush(#%02X%02X%02X%02X) A=%u R=%u G=%u B=%u", c.A, c.R, c.G, c.B, c.A, c.R, c.G, c.B); | |
| return std::wstring(buf); | |
| } | |
| // ---------- AcrylicBrush ---------- | |
| wuxm::AcrylicBrush acrylicBrush{ nullptr }; | |
| if(v.try_as(acrylicBrush)) { | |
| wui::Color c = acrylicBrush.TintColor(); | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"AcrylicBrush(Tint=#%02X%02X%02X%02X, TintOpacity=%.2f, AlwaysUseFallback=%s)", c.A, c.R, c.G, | |
| c.B, acrylicBrush.TintOpacity(), acrylicBrush.AlwaysUseFallback() ? L"true" : L"false"); | |
| return std::wstring(buf); | |
| } | |
| // ---------- GradientBrush / LinearGradientBrush / RadialGradientBrush ---------- | |
| wuxm::GradientBrush gradientBrush{ nullptr }; | |
| if(v.try_as(gradientBrush)) { | |
| int stopCount = gradientBrush.GradientStops().Size(); | |
| wuxm::LinearGradientBrush linear{ nullptr }; | |
| if(v.try_as(linear)) { | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"LinearGradientBrush(Stops=%d)", stopCount); | |
| return std::wstring(buf); | |
| } | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"GradientBrush(Stops=%d)", stopCount); | |
| return std::wstring(buf); | |
| } | |
| // ---------- Thickness ---------- | |
| wux::Thickness thicknessValue; | |
| if(v.try_as(thicknessValue)) { | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"Thickness(Left=%.2f, Top=%.2f, Right=%.2f, Bottom=%.2f)", thicknessValue.Left, | |
| thicknessValue.Top, thicknessValue.Right, thicknessValue.Bottom); | |
| return std::wstring(buf); | |
| } | |
| // ---------- CornerRadius ---------- | |
| wux::CornerRadius cornerValue; | |
| if(v.try_as(cornerValue)) { | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"CornerRadius(TL=%.2f, TR=%.2f, BR=%.2f, BL=%.2f)", cornerValue.TopLeft, cornerValue.TopRight, | |
| cornerValue.BottomRight, cornerValue.BottomLeft); | |
| return std::wstring(buf); | |
| } | |
| // ---------- GridLength ---------- | |
| wux::GridLength gridValue; | |
| if(v.try_as(gridValue)) { | |
| wchar_t buf[128]; | |
| const wchar_t* typeStr = gridValue.GridUnitType == wux::GridUnitType::Auto ? L"Auto" | |
| : gridValue.GridUnitType == wux::GridUnitType::Pixel ? L"Pixel" | |
| : L"Star"; | |
| swprintf_s(buf, L"GridLength(Value=%.2f, Type=%s)", gridValue.Value, typeStr); | |
| return std::wstring(buf); | |
| } | |
| // ---------- Duration ---------- | |
| wux::Duration durationValue; | |
| if(v.try_as(durationValue)) { | |
| wchar_t buf[128]; | |
| long long ticks = durationValue.TimeSpan.count(); | |
| swprintf_s(buf, L"Duration(TimeSpan=%lld ticks)", ticks); | |
| return std::wstring(buf); | |
| } | |
| // ---------- FontWeight ---------- | |
| wui::Text::FontWeight fontWeightValue; | |
| if(v.try_as(fontWeightValue)) { | |
| wchar_t buf[64]; | |
| swprintf_s(buf, L"FontWeight(%u)", fontWeightValue.Weight); | |
| return std::wstring(buf); | |
| } | |
| // ---------- Point ---------- | |
| wf::Point pointValue; | |
| if(v.try_as(pointValue)) { | |
| wchar_t buf[64]; | |
| swprintf_s(buf, L"Point(X=%.2f, Y=%.2f)", pointValue.X, pointValue.Y); | |
| return std::wstring(buf); | |
| } | |
| // ---------- Size ---------- | |
| wf::Size sizeValue; | |
| if(v.try_as(sizeValue)) { | |
| wchar_t buf[64]; | |
| swprintf_s(buf, L"Size(W=%.2f, H=%.2f)", sizeValue.Width, sizeValue.Height); | |
| return std::wstring(buf); | |
| } | |
| // ---------- Rect ---------- | |
| wf::Rect rectValue; | |
| if(v.try_as(rectValue)) { | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"Rect(X=%.2f, Y=%.2f, W=%.2f, H=%.2f)", rectValue.X, rectValue.Y, rectValue.Width, | |
| rectValue.Height); | |
| return std::wstring(buf); | |
| } | |
| // ---------- Transforms ---------- | |
| wuxm::RotateTransform rotate{ nullptr }; | |
| if(v.try_as(rotate)) { | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"RotateTransform(Angle=%.2f, CenterX=%.2f, CenterY=%.2f)", rotate.Angle(), rotate.CenterX(), | |
| rotate.CenterY()); | |
| return std::wstring(buf); | |
| } | |
| wuxm::ScaleTransform scale{ nullptr }; | |
| if(v.try_as(scale)) { | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"ScaleTransform(ScaleX=%.2f, ScaleY=%.2f, CenterX=%.2f, CenterY=%.2f)", scale.ScaleX(), | |
| scale.ScaleY(), scale.CenterX(), scale.CenterY()); | |
| return std::wstring(buf); | |
| } | |
| wuxm::SkewTransform skew{ nullptr }; | |
| if(v.try_as(skew)) { | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"SkewTransform(AngleX=%.2f, AngleY=%.2f, CenterX=%.2f, CenterY=%.2f)", skew.AngleX(), | |
| skew.AngleY(), skew.CenterX(), skew.CenterY()); | |
| return std::wstring(buf); | |
| } | |
| wuxm::TranslateTransform translate{ nullptr }; | |
| if(v.try_as(translate)) { | |
| wchar_t buf[128]; | |
| swprintf_s(buf, L"TranslateTransform(X=%.2f, Y=%.2f)", translate.X(), translate.Y()); | |
| return std::wstring(buf); | |
| } | |
| wuxm::CompositeTransform composite{ nullptr }; | |
| if(v.try_as(composite)) { | |
| wchar_t buf[256]; | |
| swprintf_s(buf, | |
| L"CompositeTransform(ScaleX=%.2f, ScaleY=%.2f, SkewX=%.2f, SkewY=%.2f, Rot=%.2f, " | |
| L"TransX=%.2f, " | |
| L"TransY=%.2f)", | |
| composite.ScaleX(), composite.ScaleY(), composite.SkewX(), composite.SkewY(), composite.Rotation(), | |
| composite.TranslateX(), composite.TranslateY()); | |
| return std::wstring(buf); | |
| } | |
| // ---------- ResourceDictionary ---------- | |
| wux::ResourceDictionary dict{ nullptr }; | |
| if(v.try_as(dict)) { | |
| unsigned int size = dict.Size(); | |
| wchar_t buf[64]; | |
| swprintf_s(buf, L"ResourceDictionary(Size=%u)", size); | |
| return std::wstring(buf); | |
| } | |
| // ---------- IStringable ---------- | |
| wf::IStringable stringable{ nullptr }; | |
| if(v.try_as(stringable)) { | |
| winrt::hstring hs = stringable.ToString(); | |
| return std::wstring(L"IStringable(") + hs.c_str() + L")"; | |
| } | |
| // ---------- Boxed primitives ---------- | |
| try { | |
| bool b = winrt::unbox_value<bool>(v); | |
| return b ? L"bool(true)" : L"bool(false)"; | |
| } catch(...) {} | |
| try { | |
| int i = winrt::unbox_value<int>(v); | |
| wchar_t buf[32]; | |
| swprintf_s(buf, L"int(%d)", i); | |
| return std::wstring(buf); | |
| } catch(...) {} | |
| try { | |
| double d = winrt::unbox_value<double>(v); | |
| wchar_t buf[64]; | |
| swprintf_s(buf, L"double(%.4f)", d); | |
| return std::wstring(buf); | |
| } catch(...) {} | |
| try { | |
| winrt::hstring hs = winrt::unbox_value<winrt::hstring>(v); | |
| return std::wstring(L"hstring(") + hs.c_str() + L")"; | |
| } catch(...) {} | |
| return L"<unknown type>"; | |
| } | |
| static std::wstring toString(const std::variant<PCWSTR, std::vector<PCWSTR>>& oneOrMany) { | |
| if(std::holds_alternative<PCWSTR>(oneOrMany)) { | |
| return std::get<PCWSTR>(oneOrMany); | |
| } else { | |
| const std::vector<PCWSTR>& targets = std::get<std::vector<PCWSTR>>(oneOrMany); | |
| std::wstring combinedTargets; | |
| for(size_t i = 0; i < targets.size(); ++i) { | |
| if(i > 0) { combinedTargets += L" ; "; } | |
| combinedTargets += targets[i]; | |
| } | |
| return combinedTargets; | |
| } | |
| } | |
| static const std::wstring toString(const AttrMatchMode A) { | |
| switch(A) { | |
| case AttrMatchMode::Exact: | |
| return L"=="; | |
| case AttrMatchMode::NotEqual: | |
| return L"!="; | |
| case AttrMatchMode::StartsWith: | |
| return L"^="; | |
| case AttrMatchMode::EndsWith: | |
| return L"$="; | |
| case AttrMatchMode::Contains: | |
| return L"*="; | |
| case AttrMatchMode::GreaterOrEqual: | |
| return L">="; | |
| case AttrMatchMode::LessOrEqual: | |
| return L"<="; | |
| default: | |
| return L"?"; | |
| } | |
| } | |
| static std::wstring toLocator(FrameworkElement element) { | |
| const int CAP = 128; | |
| int sz = 0; | |
| int len = 0; | |
| std::vector<std::wstring> res; | |
| do { | |
| winrt::hstring clazz = winrt::get_class_name(element); | |
| winrt::hstring name = element.Name(); | |
| std::wstring loc; | |
| loc.reserve(3 + clazz.size() + name.size()); | |
| loc.append(clazz); | |
| loc.append(L"#"); | |
| loc.append(name); | |
| res.push_back(loc); | |
| sz += loc.size(); | |
| element = Media::VisualTreeHelper::GetParent(element).try_as<FrameworkElement>(); | |
| } while(len < CAP && res.size() <= 5 && !!element); | |
| std::reverse(res.begin(), res.end()); | |
| std::wstring str; | |
| str.reserve((sz + 32 + (res.size() * 3)) & ~31); | |
| str.append(res[0]); | |
| for(size_t i = 1; i < res.size(); ++i) { | |
| str.append(L" > "); | |
| str.append(res[i]); | |
| } | |
| return str; | |
| } | |
| static std::wstring EscapeXmlAttribute(std::wstring_view data) { | |
| std::wstring buffer; | |
| buffer.reserve(data.size() + 32); | |
| size_t start = 0; | |
| for(size_t i = 0; i < data.size(); ++i) { | |
| const wchar_t* replacement = nullptr; | |
| switch(data[i]) { | |
| case '&': | |
| replacement = L"&"; | |
| break; | |
| case '\"': | |
| replacement = L"""; | |
| break; | |
| case '<': | |
| replacement = L"<"; | |
| break; | |
| case '>': | |
| replacement = L">"; | |
| break; | |
| } | |
| if(replacement) { | |
| buffer.append(data.data() + start, i - start); | |
| buffer.append(replacement); | |
| start = i + 1; | |
| } | |
| } | |
| buffer.append(data.data() + start, data.size() - start); | |
| return buffer; | |
| } | |
| // https://stackoverflow.com/a/54364173 | |
| static std::wstring_view TrimStringView(std::wstring_view s) { | |
| s.remove_prefix(std::min(s.find_first_not_of(L" \t\r\v\n"), s.size())); | |
| s.remove_suffix(std::min(s.size() - s.find_last_not_of(L" \t\r\v\n") - 1, s.size())); | |
| return s; | |
| } | |
| // https://stackoverflow.com/a/46931770 | |
| static std::vector<std::wstring_view> SplitStringView(std::wstring_view s, std::wstring_view delimiter) { | |
| size_t pos_start = 0, pos_end, delim_len = delimiter.length(); | |
| std::wstring_view token; | |
| std::vector<std::wstring_view> res; | |
| while((pos_end = s.find(delimiter, pos_start)) != std::wstring_view::npos) { | |
| token = s.substr(pos_start, pos_end - pos_start); | |
| pos_start = pos_end + delim_len; | |
| res.push_back(token); | |
| } | |
| res.push_back(s.substr(pos_start)); | |
| return res; | |
| } | |
| } | |
| namespace Helper { | |
| const std::wstring* AdjustTypeName(std::wstring_view type) { | |
| // Static pool — each unique resolved name stored once. | |
| // Duplicate map entries (aliases) share the same pointer. | |
| static const struct { | |
| const std::wstring Rectangle{ L"Windows.UI.Xaml.Shapes.Rectangle" }; | |
| const std::wstring Grid{ L"Windows.UI.Xaml.Controls.Grid" }; | |
| const std::wstring Border{ L"Windows.UI.Xaml.Controls.Border" }; | |
| const std::wstring Image{ L"Windows.UI.Xaml.Controls.Image" }; | |
| const std::wstring TextBlock{ L"Windows.UI.Xaml.Controls.TextBlock" }; | |
| const std::wstring StackPanel{ L"Windows.UI.Xaml.Controls.StackPanel" }; | |
| const std::wstring ScrollViewer{ L"Windows.UI.Xaml.Controls.ScrollViewer" }; | |
| const std::wstring RootScrollViewer{ L"Windows.UI.Xaml.Internal.RootScrollViewer" }; | |
| const std::wstring ScrollContentPresenter{ L"Windows.UI.Xaml.Controls.ScrollContentPresenter" }; | |
| const std::wstring ContentPresenter{ L"Windows.UI.Xaml.Controls.ContentPresenter" }; | |
| const std::wstring ProgressBar{ L"Microsoft.UI.Xaml.Controls.ProgressBar" }; | |
| const std::wstring ItemsRepeater{ L"Microsoft.UI.Xaml.Controls.ItemsRepeater" }; | |
| const std::wstring AnimatedIcon{ L"Microsoft.UI.Xaml.Controls.AnimatedIcon" }; | |
| const std::wstring TaskbarBackground{ L"Taskbar.TaskbarBackground" }; | |
| const std::wstring TaskbarFrame{ L"Taskbar.TaskbarFrame" }; | |
| const std::wstring TaskListButton{ L"Taskbar.TaskListButton" }; | |
| const std::wstring TaskListButtonPanel{ L"Taskbar.TaskListButtonPanel" }; | |
| const std::wstring TaskListLabeledButtonPanel{ L"Taskbar.TaskListLabeledButtonPanel" }; | |
| const std::wstring Gripper{ L"Taskbar.Gripper" }; | |
| const std::wstring Badge{ L"Taskbar.Badge" }; | |
| const std::wstring AugmentedEntryPointButton{ L"Taskbar.AugmentedEntryPointButton" }; | |
| const std::wstring ExperienceToggleButton{ L"Taskbar.ExperienceToggleButton" }; | |
| const std::wstring SearchBoxButton{ L"Taskbar.SearchBoxButton" }; | |
| const std::wstring SearchBoxLaunchListButton{ L"Taskbar.SearchBoxLaunchListButton" }; | |
| const std::wstring SearchButtonRootGrid{ L"SearchUx.SearchUI.SearchButtonRootGrid" }; | |
| const std::wstring ChevronIcon{ L"SystemTray.ChevronIconView" }; | |
| const std::wstring CopilotIcon{ L"SystemTray.CopilotIcon" }; | |
| const std::wstring NotifyIconView{ L"SystemTray.NotifyIconView" }; | |
| const std::wstring IconView{ L"SystemTray.IconView" }; | |
| const std::wstring ImageIconContent{ L"SystemTray.ImageIconContent" }; | |
| const std::wstring OmniButton{ L"SystemTray.OmniButton" }; | |
| const std::wstring Stack{ L"SystemTray.Stack" }; | |
| const std::wstring StackListView{ L"SystemTray.StackListView" }; | |
| const std::wstring SystemTrayFrame{ L"SystemTray.SystemTrayFrame" }; | |
| const std::wstring NotificationAreaIcons{ L"SystemTray.NotificationAreaIcons" }; | |
| const std::wstring InputSwitcher{ L"WindowsInternal.ComposableShell.Experiences.TextInput.Common." | |
| L"InputSwitcher" }; | |
| const std::wstring SwitchItemListViewItem{ L"WindowsInternal.ComposableShell.Experiences.Switcher." | |
| L"SwitchItemListViewItem" }; | |
| const std::wstring VirtualDesktopBarElement{ L"WindowsInternal.ComposableShell.Experiences.Switcher." | |
| L"VirtualDesktopBarElement" }; | |
| } pool; | |
| static const std::unordered_map<std::wstring_view, const std::wstring*> knownTypes = { | |
| { L"Rectangle", &pool.Rectangle }, | |
| { L"Windows.UI.Xaml.Shapes.Rectangle", &pool.Rectangle }, | |
| { L"Grid", &pool.Grid }, | |
| { L"Windows.UI.Xaml.Controls.Grid", &pool.Grid }, | |
| { L"Border", &pool.Border }, | |
| { L"Windows.UI.Xaml.Controls.Border", &pool.Border }, | |
| { L"Image", &pool.Image }, | |
| { L"Windows.UI.Xaml.Controls.Image", &pool.Image }, | |
| { L"TextBlock", &pool.TextBlock }, | |
| { L"Windows.UI.Xaml.Controls.TextBlock", &pool.TextBlock }, | |
| { L"StackPanel", &pool.StackPanel }, | |
| { L"Windows.UI.Xaml.Controls.StackPanel", &pool.StackPanel }, | |
| { L"ScrollContentPresenter", &pool.ScrollContentPresenter }, | |
| { L"Windows.UI.Xaml.Controls.ScrollContentPresenter", &pool.ScrollContentPresenter }, | |
| { L"RootScrollViewer", &pool.RootScrollViewer }, | |
| { L"Windows.UI.Xaml.Internal.RootScrollViewer", &pool.RootScrollViewer }, | |
| { L"ScrollViewer", &pool.ScrollViewer }, | |
| { L"Windows.UI.Xaml.Controls.ScrollViewer", &pool.ScrollViewer }, | |
| { L"ContentPresenter", &pool.ContentPresenter }, | |
| { L"Windows.UI.Xaml.Controls.ContentPresenter", &pool.ContentPresenter }, | |
| { L"ProgressBar", &pool.ProgressBar }, | |
| { L"Microsoft.UI.Xaml.Controls.ProgressBar", &pool.ProgressBar }, | |
| { L"ItemsRepeater", &pool.ItemsRepeater }, | |
| { L"Microsoft.UI.Xaml.Controls.ItemsRepeater", &pool.ItemsRepeater }, | |
| { L"AnimatedIcon", &pool.AnimatedIcon }, | |
| { L"Microsoft.UI.Xaml.Controls.AnimatedIcon", &pool.AnimatedIcon }, | |
| { L"TaskbarBackground", &pool.TaskbarBackground }, | |
| { L"Taskbar.TaskbarBackground", &pool.TaskbarBackground }, | |
| { L"TaskbarFrame", &pool.TaskbarFrame }, | |
| { L"Taskbar.TaskbarFrame", &pool.TaskbarFrame }, | |
| { L"TaskListButton", &pool.TaskListButton }, | |
| { L"Taskbar.TaskListButton", &pool.TaskListButton }, | |
| { L"TaskListButtonPanel", &pool.TaskListButtonPanel }, | |
| { L"Taskbar.TaskListButtonPanel", &pool.TaskListButtonPanel }, | |
| { L"TaskListLabeledButtonPanel", &pool.TaskListLabeledButtonPanel }, | |
| { L"Taskbar.TaskListLabeledButtonPanel", &pool.TaskListLabeledButtonPanel }, | |
| { L"Gripper", &pool.Gripper }, | |
| { L"Taskbar.Gripper", &pool.Gripper }, | |
| { L"Badge", &pool.Badge }, | |
| { L"Taskbar.Badge", &pool.Badge }, | |
| { L"AugmentedEntryPointButton", &pool.AugmentedEntryPointButton }, | |
| { L"Taskbar.AugmentedEntryPointButton", &pool.AugmentedEntryPointButton }, | |
| { L"ExperienceToggleButton", &pool.ExperienceToggleButton }, | |
| { L"Taskbar.ExperienceToggleButton", &pool.ExperienceToggleButton }, | |
| { L"SearchBoxButton", &pool.SearchBoxButton }, | |
| { L"Taskbar.SearchBoxButton", &pool.SearchBoxButton }, | |
| { L"SearchBoxLaunchListButton", &pool.SearchBoxLaunchListButton }, | |
| { L"Taskbar.SearchBoxLaunchListButton", &pool.SearchBoxLaunchListButton }, | |
| { L"SearchButtonRootGrid", &pool.SearchButtonRootGrid }, | |
| { L"SearchUx.SearchUI.SearchButtonRootGrid", &pool.SearchButtonRootGrid }, | |
| { L"ChevronIconView", &pool.ChevronIcon }, | |
| { L"SystemTray.ChevronIconView", &pool.ChevronIcon }, | |
| { L"CopilotIcon", &pool.CopilotIcon }, | |
| { L"SystemTray.CopilotIcon", &pool.CopilotIcon }, | |
| { L"NotifyIconView", &pool.NotifyIconView }, | |
| { L"SystemTray.NotifyIconView", &pool.NotifyIconView }, | |
| { L"IconView", &pool.IconView }, | |
| { L"SystemTray.IconView", &pool.IconView }, | |
| { L"ImageIconContent", &pool.ImageIconContent }, | |
| { L"SystemTray.ImageIconContent", &pool.ImageIconContent }, | |
| { L"OmniButton", &pool.OmniButton }, | |
| { L"SystemTray.OmniButton", &pool.OmniButton }, | |
| { L"Stack", &pool.Stack }, | |
| { L"SystemTray.Stack", &pool.Stack }, | |
| { L"StackListView", &pool.StackListView }, | |
| { L"SystemTray.StackListView", &pool.StackListView }, | |
| { L"SystemTrayFrame", &pool.SystemTrayFrame }, | |
| { L"SystemTray.SystemTrayFrame", &pool.SystemTrayFrame }, | |
| { L"NotificationAreaIcons", &pool.NotificationAreaIcons }, | |
| { L"SystemTray.NotificationAreaIcons", &pool.NotificationAreaIcons }, | |
| { L"InputSwitcher", &pool.InputSwitcher }, | |
| { L"WindowsInternal.ComposableShell.Experiences.TextInput.Common.InputSwitcher", &pool.InputSwitcher }, | |
| { L"SwitchItemListViewItem", &pool.SwitchItemListViewItem }, | |
| { L"WindowsInternal.ComposableShell.Experiences.Switcher.SwitchItemListViewItem", &pool.SwitchItemListViewItem }, | |
| { L"VirtualDesktopBarElement", &pool.VirtualDesktopBarElement }, | |
| { L"WindowsInternal.ComposableShell.Experiences.Switcher.VirtualDesktopBarElement", &pool.VirtualDesktopBarElement }, | |
| }; | |
| if(std::unordered_map<std::wstring_view, const std::wstring*>::const_iterator it = knownTypes.find(type); | |
| it != knownTypes.end()) { | |
| return it->second; // pointer to static pool — no allocation, aliases share identity | |
| } | |
| Wh_Log(L"Non-Static Type Name '%s'", type.data()); | |
| auto it = g_InternedTypeNames.find(type); | |
| if(it != g_InternedTypeNames.end()) { | |
| return &it->second; // pointer to previously interned name | |
| } | |
| Wh_Log(L"Non-Interned Type Name '%s'", type.data()); | |
| if(type.find_first_of(L".:") == type.npos) { | |
| return InternTypeName(L"Windows.UI.Xaml.Controls." + std::wstring{ type }); | |
| } | |
| static const std::vector<std::pair<std::wstring_view, std::wstring_view>> adjustments = { | |
| { L"taskbar:", L"Taskbar." }, | |
| { L"systemtray:", L"SystemTray." }, | |
| { L"udk:", L"WindowsUdk.UI.Shell." }, | |
| { L"muxc:", L"Microsoft.UI.Xaml.Controls." }, | |
| }; | |
| for(const std::pair<std::wstring_view, std::wstring_view>& adjustment : adjustments) { | |
| if(type.starts_with(adjustment.first)) { | |
| std::wstring result = std::wstring{ adjustment.second }; | |
| result += type.substr(adjustment.first.size()); | |
| return InternTypeName(result); | |
| } | |
| } | |
| return InternTypeName(type); | |
| } | |
| static wf::IInspectable | |
| ReadLocalValueWithWorkaround(DependencyObject elementDo, DependencyProperty property, bool computed = false) { | |
| wf::IInspectable value = NULL; | |
| // Dynamic properties (@Prop) use GetValue to read the actual/computed value; | |
| // static properties use ReadLocalValue which only reads explicitly set values. | |
| try { | |
| if (computed) { | |
| value = elementDo.GetValue(property); | |
| } else { | |
| value = elementDo.ReadLocalValue(property); | |
| } | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error %08X: %s", ex.code(), ex.message().c_str()); | |
| } | |
| if (!value) { | |
| try { | |
| if (!computed) { | |
| value = elementDo.GetValue(property); | |
| } else { | |
| value = elementDo.ReadLocalValue(property); | |
| } | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error %08X: %s", ex.code(), ex.message().c_str()); | |
| } | |
| } | |
| if (!value) { | |
| try { | |
| value = elementDo.GetAnimationBaseValue(property); | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error %08X: %s", ex.code(), ex.message().c_str()); | |
| } | |
| } else { | |
| try { | |
| winrt::hstring className = winrt::get_class_name(value); | |
| if (className.ends_with(L".BindingExpressionBase") || className.ends_with(L".BindingExpression")) { | |
| // BindingExpressionBase was observed to be returned for XAML | |
| // properties that were declared as following: | |
| // | |
| // <Border ... CornerRadius="{TemplateBinding CornerRadius}" /> | |
| // | |
| // Calling SetValue with it fails with an error, so we won't be able | |
| // to use it to restore the value. As a workaround, we use | |
| // GetAnimationBaseValue to get the value. | |
| // Wh_Log(L"ReadLocalValue returned %s, using GetAnimationBaseValue", className.c_str()); | |
| value = elementDo.GetAnimationBaseValue(property); | |
| } | |
| } catch(winrt::hresult_error const& ex) { Wh_Log(L"Error %08X: %s", ex.code(), ex.message().c_str()); } | |
| } | |
| // Wh_Log(L"Read property value %s", | |
| // value ? (value == DependencyProperty::UnsetValue() | |
| // ? L"(unset)" | |
| // : winrt::get_class_name(value).c_str()) | |
| // : L"(null)"); | |
| return value; | |
| } | |
| inline bool IsBool(Interop::TypeName const& t) { | |
| return t.Kind == Interop::TypeKind::Primitive && t.Name.size() == 7 && std::memcmp(t.Name.data(), L"Boolean", 7 * sizeof(wchar_t)) == 0; | |
| } | |
| bool IsFloat(Interop::TypeName const& t) { | |
| if (t.Kind == Interop::TypeKind::Primitive && t.Name.size() == 6) { | |
| const wchar_t* b = t.Name.data(); | |
| if (std::memcmp(b, L"Single", 6 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(b, L"Double", 6 * sizeof(wchar_t)) == 0) return true; | |
| } | |
| return false; | |
| } | |
| bool IsInteger(Interop::TypeName const& t) { | |
| if (t.Kind == Interop::TypeKind::Primitive) { | |
| const wchar_t* b = t.Name.data(); | |
| switch (t.Name.size()) { | |
| case 4: | |
| return std::memcmp(b, L"Int8", 4 * sizeof(wchar_t)) == 0; | |
| case 5: | |
| if (std::memcmp(b, L"Int16", 5 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(b, L"Int32", 5 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(b, L"Int64", 5 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(b, L"UInt8", 5 * sizeof(wchar_t)) == 0) return true; | |
| return false; | |
| case 6: | |
| if (std::memcmp(b, L"UInt16", 6 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(b, L"UInt32", 6 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(b, L"UInt64", 6 * sizeof(wchar_t)) == 0) return true; | |
| return false; | |
| } | |
| } | |
| return false; | |
| } | |
| inline bool IsString(Interop::TypeName const& t) { | |
| return t.Kind == Interop::TypeKind::Primitive && t.Name.size() == 6 && std::memcmp(t.Name.data(), L"String", 6 * sizeof(wchar_t)) == 0; | |
| } | |
| inline bool IsNumber(Interop::TypeName const& t) { | |
| return t.Kind == Interop::TypeKind::Primitive && (IsInteger(t) || IsFloat(t)); | |
| } | |
| inline bool IsPrimitiveType(const wchar_t* begin, size_t len) { | |
| switch (len) { | |
| case 4: // Guid, Int8 | |
| if (std::memcmp(begin, L"Guid", 4 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"Int8", 4 * sizeof(wchar_t)) == 0) return true; | |
| return false; | |
| case 5: // Int16, Int32, Int64, UInt8 | |
| if (std::memcmp(begin, L"Int16", 5 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"Int32", 5 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"Int64", 5 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"UInt8", 5 * sizeof(wchar_t)) == 0) return true; | |
| return false; | |
| case 6: // String, Single, Double, Char16, UInt16, UInt32, UInt64 | |
| if (std::memcmp(begin, L"String", 6 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"Single", 6 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"Double", 6 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"Char16", 6 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"UInt16", 6 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"UInt32", 6 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"UInt64", 6 * sizeof(wchar_t)) == 0) return true; | |
| return false; | |
| case 7: // Boolean | |
| if (std::memcmp(begin, L"Boolean", 7 * sizeof(wchar_t)) == 0) return true; | |
| return false; | |
| case 8: // DateTime, TimeSpan | |
| if (std::memcmp(begin, L"DateTime", 8 * sizeof(wchar_t)) == 0) return true; | |
| if (std::memcmp(begin, L"TimeSpan", 8 * sizeof(wchar_t)) == 0) return true; | |
| return false; | |
| default: | |
| return false; | |
| } | |
| } | |
| static Interop::TypeName GetTypeName(winrt::hstring const& name){ | |
| const wchar_t* begin = name.data(); | |
| const wchar_t* end = begin + name.size(); | |
| static constexpr wchar_t prefix[] = L"Windows.Foundation.IReference`1<"; | |
| static constexpr size_t prefixLen = std::size(prefix) - 1; | |
| const wchar_t* curBegin = begin; | |
| const wchar_t* curEnd = end; | |
| // Try unwrap once | |
| if (static_cast<size_t>(curEnd - curBegin) > prefixLen + 1 && | |
| std::memcmp(curBegin, prefix, prefixLen * sizeof(wchar_t)) == 0 && | |
| *(curEnd - 1) == L'>') { | |
| curBegin += prefixLen; | |
| curEnd -= 1; | |
| } | |
| const size_t len = static_cast<size_t>(curEnd - curBegin); | |
| // Detect primitive | |
| const bool isPrimitive = IsPrimitiveType(curBegin, len); | |
| // Allocate final name | |
| winrt::hstring finalName{ curBegin, static_cast<uint32_t>(len) }; | |
| Interop::TypeName typeName; | |
| typeName.Name = finalName; | |
| typeName.Kind = isPrimitive | |
| ? Interop::TypeKind::Primitive | |
| : Interop::TypeKind::Custom; | |
| return typeName; | |
| } | |
| static Interop::TypeName GetTypeName(wf::IInspectable const& resource){ | |
| return GetTypeName(winrt::get_class_name(resource)); | |
| } | |
| } | |
| #pragma region Implementations | |
| const std::wstring StyleRule::toString() const { | |
| std::wstring s = this->name; | |
| if(this->visualState.size() > 0) { s += L"@" + this->visualState; } | |
| if(this->isXamlValue) { s += L":"; } | |
| if(this->value.size() > 0) { s += L"=" + this->value; } | |
| return s; | |
| } | |
| const std::wstring SelectorChain::toString() const { | |
| std::wstring s; | |
| s.reserve(40 + (this->ancestorMatchers.size() * 40)); | |
| for(auto it = this->ancestorMatchers.rbegin(); it != this->ancestorMatchers.rend(); ++it) { | |
| const ElementMatcher& ancestor = *it; | |
| s += ancestor.isDescendant ? L" " : L" > "; | |
| } | |
| s += this->targetMatcher.toString(); | |
| s += this->targetMatcher.isDescendant ? L" " : L" > "; | |
| return s; | |
| } | |
| const std::wstring ElementMatcher::toString() const { | |
| const ElementMatcher& a = *this; | |
| std::wstring s; | |
| s.reserve(1 + (a.type == nullptr ? 0 : a.type->size()) + (a.name.size() + 1) + | |
| (a.visualStateGroupName.has_value() ? a.visualStateGroupName.value().size() + 1 : 0) + | |
| (a.oneBasedIndex > 0 ? 2 + std::to_wstring(a.oneBasedIndex).size() : 0) + | |
| (a.hasSelectors.size() * 60) + | |
| (a.notHasSelectors.size() * 60)); | |
| if(a.type) { s += *a.type; } | |
| if(a.name.size() > 0) { s += L"#" + a.name; } | |
| if(a.visualStateGroupName.has_value()) { s += L"@" + a.visualStateGroupName.value(); } | |
| if(a.oneBasedIndex > 0) { s += L"[" + std::to_wstring(a.oneBasedIndex) + L"]"; } | |
| if(a.hasSelectors.size() > 0) { | |
| for(const SelectorChain& chain : a.hasSelectors) { | |
| s += L":has("; | |
| s += chain.toString(); | |
| s += L")"; | |
| } | |
| } | |
| if(a.notHasSelectors.size() > 0) { | |
| for(const SelectorChain& chain : a.notHasSelectors) { | |
| s += L":not-has("; | |
| s += chain.toString(); | |
| s += L")"; | |
| } | |
| } | |
| return s; | |
| } | |
| const std::wstring ElementCustomizationRules::toString() const { | |
| std::wstring s; | |
| s.reserve(std::min<size_t>(40 + this->parentElementMatchers.size() * 40, 160)); | |
| for(const ElementMatcher& m : this->parentElementMatchers) { | |
| s += m.toString() + L" > "; | |
| } | |
| s += this->elementMatcher.toString(); | |
| return s; | |
| } | |
| bool SelectorChain::Equals(const SelectorChain& a, const SelectorChain& b) { | |
| if(!a.targetMatcher.Equals(b.targetMatcher)) { return false; } | |
| if(a.ancestorMatchers.size() != b.ancestorMatchers.size()) { return false; } | |
| for(size_t i = 0; i < a.ancestorMatchers.size(); i++) { | |
| if(!a.ancestorMatchers[i].Equals(b.ancestorMatchers[i])) { return false; } | |
| } | |
| return true; | |
| } | |
| bool ElementMatcher::Equals(const ElementMatcher& a, const ElementMatcher& b) { | |
| if (&a == &b) { return true; } | |
| if (a.name != b.name) { return false; } | |
| if (a.visualStateGroupName != b.visualStateGroupName) { return false; } | |
| if (a.oneBasedIndex != b.oneBasedIndex) { return false; } | |
| if (a.isDescendant != b.isDescendant) { return false; } | |
| if(a.hasSelectors.size() != b.hasSelectors.size()) { return false; } | |
| if(a.notHasSelectors.size() != b.notHasSelectors.size()) { return false; } | |
| if (!(a.type == b.type || *a.type == *b.type)) { return false; } | |
| const std::vector<PropertyValueUnresolved>* aU = std::get_if<PropertyValuesUnresolved>(&a.propertyValues); | |
| const std::vector<PropertyValueUnresolved>* bU = std::get_if<PropertyValuesUnresolved>(&b.propertyValues); | |
| if (aU && !bU) { return false; } | |
| if (!aU && bU) { return false; } | |
| if (aU && bU) { | |
| if(aU->size() != bU->size()) { return false; } | |
| if (aU->size() > 0) { | |
| for(size_t i = 0; i < aU->size(); i++) { | |
| const PropertyValueUnresolved& aP = (*aU)[i]; | |
| const PropertyValueUnresolved& bP = (*bU)[i]; | |
| if(aP.key != bP.key) { return false; } | |
| if(aP.value != bP.value) { return false; } | |
| if(aP.matchMode != bP.matchMode) { return false; } | |
| if(aP.isDynamic != bP.isDynamic) { return false; } | |
| } | |
| } | |
| } | |
| for(size_t i = 0; i < a.hasSelectors.size(); i++) { | |
| if(!a.hasSelectors[i].Equals(b.hasSelectors[i])) { return false; } | |
| } | |
| for(size_t i = 0; i < a.notHasSelectors.size(); i++) { | |
| if(!a.notHasSelectors[i].Equals(b.notHasSelectors[i])) { return false; } | |
| } | |
| return true; | |
| } | |
| bool ElementCustomizationRules::Equals(const ElementCustomizationRules& A, const ElementCustomizationRules& B) { | |
| if(!A.elementMatcher.Equals(B.elementMatcher)) { return false; } | |
| size_t len = A.parentElementMatchers.size(); | |
| if(len != B.parentElementMatchers.size()) { return false; } | |
| for(size_t i = 0; i < len; i++) { | |
| if(!A.parentElementMatchers[i].Equals(B.parentElementMatchers[i])) { return false; } | |
| } | |
| return true; | |
| } | |
| std::vector<TargetToken> TargetToken::Tokenize(std::wstring_view target) { | |
| // Split by ">" first, keeping track of spacing. | |
| // Strategy: scan for ">" as child combinator; spaces between non-">" tokens | |
| // are descendant combinators. | |
| size_t len = target.size(); | |
| size_t i = 0; | |
| // We'll collect segments: each segment is a token, and we track what | |
| // combinator follows it. | |
| // Combinators: '>' = direct child, ' ' = descendant | |
| std::vector<TargetToken> rawTokens; | |
| while(i < len) { | |
| //skipSpaces(); | |
| while(i < len && target[i] == L' ') { i++; } | |
| if(i >= len) { break; } | |
| // Read a token (everything until next whitespace or '>'), | |
| // but skip over bracketed sections [...] which may contain spaces. | |
| size_t start = i; | |
| while(i < len && target[i] != L' ' && target[i] != L'>') { | |
| if(target[i] == L'[') { | |
| // Skip to closing bracket | |
| while(i < len && target[i] != L']') { i++; } | |
| if(i < len) { | |
| i++; // skip ']' | |
| } | |
| } else if(target[i] == L':' && i + 8 < len && target.substr(i, 9) == L":not-has(") { | |
| // Skip :not-has(...) including nested parentheses | |
| i += 9; // skip ":not-has(" | |
| int depth = 1; | |
| while(i < len && depth > 0) { | |
| if(target[i] == L'(') { | |
| depth++; | |
| } else if(target[i] == L')') { | |
| depth--; | |
| } | |
| i++; | |
| } | |
| } else if(target[i] == L':' && i + 4 < len && target.substr(i, 5) == L":has(") { | |
| // Skip :has(...) including nested parentheses | |
| i += 5; // skip ":has(" | |
| int depth = 1; | |
| while(i < len && depth > 0) { | |
| if(target[i] == L'(') { | |
| depth++; | |
| } else if(target[i] == L')') { | |
| depth--; | |
| } | |
| i++; | |
| } | |
| } else { | |
| i++; | |
| } | |
| } | |
| if(i == start) { | |
| // Could be a standalone '>' | |
| if(target[i] == L'>') { | |
| i++; | |
| // Mark previous token as direct child | |
| if(!rawTokens.empty()) { rawTokens.back().isDirectChild = true; } | |
| continue; | |
| } | |
| break; | |
| } | |
| std::wstring_view tokenText = target.substr(start, i - start); | |
| // Look ahead to see what combinator follows | |
| //skipSpaces(); | |
| while(i < len && target[i] == L' ') { i++; } | |
| bool directChild = false; | |
| if(i < len && target[i] == L'>') { | |
| directChild = true; | |
| i++; | |
| // skipSpaces(); | |
| while(i < len && target[i] == L' ') { i++; } | |
| } | |
| rawTokens.push_back({ tokenText, directChild }); | |
| } | |
| // Convert to TargetToken: for parent matching we need to know for each parent | |
| // matcher whether it's a direct parent or any-ancestor. The relationship is | |
| // stored on the PARENT matcher (i.e., the token to the left). | |
| // The isDirectChild on TargetToken means: "this token is a direct child of | |
| // the token to its left" — we store it that way for the consumer. | |
| std::vector<TargetToken> tokens; | |
| tokens.reserve(rawTokens.size()); | |
| for(size_t t = 0; t < rawTokens.size(); t++) { | |
| TargetToken tt; | |
| tt.text = rawTokens[t].text; | |
| // For the leftmost token (ultimate ancestor), isDirectChild doesn't matter. | |
| // For others, it's determined by the combinator on the token to the LEFT. | |
| if(t == 0) { | |
| tt.isDirectChild = false; // doesn't matter for root | |
| } else { | |
| tt.isDirectChild = rawTokens[t - 1].isDirectChild; | |
| } | |
| tokens.push_back(tt); | |
| } | |
| return tokens; | |
| } | |
| ElementMatcher ElementMatcher::FromString(std::wstring_view str) { | |
| ElementMatcher result; | |
| PropertyValuesUnresolved propertyValuesUnresolved; | |
| // Extract :has(...) selectors before normal parsing. | |
| // They appear after the type/name/properties, e.g.: | |
| // Type#Name[Prop=Val]:has(InnerType[Prop^=Val]) | |
| std::wstring strBuf; | |
| std::vector<std::wstring_view> hasContents; | |
| std::vector<std::wstring_view> notHasContents; | |
| { | |
| // Find all :has(...) and :not-has(...) occurrences and remove them from | |
| // str, collecting the inner content. | |
| std::wstring_view remaining = str; | |
| while(true) { | |
| size_t notHasPos = remaining.find(L":not-has("); | |
| size_t hasPos = remaining.find(L":has("); | |
| // If the :has( found is the one embedded inside :not-has(, skip past it. | |
| while(hasPos != std::wstring_view::npos && notHasPos != std::wstring_view::npos && | |
| hasPos == notHasPos + 4) { | |
| hasPos = remaining.find(L":has(", hasPos + 1); | |
| } | |
| bool isNotHas; | |
| size_t matchPos; | |
| size_t prefixLen; | |
| if(hasPos == std::wstring_view::npos && notHasPos == std::wstring_view::npos) { | |
| break; | |
| } else if(hasPos == std::wstring_view::npos) { | |
| isNotHas = true; | |
| matchPos = notHasPos; | |
| prefixLen = 9; // length of ":not-has(" | |
| } else if(notHasPos == std::wstring_view::npos) { | |
| isNotHas = false; | |
| matchPos = hasPos; | |
| prefixLen = 5; // length of ":has(" | |
| } else { | |
| isNotHas = notHasPos < hasPos; | |
| matchPos = isNotHas ? notHasPos : hasPos; | |
| prefixLen = isNotHas ? 9 : 5; | |
| } | |
| strBuf += remaining.substr(0, matchPos); | |
| // Find matching ')' accounting for nested parens. | |
| size_t depth = 1; | |
| size_t start = matchPos + prefixLen; | |
| size_t j = start; | |
| while(j < remaining.size() && depth > 0) { | |
| if(remaining[j] == L'(') { | |
| depth++; | |
| } else if(remaining[j] == L')') { | |
| depth--; | |
| } | |
| j++; | |
| } | |
| if(depth != 0) { | |
| throw std::runtime_error(isNotHas ? "Bad target syntax, unmatched :not-has( parenthesis" | |
| : "Bad target syntax, unmatched :has( parenthesis"); | |
| } | |
| std::wstring_view content = remaining.substr(start, j - start - 1); | |
| if(isNotHas) { | |
| notHasContents.push_back(content); | |
| } else { | |
| hasContents.push_back(content); | |
| } | |
| remaining = remaining.substr(j); | |
| } | |
| if(!hasContents.empty() || !notHasContents.empty()) { | |
| strBuf += remaining; | |
| str = strBuf; | |
| Wh_Log(L"[BUILD selectors] extracted %zu :has() and %zu :not-has() clause(s), remaining type str='%.*s'", | |
| hasContents.size(), notHasContents.size(), (int)str.size(), str.data()); | |
| } | |
| } | |
| size_t i = str.find_first_of(L"#@["); | |
| std::wstring_view rawType = StrFmt::TrimStringView(str.substr(0, i)); | |
| if(rawType.empty()) { throw std::runtime_error("Bad target syntax, empty type"); } | |
| if(rawType == L"??") { | |
| throw std::runtime_error("Bad TypeName, got ?? which is reserved for unknown types. This likely means the selector " | |
| "is malformed and the type was not parsed correctly."); | |
| } | |
| result.type = InternTypeName(rawType); | |
| while(i != str.npos) { | |
| size_t iNext = str[i] == L'[' | |
| ? str.find(L']', i + 1) == str.npos ? str.npos : str.find_first_of(L"#@[", str.find(L']', i + 1) + 1) | |
| : str.find_first_of(L"#@[", i + 1); | |
| std::wstring_view nextPart = str.substr(i + 1, iNext == str.npos ? str.npos : iNext - (i + 1)); | |
| switch(str[i]) { | |
| case L'#': | |
| if(!result.name.empty()) { throw std::runtime_error("Bad target syntax, more than one name"); } | |
| result.name = StrFmt::TrimStringView(nextPart); | |
| if(result.name.empty()) { throw std::runtime_error("Bad target syntax, empty name"); } | |
| break; | |
| case L'@': | |
| if(result.visualStateGroupName) { | |
| throw std::runtime_error("Bad target syntax, more than one visual state group"); | |
| } | |
| result.visualStateGroupName = StrFmt::TrimStringView(nextPart); | |
| break; | |
| case L'[': { | |
| std::wstring_view rule = StrFmt::TrimStringView(nextPart); | |
| if(rule.length() == 0 || rule.back() != L']') { throw std::runtime_error("Bad target syntax, missing ']'"); } | |
| rule = StrFmt::TrimStringView(rule.substr(0, rule.length() - 1)); | |
| if(rule.length() == 0) { throw std::runtime_error("Bad target syntax, empty property"); } | |
| if(rule.find_first_not_of(L"0123456789") == rule.npos) { | |
| result.oneBasedIndex = std::stoi(std::wstring(rule)); | |
| break; | |
| } | |
| // Detect match mode: ^= (StartsWith), $= (EndsWith), *= (Contains), = (Exact) | |
| AttrMatchMode matchMode = AttrMatchMode::Exact; | |
| size_t ruleEqPos = rule.find(L'='); | |
| if(ruleEqPos == rule.npos) { throw std::runtime_error("Bad target syntax, missing '=' in property"); } | |
| if(ruleEqPos > 0) { | |
| wchar_t preceding = rule[ruleEqPos - 1]; | |
| if(preceding == L'^') { | |
| matchMode = AttrMatchMode::StartsWith; | |
| ruleEqPos--; // exclude the ^ from the key | |
| } else if(preceding == L'$') { | |
| matchMode = AttrMatchMode::EndsWith; | |
| ruleEqPos--; | |
| } else if(preceding == L'*') { | |
| matchMode = AttrMatchMode::Contains; | |
| ruleEqPos--; | |
| } else if(preceding == L'!') { | |
| matchMode = AttrMatchMode::NotEqual; | |
| ruleEqPos--; | |
| } else if(preceding == L'>') { | |
| matchMode = AttrMatchMode::GreaterOrEqual; | |
| ruleEqPos--; | |
| } else if(preceding == L'<') { | |
| matchMode = AttrMatchMode::LessOrEqual; | |
| ruleEqPos--; | |
| } | |
| } | |
| std::wstring_view ruleKey = StrFmt::TrimStringView(rule.substr(0, ruleEqPos)); | |
| // Skip past the operator chars to get the value | |
| size_t valStart = rule.find(L'='); | |
| std::wstring_view ruleVal = StrFmt::TrimStringView(rule.substr(valStart + 1)); | |
| if(ruleKey.length() == 0) { throw std::runtime_error("Bad target syntax, empty property name"); } | |
| // Detect @ prefix for dynamic property matching. | |
| bool isDynamic = false; | |
| if(ruleKey.front() == L'@') { | |
| isDynamic = true; | |
| ruleKey = ruleKey.substr(1); | |
| if(ruleKey.empty()) { throw std::runtime_error("Bad target syntax, empty property name after @"); } | |
| } | |
| propertyValuesUnresolved.push_back({ std::wstring(ruleKey), std::wstring(ruleVal), matchMode, isDynamic }); | |
| break; | |
| } | |
| default: | |
| throw std::runtime_error("Bad target syntax"); | |
| } | |
| i = iNext; | |
| } | |
| result.propertyValues = std::move(propertyValuesUnresolved); | |
| // Build :has() selector chains from the extracted contents. | |
| // Each :has() content may be a multi-segment selector (e.g. "A B[C^=D]"), | |
| // so we tokenize it the same way as the outer selector. | |
| for(const std::wstring_view& hasContent : hasContents) { | |
| Wh_Log(L"[BUILD :has()] content: '%.*s'", (int)hasContent.size(), hasContent.data()); | |
| SelectorChain chain; | |
| std::vector<TargetToken> tokens = TargetToken::Tokenize(hasContent); | |
| Wh_Log(L"[BUILD :has()] tokenized into %zu token(s)", tokens.size()); | |
| for(size_t ti = 0; ti < tokens.size(); ti++) { | |
| Wh_Log(L"[BUILD :has()] token[%zu]: '%.*s' isDirectChild=%d", ti, (int)tokens[ti].text.size(), | |
| tokens[ti].text.data(), (int)tokens[ti].isDirectChild); | |
| } | |
| if(tokens.empty()) { throw std::runtime_error("Empty :has() selector"); } | |
| bool first = true; | |
| for(auto it = tokens.rbegin(); it != tokens.rend(); ++it) { | |
| ElementMatcher matcher = ElementMatcher::FromString(it->text); | |
| matcher.type = Helper::AdjustTypeName(*matcher.type); | |
| if(first) { | |
| chain.targetMatcher = std::move(matcher); | |
| Wh_Log(L"[BUILD :has()] targetMatcher type=%s", chain.targetMatcher.type->c_str()); | |
| first = false; | |
| } else { | |
| auto rightNeighbor = std::prev(it); // one step back toward the right | |
| matcher.isDescendant = !rightNeighbor->isDirectChild; | |
| Wh_Log(L"[BUILD :has()] ancestorMatcher type=%s isDescendant=%d", matcher.type->c_str(), | |
| (int)matcher.isDescendant); | |
| chain.ancestorMatchers.push_back(std::move(matcher)); | |
| } | |
| } | |
| result.hasSelectors.push_back(std::move(chain)); | |
| } | |
| // Build :not-has() selector chains from the extracted contents. | |
| for(const std::wstring_view& notHasContent : notHasContents) { | |
| Wh_Log(L"[BUILD :not-has()] content: '%.*s'", (int)notHasContent.size(), notHasContent.data()); | |
| SelectorChain chain; | |
| std::vector<TargetToken> tokens = TargetToken::Tokenize(notHasContent); | |
| Wh_Log(L"[BUILD :not-has()] tokenized into %zu token(s)", tokens.size()); | |
| for(size_t ti = 0; ti < tokens.size(); ti++) { | |
| Wh_Log(L"[BUILD :not-has()] token[%zu]: '%.*s' isDirectChild=%d", ti, (int)tokens[ti].text.size(), | |
| tokens[ti].text.data(), (int)tokens[ti].isDirectChild); | |
| } | |
| if(tokens.empty()) { throw std::runtime_error("Empty :not-has() selector"); } | |
| bool first = true; | |
| for(auto it = tokens.rbegin(); it != tokens.rend(); ++it) { | |
| ElementMatcher matcher = ElementMatcher::FromString(it->text); | |
| matcher.type = Helper::AdjustTypeName(*matcher.type); | |
| if(first) { | |
| chain.targetMatcher = std::move(matcher); | |
| Wh_Log(L"[BUILD :not-has()] targetMatcher type=%s", chain.targetMatcher.type->c_str()); | |
| first = false; | |
| } else { | |
| auto rightNeighbor = std::prev(it); // one step back toward the right | |
| matcher.isDescendant = !rightNeighbor->isDirectChild; | |
| Wh_Log(L"[BUILD :not-has()] ancestorMatcher type=%s isDescendant=%d", matcher.type->c_str(), | |
| (int)matcher.isDescendant); | |
| chain.ancestorMatchers.push_back(std::move(matcher)); | |
| } | |
| } | |
| result.notHasSelectors.push_back(std::move(chain)); | |
| } | |
| return result; | |
| } | |
| #pragma endregion // Implementations | |
| // Blur background implementation, copied from TranslucentTB. | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // clang-format off | |
| #include <initguid.h> | |
| // namespace wfn = wf::Numerics; | |
| // namespace wge = winrt::Windows::Graphics::Effects; | |
| // namespace wuc = winrt::Windows::UI::Composition; | |
| // namespace wuxh = wux::Hosting; | |
| template <> inline constexpr winrt::guid winrt::impl::guid_v<winrt::impl::abi_t<wf::IPropertyValue>>{ | |
| winrt::impl::guid_v<wf::IPropertyValue> | |
| }; | |
| #ifndef E_BOUNDS | |
| #define E_BOUNDS (HRESULT)(0x8000000BL) | |
| #endif | |
| typedef enum MY_D2D1_GAUSSIANBLUR_OPTIMIZATION { | |
| MY_D2D1_GAUSSIANBLUR_OPTIMIZATION_SPEED = 0, | |
| MY_D2D1_GAUSSIANBLUR_OPTIMIZATION_BALANCED = 1, | |
| MY_D2D1_GAUSSIANBLUR_OPTIMIZATION_QUALITY = 2, | |
| MY_D2D1_GAUSSIANBLUR_OPTIMIZATION_FORCE_DWORD = 0xffffffff | |
| } MY_D2D1_GAUSSIANBLUR_OPTIMIZATION; | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // XamlBlurBrush.h | |
| // #include <winrt/Windows.Foundation.Numerics.h> | |
| // #include <winrt/Windows.UI.Composition.h> | |
| // #include <winrt/Windows.UI.Xaml.Media.h> | |
| // #include <winrt/Windows.UI.ViewManagement.h> | |
| class XamlBlurBrush : public wux::Media::XamlCompositionBrushBaseT<XamlBlurBrush> | |
| { | |
| public: | |
| XamlBlurBrush(wuc::Compositor compositor, | |
| float blurAmount, | |
| winrt::Windows::UI::Color tint, | |
| std::optional<uint8_t> tintOpacity, | |
| winrt::hstring tintThemeResourceKey); | |
| void OnConnected(); | |
| void OnDisconnected(); | |
| private: | |
| void RefreshThemeTint(); | |
| void OnThemeRefreshed(); | |
| wuc::Compositor m_compositor; | |
| float m_blurAmount; | |
| winrt::Windows::UI::Color m_tint; | |
| std::optional<uint8_t> m_tintOpacity; | |
| winrt::hstring m_tintThemeResourceKey; | |
| winrt::Windows::UI::ViewManagement::UISettings m_uiSettings; | |
| }; | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // CompositeEffect.h | |
| #include <d2d1effects.h> | |
| #include <d2d1_1.h> | |
| #include <winrt/Windows.Foundation.h> | |
| #include <winrt/Windows.Graphics.Effects.h> | |
| // // #include <windows.graphics.effects.interop.h> | |
| // #include <windows.graphics.effects.h> | |
| // #include <sdkddkver.h> | |
| // clang-format on | |
| #ifndef BUILD_WINDOWS | |
| namespace ABI | |
| { | |
| #endif | |
| namespace Windows | |
| { | |
| namespace Graphics | |
| { | |
| namespace Effects | |
| { | |
| typedef interface IGraphicsEffectSource IGraphicsEffectSource; | |
| typedef interface IGraphicsEffectD2D1Interop IGraphicsEffectD2D1Interop; | |
| typedef enum GRAPHICS_EFFECT_PROPERTY_MAPPING { | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_UNKNOWN, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORX, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORY, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORZ, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_VECTORW, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_RECT_TO_VECTOR4, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_RADIANS_TO_DEGREES, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_COLORMATRIX_ALPHA_MODE, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_COLOR_TO_VECTOR3, | |
| GRAPHICS_EFFECT_PROPERTY_MAPPING_COLOR_TO_VECTOR4 | |
| } GRAPHICS_EFFECT_PROPERTY_MAPPING; | |
| //+----------------------------------------------------------------------------- | |
| // | |
| // Interface: | |
| // IGraphicsEffectD2D1Interop | |
| // | |
| // Synopsis: | |
| // An interface providing a Interop counterpart to IGraphicsEffect | |
| // and allowing for metadata queries. | |
| // | |
| //------------------------------------------------------------------------------ | |
| #undef INTERFACE | |
| #define INTERFACE IGraphicsEffectD2D1Interop | |
| DECLARE_INTERFACE_IID_(IGraphicsEffectD2D1Interop, IUnknown, "2FC57384-A068-44D7-A331-30982FCF7177") { | |
| STDMETHOD(GetEffectId)(_Out_ GUID * id) PURE; | |
| STDMETHOD(GetNamedPropertyMapping)(LPCWSTR name, _Out_ UINT * index, _Out_ GRAPHICS_EFFECT_PROPERTY_MAPPING * mapping) PURE; | |
| STDMETHOD(GetPropertyCount)(_Out_ UINT * count) PURE; | |
| STDMETHOD(GetProperty)(UINT index, _Outptr_ winrt::impl::abi_t<wf::IPropertyValue> * *value) PURE; | |
| STDMETHOD(GetSource)(UINT index, _Outptr_ IGraphicsEffectSource * *source) PURE; | |
| STDMETHOD(GetSourceCount)(_Out_ UINT * count) PURE; | |
| }; | |
| } // namespace Effects | |
| } // namespace Graphics | |
| } // namespace Windows | |
| #ifndef BUILD_WINDOWS | |
| } // namespace ABI | |
| #endif | |
| template<> | |
| inline constexpr winrt::guid winrt::impl::guid_v<ABI::Windows::Graphics::Effects::IGraphicsEffectD2D1Interop>{ | |
| 0x2FC57384, 0xA068, 0x44D7, { 0xA3, 0x31, 0x30, 0x98, 0x2F, 0xCF, 0x71, 0x77 } | |
| }; | |
| // namespace awge = ABI::Windows::Graphics::Effects; | |
| struct CompositeEffect | |
| : winrt::implements<CompositeEffect, wge::IGraphicsEffect, wge::IGraphicsEffectSource, awge::IGraphicsEffectD2D1Interop> { | |
| public: | |
| // IGraphicsEffectD2D1Interop | |
| HRESULT STDMETHODCALLTYPE GetEffectId(GUID* id) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetNamedPropertyMapping(LPCWSTR name, | |
| UINT* index, | |
| awge::GRAPHICS_EFFECT_PROPERTY_MAPPING* mapping) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetPropertyCount(UINT* count) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetProperty(UINT index, winrt::impl::abi_t<wf::IPropertyValue>** value) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetSource(UINT index, awge::IGraphicsEffectSource** source) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetSourceCount(UINT* count) noexcept override; | |
| // IGraphicsEffect | |
| winrt::hstring Name(); | |
| void Name(winrt::hstring name); | |
| std::vector<wge::IGraphicsEffectSource> Sources; | |
| D2D1_COMPOSITE_MODE Mode = D2D1_COMPOSITE_MODE_SOURCE_OVER; | |
| private: | |
| winrt::hstring m_name = L"CompositeEffect"; | |
| }; | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // CompositeEffect.cpp | |
| HRESULT CompositeEffect::GetEffectId(GUID* id) noexcept { | |
| if(id == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| *id = CLSID_D2D1Composite; | |
| return S_OK; | |
| } | |
| HRESULT CompositeEffect::GetNamedPropertyMapping(LPCWSTR name, | |
| UINT* index, | |
| awge::GRAPHICS_EFFECT_PROPERTY_MAPPING* mapping) noexcept { | |
| if(index == nullptr || mapping == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| const std::wstring_view nameView(name); | |
| if(nameView == L"Mode") { | |
| *index = D2D1_COMPOSITE_PROP_MODE; | |
| *mapping = awge::GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; | |
| return S_OK; | |
| } | |
| return E_INVALIDARG; | |
| } | |
| HRESULT CompositeEffect::GetPropertyCount(UINT* count) noexcept { | |
| if(count == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| *count = 1; | |
| return S_OK; | |
| } | |
| HRESULT CompositeEffect::GetProperty(UINT index, | |
| winrt::impl::abi_t<wf::IPropertyValue>** value) noexcept { | |
| try { | |
| if(value == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| switch(index) { | |
| case D2D1_COMPOSITE_PROP_MODE: | |
| *value = wf::PropertyValue::CreateUInt32((UINT32)Mode).as<winrt::impl::abi_t<wf::IPropertyValue>>().detach(); | |
| break; | |
| default: | |
| return E_BOUNDS; | |
| } | |
| return S_OK; | |
| } catch(...) { return winrt::to_hresult(); } | |
| } | |
| HRESULT CompositeEffect::GetSource(UINT index, awge::IGraphicsEffectSource** source) noexcept { | |
| try { | |
| if(source == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| winrt::copy_to_abi(Sources.at(index), *reinterpret_cast<void**>(source)); | |
| return S_OK; | |
| } catch(...) { return winrt::to_hresult(); } | |
| } | |
| HRESULT CompositeEffect::GetSourceCount(UINT* count) noexcept { | |
| if(count == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| *count = static_cast<UINT>(Sources.size()); | |
| return S_OK; | |
| } | |
| winrt::hstring CompositeEffect::Name() { return m_name; } | |
| void CompositeEffect::Name(winrt::hstring name) { m_name = name; } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // FloodEffect.h | |
| // #include <d2d1effects.h> | |
| // #include <winrt/Windows.Foundation.h> | |
| // #include <winrt/Windows.Foundation.Numerics.h> | |
| // #include <winrt/Windows.Graphics.Effects.h> | |
| // #include <windows.graphics.effects.interop.h> | |
| struct FloodEffect | |
| : winrt::implements<FloodEffect, wge::IGraphicsEffect, wge::IGraphicsEffectSource, awge::IGraphicsEffectD2D1Interop> { | |
| public: | |
| // IGraphicsEffectD2D1Interop | |
| HRESULT STDMETHODCALLTYPE GetEffectId(GUID* id) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetNamedPropertyMapping(LPCWSTR name, | |
| UINT* index, | |
| awge::GRAPHICS_EFFECT_PROPERTY_MAPPING* mapping) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetPropertyCount(UINT* count) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetProperty(UINT index, winrt::impl::abi_t<wf::IPropertyValue>** value) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetSource(UINT index, awge::IGraphicsEffectSource** source) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetSourceCount(UINT* count) noexcept override; | |
| // IGraphicsEffect | |
| winrt::hstring Name(); | |
| void Name(winrt::hstring name); | |
| winrt::Windows::UI::Color Color{}; | |
| private: | |
| winrt::hstring m_name = L"FloodEffect"; | |
| }; | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // FloodEffect.cpp | |
| HRESULT FloodEffect::GetEffectId(GUID* id) noexcept { | |
| if(id == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| *id = CLSID_D2D1Flood; | |
| return S_OK; | |
| } | |
| HRESULT FloodEffect::GetNamedPropertyMapping(LPCWSTR name, UINT* index, awge::GRAPHICS_EFFECT_PROPERTY_MAPPING* mapping) noexcept { | |
| if(index == nullptr || mapping == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| const std::wstring_view nameView(name); | |
| if(nameView == L"Color") { | |
| *index = D2D1_FLOOD_PROP_COLOR; | |
| *mapping = awge::GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; | |
| return S_OK; | |
| } | |
| return E_INVALIDARG; | |
| } | |
| HRESULT FloodEffect::GetPropertyCount(UINT* count) noexcept { | |
| if(count == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| *count = 1; | |
| return S_OK; | |
| } | |
| HRESULT FloodEffect::GetProperty(UINT index, winrt::impl::abi_t<wf::IPropertyValue>** value) noexcept { | |
| try { | |
| if(value == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| switch(index) { | |
| case D2D1_FLOOD_PROP_COLOR: | |
| *value = wf::PropertyValue::CreateSingleArray({ | |
| Color.R / 255.0f, | |
| Color.G / 255.0f, | |
| Color.B / 255.0f, | |
| Color.A / 255.0f, | |
| }) | |
| .as<winrt::impl::abi_t<wf::IPropertyValue>>() | |
| .detach(); | |
| break; | |
| default: | |
| return E_BOUNDS; | |
| } | |
| return S_OK; | |
| } catch(...) { return winrt::to_hresult(); } | |
| } | |
| HRESULT FloodEffect::GetSource(UINT, awge::IGraphicsEffectSource** source) noexcept { | |
| if(source == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| return E_BOUNDS; | |
| } | |
| HRESULT FloodEffect::GetSourceCount(UINT* count) noexcept { | |
| if(count == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| *count = 0; | |
| return S_OK; | |
| } | |
| winrt::hstring FloodEffect::Name() { return m_name; } | |
| void FloodEffect::Name(winrt::hstring name) { m_name = name; } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // GaussianBlurEffect.h | |
| #include <d2d1effects.h> | |
| #include <winrt/Windows.Foundation.h> | |
| #include <winrt/Windows.Graphics.Effects.h> | |
| // #include <windows.graphics.effects.interop.h> | |
| // namespace wge = winrt::Windows::Graphics::Effects; | |
| // namespace awge = ABI::Windows::Graphics::Effects; | |
| struct GaussianBlurEffect | |
| : winrt::implements<GaussianBlurEffect, wge::IGraphicsEffect, wge::IGraphicsEffectSource, awge::IGraphicsEffectD2D1Interop> { | |
| public: | |
| // IGraphicsEffectD2D1Interop | |
| HRESULT STDMETHODCALLTYPE GetEffectId(GUID* id) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetNamedPropertyMapping(LPCWSTR name, | |
| UINT* index, | |
| awge::GRAPHICS_EFFECT_PROPERTY_MAPPING* mapping) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetPropertyCount(UINT* count) noexcept override; | |
| HRESULT STDMETHODCALLTYPE | |
| GetProperty(UINT index, winrt::impl::abi_t<wf::IPropertyValue>** value) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetSource(UINT index, awge::IGraphicsEffectSource** source) noexcept override; | |
| HRESULT STDMETHODCALLTYPE GetSourceCount(UINT* count) noexcept override; | |
| // IGraphicsEffect | |
| winrt::hstring Name(); | |
| void Name(winrt::hstring name); | |
| wge::IGraphicsEffectSource Source; | |
| float BlurAmount = 3.0f; | |
| MY_D2D1_GAUSSIANBLUR_OPTIMIZATION Optimization = MY_D2D1_GAUSSIANBLUR_OPTIMIZATION_BALANCED; | |
| D2D1_BORDER_MODE BorderMode = D2D1_BORDER_MODE_SOFT; | |
| private: | |
| winrt::hstring m_name = L"GaussianBlurEffect"; | |
| }; | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // GaussianBlurEffect.cpp | |
| HRESULT GaussianBlurEffect::GetEffectId(GUID* id) noexcept { | |
| if(id == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| *id = CLSID_D2D1GaussianBlur; | |
| return S_OK; | |
| } | |
| HRESULT GaussianBlurEffect::GetNamedPropertyMapping(LPCWSTR name, | |
| UINT* index, | |
| awge::GRAPHICS_EFFECT_PROPERTY_MAPPING* mapping) noexcept { | |
| if(index == nullptr || mapping == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| const std::wstring_view nameView(name); | |
| if(nameView == L"BlurAmount") { | |
| *index = D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION; | |
| *mapping = awge::GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; | |
| return S_OK; | |
| } else if(nameView == L"Optimization") { | |
| *index = D2D1_GAUSSIANBLUR_PROP_OPTIMIZATION; | |
| *mapping = awge::GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; | |
| return S_OK; | |
| } else if(nameView == L"BorderMode") { | |
| *index = D2D1_GAUSSIANBLUR_PROP_BORDER_MODE; | |
| *mapping = awge::GRAPHICS_EFFECT_PROPERTY_MAPPING_DIRECT; | |
| return S_OK; | |
| } | |
| return E_INVALIDARG; | |
| } | |
| HRESULT GaussianBlurEffect::GetPropertyCount(UINT* count) noexcept { | |
| if(count == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| *count = 3; | |
| return S_OK; | |
| } | |
| HRESULT GaussianBlurEffect::GetProperty(UINT index, | |
| winrt::impl::abi_t<wf::IPropertyValue>** value) noexcept | |
| try { | |
| if(value == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| switch(index) { | |
| case D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION: | |
| *value = wf::PropertyValue::CreateSingle(BlurAmount) | |
| .as<winrt::impl::abi_t<wf::IPropertyValue>>() | |
| .detach(); | |
| break; | |
| case D2D1_GAUSSIANBLUR_PROP_OPTIMIZATION: | |
| *value = wf::PropertyValue::CreateUInt32((UINT32)Optimization) | |
| .as<winrt::impl::abi_t<wf::IPropertyValue>>() | |
| .detach(); | |
| break; | |
| case D2D1_GAUSSIANBLUR_PROP_BORDER_MODE: | |
| *value = wf::PropertyValue::CreateUInt32((UINT32)BorderMode) | |
| .as<winrt::impl::abi_t<wf::IPropertyValue>>() | |
| .detach(); | |
| break; | |
| default: | |
| return E_BOUNDS; | |
| } | |
| return S_OK; | |
| } catch(...) { return winrt::to_hresult(); } | |
| HRESULT GaussianBlurEffect::GetSource(UINT index, awge::IGraphicsEffectSource** source) noexcept { | |
| if(source == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| if(index == 0) { | |
| winrt::copy_to_abi(Source, *reinterpret_cast<void**>(source)); | |
| return S_OK; | |
| } else { | |
| return E_BOUNDS; | |
| } | |
| } | |
| HRESULT GaussianBlurEffect::GetSourceCount(UINT* count) noexcept { | |
| if(count == nullptr) [[unlikely]] { return E_INVALIDARG; } | |
| *count = 1; | |
| return S_OK; | |
| } | |
| winrt::hstring GaussianBlurEffect::Name() { return m_name; } | |
| void GaussianBlurEffect::Name(winrt::hstring name) { m_name = name; } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // XamlBlurBrush.cpp | |
| #include <winrt/Windows.System.h> | |
| XamlBlurBrush::XamlBlurBrush(wuc::Compositor compositor, | |
| float blurAmount, | |
| winrt::Windows::UI::Color tint, | |
| std::optional<uint8_t> tintOpacity, | |
| winrt::hstring tintThemeResourceKey) | |
| : m_compositor(std::move(compositor)) | |
| , m_blurAmount(blurAmount) | |
| , m_tint(tint) | |
| , m_tintOpacity(tintOpacity) | |
| , m_tintThemeResourceKey(std::move(tintThemeResourceKey)) { | |
| if(!m_tintThemeResourceKey.empty()) { | |
| RefreshThemeTint(); | |
| winrt::Windows::System::DispatcherQueue dq = winrt::Windows::System::DispatcherQueue::GetForCurrentThread(); | |
| m_uiSettings.ColorValuesChanged([weakThis = get_weak(), dq](auto const&, auto const&) { | |
| dq.TryEnqueue([weakThis] { | |
| if(winrt::com_ptr<XamlBlurBrush> self = weakThis.get()) { self->OnThemeRefreshed(); } | |
| }); | |
| }); | |
| } | |
| } | |
| void XamlBlurBrush::OnConnected() { | |
| if(!CompositionBrush()) { | |
| wuc::CompositionBackdropBrush backdropBrush = m_compositor.CreateBackdropBrush(); | |
| winrt::com_ptr<GaussianBlurEffect> blurEffect = winrt::make_self<GaussianBlurEffect>(); | |
| blurEffect->Source = wuc::CompositionEffectSourceParameter(L"backdrop"); | |
| blurEffect->BlurAmount = m_blurAmount; | |
| winrt::com_ptr<FloodEffect> floodEffect = winrt::make_self<FloodEffect>(); | |
| floodEffect->Color = m_tint; | |
| winrt::com_ptr<CompositeEffect> compositeEffect = winrt::make_self<CompositeEffect>(); | |
| compositeEffect->Sources.push_back(*blurEffect); | |
| compositeEffect->Sources.push_back(*floodEffect); | |
| compositeEffect->Mode = D2D1_COMPOSITE_MODE_SOURCE_OVER; | |
| // List of animatable properties. | |
| wuc::CompositionEffectFactory factory = | |
| m_compositor.CreateEffectFactory(*compositeEffect, { L"FloodEffect.Color" }); | |
| wuc::CompositionEffectBrush blurBrush = factory.CreateBrush(); | |
| blurBrush.SetSourceParameter(L"backdrop", backdropBrush); | |
| CompositionBrush(blurBrush); | |
| } | |
| } | |
| void XamlBlurBrush::OnDisconnected() { | |
| if(const wuc::CompositionBrush brush = CompositionBrush()) { | |
| brush.Close(); | |
| CompositionBrush(nullptr); | |
| } | |
| } | |
| void XamlBlurBrush::RefreshThemeTint() { | |
| if(m_tintThemeResourceKey.empty()) { return; } | |
| ResourceDictionary resources = Application::Current().Resources(); | |
| wf::IInspectable resource = resources.TryLookup(winrt::box_value(m_tintThemeResourceKey)); | |
| if(!resource) { | |
| Wh_Log(L"Failed to find resource"); | |
| return; | |
| } | |
| if(wux::Media::SolidColorBrush colorBrush = resource.try_as<wux::Media::SolidColorBrush>()) { | |
| m_tint = colorBrush.Color(); | |
| } else if(std::optional<winrt::Windows::UI::Color> color = resource.try_as<winrt::Windows::UI::Color>()) { | |
| m_tint = *color; | |
| } else { | |
| Wh_Log(L"Resource type is unsupported: %s", winrt::get_class_name(resource).c_str()); | |
| return; | |
| } | |
| if(m_tintOpacity) { m_tint.A = *m_tintOpacity; } | |
| } | |
| void XamlBlurBrush::OnThemeRefreshed() { | |
| Wh_Log(L"Theme refreshed"); | |
| winrt::Windows::UI::Color prevTint = m_tint; | |
| RefreshThemeTint(); | |
| if(prevTint != m_tint) { | |
| if(wuc::CompositionEffectBrush effectBrush = CompositionBrush().try_as<wuc::CompositionEffectBrush>()) { | |
| effectBrush.Properties().InsertColor(L"FloodEffect.Color", m_tint); | |
| } | |
| } | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // Helper functions for tracking and retrying failed ImageBrush loads. | |
| void RetryFailedImageLoadsOnCurrentThread() { | |
| Wh_Log(L"Retrying failed image loads on current thread"); | |
| std::list<ImageBrushFailedLoadInfo>& failedImageBrushes = g_failedImageBrushesForThread.failedImageBrushes; | |
| // Retry loading all failed images by re-setting the ImageSource property. | |
| for(ImageBrushFailedLoadInfo& info : failedImageBrushes) { | |
| if(Media::ImageBrush brush = info.brush.get()) { | |
| try { | |
| Wh_Log(L"Retrying image load for: %s", info.imageSource.c_str()); | |
| // Clear the ImageSource first to force a reload. | |
| brush.ImageSource(nullptr); | |
| // Then create a new BitmapImage and set it. | |
| Media::Imaging::BitmapImage bitmapImage; | |
| bitmapImage.UriSource(wf::Uri(info.imageSource)); | |
| brush.ImageSource(bitmapImage); | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error retrying image load %08X: %s", ex.code(), ex.message().c_str()); | |
| } | |
| } | |
| } | |
| // Clean up any weak refs that are no longer valid. | |
| std::erase_if(failedImageBrushes, [](const auto& info) { return !info.brush.get(); }); | |
| } | |
| void OnNetworkStatusChanged(wf::IInspectable const& sender) { | |
| Wh_Log(L"Network status changed, dispatching retry to all UI threads"); | |
| // Get snapshot of dispatchers under lock. | |
| std::vector<winrt::Windows::System::DispatcherQueue> dispatchers; | |
| { | |
| std::lock_guard<std::mutex> lock(g_failedImageBrushesRegistryMutex); | |
| for(winrt::weak_ref<winrt::Windows::System::DispatcherQueue>& weakDispatcher : g_failedImageBrushesRegistry) { | |
| if(winrt::Windows::System::DispatcherQueue dispatcher = weakDispatcher.get()) { | |
| dispatchers.push_back(dispatcher); | |
| } | |
| } | |
| // Clean up dead weak refs. | |
| std::erase_if(g_failedImageBrushesRegistry, [](const auto& weakDispatcher) { return !weakDispatcher.get(); }); | |
| } | |
| // Dispatch retry to each UI thread. | |
| for(winrt::Windows::System::DispatcherQueue& dispatcher : dispatchers) { | |
| try { | |
| dispatcher.TryEnqueue([]() { RetryFailedImageLoadsOnCurrentThread(); }); | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error dispatching retry to UI thread %08X: %s", ex.code(), ex.message().c_str()); | |
| } | |
| } | |
| } | |
| void RemoveFromFailedImageBrushes(Media::ImageBrush const& brush) { | |
| std::list<ImageBrushFailedLoadInfo>& failedImageBrushes = g_failedImageBrushesForThread.failedImageBrushes; | |
| std::erase_if(failedImageBrushes, [&brush](const auto& info) { | |
| if(Media::ImageBrush existingBrush = info.brush.get()) { return existingBrush == brush; } | |
| return false; | |
| }); | |
| } | |
| void SetupImageBrushTracking(Media::ImageBrush const& brush, winrt::hstring const& imageSourceUrl) { | |
| // First remove any existing entry for this brush to avoid duplicates. | |
| RemoveFromFailedImageBrushes(brush); | |
| // Add new entry with event handlers. | |
| ImageBrushFailedLoadInfo info; | |
| info.brush = winrt::make_weak(brush); | |
| info.imageSource = imageSourceUrl; | |
| // Set up ImageFailed event handler - add to list only when load fails. | |
| info.imageFailedRevoker = | |
| brush.ImageFailed(winrt::auto_revoke, [imageSourceUrl](wf::IInspectable const&, ExceptionRoutedEventArgs const& e) { | |
| Wh_Log(L"ImageBrush load failed for: %s, error: %s", imageSourceUrl.c_str(), e.ErrorMessage().c_str()); | |
| // The brush should already be in the list, no action needed here as | |
| // we add it preemptively in SetupImageBrushTracking. | |
| }); | |
| // Set up ImageOpened event handler - remove from list when load succeeds. | |
| info.imageOpenedRevoker = brush.ImageOpened( | |
| winrt::auto_revoke, [brushWeak = winrt::make_weak(brush)](wf::IInspectable const& sender, RoutedEventArgs const& e) { | |
| Wh_Log(L"ImageBrush loaded successfully, removing from retry list"); | |
| if(Media::ImageBrush brush = brushWeak.get()) { RemoveFromFailedImageBrushes(brush); } | |
| }); | |
| // Add to the list preemptively - will be removed if load succeeds. | |
| std::list<ImageBrushFailedLoadInfo>& failedImageBrushes = g_failedImageBrushesForThread.failedImageBrushes; | |
| failedImageBrushes.push_back(std::move(info)); | |
| // Ensure we have a dispatcher for this thread. | |
| if(!g_failedImageBrushesForThread.dispatcher) { | |
| try { | |
| g_failedImageBrushesForThread.dispatcher = winrt::Windows::System::DispatcherQueue::GetForCurrentThread(); | |
| if(g_failedImageBrushesForThread.dispatcher) { | |
| // Register this thread's dispatcher globally. | |
| std::lock_guard<std::mutex> lock(g_failedImageBrushesRegistryMutex); | |
| g_failedImageBrushesRegistry.push_back(winrt::make_weak(g_failedImageBrushesForThread.dispatcher)); | |
| Wh_Log(L"Registered UI thread dispatcher for network retry"); | |
| } | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error getting dispatcher for current thread %08X: %s", ex.code(), ex.message().c_str()); | |
| } | |
| } | |
| // Register global network status changed handler if not already registered. | |
| // This is a one-time global registration. | |
| [[maybe_unused]] static bool networkHandlerRegistered = []() { | |
| try { | |
| g_networkStatusChangedToken = | |
| winrt::Windows::Networking::Connectivity::NetworkInformation::NetworkStatusChanged(OnNetworkStatusChanged); | |
| Wh_Log(L"Registered global network status change handler"); | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error registering network status handler %08X: %s", ex.code(), ex.message().c_str()); | |
| } | |
| return true; | |
| }(); | |
| } | |
| void SetOrClearValue(DependencyObject elementDo, | |
| DependencyProperty property, | |
| const PropertyOverrideValue& overrideValue, | |
| bool initialApply = false) { | |
| wf::IInspectable value; | |
| if(const wf::IInspectable* inspectable = std::get_if<wf::IInspectable>(&overrideValue)) { | |
| value = *inspectable; | |
| } else if(const XamlBlurBrushParams* blurBrushParams = std::get_if<XamlBlurBrushParams>(&overrideValue)) { | |
| if(UIElement uiElement = elementDo.try_as<UIElement>()) { | |
| wuc::Compositor compositor = wuxh::ElementCompositionPreview::GetElementVisual(uiElement).Compositor(); | |
| value = winrt::make<XamlBlurBrush>(std::move(compositor), blurBrushParams->blurAmount, blurBrushParams->tint, | |
| blurBrushParams->tintOpacity, | |
| winrt::hstring(blurBrushParams->tintThemeResourceKey)); | |
| } else { | |
| Wh_Log(L"Can't get UIElement for blur brush"); | |
| return; | |
| } | |
| } else { | |
| Wh_Log(L"Unsupported override value"); | |
| return; | |
| } | |
| // If customized before | |
| // `winrt::Taskbar::implementation::TaskbarBackground::OnApplyTemplate` is | |
| // executed, it can lead to a crash, or the customization may be overridden. | |
| // See: | |
| // https://github.com/ramensoftware/windows-11-taskbar-styling-guide/issues/4 | |
| if(winrt::get_class_name(elementDo) == L"Windows.UI.Xaml.Shapes.Rectangle" && | |
| elementDo.as<FrameworkElement>().Name() == L"BackgroundFill" && property == Shapes::Shape::FillProperty()) { | |
| std::list<std::pair<winrt::weak_ref<DependencyObject>, wf::IAsyncOperation<bool>>>::iterator it = | |
| std::find_if(g_delayedBackgroundFillSet.begin(), g_delayedBackgroundFillSet.end(), [&elementDo](const auto& it) { | |
| if(DependencyObject elementDoIter = it.first.get()) { return elementDoIter == elementDo; } | |
| return false; | |
| }); | |
| if(value != DependencyProperty::UnsetValue() && initialApply && it == g_delayedBackgroundFillSet.end()) { | |
| Wh_Log(L"Delaying SetValue for BackgroundFill"); | |
| wf::IAsyncOperation<bool> asyncOp = elementDo.Dispatcher().TryRunAsync( | |
| winrt::Windows::UI::Core::CoreDispatcherPriority::High, | |
| [elementDo = std::move(elementDo), property = std::move(property), value = std::move(value)]() { | |
| Wh_Log(L"Running delayed SetValue for BackgroundFill"); | |
| try { | |
| elementDo.SetValue(property, value); | |
| } catch(winrt::hresult_error const& ex) { Wh_Log(L"Error %08X: %s", ex.code(), ex.message().c_str()); } | |
| std::erase_if(g_delayedBackgroundFillSet, [&elementDo](const auto& it) { | |
| if(DependencyObject elementDoIter = it.first.get()) { return elementDoIter == elementDo; } | |
| return false; | |
| }); | |
| }); | |
| g_delayedBackgroundFillSet.emplace_back(elementDo, std::move(asyncOp)); | |
| return; | |
| } else if(it != g_delayedBackgroundFillSet.end()) { | |
| Wh_Log(L"Canceling delayed SetValue for BackgroundFill"); | |
| it->second.Cancel(); | |
| g_delayedBackgroundFillSet.erase(it); | |
| } | |
| } | |
| if(value == DependencyProperty::UnsetValue()) { | |
| elementDo.ClearValue(property); | |
| return; | |
| } | |
| // Track ImageBrush with remote ImageSource for retry on network | |
| // reconnection. This handles cases where an ImageBrush is set as a property | |
| // value (e.g., Background). | |
| if(Media::ImageBrush imageBrush = value.try_as<Media::ImageBrush>()) { | |
| Media::ImageSource imageSource = imageBrush.ImageSource(); | |
| if(Media::Imaging::BitmapImage bitmapImage = imageSource.try_as<Media::Imaging::BitmapImage>()) { | |
| wf::Uri uriSource = bitmapImage.UriSource(); | |
| if(uriSource) { | |
| winrt::hstring uriString = uriSource.ToString(); | |
| if(uriString.starts_with(L"https://") || uriString.starts_with(L"http://")) { | |
| Wh_Log(L"Tracking ImageBrush with remote source: %s", uriString.c_str()); | |
| SetupImageBrushTracking(imageBrush, uriString); | |
| } | |
| } | |
| } | |
| } else if(Media::ImageBrush imageBrush = elementDo.try_as<Media::ImageBrush>()) { | |
| // Also handle direct ImageSource property being set on an ImageBrush. | |
| if(property == Media::ImageBrush::ImageSourceProperty()) { | |
| // Check if the value is a BitmapImage with an http(s):// URI. | |
| if(Media::Imaging::BitmapImage bitmapImage = value.try_as<Media::Imaging::BitmapImage>()) { | |
| wf::Uri uriSource = bitmapImage.UriSource(); | |
| if(uriSource) { | |
| winrt::hstring uriString = uriSource.ToString(); | |
| if(uriString.starts_with(L"https://") || uriString.starts_with(L"http://")) { | |
| Wh_Log(L"Tracking ImageBrush ImageSource property with remote source: %s", uriString.c_str()); | |
| SetupImageBrushTracking(imageBrush, uriString); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // This might fail. See `ReadLocalValueWithWorkaround` for an example (which | |
| // we now handle but there might be other cases). | |
| try { | |
| // `setter.Value()` returns font weight as an int. Using it with | |
| // `SetValue` results in the following error: 0x80004002 (No such | |
| // interface supported). Box it as `Windows.UI.Text.FontWeight` as a | |
| // workaround. | |
| if(property == Controls::TextBlock::FontWeightProperty() || property == Controls::Control::FontWeightProperty()) { | |
| std::optional<int> valueInt = value.try_as<int>(); | |
| if(valueInt && *valueInt >= std::numeric_limits<uint16_t>::min() && | |
| *valueInt <= std::numeric_limits<uint16_t>::max()) { | |
| value = winrt::box_value(winrt::Windows::UI::Text::FontWeight{ static_cast<uint16_t>(*valueInt) }); | |
| } | |
| } | |
| elementDo.SetValue(property, value); | |
| } catch(winrt::hresult_error const& ex) { Wh_Log(L"Error %08X: %s", ex.code(), ex.message().c_str()); } | |
| } | |
| std::optional<PropertyOverrideValue> ParseNonXamlPropertyOverrideValue(std::wstring_view stringValue) { | |
| // Example: | |
| // <WindhawkBlur BlurAmount="10" TintColor="#FFFF0000"/> | |
| std::wstring_view substr = StrFmt::TrimStringView(stringValue); | |
| constexpr std::wstring_view kWindhawkBlurPrefix = L"<WindhawkBlur "sv; | |
| if(!substr.starts_with(kWindhawkBlurPrefix)) { return std::nullopt; } | |
| Wh_Log(L"%.*s", static_cast<int>(substr.length()), substr.data()); | |
| substr = substr.substr(std::size(kWindhawkBlurPrefix)); | |
| constexpr std::wstring_view kWindhawkBlurSuffix = L"/>"sv; | |
| if(!substr.ends_with(kWindhawkBlurSuffix)) { throw std::runtime_error("WindhawkBlur: Bad suffix"); } | |
| substr = substr.substr(0, substr.size() - std::size(kWindhawkBlurSuffix)); | |
| bool pendingTintColorThemeResource = false; | |
| std::wstring tintThemeResourceKey; | |
| winrt::Windows::UI::Color tint{}; | |
| float tintOpacity = std::numeric_limits<float>::quiet_NaN(); | |
| float blurAmount = 0; | |
| constexpr std::wstring_view kTintColorThemeResourcePrefix = L"TintColor=\"{ThemeResource"sv; | |
| constexpr std::wstring_view kTintColorThemeResourceSuffix = L"}\""sv; | |
| constexpr std::wstring_view kTintColorPrefix = L"TintColor=\"#"sv; | |
| constexpr std::wstring_view kTintOpacityPrefix = L"TintOpacity=\""sv; | |
| constexpr std::wstring_view kBlurAmountPrefix = L"BlurAmount=\""sv; | |
| for(const std::wstring_view prop : StrFmt::SplitStringView(substr, L" ")) { | |
| const std::wstring_view propSubstr = StrFmt::TrimStringView(prop); | |
| if(propSubstr.empty()) { continue; } | |
| Wh_Log(L" %.*s", static_cast<int>(propSubstr.length()), propSubstr.data()); | |
| if(pendingTintColorThemeResource) { | |
| if(!propSubstr.ends_with(kTintColorThemeResourceSuffix)) { | |
| throw std::runtime_error("WindhawkBlur: Invalid TintColor theme resource syntax"); | |
| } | |
| pendingTintColorThemeResource = false; | |
| tintThemeResourceKey = propSubstr.substr(0, propSubstr.size() - std::size(kTintColorThemeResourceSuffix)); | |
| continue; | |
| } | |
| if(propSubstr == kTintColorThemeResourcePrefix) { | |
| pendingTintColorThemeResource = true; | |
| continue; | |
| } | |
| if(propSubstr.starts_with(kTintColorPrefix) && propSubstr.back() == L'\"') { | |
| std::wstring_view valStr = | |
| propSubstr.substr(std::size(kTintColorPrefix), propSubstr.size() - std::size(kTintColorPrefix) - 1); | |
| bool hasAlpha; | |
| switch(valStr.size()) { | |
| case 6: | |
| hasAlpha = false; | |
| break; | |
| case 8: | |
| hasAlpha = true; | |
| break; | |
| default: | |
| throw std::runtime_error("WindhawkBlur: Unsupported TintColor value"); | |
| } | |
| unsigned long valNum = std::stoul(std::wstring(valStr), nullptr, 16); | |
| uint8_t a = hasAlpha ? HIBYTE(HIWORD(valNum)) : 255; | |
| uint8_t r = LOBYTE(HIWORD(valNum)); | |
| uint8_t g = HIBYTE(LOWORD(valNum)); | |
| uint8_t b = LOBYTE(LOWORD(valNum)); | |
| tint = { a, r, g, b }; | |
| continue; | |
| } | |
| if(propSubstr.starts_with(kTintOpacityPrefix) && propSubstr.back() == L'\"') { | |
| std::wstring_view valStr = | |
| propSubstr.substr(std::size(kTintOpacityPrefix), propSubstr.size() - std::size(kTintOpacityPrefix) - 1); | |
| tintOpacity = std::stof(std::wstring(valStr)); | |
| continue; | |
| } | |
| if(propSubstr.starts_with(kBlurAmountPrefix) && propSubstr.back() == L'\"') { | |
| std::wstring_view valStr = | |
| propSubstr.substr(std::size(kBlurAmountPrefix), propSubstr.size() - std::size(kBlurAmountPrefix) - 1); | |
| blurAmount = std::stof(std::wstring(valStr)); | |
| continue; | |
| } | |
| throw std::runtime_error("WindhawkBlur: Bad property"); | |
| } | |
| if(pendingTintColorThemeResource) { throw std::runtime_error("WindhawkBlur: Unterminated TintColor theme resource"); } | |
| if(!isnan(tintOpacity)) { | |
| if(tintOpacity < 0.0f) { | |
| tintOpacity = 0.0f; | |
| } else if(tintOpacity > 1.0f) { | |
| tintOpacity = 1.0f; | |
| } | |
| tint.A = static_cast<uint8_t>(tintOpacity * 255.0f); | |
| } | |
| return XamlBlurBrushParams{ | |
| .blurAmount = blurAmount, | |
| .tint = tint, | |
| .tintOpacity = !isnan(tintOpacity) ? std::optional(tint.A) : std::nullopt, | |
| .tintThemeResourceKey = std::move(tintThemeResourceKey), | |
| }; | |
| } | |
| Style GetStyleFromXamlSetters(const std::wstring_view type, const std::wstring_view xamlStyleSetters) { | |
| std::wstring xaml = LR"(<ResourceDictionary | |
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
| xmlns:muxc="using:Microsoft.UI.Xaml.Controls")"; | |
| if(size_t pos = type.rfind('.'); pos != type.npos) { | |
| std::wstring_view typeNamespace = std::wstring_view(type).substr(0, pos); | |
| std::wstring_view typeName = std::wstring_view(type).substr(pos + 1); | |
| xaml += L"\n xmlns:windhawkstyler=\"using:"; | |
| xaml += StrFmt::EscapeXmlAttribute(typeNamespace); | |
| xaml += L"\">\n" | |
| L" <Style TargetType=\"windhawkstyler:"; | |
| xaml += StrFmt::EscapeXmlAttribute(typeName); | |
| xaml += L"\">\n"; | |
| } else { | |
| xaml += L">\n" | |
| L" <Style TargetType=\""; | |
| xaml += StrFmt::EscapeXmlAttribute(type); | |
| xaml += L"\">\n"; | |
| } | |
| xaml += xamlStyleSetters; | |
| xaml += L" </Style>\n" | |
| L"</ResourceDictionary>"; | |
| // Wh_Log(L"======================================== XAML:"); | |
| // std::wstringstream ss(xaml); | |
| // std::wstring line; | |
| // while(std::getline(ss, line, L'\n')) { | |
| // Wh_Log(L"%s", line.c_str()); | |
| // } | |
| // Wh_Log(L"========================================"); | |
| ResourceDictionary resourceDictionary = Markup::XamlReader::Load(xaml).as<ResourceDictionary>(); | |
| auto [styleKey, styleInspectable] = resourceDictionary.First().Current(); | |
| return styleInspectable.as<Style>(); | |
| } | |
| Style GetStyleFromXamlSettersWithFallbackType(const std::wstring_view type, | |
| const std::wstring_view fallbackType, | |
| const std::wstring_view xamlStyleSetters) { | |
| try { | |
| return GetStyleFromXamlSetters(type, xamlStyleSetters); | |
| } catch(winrt::hresult_error const& ex) { | |
| constexpr HRESULT kStowedException = 0x802B000A; | |
| if(ex.code() != kStowedException || fallbackType.empty() || fallbackType == type) { throw; } | |
| // For some types such as JumpViewUI.JumpListListViewItem, the following | |
| // error is returned: | |
| // | |
| // Error 802B000A: Failed to create a 'System.Type' from the text | |
| // 'windhawkstyler:JumpListListViewItem'. [Line: 8 Position: 12] | |
| // | |
| // Retry with a fallback type, which will allow to at least use the | |
| // basic properties. | |
| Wh_Log(L"Retrying with fallback type type due to error %08X: %s", ex.code(), ex.message().c_str()); | |
| return GetStyleFromXamlSetters(fallbackType, xamlStyleSetters); | |
| } | |
| } | |
| const PropertyOverrides& GetResolvedPropertyOverrides(const std::wstring_view type, | |
| const std::wstring_view fallbackType, | |
| PropertyOverridesMaybeUnresolved* propertyOverridesMaybeUnresolved) { | |
| if(const PropertyOverrides* resolved = std::get_if<PropertyOverrides>(propertyOverridesMaybeUnresolved)) { | |
| return *resolved; | |
| } | |
| PropertyOverrides propertyOverrides; | |
| try { | |
| const PropertyOverridesUnresolved& styleRules = | |
| std::get<PropertyOverridesUnresolved>(*propertyOverridesMaybeUnresolved); | |
| if(!styleRules.empty()) { | |
| std::wstring xaml; | |
| xaml.reserve(512); | |
| std::vector<std::optional<PropertyOverrideValue>> propertyOverrideValues; | |
| propertyOverrideValues.reserve(styleRules.size()); | |
| for(const StyleRule& rule : styleRules) { | |
| propertyOverrideValues.push_back( | |
| // Allow to use WindhawkBlur without ":=" for compatibility, | |
| // as it was always allowed in v1.5. | |
| true // rule.isXamlValue | |
| ? ParseNonXamlPropertyOverrideValue(rule.value) | |
| : std::nullopt); | |
| xaml += L" <Setter Property=\""; | |
| xaml += StrFmt::EscapeXmlAttribute(rule.name); | |
| xaml += L"\""; | |
| if(propertyOverrideValues.back() || (rule.isXamlValue && rule.value.empty())) { | |
| xaml += L" Value=\"{x:Null}\" />\n"; | |
| } else if(!rule.isXamlValue) { | |
| xaml += L" Value=\""; | |
| xaml += StrFmt::EscapeXmlAttribute(rule.value); | |
| xaml += L"\" />\n"; | |
| } else { | |
| xaml += L">\n" | |
| L" <Setter.Value>\n"; | |
| xaml += rule.value; | |
| xaml += L"\n" | |
| L" </Setter.Value>\n" | |
| L" </Setter>\n"; | |
| } | |
| } | |
| Style style = GetStyleFromXamlSettersWithFallbackType(type, fallbackType, xaml); | |
| uint32_t i = 0; | |
| for(const StyleRule& rule : styleRules) { | |
| const Setter setter = style.Setters().GetAt(i).as<Setter>(); | |
| propertyOverrides[setter.Property()][rule.visualState] = propertyOverrideValues[i].value_or( | |
| rule.isXamlValue && rule.value.empty() ? DependencyProperty::UnsetValue() : setter.Value()); | |
| i++; | |
| } | |
| } | |
| if (propertyOverrides.size() > 0) { | |
| Wh_Log(L"%.*s: %zu override styles", static_cast<int>(type.length()), type.data(), propertyOverrides.size()); | |
| } | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error %08X: %s", ex.code(), ex.message().c_str()); | |
| } catch(std::exception const& ex) { Wh_Log(L"Error: %S", ex.what()); } | |
| *propertyOverridesMaybeUnresolved = std::move(propertyOverrides); | |
| return std::get<PropertyOverrides>(*propertyOverridesMaybeUnresolved); | |
| } | |
| const PropertyValues& GetResolvedPropertyValues(const std::wstring_view type, | |
| const std::wstring_view fallbackType, | |
| PropertyValuesMaybeUnresolved* propertyValuesMaybeUnresolved) { | |
| if(const PropertyValues* resolved = std::get_if<PropertyValues>(propertyValuesMaybeUnresolved)) { return *resolved; } | |
| PropertyValues propertyValues; | |
| try { | |
| const PropertyValuesUnresolved& propertyValuesStr = | |
| std::get<PropertyValuesUnresolved>(*propertyValuesMaybeUnresolved); | |
| if(!propertyValuesStr.empty()) { | |
| std::wstring xaml; | |
| for(const PropertyValueUnresolved& pvu : propertyValuesStr) { | |
| xaml += L" <Setter Property=\""; | |
| xaml += StrFmt::EscapeXmlAttribute(pvu.key); | |
| xaml += L"\" Value=\""; | |
| xaml += StrFmt::EscapeXmlAttribute(pvu.value); | |
| xaml += L"\" />\n"; | |
| } | |
| Style style = GetStyleFromXamlSettersWithFallbackType(type, fallbackType, xaml); | |
| for(size_t i = 0; i < propertyValuesStr.size(); i++) { | |
| const Setter setter = style.Setters().GetAt(i).as<Setter>(); | |
| propertyValues.push_back({ | |
| setter.Property(), | |
| setter.Value(), | |
| propertyValuesStr[i].matchMode, | |
| propertyValuesStr[i].isDynamic, | |
| propertyValuesStr[i].key, | |
| }); | |
| } | |
| } | |
| if (propertyValues.size() > 0) { | |
| Wh_Log(L"%.*s: %zu matcher styles", static_cast<int>(type.length()), type.data(), propertyValues.size()); | |
| } | |
| } catch(winrt::hresult_error const& ex) { Wh_Log(L"Error %08X: %s", ex.code(), ex.message().c_str()); | |
| } catch(std::exception const& ex) { Wh_Log(L"Error: %S", ex.what()); } | |
| *propertyValuesMaybeUnresolved = std::move(propertyValues); | |
| return std::get<PropertyValues>(*propertyValuesMaybeUnresolved); | |
| } | |
| // https://stackoverflow.com/a/12835139 | |
| VisualStateGroup GetVisualStateGroup(FrameworkElement element, std::wstring_view visualStateGroupName) { | |
| winrt::hstring cname = winrt::get_class_name(element); | |
| // The TaskListButtonPanel child element of the search box (with "Icon and | |
| // label" configuration) returns a list of size 1, but accessing the first | |
| // item leads to a null dereference crash. Skip this element. | |
| if(cname == L"Taskbar.TaskListButtonPanel" || cname == L"SearchUx.SearchUI.SearchButtonRootGrid") { | |
| FrameworkElement parent = Media::VisualTreeHelper::GetParent(element).try_as<FrameworkElement>(); | |
| if(parent) { | |
| winrt::hstring pcname = winrt::get_class_name(parent); | |
| if(pcname == L"Taskbar.SearchBoxLaunchListButton" || pcname == L"SearchUx.SearchUI.SearchPillButton") { | |
| return nullptr; | |
| } | |
| } | |
| } | |
| wf::Collections::IVector<VisualStateGroup> list = VisualStateManager::GetVisualStateGroups(element); | |
| for(const VisualStateGroup& v : list) { | |
| if(v.Name() == visualStateGroupName) { return v; } | |
| } | |
| return nullptr; | |
| } | |
| // Forward declaration for recursive use. | |
| bool HasDescendantMatchingChain(DependencyObject node, DependencyObject originalRoot, SelectorChain& chain); | |
| static bool CheckIfCanEnumToIntComparison(const wf::IInspectable value, const PropertyValueResolved& propertyValue, const std::wstring_view actClsName, const std::wstring_view expClsName) { | |
| constexpr std::wstring_view kRefPrefix = L"Windows.Foundation.IReference`1<"; | |
| if (actClsName.starts_with(kRefPrefix) && expClsName.starts_with(kRefPrefix)) { | |
| try { | |
| winrt::unbox_value<int32_t>(value); | |
| try { | |
| winrt::unbox_value<int32_t>(propertyValue.value); | |
| return true; | |
| } catch(winrt::hresult_error const& ex) { Wh_Log(L"Not convertible to int32 Error <%s>: %08X: %s", expClsName.data(), ex.code(), ex.message().c_str()); | |
| } catch(std::exception const& ex) { Wh_Log(L"Not convertible to int32 Error <%s>: %S", expClsName.data(), ex.what()); } | |
| } catch(winrt::hresult_error const& ex) { Wh_Log(L"Not convertible to int32 Error <%s>: %08X: %s", actClsName.data(), ex.code(), ex.message().c_str()); | |
| } catch(std::exception const& ex) { Wh_Log(L"Not convertible to int32 Error <%s>: %S", actClsName.data(), ex.what()); } | |
| Wh_Log(L"Different property class: %s vs. %s", actClsName.data(), expClsName.data()); | |
| } | |
| return false; | |
| } | |
| bool TestElementMatcher(FrameworkElement element, | |
| ElementMatcher& matcher, | |
| VisualStateGroup* visualStateGroup, | |
| PCWSTR fallbackClassName, | |
| const winrt::hstring* cachedClassName = nullptr) { | |
| if(!matcher.type->empty()) { | |
| const winrt::hstring& className = cachedClassName ? *cachedClassName : winrt::get_class_name(element); | |
| if(*matcher.type != className && (!fallbackClassName || *matcher.type != fallbackClassName)) { return false; } | |
| } | |
| if(!matcher.name.empty() && matcher.name != element.Name()) { return false; } | |
| const wchar_t* name = matcher.name.empty() ? element.Name().c_str() : matcher.name.c_str(); | |
| if(matcher.oneBasedIndex) { | |
| DependencyObject parent = Media::VisualTreeHelper::GetParent(element); | |
| if(!parent) { return false; } | |
| int index = matcher.oneBasedIndex - 1; | |
| if(index < 0) { | |
| return false; | |
| } else if (index >= Media::VisualTreeHelper::GetChildrenCount(parent)) { | |
| return false; | |
| } else if (Media::VisualTreeHelper::GetChild(parent, index) != element) { | |
| return false; | |
| } | |
| } | |
| DependencyObject elementDo = element.as<DependencyObject>(); | |
| std::vector<PropertyValueResolved> resolved = GetResolvedPropertyValues( | |
| *matcher.type, fallbackClassName ? fallbackClassName : winrt::name_of<FrameworkElement>(), | |
| &matcher.propertyValues); | |
| // size_t matchCount = 0; | |
| // size_t unknownCount = 0; | |
| for(const PropertyValueResolved& propertyValue : resolved) { | |
| // Dynamic properties (@Prop) use GetValue to read the actual/computed value; | |
| // static properties use ReadLocalValue which only reads explicitly set values. | |
| const wf::IInspectable value = Helper::ReadLocalValueWithWorkaround(elementDo, propertyValue.property, propertyValue.isDynamic); | |
| if(!value) { | |
| Wh_Log(L"Null property value"); | |
| // unknownCount++; | |
| return false; | |
| // continue; | |
| } | |
| const auto mode = propertyValue.matchMode; | |
| const auto key = propertyValue.key; | |
| const winrt::hstring actClsName = winrt::get_class_name(value); | |
| const winrt::hstring expClsName = winrt::get_class_name(propertyValue.value); | |
| // WinRT enums are backed by Int32. When one side is an enum and the other | |
| // is Int32, treat both as Int32 for comparison via IPropertyValue. | |
| if(actClsName == L"Windows.Foundation.IReference`1<Int32>" || (actClsName != expClsName && CheckIfCanEnumToIntComparison(value, propertyValue, actClsName, expClsName))) { | |
| int32_t actual; | |
| int32_t expected; | |
| try { | |
| actual = winrt::unbox_value<int32_t>(value); | |
| expected = winrt::unbox_value<int32_t>(propertyValue.value); | |
| } catch(std::exception const& ex) { Wh_Log(L"%s#%s[%s<%s>]: Error unboxing to int32: %S", matcher.type->c_str(), name, key.c_str(), actClsName.c_str(), ex.what()); | |
| return false; | |
| } | |
| bool matched = false; | |
| switch(mode) { | |
| case AttrMatchMode::Exact: matched = (actual == expected); break; | |
| case AttrMatchMode::NotEqual: matched = (actual != expected); break; | |
| case AttrMatchMode::GreaterOrEqual: matched = (actual >= expected); break; | |
| case AttrMatchMode::LessOrEqual: matched = (actual <= expected); break; | |
| case AttrMatchMode::StartsWith: | |
| case AttrMatchMode::EndsWith: | |
| case AttrMatchMode::Contains: | |
| Wh_Log(L"%s#%s[%s<%s>]: Partial matching (^=, $=, *=) not supported for integer properties", matcher.type->c_str(), name, key.c_str(), actClsName.c_str()); | |
| return false; | |
| } | |
| if(matched) { | |
| // Wh_Log(L"%s#%s[%s<%s>]: matched = %d %s %d", matcher.type->c_str(), name, key.c_str(), actClsName.c_str(), actual, StrFmt::toString(mode).c_str(), expected); | |
| continue; | |
| } | |
| return false; | |
| } else if(actClsName == L"Windows.Foundation.IReference`1<String>") { | |
| std::wstring_view actual ; | |
| std::wstring_view expected; | |
| try { | |
| actual = StrFmt::TrimStringView(winrt::unbox_value<winrt::hstring>(value)); | |
| expected = StrFmt::TrimStringView(winrt::unbox_value<winrt::hstring>(propertyValue.value)); | |
| } catch(std::exception const& ex) { Wh_Log(L"%s#%s[%s<%s>]: Error unboxing string: %S", matcher.type->c_str(), name, key.c_str(), actClsName.c_str(), ex.what()); | |
| return false; | |
| } | |
| bool matched = false; | |
| switch(mode) { | |
| case AttrMatchMode::Exact: matched = (actual == expected); break; | |
| case AttrMatchMode::NotEqual: matched = (actual != expected); break; | |
| case AttrMatchMode::StartsWith: matched = actual.starts_with(expected); break; | |
| case AttrMatchMode::EndsWith: matched = actual.ends_with(expected); break; | |
| case AttrMatchMode::Contains: matched = (actual.find(expected) != std::wstring_view::npos); break; | |
| case AttrMatchMode::GreaterOrEqual: matched = (actual >= expected); break; | |
| case AttrMatchMode::LessOrEqual: matched = (actual <= expected); break; | |
| } | |
| if(matched) { | |
| // Wh_Log(L"%s#%s[%s<%s>]: matched = '%s' %s '%s'", matcher.type->c_str(), name, key.c_str(), actClsName.c_str(), actual.data(), StrFmt::toString(mode).c_str(), expected.data()); | |
| continue; | |
| } | |
| return false; | |
| } else if(actClsName == L"Windows.Foundation.IReference`1<Double>") { | |
| double actual ; | |
| double expected; | |
| try { | |
| actual = winrt::unbox_value<double>(value); | |
| expected = winrt::unbox_value<double>(propertyValue.value); | |
| } catch(std::exception const& ex) { Wh_Log(L"%s#%s[%s<%s>]: Error unboxing double: %S", matcher.type->c_str(), name, key.c_str(), actClsName.c_str(), ex.what()); | |
| return false; | |
| } | |
| bool matched = false; | |
| switch(mode) { | |
| case AttrMatchMode::Exact: matched = (actual == expected); break; | |
| case AttrMatchMode::NotEqual: matched = (actual != expected); break; | |
| case AttrMatchMode::GreaterOrEqual: matched = (actual >= expected); break; | |
| case AttrMatchMode::LessOrEqual: matched = (actual <= expected); break; | |
| case AttrMatchMode::StartsWith: matched = static_cast<int64_t>(actual) == static_cast<int64_t>(expected); break; // Allow integer matching with startsWith for convenience, e.g. 1.0 startsWith 1 | |
| case AttrMatchMode::EndsWith: | |
| case AttrMatchMode::Contains: | |
| Wh_Log(L"%s#%s[%s<%s>]: Partial matching ($=, *=) not supported for double properties", matcher.type->c_str(), name, key.c_str(), actClsName.c_str()); | |
| return false; | |
| } | |
| if(matched) { | |
| // Wh_Log(L"%s#%s[%s<%s>]: matched = %f %s %f", matcher.type->c_str(), name, key.c_str(), actClsName.c_str(), actual, StrFmt::toString(mode).c_str(), expected); | |
| continue; | |
| } | |
| return false; | |
| } else if(actClsName == L"Windows.Foundation.IReference`1<Boolean>") { | |
| bool actual ; | |
| bool expected; | |
| try { | |
| actual = winrt::unbox_value<bool>(value); | |
| expected = winrt::unbox_value<bool>(propertyValue.value); | |
| } catch(std::exception const& ex) { Wh_Log(L"%s#%s[%s<%s>]: Error unboxing boolean: %S", matcher.type->c_str(), name, key.c_str(), actClsName.c_str(), ex.what()); | |
| return false; | |
| } | |
| bool matched = (mode == AttrMatchMode::NotEqual) ? (actual != expected) : (actual == expected); | |
| if(matched) { | |
| // Wh_Log(L"%s#%s[%s<%s>]: matched = %s %s %s", matcher.type->c_str(), name, key.c_str(), actClsName.c_str(), actual ? L"true" : L"false", StrFmt::toString(mode).c_str(), expected ? L"true" : L"false"); | |
| continue; | |
| } | |
| return false; | |
| } | |
| Wh_Log(L"%s#%s[%s<%s>]: Unsupported property class: %s", matcher.type->c_str(), name, key.c_str(), actClsName.c_str(), actClsName.c_str()); | |
| return false; | |
| } | |
| if(matcher.visualStateGroupName && visualStateGroup) { | |
| *visualStateGroup = GetVisualStateGroup(element, *matcher.visualStateGroupName); | |
| } | |
| // Check :has() conditions — element must have a descendant matching each chain. | |
| if (!matcher.hasSelectors.empty()) { | |
| DependencyObject elementDO = element.as<DependencyObject>(); | |
| bool matched = true; | |
| SelectorChain* clause = nullptr; | |
| for(SelectorChain& hasChain : matcher.hasSelectors) { | |
| clause = &hasChain; | |
| if(!HasDescendantMatchingChain(elementDO, elementDO, hasChain)) { | |
| matched = false; | |
| break; | |
| } | |
| } | |
| Wh_Log(L"%s HasClausesMatch: %s#%s:has(%s#%s)", matched ? L"true" : L"false", matcher.type->c_str(), name, matcher.type->c_str(), clause->toString().c_str()); | |
| if (!matched) { | |
| return false; | |
| } | |
| } | |
| if (!matcher.notHasSelectors.empty()) { | |
| DependencyObject elementDO = element.as<DependencyObject>(); | |
| bool matched = true; | |
| SelectorChain* clause = nullptr; | |
| for(SelectorChain& notHasChain : matcher.notHasSelectors) { | |
| clause = ¬HasChain; | |
| if(HasDescendantMatchingChain(elementDO, elementDO, notHasChain)) { | |
| matched = false; | |
| break; | |
| } | |
| } | |
| Wh_Log(L"%s NotHasClausesMatch: %s#%s:notHas(%s#%s)", matched ? L"true" : L"false", matcher.type->c_str(), name, matcher.type->c_str(), clause->toString().c_str()); | |
| if (!matched) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| bool HasDescendantMatchingChain(DependencyObject node, DependencyObject originalRoot, SelectorChain& chain) { | |
| // Walk the visual tree under node looking for a descendant matching the | |
| // chain's targetMatcher. For each candidate, verify the ancestor matchers | |
| // chain (same logic as FindElementPropertyOverrides parent matching). | |
| // originalRoot is the element with the :has() — ancestor walks stop there. | |
| int childCount = Media::VisualTreeHelper::GetChildrenCount(node); | |
| for(int i = 0; i < childCount; i++) { | |
| DependencyObject child = Media::VisualTreeHelper::GetChild(node, i); | |
| if(FrameworkElement fe = child.try_as<FrameworkElement>()) { | |
| winrt::hstring feClassName = winrt::get_class_name(fe); | |
| // Log each candidate we examine so we can see the tree structure | |
| // if(*chain.targetMatcher->type == feClassName) { | |
| // // Wh_Log(L":has() candidate: %s#%s — type matches target %s, testing properties...", feClassName.c_str(), fe.Name().c_str(), chain.targetMatcher->type->c_str()); | |
| // } | |
| if(TestElementMatcher(fe, chain.targetMatcher, nullptr, nullptr)) { | |
| // Wh_Log(L":has() target MATCHED: %s#%s", feClassName.c_str(), fe.Name().c_str()); | |
| // If there are no ancestor matchers, we have a match. | |
| if(chain.ancestorMatchers.empty()) { | |
| // Wh_Log(L":has() no ancestor matchers needed, chain PASSED"); | |
| return true; | |
| } | |
| // Wh_Log(L":has() checking %zu ancestor matcher(s)...", chain.ancestorMatchers.size()); | |
| // Verify ancestor chain from this element up toward originalRoot. | |
| FrameworkElement parentIter = fe; | |
| bool ancestorMatchOK = true; | |
| for(ElementMatcher& ancestorMatcher : chain.ancestorMatchers) { | |
| // Wh_Log(L":has() ancestor check: looking for %s (isDescendant=%d)", ancestorMatcher.type->c_str(), (int)ancestorMatcher.isDescendant); | |
| if(ancestorMatcher.isDescendant) { | |
| // Descendant combinator: walk up until we find a match or hit originalRoot. | |
| bool found = false; | |
| FrameworkElement ancestor = Media::VisualTreeHelper::GetParent(parentIter).try_as<FrameworkElement>(); | |
| while(ancestor) { | |
| winrt::hstring ancestorClass = winrt::get_class_name(ancestor); | |
| // Stop searching if we've reached the :has() element. | |
| if(ancestor.as<DependencyObject>() == originalRoot) { | |
| Wh_Log(L":has() ancestor walk hit originalRoot (%s), stopping", ancestorClass.c_str()); | |
| break; | |
| } | |
| // Wh_Log(L":has() ancestor walk: testing %s#%s", ancestorClass.c_str(), ancestor.Name().c_str()); | |
| if(TestElementMatcher(ancestor, ancestorMatcher, nullptr, nullptr)) { | |
| Wh_Log(L":has() ancestor MATCHED: %s#%s", ancestorClass.c_str(), ancestor.Name().c_str()); | |
| parentIter = ancestor; | |
| found = true; | |
| break; | |
| } | |
| ancestor = Media::VisualTreeHelper::GetParent(ancestor).try_as<FrameworkElement>(); | |
| } | |
| if(!found) { | |
| ancestorMatchOK = false; | |
| break; | |
| } | |
| } else { | |
| // Direct child combinator (>): must be the immediate parent. | |
| FrameworkElement parent = Media::VisualTreeHelper::GetParent(parentIter).try_as<FrameworkElement>(); | |
| if(!parent || parent.as<DependencyObject>() == originalRoot) { | |
| ancestorMatchOK = false; | |
| break; | |
| } | |
| if(!TestElementMatcher(parent, ancestorMatcher, nullptr, nullptr)) { | |
| ancestorMatchOK = false; | |
| break; | |
| } | |
| parentIter = parent; | |
| } | |
| } | |
| if(ancestorMatchOK) { return true; } | |
| } | |
| } | |
| // Recurse into children regardless of whether this child matched. | |
| if(HasDescendantMatchingChain(child, originalRoot, chain)) { return true; } | |
| } | |
| return false; | |
| } | |
| std::unordered_map<VisualStateGroup, PropertyOverrides> | |
| FindElementPropertyOverrides(FrameworkElement element, PCWSTR fallbackClassName) { | |
| std::unordered_map<VisualStateGroup, PropertyOverrides> overrides; | |
| std::unordered_set<DependencyProperty> propertiesAdded; | |
| const winrt::hstring elementClassName = winrt::get_class_name(element); | |
| for(std::vector<ElementCustomizationRules>::reverse_iterator it = g_elementsCustomizationRules.rbegin(); | |
| it != g_elementsCustomizationRules.rend(); ++it) { | |
| ElementCustomizationRules& override = *it; | |
| VisualStateGroup visualStateGroup = nullptr; | |
| if(!TestElementMatcher(element, override.elementMatcher, &visualStateGroup, fallbackClassName, &elementClassName)) { | |
| continue; | |
| } | |
| FrameworkElement parentElementIter = element; | |
| bool parentElementMatchFailed = false; | |
| for(ElementMatcher& matcher : override.parentElementMatchers) { | |
| if(matcher.isDescendant) { | |
| // Descendant combinator (space): walk up the tree until we find a match. | |
| bool found = false; | |
| FrameworkElement ancestor = Media::VisualTreeHelper::GetParent(parentElementIter).try_as<FrameworkElement>(); | |
| while(ancestor) { | |
| if(TestElementMatcher(ancestor, matcher, &visualStateGroup, nullptr)) { | |
| parentElementIter = ancestor; | |
| found = true; | |
| break; | |
| } | |
| ancestor = Media::VisualTreeHelper::GetParent(ancestor).try_as<FrameworkElement>(); | |
| } | |
| if(!found) { | |
| parentElementMatchFailed = true; | |
| break; | |
| } | |
| } else { | |
| // Child combinator (>): must be the direct parent. | |
| parentElementIter = Media::VisualTreeHelper::GetParent(parentElementIter).try_as<FrameworkElement>(); | |
| if(!parentElementIter) { | |
| parentElementMatchFailed = true; | |
| break; | |
| } | |
| if(!TestElementMatcher(parentElementIter, matcher, &visualStateGroup, nullptr)) { | |
| parentElementMatchFailed = true; | |
| break; | |
| } | |
| } | |
| } | |
| if(parentElementMatchFailed) { continue; } | |
| PropertyOverrides& overridesForVisualStateGroup = overrides[visualStateGroup]; | |
| for(const auto& [property, valuesPerVisualState] : GetResolvedPropertyOverrides( | |
| *override.elementMatcher.type, fallbackClassName ? fallbackClassName : winrt::name_of<FrameworkElement>(), | |
| &override.propertyOverrides)) { | |
| bool propertyInserted = propertiesAdded.insert(property).second; | |
| if(!propertyInserted) { continue; } | |
| std::unordered_map<std::wstring, PropertyOverrideValue>& propertyOverrides = overridesForVisualStateGroup[property]; | |
| for(const auto& [visualState, value] : valuesPerVisualState) { | |
| propertyOverrides.insert({ visualState, value }); | |
| } | |
| } | |
| } | |
| std::erase_if(overrides, [](const auto& item) { | |
| auto const& [key, value] = item; | |
| return value.empty(); | |
| }); | |
| return overrides; | |
| } | |
| void ApplyCustomizationsForVisualStateGroup( | |
| FrameworkElement element, | |
| VisualStateGroup visualStateGroup, | |
| PropertyOverrides propertyOverrides, | |
| ElementCustomizationStateForVisualStateGroup* elementCustomizationStateForVisualStateGroup) { | |
| DependencyObject elementDo = element.as<DependencyObject>(); | |
| VisualState currentVisualState(visualStateGroup ? visualStateGroup.CurrentState() : nullptr); | |
| std::wstring currentVisualStateName(currentVisualState ? currentVisualState.Name() : L""); | |
| for(const auto& [property, valuesPerVisualState] : propertyOverrides) { | |
| const auto [propertyCustomizationStatesIt, inserted] = | |
| elementCustomizationStateForVisualStateGroup->propertyCustomizationStates.insert({ property, {} }); | |
| if(!inserted) { continue; } | |
| ElementPropertyCustomizationState& propertyCustomizationState = propertyCustomizationStatesIt->second; | |
| std::unordered_map<std::wstring, PropertyOverrideValue>::const_iterator it = | |
| valuesPerVisualState.find(currentVisualStateName); | |
| if(it == valuesPerVisualState.end() && !currentVisualStateName.empty()) { it = valuesPerVisualState.find(L""); } | |
| if(it != valuesPerVisualState.end()) { | |
| propertyCustomizationState.originalValue = Helper::ReadLocalValueWithWorkaround(element, property); | |
| propertyCustomizationState.customValue = it->second; | |
| SetOrClearValue(element, property, it->second, | |
| /*initialApply=*/true); | |
| } | |
| propertyCustomizationState.propertyChangedToken = elementDo.RegisterPropertyChangedCallback( | |
| property, [&propertyCustomizationState](DependencyObject sender, DependencyProperty property) { | |
| if(g_elementPropertyModifying) { return; } | |
| FrameworkElement element = sender.try_as<FrameworkElement>(); | |
| if(!element) { return; } | |
| if(!propertyCustomizationState.customValue) { return; } | |
| // Wh_Log(L"Re-applying style for %s", GetLocator(element).c_str()); | |
| wf::IInspectable localValue = Helper::ReadLocalValueWithWorkaround(element, property); | |
| if(wf::IInspectable* customValue = std::get_if<wf::IInspectable>(&*propertyCustomizationState.customValue)) { | |
| if(*customValue != localValue) { propertyCustomizationState.originalValue = localValue; } | |
| } | |
| g_elementPropertyModifying = true; | |
| SetOrClearValue(element, property, *propertyCustomizationState.customValue); | |
| g_elementPropertyModifying = false; | |
| }); | |
| } | |
| if(visualStateGroup) { | |
| winrt::weak_ref<FrameworkElement> elementWeakRef = element; | |
| elementCustomizationStateForVisualStateGroup->visualStateGroupCurrentStateChangedToken = | |
| visualStateGroup.CurrentStateChanged( | |
| [elementWeakRef, propertyOverrides = std::move(propertyOverrides), elementCustomizationStateForVisualStateGroup]( | |
| wf::IInspectable const& sender, VisualStateChangedEventArgs const& e | |
| ) { | |
| FrameworkElement element = elementWeakRef.get(); | |
| if(!element) { return; } | |
| // Wh_Log(L"Re-applying %d styles for %s", propertyOverrides.size(), GetLocator(element).c_str()); | |
| g_elementPropertyModifying = true; | |
| std::unordered_map<DependencyProperty, ElementPropertyCustomizationState>& propertyCustomizationStates = | |
| elementCustomizationStateForVisualStateGroup->propertyCustomizationStates; | |
| for(const auto& [property, valuesPerVisualState] : propertyOverrides) { | |
| ElementPropertyCustomizationState& propertyCustomizationState = propertyCustomizationStates.at(property); | |
| VisualState newState = e.NewState(); | |
| std::wstring newStateName = std::wstring{ newState ? newState.Name() : L"" }; | |
| std::unordered_map<std::wstring, PropertyOverrideValue>::const_iterator it = | |
| valuesPerVisualState.find(newStateName); | |
| if(it == valuesPerVisualState.end()) { | |
| it = valuesPerVisualState.find(L""); | |
| if(it != valuesPerVisualState.end()) { | |
| VisualState oldState = e.OldState(); | |
| std::wstring oldStateName = std::wstring{ oldState ? oldState.Name() : L"" }; | |
| if(!valuesPerVisualState.contains(oldStateName)) { continue; } | |
| } | |
| } | |
| if(it != valuesPerVisualState.end()) { | |
| if(!propertyCustomizationState.originalValue) { | |
| propertyCustomizationState.originalValue = Helper::ReadLocalValueWithWorkaround(element, property); | |
| } | |
| propertyCustomizationState.customValue = it->second; | |
| SetOrClearValue(element, property, it->second); | |
| } else { | |
| if(propertyCustomizationState.originalValue) { | |
| SetOrClearValue(element, property, *propertyCustomizationState.originalValue); | |
| propertyCustomizationState.originalValue.reset(); | |
| } | |
| propertyCustomizationState.customValue.reset(); | |
| } | |
| } | |
| g_elementPropertyModifying = false; | |
| }); | |
| } | |
| } | |
| void RestoreCustomizationsForVisualStateGroup( | |
| FrameworkElement element, | |
| std::optional<winrt::weak_ref<VisualStateGroup>> visualStateGroupOptionalWeakPtr, | |
| const ElementCustomizationStateForVisualStateGroup& elementCustomizationStateForVisualStateGroup) { | |
| if(element) { | |
| for(const auto& [property, state] : elementCustomizationStateForVisualStateGroup.propertyCustomizationStates) { | |
| element.UnregisterPropertyChangedCallback(property, state.propertyChangedToken); | |
| if(state.originalValue) { SetOrClearValue(element, property, *state.originalValue); } | |
| } | |
| } | |
| VisualStateGroup visualStateGroupIter = | |
| visualStateGroupOptionalWeakPtr ? visualStateGroupOptionalWeakPtr->get() : nullptr; | |
| if(visualStateGroupIter && elementCustomizationStateForVisualStateGroup.visualStateGroupCurrentStateChangedToken) { | |
| visualStateGroupIter.CurrentStateChanged( | |
| elementCustomizationStateForVisualStateGroup.visualStateGroupCurrentStateChangedToken); | |
| } | |
| } | |
| void ScheduleHasReevaluation() { | |
| if(!g_anyRuleUsesHas || g_hasReevalScheduled) { return; } | |
| g_hasReevalScheduled = true; | |
| if(auto dq = winrt::Windows::System::DispatcherQueue::GetForCurrentThread()) { | |
| dq.TryEnqueue([]() { ReevaluateHasSelectors(); }); | |
| } else { | |
| g_hasReevalScheduled = false; | |
| } | |
| } | |
| void ReevaluateHasSelectors() { | |
| g_hasReevalScheduled = false; | |
| for(auto& [handle, entry] : g_hasReevalElements) { | |
| FrameworkElement element = entry.element.get(); | |
| if(!element) { continue; } | |
| PCWSTR fallback = entry.fallbackClassName.empty() ? nullptr : entry.fallbackClassName.c_str(); | |
| std::unordered_map<VisualStateGroup, PropertyOverrides> overrides = | |
| FindElementPropertyOverrides(element, fallback); | |
| auto stateIt = g_elementsCustomizationState.find(handle); | |
| bool wasCustomized = (stateIt != g_elementsCustomizationState.end()); | |
| if(overrides.empty() && wasCustomized) { | |
| // :has() no longer matches — restore original values. | |
| ElementCustomizationState& state = stateIt->second; | |
| for(const auto& [vsgWeakPtr, vsgState] : state.perVisualStateGroup) { | |
| RestoreCustomizationsForVisualStateGroup(element, vsgWeakPtr, vsgState); | |
| } | |
| g_elementsCustomizationState.erase(stateIt); | |
| } else if(!overrides.empty()) { | |
| // Re-apply (ApplyCustomizations handles restore + re-apply internally). | |
| ApplyCustomizations(handle, element, fallback); | |
| } | |
| } | |
| } | |
| void ApplyCustomizations(InstanceHandle handle, FrameworkElement element, PCWSTR fallbackClassName) { | |
| // Track element for :has() re-evaluation. | |
| if(g_anyRuleUsesHas) { | |
| g_hasReevalElements.insert_or_assign(handle, HasReevalEntry{ | |
| winrt::make_weak(element), | |
| fallbackClassName ? std::wstring(fallbackClassName) : std::wstring() | |
| }); | |
| } | |
| std::unordered_map<VisualStateGroup, PropertyOverrides> overrides = | |
| FindElementPropertyOverrides(element, fallbackClassName); | |
| if(overrides.empty()) { return; } | |
| // Wh_Log(L"Applying %d styles for %s", overrides.size(), GetLocator(element).c_str()); | |
| ElementCustomizationState& elementCustomizationState = g_elementsCustomizationState[handle]; | |
| for(const auto& [visualStateGroupOptionalWeakPtrIter, stateIter] : elementCustomizationState.perVisualStateGroup) { | |
| RestoreCustomizationsForVisualStateGroup(element, visualStateGroupOptionalWeakPtrIter, stateIter); | |
| } | |
| elementCustomizationState.element = element; | |
| elementCustomizationState.perVisualStateGroup.clear(); | |
| for(auto& [visualStateGroup, overridesForVisualStateGroup] : overrides) { | |
| std::optional<winrt::weak_ref<VisualStateGroup>> visualStateGroupOptionalWeakPtr; | |
| if(visualStateGroup) { visualStateGroupOptionalWeakPtr = visualStateGroup; } | |
| elementCustomizationState.perVisualStateGroup.push_back({ visualStateGroupOptionalWeakPtr, {} }); | |
| ElementCustomizationStateForVisualStateGroup* elementCustomizationStateForVisualStateGroup = | |
| &elementCustomizationState.perVisualStateGroup.back().second; | |
| ApplyCustomizationsForVisualStateGroup(element, visualStateGroup, std::move(overridesForVisualStateGroup), | |
| elementCustomizationStateForVisualStateGroup); | |
| } | |
| } | |
| void CleanupCustomizations(InstanceHandle handle) { | |
| if(std::unordered_map<InstanceHandle, ElementCustomizationState>::iterator it = | |
| g_elementsCustomizationState.find(handle); | |
| it != g_elementsCustomizationState.end()) { | |
| ElementCustomizationState& elementCustomizationState = it->second; | |
| FrameworkElement element = elementCustomizationState.element.get(); | |
| for(const auto& [visualStateGroupOptionalWeakPtrIter, stateIter] : elementCustomizationState.perVisualStateGroup) { | |
| RestoreCustomizationsForVisualStateGroup(element, visualStateGroupOptionalWeakPtrIter, stateIter); | |
| } | |
| g_elementsCustomizationState.erase(it); | |
| } | |
| g_hasReevalElements.erase(handle); | |
| } | |
| using StyleConstant = std::pair<std::wstring, std::wstring>; | |
| struct StyleConstants { | |
| std::unordered_map<std::wstring, std::wstring> map; | |
| size_t maxKeyLen = 0; | |
| }; | |
| std::optional<StyleConstant> ParseStyleConstant(std::wstring_view constant) { | |
| // Skip if commented. | |
| if(constant.starts_with(L"//")) { return std::nullopt; } | |
| size_t eqPos = constant.find(L'='); | |
| if(eqPos == constant.npos) { | |
| Wh_Log(L"Skipping entry with no '=': %.*s", static_cast<int>(constant.length()), constant.data()); | |
| return std::nullopt; | |
| } | |
| std::wstring_view key = StrFmt::TrimStringView(constant.substr(0, eqPos)); | |
| std::wstring_view val = StrFmt::TrimStringView(constant.substr(eqPos + 1)); | |
| return StyleConstant{ std::wstring(key), std::wstring(val) }; | |
| } | |
| // Dead code — was buggy (param by value, wrong substr math) and all call sites are commented out. | |
| // Kept as reference. Do not call. | |
| // void applyStyleSubstitutions(StyleConstants result) { ... } | |
| StyleConstants LoadStyleConstants(const std::vector<PCWSTR>& themeStyleConstants) { | |
| // Collect raw constants; user settings (loaded second) override theme constants. | |
| std::vector<StyleConstant> raw; | |
| for(PCWSTR themeStyleConstant : themeStyleConstants) { | |
| if(std::optional<StyleConstant> parsed = ParseStyleConstant(themeStyleConstant)) { | |
| raw.push_back(std::move(*parsed)); | |
| } | |
| } | |
| for(int i = 0;; i++) { | |
| string_setting_unique_ptr constantSetting(Wh_GetStringSetting(L"styleConstants[%d]", i)); | |
| if(!*constantSetting.get()) { break; } | |
| if(std::optional<StyleConstant> parsed = ParseStyleConstant(constantSetting.get())) { | |
| raw.push_back(std::move(*parsed)); | |
| } | |
| } | |
| // Build map — later entries override earlier ones (user settings override theme). | |
| StyleConstants result; | |
| for(auto& [key, value] : raw) { | |
| result.maxKeyLen = std::max(result.maxKeyLen, key.size()); | |
| result.map[std::move(key)] = std::move(value); | |
| } | |
| return result; | |
| } | |
| std::wstring ApplyStyleConstants(std::wstring_view style, const StyleConstants& styleConstants) { | |
| if(styleConstants.map.empty()) { return std::wstring(style); } | |
| std::wstring result; | |
| result.reserve((style.length() + 63) & ~63); | |
| size_t lastPos = 0; | |
| size_t findPos; | |
| while((findPos = style.find('$', lastPos)) != style.npos) { | |
| result.append(style, lastPos, findPos - lastPos); | |
| size_t remaining = style.size() - (findPos + 1); | |
| size_t maxTry = std::min(styleConstants.maxKeyLen, remaining); | |
| bool found = false; | |
| // Allocate candidate once at max length, then shrink via resize (no reallocation). | |
| std::wstring candidate(style.substr(findPos + 1, maxTry)); | |
| // Try longest key first to match longest constant name. | |
| for(size_t tryLen = maxTry; tryLen > 0; --tryLen) { | |
| candidate.resize(tryLen); | |
| std::unordered_map<std::wstring, std::wstring>::const_iterator it = styleConstants.map.find(candidate); | |
| if(it != styleConstants.map.end()) { | |
| result.append(it->second); | |
| lastPos = findPos + 1 + tryLen; | |
| found = true; | |
| break; | |
| } | |
| } | |
| if(!found) { | |
| result += '$'; | |
| lastPos = findPos + 1; | |
| } | |
| } | |
| // Append the rest after last occurrence. | |
| result += style.substr(lastPos); | |
| return result; | |
| } | |
| StyleRule StyleRuleFromString(std::wstring_view str) { | |
| StyleRule result; | |
| size_t eqPos = str.find(L'='); | |
| if(eqPos == str.npos) { throw std::runtime_error("Bad style syntax, '=' is missing"); } | |
| std::wstring_view name = str.substr(0, eqPos); | |
| std::wstring_view value = str.substr(eqPos + 1); | |
| result.value = StrFmt::TrimStringView(value); | |
| if(name.size() > 0 && name.back() == L':') { | |
| result.isXamlValue = true; | |
| name = name.substr(0, name.size() - 1); | |
| } | |
| size_t atPos = name.find(L'@'); | |
| if(atPos != name.npos) { | |
| result.visualState = StrFmt::TrimStringView(name.substr(atPos + 1)); | |
| name = name.substr(0, atPos); | |
| } | |
| result.name = StrFmt::TrimStringView(name); | |
| if(result.name.empty()) { throw std::runtime_error("Bad style syntax, empty name"); } | |
| return result; | |
| } | |
| void InitElementCustomizationRules(ElementCustomizationRules* rule, PCWSTR target) { | |
| std::vector<TargetToken> tokens = TargetToken::Tokenize(target); | |
| if(tokens.empty()) { throw std::runtime_error("Empty target selector"); } | |
| bool first = true; | |
| bool hasVisualStateGroup = false; | |
| // Iterate right-to-left: rightmost token is the element itself, | |
| // tokens to its left are parent matchers. | |
| for(std::vector<TargetToken>::reverse_iterator i = tokens.rbegin(); i != tokens.rend(); ++i) { | |
| const TargetToken& token = *i; | |
| ElementMatcher matcher = ElementMatcher::FromString(token.text); | |
| matcher.type = Helper::AdjustTypeName(*matcher.type); | |
| if(matcher.visualStateGroupName) { | |
| if(hasVisualStateGroup) { throw std::runtime_error("Element type can't have more than one visual state group"); } | |
| hasVisualStateGroup = true; | |
| } | |
| if(first) { | |
| // The element itself — isDirectChild from the token to its left | |
| // will be stored on the first parent matcher, not here. | |
| rule->elementMatcher = std::move(matcher); | |
| first = false; | |
| } else { | |
| // This is a parent matcher. isDirectChild on the token ONE position | |
| // to the RIGHT tells us the relationship between this parent and | |
| // its child. But we stored isDirectChild on each token as "this token | |
| // is a direct child of the one to its left". So the token to the right | |
| // of this one carries the flag. | |
| std::vector<TargetToken>::reverse_iterator rightNeighbor = std::prev(i); // one step back toward the right | |
| matcher.isDescendant = !rightNeighbor->isDirectChild; | |
| rule->parentElementMatchers.push_back(std::move(matcher)); | |
| } | |
| } | |
| // // Log the final parsed rule structure | |
| // Wh_Log(L"[RULE] elementMatcher: type=%s name=%s hasSelectors=%zu", rule->elementMatcher.type->c_str(), | |
| // rule->elementMatcher.name.c_str(), rule->elementMatcher.hasSelectors.size()); | |
| // for(size_t pi = 0; pi < rule->parentElementMatchers.size(); pi++) { | |
| // const ElementMatcher& pm = rule->parentElementMatchers[pi]; | |
| // Wh_Log(L"[RULE] parentMatcher[%zu]: type=%s name=%s isDescendant=%d hasSelectors=%zu", pi, pm.type->c_str(), | |
| // pm.name.c_str(), (int)pm.isDescendant, pm.hasSelectors.size()); | |
| // for(size_t hi = 0; hi < pm.hasSelectors.size(); hi++) { | |
| // const SelectorChain& hc = pm.hasSelectors[hi]; | |
| // Wh_Log(L"[RULE] :has()[%zu]: target=%s, ancestors=%zu", hi, hc.targetMatcher.type->c_str(), | |
| // hc.ancestorMatchers.size()); | |
| // for(size_t ai = 0; ai < hc.ancestorMatchers.size(); ai++) { | |
| // Wh_Log(L"[RULE] ancestor[%zu]: type=%s isDescendant=%d", ai, hc.ancestorMatchers[ai].type->c_str(), | |
| // (int)hc.ancestorMatchers[ai].isDescendant); | |
| // } | |
| // } | |
| // } | |
| } | |
| void AddElementCustomizationRules(ElementCustomizationRules rule) { | |
| for(size_t i = 0; i < g_elementsCustomizationRules.size(); i++) { | |
| ElementCustomizationRules* other = &g_elementsCustomizationRules[i]; | |
| // Check if an existing matcher exists that points to the same thing | |
| if(other->Equals(rule)) { | |
| Wh_Log(L"Found existing ElementCustomizationRules %s", other->toString().c_str()); | |
| // If one is found, merge the new rules instead of adding | |
| PropertyOverridesUnresolved* existingOverrides = | |
| std::get_if<PropertyOverridesUnresolved>(&other->propertyOverrides); | |
| PropertyOverridesUnresolved* newOverrides = std::get_if<PropertyOverridesUnresolved>(&rule.propertyOverrides); | |
| if(!existingOverrides || !newOverrides) { | |
| Wh_Log(L"Cannot merge: property overrides already resolved"); | |
| continue; | |
| } | |
| // Create a map to track existing rules by name+visualState for easy lookup | |
| std::unordered_map<std::wstring, size_t> existingRuleMap; | |
| for(size_t j = 0; j < existingOverrides->size(); j++) { | |
| const StyleRule& existingRule = (*existingOverrides)[j]; | |
| std::wstring key = existingRule.name + L"@" + existingRule.visualState; | |
| existingRuleMap[key] = j; | |
| } | |
| for(const StyleRule& newRule : *newOverrides) { | |
| std::wstring key = newRule.name + L"@" + newRule.visualState; | |
| std::unordered_map<std::wstring, size_t>::iterator it = existingRuleMap.find(key); | |
| if(it != existingRuleMap.end()) { | |
| // Overwrite existing rule | |
| // const StyleRule existingRule = existingOverrides[it->second]; | |
| Wh_Log(L"Overriding Existing Rule %s to %s", (*existingOverrides)[it->second].toString().c_str(), | |
| newRule.toString().c_str()); | |
| (*existingOverrides)[it->second] = newRule; | |
| } else { | |
| // Add new unique rule | |
| existingOverrides->push_back(newRule); | |
| } | |
| } | |
| return; // Found a match, merged the rules, don't add as new | |
| } | |
| } | |
| g_elementsCustomizationRules.push_back(std::move(rule)); | |
| } | |
| void AddElementCustomizationRules(PCWSTR target, std::vector<StyleRule> style) { | |
| ElementCustomizationRules rule; | |
| InitElementCustomizationRules(&rule, target); | |
| rule.propertyOverrides = std::move(style); | |
| AddElementCustomizationRules(std::move(rule)); | |
| } | |
| void AddElementCustomizationRules(PCWSTR target, std::vector<std::wstring> styleStrings) { | |
| std::vector<StyleRule> styleRules; | |
| styleRules.reserve(styleStrings.size()); | |
| for(const std::wstring& style : styleStrings) { | |
| try { | |
| StyleRule rule = StyleRuleFromString(style); | |
| styleRules.push_back(rule); | |
| } catch(std::runtime_error const& exA) { | |
| Wh_Log(L"StyleRuleFromString std::exception: %S | %s ", exA.what(), style.c_str()); | |
| } | |
| } | |
| AddElementCustomizationRules(target, std::move(styleRules)); | |
| } | |
| bool ProcessSingleTargetStylesFromSettings(int index, const StyleConstants& styleConstants) { | |
| string_setting_unique_ptr targetStringSetting(Wh_GetStringSetting(L"controlStyles[%d].target", index)); | |
| if(!*targetStringSetting.get()) { return false; } | |
| // Skip if commented. | |
| if(targetStringSetting[0] == L'/' && targetStringSetting[1] == L'/') { return true; } | |
| Wh_Log(L"Processing styles for %s", targetStringSetting.get()); | |
| std::vector<std::wstring> styles; | |
| for(int styleIndex = 0;; styleIndex++) { | |
| string_setting_unique_ptr styleSetting(Wh_GetStringSetting(L"controlStyles[%d].styles[%d]", index, styleIndex)); | |
| if(!*styleSetting.get()) { break; } | |
| // Skip if commented. | |
| if(styleSetting[0] == L'/' && styleSetting[1] == L'/') { continue; } | |
| styles.push_back(ApplyStyleConstants(styleSetting.get(), styleConstants)); | |
| } | |
| if(styles.size() > 0) { AddElementCustomizationRules(targetStringSetting.get(), std::move(styles)); } | |
| return true; | |
| } | |
| std::optional<bool> IsOsFeatureEnabled(UINT32 featureId) { | |
| enum FEATURE_ENABLED_STATE { | |
| FEATURE_ENABLED_STATE_DEFAULT = 0, | |
| FEATURE_ENABLED_STATE_DISABLED = 1, | |
| FEATURE_ENABLED_STATE_ENABLED = 2, | |
| }; | |
| #pragma pack(push, 1) | |
| struct RTL_FEATURE_CONFIGURATION { | |
| unsigned int featureId; | |
| unsigned __int32 group : 4; | |
| FEATURE_ENABLED_STATE enabledState : 2; | |
| unsigned __int32 enabledStateOptions : 1; | |
| unsigned __int32 unused1 : 1; | |
| unsigned __int32 variant : 6; | |
| unsigned __int32 variantPayloadKind : 2; | |
| unsigned __int32 unused2 : 16; | |
| unsigned int payload; | |
| }; | |
| #pragma pack(pop) | |
| using RtlQueryFeatureConfiguration_t = int(NTAPI*)(UINT32, int, INT64*, RTL_FEATURE_CONFIGURATION*); | |
| static RtlQueryFeatureConfiguration_t pRtlQueryFeatureConfiguration = []() { | |
| HMODULE hNtDll = LoadLibraryW(L"ntdll.dll"); | |
| return hNtDll ? (RtlQueryFeatureConfiguration_t)GetProcAddress(hNtDll, "RtlQueryFeatureConfiguration") : nullptr; | |
| }(); | |
| if(!pRtlQueryFeatureConfiguration) { | |
| Wh_Log(L"RtlQueryFeatureConfiguration not found"); | |
| return std::nullopt; | |
| } | |
| RTL_FEATURE_CONFIGURATION feature = { 0 }; | |
| INT64 changeStamp = 0; | |
| HRESULT hr = pRtlQueryFeatureConfiguration(featureId, 1, &changeStamp, &feature); | |
| if(SUCCEEDED(hr)) { | |
| Wh_Log(L"RtlQueryFeatureConfiguration result for %u: %d", featureId, feature.enabledState); | |
| switch(feature.enabledState) { | |
| case FEATURE_ENABLED_STATE_DISABLED: | |
| return false; | |
| case FEATURE_ENABLED_STATE_ENABLED: | |
| return true; | |
| case FEATURE_ENABLED_STATE_DEFAULT: | |
| return std::nullopt; | |
| } | |
| } else { | |
| Wh_Log(L"RtlQueryFeatureConfiguration error for %u: %08X", featureId, hr); | |
| } | |
| return std::nullopt; | |
| } | |
| void ProcessAllStylesFromSettings() { | |
| string_setting_unique_ptr _themeName(Wh_GetStringSetting(L"theme")); | |
| auto themeName = _themeName.get(); | |
| const Theme* theme = nullptr; | |
| if(wcscmp(themeName, L"TranslucentTaskbar") == 0) { | |
| theme = &g_Themes.TranslucentTaskbar; | |
| } else if(wcscmp(themeName, L"DockLike") == 0) { | |
| theme = &g_Themes.DockLike; | |
| } else if(wcscmp(themeName, L"SimplyTransparent") == 0) { | |
| theme = &g_Themes.SimplyTransparent; | |
| } else if(wcscmp(themeName, L"Squircle") == 0) { | |
| // Weather widget on the right. | |
| // https://www.reddit.com/r/Windows11/comments/1dnew8x/my_weather_widget_is_on_the_right_side/ | |
| constexpr UINT32 kExtendedModeAEPForTaskbar = 48660958; | |
| theme = IsOsFeatureEnabled(kExtendedModeAEPForTaskbar).value_or(false) ? &g_Themes.Squircle_variant_WeatherOnTheRight | |
| : &g_Themes.Squircle; | |
| } else if(wcscmp(themeName, L"Matter") == 0) { | |
| theme = &g_Themes.Matter; | |
| } else if(wcscmp(themeName, L"WinXP") == 0) { | |
| theme = &g_Themes.WinXP; | |
| } else if(wcscmp(themeName, L"WinXP_variant_Zune") == 0) { | |
| theme = &g_Themes.WinXP_variant_Zune; | |
| } else if(wcscmp(themeName, L"Bubbles") == 0) { | |
| theme = &g_Themes.Bubbles; | |
| } else if(wcscmp(themeName, L"RosePine") == 0) { | |
| theme = &g_Themes.RosePine; | |
| } else if(wcscmp(themeName, L"WinVista") == 0) { | |
| theme = &g_Themes.WinVista; | |
| } else if(wcscmp(themeName, L"CleanSlate") == 0) { | |
| theme = &g_Themes.CleanSlate; | |
| } else if(wcscmp(themeName, L"Lucent") == 0) { | |
| theme = &g_Themes.Lucent; | |
| } else if(wcscmp(themeName, L"Lucent_variant_Light") == 0) { | |
| theme = &g_Themes.Lucent_variant_Light; | |
| } else if(wcscmp(themeName, L"SunValley") == 0) { | |
| theme = &g_Themes.SunValley; | |
| } else if(wcscmp(themeName, L"21996Taskbar") == 0) { | |
| theme = &g_Themes.Taskbar21996; | |
| } else if(wcscmp(themeName, L"BottomDensy") == 0) { | |
| theme = &g_Themes.BottomDensy; | |
| } else if(wcscmp(themeName, L"BottomDensy_variant_NoInd") == 0) { | |
| theme = &g_Themes.BottomDensy_variant_NoInd; | |
| } else if(wcscmp(themeName, L"TaskbarXII") == 0) { | |
| theme = &g_Themes.TaskbarXII; | |
| } else if(wcscmp(themeName, L"xdark") == 0) { | |
| theme = &g_Themes.xdark; | |
| } else if(wcscmp(themeName, L"Windows7") == 0) { | |
| theme = &g_Themes.Windows7; | |
| } else if(wcscmp(themeName, L"Aeris") == 0) { | |
| theme = &g_Themes.Aeris; | |
| } else if(wcscmp(themeName, L"Plasma") == 0) { | |
| theme = &g_Themes.Plasma; | |
| } else if(wcscmp(themeName, L"WindowGlass") == 0) { | |
| theme = &g_Themes.WindowGlass; | |
| } else if(wcscmp(themeName, L"Surface") == 0) { | |
| theme = &g_Themes.Surface; | |
| } else if(wcscmp(themeName, L"Oversimplified&Accentuated") == 0) { | |
| theme = &g_Themes.Oversimplified_Accentuated; | |
| } else if(wcscmp(themeName, L"Luminosity_variant_Dock") == 0) { | |
| theme = &g_Themes.Luminosity_variant_Dock; | |
| } else if(wcscmp(themeName, L"Luminosity_variant_Classic") == 0) { | |
| theme = &g_Themes.Luminosity_variant_Classic; | |
| } else if(wcscmp(themeName, L"Luminosity_variant_Compact") == 0) { | |
| theme = &g_Themes.Luminosity_variant_Compact; | |
| } else if(wcscmp(themeName, L"Derek") == 0) { | |
| theme = &g_Themes.Derek; | |
| } | |
| StyleConstants styleConstants = LoadStyleConstants(theme ? theme->styleConstants : std::vector<PCWSTR>{}); | |
| if(theme) { | |
| for(const ThemeTargetStyles& themeTargetStyle : theme->targetStyles) { | |
| try { | |
| std::vector<StyleRule> styles; | |
| styles.reserve(themeTargetStyle.styles.size()); | |
| for(PCWSTR s : themeTargetStyle.styles) { | |
| try { | |
| std::wstring subbed = ApplyStyleConstants(s, styleConstants); | |
| StyleRule rule = StyleRuleFromString(subbed); | |
| styles.push_back(rule); | |
| } catch(winrt::hresult_error const& exA) { | |
| Wh_Log(L"ApplyStyleConstants hresult_error %08X | %s | %s", exA.code(), | |
| StrFmt::toString(themeTargetStyle.target).c_str(), s); | |
| } catch(std::exception const& exA) { | |
| Wh_Log(L"ApplyStyleConstants std::exception: %S | %s | %s", exA.what(), | |
| StrFmt::toString(themeTargetStyle.target).c_str(), s); | |
| } | |
| } | |
| if(std::holds_alternative<PCWSTR>(themeTargetStyle.target)) { | |
| PCWSTR singleTarget = std::get<PCWSTR>(themeTargetStyle.target); | |
| AddElementCustomizationRules(singleTarget, std::move(styles)); | |
| } else { | |
| // Multiple targets | |
| const std::vector<PCWSTR>& targets = std::get<std::vector<PCWSTR>>(themeTargetStyle.target); | |
| for(size_t i = 0; i < targets.size(); ++i) { | |
| if(i == targets.size() - 1) { | |
| AddElementCustomizationRules(targets[i], std::move(styles)); | |
| } else { | |
| AddElementCustomizationRules(targets[i], styles); | |
| } | |
| } | |
| } | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"InitElementCustomizationRules hresult_error %08X | %s | %s", ex.code(), | |
| StrFmt::toString(themeTargetStyle.target).c_str(), ex.message().c_str()); | |
| } catch(std::exception const& ex) { | |
| Wh_Log(L"InitElementCustomizationRules std::exception: %S | %s | %s", ex.what(), | |
| StrFmt::toString(themeTargetStyle.target).c_str(), ex.what()); | |
| } | |
| } | |
| } | |
| for(int i = 0;; i++) { | |
| try { | |
| if(!ProcessSingleTargetStylesFromSettings(i, styleConstants)) { break; } | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"ProcessSingleTargetStylesFromSettings hresult_error %08X: %s", ex.code(), ex.message().c_str()); | |
| } catch(std::exception const& ex) { | |
| Wh_Log(L"ProcessSingleTargetStylesFromSettings: std::exception %S %s", ex.what(), ex.what()); | |
| } | |
| } | |
| } | |
| bool ProcessSingleResourceVariableFromSettings(int index) { | |
| string_setting_unique_ptr variableKeyStringSetting(Wh_GetStringSetting(L"resourceVariables[%d].variableKey", index)); | |
| if(!*variableKeyStringSetting.get()) { return false; } | |
| Wh_Log(L"Processing resource variable %s", variableKeyStringSetting.get()); | |
| std::wstring_view variableKey = variableKeyStringSetting.get(); | |
| ResourceDictionary resources = Application::Current().Resources(); | |
| wf::IInspectable resource = resources.Lookup(winrt::box_value(variableKey)); | |
| if(!resource) { | |
| Wh_Log(L"Resource variable '%.*s' resolved to null", static_cast<int>(variableKey.size()), variableKey.data()); | |
| return true; | |
| } | |
| // Example: Windows.Foundation.IReference`1<Windows.UI.Xaml.Thickness> | |
| Interop::TypeName resourceTypeName = Helper::GetTypeName(resource); | |
| string_setting_unique_ptr valueStringSetting(Wh_GetStringSetting(L"resourceVariables[%d].value", index)); | |
| std::wstring_view value = valueStringSetting.get(); | |
| resources.Insert(winrt::box_value(variableKey), | |
| Markup::XamlBindingHelper::ConvertValue(resourceTypeName, winrt::box_value(value))); | |
| return true; | |
| } | |
| std::optional<ResourceVariableEntry> ParseResourceVariable(std::wstring_view entry, const StyleConstants& styleConstants) { | |
| // Skip if commented. | |
| if(entry.starts_with(L"//")) { return std::nullopt; } | |
| // Find the first '=' to split key and value. | |
| size_t eqPos = entry.find(L'='); | |
| if(eqPos == entry.npos) { | |
| Wh_Log(L"Skipping entry with no '=': %.*s", static_cast<int>(entry.length()), entry.data()); | |
| return std::nullopt; | |
| } | |
| std::wstring_view keyPart = StrFmt::TrimStringView(entry.substr(0, eqPos)); | |
| std::wstring_view valueRaw = StrFmt::TrimStringView(entry.substr(eqPos + 1)); | |
| std::wstring value = ApplyStyleConstants(valueRaw, styleConstants); | |
| ResourceVariableTheme theme = ResourceVariableTheme::None; | |
| std::wstring key; | |
| // Check for @theme suffix in key part. | |
| size_t atPos = keyPart.find(L'@'); | |
| if(atPos != keyPart.npos) { | |
| key = StrFmt::TrimStringView(keyPart.substr(0, atPos)); | |
| std::wstring_view themePart = StrFmt::TrimStringView(keyPart.substr(atPos + 1)); | |
| if(themePart == L"Dark") { | |
| theme = ResourceVariableTheme::Dark; | |
| } else if(themePart == L"Light") { | |
| theme = ResourceVariableTheme::Light; | |
| } else { | |
| Wh_Log(L"Unknown theme '%.*s', expected 'Dark' or 'Light'", static_cast<int>(themePart.size()), themePart.data()); | |
| return std::nullopt; | |
| } | |
| } else { | |
| key = std::wstring(keyPart); | |
| } | |
| return ResourceVariableEntry{ std::move(key), std::move(value), theme }; | |
| } | |
| constexpr std::wstring_view kThemeResourcePrefix = L"{ThemeResource "; | |
| bool IsThemeResourceReference(std::wstring_view value) { | |
| return value.starts_with(kThemeResourcePrefix) && value.ends_with(L"}"); | |
| } | |
| wf::IInspectable ResolveResourceVariableValue(ResourceDictionary resources, std::wstring_view value) { | |
| // Check for {ThemeResource X} syntax - look up the resource directly | |
| // to preserve dynamic theme-aware behavior. | |
| if(IsThemeResourceReference(value)) { | |
| auto resourceKey = value.substr(kThemeResourcePrefix.size(), value.size() - kThemeResourcePrefix.size() - 1); | |
| return resources.Lookup(winrt::box_value(winrt::hstring(StrFmt::TrimStringView(resourceKey)))); | |
| } | |
| // For other values, use boxed string (works for colors, etc.). | |
| return winrt::box_value(winrt::hstring(value)); | |
| } | |
| // Returns true if a theme resource was added. | |
| bool ProcessResourceVariableFromSetting(ResourceDictionary resources, | |
| ResourceDictionary darkDict, | |
| ResourceDictionary lightDict, | |
| const ResourceVariableEntry& entry) { | |
| auto boxedKey = winrt::box_value(entry.key); | |
| if(entry.theme != ResourceVariableTheme::None) { | |
| // Key@Dark= or Key@Light= - add to theme dict. | |
| auto value = ResolveResourceVariableValue(resources, entry.value); | |
| if(entry.theme == ResourceVariableTheme::Dark) { | |
| darkDict.Insert(boxedKey, value); | |
| } else { | |
| lightDict.Insert(boxedKey, value); | |
| } | |
| return true; | |
| } | |
| // key= - convert using existing resource type. | |
| auto existingResource = resources.TryLookup(boxedKey); | |
| if(!existingResource) { | |
| Wh_Log(L"Resource variable key '%s' not found, skipping", entry.key.c_str()); | |
| return false; | |
| } | |
| if(!g_originalResourceValues.contains(entry.key)) { g_originalResourceValues[entry.key] = existingResource; } | |
| Interop::TypeName resourceTypeName = Helper::GetTypeName(existingResource); | |
| resources.Insert(boxedKey, Markup::XamlBindingHelper::ConvertValue(resourceTypeName, | |
| winrt::box_value(entry.value))); | |
| return false; | |
| } | |
| void RefreshThemeResourceEntries() { | |
| if(g_themeResourceEntries.empty()) { return; } | |
| Wh_Log(L"Refreshing %zu theme resource entries", g_themeResourceEntries.size()); | |
| auto resources = Application::Current().Resources(); | |
| auto darkDict = | |
| g_resourceVariablesThemeDict.ThemeDictionaries().TryLookup(winrt::box_value(L"Dark")).try_as<ResourceDictionary>(); | |
| auto lightDict = | |
| g_resourceVariablesThemeDict.ThemeDictionaries().TryLookup(winrt::box_value(L"Light")).try_as<ResourceDictionary>(); | |
| for(const auto& entry : g_themeResourceEntries) { | |
| try { | |
| auto boxedKey = winrt::box_value(entry.key); | |
| auto value = ResolveResourceVariableValue(resources, entry.value); | |
| if(entry.theme == ResourceVariableTheme::Dark && darkDict) { | |
| darkDict.Insert(boxedKey, value); | |
| } else if(entry.theme == ResourceVariableTheme::Light && lightDict) { | |
| lightDict.Insert(boxedKey, value); | |
| } | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error refreshing '%s': %08X | %s", entry.key.c_str(), ex.code(), ex.message().c_str()); | |
| } | |
| } | |
| } | |
| void ProcessResourceVariablesFromSettings() { | |
| try { | |
| StyleConstants styleConstants = LoadStyleConstants(std::vector<PCWSTR>{}); | |
| auto resources = Application::Current().Resources(); | |
| // Create theme dictionaries for @Dark/@Light resources. | |
| g_resourceVariablesThemeDict = ResourceDictionary(); | |
| ResourceDictionary darkDict; | |
| ResourceDictionary lightDict; | |
| bool hasThemeResources = false; | |
| for(int i = 0;; i++) { | |
| string_setting_unique_ptr setting(Wh_GetStringSetting(L"themeResourceVariables[%d]", i)); | |
| if(!*setting.get()) { break; } | |
| Wh_Log(L"Processing theme resource variable %s", setting.get()); | |
| auto parsed = ParseResourceVariable(setting.get(), styleConstants); | |
| if(!parsed) { continue; } | |
| try { | |
| if(ProcessResourceVariableFromSetting(resources, darkDict, lightDict, *parsed)) { | |
| hasThemeResources = true; | |
| // Track entries with {ThemeResource ...} for refresh on color | |
| // change. | |
| if(IsThemeResourceReference(parsed->value)) { g_themeResourceEntries.push_back(*parsed); } | |
| } | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error %08X: %s", ex.code(), ex.message().c_str()); | |
| } catch(std::exception const& ex) { Wh_Log(L"Error: %S", ex.what()); } | |
| } | |
| if(hasThemeResources) { | |
| g_resourceVariablesThemeDict.ThemeDictionaries().Insert(winrt::box_value(L"Dark"), darkDict); | |
| g_resourceVariablesThemeDict.ThemeDictionaries().Insert(winrt::box_value(L"Light"), lightDict); | |
| resources.MergedDictionaries().Append(g_resourceVariablesThemeDict); | |
| } else { | |
| Wh_Log(L"No theme resource variables found, skipping creation of theme dictionary"); | |
| } | |
| // Register for color changes to refresh theme resource references. | |
| if(!g_themeResourceEntries.empty()) { | |
| g_uiSettings = winrt::Windows::UI::ViewManagement::UISettings(); | |
| auto dispatcherQueue = winrt::Windows::System::DispatcherQueue::GetForCurrentThread(); | |
| g_colorValuesChangedToken = g_uiSettings.ColorValuesChanged( | |
| [dispatcherQueue](auto&&, auto&&) { dispatcherQueue.TryEnqueue([]() { RefreshThemeResourceEntries(); }); }); | |
| } else { | |
| Wh_Log(L"g_themeResourceEntries is empty, no need to register for color changes"); | |
| } | |
| } catch(std::exception const& ex) { Wh_Log(L"Error: %S", ex.what()); } | |
| } | |
| void UninitializeResourceVariables() { | |
| // Unregister color change handler. | |
| if(g_colorValuesChangedToken) { | |
| g_uiSettings.ColorValuesChanged(g_colorValuesChangedToken); | |
| g_colorValuesChangedToken = {}; | |
| } | |
| g_uiSettings = nullptr; | |
| g_themeResourceEntries.clear(); | |
| // Restore original resource values. | |
| auto resources = Application::Current().Resources(); | |
| for(const auto& [key, originalValue] : g_originalResourceValues) { | |
| try { | |
| resources.Insert(winrt::box_value(key), originalValue); | |
| } catch(...) { | |
| HRESULT hr = winrt::to_hresult(); | |
| Wh_Log(L"Error %08X", hr); | |
| } | |
| } | |
| g_originalResourceValues.clear(); | |
| // Remove our merged theme dictionary. | |
| if(g_resourceVariablesThemeDict) { | |
| auto merged = resources.MergedDictionaries(); | |
| uint32_t index; | |
| if(merged.IndexOf(g_resourceVariablesThemeDict, index)) { merged.RemoveAt(index); } | |
| g_resourceVariablesThemeDict = nullptr; | |
| } | |
| } | |
| void UninitializeForCurrentThread() { | |
| // Clear failed image brushes list for this thread (revokers will | |
| // automatically unregister). | |
| g_failedImageBrushesForThread.failedImageBrushes.clear(); | |
| g_failedImageBrushesForThread.dispatcher = nullptr; | |
| for(const auto& [elementDo, asyncOp] : g_delayedBackgroundFillSet) { | |
| asyncOp.Cancel(); | |
| } | |
| g_delayedBackgroundFillSet.clear(); | |
| for(const auto& [handle, elementCustomizationState] : g_elementsCustomizationState) { | |
| FrameworkElement element = elementCustomizationState.element.get(); | |
| for(const auto& [visualStateGroupOptionalWeakPtrIter, stateIter] : elementCustomizationState.perVisualStateGroup) { | |
| RestoreCustomizationsForVisualStateGroup(element, visualStateGroupOptionalWeakPtrIter, stateIter); | |
| } | |
| } | |
| g_elementsCustomizationState.clear(); | |
| g_elementsCustomizationRules.clear(); | |
| g_hasReevalElements.clear(); | |
| g_hasReevalScheduled = false; | |
| g_anyRuleUsesHas = false; | |
| UninitializeResourceVariables(); | |
| g_initializedForThread = false; | |
| } | |
| void UninitializeSettingsAndTap() { | |
| if(g_visualTreeWatcher) { | |
| g_visualTreeWatcher->UnadviseVisualTreeChange(); | |
| g_visualTreeWatcher = nullptr; | |
| } | |
| // Invalidate the shared rules template so it is rebuilt on next init. | |
| { | |
| std::lock_guard<std::mutex> lock(g_sharedRulesMutex); | |
| g_sharedRulesBuilt = false; | |
| g_sharedRulesTemplate.clear(); | |
| } | |
| g_initialized = false; | |
| } | |
| void InitializeForCurrentThread() { | |
| if(g_initializedForThread) { return; } | |
| Wh_Log(L"Initializing For new Thread"); | |
| try { | |
| std::lock_guard<std::mutex> lock(g_sharedRulesMutex); | |
| if(!g_sharedRulesBuilt) { | |
| // First thread to initialize: parse settings into rules. | |
| ProcessAllStylesFromSettings(); | |
| // Snapshot the unresolved rules as the shared template. | |
| g_sharedRulesTemplate = g_elementsCustomizationRules; | |
| g_sharedRulesBuilt = true; | |
| } else { | |
| // Subsequent threads: copy the already-parsed template. | |
| g_elementsCustomizationRules = g_sharedRulesTemplate; | |
| } | |
| } catch(std::exception const& ex) { Wh_Log(L"Error processing styles: %S", ex.what()); } | |
| Wh_Log(L"InitializeForCurrentThread: shared rules done, about to process resource variables"); | |
| ProcessResourceVariablesFromSettings(); | |
| // Check if any rule uses :has() selectors. | |
| g_anyRuleUsesHas = std::any_of(g_elementsCustomizationRules.begin(), g_elementsCustomizationRules.end(), | |
| [](const ElementCustomizationRules& rule) { | |
| if(!rule.elementMatcher.hasSelectors.empty() || !rule.elementMatcher.notHasSelectors.empty()) { return true; } | |
| return std::any_of(rule.parentElementMatchers.begin(), rule.parentElementMatchers.end(), | |
| [](const ElementMatcher& m) { return !m.hasSelectors.empty() || !m.notHasSelectors.empty(); }); | |
| }); | |
| if(g_anyRuleUsesHas) { | |
| Wh_Log(L":has() and/or :not-has() selectors detected — enabling periodic re-evaluation"); | |
| } | |
| Wh_Log(L"Finished Initializing For new Thread"); | |
| g_initializedForThread = true; | |
| } | |
| void InitializeSettingsAndTap() { | |
| if(g_initialized.exchange(true)) { return; } | |
| HRESULT hr = InjectWindhawkTAP(); | |
| if(FAILED(hr)) { Wh_Log(L"Error %08X", hr); } | |
| } | |
| using RunFromWindowThreadProc_t = void(WINAPI*)(PVOID parameter); | |
| bool RunFromWindowThread(HWND hWnd, RunFromWindowThreadProc_t proc, PVOID procParam) { | |
| static const UINT runFromWindowThreadRegisteredMsg = RegisterWindowMessage(L"Windhawk_" | |
| L"RunFromWindowThread_" WH_MOD_ID); | |
| struct RUN_FROM_WINDOW_THREAD_PARAM { | |
| RunFromWindowThreadProc_t proc; | |
| PVOID procParam; | |
| }; | |
| DWORD dwThreadId = GetWindowThreadProcessId(hWnd, nullptr); | |
| if(dwThreadId == 0) { return false; } | |
| if(dwThreadId == GetCurrentThreadId()) { | |
| proc(procParam); | |
| return true; | |
| } | |
| HHOOK hook = SetWindowsHookEx( | |
| WH_CALLWNDPROC, | |
| [](int nCode, WPARAM wParam, LPARAM lParam) -> LRESULT { | |
| if(nCode == HC_ACTION) { | |
| const CWPSTRUCT* cwp = (const CWPSTRUCT*)lParam; | |
| if(cwp->message == runFromWindowThreadRegisteredMsg) { | |
| RUN_FROM_WINDOW_THREAD_PARAM* param = (RUN_FROM_WINDOW_THREAD_PARAM*)cwp->lParam; | |
| param->proc(param->procParam); | |
| } | |
| } | |
| return CallNextHookEx(nullptr, nCode, wParam, lParam); | |
| }, | |
| nullptr, dwThreadId); | |
| if(!hook) { return false; } | |
| RUN_FROM_WINDOW_THREAD_PARAM param; | |
| param.proc = proc; | |
| param.procParam = procParam; | |
| SendMessage(hWnd, runFromWindowThreadRegisteredMsg, 0, (LPARAM)¶m); | |
| UnhookWindowsHookEx(hook); | |
| return true; | |
| } | |
| void OnWindowCreated(HWND hWnd, HWND hWndParent, LPCWSTR lpClassName, PCSTR funcName) { | |
| BOOL bTextualClassName = ((ULONG_PTR)lpClassName & ~(ULONG_PTR)0xffff) != 0; | |
| WCHAR className[64]; | |
| if(hWndParent && GetClassName(hWnd, className, ARRAYSIZE(className)) && | |
| _wcsicmp(className, L"Windows.UI.Composition.DesktopWindowContentBridge") == 0 && | |
| GetClassName(hWndParent, className, ARRAYSIZE(className)) && _wcsicmp(className, L"Shell_TrayWnd") == 0) { | |
| Wh_Log(L"Initializing - Created DesktopWindowContentBridge window"); | |
| InitializeForCurrentThread(); | |
| InitializeSettingsAndTap(); | |
| return; | |
| } | |
| if(bTextualClassName && | |
| (_wcsicmp(lpClassName, L"XamlExplorerHostIslandWindow") == 0 || _wcsicmp(lpClassName, L"Shell_" | |
| L"InputSwitchTopLevelWindo" | |
| L"w") == 0)) { | |
| Wh_Log(L"Initializing - Created XAML host window: %08X via %S", (DWORD)(ULONG_PTR)hWnd, funcName); | |
| InitializeForCurrentThread(); | |
| InitializeSettingsAndTap(); | |
| return; | |
| } | |
| } | |
| using CreateWindowExW_t = decltype(&CreateWindowExW); | |
| CreateWindowExW_t CreateWindowExW_Original; | |
| HWND WINAPI CreateWindowExW_Hook(DWORD dwExStyle, | |
| LPCWSTR lpClassName, | |
| LPCWSTR lpWindowName, | |
| DWORD dwStyle, | |
| int X, | |
| int Y, | |
| int nWidth, | |
| int nHeight, | |
| HWND hWndParent, | |
| HMENU hMenu, | |
| HINSTANCE hInstance, | |
| PVOID lpParam) { | |
| HWND hWnd = CreateWindowExW_Original(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, | |
| hMenu, hInstance, lpParam); | |
| if(!hWnd) { return hWnd; } | |
| OnWindowCreated(hWnd, hWndParent, lpClassName, __FUNCTION__); | |
| return hWnd; | |
| } | |
| using CreateWindowInBand_t = HWND(WINAPI*)(DWORD dwExStyle, | |
| LPCWSTR lpClassName, | |
| LPCWSTR lpWindowName, | |
| DWORD dwStyle, | |
| int X, | |
| int Y, | |
| int nWidth, | |
| int nHeight, | |
| HWND hWndParent, | |
| HMENU hMenu, | |
| HINSTANCE hInstance, | |
| PVOID lpParam, | |
| DWORD dwBand); | |
| CreateWindowInBand_t CreateWindowInBand_Original; | |
| HWND WINAPI CreateWindowInBand_Hook(DWORD dwExStyle, | |
| LPCWSTR lpClassName, | |
| LPCWSTR lpWindowName, | |
| DWORD dwStyle, | |
| int X, | |
| int Y, | |
| int nWidth, | |
| int nHeight, | |
| HWND hWndParent, | |
| HMENU hMenu, | |
| HINSTANCE hInstance, | |
| PVOID lpParam, | |
| DWORD dwBand) { | |
| HWND hWnd = CreateWindowInBand_Original(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, | |
| hWndParent, hMenu, hInstance, lpParam, dwBand); | |
| if(!hWnd) { return hWnd; } | |
| OnWindowCreated(hWnd, hWndParent, lpClassName, __FUNCTION__); | |
| return hWnd; | |
| } | |
| using CreateWindowInBandEx_t = HWND(WINAPI*)(DWORD dwExStyle, | |
| LPCWSTR lpClassName, | |
| LPCWSTR lpWindowName, | |
| DWORD dwStyle, | |
| int X, | |
| int Y, | |
| int nWidth, | |
| int nHeight, | |
| HWND hWndParent, | |
| HMENU hMenu, | |
| HINSTANCE hInstance, | |
| PVOID lpParam, | |
| DWORD dwBand, | |
| DWORD dwTypeFlags); | |
| CreateWindowInBandEx_t CreateWindowInBandEx_Original; | |
| HWND WINAPI CreateWindowInBandEx_Hook(DWORD dwExStyle, | |
| LPCWSTR lpClassName, | |
| LPCWSTR lpWindowName, | |
| DWORD dwStyle, | |
| int X, | |
| int Y, | |
| int nWidth, | |
| int nHeight, | |
| HWND hWndParent, | |
| HMENU hMenu, | |
| HINSTANCE hInstance, | |
| PVOID lpParam, | |
| DWORD dwBand, | |
| DWORD dwTypeFlags) { | |
| HWND hWnd = CreateWindowInBandEx_Original(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, | |
| hWndParent, hMenu, hInstance, lpParam, dwBand, dwTypeFlags); | |
| if(!hWnd) { return hWnd; } | |
| OnWindowCreated(hWnd, hWndParent, lpClassName, __FUNCTION__); | |
| return hWnd; | |
| } | |
| PFN_INITIALIZE_XAML_DIAGNOSTICS_EX InitializeXamlDiagnosticsEx_Original; | |
| HRESULT WINAPI InitializeXamlDiagnosticsEx_Hook(_In_ PCWSTR endPointName, | |
| _In_ DWORD pid, | |
| _In_ PCWSTR wszDllXamlDiagnostics, | |
| _In_ PCWSTR wszTAPDllName, | |
| _In_ CLSID tapClsid, | |
| _In_opt_ PCWSTR wszInitializationData) { | |
| if(g_inInjectWindhawkTAP) { | |
| return InitializeXamlDiagnosticsEx_Original(endPointName, pid, wszDllXamlDiagnostics, wszTAPDllName, tapClsid, | |
| wszInitializationData); | |
| } | |
| bool blockCall = false; | |
| switch(g_settings.xamlDiagnosticsHandling) { | |
| case XamlDiagnosticsHandling::kAlert: { | |
| void* retAddress = __builtin_return_address(0); | |
| WCHAR modulePath[MAX_PATH]; | |
| PCWSTR modulePathStr = L"<unknown>"; | |
| HMODULE module; | |
| if(GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, | |
| reinterpret_cast<LPCWSTR>(retAddress), &module)) { | |
| switch(GetModuleFileName(module, modulePath, ARRAYSIZE(modulePath))) { | |
| case 0: | |
| case ARRAYSIZE(modulePath): | |
| break; | |
| default: | |
| modulePathStr = modulePath; | |
| break; | |
| } | |
| } | |
| WCHAR message[1024]; | |
| _snwprintf_s(message, _TRUNCATE, | |
| L"The following module is trying to use XAML diagnostics:\n\n" | |
| L"%s\n\n" | |
| L"There can only be one consumer at a time. Blocking it might " | |
| L"break that module, but allowing it might break this mod.\n\n" | |
| L"Do you want to block it?\n\n" | |
| L"Note: You can change this behavior in the mod settings.", | |
| modulePathStr); | |
| int result = | |
| MessageBox(nullptr, message, L"Windows 11 Taskbar Styler - Windhawk", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST); | |
| blockCall = (result == IDYES); | |
| break; | |
| } | |
| case XamlDiagnosticsHandling::kBlock: | |
| blockCall = true; | |
| break; | |
| case XamlDiagnosticsHandling::kAllow: | |
| blockCall = false; | |
| break; | |
| } | |
| if(blockCall) { | |
| Wh_Log(L"Blocking InitializeXamlDiagnosticsEx call"); | |
| // Return success to avoid exception in the caller. | |
| return S_OK; | |
| } | |
| Wh_Log(L"Allowing InitializeXamlDiagnosticsEx call"); | |
| return InitializeXamlDiagnosticsEx_Original(endPointName, pid, wszDllXamlDiagnostics, wszTAPDllName, tapClsid, | |
| wszInitializationData); | |
| } | |
| void HookInitializeXamlDiagnosticsExIfNeeded() { | |
| if(InitializeXamlDiagnosticsEx_Original) { | |
| return; // Already hooked | |
| } | |
| const HMODULE wux = GetModuleHandle(L"Windows.UI.Xaml.dll"); | |
| if(!wux) { | |
| return; // DLL not loaded yet | |
| } | |
| const auto ixde = reinterpret_cast<PFN_INITIALIZE_XAML_DIAGNOSTICS_EX>(GetProcAddress(wux, "InitializeXamlDiagnostics" | |
| "Ex")); | |
| if(!ixde) { return; } | |
| Wh_Log(L"Hooking InitializeXamlDiagnosticsEx to handle other consumers"); | |
| WindhawkUtils::SetFunctionHook(ixde, InitializeXamlDiagnosticsEx_Hook, &InitializeXamlDiagnosticsEx_Original); | |
| Wh_ApplyHookOperations(); | |
| } | |
| using LoadLibraryExW_t = decltype(&LoadLibraryExW); | |
| LoadLibraryExW_t LoadLibraryExW_Original; | |
| HMODULE WINAPI LoadLibraryExW_Hook(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) { | |
| HMODULE module = LoadLibraryExW_Original(lpLibFileName, hFile, dwFlags); | |
| if(module && !InitializeXamlDiagnosticsEx_Original && lpLibFileName) { | |
| PCWSTR fileName = wcsrchr(lpLibFileName, L'\\'); | |
| fileName = fileName ? fileName + 1 : lpLibFileName; | |
| if(_wcsicmp(fileName, L"Windows.UI.Xaml.dll") == 0) { HookInitializeXamlDiagnosticsExIfNeeded(); } | |
| } | |
| return module; | |
| } | |
| std::vector<HWND> GetXamlHostWnds() { | |
| struct ENUM_WINDOWS_PARAM { | |
| std::vector<HWND>* hWnds; | |
| }; | |
| std::vector<HWND> hWnds; | |
| ENUM_WINDOWS_PARAM param = { &hWnds }; | |
| EnumWindows( | |
| [](HWND hWnd, LPARAM lParam) -> BOOL { | |
| ENUM_WINDOWS_PARAM& param = *(ENUM_WINDOWS_PARAM*)lParam; | |
| DWORD dwProcessId = 0; | |
| if(!GetWindowThreadProcessId(hWnd, &dwProcessId) || dwProcessId != GetCurrentProcessId()) { return TRUE; } | |
| WCHAR szClassName[32]; | |
| if(GetClassName(hWnd, szClassName, ARRAYSIZE(szClassName)) == 0) { return TRUE; } | |
| if(_wcsicmp(szClassName, L"XamlExplorerHostIslandWindow") == 0 || _wcsicmp(szClassName, L"Shell_" | |
| L"InputSwitchTo" | |
| L"pLeve" | |
| L"lWind" | |
| L"ow") == 0) { | |
| param.hWnds->push_back(hWnd); | |
| } | |
| return TRUE; | |
| }, | |
| (LPARAM)¶m); | |
| return hWnds; | |
| } | |
| HWND FindCurrentProcessTaskbarWnd() { | |
| HWND hTaskbarWnd = nullptr; | |
| EnumWindows( | |
| [](HWND hWnd, LPARAM lParam) -> BOOL { | |
| DWORD dwProcessId; | |
| WCHAR className[32]; | |
| if(GetWindowThreadProcessId(hWnd, &dwProcessId) && dwProcessId == GetCurrentProcessId() && | |
| GetClassName(hWnd, className, ARRAYSIZE(className)) && _wcsicmp(className, L"Shell_TrayWnd") == 0) { | |
| *reinterpret_cast<HWND*>(lParam) = hWnd; | |
| return FALSE; | |
| } | |
| return TRUE; | |
| }, | |
| reinterpret_cast<LPARAM>(&hTaskbarWnd)); | |
| return hTaskbarWnd; | |
| } | |
| HWND GetTaskbarUiWnd() { | |
| HWND hTaskbarWnd = FindCurrentProcessTaskbarWnd(); | |
| if(!hTaskbarWnd) { return nullptr; } | |
| return FindWindowEx(hTaskbarWnd, nullptr, L"Windows.UI.Composition.DesktopWindowContentBridge", nullptr); | |
| } | |
| void LoadSettings() { | |
| PCWSTR xamlDiagnosticsHandling = Wh_GetStringSetting(L"xamlDiagnosticsHandling"); | |
| g_settings.xamlDiagnosticsHandling = XamlDiagnosticsHandling::kAlert; | |
| if(wcscmp(xamlDiagnosticsHandling, L"block") == 0) { | |
| g_settings.xamlDiagnosticsHandling = XamlDiagnosticsHandling::kBlock; | |
| } else if(wcscmp(xamlDiagnosticsHandling, L"allow") == 0) { | |
| g_settings.xamlDiagnosticsHandling = XamlDiagnosticsHandling::kAllow; | |
| } | |
| Wh_FreeStringSetting(xamlDiagnosticsHandling); | |
| } | |
| // // Signature varies by WinUI version, but Lookup takes an HSTRING key. | |
| // typedef IInspectable* (__stdcall *Lookup_t)(void* resourceDictionary, HSTRING key); | |
| // Lookup_t Lookup_Original; | |
| // IInspectable* __stdcall Lookup_Hook(void* resourceDictionary, HSTRING key) { | |
| // // Convert HSTRING to std::wstring | |
| // UINT32 length; | |
| // const wchar_t* raw = WindowsGetStringRawBuffer(key, &length); | |
| // std::wstring name(raw, length); | |
| // Wh_Log(L"ThemeResource Lookup: %s", name.c_str()); | |
| // return Lookup_Original(resourceDictionary, key); | |
| // } | |
| BOOL Wh_ModInit() { | |
| Wh_Log(L">"); | |
| LoadSettings(); | |
| if(!Wh_SetFunctionHook((void*)CreateWindowExW, (void*)CreateWindowExW_Hook, (void**)&CreateWindowExW_Original)) { | |
| Wh_Log(L"Failed to hook CreateWindowExW"); | |
| } | |
| HMODULE user32Module = LoadLibraryEx(L"user32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); | |
| if(user32Module) { | |
| void* pCreateWindowInBand = (void*)GetProcAddress(user32Module, "CreateWindowInBand"); | |
| if(pCreateWindowInBand) { | |
| Wh_SetFunctionHook(pCreateWindowInBand, (void*)CreateWindowInBand_Hook, (void**)&CreateWindowInBand_Original); | |
| } | |
| void* pCreateWindowInBandEx = (void*)GetProcAddress(user32Module, "CreateWindowInBandEx"); | |
| if(pCreateWindowInBandEx) { | |
| Wh_SetFunctionHook(pCreateWindowInBandEx, (void*)CreateWindowInBandEx_Hook, (void**)&CreateWindowInBandEx_Original); | |
| } | |
| } | |
| HMODULE kernelBaseModule = GetModuleHandle(L"kernelbase.dll"); | |
| auto pKernelBaseLoadLibraryExW = (decltype(&LoadLibraryExW))GetProcAddress(kernelBaseModule, "LoadLibraryExW"); | |
| WindhawkUtils::SetFunctionHook(pKernelBaseLoadLibraryExW, LoadLibraryExW_Hook, &LoadLibraryExW_Original); | |
| // Hook immediately if DLL is already loaded. | |
| HookInitializeXamlDiagnosticsExIfNeeded(); | |
| return TRUE; | |
| } | |
| void Wh_ModAfterInit() { | |
| Wh_Log(L">"); | |
| bool initialize = false; | |
| HWND hTaskbarUiWnd = GetTaskbarUiWnd(); | |
| if(hTaskbarUiWnd) { | |
| Wh_Log(L"Initializing - Found DesktopWindowContentBridge window"); | |
| RunFromWindowThread(hTaskbarUiWnd, [](PVOID) { InitializeForCurrentThread(); }, nullptr); | |
| initialize = true; | |
| } | |
| for(HWND hXamlHostWnd : GetXamlHostWnds()) { | |
| Wh_Log(L"Initializing for %08X", (DWORD)(ULONG_PTR)hXamlHostWnd); | |
| RunFromWindowThread(hXamlHostWnd, [](PVOID) { InitializeForCurrentThread(); }, nullptr); | |
| initialize = true; | |
| } | |
| if(initialize) { InitializeSettingsAndTap(); } | |
| } | |
| void Wh_ModUninit() { | |
| Wh_Log(L">"); | |
| HWND restartExplorerPromptWindow = g_restartExplorerPromptWindow; | |
| if(restartExplorerPromptWindow) { PostMessage(restartExplorerPromptWindow, WM_CLOSE, 0, 0); } | |
| if(g_restartExplorerPromptThread) { | |
| WaitForSingleObject(g_restartExplorerPromptThread, INFINITE); | |
| CloseHandle(g_restartExplorerPromptThread); | |
| g_restartExplorerPromptThread = nullptr; | |
| } | |
| UninitializeSettingsAndTap(); | |
| HWND hTaskbarUiWnd = GetTaskbarUiWnd(); | |
| if(hTaskbarUiWnd) { | |
| Wh_Log(L"Uninitializing - Found DesktopWindowContentBridge window"); | |
| RunFromWindowThread(hTaskbarUiWnd, [](PVOID) { UninitializeForCurrentThread(); }, nullptr); | |
| } | |
| for(HWND hXamlHostWnd : GetXamlHostWnds()) { | |
| Wh_Log(L"Uninitializing for %08X", (DWORD)(ULONG_PTR)hXamlHostWnd); | |
| RunFromWindowThread(hXamlHostWnd, [](PVOID) { UninitializeForCurrentThread(); }, nullptr); | |
| } | |
| // Unregister global network status change handler. | |
| if(g_networkStatusChangedToken) { | |
| try { | |
| winrt::Windows::Networking::Connectivity::NetworkInformation::NetworkStatusChanged(g_networkStatusChangedToken); | |
| Wh_Log(L"Unregistered global network status change handler"); | |
| } catch(winrt::hresult_error const& ex) { | |
| Wh_Log(L"Error unregistering network status handler %08X: %s", ex.code(), ex.message().c_str()); | |
| } | |
| g_networkStatusChangedToken = {}; | |
| } | |
| // Clear the dispatcher registry. | |
| { | |
| std::lock_guard<std::mutex> lock(g_failedImageBrushesRegistryMutex); | |
| g_failedImageBrushesRegistry.clear(); | |
| } | |
| } | |
| void Wh_ModSettingsChanged() { | |
| Wh_Log(L">"); | |
| UninitializeSettingsAndTap(); | |
| LoadSettings(); | |
| bool initialize = false; | |
| HWND hTaskbarUiWnd = GetTaskbarUiWnd(); | |
| if(hTaskbarUiWnd) { | |
| Wh_Log(L"Reinitializing - Found DesktopWindowContentBridge window"); | |
| RunFromWindowThread( | |
| hTaskbarUiWnd, | |
| [](PVOID) { | |
| UninitializeForCurrentThread(); | |
| InitializeForCurrentThread(); | |
| }, | |
| nullptr); | |
| initialize = true; | |
| } | |
| for(HWND hXamlHostWnd : GetXamlHostWnds()) { | |
| Wh_Log(L"Reinitializing for %08X", (DWORD)(ULONG_PTR)hXamlHostWnd); | |
| RunFromWindowThread( | |
| hXamlHostWnd, | |
| [](PVOID) { | |
| UninitializeForCurrentThread(); | |
| InitializeForCurrentThread(); | |
| }, | |
| nullptr); | |
| initialize = true; | |
| } | |
| if(initialize) { InitializeSettingsAndTap(); } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment