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:
William Bradley
2022-07-01 21:52:48 +12:00
committed by GitHub
parent e637902892
commit b7fccc3211
22 changed files with 393 additions and 78 deletions

View File

@@ -147,7 +147,6 @@ betadele
betsegaw betsegaw
BGR BGR
bgra bgra
BGSOUNDS
bhid bhid
Bicubic Bicubic
bigbar bigbar
@@ -245,7 +244,6 @@ CLASSNOTAVAILABLE
clickable clickable
clickonce clickonce
CLIENTEDGE CLIENTEDGE
CLIENTPULL
clientside clientside
CLIPCHILDREN CLIPCHILDREN
Clipperton Clipperton
@@ -452,19 +450,14 @@ dimm
directshow directshow
dirs dirs
DISABLEASACTIONKEY DISABLEASACTIONKEY
dispid
DISPIDAMBIENTDLCONTROL
DISPLAYCHANGE DISPLAYCHANGE
DISPLAYCONFIG DISPLAYCONFIG
displayname displayname
divyan divyan
DLACTIVEXCTLS
DLCONTROL
Dlg Dlg
DLGFRAME DLGFRAME
DLGMODALFRAME DLGMODALFRAME
dlib dlib
DLIMAGES
dllexport dllexport
dllhost dllhost
dllimport dllimport
@@ -476,7 +469,6 @@ doctype
DONOTROUND DONOTROUND
DONTVALIDATEPATH DONTVALIDATEPATH
dotnet dotnet
DOWNLOADONLY
DPICHANGED DPICHANGED
DPIs DPIs
DPolicy DPolicy
@@ -536,6 +528,7 @@ Emoji
emptyrecyclebin emptyrecyclebin
ENABLEDPOPUP ENABLEDPOPUP
endforeach endforeach
endian
endif endif
endl endl
endpointvolume endpointvolume
@@ -547,7 +540,6 @@ enum
EOAC EOAC
eol eol
epicgames epicgames
epo
Eqn Eqn
ERASEBKGND ERASEBKGND
EREOF EREOF
@@ -595,7 +587,6 @@ fallthrough
fancyzones fancyzones
FANCYZONESDRAWLAYOUTTEST FANCYZONESDRAWLAYOUTTEST
FANCYZONESEDITOR FANCYZONESEDITOR
FANCYZONESWINDOWSTYLES
Farbraum Farbraum
Faroe Faroe
FARPROC FARPROC
@@ -634,11 +625,9 @@ FOFX
FOLDERID FOLDERID
folderpath folderpath
FORCEMINIMIZE FORCEMINIMIZE
FORCEOFFLINE
foreach foreach
formatetc formatetc
FRAMECHANGED FRAMECHANGED
FRAMEDOWNLOAD
franky franky
frankychen frankychen
Froml Froml
@@ -681,7 +670,6 @@ globals
GNumber GNumber
google google
GPTR GPTR
gsuberland
gtm gtm
gui gui
guiddef guiddef
@@ -718,7 +706,6 @@ helptext
Heure Heure
HEVC HEVC
hfile hfile
HFONT
hglobal hglobal
hhk hhk
HHmmss HHmmss
@@ -778,8 +765,8 @@ hstring
hsv hsv
htcfreek htcfreek
HTHUMBNAIL HTHUMBNAIL
Htmdid
HTTRANSPARENT HTTRANSPARENT
HValue
Hvci Hvci
hwb hwb
HWINEVENTHOOK HWINEVENTHOOK
@@ -813,10 +800,8 @@ ICompositor
ICONERROR ICONERROR
IContext IContext
ICONWARNING ICONWARNING
ICore
ICreate ICreate
IData IData
IDCANCEL
IDD IDD
IDelayed IDelayed
IDesktop IDesktop
@@ -827,7 +812,6 @@ IDispatcher
IDisposable IDisposable
idl idl
IDLIST IDLIST
IDOK
IDOn IDOn
IDR IDR
IDrive IDrive
@@ -895,7 +879,6 @@ INFOEXAMPLE
Infotip Infotip
ingbuffer ingbuffer
inheritdoc inheritdoc
INITDIALOG
initguid initguid
Inkscape Inkscape
Inlines Inlines
@@ -958,7 +941,6 @@ IPublic
IQuery IQuery
IRead IRead
IReference IReference
IReflect
IRegistered IRegistered
IRegistration IRegistration
IRegistry IRegistry
@@ -1006,9 +988,7 @@ IWbem
IWeb IWeb
IWIC IWIC
iwindow iwindow
IWindows
IWork IWork
IXaml
IXml IXml
IYUV IYUV
IZone IZone
@@ -1066,7 +1046,6 @@ Kyrgyzstan
Kyzylorda Kyzylorda
LAlt LAlt
Lambson Lambson
lamotile
langword langword
Lastdevice Lastdevice
Latn Latn
@@ -1153,6 +1132,7 @@ LPSAFEARRAY
LPSTR LPSTR
lpsz lpsz
lpt lpt
LPTHREAD
LPTOP LPTOP
lptpm lptpm
LPTSTR LPTSTR
@@ -1225,7 +1205,6 @@ MENUBREAK
MENUITEMINFO MENUITEMINFO
MENUITEMINFOW MENUITEMINFOW
messageboxes messageboxes
METACHARSET
Metadatas Metadatas
metafile metafile
mfapi mfapi
@@ -1252,7 +1231,6 @@ miniz
minlevel minlevel
MINORVERSION MINORVERSION
Miracast Miracast
mirophone
Mishkeegogamang Mishkeegogamang
mjpg mjpg
mkd mkd
@@ -1296,7 +1274,6 @@ msdata
MSDN MSDN
msedge msedge
MSGFLT MSGFLT
mshtmdid
MSIFASTINSTALL MSIFASTINSTALL
MSIHANDLE MSIHANDLE
msiquery msiquery
@@ -1362,10 +1339,8 @@ netcore
netcoreapp netcoreapp
netcpl netcpl
netframework netframework
NETFX
netsetup netsetup
netsh netsh
netstandard
Neue Neue
newcolor newcolor
newdev newdev
@@ -1443,7 +1418,6 @@ NUMLOCK
NUMPAD NUMPAD
Nunavut Nunavut
Nusa Nusa
Nvidia
nwc nwc
NWSE NWSE
Objbase Objbase
@@ -1483,6 +1457,7 @@ ostream
ostringstream ostringstream
OSVERSIONINFOEX OSVERSIONINFOEX
OSVERSIONINFOEXW OSVERSIONINFOEXW
OSVERSIONINFOW
osvi osvi
otating otating
OUTOFCONTEXT OUTOFCONTEXT
@@ -1566,7 +1541,6 @@ Pohnpei
popup popup
POPUPWINDOW POPUPWINDOW
posix posix
Postion
powercfg powercfg
powerlauncher powerlauncher
powerpreview powerpreview
@@ -1596,7 +1570,6 @@ Prefixer
Preinstalled Preinstalled
preload preload
PREMULTIPLIED PREMULTIPLIED
preperty
prevhost prevhost
previewer previewer
PREVIEWHANDLERFRAMEINFO PREVIEWHANDLERFRAMEINFO
@@ -1623,6 +1596,7 @@ PROPBAG
PROPERTYKEY PROPERTYKEY
propkey propkey
propvarutil propvarutil
PRTL
prvpane prvpane
psapi psapi
PSECURITY PSECURITY
@@ -1824,7 +1798,6 @@ SENDCHANGE
sendvirtualinput sendvirtualinput
serializationexception serializationexception
serializer serializer
serizalization
serverside serverside
SETCONTEXT SETCONTEXT
setcursor setcursor
@@ -1839,8 +1812,6 @@ SETTEXT
SETTINGCHANGE SETTINGCHANGE
settingsheader settingsheader
settingshotkeycontrol settingshotkeycontrol
settingsv
Setttings
SETWORKAREA SETWORKAREA
sfgao sfgao
SFGAOF SFGAOF
@@ -1920,7 +1891,6 @@ somil
Soref Soref
SOURCECLIENTAREAONLY SOURCECLIENTAREAONLY
SOURCEHEADER SOURCEHEADER
sourceid
sourcesdirectory sourcesdirectory
spam spam
spdisp spdisp
@@ -2076,7 +2046,6 @@ Tenggara
testcase testcase
testhost testhost
testprocess testprocess
testtrocess
testzones testzones
TEXCOORD TEXCOORD
textblock textblock
@@ -2100,7 +2069,6 @@ TMPVAR
TNP TNP
todo todo
toggleswitch toggleswitch
Toolchain
toolkitcontrols toolkitcontrols
toolkitconverters toolkitconverters
Toolset Toolset
@@ -2227,7 +2195,6 @@ vcruntime
vcvars vcvars
VDesktop VDesktop
vdi vdi
VDId
vec vec
VERBSONLY VERBSONLY
VERBW VERBW
@@ -2385,6 +2352,7 @@ wpf
wpr wpr
wprintf wprintf
wprp wprp
wql
WQL WQL
wregex wregex
WResize WResize
@@ -2410,8 +2378,6 @@ Wwan
Wwanpp Wwanpp
xamarin xamarin
XAttribute XAttribute
xbf
XBind
Xbox Xbox
XBUTTON XBUTTON
XBUTTONDBLCLK XBUTTONDBLCLK
@@ -2422,7 +2388,6 @@ XDocument
XElement XElement
XFile XFile
XIncrement XIncrement
XInstance
XLoc XLoc
XNamespace XNamespace
XOffset XOffset

