Skip to content

Commit 801b203

Browse files
committed
Call gtk quit
1 parent 5d207fb commit 801b203

File tree

6 files changed

+190
-54
lines changed

6 files changed

+190
-54
lines changed

AssetRipper.NativeDialogs/ConfirmationDialog.cs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,26 @@ public Options(string message, Type type = Type.OkCancel)
115115
{
116116
if (Gtk.Global.IsSupported)
117117
{
118-
bool? result;
119-
GtkHelper.EnsureInitialized();
118+
return ConfirmLinuxGtk(options);
119+
}
120+
else
121+
{
122+
// Fallback
123+
return Task.FromResult<bool?>(null);
124+
}
125+
}
126+
127+
[SupportedOSPlatform("linux")]
128+
private static async Task<bool?> ConfirmLinuxGtk(Options options)
129+
{
130+
bool? result;
131+
while (!GtkHelper.TryInitialize())
132+
{
133+
await GtkHelper.Delay(); // Wait for the GTK initialization to complete
134+
}
120135

136+
try
137+
{
121138
using Gtk.MessageDialog md = new(
122139
null,
123140
Gtk.DialogFlags.Modal,
@@ -133,13 +150,12 @@ public Options(string message, Type type = Type.OkCancel)
133150
(int)Gtk.ResponseType.Cancel or (int)Gtk.ResponseType.No => false,
134151
_ => throw new($"Unexpected response type: {response}"),
135152
};
136-
137-
return Task.FromResult(result);
138153
}
139-
else
154+
finally
140155
{
141-
// Fallback
142-
return Task.FromResult<bool?>(null);
156+
GtkHelper.Shutdown(); // Ensure GTK is properly shut down after use
143157
}
158+
159+
return result;
144160
}
145161
}
Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
1-
namespace AssetRipper.NativeDialogs;
1+
using System.Diagnostics;
2+
3+
namespace AssetRipper.NativeDialogs;
24

35
internal static class GtkHelper
46
{
57
private static bool isInitialized;
68

7-
public static void EnsureInitialized()
9+
public static bool TryInitialize()
810
{
9-
if (!isInitialized)
11+
bool wasInitialized = Interlocked.CompareExchange(ref isInitialized, true, false);
12+
if (wasInitialized)
1013
{
11-
Gtk.Application.Init();
12-
isInitialized = true;
14+
return false; // Already initialized
1315
}
16+
17+
Gtk.Application.Init();
18+
return true; // Successfully initialized
19+
}
20+
21+
public static Task Delay()
22+
{
23+
return Task.Delay(100); // Wait for 100 milliseconds
24+
}
25+
26+
public static void Shutdown()
27+
{
28+
Debug.Assert(isInitialized);
29+
Gtk.Application.Quit();
30+
isInitialized = false;
1431
}
1532
}

AssetRipper.NativeDialogs/MessageDialog.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,25 @@ private static Task MessageLinux(Options options)
8383
{
8484
if (Gtk.Global.IsSupported)
8585
{
86-
GtkHelper.EnsureInitialized();
86+
return MessageLinuxGtk(options);
87+
}
88+
else
89+
{
90+
// Fallback
91+
return Task.CompletedTask;
92+
}
93+
}
94+
95+
[SupportedOSPlatform("linux")]
96+
private static async Task MessageLinuxGtk(Options options)
97+
{
98+
while (!GtkHelper.TryInitialize())
99+
{
100+
await GtkHelper.Delay(); // Wait for the GTK initialization to complete
101+
}
87102

103+
try
104+
{
88105
using Gtk.MessageDialog md = new(
89106
null,
90107
Gtk.DialogFlags.Modal,
@@ -93,13 +110,10 @@ private static Task MessageLinux(Options options)
93110
options.Message
94111
);
95112
md.Run();
96-
97-
return Task.CompletedTask;
98113
}
99-
else
114+
finally
100115
{
101-
// Fallback
102-
return Task.CompletedTask;
116+
GtkHelper.Shutdown(); // Ensure GTK is properly shut down after use
103117
}
104118
}
105119
}

