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

examples/09-toolbar.raku failed and 11,15,16 also #112

Open
vincentaxhe opened this issue Dec 27, 2024 · 10 comments
Open

examples/09-toolbar.raku failed and 11,15,16 also #112

vincentaxhe opened this issue Dec 27, 2024 · 10 comments

Comments

@vincentaxhe
Copy link

error log

Cannot resolve caller pack-start(GTK::Simple::VBox:D: Array:D, Bool:D, Bool:D, Int:D); none of these signatures matches:
    (GTK::Simple::VBox $:: GTK::Simple::Widget:D $widget, Bool $expand, Bool $fill, Int $padding, *%_)
    (GTK::Simple::VBox $:: $widget, *%_)
  in method pack-start at /opt/Raku/share/perl6/site/sources/2DE7459AFCBA2BE1A81FE9E3CFDE0E43287BAC95 (GTK::Simple::Box) line 36
  in method new at /opt/Raku/share/perl6/site/sources/2DE7459AFCBA2BE1A81FE9E3CFDE0E43287BAC95 (GTK::Simple::Box) line 23
  in block <unit> at ./09-toolbar.raku line 35
@vincentaxhe vincentaxhe changed the title examples/09-toolbar.raku failed examples/09-toolbar.raku failed and 11,15,16 also Dec 27, 2024
@finanalyst
Copy link
Owner

Hi @vincentaxhe . GTK is very sensitive to the OS you are using. Are you using a Linux OS or Windows?
Have you got the GTK binaries or package installed?

@raiph
Copy link

raiph commented Dec 27, 2024

TL;DR This commit changed an element of this package's API and broke the example which relied on the API as it had been.


Disclaimer: I barely know anything about this module beyond that it exists, that I recall paying attention to it once or twice over the last 8 years, and that I have just read the code relevant to the back trace of the error message provided by @vincentaxhe. I have not looked at the other examples. I have not run any code.


I think, and am confident that:

  • The error in example 09 is inevitable if run using the GTK::Simple package's HEAD master branch code I just looked at.

  • The OS is irrelevant to that error in example 09.


