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
  • Loading branch information
danwalmsley authored Jul 18, 2022
2 parents f0e53ba + edede8c commit 2224ff9
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ public IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func

var control = createDefault();
var nodes = Path.GetFullPath(Path.Combine(typeof(EmbedSample).Assembly.GetModules()[0].FullyQualifiedName,
"..",
"nodes.mp4"));
"..", "NativeControls", "Gtk", "nodes.mp4"));
_mplayer = Process.Start(new ProcessStartInfo("mplayer",
$"-vo x11 -zoom -loop 0 -wid {control.Handle.ToInt64()} \"{nodes}\"")
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Avalonia.Controls.Platform;
using Avalonia.Platform.Interop;
using Avalonia.X11.Interop;
using Avalonia.X11.NativeDialogs;
using static Avalonia.X11.NativeDialogs.Gtk;
using static Avalonia.X11.NativeDialogs.Glib;
Expand All @@ -10,8 +11,6 @@ namespace ControlCatalog.NetCore;

internal class GtkHelper
{
private static Task<bool> s_gtkTask;

class FileChooser : INativeControlHostDestroyableControlHandle
{
private readonly IntPtr _widget;
Expand All @@ -38,11 +37,7 @@ public void Destroy()

public static INativeControlHostDestroyableControlHandle CreateGtkFileChooser(IntPtr parentXid)
{
if (s_gtkTask == null)
s_gtkTask = StartGtk();
if (!s_gtkTask.Result)
return null;
return RunOnGlibThread(() =>
return GtkInteropHelper.RunOnGlibThread(() =>
{
using (var title = new Utf8Buffer("Embedded"))
{
Expand Down
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 @@ -256,10 +258,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 @@ -293,7 +304,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 2224ff9

Please sign in to comment.