gtk3.cr

forked from hugopl/gtk4.cr
GTK3 bindings for Crystal

GTK3 Crystal Bindings

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.

GC-related problems

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.

  1. Call GC manually before and after running Gtk code. Example: Instead of
    GLib.idle_add do { gtk code... }
    
    do
    GC.collect
    GLib.idle_add do { gtk code...}
    GC.collect
    
    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.
  2. Avoid begin/rescue inside destroy handlers. Example:
    window.destroy_signal.connect do
      begin
        raise "asdf"
      rescue e
        STDERR.puts e
    end
    
    this will somehow lead to crashes
  3. 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 of
    def 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 { ... } }
    
    do
    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 { ... } }
    
    Where the second method also offers the capability of error handling or returning values as well, at the expense of speed.
Repository

gtk3.cr

Owner
Statistic
  • 2
  • 1
  • 0
  • 1
  • 2
  • about 1 month ago
  • February 8, 2023
License

MIT License

Links
Synced at

Tue, 07 May 2024 16:39:24 GMT

Languages