bohonghuang / cl-gtk4

GTK4/Libadwaita/WebKit2 bindings for Common Lisp.
GNU Lesser General Public License v3.0
217 stars 9 forks source link

Problems when trying to handle GTK's OPEN signal #3

Closed phntxx closed 2 years ago

phntxx commented 2 years ago

Hi!

I'm fairly new to LISP and am currently using this library to create an image viewing program. However, I've hit a roadblock when trying to handle the "open" signal. According to the official GTK documentation, the type of files is GFile**, i.e. a pointer to an array of GFile elements.

I have tried the following:

(connect app "open"
  (lambda (app files n-files hint)
    ;; How do I use files here?
    (format T "~a~%" files)))
    ;; This prints "#.(SB-SYS:INT-SAP #X56334FB51140)"

I have not been able to figure out how to convert this into a LISP-usable list. Could you perhaps point me to a solution or documentation that might aid me in this?

bohonghuang commented 2 years ago

@phntxx It may boil down to the upstream library handling signal parameters incorrectly, for which I have opened issue #84. However, it's possible to address this problem via cffi currently. The solution may seem tricky, but it does work though:

(defpackage test-application-open
  (:use #:cl #:gtk4))

(in-package #:test-application-open)

(defun main ()
  (let ((app (make-application :application-id "org.bohonghuang.test-application-open"
                               :flags gio:+application-flags-handles-open+)))
    (connect app "activate" (lambda (app)
                              (gio:application-open app (list (gio:file-new-for-path "/home/coco24/.emacs.d/init.el")
                                                              (gio:file-new-for-path "/home/coco24/.emacs.d/local.el"))
                                                    "")))
    (connect app "open" (lambda (app files n-files hint)
                          (declare (ignore app hint))
                          (let ((files (loop :for i :below n-files
                                             :collect (make-instance 'gir::object-instance
                                                                     :class (gir:nget gio:*ns* "File")
                                                                     :this (cffi:mem-aref files :pointer i)))))
                            (print (mapcar #'gio:file-basename files))))) ;; This outputs ("init.el" "local.el")
    (gio:application-run app nil)))
phntxx commented 2 years ago

Words cannot describe how thankful I am for your support in this. Thank you very much for the code example, I'll make sure to follow the progress of the issue in the upstream repository.