AssetRipper.NativeDialogs/OpenFileDialog.cs

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Buffers;
2+
using System.Diagnostics;
23
using System.Runtime.CompilerServices;
34
using System.Runtime.Versioning;
45
using TerraFX.Interop.Windows;
@@ -73,9 +74,28 @@ public static class OpenFileDialog
7374
{
7475
if (Gtk.Global.IsSupported)
7576
{
76-
string? result;
77-
GtkHelper.EnsureInitialized();
77+
return OpenFileLinuxGtk();
78+
}
79+
else
80+
{
81+
// Fallback
82+
return Task.FromResult<string?>(null);
83+
}
84+
}
85+
86+
[SupportedOSPlatform("linux")]
87+
private static async Task<string?> OpenFileLinuxGtk()
88+
{
89+
Debug.Assert(Gtk.Global.IsSupported);
7890

91+
string? result;
92+
while (!GtkHelper.TryInitialize())
93+
{
94+
await GtkHelper.Delay(); // Wait for the GTK initialization to complete
95+
}
96+
97+
try
98+
{
7999
using Gtk.FileChooserNative dlg = new(
80100
"Open a file", null,
81101
Gtk.FileChooserAction.Open, "Open", "Cancel");
@@ -88,14 +108,13 @@ public static class OpenFileDialog
88108
{
89109
result = null; // User canceled the dialog
90110
}
91-
92-
return Task.FromResult(result);
93111
}
94-
else
112+
finally
95113
{
96-
// Fallback
97-
return Task.FromResult<string?>(null);
114+
GtkHelper.Shutdown(); // Ensure GTK is properly shut down after use
98115
}
116+
117+
return result;
99118
}
100119

101120
public static Task<string[]?> OpenFiles()
@@ -196,9 +215,28 @@ public static class OpenFileDialog
196215
{
197216
if (Gtk.Global.IsSupported)
198217
{
199-
string[]? result;
200-
GtkHelper.EnsureInitialized();
218+
return OpenFilesLinuxGtk();
219+
}
220+
else
221+
{
222+
// Fallback
223+
return Task.FromResult<string[]?>(null);
224+
}
225+
}
226+
227+
[SupportedOSPlatform("linux")]
228+
private static async Task<string[]?> OpenFilesLinuxGtk()
229+
{
230+
Debug.Assert(Gtk.Global.IsSupported);
201231

232+
string[]? result;
233+
while (!GtkHelper.TryInitialize())
234+
{
235+
await GtkHelper.Delay(); // Wait for the GTK initialization to complete
236+
}
237+
238+
try
239+
{
202240
using Gtk.FileChooserNative dlg = new(
203241
"Open files", null,
204242
Gtk.FileChooserAction.Open, "Open", "Cancel");
@@ -213,13 +251,12 @@ public static class OpenFileDialog
213251
{
214252
result = null; // User canceled the dialog
215253
}
216-
217-
return Task.FromResult(result);
218254
}
219-
else
255+
finally
220256
{
221-
// Fallback
222-
return Task.FromResult<string[]?>(null);
257+
GtkHelper.Shutdown(); // Ensure GTK is properly shut down after use
223258
}
259+
260+
return result;
224261
}
225262
}