According to GH's Blame feature, this code from the example:

    GTK::Simple::VBox.new(
        [
            { :widget($toolbar-vbox), :expand(False) },
            $bottom-button
        ]

was written 8 years ago.

That code is guaranteed to generate an error with a message along the lines shown by @vincentaxhe if run using this repo's GTK::Simple HEAD master code in the last 2 years.


The code to "blame" is this commit made 2 years ago ("Make the Hash checking logic work again for %hashes"). It changed the .new API (and broke example 09).

More specifically, the commit added another * to the *@packees slurpy of the new method in GTK::Simple::Box (which is what ends up processing the example's [ { :widget($toolbar-vbox), :expand(False) }, $bottom-button ] argument). That made the following change relevant to breaking the example:

  • The "old" *@ slurpy, which was in place until 2 years ago, would have flattened the [...] argument passed to it. Thus the @packees array would have ended up with two elements, namely { :widget($toolbar-vbox), :expand(False) } (a Hash) and $bottom-button (a GTK::Simple::Button, i.e. a "widget").

  • The "new" **@ slurpy, which has been in place for the last 2 years, does not flatten the [...] argument passed to it. Thus @packees currently ends up with one element, namely an Array (which in turn contains a Hash and a widget).

Next, this code from the same GTK::Simple::Box package:

for @packees {
        if $_ ~~ Hash {
            ...
        } else {
            $box.pack-start($_);
        }

executes the else branch, which calls this method:

multi method pack-start($widget) {
    self.pack-start($widget, True, True, 0);
}

which fails to spot that $widget is not a widget but instead an Array, and that there will be no pack-start method that will bind to the Array as its first argument.

Hence the error message.


PS. I suggest opening a new issue saying something like the following as part of closing this issue:

This breaking API change / error in example 09 would have been caught if the examples were part of the package's tests, or at least might have been caught if there were more than rudimentary tests, at least of the package's API. It might make sense to aspire to adding tests of the examples and/or its API to this package's test suite.

@vincentaxhe
Copy link
Author

I'm using arch package 'gtk3 1:3.24.43-4'

@finanalyst
Copy link
Owner

@vincentaxhe Thank you for clarifying. @raiph ++++ for the analysis.

I will look to fix the problem, and see how to add the examples to an xt/* set of tests, or at least to check they run.

@vincentaxhe
Copy link
Author

one more thing about limitations, hope to expound the gap and why, and further plan, it's a bit vague, one may wonder is it better implemented by python or not. Or raku indeed have an advantage to wrap libs.

@finanalyst
Copy link
Owner

@vincentaxhe The limitations are due to (a) the number of people working on this module, (b) the existence of GTK-4. Its probably more productive to get a GTK-4 version working, with more automatic wrapping of the underlying widgets.

The people who have worked on this module, like myself (I took over the maintenance), have extended it to their own needs, rather than creating an exhaustive implementation

@ab5tract
Copy link
Contributor

Preamble and Apology

As the author of the offending commit, I apologize for this unexpected outcome.

I actually spent a fair amount of time around that commit ensuring that the GH Actions were working properly, so I feel fairly confident in saying that I wouldn't have merged that change if this example (or an equivalent usaged) had been part of the test suite.

That doesn't undo the damage of mismatched expectations.

GTK::Simple vs Python Bindings

@vincentaxhe To clarify a bit more on the differences between GTK::Simple and the Python GTK bindings, GTK::Simple is "hand-rolled" for each GTK widget / widget functionality, whereas the "official" Python GTK bindings are generated via GObject Introspection. (@polyjitter++ brought this avenue of development up already 4 years ago

In the long-term, this introspection approach seems to be much more future-proof. However it is also a significantly larger project than a periodically evolving framework like GTK::Simple which gets its features more or less 'as needed'.

In some sense, GTK::Simple is actually an awesome library for learning the (IME) incredibly smooth possibilities of binding Raku to C libraries via NativeCall while also being a terrible example on how to accomplish comprehensive GTK bindings in particularl.

I've looked at the previously mentioned GObject Introspection docs a handful of times since @polyjitter's mention of them and have so far bounced off of them before any work could be done. It doesn't help that I've switched to macOS as my primary Unix in the meantime, which is probably the least supported of GTK's target architectures.

A sort of halfway-point exists in @MARTIMM's incredibly comprehensive Gnome-Gtk3 bindings, which are as noteworthy for their wide coverage of GTK3 as they are for also being hand-rolled.

Final Note

As far as GTK4 goes, I am at this time strongly convinced that GObject Introspection is the only viable option.

I will also look into how I can modify the troublesome code so that it doesn't break these examples.

@finanalyst
Copy link
Owner

@ab5tract I was just coming back to look at this code, so I think it is almost a miracle you appeared in time to fix it.
I have also looked at GTK4 and the GObject introspection, and also recoiled at the learning curve needed to accomplish it.

@vincentaxhe
Copy link
Author

Happy to know the developers of this project face up to the future development, hope there will be a Raku's way.

@MARTIMM
Copy link

MARTIMM commented Dec 29, 2024

@finalist Thank you for mentioning it: "A sort of halfway-point exists in @MARTIMM's incredibly comprehensive Gnome-Gtk3 bindings, which are as noteworthy for their wide coverage of GTK3 as they are for also being hand-rolled.".

The distros are partially generated from the C-sources of Gnome and then adjusted by hand for code, tests, and documentation. The distros are now tagged with :api<1> because a short while ago I made a Gtk version 4 available tagged with :api<2>. Those newer versions are generated from XML files which belong to the introspection files and libraries. The results needed less work afterward. So, there is an in-between way of solving this, on the one hand, calling routines in the GIR libraries and then calling the routine needed by the user with the retrieved information, on the other hand, reading the XML files and storing that information in a hash per class. Then when the user needs to call a function, the entry in the hash is looked up to get information for the function and then access it. This last method looks simpler to me with less overhead for calling the routines in the GIR libraries at run time.

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

5 participants