romgrk / node-gtk

GTK+ bindings for NodeJS (via GObject introspection)
MIT License
495 stars 42 forks source link

Generate typescript definitions & documentation for common GIR libraries #24

Open romgrk opened 6 years ago

WebReflection commented 6 years ago

not sure if it helps, but I have created a GJS based CommonJS env called cgjs which brings in also a gir namespace scanner called cgjs-about

cgjs-about gi.Gio.File

# output as json format
cgjs-about gi.Gio.File --json

It provides all things it understands per each class, including optional arguments. Maybe from that JSON it's easy to create the .ts definition.

benwaffle commented 6 years ago

Looks like there's a couple of projects that already try to do this:

https://github.com/darkoverlordofdata/gir2dts https://github.com/niagr/GIR2TS https://github.com/Place1/gir-dts-generator

romgrk commented 6 years ago

Looks interesting! Although those are aimed at GJS bindings, which means the naming conventions are not the same as the ones we're using here. Btw, we also don't have documentation about our naming conventions, so I'll need to review the code to check how we're naming constants, enums, interfaces and some other things. I know in some cases, we're not respecting JS standards, example:

const win = new Gtk.Window({
  window_position: Gtk.WindowPosition.CENTER // should be windowPosition
})

There is already lib/inspect.js, which would be a good starting point. It implements functions for exploring the GIR namespaces through javascript. E.g.:

const inspect = require('./lib/inspect')
const gtk = inspect.parseNamespace('Gtk')
console.log(gtk.init)
// => FunctionInfo { type: 'function', ... }
WebReflection commented 6 years ago

@romgrk the result would be the same, 'cause AFAIK the GIR namespace is the same in GJS or whatever Node.js is doing here, it's standard 🤷‍♂️

in cgjs I convert at runtime through proxies the accessor, mapping that to equivalent snake_case counterpart, for the simple reason every documentation you have about Gtk+ online is pretty much Python Gtk+ based so it's sneak_case, and I wanted cgjs developers to be free to use both.

And yet, this has nothing to do with .ts files generation, right?

cancerberoSgx commented 5 years ago

Hello, I'm interesting on generating TypeScript type definitions using ./lib/inspect . I have very basic knowledge of GTK and I?m not an expert on C++ but have plenty experience with TypeScript and in particular TypeScript type definitions for libraries. My plan is to start with lib/inspect.js, and when I see I can reach somewhere, start researching how to support also the jsdocs. I wonder know if someone is planning / working on this or if the project has any plan to support TS descriptions at all ? Thanks

I see this project https://github.com/niagr/gjs-ts/blob/master/Gtk-3.0.d.ts has what's seems to be a complete type definitions for gtk+3 although I think the member camel/case conventions does not match this project's. It would be easy for build a small program to refactor these names to support this project's API, but I wonder what't the opinion on that take - or if it would be better to build a solution from scratch (that also considers jsdoc descriptions ?)

romgrk commented 5 years ago

As far as I know, no one is actively working on generating typedefs at the moment. Having TS descriptions would be SO awesome, I just haven't had enough time to do it myself :) If you want to take the task, you're more than welcome.

lib/inspect.js is a good starting point because I've translated some C++ behaviors in JS (eg C++ and JS). And it makes sense to build from scratch because there are various details that can differ between implementations. Also because if we want to generate correct bindings we need to take in account the overrides.

The naming is handled in lib/index.js, so that part is quite easy to use. It could be imported in lib/inspect.js.

Another thing to be mindful of is that event handlers don't have the self parameter as other GIR implementation have. Other bindings are usually in the format

widget.on('key-press-event', (self: Gtk.Widget, event: Gdk.EventKey) => {...}) 
// where widget === self

in node-gtk, the self parameter is elided:

widget.on('key-press-event', (event: Gdk.EventKey) => {...})

If you open a PR, I can try to list all the gotchas that I can think of.

cancerberoSgx commented 5 years ago

Working on it and this is more or less my plan :

Will keep you updated, thanks for the project, btw: do you know / have a working gdk-cairo test ? with time would be awesome to build a playground app with an editor on one side and the running app on the other and a list of examples - just compile and eval() the code on edit to reload the app - That should be an awesome gtk/cairo playground not so easy to implement with C I think.

Thanks

dhonx commented 5 years ago

@cancerberoSgx Actually I want to do it ... but I'm not very good with typescript. It's great if you can help with that. I'm ready to help if you need. ✌️

dhonx commented 5 years ago

@cancerberoSgx dont forget to join us on discord for discussion. 🙂

benwaffle commented 5 years ago

@cancerberoSgx gir has the docs/descriptions

cancerberoSgx commented 5 years ago

