mono / gtk-sharp

Gtk# is a Mono/.NET binding to the cross platform Gtk+ GUI toolkit and the foundation of most GUI apps built with Mono
http://www.mono-project.com/GtkSharp
Other
426 stars 141 forks source link

Attempt at getting Gdk events to get finalized and freed on the UI th… #254

Closed Therzok closed 5 years ago

Therzok commented 5 years ago

…read

Possible fix for VSTS #739030 - Visual Studio Community 7.7 for Mac - crahses when holding down cursor key

Therzok commented 5 years ago

Updated with PR feedback.

slluis commented 5 years ago

@alanmcgovern can you review?

Therzok commented 5 years ago
using System;
using System.IO;
using Gdk;
using Gtk;

public partial class MainWindow : Gtk.Window
{
    public MainWindow() : base(Gtk.WindowType.Toplevel)
    {
        Build();
    }

    protected override bool OnExposeEvent(EventExpose evnt)
    {
        for (int i = 0; i < 1000000; ++i)
        {
            var ev = Gtk.Application.CurrentEvent;
            var copy = new Gdk.Event(ev.Handle, true);
        }

        System.GC.Collect();
        System.GC.Collect();
        System.GC.Collect();
        System.GC.WaitForPendingFinalizers();

        return base.OnExposeEvent(evnt);
    }
}

    public class MainClass
    {
        public static void Main(string[] args)
        {
            Application.Init();

            var mw = new MainWindow();
            mw.ShowAll();

            Application.Run();

        }
    }
Therzok commented 5 years ago

Actually, this doesn't fix the issue...

The event goes out of scope and it gets freed by native gtk. I think our only solution is to make it a ref struct and avoid the value from escaping, otherwise it'll just free invalid memory.

Therzok commented 5 years ago

I thought it was an UI thread bug, but it can still happen.

Therzok commented 5 years ago

EventOwnerChange as it's not read-only, the rest of the events could be solved by just making a copy of the GdkEvent.

Therzok commented 5 years ago

Closing. The problem with Gdk.Event is how it's bound and it requires breaking API to fix. We worked around it in VSMac by manually pinvoking