This is a fork of hugopl/gtk4.cr, but with GTK3. Please see that other repo for details.
There's also the more popular and more battle-tested jhass/crystal-gobject for GTK3. Both bindings are not compatible, but migrating is not hard. I made this very alternative because when I used the other one, there were rare different rare crashes which I couldn't resolve.
If you need AT-SPI, you can use https://github.com/phil294/atspi.cr.
Crystal's garbage collector [GC] normally runs in somewhat unpredictable intervals. This can lead to crashes, sometimes. The following precautions seem to resolve them (entirely?). Maybe they only occur with -Dpreview_mt
only anyway.
You'll see a lot of GLib-GObject-CRITICAL **:
etc. error messages in the console all the time. I guess they're not avoidable for now.
- Call GC manually before and after running Gtk code. Example: Instead of
do
GLib.idle_add do { gtk code... }
Those Glib error messages mentioned above will still show up, but now exactly when you instruct it to, so it doesn't interfere with the Gtk thread.GC.collect GLib.idle_add do { gtk code...} GC.collect
- Avoid
begin
/rescue
inside destroy handlers. Example:this will somehow lead to crasheswindow.destroy_signal.connect do begin raise "asdf" rescue e STDERR.puts e end
- When you have many invocations of
idle_add
in a short timeframe (e.g. 1000 within 1 second), you should wait for each of those to complete before querying the next to avoid crashes. Example: Instead ofdodef my_gtk_act_function(&block : -> nil) GC.collect GLib.idle_add do block.call false end GC.collect end 1000.times { my_gtk_act_function { ... } }
Where the second method also offers the capability of error handling or returning values as well, at the expense of speed.def my_gtk_act_function(&block : -> nil) channel = Channel(Nil).new GC.collect GLib.idle_add do block.call channel.send(nil) false end channel.receive GC.collect end 1000.times { my_gtk_act_function { ... } }