View File

@@ -25,6 +25,7 @@
<File DestinationPath="modules\Newtonsoft.Json.dll" SourcePath="..\..\x64\Release\modules\Newtonsoft.Json.dll"/> <File DestinationPath="modules\Newtonsoft.Json.dll" SourcePath="..\..\x64\Release\modules\Newtonsoft.Json.dll"/>
<File DestinationPath="modules\PowerKeys.dll" SourcePath="..\..\x64\Release\modules\PowerKeys.dll"/> <File DestinationPath="modules\PowerKeys.dll" SourcePath="..\..\x64\Release\modules\PowerKeys.dll"/>
<File DestinationPath="modules\System.Text.Json.dll" SourcePath="..\..\x64\Release\modules\System.Text.Json.dll"/> <File DestinationPath="modules\System.Text.Json.dll" SourcePath="..\..\x64\Release\modules\System.Text.Json.dll"/>
<File DestinationPath="modules\System.Management.dll" SourcePath="..\..\x64\Release\modules\System.Management.dll"/>
<File DestinationPath="modules\System.Memory.dll" SourcePath="..\..\x64\Release\modules\System.Memory.dll"/> <File DestinationPath="modules\System.Memory.dll" SourcePath="..\..\x64\Release\modules\System.Memory.dll"/>
<File DestinationPath="modules\System.Buffers.dll" SourcePath="..\..\x64\Release\modules\System.Buffers.dll"/> <File DestinationPath="modules\System.Buffers.dll" SourcePath="..\..\x64\Release\modules\System.Buffers.dll"/>
<File DestinationPath="modules\System.Runtime.CompilerServices.Unsafe.dll" SourcePath="..\..\x64\Release\modules\System.Runtime.CompilerServices.Unsafe.dll"/> <File DestinationPath="modules\System.Runtime.CompilerServices.Unsafe.dll" SourcePath="..\..\x64\Release\modules\System.Runtime.CompilerServices.Unsafe.dll"/>
@@ -33,6 +34,7 @@
<File DestinationPath="modules\System.ValueTuple.dll" SourcePath="..\..\x64\Release\modules\System.ValueTuple.dll"/> <File DestinationPath="modules\System.ValueTuple.dll" SourcePath="..\..\x64\Release\modules\System.ValueTuple.dll"/>
<File DestinationPath="modules\System.Numerics.Vectors.dll" SourcePath="..\..\x64\Release\modules\System.Numerics.Vectors.dll"/> <File DestinationPath="modules\System.Numerics.Vectors.dll" SourcePath="..\..\x64\Release\modules\System.Numerics.Vectors.dll"/>
<File DestinationPath="modules\Microsoft.Bcl.AsyncInterfaces.dll" SourcePath="..\..\x64\Release\modules\Microsoft.Bcl.AsyncInterfaces.dll"/> <File DestinationPath="modules\Microsoft.Bcl.AsyncInterfaces.dll" SourcePath="..\..\x64\Release\modules\Microsoft.Bcl.AsyncInterfaces.dll"/>
<File DestinationPath="modules\Microsoft.Win32.Registry.dll" SourcePath="..\..\x64\Release\modules\Microsoft.Win32.Registry.dll"/>
<File DestinationPath="modules\PowerToys.powerpreview.dll" SourcePath="..\..\x64\Release\modules\PowerToys.powerpreview.dll"/> <File DestinationPath="modules\PowerToys.powerpreview.dll" SourcePath="..\..\x64\Release\modules\PowerToys.powerpreview.dll"/>
<File DestinationPath="modules\PowerToys.PreviewHandlerCommon.dll" SourcePath="..\..\x64\Release\modules\PowerToys.PreviewHandlerCommon.dll"/> <File DestinationPath="modules\PowerToys.PreviewHandlerCommon.dll" SourcePath="..\..\x64\Release\modules\PowerToys.PreviewHandlerCommon.dll"/>
<File DestinationPath="modules\PowerToys.SvgPreviewHandler.dll" SourcePath="..\..\x64\Release\modules\PowerToys.SvgPreviewHandler.dll"/> <File DestinationPath="modules\PowerToys.SvgPreviewHandler.dll" SourcePath="..\..\x64\Release\modules\PowerToys.SvgPreviewHandler.dll"/>

View File

