8000 Implemented Application.ThemeMode and Window.ThemeMode properties by dipeshmsft · Pull Request #9436 · dotnet/wpf · GitHub
[go: up one dir, main page]

Skip to content

Implemented Application.ThemeMode and Window.ThemeMode properties #9436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,34 +50,6 @@ CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVi
CannotChangeAttribute : Attribute 'System.Windows.LocalizabilityAttribute' on 'System.Windows.Style.TargetType' changed from '[LocalizabilityAttribute(17)]' in the contract to '[LocalizabilityAttribute(LocalizationCategory.NeverLocalize)]' in the implementation.
CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVisibilityAttribute' on 'System.Windows.Style.Triggers' changed from '[DesignerSerializationVisibilityAttribute(2)]' in the contract to '[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]' in the implementation.
CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Windows.StyleTypedPropertyAttribute' changed from '[AttributeUsageAttribute(4, AllowMultiple=true)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple=true)]' in the implementation.
MembersMustExist : Member 'public System.Windows.Media.Color System.Windows.SystemColors.AccentColor.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.SolidColorBrush System.Windows.SystemColors.AccentColorBrush.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorBrushKey.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.Color System.Windows.SystemColors.AccentColorDark1.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.SolidColorBrush System.Windows.SystemColors.AccentColorDark1Brush.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorDark1BrushKey.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorDark1Key.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.Color System.Windows.SystemColors.AccentColorDark2.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.SolidColorBrush System.Windows.SystemColors.AccentColorDark2Brush.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorDark2BrushKey.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorDark2Key.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.Color System.Windows.SystemColors.AccentColorDark3.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.SolidColorBrush System.Windows.SystemColors.AccentColorDark3Brush.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorDark3BrushKey.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorDark3Key.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorKey.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.Color System.Windows.SystemColors.AccentColorLight1.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.SolidColorBrush System.Windows.SystemColors.AccentColorLight1Brush.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorLight1BrushKey.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorLight1Key.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.Color System.Windows.SystemColors.AccentColorLight2.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.SolidColorBrush System.Windows.SystemColors.AccentColorLight2Brush.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorLight2BrushKey.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorLight2Key.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.Color System.Windows.SystemColors.AccentColorLight3.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.Media.SolidColorBrush System.Windows.SystemColors.AccentColorLight3Brush.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorLight3BrushKey.get()' does not exist in the implementation but it does exist in the contract.
MembersMustExist : Member 'public System.Windows.ResourceKey System.Windows.SystemColors.AccentColorLight3Key.get()' does not exist in the implementation but it does exist in the contract.
CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Windows.TemplatePartAttribute' changed from '[AttributeUsageAttribute(4, AllowMultiple=true)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple=true)]' in the implementation.
CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Windows.TemplateVisualStateAttribute' changed from '[AttributeUsageAttribute(4, AllowMultiple=true)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple=true)]' in the implementation.
CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'System.Windows.ThemeInfoAttribute' changed from '[AttributeUsageAttribute(1)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Assembly)]' in the implementation.
Expand Down Expand Up @@ -290,4 +262,4 @@ CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVi
CannotChangeAttribute : Attribute 'System.Windows.Markup.DesignerSerializationOptionsAttribute' on 'System.Windows.Markup.XmlAttributeProperties.GetXmlSpace(System.Windows.DependencyObject)' changed from '[DesignerSerializationOptionsAttribute(1)]' in the contract to '[DesignerSerializationOptionsAttribute(DesignerSerializationOptions.SerializeAsAttribute)]' in the implementation.
CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerSerializationVisibilityAttribute' on 'System.Windows.Media.Animation.Storyboard.GetTarget(System.Windows.DependencyObject)' changed from '[DesignerSerializationVisibilityAttribute(0)]' in the contract to '[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]' in the implementation.
CannotChangeAttribute : Attribute 'System.Windows.LocalizabilityAttribute' on 'System.Windows.Shapes.Shape' changed from '[LocalizabilityAttribute(0, Readability=0)]' in the contract to '[LocalizabilityAttribute(LocalizationCategory.None, Readability=Readability.Unreadable)]' in the implementation.
Total Issues: 291
Total Issues: 263
2 changes: 1 addition & 1 deletion src/Microsoft.DotNet.Wpf/Directory.Build.Props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
<PropertyGroup>
<NoWarn>$(NoWarn);CA1420</NoWarn>
<NoWarn>$(NoWarn);CA1420;WPF0001</NoWarn>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,9 @@
<Compile Include="System\Windows\TemplateVisualStateAttribute.cs" />
<Compile Include="System\Windows\TextPanelProperties.cs" />
<Compile Include="System\Windows\ThemeManager.cs" />
<Compile Include="System\Windows\FluentThemeState.cs" />
<Compile Include="System\Windows\ThemeMode.cs" />
<Compile Include="System\Windows\ThemeModeConverter.cs" />
<Compile Include="System\Windows\ThemeDictionaryExtension.cs" />
<Compile Include="System\Windows\ThemeInfoAttribute.cs" />
<Compile Include="System\Windows\Thickness.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ internal static bool SetBackdrop(Window window, WindowBackdropType backdropType)
return false;
}

