Browse Source

Introduced GtkInteropHelper.RunOnGlibThread, fixed demos

pull/8538/head
Nikita Tsukanov 4 years ago
parent
commit
fa17ee9bb9
  1. 3
      samples/ControlCatalog.NetCore/NativeControls/Gtk/EmbedSample.Gtk.cs
  2. 9
      samples/ControlCatalog.NetCore/NativeControls/Gtk/GtkHelper.cs
  3. 15
      src/Avalonia.X11/Interop/GtkInteropHelper.cs
  4. 27
      src/Avalonia.X11/NativeDialogs/Gtk.cs

3
samples/ControlCatalog.NetCore/NativeControls/Gtk/EmbedSample.Gtk.cs

@ -22,8 +22,7 @@ public class EmbedSampleGtk : INativeDemoControl
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}\"")
{

9
samples/ControlCatalog.NetCore/NativeControls/Gtk/GtkHelper.cs

@ -2,6 +2,7 @@ using System;
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;
@ -10,8 +11,6 @@ namespace ControlCatalog.NetCore;
internal class GtkHelper
{
private static Task<bool> s_gtkTask;
class FileChooser : INativeControlHostDestroyableControlHandle
{
private readonly IntPtr _widget;
@ -38,11 +37,7 @@ internal class GtkHelper
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"))
{

15
src/Avalonia.X11/Interop/GtkInteropHelper.cs

@ -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
src/Avalonia.X11/NativeDialogs/Gtk.cs

@ -3,6 +3,8 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Platform.Interop;
using JetBrains.Annotations;
// ReSharper disable IdentifierTypo
namespace Avalonia.X11.NativeDialogs
{
@ -256,10 +258,19 @@ namespace Avalonia.X11.NativeDialogs
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
{
@ -293,7 +304,17 @@ namespace Avalonia.X11.NativeDialogs
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;
}
}

Loading…
Cancel
Save