@@ -40,13 +40,13 @@
--> -->
<?define ShortcutGuideSvgsFiles=0.svg;1.svg;2.svg;3.svg;4.svg;5.svg;6.svg;7.svg;8.svg;9.svg;no_active_window.svg;overlay.svg;overlay_portrait.svg?> <?define ShortcutGuideSvgsFiles=0.svg;1.svg;2.svg;3.svg;4.svg;5.svg;6.svg;7.svg;8.svg;9.svg;no_active_window.svg;overlay.svg;overlay_portrait.svg?>
<?define FancyZonesFiles=PowerToys.FancyZonesModuleInterface.dll;PowerToys.FancyZonesEditor.dll;PowerToys.FancyZonesEditor.runtimeconfig.json;PowerToys.FancyZonesEditor.deps.json;PowerToys.FancyZonesEditor.exe;PowerToys.FancyZones.exe;ControlzEx.dll;Microsoft.Xaml.Behaviors.dll;ModernWpf.dll;ModernWpf.Controls.dll;System.Text.Json.dll;PowerToys.Interop.dll;PowerToys.ManagedCommon.dll;PowerToys.Common.UI.dll;PowerToys.ManagedTelemetry.dll;System.IO.Abstractions.dll;Microsoft.Windows.SDK.NET.dll;WinRT.Runtime.dll;Ijwhost.dll?> <?define FancyZonesFiles=PowerToys.FancyZonesModuleInterface.dll;PowerToys.FancyZonesEditor.dll;PowerToys.FancyZonesEditor.runtimeconfig.json;PowerToys.FancyZonesEditor.deps.json;PowerToys.FancyZonesEditor.exe;PowerToys.FancyZones.exe;ControlzEx.dll;Microsoft.Xaml.Behaviors.dll;ModernWpf.dll;ModernWpf.Controls.dll;System.Text.Json.dll;PowerToys.Interop.dll;PowerToys.ManagedCommon.dll;System.Management.dll;PowerToys.Common.UI.dll;PowerToys.ManagedTelemetry.dll;System.IO.Abstractions.dll;Microsoft.Windows.SDK.NET.dll;WinRT.Runtime.dll;Ijwhost.dll?>
<?define ImageResizerFiles=ImageResizer.ico;PowerToys.ImageResizer.exe;PowerToys.ImageResizerExt.dll;PowerToys.ImageResizer.dll;PowerToys.ImageResizer.deps.json;PowerToys.ImageResizer.runtimeconfig.json;PowerToys.ManagedCommon.dll;PowerToys.ManagedTelemetry.dll;PowerToys.Common.UI.dll;ControlzEx.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.Text.Json.dll;Microsoft.Xaml.Behaviors.dll;PowerToys.Interop.dll;System.IO.Abstractions.dll;WinRT.Runtime.dll;Microsoft.Windows.SDK.NET.dll;Ijwhost.dll;ImageResizerContextMenuPackage.msix;PowerToys.ImageResizerContextMenu.dll ?> <?define ImageResizerFiles=ImageResizer.ico;PowerToys.ImageResizer.exe;PowerToys.ImageResizerExt.dll;PowerToys.ImageResizer.dll;PowerToys.ImageResizer.deps.json;PowerToys.ImageResizer.runtimeconfig.json;PowerToys.ManagedCommon.dll;System.Management.dll;PowerToys.ManagedTelemetry.dll;PowerToys.Common.UI.dll;ControlzEx.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.Text.Json.dll;Microsoft.Xaml.Behaviors.dll;PowerToys.Interop.dll;System.IO.Abstractions.dll;WinRT.Runtime.dll;Microsoft.Windows.SDK.NET.dll;Ijwhost.dll;ImageResizerContextMenuPackage.msix;PowerToys.ImageResizerContextMenu.dll ?>
<?define PowerPreviewFiles=PowerToys.powerpreview.dll;PowerToys.PreviewHandlerCommon.dll;PowerToys.PreviewHandlerCommon.deps.json;PowerToys.ManagedCommon.dll;PowerToys.ManagedTelemetry.dll;PowerToys.SvgPreviewHandler.dll;PowerToys.SvgPreviewHandler.comhost.dll;PowerToys.SvgPreviewHandler.runtimeconfig.json;PowerToys.SvgPreviewHandler.deps.json;PowerToys.SvgThumbnailProvider.dll;PowerToys.SvgThumbnailProvider.comhost.dll;PowerToys.SvgThumbnailProvider.runtimeconfig.json;PowerToys.SvgThumbnailProvider.deps.json;PowerToys.MarkdownPreviewHandler.dll;PowerToys.MarkdownPreviewHandler.comhost.dll;PowerToys.MarkdownPreviewHandler.runtimeconfig.json;PowerToys.MarkdownPreviewHandler.deps.json;Markdig.Signed.dll;HtmlAgilityPack.dll;System.IO.Abstractions.dll;monaco_languages.json;monacoSpecialLanguages.js;PowerToys.Common.UI.dll;PowerToys.Settings.UI.Lib.dll;PowerToys.MonacoPreviewHandler.dll;PowerToys.MonacoPreviewHandler.comhost.dll;PowerToys.MonacoPreviewHandler.runtimeconfig.json;PowerToys.MonacoPreviewHandler.deps.json;ControlzEx.dll;Microsoft.Web.WebView2.Core.dll;Microsoft.Web.WebView2.WinForms.dll;Microsoft.Web.WebView2.Wpf.dll;WebView2Loader.dll;System.Runtime.WindowsRuntime.dll;index.html;PowerToys.PdfPreviewHandler.dll;PowerToys.PdfPreviewHandler.comhost.dll;PowerToys.PdfPreviewHandler.runtimeconfig.json;PowerToys.PdfPreviewHandler.deps.json;Microsoft.Windows.SDK.NET.dll;WinRT.Runtime.dll;PowerToys.PdfThumbnailProvider.dll;PowerToys.PdfThumbnailProvider.comhost.dll;PowerToys.PdfThumbnailProvider.runtimeconfig.json;PowerToys.PdfThumbnailProvider.deps.json;PowerToys.GcodePreviewHandler.dll;PowerToys.GcodePreviewHandler.comhost.dll;PowerToys.GcodePreviewHandler.runtimeconfig.json;PowerToys.GcodePreviewHandler.deps.json;PowerToys.GcodeThumbnailProvider.dll;PowerToys.GcodeThumbnailProvider.comhost.dll;PowerToys.GcodeThumbnailProvider.runtimeconfig.json;PowerToys.GcodeThumbnailProvider.deps.json;PowerToys.StlThumbnailProvider.dll;PowerToys.StlThumbnailProvider.comhost.dll;PowerToys.StlThumbnailProvider.runtimeconfig.json;PowerToys.StlThumbnailProvider.deps.json;HelixToolkit.dll;HelixToolkit.Core.Wpf.dll;Ijwhost.dll;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll?> <?define PowerPreviewFiles=PowerToys.powerpreview.dll;PowerToys.PreviewHandlerCommon.dll;PowerToys.PreviewHandlerCommon.deps.json;PowerToys.ManagedCommon.dll;System.Management.dll;PowerToys.ManagedTelemetry.dll;PowerToys.SvgPreviewHandler.dll;PowerToys.SvgPreviewHandler.comhost.dll;PowerToys.SvgPreviewHandler.runtimeconfig.json;PowerToys.SvgPreviewHandler.deps.json;PowerToys.SvgThumbnailProvider.dll;PowerToys.SvgThumbnailProvider.comhost.dll;PowerToys.SvgThumbnailProvider.runtimeconfig.json;PowerToys.SvgThumbnailProvider.deps.json;PowerToys.MarkdownPreviewHandler.dll;PowerToys.MarkdownPreviewHandler.comhost.dll;PowerToys.MarkdownPreviewHandler.runtimeconfig.json;PowerToys.MarkdownPreviewHandler.deps.json;Markdig.Signed.dll;HtmlAgilityPack.dll;System.IO.Abstractions.dll;monaco_languages.json;monacoSpecialLanguages.js;PowerToys.Common.UI.dll;PowerToys.Settings.UI.Lib.dll;PowerToys.MonacoPreviewHandler.dll;PowerToys.MonacoPreviewHandler.comhost.dll;PowerToys.MonacoPreviewHandler.runtimeconfig.json;PowerToys.MonacoPreviewHandler.deps.json;ControlzEx.dll;Microsoft.Web.WebView2.Core.dll;Microsoft.Web.WebView2.WinForms.dll;Microsoft.Web.WebView2.Wpf.dll;WebView2Loader.dll;System.Runtime.WindowsRuntime.dll;index.html;PowerToys.PdfPreviewHandler.dll;PowerToys.PdfPreviewHandler.comhost.dll;PowerToys.PdfPreviewHandler.runtimeconfig.json;PowerToys.PdfPreviewHandler.deps.json;Microsoft.Windows.SDK.NET.dll;WinRT.Runtime.dll;PowerToys.PdfThumbnailProvider.dll;PowerToys.PdfThumbnailProvider.comhost.dll;PowerToys.PdfThumbnailProvider.runtimeconfig.json;PowerToys.PdfThumbnailProvider.deps.json;PowerToys.GcodePreviewHandler.dll;PowerToys.GcodePreviewHandler.comhost.dll;PowerToys.GcodePreviewHandler.runtimeconfig.json;PowerToys.GcodePreviewHandler.deps.json;PowerToys.GcodeThumbnailProvider.dll;PowerToys.GcodeThumbnailProvider.comhost.dll;PowerToys.GcodeThumbnailProvider.runtimeconfig.json;PowerToys.GcodeThumbnailProvider.deps.json;PowerToys.StlThumbnailProvider.dll;PowerToys.StlThumbnailProvider.comhost.dll;PowerToys.StlThumbnailProvider.runtimeconfig.json;PowerToys.StlThumbnailProvider.deps.json;HelixToolkit.dll;HelixToolkit.Core.Wpf.dll;Ijwhost.dll;Microsoft.Xaml.Behaviors.dll;System.Text.Json.dll?>
<?define SettingsV2Files=Ijwhost.dll;ColorCode.Core.dll;ColorCode.WinUI.dll;CommunityToolkit.Common.dll;CommunityToolkit.WinUI.dll;CommunityToolkit.WinUI.UI.Controls.Core.dll;CommunityToolkit.WinUI.UI.Controls.DataGrid.dll;CommunityToolkit.WinUI.UI.Controls.Input.dll;CommunityToolkit.WinUI.UI.Controls.Layout.dll;CommunityToolkit.WinUI.UI.Controls.Markdown.dll;CommunityToolkit.WinUI.UI.Controls.Media.dll;CommunityToolkit.WinUI.UI.Controls.Primitives.dll;CommunityToolkit.WinUI.UI.dll;icon.ico;Microsoft.Graphics.Canvas.Interop.dll;Microsoft.InteractiveExperiences.Projection.dll;Microsoft.Windows.ApplicationModel.DynamicDependency.Projection.dll;Microsoft.Windows.ApplicationModel.Resources.Projection.dll;Microsoft.Windows.ApplicationModel.WindowsAppRuntime.Projection.dll;Microsoft.Windows.AppLifecycle.Projection.dll;Microsoft.Windows.SDK.NET.dll;Microsoft.Windows.System.Power.Projection.dll;Microsoft.WindowsAppRuntime.Bootstrap.Net.dll;Microsoft.WinUI.dll;Microsoft.Xaml.Interactions.dll;Microsoft.Xaml.Interactivity.dll;PowerToys.Interop.dll;PowerToys.ManagedCommon.dll;PowerToys.ManagedTelemetry.dll;PowerToys.Settings.deps.json;PowerToys.Settings.dll;PowerToys.Settings.exe;PowerToys.Settings.runtimeconfig.json;PowerToys.Settings.UI.Lib.dll;resources.pri;System.IO.Abstractions.dll;System.Text.Json.dll;WinRT.Runtime.dll;Microsoft.Graphics.Canvas.dll;Microsoft.WindowsAppRuntime.Bootstrap.dll;CoreMessagingXP.dll;dcompi.dll;dwmcorei.dll;DwmSceneI.dll;DWriteCore.dll;marshal.dll;Microsoft.DirectManipulation.dll;Microsoft.InputStateManager.dll;Microsoft.Internal.FrameworkUdk.dll;Microsoft.UI.Composition.OSSupport.dll;Microsoft.UI.Input.dll;Microsoft.UI.Windowing.Core.dll;Microsoft.UI.Xaml.Controls.dll;Microsoft.UI.Xaml.Controls.pri;Microsoft.ui.xaml.dll;Microsoft.UI.Xaml.Internal.dll;Microsoft.UI.Xaml.Phone.dll;Microsoft.ui.xaml.resources.19h1.dll;Microsoft.ui.xaml.resources.common.dll;Microsoft.Web.WebView2.Core.dll;Microsoft.Windows.ApplicationModel.Resources.dll;Microsoft.Windows.AppNotifications.Projection.dll;Microsoft.Windows.PushNotifications.Projection.dll;Microsoft.Windows.System.Projection.dll;Microsoft.WindowsAppRuntime.dll;Microsoft.WindowsAppRuntime.Insights.Resource.dll;Microsoft.WindowsAppRuntime.Release.Net.dll;MRM.dll;PushNotificationsLongRunningTask.ProxyStub.dll;WindowsAppRuntime.png;WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll;WinUIEdit.dll;wuceffectsi.dll?> <?define SettingsV2Files=Ijwhost.dll;ColorCode.Core.dll;ColorCode.WinUI.dll;CommunityToolkit.Common.dll;CommunityToolkit.WinUI.dll;CommunityToolkit.WinUI.UI.Controls.Core.dll;CommunityToolkit.WinUI.UI.Controls.DataGrid.dll;CommunityToolkit.WinUI.UI.Controls.Input.dll;CommunityToolkit.WinUI.UI.Controls.Layout.dll;CommunityToolkit.WinUI.UI.Controls.Markdown.dll;CommunityToolkit.WinUI.UI.Controls.Media.dll;CommunityToolkit.WinUI.UI.Controls.Primitives.dll;CommunityToolkit.WinUI.UI.dll;icon.ico;Microsoft.Graphics.Canvas.Interop.dll;Microsoft.InteractiveExperiences.Projection.dll;Microsoft.Windows.ApplicationModel.DynamicDependency.Projection.dll;Microsoft.Windows.ApplicationModel.Resources.Projection.dll;Microsoft.Windows.ApplicationModel.WindowsAppRuntime.Projection.dll;Microsoft.Windows.AppLifecycle.Projection.dll;Microsoft.Windows.SDK.NET.dll;Microsoft.Windows.System.Power.Projection.dll;Microsoft.WindowsAppRuntime.Bootstrap.Net.dll;Microsoft.WinUI.dll;Microsoft.Xaml.Interactions.dll;Microsoft.Xaml.Interactivity.dll;PowerToys.Interop.dll;PowerToys.ManagedCommon.dll;System.Management.dll;PowerToys.ManagedTelemetry.dll;PowerToys.Settings.deps.json;PowerToys.Settings.dll;PowerToys.Settings.exe;PowerToys.Settings.runtimeconfig.json;PowerToys.Settings.UI.Lib.dll;resources.pri;System.IO.Abstractions.dll;System.Text.Json.dll;WinRT.Runtime.dll;Microsoft.Graphics.Canvas.dll;Microsoft.WindowsAppRuntime.Bootstrap.dll;CoreMessagingXP.dll;dcompi.dll;dwmcorei.dll;DwmSceneI.dll;DWriteCore.dll;marshal.dll;Microsoft.DirectManipulation.dll;Microsoft.InputStateManager.dll;Microsoft.Internal.FrameworkUdk.dll;Microsoft.UI.Composition.OSSupport.dll;Microsoft.UI.Input.dll;Microsoft.UI.Windowing.Core.dll;Microsoft.UI.Xaml.Controls.dll;Microsoft.UI.Xaml.Controls.pri;Microsoft.ui.xaml.dll;Microsoft.UI.Xaml.Internal.dll;Microsoft.UI.Xaml.Phone.dll;Microsoft.ui.xaml.resources.19h1.dll;Microsoft.ui.xaml.resources.common.dll;Microsoft.Web.WebView2.Core.dll;Microsoft.Windows.ApplicationModel.Resources.dll;Microsoft.Windows.AppNotifications.Projection.dll;Microsoft.Windows.PushNotifications.Projection.dll;Microsoft.Windows.System.Projection.dll;Microsoft.WindowsAppRuntime.dll;Microsoft.WindowsAppRuntime.Insights.Resource.dll;Microsoft.WindowsAppRuntime.Release.Net.dll;MRM.dll;PushNotificationsLongRunningTask.ProxyStub.dll;WindowsAppRuntime.png;WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll;WinUIEdit.dll;wuceffectsi.dll?>
<?define SettingsV2AssetsModulesFiles=ColorPicker.png;FancyZones.png;AlwaysOnTop.png;Awake.png;ImageResizer.png;KBM.png;MouseUtils.png;PowerLauncher.png;PowerPreview.png;PowerRename.png;PT.png;ShortcutGuide.png;VideoConference.png?> <?define SettingsV2AssetsModulesFiles=ColorPicker.png;FancyZones.png;AlwaysOnTop.png;Awake.png;ImageResizer.png;KBM.png;MouseUtils.png;PowerLauncher.png;PowerPreview.png;PowerRename.png;PT.png;ShortcutGuide.png;VideoConference.png?>
@@ -872,7 +872,7 @@
<DirectoryRef Id="ColorPickerInstallFolder" FileSource="$(var.BinDir)modules\$(var.ColorPickerProjectName)"> <DirectoryRef Id="ColorPickerInstallFolder" FileSource="$(var.BinDir)modules\$(var.ColorPickerProjectName)">
<!-- !Warning! Make sure to change Component Guid if you update the file list --> <!-- !Warning! Make sure to change Component Guid if you update the file list -->
<Component Id="Module_ColorPicker" Guid="C15076EC-70EE-4CE9-BEA0-665B1EECCAAF" Win64="yes"> <Component Id="Module_ColorPicker" Guid="C15076EC-70EE-4CE9-BEA0-665B1EECCAAF" Win64="yes">
<?foreach File in PowerToys.ColorPicker.dll;System.IO.Abstractions.dll;PowerToys.ColorPickerUI.exe;PowerToys.ColorPickerUI.dll;PowerToys.ColorPickerUI.deps.json;PowerToys.ColorPickerUI.runtimeconfig.json;PowerToys.Settings.UI.Lib.dll;PowerToys.Interop.dll;PowerToys.ManagedTelemetry.dll;PowerToys.ManagedCommon.dll;ControlzEx.dll;Microsoft.Xaml.Behaviors.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.ComponentModel.Composition.dll;PowerToys.Common.UI.dll;WinRT.Runtime.dll;Microsoft.Windows.SDK.NET.dll;System.Text.Json.dll;Ijwhost.dll?> <?foreach File in PowerToys.ColorPicker.dll;System.IO.Abstractions.dll;PowerToys.ColorPickerUI.exe;PowerToys.ColorPickerUI.dll;PowerToys.ColorPickerUI.deps.json;PowerToys.ColorPickerUI.runtimeconfig.json;PowerToys.Settings.UI.Lib.dll;PowerToys.Interop.dll;PowerToys.ManagedTelemetry.dll;PowerToys.ManagedCommon.dll;System.Management.dll;ControlzEx.dll;Microsoft.Xaml.Behaviors.dll;ModernWpf.Controls.dll;ModernWpf.dll;System.ComponentModel.Composition.dll;PowerToys.Common.UI.dll;WinRT.Runtime.dll;Microsoft.Windows.SDK.NET.dll;System.Text.Json.dll;Ijwhost.dll?>
<File Id="ColorPickerFile_$(var.File)" Source="$(var.BinDir)modules\$(var.ColorPickerProjectName)\$(var.File)" /> <File Id="ColorPickerFile_$(var.File)" Source="$(var.BinDir)modules\$(var.ColorPickerProjectName)\$(var.File)" />
<?endforeach?> <?endforeach?>
</Component> </Component>
@@ -892,7 +892,7 @@
<DirectoryRef Id="AwakeInstallFolder" FileSource="$(var.BinDir)modules\$(var.AwakeProjectName)"> <DirectoryRef Id="AwakeInstallFolder" FileSource="$(var.BinDir)modules\$(var.AwakeProjectName)">
<!-- !Warning! Make sure to change Component Guid if you update the file list --> <!-- !Warning! Make sure to change Component Guid if you update the file list -->
<Component Id="Module_Awake" Guid="0D571D9A-743B-4CC5-9297-F0289FBE3398" Win64="yes"> <Component Id="Module_Awake" Guid="0D571D9A-743B-4CC5-9297-F0289FBE3398" Win64="yes">
<?foreach File in PowerToys.AwakeModuleInterface.dll;PowerToys.ManagedCommon.dll;PowerToys.ManagedTelemetry.dll;PowerToys.Settings.UI.Lib.dll;NLog.config;NLog.dll;PowerToys.Awake.deps.json;PowerToys.Awake.dll;PowerToys.Awake.exe;PowerToys.Awake.runtimeconfig.json;PowerToys.Interop.dll;System.CommandLine.dll;System.IO.Abstractions.dll;System.Reactive.dll;System.Runtime.Caching.dll;System.Text.Json.dll;Ijwhost.dll;Microsoft.Windows.SDK.NET.dll;WinRT.Runtime.dll?> <?foreach File in PowerToys.AwakeModuleInterface.dll;PowerToys.ManagedCommon.dll;System.Management.dll;PowerToys.ManagedTelemetry.dll;PowerToys.Settings.UI.Lib.dll;NLog.config;NLog.dll;PowerToys.Awake.deps.json;PowerToys.Awake.dll;PowerToys.Awake.exe;PowerToys.Awake.runtimeconfig.json;PowerToys.Interop.dll;System.CommandLine.dll;System.IO.Abstractions.dll;System.Reactive.dll;System.Runtime.Caching.dll;System.Text.Json.dll;Ijwhost.dll;Microsoft.Windows.SDK.NET.dll;WinRT.Runtime.dll?>
<File Id="AwakeFile_$(var.File)" Source="$(var.BinDir)modules\$(var.AwakeProjectName)\$(var.File)" /> <File Id="AwakeFile_$(var.File)" Source="$(var.BinDir)modules\$(var.AwakeProjectName)\$(var.File)" />
<?endforeach?> <?endforeach?>
</Component> </Component>
@@ -1731,7 +1731,7 @@
<!-- !Warning! Make sure to change Component Guid if you update the file list --> <!-- !Warning! Make sure to change Component Guid if you update the file list -->
<Component Id="launcherInstallComponent" Guid="ab0d0567-1e41-4da4-9934-dcb74b7048a4" Directory="LauncherInstallFolder" > <Component Id="launcherInstallComponent" Guid="ab0d0567-1e41-4da4-9934-dcb74b7048a4" Directory="LauncherInstallFolder" >
<File Source="$(var.BinDir)modules\Launcher\PowerToys.Launcher.dll" /> <File Source="$(var.BinDir)modules\Launcher\PowerToys.Launcher.dll" />
<?foreach File in e_sqlite3.dll;JetBrains.Annotations.dll;Mages.Core.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerToys.PowerLauncher.deps.json;PowerToys.PowerLauncher.dll;PowerToys.PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;PowerToys.PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;UnitsNet.dll;vcamp140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToys.Interop.dll;PowerToys.ManagedTelemetry.dll;PowerToys.PowerLauncher.Telemetry.dll;Microsoft.Data.Sqlite.dll;SQLitePCLRaw.batteries_v2.dll;SQLitePCLRaw.core.dll;SQLitePCLRaw.provider.e_sqlite3.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;PowerToys.ManagedCommon.dll;System.IO.Abstractions.dll;PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;WinRT.Runtime.dll;Microsoft.Windows.SDK.NET.dll;System.Reactive.dll;System.Text.Json.dll;Ijwhost.dll;ScipBe.Common.Office.OneNote.dll;Interop.Microsoft.Office.Interop.OneNote.dll;LazyCache.dll;Microsoft.Extensions.Caching.Abstractions.dll;Microsoft.Extensions.Caching.Memory.dll?> <?foreach File in e_sqlite3.dll;JetBrains.Annotations.dll;Mages.Core.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerToys.PowerLauncher.deps.json;PowerToys.PowerLauncher.dll;PowerToys.PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;PowerToys.PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;UnitsNet.dll;vcamp140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToys.Interop.dll;PowerToys.ManagedTelemetry.dll;PowerToys.PowerLauncher.Telemetry.dll;Microsoft.Data.Sqlite.dll;SQLitePCLRaw.batteries_v2.dll;SQLitePCLRaw.core.dll;SQLitePCLRaw.provider.e_sqlite3.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;PowerToys.ManagedCommon.dll;System.Management.dll;System.IO.Abstractions.dll;PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;WinRT.Runtime.dll;Microsoft.Windows.SDK.NET.dll;System.Reactive.dll;System.Text.Json.dll;Ijwhost.dll;ScipBe.Common.Office.OneNote.dll;Interop.Microsoft.Office.Interop.OneNote.dll;LazyCache.dll;Microsoft.Extensions.Caching.Abstractions.dll;Microsoft.Extensions.Caching.Memory.dll?>
<File Id="File_$(var.File)" Source="$(var.BinDir)modules\launcher\$(var.File)" /> <File Id="File_$(var.File)" Source="$(var.BinDir)modules\launcher\$(var.File)" />
<?endforeach?> <?endforeach?>
<File Source="$(var.BinDir)Settings\PowerToys.Settings.UI.Lib.dll" /> <File Source="$(var.BinDir)Settings\PowerToys.Settings.UI.Lib.dll" />