if(!ThemeManager.IsFluentThemeEnabled && window.ThemeMode == ThemeMode.None)
{
return false;
}

var handle = new WindowInteropHelper(window).Handle;
if (handle == IntPtr.Zero)
{
Expand Down Expand Up @@ -133,7 +138,6 @@ private static bool UpdateGlassFrame(IntPtr hwnd, WindowBackdropType backdropTyp
#region Internal Properties

internal static bool IsBackdropEnabled => _isBackdropEnabled ??= Utility.IsWindows11_22H2OrNewer &&
ThemeManager.IsFluentThemeEnabled &&
!FrameworkAppContextSwitches.DisableFluentThemeWindowBackdrop;

private static bool? _isBackdropEnabled = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
//warnings 1634 and 1691. (From PreSharp Documentation)
#pragma warning disable 1634, 1691

using System;

using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
Expand Down Expand Up @@ -56,6 +58,7 @@
using MS.Win32;
using Microsoft.Win32;
using MS.Internal.Telemetry.PresentationFramework;
using System.Diagnostics.CodeAnalysis;

using PackUriHelper = System.IO.Packaging.PackUriHelper;

Expand Down Expand Up @@ -929,6 +932,16 @@ public ResourceDictionary Resources
oldValue.RemoveOwner(this);
}

if(ThemeManager.DeferredAppThemeLoading && !_resourcesInitialized)
{
if(value != null)
{
var uri = ThemeManager.GetThemeResource(ThemeMode);
value.MergedDictionaries.Insert(0, new ResourceDictionary() { Source = uri });
}
ThemeManager.DeferredAppThemeLoading = false;
}

if (value != null)
{
if (!value.ContainsOwner(this))
Expand Down Expand Up @@ -956,6 +969,38 @@ ResourceDictionary IHaveResources.Resources
set { Resources = value; }
}

[Experimental("WPF0001")]
[TypeConverter(typeof(ThemeModeConverter))]
public ThemeMode ThemeMode
{
get
{
return _themeMode;
}
set
{
VerifyAccess();
if (!ThemeManager.IsValidThemeMode(value))
{
throw new ArgumentException(string.Format("ThemeMode value {0} is invalid. Use None, System, Light or Dark", value));
}

ThemeMode oldValue = _themeMode;
_themeMode = value;

if(!_resourcesInitialized)
{
// If the resources are not initializd,
// fluent dictionary included will be reset.
// Hence, deferring the step.
ThemeManager.DeferredAppThemeLoading = true;
return;
}

ThemeManager.OnApplicationThemeChanged(oldValue, value);
}
}

bool IQueryAmbient.IsAmbientPropertyAvailable(string propertyName)
{
// We want to make sure that StaticResource resolution checks the .Resources
Expand Down Expand Up @@ -1687,6 +1732,16 @@ internal int RunInternal(Window window)

internal void InvalidateResourceReferences(ResourcesChangeInfo info)
{
_resourcesInitialized = true;

if(!ThemeManager.IgnoreAppResourcesChange)
{
if(ThemeManager.SyncThemeModeAndResources())
{
return;
}
}

// Invalidate ResourceReference properties on all the windows.
// we Clone() the collection b/c if we don't then some other thread can be
// modifying the collection while we iterate over it
Expand Down Expand Up @@ -2428,6 +2483,9 @@ private object RunDispatcher(object ignore)
private bool _ownDispatcherStarted;
private NavigationService _navService;

private ThemeMode _themeMode = ThemeMode.None;
private bool _resourcesInitialized = false;

private SecurityCriticalDataForSet<MimeType> _appMimeType;
private IServiceProvider _serviceProvider;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using System.ComponentModel;

using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Media;
using System.Security;
using MS.Internal;
using MS.Utility;
using System.Diagnostics.CodeAnalysis;

namespace System.Windows
{
internal readonly struct FluentThemeState : IEquatable<FluentThemeState>
{

public FluentThemeState(string themeName, bool useLightColors, Color accentColor)
{
_themeName = themeName;
_useLightColors = useLightColors;
_accentColor = accentColor;
}

public FluentThemeState(string themeName, bool useLightColors)
{
_themeName = themeName;
_useLightColors = useLightColors;
_accentColor = SystemColors.AccentColor;
}

public string ThemeName => _themeName;
public bool UseLightColors => _useLightColors;
public Color AccentColor => _accentColor;

private readonly string _themeName;
private readonly bool _useLightColors;
private readonly Color _accentColor;


public bool Equals(FluentThemeState other)
{
return string.Equals(ThemeName, other.ThemeName, StringComparison.Ordinal) &&
UseLightColors == other.UseLightColors &&
AccentColor == other.AccentColor;
}

public override bool Equals(object obj)
{
return obj is FluentThemeState other && Equals(other);
}

public static bool operator ==(FluentThemeState left, FluentThemeState right)
{
return left.Equals(right);
}

public static bool operator !=(FluentThemeState left, FluentThemeState right)
{
return !left.Equals(right);
}

public override int GetHashCode()
{
return StringComparer.Ordinal.GetHashCode(ToString());
}


public override string ToString()
{
return $"ThemeName: {ThemeName}, UseLightColors: {UseLightColors}, AccentColor: {AccentColor}";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2632,11 +2632,12 @@ public static HRESULT DwmSetWindowAttributeSystemBackdropType(IntPtr hwnd, DWMSB
}

[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public static HRESULT DwmSetWindowAttributeUseImmersiveDarkMode(IntPtr hwnd, bool useImmersiveDarkMode)
public static bool DwmSetWindowAttributeUseImmersiveDarkMode(IntPtr hwnd, bool useImmersiveDarkMode)
{
Assert.IsTrue(Utility.IsWindows11_22H2OrNewer);
var pvAttribute = useImmersiveDarkMode ? 0x1 : 0x0;
return _DwmSetWindowAttribute(hwnd, DWMWA.USE_IMMERSIVE_DARK_MODE, ref pvAttribute, Marshal.SizeOf(typeof(int)));
var dwmResult = _DwmSetWindowAttribute(hwnd, DWMWA.USE_IMMERSIVE_DARK_MODE, ref pvAttribute, Marshal.SizeOf(typeof(int)));
return dwmResult == HRESULT.S_OK;
}

[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1413,9 +1413,9 @@ private static IntPtr SystemThemeFilterMessage(IntPtr hwnd, int msg, IntPtr wPar

SystemParameters.InvalidateWindowFrameThicknessProperties();

if(ThemeManager.IsFluentThemeEnabled)
if(ThemeManager.IsFluentThemeEnabled || ThemeManager.FluentEnabledWindows.Count > 0)
{
ThemeManager.ApplySystemTheme();
ThemeManager.OnSystemThemeChanged();
}
break;

Expand Down
Loading
Loading
0