AssetRipper.NativeDialogs/OpenFolderDialog.cs

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,30 @@ public static class OpenFolderDialog
124124
{
125125
if (Gtk.Global.IsSupported)
126126
{
127-
string? result;
128-
GtkHelper.EnsureInitialized();
127+
return OpenFolderLinuxGtk();
128+
}
129+
else
130+
{
131+
// Fallback
132+
return Task.FromResult<string?>(null);
133+
}
134+
}
135+
136+
[SupportedOSPlatform("linux")]
137+
private static async Task<string?> OpenFolderLinuxGtk()
138+
{
139+
Debug.Assert(Gtk.Global.IsSupported);
129140

141+
string? result;
142+
while (!GtkHelper.TryInitialize())
143+
{
144+
await GtkHelper.Delay(); // Wait for the GTK initialization to complete
145+
}
146+
147+
try
148+
{
130149
using Gtk.FileChooserNative dlg = new(
131-
"Open a folder", null,
150+
"Open folder", null,
132151
Gtk.FileChooserAction.SelectFolder, "Open", "Cancel");
133152

134153
if (dlg.Run() == (int)Gtk.ResponseType.Accept)
@@ -139,14 +158,13 @@ public static class OpenFolderDialog
139158
{
140159
result = null; // User canceled the dialog
141160
}
142-
143-
return Task.FromResult(result);
144161
}
145-
else
162+
finally
146163
{
147-
// Fallback
148-
return Task.FromResult<string?>(null);
164+
GtkHelper.Shutdown(); // Ensure GTK is properly shut down after use
149165
}
166+
167+
return result;
150168
}
151169

152170
public static Task<string[]?> OpenFolders()
@@ -297,9 +315,28 @@ public static class OpenFolderDialog
297315
{
298316
if (Gtk.Global.IsSupported)
299317
{
300-
string[]? result;
301-
GtkHelper.EnsureInitialized();
318+
return OpenFoldersLinuxGtk();
319+
}
320+
else
321+
{
322+
// Fallback
323+
return Task.FromResult<string[]?>(null);
324+
}
325+
}
326+
327+
[SupportedOSPlatform("linux")]
328+
private static async Task<string[]?> OpenFoldersLinuxGtk()
329+
{
330+
Debug.Assert(Gtk.Global.IsSupported);
302331

332+
string[]? result;
333+
while (!GtkHelper.TryInitialize())
334+
{
335+
await GtkHelper.Delay(); // Wait for the GTK initialization to complete
336+
}
337+
338+
try
339+
{
303340
using Gtk.FileChooserNative dlg = new(
304341
"Open folders", null,
305342
Gtk.FileChooserAction.SelectFolder, "Open", "Cancel");
@@ -314,13 +351,12 @@ public static class OpenFolderDialog
314351
{
315352
result = null; // User canceled the dialog
316353
}
317-
318-
return Task.FromResult(result);
319354
}
320-
else
355+
finally
321356
{
322-
// Fallback
323-
return Task.FromResult<string[]?>(null);
357+
GtkHelper.Shutdown(); // Ensure GTK is properly shut down after use
324358
}
359+
360+
return result;
325361
}
326362
}

AssetRipper.NativeDialogs/SaveFileDialog.cs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,26 @@ public static class SaveFileDialog
7575
{
7676
if (Gtk.Global.IsSupported)
7777
{
78-
string? result;
79-
GtkHelper.EnsureInitialized();
78+
return SaveFileLinuxGtk();
79+
}
80+
else
81+
{
82+
// Fallback
83+
return Task.FromResult<string?>(null);
84+
}
85+
}
86+
87+
[SupportedOSPlatform("linux")]
88+
private static async Task<string?> SaveFileLinuxGtk()
89+
{
90+
string? result;
91+
while (!GtkHelper.TryInitialize())
92+
{
93+
await GtkHelper.Delay(); // Wait for the GTK initialization to complete
94+
}
8095

96+
try
97+
{
8198
using Gtk.FileChooserNative dlg = new(
8299
"Save a file", null,
83100
Gtk.FileChooserAction.Save, "Save", "Cancel");
@@ -90,13 +107,12 @@ public static class SaveFileDialog
90107
{
91108
result = null; // User canceled the dialog
92109
}
93-
94-
return Task.FromResult(result);
95110
}
96-
else
111+
finally
97112
{
98-
// Fallback
99-
return Task.FromResult<string?>(null);
113+
GtkHelper.Shutdown(); // Ensure GTK is properly shut down after use
100114
}
115+
116+
return result;
101117
}
102118
}

0 commit comments

Comments
 (0)