mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
Immersive dark mode + Theme Listener (#18315)
* C++ impl of immersive dark mode * Stop using the hardcoded value. * Conjured up theme listener based on registry. * Update MainWindow.xaml.cpp * Update expect.txt * Moved themehelpers to the common themes lib. * Ported theme helpers back to .NET * Update expect.txt * Updated C# Theme Listening logic to mimic the one from Windows Community Toolkit. * Replaced unmanaged code for RegisterForImmersiveDarkMode with unmanaged ThemeListener class. * Fix upstream changes * Update ThemeListener.h * Update ThemeListener.h * Proper formatting * Added handler to Keyboard Manager. * Update EditKeyboardWindow.cpp * Added dwmapi.lib to runner, removed condition from additional dependencies. * Update PowerRenameUI.vcxproj * Added new deps for ManagedCommon to Product.wxs * Crude attempts and understanding installer * Removed Microsoft.Win32.Registry.dll from product.wxs. * Updated dictionary * Renamed ThemeListener class file for consistency, removed unused CheckImmersiveDarkMode in theme_helpers. * Update Themes.vcxproj * Update theme_listener.cpp * Removed SupportsImmersiveDarkMode version check * Removed SupportsImmersiveDarkMode version check * Whoops * Update expect.txt
This commit is contained in:
@@ -15,7 +15,6 @@ using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Windows.UI.Popups;
|
||||
using Windows.UI.ViewManagement;
|
||||
using WinRT.Interop;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI
|
||||
@@ -73,7 +72,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
{
|
||||
if (settingsWindow == null)
|
||||
{
|
||||
settingsWindow = new MainWindow();
|
||||
settingsWindow = new MainWindow(IsDarkTheme());
|
||||
}
|
||||
|
||||
settingsWindow.Activate();
|
||||
@@ -88,6 +87,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
|
||||
{
|
||||
var cmdArgs = Environment.GetCommandLineArgs();
|
||||
var isDark = IsDarkTheme();
|
||||
|
||||
if (cmdArgs != null && cmdArgs.Length >= RequiredArgumentsQty)
|
||||
{
|
||||
@@ -143,7 +143,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
|
||||
if (!ShowOobe && !ShowScoobe)
|
||||
{
|
||||
settingsWindow = new MainWindow();
|
||||
settingsWindow = new MainWindow(isDark);
|
||||
settingsWindow.Activate();
|
||||
settingsWindow.NavigateToSection(StartupPage);
|
||||
}
|
||||
@@ -152,19 +152,19 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
// Create the Settings window hidden so that it's fully initialized and
|
||||
// it will be ready to receive the notification if the user opens
|
||||
// the Settings from the tray icon.
|
||||
settingsWindow = new MainWindow(true);
|
||||
settingsWindow = new MainWindow(isDark, true);
|
||||
|
||||
if (ShowOobe)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent());
|
||||
OobeWindow oobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.Overview);
|
||||
OobeWindow oobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.Overview, isDark);
|
||||
oobeWindow.Activate();
|
||||
SetOobeWindow(oobeWindow);
|
||||
}
|
||||
else if (ShowScoobe)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new ScoobeStartedEvent());
|
||||
OobeWindow scoobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.WhatsNew);
|
||||
OobeWindow scoobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.WhatsNew, isDark);
|
||||
scoobeWindow.Activate();
|
||||
SetOobeWindow(scoobeWindow);
|
||||
}
|
||||
@@ -174,7 +174,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
{
|
||||
// For debugging purposes
|
||||
// Window is also needed to show MessageDialog
|
||||
settingsWindow = new MainWindow();
|
||||
settingsWindow = new MainWindow(isDark);
|
||||
settingsWindow.Activate();
|
||||
ShowMessageDialog("The application cannot be run as a standalone process. Please start the application through the runner.", "Forbidden");
|
||||
}
|
||||
@@ -203,18 +203,50 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
return ipcmanager;
|
||||
}
|
||||
|
||||
public static string SelectedTheme()
|
||||
{
|
||||
return SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpper(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static bool IsDarkTheme()
|
||||
{
|
||||
var selectedTheme = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpper(CultureInfo.InvariantCulture);
|
||||
var defaultTheme = new UISettings();
|
||||
var uiTheme = defaultTheme.GetColorValue(UIColorType.Background).ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
return selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && uiTheme == "#FF000000");
|
||||
var selectedTheme = SelectedTheme();
|
||||
return selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && ThemeHelpers.GetAppTheme() == AppTheme.Dark);
|
||||
}
|
||||
|
||||
public static void HandleThemeChange()
|
||||
{
|
||||
var isDark = IsDarkTheme();
|
||||
if (settingsWindow != null)
|
||||
{
|
||||
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(settingsWindow);
|
||||
ThemeHelpers.SetImmersiveDarkMode(hWnd, isDark);
|
||||
}
|
||||
|
||||
if (oobeWindow != null)
|
||||
{
|
||||
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(oobeWindow);
|
||||
ThemeHelpers.SetImmersiveDarkMode(hWnd, isDark);
|
||||
}
|
||||
|
||||
var selectedTheme = SelectedTheme();
|
||||
if (selectedTheme == "SYSTEM")
|
||||
{
|
||||
themeListener = new ThemeListener();
|
||||
themeListener.ThemeChanged += (_) => HandleThemeChange();
|
||||
}
|
||||
else if (themeListener != null)
|
||||
{
|
||||
themeListener.Dispose();
|
||||
themeListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static ISettingsUtils settingsUtils = new SettingsUtils();
|
||||
|
||||
private static MainWindow settingsWindow;
|
||||
private static OobeWindow oobeWindow;
|
||||
private static ThemeListener themeListener;
|
||||
|
||||
public static void ClearSettingsWindow()
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerLauncher.Telemetry;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
||||
@@ -22,7 +22,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
/// </summary>
|
||||
public sealed partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow(bool createHidden = false)
|
||||
public MainWindow(bool isDark, bool createHidden = false)
|
||||
{
|
||||
var bootTime = new System.Diagnostics.Stopwatch();
|
||||
bootTime.Start();
|
||||
@@ -36,6 +36,12 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
AppWindow appWindow = AppWindow.GetFromWindowId(windowId);
|
||||
appWindow.SetIcon("icon.ico");
|
||||
|
||||
// Passed by parameter, as it needs to be evaluated ASAP, otherwise there is a white flash
|
||||
if (isDark)
|
||||
{
|
||||
ThemeHelpers.SetImmersiveDarkMode(hWnd, isDark);
|
||||
}
|
||||
|
||||
var placement = Utils.DeserializePlacementOrDefault(hWnd);
|
||||
if (createHidden)
|
||||
{
|
||||
@@ -72,7 +78,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
{
|
||||
if (App.GetOobeWindow() == null)
|
||||
{
|
||||
App.SetOobeWindow(new OobeWindow(Microsoft.PowerToys.Settings.UI.OOBE.Enums.PowerToysModules.Overview));
|
||||
App.SetOobeWindow(new OobeWindow(Microsoft.PowerToys.Settings.UI.OOBE.Enums.PowerToysModules.Overview, App.IsDarkTheme()));
|
||||
}
|
||||
|
||||
App.GetOobeWindow().Activate();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using interop;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
|
||||
using Microsoft.PowerToys.Settings.UI.OOBE.Views;
|
||||
@@ -30,7 +31,7 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
private IntPtr _hWnd;
|
||||
private AppWindow _appWindow;
|
||||
|
||||
public OobeWindow(PowerToysModules initialModule)
|
||||
public OobeWindow(PowerToysModules initialModule, bool isDark)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
@@ -40,6 +41,12 @@ namespace Microsoft.PowerToys.Settings.UI
|
||||
_appWindow = AppWindow.GetFromWindowId(_windowId);
|
||||
_appWindow.SetIcon("icon.ico");
|
||||
|
||||
// Passed by parameter, as it needs to be evaluated ASAP, otherwise there is a white flash
|
||||
if (isDark)
|
||||
{
|
||||
ThemeHelpers.SetImmersiveDarkMode(_hWnd, isDark);
|
||||
}
|
||||
|
||||
OverlappedPresenter presenter = _appWindow.Presenter as OverlappedPresenter;
|
||||
presenter.IsMinimizable = false;
|
||||
presenter.IsMaximizable = false;
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
break;
|
||||
}
|
||||
|
||||
App.HandleThemeChange();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user