View File

@@ -17,6 +17,8 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="System.Management" Version="6.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -14,4 +14,10 @@ namespace ManagedCommon
HighContrastBlack, HighContrastBlack,
HighContrastWhite, HighContrastWhite,
} }
public enum AppTheme
{
Dark = 0,
Light = 1,
}
} }

View File

@@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace ManagedCommon
{
// Based on https://stackoverflow.com/a/62811758/5001796
public static class ThemeHelpers
{
[DllImport("dwmapi.dll")]
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
internal const string HKeyRoot = "HKEY_CURRENT_USER";
internal const string HkeyWindowsTheme = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Themes";
internal const string HkeyWindowsPersonalizeTheme = $@"{HkeyWindowsTheme}\Personalize";
internal const string HValueAppTheme = "AppsUseLightTheme";
internal const int DWMWAImmersiveDarkMode = 20;
// based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
public static AppTheme GetAppTheme()
{
int value = (int)Registry.GetValue($"{HKeyRoot}\\{HkeyWindowsPersonalizeTheme}", HValueAppTheme, 1);
return (AppTheme)value;
}
public static void SetImmersiveDarkMode(IntPtr window, bool enabled)
{
int useImmersiveDarkMode = enabled ? 1 : 0;
_ = DwmSetWindowAttribute(window, DWMWAImmersiveDarkMode, ref useImmersiveDarkMode, sizeof(int));
}
}
}

View File

@@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Management;
using System.Security.Principal;
namespace ManagedCommon
{
/// <summary>
/// The Delegate for a ThemeChanged Event.
/// </summary>
/// <param name="sender">Sender ThemeListener</param>
public delegate void ThemeChangedEvent(ThemeListener sender);
public class ThemeListener : IDisposable
{
/// <summary>
/// Gets the App Theme.
/// </summary>
public AppTheme AppTheme { get; private set; }
/// <summary>
/// An event that fires if the Theme changes.
/// </summary>
public event ThemeChangedEvent ThemeChanged;
private readonly ManagementEventWatcher watcher;
public ThemeListener()
{
var currentUser = WindowsIdentity.GetCurrent();
var query = new WqlEventQuery(
$"SELECT * FROM RegistryValueChangeEvent WHERE Hive='HKEY_USERS' AND " +
$"KeyPath='{currentUser.User.Value}\\\\{ThemeHelpers.HkeyWindowsPersonalizeTheme.Replace("\\", "\\\\")}' AND ValueName='{ThemeHelpers.HValueAppTheme}'");
watcher = new ManagementEventWatcher(query);
watcher.EventArrived += Watcher_EventArrived;
watcher.Start();
AppTheme = ThemeHelpers.GetAppTheme();
}
private void Watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
var appTheme = ThemeHelpers.GetAppTheme();
if (appTheme != AppTheme)
{
AppTheme = appTheme;
ThemeChanged?.Invoke(this);
}
}
public void Dispose()
{
watcher.Dispose();
GC.SuppressFinalize(this);
}
}
}

