From 1053932cfd4d89956a7fe5e4ed999de9820a5476 Mon Sep 17 00:00:00 2001 From: Aleksandr Neychev Date: Sun, 9 Aug 2026 20:11:14 +0500 Subject: [PATCH] modified ThemeService --- CursorLang/Services/ThemeService.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/CursorLang/Services/ThemeService.cs b/CursorLang/Services/ThemeService.cs index 03a27e8..133d96c 100644 --- a/CursorLang/Services/ThemeService.cs +++ b/CursorLang/Services/ThemeService.cs @@ -17,13 +17,24 @@ public sealed class ThemeService : IThemeService, IDisposable @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; private readonly AppSettings _settings; + private readonly Func _detectSystemTheme; private readonly List _windows = []; private ResourceDictionary? _palette; private AppTheme _current; public ThemeService(AppSettings settings) + : this(settings, DetectSystemTheme) + { + } + + /// + /// Takes the source of the system theme explicitly: in tests it is not the registry + /// that provides it. + /// + internal ThemeService(AppSettings settings, Func detectSystemTheme) { _settings = settings; + _detectSystemTheme = detectSystemTheme; _settings.PropertyChanged += OnSettingsChanged; SystemEvents.UserPreferenceChanged += OnUserPreferenceChanged; Apply(); @@ -90,7 +101,7 @@ public sealed class ThemeService : IThemeService, IDisposable private void Apply() { - AppTheme theme = _settings.Theme == AppTheme.System ? DetectSystemTheme() : _settings.Theme; + AppTheme theme = _settings.Theme == AppTheme.System ? _detectSystemTheme() : _settings.Theme; if (_palette is not null && theme == _current) { return; @@ -100,7 +111,7 @@ public sealed class ThemeService : IThemeService, IDisposable var next = new ResourceDictionary { - Source = new Uri($"pack://application:,,,/Themes/{theme}.xaml", UriKind.Absolute), + Source = PaletteUri(theme), }; ICollection dictionaries = Application.Current.Resources.MergedDictionaries; @@ -119,6 +130,12 @@ public sealed class ThemeService : IThemeService, IDisposable } } + // The assembly name in the address is there on purpose: without it the dictionary + // is looked up in the assembly the process started from, which is not always the + // application itself + internal static Uri PaletteUri(AppTheme theme) => + new($"pack://application:,,,/CursorLang;component/Themes/{theme}.xaml", UriKind.Absolute); + private void ApplyTitleBar(Window window) => WindowThemeNative.SetDarkTitleBar( new WindowInteropHelper(window).Handle,