From 63e92fbb598b96e3696410a5bde1b235ba2079be Mon Sep 17 00:00:00 2001 From: he3als <65787561+he3als@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:22:20 +0100 Subject: [PATCH] feat: make applying theme faster & reliable --- .../tweaks/qol/appearance/atlas-theme.yml | 21 +--- .../Scripts/Modules/Themes/Themes.psm1 | 96 +++++++++++++++++++ .../AtlasModules/Scripts/newUsers.ps1 | 16 ---- 3 files changed, 101 insertions(+), 32 deletions(-) create mode 100644 src/playbook/Executables/AtlasModules/Scripts/Modules/Themes/Themes.psm1 diff --git a/src/playbook/Configuration/tweaks/qol/appearance/atlas-theme.yml b/src/playbook/Configuration/tweaks/qol/appearance/atlas-theme.yml index b9bac9d477..3a2cdc6293 100644 --- a/src/playbook/Configuration/tweaks/qol/appearance/atlas-theme.yml +++ b/src/playbook/Configuration/tweaks/qol/appearance/atlas-theme.yml @@ -2,26 +2,15 @@ title: Add Theme description: Adds and sets the Atlas themes by default actions: - # Apply theme file - - !taskKill: {name: 'SystemSettings', ignoreErrors: true} + # Apply theme file and set recent themes - !powerShell: - command: >- - Start-Process -FilePath explorer -ArgumentList """$([Environment]::GetFolderPath('Windows'))\Resources\Themes\atlas-v0.4.x-dark.theme"""; - Start-Sleep 6 + command: | + .\AtlasModules\initPowerShell.ps1 + Set-Theme -Path """$([Environment]::GetFolderPath('Windows'))\Resources\Themes\atlas-v0.4.x-dark.theme""" + Set-ThemeMRU wait: true - runas: currentUserElevated - - # For Windows 11, set recent theme selection - - !taskKill: {name: 'SystemSettings', ignoreErrors: true} - - !taskKill: {name: 'control', ignoreErrors: true} - - !taskKill: {name: 'explorer', ignoreErrors: true, builds: [ '>=22000' ]} - - !powerShell: - command: '.\AtlasModules\Scripts\newUsers.ps1 -ThemeMRU' exeDir: true - wait: true runas: currentUserElevated - builds: [ '>=22000' ] - - !run: {exe: 'explorer.exe', runas: 'currentUser', wait: false, builds: [ '>=22000' ]} # Applies Atlas lockscreen background # Also disables fun facts, tips, tricks, and more on lockscreen - only on Enterprise/Education diff --git a/src/playbook/Executables/AtlasModules/Scripts/Modules/Themes/Themes.psm1 b/src/playbook/Executables/AtlasModules/Scripts/Modules/Themes/Themes.psm1 new file mode 100644 index 0000000000..9826c278a9 --- /dev/null +++ b/src/playbook/Executables/AtlasModules/Scripts/Modules/Themes/Themes.psm1 @@ -0,0 +1,96 @@ +$windir = [Environment]::GetFolderPath('Windows') + +function Stop-ThemeProcesses { + Get-Process 'SystemSettings', 'control' -EA 0 | Stop-Process -Force +} + +function Set-Theme { + param ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$Path + ) + + if (!((Get-Item $Path -EA 0).Extension -eq '.theme')) { + throw "'$Path' is not a valid path to a theme file." + } + + function Set-ThemeUsingExplorer { + Write-Warning "Failed to apply theme using COM, falling back to launching file..." + + Stop-ThemeProcesses + Start-Process -FilePath explorer -ArgumentList $Path + Start-Sleep 10 + } + + Add-Type @' +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +public static class ThemeManagerAPI +{ + public static void ApplyTheme(string themeFilePath) + { + IThemeManager themeManager = new ThemeManagerClass(); + themeManager.ApplyTheme(themeFilePath); + } + + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("D23CC733-5522-406D-8DFB-B3CF5EF52A71")] + [ComImport] + public interface ITheme + { + } + + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("0646EBBE-C1B7-4045-8FD0-FFD65D3FC792")] + [ComImport] + public interface IThemeManager + { + [DispId(1610678272)] + ITheme CurrentTheme { get; } + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ApplyTheme([MarshalAs(UnmanagedType.BStr)] string themeFilePath); + } + + [TypeLibType(TypeLibTypeFlags.FCanCreate)] + [Guid("C04B329E-5823-4415-9C93-BA44688947B0")] + [ClassInterface(ClassInterfaceType.None)] + [ComImport] + public class ThemeManagerClass : IThemeManager + { + [DispId(1610678272)] + public virtual extern ITheme CurrentTheme { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] get; } + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern void ApplyTheme([MarshalAs(UnmanagedType.BStr)] string themeFilePath); + } +} +'@ + + try { + [ThemeManagerAPI]::ApplyTheme($Path) + } catch { + Set-ThemeUsingExplorer + } + + Stop-ThemeProcesses +} + +function Set-ThemeMRU { + if ([System.Environment]::OSVersion.Version.Build -ge 22000) { + Stop-ThemeProcesses + Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes" -Name "ThemeMRU" -Value "$((@( + "atlas-v0.4.x-dark.theme", + "atlas-v0.4.x-light.theme", + "atlas-v0.3.x-dark.theme", + "atlas-v0.3.x-light.theme", + "dark.theme", + "aero.theme" + ) | ForEach-Object { "$windir\resources\Themes\$_" }) -join ';');" -Type String -Force + } +} + +Export-ModuleMember -Function Set-Theme, Set-ThemeMRU \ No newline at end of file diff --git a/src/playbook/Executables/AtlasModules/Scripts/newUsers.ps1 b/src/playbook/Executables/AtlasModules/Scripts/newUsers.ps1 index 0ddce37002..c82df087c0 100644 --- a/src/playbook/Executables/AtlasModules/Scripts/newUsers.ps1 +++ b/src/playbook/Executables/AtlasModules/Scripts/newUsers.ps1 @@ -1,23 +1,7 @@ -param ( - [switch]$ThemeMRU -) - $windir = [Environment]::GetFolderPath('Windows') $atlasDesktop = "$windir\AtlasDesktop" $atlasModules = "$windir\AtlasModules" -function ThemeMRU { - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes" -Name "ThemeMRU" -Value "$((@( - "atlas-v0.4.x-dark.theme", - "atlas-v0.4.x-light.theme", - "atlas-v0.3.x-dark.theme", - "atlas-v0.3.x-light.theme", - "dark.theme", - "aero.theme" - ) | ForEach-Object { "$windir\resources\Themes\$_" }) -join ';');" -Type String -Force -} -if ($ThemeMRU) { ThemeMRU; exit } - $title = 'Preparing Atlas user settings...' if (!(Test-Path $atlasDesktop) -or !(Test-Path $atlasModules)) {