View File

@@ -31,10 +31,14 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="icon_helpers.h" /> <ClInclude Include="icon_helpers.h" />
<ClInclude Include="theme_listener.h" />
<ClInclude Include="theme_helpers.h" />
<ClInclude Include="windows_colors.h" /> <ClInclude Include="windows_colors.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="icon_helpers.cpp" /> <ClCompile Include="icon_helpers.cpp" />
<ClCompile Include="theme_listener.cpp" />
<ClCompile Include="theme_helpers.cpp" />
<ClCompile Include="windows_colors.cpp" /> <ClCompile Include="windows_colors.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -0,0 +1,43 @@
// Port Based on https://stackoverflow.com/a/62811758/5001796
#include "theme_helpers.h"
#include "dwmapi.h"
#include <windows.h>
#include <vector>
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
#define HKEY_WINDOWS_THEME L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"
// based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
AppTheme ThemeHelpers::GetAppTheme()
{
// The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian
auto buffer = std::vector<char>(4);
auto cbData = static_cast<DWORD>(buffer.size() * sizeof(char));
auto res = RegGetValueW(
HKEY_CURRENT_USER,
HKEY_WINDOWS_THEME,
L"AppsUseLightTheme",
RRF_RT_REG_DWORD, // expected value type
nullptr,
buffer.data(),
&cbData);
if (res != ERROR_SUCCESS)
{
return AppTheme::Light;
}
// convert bytes written to our buffer to an int, assuming little-endian
auto i = int(buffer[3] << 24 |
buffer[2] << 16 |
buffer[1] << 8 |
buffer[0]);
return AppTheme(i);
}
void ThemeHelpers::SetImmersiveDarkMode(HWND window, bool enabled)
{
int useImmersiveDarkMode = enabled ? 1 : 0;
DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, &useImmersiveDarkMode, sizeof(useImmersiveDarkMode));
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include <windows.h>
enum class AppTheme
{
Dark = 0,
Light = 1
};
struct ThemeHelpers
{
static AppTheme GetAppTheme();
static void ThemeHelpers::SetImmersiveDarkMode(HWND window, bool enabled);
};

View File

@@ -0,0 +1,57 @@
#include "theme_listener.h"
#define HKEY_WINDOWS_THEME L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"
DWORD WINAPI _checkTheme(LPVOID lpParam)
{
auto listener = (ThemeListener*)lpParam;
listener->CheckTheme();
return 0;
}
void ThemeListener::AddChangedHandler(THEME_HANDLE handle)
{
handles.push_back(handle);
}
void ThemeListener::DelChangedHandler(THEME_HANDLE handle)
{
auto it = std::find(handles.begin(), handles.end(), handle);
handles.erase(it);
}
void ThemeListener::CheckTheme()
{
HANDLE hEvent;
HKEY hKey;
// Open the Key to listen
RegOpenKeyEx(HKEY_CURRENT_USER, HKEY_WINDOWS_THEME, 0, KEY_NOTIFY, &hKey);
while (true)
{
// Create an event.
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (hEvent != 0)
{
// Watch the registry key for a change of value.
RegNotifyChangeKeyValue(hKey,
TRUE,
REG_NOTIFY_CHANGE_LAST_SET,
hEvent,
TRUE);
WaitForSingleObject(hEvent, INFINITE);
auto _theme = ThemeHelpers::GetAppTheme();
if (AppTheme != _theme)
{
AppTheme = _theme;
for (int i = 0; i < handles.size(); i++)
{
handles[i]();
}
}
}
}
}

View File

@@ -0,0 +1,34 @@
#include "theme_helpers.h"
#include "dwmapi.h"
#include <windows.h>
#include <iostream>
#include <vector>
typedef void (*THEME_HANDLE)();
DWORD WINAPI _checkTheme(LPVOID lpParam);
#pragma once
class ThemeListener
{
public:
ThemeListener()
{
AppTheme = ThemeHelpers::GetAppTheme();
dwThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_checkTheme, this, 0, &dwThreadId);
}
~ThemeListener()
{
CloseHandle(dwThreadHandle);
dwThreadId = 0;
}
AppTheme AppTheme;
void ThemeListener::AddChangedHandler(THEME_HANDLE handle);
void ThemeListener::DelChangedHandler(THEME_HANDLE handle);
void CheckTheme();
private:
HANDLE dwThreadHandle;
DWORD dwThreadId;
std::vector<THEME_HANDLE> handles;
};

View File

