StefanSalewski / gintro

High level GObject-Introspection based GTK3/GTK4 bindings for Nim language
MIT License
298 stars 20 forks source link

AsyncReadyCallback signature is low level #146

Open gavr123456789 opened 3 years ago

gavr123456789 commented 3 years ago

Same as https://github.com/StefanSalewski/gintro/issues/142
I will provide vala example soon.
Can you explain why we have 00 version of all types?
Here example Im working on:

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

let readTextCb: AsyncReadyCallback = proc (sourceObject: ptr gobject.Object00; res: ptr AsyncResult00; userData: pointer) {.cdecl.} = 
  echo "sas"
  echo res == nil
  # Trying to get text from res here

  # echo cast[cstring](res[])

proc appActivate(app: Application) =

  let window = newApplicationWindow(app)
  let clb = window.getClipboard()
  clb.readTextAsync(nil, readTextCb, nil)

  with window:
    title = "GTK4 Clipboard example"
    defaultSize = (200, 200)
    show

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

main()

I think AsyncReadyCallback signature should look like

(sourceObject: gobject.Object; res: AsyncResult; userData: pointer) 
StefanSalewski commented 3 years ago

I thought you had retired :-)

Do you still think https://github.com/StefanSalewski/gintro/issues/145 is a memory leak?

For your other question and for https://github.com/StefanSalewski/gintro/issues/142:

For callbacks we generally need a macro, which we have to create manually. The gimpl files have some examples for that. The reason is that we have at least three problems: Nim does not use cdecl calling convention, but GTK use it when calling callbacks. Gintro Nim code operates on the proxy objects like Button, while GTK internally uses the low level objects like Button00. So GTK passes the low level objects when calling a callback. We have to provide with our Nim macro a cdecl trampoline function which creates the proxy object and calls the real user Nim callback function, additional passing an optional argument with well defined type.

All that is not too difficult, but I see no way to automate that. Module gimplgobject.nim has examples like macro timeoutAdd() and idleAdd(). But of course for each new macro we need testing code. Creating such a macro takes generally only a few hours, but creating a test may take more time.

Unfortunately I have the impression that we two are currently the only gintro users. We just had a bindings discussion at https://discourse.gnome.org/t/steps-to-get-started-creating-a-new-language-binding/6904/12. I would really like to hire a Rust and GTK dev to create more Rust like bindings without proxy objects, maybe that would make callback handling easier. On the other hand, I have seen Rust GTK code which was not that nice, with wrap and unwrap calls. I would really want to avoid such ugly code.

A week ago we had the online Nim conf, I had some hope to see a talk about Fidget2 or maybe about another Nim GUI toolkit, but unfortunately there was nothing.

gavr123456789 commented 3 years ago

I thought you had retired

I went to the dacha for 2 weeks, the Internet here is incredibly bad xd.
I'm not going to leave, I really think that nim is the best language for GTK. Vala has few libraries and is developing slowly, Rust is too systemic for the GUI(write drivers or graphic renders, not high order buisness logic). Crystal does have bindings only for GTK 3, and is still too not finished(lack of windows support and multithreading).

Do you still think #145 is a memory leak?

This can be gintro leak or GTK bug, I think it can be related to https://gitlab.gnome.org/GNOME/gtk/-/issues/3784
I just need to remake this code on Vala and check if it leaks, if it is then its GTK bug.

StefanSalewski commented 3 years ago

This can be gintro leak or GTK bug,

See my last reply, I had the impression that there is no leak at all?

gavr123456789 commented 3 years ago

On the other hand, I have seen Rust GTK code which was not that nice, with wrap and unwrap calls

Maybe you should look at others for inspiration https://github.com/gircore/gir.core
https://github.com/diamondburned/gotk4
https://github.com/jhass/crystal-gobject

gavr123456789 commented 3 years ago

Here C example https://github.com/andyholmes/valent/blob/da678083640f1bccd23d3718631f3df921d4997b/src/plugins/gtk/valent-gdk-clipboard.c#L44

Here my code now:

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

let readTextCb: AsyncReadyCallback = proc (sourceObject: ptr Clipboard00; res: ptr AsyncResult00; userData: pointer) {.cdecl.} = 
  echo "sas"
  echo res == nil
  let text = gdk4.readTextFinish(cast[Clipboard](sourceObject[]) , cast[AsyncResult](res[]))
  echo text
  # gdk_clipboard_read_text_finish(sourceObject, res, nil)

proc appActivate(app: Application) =

  let window = newApplicationWindow(app)
  let clb = window.getClipboard()
  clb.readTextAsync(nil, readTextCb, nil)

  with window:
    title = "GTK4 Clipboard example"
    defaultSize = (200, 200)
    show

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

main()

Got sigseg on line 7, and Im stuck.
Also I see internal

 proc gdk_clipboard_read_text_finish(self: ptr Clipboard00; resu: ptr gio.AsyncResult00;
    error: ptr ptr glib.Error = nil): cstring {.
    importc, libprag.}

In gdk4.nim, may be it would be nice if all internal(pure GTK C funcs) was awaileble in some kind of another module like

import gintro/[gtk4private] 

to get access to low level gtk.

StefanSalewski commented 3 years ago

Thanks for C example. Does that work fine?

Got sigseg on line 7, and Im stuck.

Will try in the next days. Have never used Clipboard before.

would be nice if all internal(pure GTK C funcs) was awaileble

Mixing low level and high level is not that easy. In early gintro versions we had all the low level functions available, and some people used them in the wrong way, so we do not export them now. We still export the 00 types, as sometimes they are useful. Well a separate module for low level functions may be an option.

When you think that you need a low level function, you can just edit the nim file like ~/.nimble/pkgs/gintro-#head/gintro/gtk4.nim and add a export marker to a function. I do that often when I have to create macros, as I generally write the code which the macro shall create manually first.

But the general problem is that most people just do not know GTK good enough, or often not at all.

For really hard cases I created the example with a C part and a Nim part in https://github.com/StefanSalewski/gintro/issues/141. That is really not that bad as we so can use the C macros.

StefanSalewski commented 3 years ago

Here C example

How do I compile and run/test that C code?

StefanSalewski commented 3 years ago

to create more Rust like bindings without proxy objects,

But for that we need destructors which work with plain pointer objects. In 2016 when I started the gintro project we had only finalizers for ref objects. Now with ARC/ORC destructors seems to work for distinct pointers, so it may be possible. But without proxy objects, we can not subclass widgets like we do now, i.e. by adding a Nim data type like a seq. We would have to use composition instead as Go does.

For your linked C code example, that seems to be not a stand alone file, but a component of a larger unmaintained project. So it is not that helpful as we can test it not separately.

StefanSalewski commented 3 years ago

OK, I see your problem with the async callback.

For simple clipboard operation you can use clipboard without async callback as shown in

https://developer.gnome.org/gtk4/stable/ch41s02.html

using gdk_clipboard_get_content().

Providing manually a working async callback macro should be not that hard, and for testing a tiny test program should work. Maybe one weekend is enough for it, I am not sure. Unfortunately I am really busy currently, and generally that is more a task for dark winter days. Have you already considered asking in the Nim forum or Nim IRC? There seems to be some people who sit the whole day in front of IRC, maybe some of them are interested doing some useful work instead, writings some nice macros? Or you may ask which of the other 20 Nim GUI tools supports clipboard already well.

gavr123456789 commented 3 years ago

async callback macro also will be userfull for async work with files in GIO
https://developer.gnome.org/gio/stable/GFile.html