22using DevToys . Core . Settings ;
33using DevToys . Blazor . Components ;
44using DevToys . Blazor . Core . Services ;
5+ using Gio ;
6+ using GLib ;
7+ using Microsoft . Extensions . Logging ;
58using Object = GObject . Object ;
69using static GObject . Object ;
710
811namespace DevToys . Linux . Core ;
912
1013[ Export ( typeof ( IThemeListener ) ) ]
11- internal sealed class ThemeListener : IThemeListener
14+ internal sealed partial class ThemeListener : IThemeListener
1215{
16+ private readonly ILogger _logger ;
1317 private readonly ISettingsProvider _settingsProvider ;
1418 private readonly Gtk . Settings _gtkSettings ;
1519
@@ -19,6 +23,8 @@ internal sealed class ThemeListener : IThemeListener
1923 [ ImportingConstructor ]
2024 public ThemeListener ( ISettingsProvider settingsProvider )
2125 {
26+ _logger = this . Log ( ) ;
27+
2228 // Listen for app settings
2329 _settingsProvider = settingsProvider ;
2430 _settingsProvider . SettingChanged += SettingsProvider_SettingChanged ;
@@ -64,10 +70,12 @@ public void ApplyDesiredColorTheme()
6470 if ( theme == AvailableApplicationTheme . Dark )
6571 {
6672 ActualAppTheme = ApplicationTheme . Dark ;
73+ _gtkSettings . GtkApplicationPreferDarkTheme = true ;
6774 }
6875 else
6976 {
7077 ActualAppTheme = ApplicationTheme . Light ;
78+ _gtkSettings . GtkApplicationPreferDarkTheme = false ;
7179 }
7280
7381 _ignoreOperatingSystemSettingChanged = false ;
@@ -147,8 +155,48 @@ private void UpdateSystemSettingsAndApplyTheme()
147155
148156 private AvailableApplicationTheme GetCurrentSystemTheme ( )
149157 {
150- return _gtkSettings . GtkApplicationPreferDarkTheme || ( _gtkSettings . GtkThemeName ? . Contains ( "Dark" , StringComparison . OrdinalIgnoreCase ) ?? false )
151- ? AvailableApplicationTheme . Dark
152- : AvailableApplicationTheme . Light ;
158+ try
159+ {
160+ var bus = DBusConnection . Get ( BusType . Session ) ;
161+ using var parameters = Variant . NewTuple ( [
162+ Variant . NewString ( "org.freedesktop.appearance" ) , Variant . NewString ( "color-scheme" )
163+ ] ) ;
164+
165+ using Variant ret = bus . CallSync (
166+ busName : "org.freedesktop.portal.Desktop" ,
167+ objectPath : "/org/freedesktop/portal/desktop" ,
168+ interfaceName : "org.freedesktop.portal.Settings" ,
169+ methodName : "Read" ,
170+ parameters : parameters ,
171+ replyType : VariantType . New ( "(v)" ) ,
172+ flags : DBusCallFlags . None ,
173+ timeoutMsec : 2000 ,
174+ cancellable : null
175+ ) ;
176+
177+ uint userThemePreference = ret . GetChildValue ( 0 ) . GetVariant ( ) . GetVariant ( ) . GetUint32 ( ) ;
178+
179+ return userThemePreference switch
180+ {
181+ 1 => AvailableApplicationTheme . Dark ,
182+ 2 => AvailableApplicationTheme . Light ,
183+ _ => AvailableApplicationTheme . Light
184+ } ;
185+ }
186+ catch ( Exception ex )
187+ {
188+ LogGetLinuxThemeFailed ( ex ) ;
189+ return FallBack ( ) ;
190+ }
191+
192+ AvailableApplicationTheme FallBack ( )
193+ {
194+ return _gtkSettings . GtkThemeName ? . Contains ( "Dark" , StringComparison . OrdinalIgnoreCase ) ?? false
195+ ? AvailableApplicationTheme . Dark
196+ : AvailableApplicationTheme . Light ;
197+ }
153198 }
199+
200+ [ LoggerMessage ( 0 , LogLevel . Error , "Failed to detect Linux theme." ) ]
201+ partial void LogGetLinuxThemeFailed ( Exception ex ) ;
154202}
0 commit comments