@@ -1,4 +1,5 @@
#include "windows_colors.h" #include "windows_colors.h"
#include "theme_helpers.h"
DWORD WindowsColors::rgb_color(DWORD abgr_color) DWORD WindowsColors::rgb_color(DWORD abgr_color)
{ {
@@ -65,7 +66,7 @@ WindowsColors::Color WindowsColors::get_background_color()
bool WindowsColors::is_dark_mode() bool WindowsColors::is_dark_mode()
{ {
return rgb_color(get_background_color()) == 0; return ThemeHelpers::GetAppTheme() == AppTheme::Dark;
} }
bool WindowsColors::update() bool WindowsColors::update()

View File

@@ -102,7 +102,7 @@
<AdditionalIncludeDirectories>./;$(SolutionDir)src\modules\;$(SolutionDir)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(SolutionDir)src\common\Display;$(SolutionDir)src\common\inc;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>./;$(SolutionDir)src\modules\;$(SolutionDir)src\modules\KeyboardManager\KeyboardManagerEditorLibrary\;$(SolutionDir)src\common\Display;$(SolutionDir)src\common\inc;$(SolutionDir)src\common\Telemetry;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>Display.lib;shcore.lib;Dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Display.lib;shcore.lib;Dbghelp.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@@ -113,7 +113,7 @@
<Link> <Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Display.lib;shcore.lib;Dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Display.lib;shcore.lib;Dbghelp.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(ConfigurationName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>

View File

@@ -22,6 +22,7 @@
#include "UIHelpers.h" #include "UIHelpers.h"
#include "ShortcutErrorType.h" #include "ShortcutErrorType.h"
#include "EditorConstants.h" #include "EditorConstants.h"
#include <common/Themes/theme_listener.h>
using namespace winrt::Windows::Foundation; using namespace winrt::Windows::Foundation;
@@ -42,6 +43,20 @@ std::mutex editKeyboardWindowMutex;
// Stores a pointer to the Xaml Bridge object so that it can be accessed from the window procedure // Stores a pointer to the Xaml Bridge object so that it can be accessed from the window procedure
static XamlBridge* xamlBridgePtr = nullptr; static XamlBridge* xamlBridgePtr = nullptr;
// Theming
ThemeListener theme_listener{};
void handleTheme()
{
auto theme = theme_listener.AppTheme;
auto isDark = theme == AppTheme::Dark;
Logger::info(L"Theme is now {}", isDark ? L"Dark" : L"Light");
if (hwndEditKeyboardNativeWindow != nullptr)
{
ThemeHelpers::SetImmersiveDarkMode(hwndEditKeyboardNativeWindow, isDark);
}
}
static IAsyncOperation<bool> OrphanKeysConfirmationDialog( static IAsyncOperation<bool> OrphanKeysConfirmationDialog(
KBMEditor::KeyboardManagerState& state, KBMEditor::KeyboardManagerState& state,
const std::vector<DWORD>& keys, const std::vector<DWORD>& keys,
@@ -130,7 +145,7 @@ inline void CreateEditKeyboardWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMan
48, 48,
48, 48,
LR_DEFAULTCOLOR); LR_DEFAULTCOLOR);
if (RegisterClassEx(&windowClass) == NULL) if (RegisterClassEx(&windowClass) == NULL)
{ {
MessageBox(NULL, GET_RESOURCE_STRING(IDS_REGISTERCLASSFAILED_ERRORMESSAGE).c_str(), GET_RESOURCE_STRING(IDS_REGISTERCLASSFAILED_ERRORTITLE).c_str(), NULL); MessageBox(NULL, GET_RESOURCE_STRING(IDS_REGISTERCLASSFAILED_ERRORMESSAGE).c_str(), GET_RESOURCE_STRING(IDS_REGISTERCLASSFAILED_ERRORTITLE).c_str(), NULL);
@@ -149,7 +164,7 @@ inline void CreateEditKeyboardWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMan
DPIAware::ConvertByCursorPosition(windowWidth, windowHeight); DPIAware::ConvertByCursorPosition(windowWidth, windowHeight);
DPIAware::GetScreenDPIForCursor(g_currentDPI); DPIAware::GetScreenDPIForCursor(g_currentDPI);
// Window Creation // Window Creation
HWND _hWndEditKeyboardWindow = CreateWindow( HWND _hWndEditKeyboardWindow = CreateWindow(
szWindowClass, szWindowClass,
@@ -163,7 +178,7 @@ inline void CreateEditKeyboardWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMan
NULL, NULL,
hInst, hInst,
NULL); NULL);
if (_hWndEditKeyboardWindow == NULL) if (_hWndEditKeyboardWindow == NULL)
{ {
MessageBox(NULL, GET_RESOURCE_STRING(IDS_CREATEWINDOWFAILED_ERRORMESSAGE).c_str(), GET_RESOURCE_STRING(IDS_CREATEWINDOWFAILED_ERRORTITLE).c_str(), NULL); MessageBox(NULL, GET_RESOURCE_STRING(IDS_CREATEWINDOWFAILED_ERRORMESSAGE).c_str(), GET_RESOURCE_STRING(IDS_CREATEWINDOWFAILED_ERRORTITLE).c_str(), NULL);
@@ -181,12 +196,15 @@ inline void CreateEditKeyboardWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMan
hwndEditKeyboardNativeWindow = _hWndEditKeyboardWindow; hwndEditKeyboardNativeWindow = _hWndEditKeyboardWindow;
hwndLock.unlock(); hwndLock.unlock();
handleTheme();
theme_listener.AddChangedHandler(handleTheme);
// Create the xaml bridge object // Create the xaml bridge object
XamlBridge xamlBridge(_hWndEditKeyboardWindow); XamlBridge xamlBridge(_hWndEditKeyboardWindow);
// DesktopSource needs to be declared before the RelativePanel xamlContainer object to avoid errors // DesktopSource needs to be declared before the RelativePanel xamlContainer object to avoid errors
winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource desktopSource; winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource desktopSource;
// Create the desktop window xaml source object and set its content // Create the desktop window xaml source object and set its content
hWndXamlIslandEditKeyboardWindow = xamlBridge.InitDesktopWindowsXamlSource(desktopSource); hWndXamlIslandEditKeyboardWindow = xamlBridge.InitDesktopWindowsXamlSource(desktopSource);
@@ -253,10 +271,10 @@ inline void CreateEditKeyboardWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMan
SingleKeyRemapControl::keyboardManagerState = &keyboardManagerState; SingleKeyRemapControl::keyboardManagerState = &keyboardManagerState;
KeyDropDownControl::keyboardManagerState = &keyboardManagerState; KeyDropDownControl::keyboardManagerState = &keyboardManagerState;
KeyDropDownControl::mappingConfiguration = &mappingConfiguration; KeyDropDownControl::mappingConfiguration = &mappingConfiguration;
// Clear the single key remap buffer // Clear the single key remap buffer
SingleKeyRemapControl::singleKeyRemapBuffer.clear(); SingleKeyRemapControl::singleKeyRemapBuffer.clear();
// Vector to store dynamically allocated control objects to avoid early destruction // Vector to store dynamically allocated control objects to avoid early destruction
std::vector<std::vector<std::unique_ptr<SingleKeyRemapControl>>> keyboardRemapControlObjects; std::vector<std::vector<std::unique_ptr<SingleKeyRemapControl>>> keyboardRemapControlObjects;
@@ -378,6 +396,7 @@ inline void CreateEditKeyboardWindowImpl(HINSTANCE hInst, KBMEditor::KeyboardMan
xamlBridgePtr = nullptr; xamlBridgePtr = nullptr;
hWndXamlIslandEditKeyboardWindow = nullptr; hWndXamlIslandEditKeyboardWindow = nullptr;
hwndLock.lock(); hwndLock.lock();
theme_listener.DelChangedHandler(handleTheme);
hwndEditKeyboardNativeWindow = nullptr; hwndEditKeyboardNativeWindow = nullptr;
keyboardManagerState.ResetUIState(); keyboardManagerState.ResetUIState();
keyboardManagerState.ClearRegisteredKeyDelays(); keyboardManagerState.ClearRegisteredKeyDelays();
@@ -450,8 +469,7 @@ LRESULT CALLBACK EditKeyboardWindowProc(HWND hWnd, UINT messageCode, WPARAM wPar
rect->top, rect->top,
rect->right - rect->left, rect->right - rect->left,
rect->bottom - rect->top, rect->bottom - rect->top,
SWP_NOZORDER | SWP_NOACTIVATE SWP_NOZORDER | SWP_NOACTIVATE);
);
Logger::trace(L"WM_DPICHANGED: new dpi {} rect {} {} ", newDPI, rect->right - rect->left, rect->bottom - rect->top); Logger::trace(L"WM_DPICHANGED: new dpi {} rect {} {} ", newDPI, rect->right - rect->left, rect->bottom - rect->top);
} }
@@ -487,7 +505,7 @@ bool CheckEditKeyboardWindowActive()
{ {
ShowWindow(hwndEditKeyboardNativeWindow, SW_RESTORE); ShowWindow(hwndEditKeyboardNativeWindow, SW_RESTORE);
} }
// If there is an already existing window no need to create a new open bring it on foreground. // If there is an already existing window no need to create a new open bring it on foreground.
SetForegroundWindow(hwndEditKeyboardNativeWindow); SetForegroundWindow(hwndEditKeyboardNativeWindow);
result = true; result = true;

View File

@@ -21,6 +21,8 @@
#include "microsoft.ui.xaml.window.h" #include "microsoft.ui.xaml.window.h"
#include <winrt/Microsoft.UI.Interop.h> #include <winrt/Microsoft.UI.Interop.h>
#include <winrt/Microsoft.UI.Windowing.h> #include <winrt/Microsoft.UI.Windowing.h>
#include <common/Themes/theme_helpers.h>
#include <common/Themes/theme_listener.h>
using namespace winrt; using namespace winrt;
using namespace Windows::UI::Xaml; using namespace Windows::UI::Xaml;
@@ -35,15 +37,31 @@ HINSTANCE g_hostHInst;
extern std::vector<std::wstring> g_files; extern std::vector<std::wstring> g_files;
// Theming
ThemeListener theme_listener{};
HWND CurrentWindow;
void handleTheme() {
auto theme = theme_listener.AppTheme;
auto isDark = theme == AppTheme::Dark;
Logger::info(L"Theme is now {}", isDark ? L"Dark" : L"Light");
ThemeHelpers::SetImmersiveDarkMode(CurrentWindow, isDark);
}
namespace winrt::PowerRenameUI::implementation namespace winrt::PowerRenameUI::implementation
{ {
MainWindow::MainWindow() : MainWindow::MainWindow() :
m_instance{ nullptr }, m_allSelected{ true }, m_managerEvents{ this } m_instance{ nullptr }, m_allSelected{ true }, m_managerEvents{ this }
{ {
auto windowNative{ this->try_as<::IWindowNative>() }; auto windowNative{ this->try_as<::IWindowNative>() };
winrt::check_bool(windowNative); winrt::check_bool(windowNative);
windowNative->get_WindowHandle(&m_window); windowNative->get_WindowHandle(&m_window);
CurrentWindow = m_window;
// Attach theme handling
theme_listener.AddChangedHandler(handleTheme);
handleTheme();
Microsoft::UI::WindowId windowId = Microsoft::UI::WindowId windowId =
Microsoft::UI::GetWindowIdFromWindow(m_window); Microsoft::UI::GetWindowIdFromWindow(m_window);
@@ -69,7 +87,6 @@ namespace winrt::PowerRenameUI::implementation
} }
} }
Microsoft::UI::Windowing::AppWindow appWindow = Microsoft::UI::Windowing::AppWindow appWindow =
Microsoft::UI::Windowing::AppWindow::GetFromWindowId(windowId); Microsoft::UI::Windowing::AppWindow::GetFromWindowId(windowId);
appWindow.SetIcon(PowerRenameUIIco); appWindow.SetIcon(PowerRenameUIIco);

View File

@@ -69,6 +69,9 @@
<ClCompile> <ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link>
<AdditionalDependencies>kernel32.lib;user32.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile> <ClCompile>
@@ -77,6 +80,7 @@
<Link> <Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
@@ -161,6 +165,9 @@
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj"> <ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project> <Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\..\common\Themes\Themes.vcxproj">
<Project>{98537082-0fdb-40de-abd8-0dc5a4269bab}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\version\version.vcxproj"> <ProjectReference Include="..\..\..\common\version\version.vcxproj">
<Project>{cc6e41ac-8174-4e8a-8d22-85dd7f4851df}</Project> <Project>{cc6e41ac-8174-4e8a-8d22-85dd7f4851df}</Project>
</ProjectReference> </ProjectReference>

View File

@@ -39,7 +39,7 @@
<Link> <Link>
<UACExecutionLevel>AsInvoker</UACExecutionLevel> <UACExecutionLevel>AsInvoker</UACExecutionLevel>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>Shcore.lib;gdiplus.lib;Msi.lib;WindowsApp.lib;taskschd.lib;Rstrtmgr.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Shcore.lib;gdiplus.lib;Msi.lib;WindowsApp.lib;taskschd.lib;Rstrtmgr.lib;Shlwapi.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<Manifest> <Manifest>
<EnableDpiAwareness>false</EnableDpiAwareness> <EnableDpiAwareness>false</EnableDpiAwareness>

View File

@@ -15,7 +15,6 @@ using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;
using Microsoft.PowerToys.Telemetry; using Microsoft.PowerToys.Telemetry;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Windows.UI.Popups; using Windows.UI.Popups;
using Windows.UI.ViewManagement;
using WinRT.Interop; using WinRT.Interop;
namespace Microsoft.PowerToys.Settings.UI namespace Microsoft.PowerToys.Settings.UI
@@ -73,7 +72,7 @@ namespace Microsoft.PowerToys.Settings.UI
{ {
if (settingsWindow == null) if (settingsWindow == null)
{ {
settingsWindow = new MainWindow(); settingsWindow = new MainWindow(IsDarkTheme());
} }
settingsWindow.Activate(); settingsWindow.Activate();
@@ -88,6 +87,7 @@ namespace Microsoft.PowerToys.Settings.UI
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{ {
var cmdArgs = Environment.GetCommandLineArgs(); var cmdArgs = Environment.GetCommandLineArgs();
var isDark = IsDarkTheme();
if (cmdArgs != null && cmdArgs.Length >= RequiredArgumentsQty) if (cmdArgs != null && cmdArgs.Length >= RequiredArgumentsQty)
{ {
@@ -143,7 +143,7 @@ namespace Microsoft.PowerToys.Settings.UI
if (!ShowOobe && !ShowScoobe) if (!ShowOobe && !ShowScoobe)
{ {
settingsWindow = new MainWindow(); settingsWindow = new MainWindow(isDark);
settingsWindow.Activate(); settingsWindow.Activate();
settingsWindow.NavigateToSection(StartupPage); settingsWindow.NavigateToSection(StartupPage);
} }
@@ -152,19 +152,19 @@ namespace Microsoft.PowerToys.Settings.UI
// Create the Settings window hidden so that it's fully initialized and // Create the Settings window hidden so that it's fully initialized and
// it will be ready to receive the notification if the user opens // it will be ready to receive the notification if the user opens
// the Settings from the tray icon. // the Settings from the tray icon.
settingsWindow = new MainWindow(true); settingsWindow = new MainWindow(isDark, true);
if (ShowOobe) if (ShowOobe)
{ {
PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent()); PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent());
OobeWindow oobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.Overview); OobeWindow oobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.Overview, isDark);
oobeWindow.Activate(); oobeWindow.Activate();
SetOobeWindow(oobeWindow); SetOobeWindow(oobeWindow);
} }
else if (ShowScoobe) else if (ShowScoobe)
{ {
PowerToysTelemetry.Log.WriteEvent(new ScoobeStartedEvent()); PowerToysTelemetry.Log.WriteEvent(new ScoobeStartedEvent());
OobeWindow scoobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.WhatsNew); OobeWindow scoobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.WhatsNew, isDark);
scoobeWindow.Activate(); scoobeWindow.Activate();
SetOobeWindow(scoobeWindow); SetOobeWindow(scoobeWindow);
} }
@@ -174,7 +174,7 @@ namespace Microsoft.PowerToys.Settings.UI
{ {
// For debugging purposes // For debugging purposes
// Window is also needed to show MessageDialog // Window is also needed to show MessageDialog
settingsWindow = new MainWindow(); settingsWindow = new MainWindow(isDark);
settingsWindow.Activate(); settingsWindow.Activate();
ShowMessageDialog("The application cannot be run as a standalone process. Please start the application through the runner.", "Forbidden"); 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; return ipcmanager;
} }
public static string SelectedTheme()
{
return SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpper(CultureInfo.InvariantCulture);
}
public static bool IsDarkTheme() public static bool IsDarkTheme()
{ {
var selectedTheme = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Theme.ToUpper(CultureInfo.InvariantCulture); var selectedTheme = SelectedTheme();
var defaultTheme = new UISettings(); return selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && ThemeHelpers.GetAppTheme() == AppTheme.Dark);
var uiTheme = defaultTheme.GetColorValue(UIColorType.Background).ToString(System.Globalization.CultureInfo.InvariantCulture); }
return selectedTheme == "DARK" || (selectedTheme == "SYSTEM" && uiTheme == "#FF000000");
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 ISettingsUtils settingsUtils = new SettingsUtils();
private static MainWindow settingsWindow; private static MainWindow settingsWindow;
private static OobeWindow oobeWindow; private static OobeWindow oobeWindow;
private static ThemeListener themeListener;
public static void ClearSettingsWindow() public static void ClearSettingsWindow()
{ {

View File

@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
using System; using System;
using System.Drawing; using ManagedCommon;
using Microsoft.PowerLauncher.Telemetry; using Microsoft.PowerLauncher.Telemetry;
using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library.Utilities; using Microsoft.PowerToys.Settings.UI.Library.Utilities;
@@ -22,7 +22,7 @@ namespace Microsoft.PowerToys.Settings.UI
/// </summary> /// </summary>
public sealed partial class MainWindow : Window public sealed partial class MainWindow : Window
{ {
public MainWindow(bool createHidden = false) public MainWindow(bool isDark, bool createHidden = false)
{ {
var bootTime = new System.Diagnostics.Stopwatch(); var bootTime = new System.Diagnostics.Stopwatch();
bootTime.Start(); bootTime.Start();
@@ -36,6 +36,12 @@ namespace Microsoft.PowerToys.Settings.UI
AppWindow appWindow = AppWindow.GetFromWindowId(windowId); AppWindow appWindow = AppWindow.GetFromWindowId(windowId);
appWindow.SetIcon("icon.ico"); 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); var placement = Utils.DeserializePlacementOrDefault(hWnd);
if (createHidden) if (createHidden)
{ {
@@ -72,7 +78,7 @@ namespace Microsoft.PowerToys.Settings.UI
{ {
if (App.GetOobeWindow() == null) 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(); App.GetOobeWindow().Activate();

View File

@@ -4,6 +4,7 @@
using System; using System;
using interop; using interop;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.OOBE.Enums; using Microsoft.PowerToys.Settings.UI.OOBE.Enums;
using Microsoft.PowerToys.Settings.UI.OOBE.Views; using Microsoft.PowerToys.Settings.UI.OOBE.Views;
@@ -30,7 +31,7 @@ namespace Microsoft.PowerToys.Settings.UI
private IntPtr _hWnd; private IntPtr _hWnd;
private AppWindow _appWindow; private AppWindow _appWindow;
public OobeWindow(PowerToysModules initialModule) public OobeWindow(PowerToysModules initialModule, bool isDark)
{ {
this.InitializeComponent(); this.InitializeComponent();
@@ -40,6 +41,12 @@ namespace Microsoft.PowerToys.Settings.UI
_appWindow = AppWindow.GetFromWindowId(_windowId); _appWindow = AppWindow.GetFromWindowId(_windowId);
_appWindow.SetIcon("icon.ico"); _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; OverlappedPresenter presenter = _appWindow.Presenter as OverlappedPresenter;
presenter.IsMinimizable = false; presenter.IsMinimizable = false;
presenter.IsMaximizable = false; presenter.IsMaximizable = false;

View File

@@ -78,6 +78,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
break; break;
} }
App.HandleThemeChange();
return 0; return 0;
} }