Skip to content

Commit

Permalink
Merge pull request #8538 from AvaloniaUI/feature/expose-gtk-thread-in…
Browse files Browse the repository at this point in the history
…voke

Introduced GtkInteropHelper.RunOnGlibThread, fixed demos
# Conflicts:
#	samples/ControlCatalog.NetCore/NativeControls/Gtk/EmbedSample.Gtk.cs
#	samples/ControlCatalog.NetCore/NativeControls/Gtk/GtkHelper.cs
  • Loading branch information
danwalmsley committed Jul 21, 2022
1 parent 0b525bf commit e975100
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
15 changes: 15 additions & 0 deletions src/Avalonia.X11/Interop/GtkInteropHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;

namespace Avalonia.X11.Interop;

public class GtkInteropHelper
{
public static async Task<T> RunOnGlibThread<T>(Func<T> cb)
{
if (!await NativeDialogs.Gtk.StartGtk().ConfigureAwait(false))
throw new Win32Exception("Unable to initialize GTK");
return await NativeDialogs.Glib.RunOnGlibThread(cb).ConfigureAwait(false);
}
}
27 changes: 24 additions & 3 deletions src/Avalonia.X11/NativeDialogs/Gtk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Platform.Interop;
using JetBrains.Annotations;

// ReSharper disable IdentifierTypo
namespace Avalonia.X11.NativeDialogs
{
Expand Down Expand Up @@ -247,10 +249,19 @@ public static extern void

public static IntPtr GetForeignWindow(IntPtr xid) => gdk_x11_window_foreign_new_for_display(s_display, xid);

static object s_startGtkLock = new();
static Task<bool> s_startGtkTask;

public static Task<bool> StartGtk()
{
var tcs = new TaskCompletionSource<bool>();
new Thread(() =>
return StartGtkCore();
lock (s_startGtkLock)
return s_startGtkTask ??= StartGtkCore();
}

private static void GtkThread(TaskCompletionSource<bool> tcs)
{
try
{
try
{
Expand Down Expand Up @@ -284,7 +295,17 @@ public static Task<bool> StartGtk()
tcs.SetResult(true);
while (true)
gtk_main_iteration();
}) {Name = "GTK3THREAD", IsBackground = true}.Start();
}
catch
{
tcs.SetResult(false);
}
}

private static Task<bool> StartGtkCore()
{
var tcs = new TaskCompletionSource<bool>();
new Thread(() => GtkThread(tcs)) {Name = "GTK3THREAD", IsBackground = true}.Start();
return tcs.Task;
}
}
Expand Down

0 comments on commit e975100

Please sign in to comment.