Skip to content

Commit 86a5cf3

Browse files
authored
Merge pull request #476 from memstechtips/dev
Release v26.02.20
2 parents 1ceb6f7 + a881c1a commit 86a5cf3

10 files changed

Lines changed: 95 additions & 129 deletions

File tree

src/Winhance.Core/Features/Common/Interfaces/IWindowsThemeQueryService.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/Winhance.Core/Features/Customize/Interfaces/IThemeStateQuery.cs

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/Winhance.Infrastructure/Features/Common/Services/SettingApplicationService.cs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,6 @@ public async Task ApplySettingAsync(string settingId, bool enable, object? value
7070
{
7171
await HandleProcessAndServiceRestarts(setting);
7272

73-
if (checkboxResult)
74-
{
75-
logService.Log(LogLevel.Info, $"[SettingApplicationService] Applying recommended settings for domain containing '{settingId}' (checkbox checked)");
76-
try
77-
{
78-
await ApplyRecommendedSettingsForDomainAsync(settingId);
79-
logService.Log(LogLevel.Info, $"[SettingApplicationService] Successfully applied recommended settings for '{settingId}'");
80-
}
81-
catch (Exception ex)
82-
{
83-
logService.Log(LogLevel.Warning, $"[SettingApplicationService] Failed to apply recommended settings for '{settingId}': {ex.Message}");
84-
}
85-
}
86-
8773
eventBus.Publish(new SettingAppliedEvent(settingId, enable, value));
8874
logService.Log(LogLevel.Info, $"[SettingApplicationService] Successfully applied setting '{settingId}' via domain service");
8975

@@ -611,14 +597,21 @@ private async Task HandleProcessAndServiceRestarts(SettingDefinition setting)
611597
{
612598
if (!string.IsNullOrEmpty(setting.RestartProcess))
613599
{
614-
logService.Log(LogLevel.Info, $"[SettingApplicationService] Restarting process '{setting.RestartProcess}' for setting '{setting.Id}'");
615-
try
600+
if (uiManagementService.IsConfigImportMode)
616601
{
617-
uiManagementService.KillProcess(setting.RestartProcess);
602+
logService.Log(LogLevel.Debug, $"[SettingApplicationService] Skipping process restart for '{setting.RestartProcess}' (config import mode - will restart at end)");
618603
}
619-
catch (Exception ex)
604+
else
620605
{
621-
logService.Log(LogLevel.Warning, $"[SettingApplicationService] Failed to restart process '{setting.RestartProcess}': {ex.Message}");
606+
logService.Log(LogLevel.Info, $"[SettingApplicationService] Restarting process '{setting.RestartProcess}' for setting '{setting.Id}'");
607+
try
608+
{
609+
uiManagementService.KillProcess(setting.RestartProcess);
610+
}
611+
catch (Exception ex)
612+
{
613+
logService.Log(LogLevel.Warning, $"[SettingApplicationService] Failed to restart process '{setting.RestartProcess}': {ex.Message}");
614+
}
622615
}
623616
}
624617

src/Winhance.Infrastructure/Features/Common/Services/WindowsThemeQueryService.cs

Lines changed: 0 additions & 65 deletions
This file was deleted.

src/Winhance.Infrastructure/Features/Customize/Services/WallpaperService.cs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ namespace Winhance.Infrastructure.Features.Customize.Services
1414
public class WallpaperService : IWallpaperService
1515
{
1616
private readonly ILogService _logService;
17+
private readonly IInteractiveUserService _interactiveUserService;
18+
private readonly IWindowsRegistryService _registryService;
1719

1820
// P/Invoke constants
1921
private const int SPI_SETDESKWALLPAPER = 0x0014;
@@ -23,13 +25,14 @@ public class WallpaperService : IWallpaperService
2325
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
2426
private static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
2527

26-
/// <summary>
27-
/// Initializes a new instance of the <see cref="WallpaperService"/> class.
28-
/// </summary>
29-
/// <param name="logService">The log service.</param>
30-
public WallpaperService(ILogService logService)
28+
public WallpaperService(
29+
ILogService logService,
30+
IInteractiveUserService interactiveUserService,
31+
IWindowsRegistryService registryService)
3132
{
3233
_logService = logService ?? throw new ArgumentNullException(nameof(logService));
34+
_interactiveUserService = interactiveUserService;
35+
_registryService = registryService;
3336
}
3437

3538
/// <inheritdoc/>
@@ -50,8 +53,26 @@ public async Task<bool> SetWallpaperAsync(string wallpaperPath)
5053
{
5154
try
5255
{
53-
bool success = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, wallpaperPath,
54-
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE) != 0;
56+
int flags;
57+
58+
if (_interactiveUserService.IsOtsElevation)
59+
{
60+
// Under OTS, SPIF_UPDATEINIFILE would persist to the admin's profile.
61+
// Write to the interactive user's registry instead, then only broadcast.
62+
_registryService.SetValue(
63+
@"HKEY_CURRENT_USER\Control Panel\Desktop",
64+
"Wallpaper",
65+
wallpaperPath,
66+
Microsoft.Win32.RegistryValueKind.String);
67+
68+
flags = SPIF_SENDCHANGE;
69+
}
70+
else
71+
{
72+
flags = SPIF_UPDATEINIFILE | SPIF_SENDCHANGE;
73+
}
74+
75+
bool success = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, wallpaperPath, flags) != 0;
5576

5677
if (success)
5778
{
@@ -62,7 +83,7 @@ public async Task<bool> SetWallpaperAsync(string wallpaperPath)
6283
_logService.Log(LogLevel.Error, $"Failed to set wallpaper: {Marshal.GetLastWin32Error()}");
6384
}
6485

65-
await Task.CompletedTask; // To keep the async signature
86+
await Task.CompletedTask;
6687
return success;
6788
}
6889
catch (Exception ex)

src/Winhance.UI/Features/Common/Extensions/DI/InfrastructureServicesExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public static IServiceCollection AddInfrastructureServices(this IServiceCollecti
2929

3030
// Windows Services
3131
services.AddSingleton<IWindowsVersionService, WindowsVersionService>();
32-
services.AddSingleton<IWindowsThemeQueryService, WindowsThemeQueryService>();
3332
services.AddSingleton<IWindowsUIManagementService, WindowsUIManagementService>();
3433

3534
// User Preferences Service

src/Winhance.UI/Features/Common/Services/ConfigurationService.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ public class ConfigurationService : IConfigurationService
3535
private readonly ConfigurationApplicationBridgeService _bridgeService;
3636
private readonly IWindowsUIManagementService _windowsUIManagementService;
3737
private readonly IWindowsVersionService _windowsVersionService;
38-
private readonly IWindowsThemeQueryService _windowsThemeQueryService;
3938
private readonly ILocalizationService _localizationService;
4039
private readonly IConfigImportOverlayService _overlayService;
4140
private readonly IConfigReviewService _configReviewService;
@@ -61,7 +60,6 @@ public ConfigurationService(
6160
ConfigurationApplicationBridgeService bridgeService,
6261
IWindowsUIManagementService windowsUIManagementService,
6362
IWindowsVersionService windowsVersionService,
64-
IWindowsThemeQueryService windowsThemeQueryService,
6563
ILocalizationService localizationService,
6664
IConfigImportOverlayService overlayService,
6765
IConfigReviewService configReviewService,
@@ -78,7 +76,6 @@ public ConfigurationService(
7876
_bridgeService = bridgeService;
7977
_windowsUIManagementService = windowsUIManagementService;
8078
_windowsVersionService = windowsVersionService;
81-
_windowsThemeQueryService = windowsThemeQueryService;
8279
_localizationService = localizationService;
8380
_overlayService = overlayService;
8481
_configReviewService = configReviewService;

src/Winhance.UI/Features/Common/Services/ThemeService.cs

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using Microsoft.UI.Xaml;
2+
using Winhance.Core.Features.Common.Events;
3+
using Winhance.Core.Features.Common.Events.Settings;
24
using Winhance.Core.Features.Common.Interfaces;
35
using Winhance.UI.Features.Common.Interfaces;
46
using Windows.UI.ViewManagement;
@@ -11,6 +13,8 @@ namespace Winhance.UI.Features.Common.Services;
1113
public class ThemeService : IThemeService
1214
{
1315
private readonly IUserPreferencesService _userPreferences;
16+
private readonly IWindowsRegistryService _registryService;
17+
private readonly IInteractiveUserService _interactiveUserService;
1418
private readonly UISettings _uiSettings;
1519
private WinhanceTheme _currentTheme = WinhanceTheme.System;
1620

@@ -20,13 +24,26 @@ public class ThemeService : IThemeService
2024
/// <inheritdoc />
2125
public event EventHandler<WinhanceTheme>? ThemeChanged;
2226

23-
public ThemeService(IUserPreferencesService userPreferences)
27+
public ThemeService(
28+
IUserPreferencesService userPreferences,
29+
IWindowsRegistryService registryService,
30+
IInteractiveUserService interactiveUserService,
31+
IEventBus eventBus)
2432
{
2533
_userPreferences = userPreferences;
34+
_registryService = registryService;
35+
_interactiveUserService = interactiveUserService;
2636
_uiSettings = new UISettings();
2737

2838
// Listen for Windows theme changes to update System theme followers
2939
_uiSettings.ColorValuesChanged += OnWindowsThemeChanged;
40+
41+
// Under OTS, UISettings.ColorValuesChanged tracks the admin's theme.
42+
// Listen for the theme setting being applied so we can update the window.
43+
if (_interactiveUserService.IsOtsElevation)
44+
{
45+
eventBus.Subscribe<SettingAppliedEvent>(OnSettingApplied);
46+
}
3047
}
3148

3249
/// <inheritdoc />
@@ -94,7 +111,12 @@ private void ApplyTheme(WinhanceTheme theme)
94111
switch (theme)
95112
{
96113
case WinhanceTheme.System:
97-
rootElement.RequestedTheme = ElementTheme.Default;
114+
// Under OTS, ElementTheme.Default follows the admin's theme.
115+
// Explicitly set based on the interactive user's registry instead.
116+
if (_interactiveUserService.IsOtsElevation)
117+
rootElement.RequestedTheme = IsWindowsDarkTheme() ? ElementTheme.Dark : ElementTheme.Light;
118+
else
119+
rootElement.RequestedTheme = ElementTheme.Default;
98120
break;
99121

100122
case WinhanceTheme.LightNative:
@@ -145,12 +167,33 @@ private async Task<WinhanceTheme> LoadThemePreferenceAsync()
145167

146168
private bool IsWindowsDarkTheme()
147169
{
148-
// Check Windows apps use dark theme setting
170+
if (_interactiveUserService.IsOtsElevation)
171+
{
172+
// Under OTS elevation, UISettings reflects the admin's theme.
173+
// Read from the interactive user's registry hive instead.
174+
var value = _registryService.GetValue(
175+
@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize",
176+
"AppsUseLightTheme");
177+
if (value is int intVal)
178+
return intVal == 0;
179+
}
180+
149181
var foreground = _uiSettings.GetColorValue(UIColorType.Foreground);
150-
// If foreground is light, it's dark mode
151182
return foreground.R > 128 && foreground.G > 128 && foreground.B > 128;
152183
}
153184

185+
private void OnSettingApplied(SettingAppliedEvent evt)
186+
{
187+
if (evt.SettingId != "theme-mode-windows" || _currentTheme != WinhanceTheme.System)
188+
return;
189+
190+
App.MainWindow?.DispatcherQueue.TryEnqueue(() =>
191+
{
192+
ApplyTheme(WinhanceTheme.System);
193+
ThemeChanged?.Invoke(this, WinhanceTheme.System);
194+
});
195+
}
196+
154197
private void OnWindowsThemeChanged(UISettings sender, object args)
155198
{
156199
// Only react if we're following system theme
@@ -159,7 +202,10 @@ private void OnWindowsThemeChanged(UISettings sender, object args)
159202
// Must dispatch to UI thread
160203
App.MainWindow?.DispatcherQueue.TryEnqueue(() =>
161204
{
162-
// Re-apply to trigger any listeners that depend on effective theme
205+
// Under OTS, re-apply explicitly since ElementTheme.Default tracks the admin
206+
if (_interactiveUserService.IsOtsElevation)
207+
ApplyTheme(WinhanceTheme.System);
208+
163209
ThemeChanged?.Invoke(this, WinhanceTheme.System);
164210
});
165211
}

src/Winhance.UI/Features/Optimize/ViewModels/SettingItemViewModel.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -919,8 +919,6 @@ private void UpdateTechnicalDetails(SettingTooltipData tooltipData)
919919
_logService.Log(LogLevel.Warning, $"[TechnicalDetails] KeyExists failed for '{reg.KeyPath}': {kex.GetType().Name}: {kex.Message}");
920920
}
921921

922-
_logService.Log(LogLevel.Debug, $"[TechnicalDetails] {reg.KeyPath} → KeyExists={keyExists}, Value='{kvp.Value ?? "(not set)"}'");
923-
924922
TechnicalDetails.Add(new TechnicalDetailRow
925923
{
926924
RowType = DetailRowType.Registry,

src/Winhance.UI/Winhance.UI.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@
130130

131131

132132

133+
134+
135+
133136

134137

135138

0 commit comments

Comments
 (0)