garrigue / lablgtk

LablGTK 2 and 3: an interface to the GIMP Tool Kit
https://garrigue.github.io/lablgtk
Other
89 stars 40 forks source link

GTK 4.0 support #126

Open sidkshatriya opened 3 years ago

sidkshatriya commented 3 years ago

I just wanted to know if there are plans to support GTK 4.0.

(Thanks for your efforts on GTK+ 2 & 3)

garrigue commented 3 years ago

Sorry for the very slow answer: no plans so far. We are basically demand-driven. That is, if this is required to do something we may try to update lablgtk. This was the case for lablgtk3: it was required for coqide, and the coqide implementers contributed to the port.

btj commented 3 years ago

CoqIDE's UI is rather sluggish on macOS (https://github.com/coq/coq/issues/12779). This seems partially due to a lot of image conversion going on all the time (https://github.com/coq/coq/issues/12779#issuecomment-894703188). This is presumably due to a suboptimal GTK backend for macOS. A new backend for macOS was created for GTK 4.0. So porting CoqIDE to GTK 4.0 will probably improve its responsiveness.

btj commented 3 years ago

A first step toward migrating to GTK 4 would probably be to mark the lablgtk API elements corresponding to GTK APIs that are deprecated in the latest version of GTK 3 (and removed in GTK 4) with deprecated alerts, to help apps eliminate them if and when they choose to attempt a migration. Does that sound reasonable? @garrigue would you consider such PRs? I guess the strategy is to temporarily remove the -Wno-deprecated-declarations flag and to individually suppress a deprecated declaration warning for each deprecated declaration that we propagate to the OCaml level. That way, we can easily tell our progress. (I would not include the removal of Wno-deprecated-declarations into the commit so as not to drown out "legitimate" warnings.)

This allows at least part of the migration to happen incrementally. Unfortunately, judging from the GTK migration guide, this still leaves a potentially pretty significant big bang effort when actually making the switch, though.

DemiMarie commented 1 year ago

Could much of the code be generated from GObject introspection metadata?

btj commented 1 year ago

I'm working on generating OCaml bindings for GTK 4 from GObject introspection data (from scratch, not based on lablgtk); see https://github.com/btj/ocaml-gtk. "Naked" bindings for the C functions mostly work; I'm now working on an OO layer. It will not be fully compatible with lablgtk.

DemiMarie commented 1 year ago

I'm working on generating OCaml bindings for GTK 4 from GObject introspection data (from scratch, not based on lablgtk); see https://github.com/btj/ocaml-gtk. "Naked" bindings for the C functions mostly work; I'm now working on an OO layer. It will not be fully compatible with lablgtk.

Will the ergonomics be comparable to lablgtk?

DemiMarie commented 1 year ago

Also, could the OO layer be generated too?

btj commented 1 year ago

Also, could the OO layer be generated too?

That's the plan.

I'm working on generating OCaml bindings for GTK 4 from GObject introspection data (from scratch, not based on lablgtk); see https://github.com/btj/ocaml-gtk. "Naked" bindings for the C functions mostly work; I'm now working on an OO layer. It will not be fully compatible with lablgtk.

Will the ergonomics be comparable to lablgtk?

Ideally, yes; let's see how much work that is.

sacerdot commented 1 year ago

See also #106 that generates the bindings from GObject introspection and tries to be backward compatible as much as possible. There has been no activity on the repository in the recent period, but it was already running some examples. A porting of the Haskell code to OCaml code was also done by a student of mine, even if not completely finished. What was missing from the two implementations is automatic support for several datatypes used in Gtk that are not GObjects (sic!) and need ad-hoc code to be handled.

btj commented 1 year ago

I now have a basic OO layer working in https://github.com/btj/ocaml-gtk .

btj commented 1 year ago

I am now looking at adding support for TextIter to https://github.com/btj/ocaml-gtk . I am wondering if there is a way to create bindings for TextIter that preserve memory safety. There seem to be (at least) two issues:

  1. A TextIter should keep the TextBuffer it refers to alive.
  2. A TextIter that was invalidated by a modification to the TextBuffer should no longer be used.

The first issue seems feasible: have the TextIter wrapper own a reference to the TextBuffer. I do not see a reasonable way to deal with the second issue, however. Am I missing something? (It does not seem like lablgtk is safe for either of these two issues.)

I also asked this question at the Gtk Discourse.

btj commented 1 year ago

Answering my own question: I had a peek inside gtktextiter.c and gtktextbtree.c and it appears that the first thing any function that uses a TextIter does is check that the TextIter’s chars_changed_stamp equals the B-tree’s chars_changed_stamp; this value is initialized to a random value and incremented whenever the contents change so it seems like this will either segfault (if the tree is gone) or produce a nice warning if the TextIter is invalid. So it seems safe for a language binding not to take special measures here.

DemiMarie commented 1 year ago

this will either segfault (if the tree is gone)

This cannot be relied on. The backing memory could have been reused for other purposes. You’ll need to rely on reference counting.

produce a nice warning if the TextIter is invalid.

If the counter is not 64-bit then it could overflow.

btj commented 1 year ago

This cannot be relied on.

Good point. I just submitted this bug report. Once this is fixed, it seems fine to treat TextIter records as plain values: misusing it causes either a segfault on the offending call (if the memory is no longer mapped), which seems easy enough to diagnose, or a helpful warning saying an invalid TextIter is being used (if the TextBuffer was freed but the memory is still mapped, or if the TextBuffer is still alive but has changed).

(Note, BTW, that lablgtk has been treating TextIter records as plain values all along. It does not cause a live TextIter to keep the TextBuffer alive.)

(Note also: for added safety, one could propose that the Gtk authors change the chars_changed_stamp from a guint to a guint64, but this seems orthogonal to the design of the language bindings. Personally, I think 32 bits is enough for this. The probability that a program would accidentally try to use an old TextIter after exactly 2^32 changes have happened to the TextBuffer seems very low.)