11using Microsoft . Extensions . DependencyInjection ;
22using Microsoft . Extensions . Hosting ;
3+ using Microsoft . Extensions . Logging ;
34using Nickvision . Desktop . Application ;
45using Nickvision . Desktop . GNOME . Helpers ;
56using Nickvision . Desktop . Hosting ;
67using System ;
78using System . Linq ;
9+ using System . Runtime . InteropServices ;
810using System . Threading ;
911using System . Threading . Tasks ;
1012
1113namespace Nickvision . Desktop . GNOME . Hosting ;
1214
1315public class AdwUserInterfaceThread : IDisposable , IUserInterfaceThread
1416{
17+ private readonly ILogger < AdwUserInterfaceThread > _logger ;
1518 private readonly IServiceProvider _serviceProvider ;
1619 private readonly IHostApplicationLifetime _lifetime ;
1720 private readonly AdwUserInterfaceContext _context ;
18- private readonly ManualResetEvent _serviceManualResetEvent ;
21+ private readonly ManualResetEvent ? _serviceManualResetEvent ;
1922 private WindowExtensions . OpenCallback ? _openCallback ;
2023
21- public AdwUserInterfaceThread ( IServiceProvider serviceProvider , IHostApplicationLifetime lifetime , AdwUserInterfaceContext context )
24+ public AdwUserInterfaceThread ( ILogger < AdwUserInterfaceThread > logger , IServiceProvider serviceProvider , IHostApplicationLifetime lifetime , AdwUserInterfaceContext context )
2225 {
26+ _logger = logger ;
2327 _serviceProvider = serviceProvider ;
2428 _lifetime = lifetime ;
2529 _context = context ;
26- _serviceManualResetEvent = new ManualResetEvent ( false ) ;
27- var thread = new Thread ( ( ) =>
30+ if ( OperatingSystem . IsMacOS ( ) )
2831 {
29- var argumentsService = _serviceProvider . GetRequiredService < IArgumentsService > ( ) ;
30- _context . Application = _serviceProvider . GetRequiredService < Adw . Application > ( ) ;
31- _context . Application . OnStartup += ( _ , _ ) => _context . Application . AddWindow ( _serviceProvider . GetRequiredService < Adw . ApplicationWindow > ( ) ) ;
32- _context . Application . OnShutdown += ( _ , _ ) =>
32+ InitializeApplication ( ) ;
33+ }
34+ else
35+ {
36+ _serviceManualResetEvent = new ManualResetEvent ( false ) ;
37+ var thread = new Thread ( ( ) =>
3338 {
39+ InitializeApplication ( ) ;
40+ var argumentsService = _serviceProvider . GetRequiredService < IArgumentsService > ( ) ;
41+ _ = _serviceManualResetEvent . WaitOne ( ) ;
42+ _context . IsRunning = true ;
43+ _context . Application ! . RunWithSynchronizationContext ( argumentsService . Data . ToArray ( ) ) ;
3444 _context . IsRunning = false ;
35- if ( ! _lifetime . ApplicationStarted . IsCancellationRequested && _lifetime . ApplicationStopping . IsCancellationRequested )
36- {
37- _lifetime . StopApplication ( ) ;
38- }
39- } ;
40- _context . Application . OnActivate += ( _ , _ ) => _serviceProvider . GetRequiredService < Adw . ApplicationWindow > ( ) . Present ( ) ;
41- if ( _context . HandlesOpen )
45+ } )
4246 {
43- _openCallback = ( nint application , nint [ ] files , int n_files , nint hint , nint data ) =>
44- {
45- foreach ( var file in files )
46- {
47- if ( OperatingSystem . IsWindows ( ) )
48- {
49- argumentsService . Add ( WindowsImports . g_file_get_uri ( file ) ) ;
50- }
51- else if ( OperatingSystem . IsLinux ( ) )
52- {
53- argumentsService . Add ( LinuxImports . g_file_get_uri ( file ) ) ;
54- }
55- else if ( OperatingSystem . IsMacOS ( ) )
56- {
57- argumentsService . Add ( MacOSImports . g_file_get_uri ( file ) ) ;
58- }
59- }
60- _context . Application . Activate ( ) ;
61- } ;
62- if ( OperatingSystem . IsWindows ( ) )
63- {
64- WindowsImports . g_signal_connect_data ( _context . Application . Handle . DangerousGetHandle ( ) , "open" , _openCallback , nint . Zero , nint . Zero , 0 ) ;
65- }
66- else if ( OperatingSystem . IsLinux ( ) )
67- {
68- LinuxImports . g_signal_connect_data ( _context . Application . Handle . DangerousGetHandle ( ) , "open" , _openCallback , nint . Zero , nint . Zero , 0 ) ;
69- }
70- else if ( OperatingSystem . IsMacOS ( ) )
71- {
72- MacOSImports . g_signal_connect_data ( _context . Application . Handle . DangerousGetHandle ( ) , "open" , _openCallback , nint . Zero , nint . Zero , 0 ) ;
73- }
74- }
75- _ = _serviceManualResetEvent . WaitOne ( ) ;
76- _context . IsRunning = true ;
77- _context . Application . RunWithSynchronizationContext ( argumentsService . Data . ToArray ( ) ) ;
78- _context . IsRunning = false ;
79- } )
80- {
81- IsBackground = true
82- } ;
83- thread . Start ( ) ;
47+ IsBackground = true
48+ } ;
49+ thread . Start ( ) ;
50+ }
8451 }
8552
8653 ~ AdwUserInterfaceThread ( )
@@ -96,7 +63,19 @@ public void Dispose()
9663
9764 public Task StartAsync ( )
9865 {
99- _serviceManualResetEvent . Set ( ) ;
66+ if ( OperatingSystem . IsMacOS ( ) )
67+ {
68+ var argumentsService = _serviceProvider . GetRequiredService < IArgumentsService > ( ) ;
69+ _lifetime . ApplicationStopping . Register ( ( ) => _context . Application ? . Quit ( ) ) ;
70+ _context . IsRunning = true ;
71+ _context . Application ! . RunWithSynchronizationContext ( argumentsService . Data . ToArray ( ) ) ;
72+ _context . IsRunning = false ;
73+ _lifetime . StopApplication ( ) ;
74+ }
75+ else
76+ {
77+ _serviceManualResetEvent ! . Set ( ) ;
78+ }
10079 return Task . CompletedTask ;
10180 }
10281
@@ -112,6 +91,80 @@ private void Dispose(bool disposing)
11291 {
11392 return ;
11493 }
115- _serviceManualResetEvent . Dispose ( ) ;
94+ _serviceManualResetEvent ? . Dispose ( ) ;
95+ }
96+
97+ private void InitializeApplication ( )
98+ {
99+ var argumentsService = _serviceProvider . GetRequiredService < IArgumentsService > ( ) ;
100+ _context . Application = _serviceProvider . GetRequiredService < Adw . Application > ( ) ;
101+ _context . Application . OnStartup += ( _ , _ ) => _context . Application . AddWindow ( _serviceProvider . GetRequiredService < Adw . ApplicationWindow > ( ) ) ;
102+ _context . Application . OnShutdown += ( _ , _ ) =>
103+ {
104+ _context . IsRunning = false ;
105+ if ( ! OperatingSystem . IsMacOS ( ) && ! _lifetime . ApplicationStarted . IsCancellationRequested && _lifetime . ApplicationStopping . IsCancellationRequested )
106+ {
107+ _lifetime . StopApplication ( ) ;
108+ }
109+ } ;
110+ _context . Application . OnActivate += ( _ , _ ) => _serviceProvider . GetRequiredService < Adw . ApplicationWindow > ( ) . Present ( ) ;
111+ GLib . Functions . LogSetWriterFunc ( ( logLevel , fields ) =>
112+ {
113+ foreach ( var field in fields )
114+ {
115+ if ( field . Key != "MESSAGE" )
116+ {
117+ continue ;
118+ }
119+ var ptr = field . Handle . DangerousGetHandle ( ) ;
120+ var length = Marshal . ReadIntPtr ( ptr , IntPtr . Size * 2 ) . ToInt64 ( ) ;
121+ var message = length >= 0 ? Marshal . PtrToStringUTF8 ( Marshal . ReadIntPtr ( ptr , IntPtr . Size ) , ( int ) length ) : Marshal . PtrToStringUTF8 ( Marshal . ReadIntPtr ( ptr , IntPtr . Size ) ) ;
122+ _logger . Log ( logLevel switch
123+ {
124+ GLib . LogLevelFlags . LevelError => LogLevel . Error ,
125+ GLib . LogLevelFlags . LevelCritical => LogLevel . Critical ,
126+ GLib . LogLevelFlags . LevelWarning => LogLevel . Warning ,
127+ GLib . LogLevelFlags . LevelMessage => LogLevel . Information ,
128+ GLib . LogLevelFlags . LevelInfo => LogLevel . Information ,
129+ GLib . LogLevelFlags . LevelDebug => LogLevel . Debug ,
130+ _ => LogLevel . None
131+ } , message ? . Trim ( ) ) ;
132+ }
133+ return GLib . LogWriterOutput . Handled ;
134+ } ) ;
135+ if ( _context . HandlesOpen )
136+ {
137+ _openCallback = ( nint application , nint [ ] files , int n_files , nint hint , nint data ) =>
138+ {
139+ foreach ( var file in files )
140+ {
141+ if ( OperatingSystem . IsWindows ( ) )
142+ {
143+ argumentsService . Add ( WindowsImports . g_file_get_uri ( file ) ) ;
144+ }
145+ else if ( OperatingSystem . IsLinux ( ) )
146+ {
147+ argumentsService . Add ( LinuxImports . g_file_get_uri ( file ) ) ;
148+ }
149+ else if ( OperatingSystem . IsMacOS ( ) )
150+ {
151+ argumentsService . Add ( MacOSImports . g_file_get_uri ( file ) ) ;
152+ }
153+ }
154+ _context . Application . Activate ( ) ;
155+ } ;
156+ if ( OperatingSystem . IsWindows ( ) )
157+ {
158+ WindowsImports . g_signal_connect_data ( _context . Application . Handle . DangerousGetHandle ( ) , "open" , _openCallback , nint . Zero , nint . Zero , 0 ) ;
159+ }
160+ else if ( OperatingSystem . IsLinux ( ) )
161+ {
162+ LinuxImports . g_signal_connect_data ( _context . Application . Handle . DangerousGetHandle ( ) , "open" , _openCallback , nint . Zero , nint . Zero , 0 ) ;
163+ }
164+ else if ( OperatingSystem . IsMacOS ( ) )
165+ {
166+ MacOSImports . g_signal_connect_data ( _context . Application . Handle . DangerousGetHandle ( ) , "open" , _openCallback , nint . Zero , nint . Zero , 0 ) ;
167+ }
168+ }
116169 }
117- }
170+ }
0 commit comments