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

How do I use Gtk, Gdk, etc., functions and constants? #122

Open
sirgazil opened this issue Mar 18, 2022 · 6 comments
Open

How do I use Gtk, Gdk, etc., functions and constants? #122

sirgazil opened this issue Mar 18, 2022 · 6 comments

Comments

@sirgazil
Copy link

Hi,

I asked this question on Guile's mailing list, but I thought I might have better luck here.

In summary, I haven't been able to figure out how to call functions, like Gtk's show_uri, or use constants, like Gdk's CURRENT_TIME.

Take this application for example:

(use-modules (gi) (gi repository))

(require "Gio" "2.0")
(require "Gtk" "4.0")

(load-by-name "Gio" "Application") ;; activate, run
(load-by-name "Gtk" "Application")
(load-by-name "Gtk" "ApplicationWindow")
(load-by-name "Gtk" "Button")
(load-by-name "Gtk" "Window")


(define (on-activate app)
  (let* ((window (make <GtkApplicationWindow>
                   #:application app
                   #:default-height 200
                   #:default-width 200
                   #:title "Window"))
         (button (make <GtkButton> #:label "Help")))

    (set-child window button)
    (connect button clicked (lambda _ (show-uri window "help:gedit" CURRENT_TIME)))
    (present window)))


(define (main)
  (let ((app (make <GtkApplication> #:application-id "org.gtk.example")))

    (connect app activate on-activate)
    (run app (command-line))))

(main)

When I click the Help button, the application shuts down and says that show-uri is unbound.

$ guile gtk-functions.scm 
WARNING: (guile-user): imported module (gi) overrides core binding `quit'
WARNING: (guile-user): imported module (gi) overrides core binding `command-line'
WARNING: (guile-user): imported module (gi) overrides core binding `shutdown'
WARNING: (guile-user): imported module (gi) overrides core binding `connect'
Backtrace:
In ice-9/boot-9.scm:
  1752:10  7 (with-exception-handler _ _ #:unwind? _ # _)
In unknown file:
           6 (apply-smob/0 #<thunk 7f33c1417080>)
In ice-9/boot-9.scm:
    724:2  5 (call-with-prompt _ _ #<procedure default-prompt-handle…>)
In ice-9/eval.scm:
    619:8  4 (_ #(#(#<directory (guile-user) 7f33c141dc80>)))
In ice-9/boot-9.scm:
   2835:4  3 (save-module-excursion _)
  4380:12  2 (_)
In unknown file:
           1 (application:run #<<GtkApplication> 7f33c04782a0> ("gt…"))
In /home/yo/Descargas/gtk-functions.scm:
    22:39  0 (_ . _)

/home/yo/Descargas/gtk-functions.scm:22:39: Unbound variable: show-uri

If you use Guix, you can run the example above in Guix shell using the following manifest:

#| GNU Guix manifest.

guix 579e9e9
repository URL: https://git.savannah.gnu.org/git/guix.git
branch: master
commit: 579e9e9509f45fdc8543323b3c9f662b53dbfc6d |#

(use-modules (gnu packages))


(specifications->manifest
 (list ;; "gnome@41.0"  ; For containerized environment only.
       "gobject-introspection@1.66.1"
       "gtk@4.4.1"
       "guile@3.0.7"
       "guile-gi@0.3.2"))
@lshoravi
Copy link

lshoravi commented Mar 21, 2022

The following works for me:

(define-module (example)
  #:use-module (gi)
  #:use-module (gi repository))

(use-typelibs ("Gtk" "4.0"))

show-uri

Using:

  (inputs `(("guile" ,guile-3.0)
            ("guile-gi" ,guile-gi)
            ("gtk4" ,gtk)

and guix shell --no-grafts

It's possible that show-uri isn't in any of the namespaces you imported through load-by-name, but I don't know if it's possible to look up functions in that way.

@lshoravi
Copy link

lshoravi commented Mar 21, 2022

Apropos doesn't seem to help either:

scheme@(guile-user)> (use-modules (gi) (gi repository))
scheme@(guile-user)> (use-typelibs ("Gtk" "4.0"))

...

scheme@(guile-user)> ,apropos show-uri
(gi Gtk-4.0): show-uri	#<<generic> show-uri (1)>
(gi Gtk-4.0): show-uri-full	#<<generic> show-uri-full (4)>
(gi Gtk-4.0): show-uri-full-finish?	#<<generic> show-uri-full-finish? (1)>
scheme@(guile-user)> 

@sirgazil
Copy link
Author

@lshoravi thanks for commenting :)

I can confirm that using use-typelibs I can simply call the function and it works. So I guess the question is, what would I need to load using the require and load-by-name strategy to be able to call show-uri?

But here is a modified version of the initial example, anyway, doing what it was expected to do:

(use-modules (gi) (gi repository))
(use-typelibs ("Gdk" "4.0")  ; CURRENT_TIME
              ("Gtk" "4.0")
              ("Gio" "2.0"))  ; XXX: MUST BE HERE


(define (on-activate app)
  (let* ((window (make <GtkApplicationWindow>
                   #:application app
                   #:default-height 200
                   #:default-width 200
                   #:title "Window"))
         (button (make <GtkButton> #:label "Help")))

    (set-child window button)
    (connect button clicked (lambda _ (show-uri window "help:gedit" CURRENT_TIME)))
    (present window)))


(define (main)
  (let ((app (make <GtkApplication> #:application-id "org.gtk.example")))

    (connect app activate on-activate)
    (run app (command-line))))

(main)

Note that I added Gdk, which I forgot to do in the first example. Then, I could run it like so:

guix shell guile guile-gi gtk   # It worked without --no-grafts
guile app.scm

Something unexpected here is that placing Gio import before Gdk, makes the application fail to run with the following message, so I had to move the import of Gio to the end.

Backtrace:
In ice-9/boot-9.scm:
  1752:10  7 (with-exception-handler _ _ #:unwind? _ # _)
In unknown file:
           6 (apply-smob/0 #<thunk 7fdc3d781080>)
In ice-9/boot-9.scm:
    724:2  5 (call-with-prompt _ _ #<procedure default-prompt-handle…>)
In ice-9/eval.scm:
    619:8  4 (_ #(#(#<directory (guile-user) 7fdc3d787c80>)))
In ice-9/boot-9.scm:
   2835:4  3 (save-module-excursion _)
  4380:12  2 (_)
In /home/yo/Descargas/guile-gi-functions/main-use-typelibs.scm:
     24:4  1 (main)
In gi/oop.scm:
    103:8  0 (connect-1 _ _ _ #:after? _ #:detail _)

gi/oop.scm:103:8: In procedure connect-1:
~S has no signal in ~S #<<GtkApplication> 7fdc34599650> #<<generic> activate (17)>

Another unexpected thing, although Guix-related, is that the application fails to run if I put the inputs in a manifest instead of passing them directly to guix shell. For example:

Manifest:

(use-modules (gnu packages))

(specifications->manifest
 (list "gtk"
       "guile"
       "guile-gi"))

Then:

guix shell -m manifest-unversioned.scm
guile app.scm

Results in critical errors:

(process:4201): GuileGI-WARNING **: 11:47:37.771: not redefining fundamental type GdkEvent

(process:4201): GuileGI-WARNING **: 11:47:37.790: no way of determining array size of GArray, coercing to pointer

(process:4201): GLib-GObject-WARNING **: 11:47:37.831: cannot register existing type 'GdkPixbuf'

(process:4201): GLib-GObject-CRITICAL **: 11:47:37.831: g_type_add_interface_static: assertion 'G_TYPE_IS_INSTANTIATABLE (instance_type)' failed

(process:4201): GLib-GObject-CRITICAL **: 11:47:37.831: g_type_add_interface_static: assertion 'G_TYPE_IS_INSTANTIATABLE (instance_type)' failed

(process:4201): GLib-CRITICAL **: 11:47:37.831: g_once_init_leave: assertion 'result != 0' failed

(process:4201): GLib-GObject-CRITICAL **: 11:47:37.831: g_param_spec_object: assertion 'g_type_is_a (object_type, G_TYPE_OBJECT)' failed

(process:4201): GLib-GObject-CRITICAL **: 11:47:37.831: validate_pspec_to_install: assertion 'G_IS_PARAM_SPEC (pspec)' failed

(process:4201): GLib-GObject-CRITICAL **: 11:47:37.831: g_param_spec_object: assertion 'g_type_is_a (object_type, G_TYPE_OBJECT)' failed

(process:4201): GLib-GObject-CRITICAL **: 11:47:37.831: validate_pspec_to_install: assertion 'G_IS_PARAM_SPEC (pspec)' failed

(process:4201): GLib-GObject-CRITICAL **: 11:47:37.831: g_param_spec_object: assertion 'g_type_is_a (object_type, G_TYPE_OBJECT)' failed

(process:4201): GLib-GObject-CRITICAL **: 11:47:37.831: validate_pspec_to_install: assertion 'G_IS_PARAM_SPEC (pspec)' failed

(process:4201): GuileGI-WARNING **: 11:47:37.832: Missing property cell-renderer-pixbuf:pixbuf

(process:4201): GuileGI-WARNING **: 11:47:37.832: Missing property cell-renderer-pixbuf:pixbuf-expander-closed

(process:4201): GuileGI-WARNING **: 11:47:37.832: Missing property cell-renderer-pixbuf:pixbuf-expander-open

(process:4201): GuileGI-WARNING **: 11:47:37.880: not redefining fundamental type GtkExpression

(process:4201): GuileGI-WARNING **: 11:47:37.909: no way of determining array size of GArray, coercing to pointer

(process:4201): GuileGI-WARNING **: 11:47:37.909: no way of determining array size of GArray, coercing to pointer

@lshoravi
Copy link

I had these issues as well, including #120.

The reason for this is that guix "grafts" packages, resulting in guile-gi being built for one version of Gtk but guix is using a slightly different version. Hence the reason for entering the development shell with --no-grafts. Doing so eliminates most errors for me.

There's ongoing discussion about this in #96.

@lshoravi
Copy link

As for what to give load-by-name, I have no idea.

@LordYuuma
Copy link
Collaborator

For completeness, load-by-name takes the unprefixed constant name, so for Gdk's CURRENT_TIME, that ought to be simply CURRENT_TIME. Constants can appear in two flavors: either as constants, in which they have their own entry, or as enums/flags, in which you need to import the corresponding enum instead.

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

3 participants