hugopl / gtk4.cr

GTK4 bindings for Crystal
https://hugopl.github.io/gtk4.cr/
MIT License
101 stars 8 forks source link

`target` in `Gio::MenuItem#set_action_and_target_value` cannot be set (Runtime Exception) #22

Closed BlobCodes closed 2 years ago

BlobCodes commented 2 years ago

The GVariant target cannot be passed to Gio::MenuItem#set_action_and_target_value.

Test code:

require "gtk4"

menu_item = Gio::MenuItem.new(nil, nil)

# Does not work
variant = GLib::Variant.new("test")
menu_item.set_action_and_target_value("app.some_action", variant)

# Also does not work
menu_item.set_action_and_target_value("app.some_action", "test")

# Not even this works
menu_item.set_action_and_target_value("app.some_action", nil)

Exception:

# Exception 1

Unhandled exception: Unable to wrap a Pointer(Void) into a GVariant. (ArgumentError)
  from lib/gtk4/lib/gi-crystal/src/bindings/g_lib/variant.cr:20:15 in 'initialize'
  from lib/gtk4/lib/gi-crystal/src/bindings/g_lib/variant.cr:5:5 in 'new'
  from lib/gtk4/lib/gi-crystal/src/auto/gio-2.0/menu_item.cr:272:7 in 'set_action_and_target_value'
  from src/test2.cr:19:1 in '__crystal_main'
  from /usr/share/crystal/src/crystal/main.cr:115:5 in 'main_user_code'
  from /usr/share/crystal/src/crystal/main.cr:101:7 in 'main'
  from /usr/share/crystal/src/crystal/main.cr:127:3 in 'main'
  from /lib64/libc.so.6 in '??'
  from /lib64/libc.so.6 in '__libc_start_main'
  from /var/home/blobcodes/.cache/crystal/crystal-run-test2.tmp in '_start'
  from ???

# Exception 2

Unhandled exception: Unable to wrap a Pointer(UInt8) into a GVariant. (ArgumentError)
  from lib/gtk4/lib/gi-crystal/src/bindings/g_lib/variant.cr:5:5 in 'initialize'
  from lib/gtk4/lib/gi-crystal/src/bindings/g_lib/variant.cr:5:5 in 'new'
  from lib/gtk4/lib/gi-crystal/src/auto/gio-2.0/menu_item.cr:272:7 in 'set_action_and_target_value'
  from src/test2.cr:17:1 in '__crystal_main'
  from /usr/share/crystal/src/crystal/main.cr:115:5 in 'main_user_code'
  from /usr/share/crystal/src/crystal/main.cr:101:7 in 'main'
  from /usr/share/crystal/src/crystal/main.cr:127:3 in 'main'
  from /lib64/libc.so.6 in '??'
  from /lib64/libc.so.6 in '__libc_start_main'
  from /var/home/blobcodes/.cache/crystal/crystal-run-test2.tmp in '_start'
  from ???

Gio::MenuItem#set_action_and_target_value implementation:

    def set_action_and_target_value(action : ::String?, target_value : _?) : Nil
      # g_menu_item_set_action_and_target_value: (Method)
      # @action: (nullable)
      # @target_value: (nullable)
      # Returns: (transfer none)

      # Generator::NullableArrayPlan
      action = if action.nil?
                 Pointer(LibC::Char).null
               else
                 action.to_unsafe
               end

      # Generator::NullableArrayPlan
      target_value = if target_value.nil?
                       Pointer(Void).null
                     else
                       target_value.to_unsafe
                     end

      # Generator::HandmadeArgPlan
      target_value = GLib::Variant.new(target_value) unless target_value.is_a?(GLib::Variant)

      # C call
      LibGio.g_menu_item_set_action_and_target_value(self, action, target_value)

      # Return value handling
    end

I think the conversion to a GLib::Variant has to be done before using to_unsafe.

hugopl commented 2 years ago

At a first look seems that Generator::NullableArrayPlan must do nothing on handmade types.