Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need same cast helper as stringObject() for FileInfo #135

Open
gavr123456789 opened this issue Jun 4, 2021 · 8 comments
Open

Need same cast helper as stringObject() for FileInfo #135

gavr123456789 opened this issue Jun 4, 2021 · 8 comments

Comments

@gavr123456789
Copy link

gavr123456789 commented Jun 4, 2021

import gintro/[gtk4, gobject, gio]
import std/with

proc getFileName(info: gio.FileInfo): string =
  return info.getName()  

proc setup_cb(factory: gtk4.SignalListItemFactory, listitem: gtk4.ListItem) =
  listitem.setChild(newLabel(""))
  
proc bind_cb(factory: gtk4.SignalListItemFactory, listitem: gtk4.ListItem) =
  let 
    lb = listitem.getChild().Label
    strobj = cast[FileInfo](listitem.getItem())

  lb.text = strobj.getFileName()

proc unbind_cb(factory: gtk4.SignalListItemFactory, listitem: gtk4.ListItem) =
  # There's nothing to do here. 
  # If you does something like setting a signal in bind_cb,
  # then disconnecting the signal is necessary in unbind_cb. 
  echo "unbind"

proc teardown_cb(factory: gtk4.SignalListItemFactory, listitem: gtk4.ListItem) =
  listitem.setChild (nil)
  # When the child of listitem is set to NULL, the reference to GtkLabel will be released and lb will be destroyed. 
  # Therefore, g_object_unref () for the GtkLabel object doesn't need in the user code. 

proc activate(app: gtk4.Application) =
  let
    window = newApplicationWindow(app)
    scr = newScrolledWindow()
    file = gio.newGFileForPath(".")
    sl = gtk4.newDirectoryList("standard::name", file)
    ls = listModel(sl)
    ns = gtk4.newNoSelection(ls)
    factory = gtk4.newSignalListItemFactory()
    lv = newListView(ns, factory)
  
  scr.setChild lv

  with factory:
    connect("setup", setup_cb)
    connect("bind", bind_cb)
    connect("unbind", unbind_cb)
    connect("teardown", teardown_cb)

  with window:
    defaultSize = (600, 400)
    title = "Nim ListView"
    setChild scr
    show

proc main =
  let app = newApplication("org.gtk.example")
  app.connect("activate", activate)
  discard run(app)

main()
@StefanSalewski
Copy link
Owner

I was just going to add your requested converter proc, but I noticed that your example code crash when compiled with --gc:arc.

Does it crash for you also, and do you have an idea about the reason already?

Yesterday I discovered another bug myself, see #137

So I think I will call the current version at github 0.90 for now and then try to fix bug #137.

In the last week I spent a lot of time with the listview_clocks example requested by aeldemery.

That example is really low level and too hard for pure Nim currently, but mixing C and Nim code works not that bad, so I got it working. But while playing with it I noticed another issue for the "transfer full" case of proc arguments. An example is

  expression = gtk_property_expression_new (GTK_TYPE_CLOCK,
                                            gtk_expression_ref (clock_expression),
                                            "location");

from listview_clocks.c.

Here the clock expression is a "transfer full" parameter, which is used later in the proc again. So detaching it from the Nim GC with .ignoreFinalizer = true is not the best solution here, we should better call gtk_expression_ref() on the gtk object. I will try that for version 0.91 then.

Another interesting problem is

discard gtk4.bind(expression, location_label, "label", location_label)

Would compile fine without the gtk4. prefix, just using Nim's own bind keyword. But is not working then of course. Took me nearly a full day to find that. I regard that a Nim bug, but I guess reporting to Nim's issue tracker will not help, they will tell us that we should know what we are doing.

@gavr123456789
Copy link
Author

Does it crash for you also, and do you have an idea about the reason already?

Yes, I think this is exactly #137

Traceback (most recent call last)
/home/gavr/Projects/Nim/gintro/examples/gtk4/directory_list.nim(59) directory_list
/home/gavr/Projects/Nim/gintro/examples/gtk4/directory_list.nim(57) main
/home/gavr/.nimble/pkgs/gintro-#head/gintro/gio.nim(31021) run
/usr/lib/nim/core/macros.nim(565) connect_for_signal_cdecl_bind2
/home/gavr/Projects/Nim/gintro/examples/gtk4/directory_list.nim(13) bind_cb
/home/gavr/.nimble/pkgs/gintro-#head/gintro/gtk4.nim(49244) getItem
/usr/lib/nim/system/arc.nim(84) nimNewObj
/usr/lib/nim/system/alloc.nim(958) alloc0
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Error: execution of an external program failed: '/home/gavr/Projects/Nim/gintro/examples/gtk4/directory_list 

@StefanSalewski
Copy link
Owner

OK, following the discussion from

https://discourse.gnome.org/t/get-ref-function-for-none-gobject-classes-like-gtkexpression/6696

with nimble install gintro@#head

your example above should work now. We have also added the fileInfo() converter proc.

  strobj = fileInfo(listitem.getItem())

The existing examples seems to compile still and at least some work, but I have not tested all yet. The Gtk4 fontchooser example fails currently, but that may be due to a change in GTK4 itself.

The listview_clock example works now also, I have split it in a low level C part and a Nim part. That splitting works not bad. I will ship the code soon.

@gavr123456789
Copy link
Author

@StefanSalewski With new version I have error:
/home/gavr/.nimble/pkgs/gintro-#head/gintro/adw.nim(1796, 43) Error: undeclared identifier: 'gtk_expression_ref'
When compile any adwaita example with any GC.

@StefanSalewski
Copy link
Owner

We missed that because we have currently no working adwaita example.

proc getExpression*(self: ComboRow): gtk4.Expression =
  let impl0 = adw_combo_row_get_expression(cast[ptr ComboRow00](self.impl))
  if impl0.isNil:
    return nil
  fnew(result, generic_gtk_expression_unref)
  result.impl = cast[typeof(result.impl)](gtk_expression_ref(impl0))

proc expression*(self: ComboRow): gtk4.Expression =
  let impl0 = adw_combo_row_get_expression(cast[ptr ComboRow00](self.impl))
  if impl0.isNil:
    return nil
  fnew(result, generic_gtk_expression_unref)
  result.impl = cast[typeof(result.impl)](gtk_expression_ref(impl0))

We intentionally do not export gtk_expression_ref() because people shall not use it directly. But as adw.nim needs it we have to export it. So add an export marker to

grep "proc gtk_expression_ref" ~/.nimble/pkgs/gintro-#head/gintro/gtk4.nim 
proc gtk_expression_ref(self: ptr Expression00): ptr Expression00 {.

manually for now. I will fix that soon.

@gavr123456789
Copy link
Author

I have Adwaita examples in my PR

@StefanSalewski
Copy link
Owner

Sorry, please stop further testing for now, we have stupid bugs like

proc getFontDesc*(self: FontChooser | FontChooserWidget | FontChooserDialog | FontButton): pango.FontDescription =
  let impl0 = gtk_font_chooser_get_font_desc(cast[ptr FontChooser00](self.impl))
  if impl0.isNil:
    return nil
  fnew(result, gBoxedFreePangoFontDescription)

Will try to fix it soon, should be easy.

@StefanSalewski
Copy link
Owner

Should be fixed. Fontchooser works, and all including adw.nim compiles. Will do more serious tests soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants