Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

X11: System.Exception: Unable to initialize GTK on separate thread

Open jgcodes2020 opened this issue 1 year ago • 3 comments

Describe the bug The exception in the title is thrown when opening a file dialog.

To Reproduce Create a new project using the Avalonia .NET Core App template. (NOT THE MVVM ONE). Here's the relevant code that triggers the exception:

<!-- MainWindow.axaml -->
<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="JGCodes.AvaloniaTest.MainWindow"
        Title="Avalonia Test">
    <Button Name="SpecialButton" Click="OnButtonClick">Open, sesame!</Button>
</Window>
// MainWindow.axaml.cs
using Avalonia.Controls;
using Avalonia.Interactivity;

namespace JGCodes.AvaloniaTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public async void OnButtonClick(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new();
            await ofd.ShowAsync(this);
        }
    }
}

Run the project, click the button, and receive the above exception.

Expected behavior A file dialog should appear.

Desktop (please complete the following information):

  • OS: Linux (ArcoLinux, KDE, XWayland)
  • Version 0.10.17

Additional context N/A

jgcodes2020 avatar Jul 28 '22 19:07 jgcodes2020

Please check if you have libgtk-3.so.0 on your machine.

kekekeks avatar Jul 28 '22 19:07 kekekeks

image I do.

jgcodes2020 avatar Jul 28 '22 20:07 jgcodes2020

In the same case, execute await dlg.ShowAsync(parent: this); The UI is hang.

System: Ubuntu 22.04.1 LTS (GNU/Linux 5.15.57.1-microsoft-standard-WSL2 x86_64)

libgtk-3.so.0:

find . -name 'libgtk-3.so.0' -ls 33584910 0 lrwxrwxrwx 1 root root 21 5月 10 04:15 ./x86_64-linux-gnu/libgtk-3.so.0 -> libgtk-3.so.0.2404.29

submaie avatar Sep 05 '22 05:09 submaie

We're getting 1-2 hits of this every day. Lots of snap users getting this issue.

Exception Unable to initialize GTK on separate thread /    at Avalonia.X11.NativeDialogs.GtkSystemDialog.EnsureInitialized()
   at Avalonia.X11.NativeDialogs.GtkSystemDialog.ShowFileDialogAsync(FileDialog dialog, Window parent)
   at Avalonia.Controls.SaveFileDialog.ShowAsync(Window parent)
   at Lunacy.Services.DialogService.SaveAsync(String defaultFileName, String[] fileTypeFilter) in /root/parts/lunacy/build/Lunacy/Lunacy.UI/Services/DialogService.cs:line 66
8.7.2.0 (Snapcraft), 370s, 557MB usage, fedora/ryan, Linux X64: Linux 5.17.5-300.fc36.x86_64 #1 SMP PREEMPT Thu Apr 28 15:51:30 UTC 2022, 4 cores

Mikolaytis avatar Dec 25 '22 20:12 Mikolaytis

I've come to an idea that for linux - managed open/save file dialogs is a preferred option. This is an easy and almost 100% fix of this issue.

Mikolaytis avatar Dec 25 '22 20:12 Mikolaytis

@Mikolaytis on 11.0 we use FreeDesktop/dBus picker by default, which should work better.

maxkatz6 avatar Dec 25 '22 21:12 maxkatz6

Got a similar problem Arch, KDE Plasma, OpenFileDialog just hangs.

brunzefb avatar Dec 27 '22 04:12 brunzefb

FWIW, my workaround. below the ViewModel code, use binding to the view model. You do need kdialog installed on KDE systems for this to work.

     <Button 
                Command="{Binding OpenFileCommand}"
                Margin="0,0,10,0"
                VerticalAlignment="Center" 
                HorizontalAlignment="Right"
                Height="26"
                FontSize="11"
                Content="_Open..." />

Here the ViewModel code


    public void OpenFileCommand()
    {
        var helper = new OpenDlgHelper();
        var result = helper.GetFileName();
        HexFile = string.IsNullOrEmpty(result) ? _prompt : result;
    }

And here the helper class

using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace QMK_Toolbox;

public class OpenDlgHelper
{
    public StringBuilder sb { get; set; }
    
    public string GetFileName()
    {
        RunProcessAsync("/usr/bin/kdialog", "--getopenfilename /home/").Wait();
        return sb.ToString();
    }

    private async Task<int> RunProcessAsync(string command, string args)
    {
        sb = new StringBuilder();
        using (var process = new Process
               {
                   StartInfo =
                   {
                       FileName = command,
                       Arguments = args,
                       WorkingDirectory = Path.GetDirectoryName(command),
                       UseShellExecute = false,
                       CreateNoWindow = true,
                       RedirectStandardOutput = true,
                       RedirectStandardError = true
                   },
                   EnableRaisingEvents = true
               })
        {
            return await RunProcessAsync(process).ConfigureAwait(false);
        }
    }

    private Task<int> RunProcessAsync(Process process)
    {
        var tcs = new TaskCompletionSource<int>();

        process.Exited += (sender, e) =>
        {
            process.WaitForExit();
            tcs.SetResult(process.ExitCode);
        };

        process.OutputDataReceived += ProcessOutput;
        process.ErrorDataReceived += ProcessErrorOutput;

        bool started = process.Start();
        if (!started)
        {
            Debug.WriteLine($"Could not start process: {process}");
        }

        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        return tcs.Task;
    }

    private void ProcessOutput(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null)
        {
            sb.Append(e.Data);
        }
    }

    private void ProcessErrorOutput(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null)
        {
            Debug.WriteLine(e.Data);
        }
    }
}

brunzefb avatar Dec 27 '22 04:12 brunzefb

Should be fixed with 11.0 previews, as we use FreeDesktop dialogs instead, when available. Also, GTK initialization was changed, which might also solve old issue, if FreeDesktop is not available.

Please let us know if it's still a problem in 11.0 previews.

maxkatz6 avatar Jan 12 '23 05:01 maxkatz6