Hi im sorry but currenlty my desktop is mac which is not my favorite technology and until a moment everything was fine but now listLibs() is showing gtk+ version 2.0 (not 3.0) and is failing

  [ 'Atk-1.0', 'Atk', '1.0' ],
  [ 'DBus-1.0', 'DBus', '1.0' ],
  [ 'DBusGLib-1.0', 'DBusGLib', '1.0' ],
  [ 'GIRepository-2.0', 'GIRepository', '2.0' ],
  [ 'GL-1.0', 'GL', '1.0' ],
  [ 'GLib-2.0', 'GLib', '2.0' ],
  [ 'GModule-2.0', 'GModule', '2.0' ],
  [ 'GObject-2.0', 'GObject', '2.0' ],
  [ 'Gdk-2.0', 'Gdk', '2.0' ],
  [ 'GdkPixbuf-2.0', 'GdkPixbuf', '2.0' ],
  [ 'GdkX11-2.0', 'GdkX11', '2.0' ],
  [ 'Gio-2.0', 'Gio', '2.0' ],
  [ 'Gtk-2.0', 'Gtk', '2.0' ],
  [ 'Pango-1.0', 'Pango', '1.0' ],
  [ 'PangoCairo-1.0', 'PangoCairo', '1.0' ],
  [ 'PangoFT2-1.0', 'PangoFT2', '1.0' ],
  [ 'PangoXft-1.0', 'PangoXft', '1.0' ],
  [ 'cairo-1.0', 'cairo', '1.0' ],
  [ 'fontconfig-2.0', 'fontconfig', '2.0' ],
  [ 'freetype2-2.0', 'freetype2', '2.0' ],
  [ 'libxml2-2.0', 'libxml2', '2.0' ],
  [ 'win32-1.0', 'win32', '1.0' ],
  [ 'xfixes-4.0', 'xfixes', '4.0' ],
  [ 'xft-2.0', 'xft', '2.0' ],
  [ 'xlib-2.0', 'xlib', '2.0' ],
  [ 'xrandr-1.3', 'xrandr', '1.3' ]

I'm using this brew thing, and tried to remove everything and installing it again, but no luck - restarting.... Perhaps somebody knows some trick ? will try again but in the meanwhile perhaps somebody had the same trouble ? thanks

cancerberoSgx commented 5 years ago

@benwaffle oh, nice to know - I read about that files(?) will research how to generated from the sources - will try with an old ones I imagine are easy to generate from latest sources right ? thanks! good tip

cancerberoSgx commented 5 years ago

@benwaffle form your repo https://github.com/nemequ/vala-girs/tree/master/gir-1.0 !! sorry I'm kind of rusty in native desktop technologies -... thanks

cancerberoSgx commented 5 years ago

@benwaffle Thanks for this - accessing this data from files will make my job much more easy. I'm assuming the rest of the metadata (not only descriptions) will comply with this project (with the exception of mentioned overrides signal syntax) ?

Congratulations , you saved my day - Don't know why I didn't see these technologies before - Nice to see an initiative building on top of formal object descriptions and documentation! - https://valadoc.org/ and the value there is amazing - all those technologies ruled with the same ring... one little suggestion, from a total outsider - adding a link to download the .gir file that sourced each project could make sense. Congrats and thanks again!

romgrk commented 5 years ago

Lots of questions and I don't have much time for personal projects today ^^

I'll start with these two:

Do not hesitate if you have questions about GObject concepts. I've found it a bit hard to understand them sometimes so it helps to have someone who can explain them.

JumpLink commented 4 years ago

Here is a fork from me of ts-for-gjs to add type definition generation support for node-gtk (including two examples).

Btw here is also an interesting conversation about type definitions for node-gtk: https://github.com/codejamninja/ts-gir/pull/1

JumpLink commented 4 years ago

The ts-for-gjs fork with initial support for node-gtk is merged (including examples) now, help for improvement is very welcome

romgrk commented 4 years ago

I've found a few issues that I've listed here. Thanks for your contribution!

padcom commented 2 years ago

Guys, anything happening it that department?

JumpLink commented 2 years ago

@padcom You can use ts-for-gir which has already very good results

romgrk commented 2 years ago

Nothing new here, ts-for-gir has a node-gtk mode. There were some issues but I think it was at least somewhat usable.

JumpLink commented 2 years ago

There is quite news there, because there were a few code contributions to further improve the types for node-gtk on ts-for-gir. So please test them again and give me feedback.

It is important not to use the package from NPM as this is not from us and is unfortunately heavily deprecated (but I will be releasing it officially on NPM under a different name soon), more about how to use ts-for-gjs in die README.

Bug reports and other contributions are welcome. Currently I'm working on a big pull request https://github.com/sammydre/ts-for-gir/pull/63 where I'm working on introducing real inheritance in the types. This is already working very well but I still need to fix some type conflicts. I would also be happy about contributions to this PR because it's not easy to fix this conflicts and maybe a new way of thinking will also help.

The master branch currently does not use inheritance and simply copies all inherited methods, this has the advantage that it avoids the type conflicts, but has the disadvantage that the generated types become very large.

By the way, I'm also working on another project in parallel to generate API documentation from this generated Typescript types: https://node-gtk-docs.gjsify.org/

As soon as my PR is finished I will improve the generated documentation as well.

JumpLink commented 2 years ago

Okay now real inheritance and implementations are merged to ts-for-gir, I would be very happy if someone would test the types for node-gtk again :)

romgrk commented 2 years ago

I did a quick overview, here are a few notes:

  1. GObject classes have $gtype, but node-gtk has __gtype__: BigInt

  2. There are some events missing, e.g. on Gtk 3.0

    • DrawingArea#on('draw', (context) => { ... }), context is typed as any
    • Window#on(...) doesn't list events show, destroy, delete-event (which are kinda important)
  3. We've added support for virtual functions, they're also kinda important in Gtk-4.0 to create custom widgets. They're exposed without a prefix, the best test is the gtk_widget_measure example along with docs for gtk_widget_measure. Note that the return value of virtual functions is similar to that of native functions, here is the logic:

    • Sum all of the out arguments, plus 1 if the return value is non-void
    • If the sum is equal to 1, the JS-retval is the simply the C-retval or the C-out-argument that needs to be returned
    • If the sum is more than 1, the JS-retval is an array that contains first the C-retval, if any, then the C-out-args in order of declaration.

That's it for the issues, I also wanted to say great work for the rest! It's really nice to be able to just switch the extension to .ts and get full autocompletion. It makes it much easier to discover the APIs.

Screenshot from 2022-06-30 01-41-24