Giter Club home page Giter Club logo

cl-gtk4's Introduction

GitHub Stats Top Langs

github contribution grid snake animation

cl-gtk4's People

Contributors

bohonghuang avatar lsh-0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cl-gtk4's Issues

Compilation errors: ultralisp 20230305133500

Updating Ultralisp and attempting to load the package:

CL-USER> (ql:update-dist "ultralisp")
You already have the latest version of "ultralisp": 20230305133500.
NIL

CL-USER> (ql:quickload :cl-gtk4)
To load "cl-gtk4":
  Load 1 ASDF system:
    cl-gtk4
; Loading "cl-gtk4"
..................................................
[package gtk4].

results in this error:

no symbol named "*APPLICATION*" in "GIO"
   [Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]

Restarts:
 0: [CONTINUE] INTERN it.
 1: [RETRY] Retry compiling #<CL-SOURCE-FILE "cl-gtk4" "gtk4">.
 2: [ACCEPT] Continue, treating compiling #<CL-SOURCE-FILE "cl-gtk4" "gtk4"> as having been successful.
 3: [RETRY] Retry ASDF operation.
 4: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting the configuration.
 5: [RETRY] Retry ASDF operation.
 --more--

SBCL 2.3.1, Linux.

Setting text doesn't work with unicode strings

I've noticed several functions that set/provide/insert text - for example (setf text-buffer-text) will, in the GTK version accept a length (bytes) parameter, but the wrappers will populate this parameter with length called on the argument. (i.e. number of characters, not number of bytes). In the case where the text contains any unicode characters, this can cause bugs, as the length provided by CL is wrong.

Unable to compile the example program into executable

你好,我在运行此条命令:(asdf:operate :program-op :cl-gtk4/example)时出现了如下问题:

Symbol "SIMPLE" not found in the GTK4.EXAMPLE package.

Stream: #<dynamic-extent STRING-INPUT-STREAM (unavailable) from "gtk4.exa...">
[Condition of type SB-INT:SIMPLE-READER-PACKAGE-ERROR]
请问该如何解决,谢谢

FLOATING-POINT-INVALID-OPERATION

After a lot of tinkering with CL-GTK4, running and restarting examples frequently, the FLOATING-POINT-INVALID-OPERATION error started appearing. I don't understand why this happens. Both applications that I load via C-c C-c and built-in examples are affected by this error, although everything was working before.

I rebooted REPL and it went away on its own. Although last time, as I remember, rebooting REPL didn't help.

It seems the same error occurred some time after I ran the example I wrote.

DSL for Cairo library.

Did you listened about Nile, special language for drawing? The main idea is that when we program in Cairo, we need to find the optimal path for rendering. You need to indicate HOW to draw. Nile's idea is that we describe WHAT needs to be drawn, and the compiler itself looks for an efficient way to do it. At least that's how I understood the articles I read.
https://tinlizzie.org/VPRIPapers/tr2009016_steps09.pdf
https://github.com/damelang/nile/tree/master
http://tinlizzie.org/dbjr/high_contrast.html

I thought maybe I could write a macro that would provide a convenient interface to Cairo? Declarative. I understand that the task is not an easy one, but you must agree, it is quite interesting.

Can you add TODO list to README?

Hello!
Could you add a list of unsolved tasks and problems to the readme? This will help a lot in development. Other people will be able to help you. I really support your development.

Problems when trying to handle GTK's OPEN signal

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?

Issue running simple example: cannot register existing type GApplication

Sorry I'm fairly new to common lisp/gtk/etc--I was wondering if you could take a quick look and point me in the right direction. The simple counter window did not pop up when I tried it. Thanks!

 guix package --list-installed|grep -E '(^gtk|^gobject)'
gtk                 	4.6.6               	out             	/gnu/store/ivwgqpd70pz4i28xs39dwza9mpjsshfy-gtk-4.6.6
gobject-introspection	1.66.1              	out             	/gnu/store/whngbagkibx40rsprgair62c59l0b2m8-gobject-introspection-1.66.1
GI_TYPELIB_PATH=~/.guix-profile/lib/girepository-1.0  LD_LIBRARY_PATH="$LIBRARY_PATH" sbcl  
This is SBCL 2.2.6, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (ql:quickload :cl-gtk4/example)
To load "cl-gtk4/example":
  Load 1 ASDF system:
    cl-gtk4/example
; Loading "cl-gtk4/example"
...................
(:CL-GTK4/EXAMPLE)
* (gtk4.example:simple)

(process:4632): GLib-GObject-WARNING **: 21:45:59.712: cannot register existing type 'GApplication'

(process:4632): GLib-GObject-WARNING **: 21:45:59.713: cannot add private field to invalid (non-instantiatable) type '<invalid>'

(process:4632): GLib-GObject-WARNING **: 21:45:59.713: cannot register existing type 'GActionGroup'

(process:4632): GLib-GObject-CRITICAL **: 21:45:59.713: g_type_interface_add_prerequisite: assertion 'G_TYPE_IS_INTERFACE (interface_type)' failed

(process:4632): GLib-CRITICAL **: 21:45:59.713: g_once_init_leave: assertion 'result != 0' failed

(process:4632): GLib-GObject-CRITICAL **: 21:45:59.713: g_type_add_interface_static: assertion 'G_TYPE_IS_INSTANTIATABLE (instance_type)' failed

(process:4632): GLib-GObject-WARNING **: 21:45:59.713: cannot register existing type 'GActionMap'

(process:4632): GLib-GObject-CRITICAL **: 21:45:59.713: g_type_interface_add_prerequisite: assertion 'G_TYPE_IS_INTERFACE (interface_type)' failed

(process:4632): GLib-CRITICAL **: 21:45:59.713: g_once_init_leave: assertion 'result != 0' failed

(process:4632): GLib-GObject-CRITICAL **: 21:45:59.713: g_type_add_interface_static: assertion 'G_TYPE_IS_INSTANTIATABLE (instance_type)' failed

(process:4632): GLib-CRITICAL **: 21:45:59.713: g_once_init_leave: assertion 'result != 0' failed

(process:4632): GLib-GIO-CRITICAL **: 21:45:59.713: g_application_run: assertion 'G_IS_APPLICATION (application)' failed
1
* 

Could not locate gtk_application_new: (null) When trying to run an example

Hi I'm new to common-lisp. I'm using nixos, so the standard positions of libraries vary. I have successfully loaded the library by setting the LD_LIBRARY_PATH to all the libraries mentioned. The $LD_LIBRARY_PATH also contains the location of gtk4/lib directory, so it should have no problem finding gtk functions. Any help please?

Typelib file for namespace 'Gtk', version '4.0' not found

New error has appeared today on one on my computers:


Error while trying to load definition for system cl-gtk4 from
pathname
/home/jacek/quicklisp/dists/ultralisp/software/bohonghuang-cl-gtk4-20231024143206/cl-gtk4.asd:

   Typelib file for namespace 'Gtk', version '4.0' not found
   [Condition of type ASDF/FIND-SYSTEM:LOAD-SYSTEM-DEFINITION-ERROR]

Compilation error: GIO missing APPLICATION-QUIT

In order to load the latest version, I am using a git submodule to put this application in the /libs/cl-gtk4 folder. When attempting to load (ql:quickload :cl-gtk4) in a fresh Slime session, I recevie the following error:

CL-USER> (ql:quickload :cl-gtk4)
To load "cl-gtk4":
  Load 1 ASDF system:
    cl-gtk4
; Loading "cl-gtk4"
[package gtk4]....................................
..................................................
.................
; 
; caught ERROR:
;   READ error during COMPILE-FILE:
;   
;     Symbol "APPLICATION-QUIT" not found in the GIO package.
;   
;       Line: 69, Column: 44, File-Position: 2688
;   
;       Stream: #<SB-INT:FORM-TRACKING-STREAM for "file /Users/jonathanbennett/.roswell/lisp/quicklisp/local-projects/megastrike/libs/cl-gtk4/gtk4.lisp" {70052A1083}>

More questions about using the library without define-application

This is related to #11 , where I encountered a surprise. I was assuming I can completely remove define-application. While trying this I got this error:

Cannot expand DEFINE-MAIN-WINDOW outside DEFINE-APPLICATION.

I am exploring this path because there are some programs that use several windows. One such example would be a paint program with a separate toolbar window. While you perform painting on canvas window, and it could be considered to be the main window, there are situations with several windows and no one of them really being the main window. Some text editors like Emacs could be such examples. When I have multiple windows open and I close the first window, what happens with the concept of the main window? Would the remaining windows still be open and fully functional?

Could you make the library interface more declarative?

Hello!
I'm comparing application code on your library and on CL-CFFI-GTK4. The second library provides a more declarative interface. For example:

(defun do-level-bar (&optional application)
  (let* ((vbox (make-instance 'gtk:box
                              :orientation :vertical
                              :margin-top 12
                              :margin-bottom 12
                              :margin-start 12
                              :margin-end 12
                              :spacing 12))
         (window (make-instance 'gtk:window
                                :title "Level bar"
                                :child vbox
                                :application application
                                :default-width 420
                                :default-height 240))
         (adj (make-instance 'gtk:adjustment
                             :value 0.0
                             :lower 0.0
                             :upper 10.0
                             :step-increment 0.1))
         (scale (make-instance 'gtk:scale
                               :orientation :horizontal
                               :digits 1
                               :value-pos :top
                               :draw-value t
                               :adjustment adj))
         (levelbar1 (create-level-bar :horizontal :continuous))
         (levelbar2 (create-level-bar :horizontal :discrete)))
    ;; Bind adjustment value for the scale to the level bar values
    (g:object-bind-property adj "value" levelbar1 "value" :default)
    (g:object-bind-property adj "value" levelbar2 "value" :default)
    ;; Pack and show the widgets
    (gtk:box-append vbox (make-instance 'gtk:label
                                        :xalign 0.0
                                        :use-markup t
                                        :label "<b>Continuous mode</b>"))
    (gtk:box-append vbox levelbar1)
    (gtk:box-append vbox (make-instance 'gtk:label
                                        :xalign 0.0
                                        :use-markup t
                                        :label "<b>Discrete mode</b>"))
    (gtk:box-append vbox levelbar2)
    (gtk:box-append vbox (make-instance 'gtk:label
                                        :use-markup t
                                        :xalign 0.0
                                        :label "<b>Change value</b>"))
    (gtk:box-append vbox scale)
    (gtk:widget-show window)))

Your code, sorry for the directness, merges into one whole when you look at it. It is very difficult to distinguish one part from another. I wish the code was more like a tree:

(defun main ()
    (ltk:with-ltk ()
        (let* (
               (control-frame (make-instance 'ltk:frame :width 100
                                                        :height 100))
               (text-frame (make-instance 'ltk:frame :width 100
                                                     :height 100))
               
               (speed-spinbox (make-instance 'ltk:spinbox
                                             :from 0 :to 10000
                                             :master control-frame))
               
               (text-field (make-instance 'ltk:scrolled-text :master text-frame
                                                             :width 1 
                                                             :height 1)) 
               (load-button  (make-instance 'ltk:button
                                            :text "Load"
                                            :master control-frame
                                            :command #'(lambda ()
                                                           (let* ((path-to-space-config (ltk:get-open-file :filetypes '(("S-expression" ".sxp"))))
                                                                  (space-config (if (equal path-to-space-config "")
                                                                                    nil
                                                                                    (alexandria:read-file-into-string path-to-space-config))))
                                                               (when space-config
                                                                   (setf (ltk:text text-field)
                                                                         space-config)))))) 

               (start-button (make-instance 'ltk:button
                                            :text "Start"
                                            :master control-frame
                                            :command #'(lambda ()
                                                           (visualise (parse-space-from-string (ltk:text text-field))
                                                                      :speed (parse-integer (ltk:text speed-spinbox)))))))
            (ltk:grid text-frame 0 0)
            (ltk:grid text-field 0 0)
            (ltk:grid control-frame 1 0) (ltk:grid speed-spinbox 0 0)
            (ltk:grid load-button 1 0)
            (ltk:grid start-button 1 1))))

So you can immediately see what is responsible for what.
Best wishes
Filipp

Can't make a GStream binding.

I tried to make binding for GStreamer and get fiasco.
cl-gtk4.gstreamer.asd:

(defsystem cl-gtk4.gstreamer
  :version "1.0.0"
  :author "Filipp Druan <[email protected]>"
  :maintainer "Bohong Huang <[email protected]>"
  :license "lgpl3"
  :description "GStreamer bindings for Common Lisp."
  :homepage "https://github.com/bohonghuang/cl-gtk4"
  :bug-tracker "https://github.com/bohonghuang/cl-gtk4/issues"
  :source-control (:git "https://github.com/bohonghuang/cl-gtk4.git")
  :serial t
  :components ((:file "gstreamer"))
  :depends-on (#:cl-gobject-introspection-wrapper #:cl-gtk4))

(uiop:register-image-restore-hook
 (lambda ()
   (let ((package (find-package :sourceview)))
     (when package
       (setf (symbol-value (find-symbol "*NS*" package))
             (uiop:symbol-call :gir :require-namespace "gstreamer"))))))

gstreamer.lisp:

(cl:defpackage gtkgstreamer
  (:use)
  (:nicknames #:gstreamer)
  (:export #:*ns*))

(in-package #:gstreamer)

(gir-wrapper:define-gir-namespace "gstreamer")

I tried different versions, different spellings of the library name, but Lisp still gave me an error:

CL-USER> (ql:quickload :cl-gtk4.gstreamer)
To load "cl-gtk4.gstreamer":
  Load 1 ASDF system:
    cl-gtk4.gstreamer
; Loading "cl-gtk4.gstreamer"
[package gtkgstreamer]

; file: /home/iam/quicklisp/local-projects/cl-gtk4/gstreamer.lisp
; in: GOBJECT-INTROSPECTION-WRAPPER:DEFINE-GIR-NAMESPACE "gstreamer"
;     (GOBJECT-INTROSPECTION-WRAPPER:DEFINE-GIR-NAMESPACE "gstreamer")
; 
; caught COMMON-LISP:ERROR:
;   (during macroexpansion of (GOBJECT-INTROSPECTION-WRAPPER:DEFINE-GIR-NAMESPACE "gstreamer"))
;   Typelib file for namespace 'gstreamer' (any version) not found
; Debugger entered on #<UIOP/LISP-BUILD:COMPILE-FILE-ERROR {10046B53C3}>
; 
; compilation unit aborted
;   caught 1 fatal ERROR condition
;   caught 1 ERROR condition
[1] CL-USER> 
; Evaluation aborted on #<UIOP/LISP-BUILD:COMPILE-FILE-ERROR {10046B53C3}>

How I can make a binding?

‘Bad FFI method name get_insert’

I’ve been trying to play around with adding markup tags to a GTK TextView using cl-gtk4, but have encountered a few issues with getting the appropriate TextIters for a user selection in CL. The obvious route would be to use get_selection_bounds, but as a relative newcomer to Common Lisp I’m unsure exactly how the two TextIter* arguments are represented in cl-gtk4; I thus decided to instead use get_insert and get_selection_bound, and then get the corresponding TextIter using get_iter_at_mark. Alas, trying to call gtk4:text-buffer-get-insert produces the following error:

Bad FFI method name get_insert
   [Condition of type SIMPLE-ERROR]

Callback when setting up a GtkFileDialog

Hello,
I wanted to implement this feature as part of a menubar action, however when trying to use (gtk:file-dialog-open) I am unable to figure out what would go in place of userdata and callback. Here is a simplified version of what I am trying to do:

(gtk:define-application (:name test-menu :id "okaynoobz.org")
  (defun test-menu-menu ()
    (let ((menu (gio:make-menu)))
      (let ((submenu (gio:make-menu)))
        (gio:menu-append-item submenu (gio:make-menu-item :model menu :label "Load Excel File" 
                                                          :detailed-action "app.open"))
        (gio:menu-append-submenu menu "File" submenu))
      menu))
  (defun setup-file-dialog ()
    (let ((dialog (gtk:make-file-dialog)))
      dialog))
  (gtk:define-main-window (window (gtk:make-application-window :application gtk:*application*))
    (setf (gtk:window-title window) "Test Menu")
    (let ((action (gio:make-simple-action :name "open" :parameter-type nil)))
      (gio:action-map-add-action gtk:*application* action)
      (gtk:connect action "activate" (lambda (action param)
                                       (declare (ignore action param))
                                       (let ((dialog (gtk:make-file-dialog)))
                                         (gtk:file-dialog-open dialog window (gio:make-cancellable)
                                                               (gio:make-task ) -12932)
                                         (setf (gtk:window-transient-for dialog) window
                                               (gtk:window-modal-p dialog) t)
                                         (gtk:window-present dialog)))))
    (let ((window-box (gtk:make-box :orientation gtk:+orientation-vertical+ :spacing 0))
          (menubar (gtk:make-popover-menu-bar :model (test-menu-menu))))
      (gtk:box-append window-box menubar)
      (setf (gtk:window-child window) window-box))
    (unless (gtk:widget-visible-p window)
      (gtk:window-present window))))

I tried looking at other examples in C but there is no AsyncReadyCallback class which I can instatiate nor any make- functions. I know you can make a task, but that itself requires a callback and it's own userdata. Kindly help me with this, love for your project. Thanks

Regards,
Hamza Shahid

Using a List-store

I need to use a list store in my program, but there is no demo of that and I cannot figure it out from the API and the error messages I'm getting. How do I pass the list of columns (I'm assuming that's via the :type keyword, but when I try different things, I get the following error:

The value STRING is not of type (UNSIGNED-BYTE 64)

Compilation errors when installing with (ql:quickload :cl-gtk4)

Quicklisp seems to pull your latest code, but it needs more work. I had to comment out the code in 3 places to have a successful compilation.

Also, with gdk moved to the dependency, I have to modify my example code.

But it is a nice project and has good potential.

FLOATING-POINT-INVALID-OPERATION under SBCL, but not CCL

I've been working through multiple of your examples, including those in issues #25 and #19 and the GTKMM C++ demos of the new List API, with the ultimate goal of displaying a tree view with GtkTreeListModel and GtkColumView, however, the CFFI callback seems to cause an internal floating point error with SBCL, but not in CCL.

(in-package #:gtk-test)

(proclaim '(optimize (safety 0) (speed 0)))

(cffi:defcallback tree-list-model-create-model-func :pointer ((item :pointer) (user-data :pointer))
  (declare (ignore user-data))
  (when item
    (let* ((uuid (string-object-string (gobj:pointer-object item 'string-object))))
      (print uuid)))
  (cffi:null-pointer))

(defstruct product-info
  name cost sale)

(define-application (:name closting :id "com.closting")
  (define-main-window (window (make-application-window :application *application*))


    (let* ((product-table (make-hash-table :test #'equal))
           (rows (loop :for (name cost sale) :in '(("HP Zbook 15" "250$" "300$")
                                                   ("Infinix S90" "40$" "60$")
                                                   ("Casio Calculator" "50$" "80$"))
                       :for product-info := (make-product-info :name name :cost cost :sale sale)
                       :for uuid := (prin1-to-string (uuid:make-v4-uuid))
                       :do (setf (gethash uuid product-table) product-info)
                       :collect uuid))
           (root-model (make-string-list :strings rows))
           (tree-list-model (make-tree-list-model :root (make-multi-selection :model root-model)
                                                  :passthrough nil
                                                  :autoexpand t
                                                  :create-func (cffi:callback tree-list-model-create-model-func)
                                                  :user-data (cffi:make-pointer (glib::put-object nil))
                                                  :user-destroy (cffi:callback glib::free-object-callback)))
           (column-view (make-column-view :model (make-multi-selection :model tree-list-model))))

      (let* ((factory (make-signal-list-item-factory))
             (col (make-column-view-column :title "Test" :factory factory)))

        (flet ((setup (factory item) (declare (ignore factory))
                 (let ((expander (make-tree-expander))
                       (label (make-label :str "")))
                   (setf (tree-expander-child expander) label
                         (list-item-child item) expander)))

               (bind (factory item) (declare (ignore factory))
                 (let* ((row (gobj:coerce (list-item-item item) 'tree-list-row))
                        (uuid (string-object-string (gobj:coerce (tree-list-row-item row) 'string-object)))
                        (expander (gobj:coerce (list-item-child item) 'tree-expander))
                        (label (gobj:coerce (tree-expander-child expander) 'label)))
                   (setf (label-text label) uuid))))

          (connect factory "setup" #'setup)
          (connect factory "bind" #'bind))

        (column-view-append-column column-view col))

      (setf (widget-vexpand-p column-view) t
            (widget-hexpand-p column-view) t
            (window-title window) "Closting"
            (window-child window) column-view)

      (unless (widget-visible-p window)
        (window-present window)))))
arithmetic error FLOATING-POINT-INVALID-OPERATION signalled
   [Condition of type FLOATING-POINT-INVALID-OPERATION]
 0: ((FLET SB-UNIX::RUN-HANDLER :IN SB-UNIX::%INSTALL-HANDLER) 8 #.(SB-SYS:INT-SAP #X66B8E750BD70) #.(SB-SYS:INT-SAP #X66B8E750BC40))
 1: ("foreign function: call_into_lisp_")
 2: ("foreign function: funcall3")
 3: ("foreign function: interrupt_handle_now_handler")
 4: ((LAMBDA (&REST GIR::ARGS-IN) :IN GIR::BUILD-FUNCTION) #.(SB-SYS:INT-SAP #X66B8E00FDB30))
 5: ((LAMBDA (GTK4::APP) :IN GTK-TEST::COM.CLOSTING.MAIN) #<unused argument>)
 6: ((LAMBDA (&REST GTK4::ARGS) :IN GTK4::ATTACH-RESTARTS) #<GIR::OBJECT-INSTANCE {10045A5D53}>)
 7: ((LAMBDA (GIR::CLOSURE RETURN GIR::N-VALUES GIR::PARAMS GIR::HINT GIR::DATA) :IN "/home/soz/quicklisp/dists/quicklisp/software/cl-gobject-introspection-20230618-git/src/signal.lisp") #.(SB-SYS:INT-SAP..
 8: ((LAMBDA (SB-ALIEN::ARGS-POINTER SB-ALIEN::RESULT-POINTER FUNCTION) :IN "/home/soz/quicklisp/dists/quicklisp/software/cl-gobject-introspection-20230618-git/src/signal.lisp") #<unavailable argument> #<..
 9: ("foreign function: funcall_alien_callback")
10: ("foreign function: #x50000DEB")
11: ((LAMBDA (&REST GIR::ARGS-IN) :IN GIR::BUILD-FUNCTION) #.(SB-SYS:INT-SAP #X66B8E0016930) NIL)
12: (GIO:APPLICATION-RUN #<GIR::OBJECT-INSTANCE {1002411A93}> NIL)
13: (SB-INT:SIMPLE-EVAL-IN-LEXENV (GTK-TEST::CLOSTING) #<NULL-LEXENV>)
14: (EVAL (GTK-TEST::CLOSTING))
15: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))

I also can't figure out how to return a pointer to the child model from the GtkTreeListModelCreateModelFunc callback, using
(cffi:make-pointer (glib::put-object (make-string-list :strings (list)))) causes a memory fault under SBCL, and simply hangs under CCL.

I appreciate any help, and thank you very much for the great library.

cl-gtk4/example:simple Doesn't Run Well

I started with my own toy application, a clock. I get a window, the label widget, and initial content, but I can't update the label. Sort of. The code executes, but the window doesn't change, unless I resize it or maximize it, or somehow convince GTK4 to redraw it. Simply hiding it behind another window and re-exposing it doesn't work, nor does minimizing it and un-minimizing it. The tooltip works (and shows the progression of time), presumably because it's reconstructed and drawn fresh every time rather than updated.

Then I tried running cl-gtk4/example:simple, and it does the same thing: the application runs, but the window doesn't update until I do something with the window manager to force a redraw.

Same thing from a shell or slime.

SBCL 2.1.11, Arch Linux, jwm window manager, gtk4 4.8.3, 2022-11-07 quicklisp distribution.

I used quicklisp to install cl-glib and cl-gobject-introspection-wrapper; and cloned cl-gtk4 into my local projects directory.

What other information can I provide?

Can't install CL-GTK.WEBKIT

I tried to install CL-GTK.WEBKIT and got an error:

CL-USER> (ql:quickload :cl-gtk4.webkit2/example)
To load "cl-gtk4.webkit2/example":
  Load 1 ASDF system:
    cl-gtk4.webkit2/example
; Loading "cl-gtk4.webkit2/example"
[package webkit2]

; file: /home/iam/quicklisp/dists/ultralisp/software/bohonghuang-cl-gtk4-20231015170944/webkit2.lisp
; in: GOBJECT-INTROSPECTION-WRAPPER:DEFINE-GIR-NAMESPACE "WebKit2"
;     (GOBJECT-INTROSPECTION-WRAPPER:DEFINE-GIR-NAMESPACE "WebKit2" "5.0")
; 
; caught COMMON-LISP:ERROR:
;   (during macroexpansion of (GOBJECT-INTROSPECTION-WRAPPER:DEFINE-GIR-NAMESPACE "WebKit2" ...))
;   Typelib file for namespace 'WebKit2', version '5.0' not found
; Debugger entered on #<UIOP/LISP-BUILD:COMPILE-FILE-ERROR {1005F712F3}>

Manjaro Linux.
Installed: webkit2gtk, webkit2gtk-4.1, webkit2gtk-6.0,

Bad FFI methood name attach

I've experiences with gtk, but I'm new to Lisp. I've been trying to make a simple front-end using a Grid.

I guess I need to use grid-attach to attach a widget to the grid. But when running that code, I got a Bad FFI method name attacherror. What am I doing wrong?

My code is below. Thanks in advance!

(define-application (:name recycle-app
                     :id "org.recycle-app")
  (define-main-window
      (window (make-application-window :application *application*))
    (setf (window-title window) "recycle-app")
    (let ((box (make-box :orientation +orientation-vertical+
                         :spacing 4))
          (grid-input (make-grid-layout))
          (label-postalcode (make-label :str "Postal code:"))
          ;(label-streetname (make-label :str "Streetname:"))
          ;(label-housenumber (make-label :str "Housenumber:"))
          (button-collect (make-button :label "get collections")))
      (setf (grid-column-spacing grid-input) 8)
      (setf (grid-row-spacing grid-input) 4)
      (grid-attach grid-input label-postalcode 0 0 1 1)
      (box-append box grid-input)
      (box-append box button-collect)
      (setf (window-child window) box))
    (unless (widget-visible-p window)
      (window-present window))))``

Unable to create an executable file in SLIME

老兄还是不行啊,报错信息:
failed AVER: (SB-THREAD::THREAD-P SB-IMPL::THREAD)
This is probably a bug in SBCL itself. (Alternatively, SBCL
might have been corrupted by bad user code, e.g. by an undefined
Lisp operation like (FMAKUNBOUND 'COMPILE), or by stray pointers
from alien code or from unsafe Lisp code; or there might be a
bug in the OS or hardware that SBCL is running on.) If it seems
to be a bug in SBCL itself, the maintainers would like to know
about it. Bug reports are welcome on the SBCL mailing lists,
which you can find at http://sbcl.sourceforge.net/.
[Condition of type SB-INT:BUG]

Can't load the library

Before I deleted the Lisp cache everything loaded and worked fine. After that I tried to load the library and it gave the following error:

CL-USER> (ql:quickload :cl-gtk4.sourceview/example)
To load "cl-gtk4.sourceview/example":
  Load 1 ASDF system:
    cl-gtk4.sourceview/example
; Loading "cl-gtk4.sourceview/example"
[package glib]

; file: /home/iam/quicklisp/dists/ultralisp/software/bohonghuang-cl-glib-20230831185201/glib/package.lisp
; in: GOBJECT-INTROSPECTION-WRAPPER:DEFINE-GIR-NAMESPACE "GLib"
;     (GOBJECT-INTROSPECTION-WRAPPER:DEFINE-GIR-NAMESPACE "GLib")
; 
; caught COMMON-LISP:ERROR:
;   (during macroexpansion of (GOBJECT-INTROSPECTION-WRAPPER:DEFINE-GIR-NAMESPACE "GLib"))
;   Unhandled memory fault at #x18.
; Debugger entered on #<UIOP/LISP-BUILD:COMPILE-FILE-ERROR {10057A03B3}>

Should these values be of float type?

(red :double)

Using float allows me to write color-to-rgba function.

(cffi:defcstruct gdk-rgba
  (red   :float)
  (green :float)
  (blue  :float)
  (alpha :float))

(defmacro with-gdk-rgba ((pointer color) &body body)
  `(cffi:with-foreign-object (,pointer '(:struct gdk-rgba))
     (let ((,pointer (make-instance 'gir::struct-instance
                                    :class (gir:nget gdk::*ns* "RGBA")
                                    :this ,pointer)))
       (gdk:rgba-parse ,pointer ,color)
       ,@body)))

(defun color-to-rgba (color)            ;names are trnaslated correctly
  (cffi:with-foreign-object (rgba '(:struct gdk-rgba))
    (let ((pointer (make-instance 'gir::struct-instance
                                  :class (gir:nget gdk::*ns* "RGBA")
                                  :this rgba)))
      (let ((valid-color (gdk:rgba-parse pointer color)))
        (cffi:with-foreign-slots ((red green blue alpha) rgba (:struct gdk-rgba))
          (list valid-color red green blue alpha))))))

Can you make a tutorial?

Hello!
I really need a tutorial, thet would help my figure out how to deal with the Lisp version of the library using the official documentation for GTK4, which uses C.
There are following questions:

  • What macros and functions were written in Lisp for Lisp version of GTK4&
  • What package are needed for what?
    Thanks!

Can't create simple application.

Hello!
I tried to write the most simple application:

(define-application (:name main
                     :id   "qwertyuiop")
  (define-main-window (main-window (make-application-window :application
                                                            *application*))
    (setf (window-title main-window)
          "Share-files")

    (let ((main-box (make-box :orientation +orientation-vertical+
                              :spacing     0)))
      (setf (window-child main-window)
            main-box)
    
      (window-present main-window))))

When I called main function I got this:

Backtrace:
 0: (GIR::G-SIGNAL-CONNECT-CLOSURE NIL "activate" #.(SB-SYS:INT-SAP #X7FF90EB56AF0) NIL)
 1: (GIR:CONNECT NIL "activate" #<FUNCTION (LAMBDA (&REST GTK4::ARGS) :IN GTK4::ATTACH-RESTARTS) {10074D8B1B}> :AFTER NIL :SWAPPED NIL)
      Locals:
        #:.DEFAULTING-TEMP. = NIL
        #:.DEFAULTING-TEMP.#1 = NIL
        AFTER = NIL
        C-HANDLER = #<FUNCTION (LAMBDA (&REST GTK4::ARGS) :IN GTK4::ATTACH-RESTARTS) {10074D8B1B}>
        C-HANDLER#1 = #<FUNCTION (LAMBDA (&REST GTK4::ARGS) :IN GTK4::ATTACH-RESTARTS) {10074D8B1B}>
        FLAGS = 0
        G-OBJECT = NIL
        #:G0 = #<FUNCTION (LAMBDA (&REST GTK4::ARGS) :IN GTK4::ATTACH-RESTARTS) {10074D8B1B}>
        OBJECT-PTR = NIL
        SIGNAL = "activate"
        STR-SIGNAL = "activate"
        SWAPPED = NIL
 2: (QWERTYUIOP.MAIN NIL)
      Locals:
        GTK4::ARGV = NIL
 3: (SB-INT:SIMPLE-EVAL-IN-LEXENV (MAIN) #<NULL-LEXENV>)
 4: (EVAL (MAIN))
 5: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
 --more--

application = NIL

What about Cairo in Lisp?

What's the deal with Cairo in Lisp? In one of the examples, you used CL-Cairo2, which has not been updated for seven years. Is it still relevant? Maybe it's time to update? Maybe it makes sense to write the same generator for it as for GObject?
Or has the library API not changed since then?

Trouble with GtkListView

Hello, love the work you have done!
I wanted to create a GtkListView, but didn't know how to. After hours of looking through the GTK docs I came up with this code:

	(let* ((model (gtk:make-list-store :types `(,(gobject:type-from-name "GtkLabel"))))
		   (selmodel (gtk:make-single-selection :model model))
		   (factory (gtk:make-signal-list-item-factory))
		   (view (gtk:make-list-view :model selmodel :factory factory))
		   (item1 (gtk:make-label :str "BRUHSEIDh")))
	  (gtk::list-box-append model 6)
	  (setf (gtk:window-child window) view))

Turns out for a reason I cannot understand, list-box-append gives out an error saying it takes only 1 argument...
Please give an example for ListViews or explain this problem to me!
I really don't want to drop this application and write it in another language. Thanks a bunch.

Regards,
Hamza

Returning from dialogs

I'm trying to understand what the lambda used to connect to a response signal from a dialog. Here's what I've got currently

(gtk:connect dialog "response"
                      (lambda (response) (format t "I'm in the response!")))

When I run this, I get the following error:

debugger invoked on a SB-INT:SIMPLE-PROGRAM-ERROR @7005729BE0 in thread
#<THREAD "main thread" RUNNING {7006070573}>:
  invalid number of arguments: 2

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [REPLACE-FUNCTION      ] Call a different function with the same arguments
  1: [CALL-FORM             ] Call a different form
  2: [RETURN                ] Return from current handler.
  3: [RETURN-AND-ABORT      ] Return from current handler and abort the GTK application.
  4: [RETURN-VALUE          ] Return from current handler with specified value.
  5: [RETURN-VALUE-AND-ABORT] Return from current handler with specified value and abort the GTK application.
  6: [CONTINUE              ] Ignore runtime option --eval "(megastrike)".
  7: [ABORT                 ] Skip rest of --eval and --load options.
  8:                          Skip to toplevel READ/EVAL/PRINT loop.
  9: [EXIT                  ] Exit SBCL (calling #'EXIT, killing the process).

((LAMBDA (RESPONSE) :IN BUILD-COMMAND-BAR) #<GIR::OBJECT-INSTANCE {7009F083D3}> -2) [external]
   source: (LAMBDA (RESPONSE) (FORMAT T "I'm in the response!"))

I'm guessing that means there should be 2 arguments to the function, but I can't tell what they would be from the documentation

Please provide example of using XML in building UI

Mostly I need an example of translating:

https://docs.gtk.org/gtk4/getting_started.html

https://docs.gtk.org/gtk4/getting_started.html#packing-buttons-with-gtkbuilder

  /* Construct a GtkBuilder instance and load our UI description */
  GtkBuilder *builder = gtk_builder_new ();
  gtk_builder_add_from_file (builder, "builder.ui", NULL);

  /* Connect signal handlers to the constructed widgets. */
  GObject *window = gtk_builder_get_object (builder, "window");
  gtk_window_set_application (GTK_WINDOW (window), app);

I do not understand how to translate variable pairs like *builder and builder, one with asterix and another without one.

TEXTVIEW key-press-event & tags

i can't find a way to get key pressed events
i tried

(connect window "key-press-event" (lambda (window event) (print event)))

as a C equivalent to
g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK (gkeypress), NULL);

but i always end up getting this type of error
(sbcl:6073): GLib-GObject-WARNING **: 11:33:38.867: ../../../gobject/gsignal.c:2510: signal 'key_press_event' is invalid

I suppose i have to cast widgets to G_OBJECT but i can't find a way to do it in lisp

an example of how to handle key events would be welcome

also i did not manage to create new tags, or in other words to find an equivalent of
tag = gtk_text_buffer_create_tag (buffer, "blue_foreground", "foreground", "blue", NULL);

make-text-tag function does not seem to provide properties
(make-text-tag :name name)

and many thanks for this excellent work btw !

Error Building via Github Actions

I'm trying to build a shippable binary for my program that other people can download and install without really knowing Lisp works. When I do so, I get the following error: Link to error in Github Action.

The action that is running here seems like it should work, but I don't know anything about Github actions, so it is entirely possible that I'm doing this completely wrong. If this isn't the right way to approach this, please let me know. What I want to happen is to have a Linux, a MacOS, and a Windows tarball attached to each release of my game that people can download, unzip, and then just click the file named "megastrike" and it runs.

How to make a GListStore of fixnums / How to subclass GObject

I have a situation where using a GtkStringList to maintain a tree view would be wasteful, as I have directly mapping indexes to an array. As far as I understand from the GTK documentation, GListStore items must be subclasses of GObject.Object, so to use integers, in C I would have to create a new GObject with my integer field, but I can't seem to find a way to do that in cl-gtk4.
This was mentioned in #27 but you ended up providing an alternative solution.
Perhaps my idea of subclassing GObject is suboptimal as well and there is a simpler way to use fixnums?

Not maintaining a reference to Objects causes errors

In sbcl, some (all?) gtk objects seem to requite a persistent reference originating from within the lisp program, otherwise upon garbage collection the object will be deleted (even if there are references to that object from other gtk objects).

To demonstrate the issue I've written a short script (assuming quicklisp is installed).

(ql:quickload '(:cl-gtk4 :cl-glib :bordeaux-threads))

(defun wait-trigger-gc ()
  (sleep 5)
  (sb-ext:gc))

(defvar *shortcuts* nil)
(defvar *window* nil)

(defun start (app)
  (let ((window (gtk4:make-application-window :application app))
        (shortcuts (gtk4:make-shortcut-controller)))

    (setf (gtk4:window-title window) "Test")
    (gtk4:widget-add-controller window shortcuts)
    ;; (setf *shortcuts* shortcuts)
    ;; (setf *window* window)

    (unless (gtk4:widget-visible-p window)
      (gtk4:window-present window))))

(defun run-app ()
  (let ((app (gtk4:make-application
              :application-id "org.rationalis-petra.test"
              :flags gio:+application-flags-flags-none+)))
    (gtk:connect app "activate" #'start)
    (unwind-protect (gio:application-run app nil)
      (progn
        (mapcar (alexandria:compose
                 #'gtk4:window-close
                 (alexandria:rcurry #'gobj:pointer-object 'window))
                (glib:glist-list (gtk4:application-windows app)))
        (glib:idle-add (lambda () (gio:application-quit app)))))))

(defun run-test ()
  (bt:make-thread #'wait-trigger-gc)
  (run-app))

(run-test)

On my system (intel laptop running Linux/EndeavourOS), executing with sbcl --load <filename> results in the following behaviour:

  • By default, after 5 seconds (i.e. when gc is forcibly triggered), the application will report the following error message:

    (sbcl:20304): Gdk-WARNING **: 14:14:19.069: gdk_gl_context_make_current() failed
    
    (sbcl:20304): GLib-GObject-CRITICAL **: 14:14:19.069: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
    0
    

    Sometimes, it will drop you into ldb, and sometimes the application crashes outright.

  • If line (setf *window* window) is uncommented, then after 5 seconds the controller will be deleted, so any event (mouse-move, keypress etc.) will result in sbcl reporting the following error:

    (sbcl:20404): Gtk-CRITICAL **: 14:16:56.782: gtk_event_controller_get_propagation_phase: assertion   'GTK_IS_EVENT_CONTROLLER (controller)' failed
    

    Further, trying to close the window will drop the user into ldb

  • Finally, if both lines are uncommented, then the application works as expected.

Whether or not this is a bug, I am unsure, but if it is expected behaviour I think it should be documented somewhere.

0 is not of type DOUBLE-FLOAT in make-level-bar

when executing the code

(let ((level-bar-widget (gtk:make-level-bar :min-value 0 :max-value 4)))
  (setf (gtk:level-bar-mode level-bar-widget) gtk:+level-bar-mode-discrete+)
  (setf (gtk:level-bar-value level-bar-widget) 2)
  (gtk:box-append layout level-bar-widget))

I receive the following error:

#<THREAD "main thread" RUNNING {7006070483}>:
  The value
    0
  is not of type
    DOUBLE-FLOAT

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [RETURN                ] Return from current handler.
  1: [RETURN-AND-ABORT      ] Return from current handler and abort the GTK application.
  2: [RETURN-VALUE          ] Return from current handler with specified value.
  3: [RETURN-VALUE-AND-ABORT] Return from current handler with specified value and abort the GTK application.
  4: [CONTINUE              ] Ignore runtime option --eval "(megastrike)".
  5: [ABORT                 ] Skip rest of --eval and --load options.
  6:                          Skip to toplevel READ/EVAL/PRINT loop.
  7: [EXIT                  ] Exit SBCL (calling #'EXIT, killing the process).

(CFFI-SYS:%MEM-SET 0 #.(SB-SYS:INT-SAP #X600003149108) :DOUBLE 0)
   source: (DEFINE-TYPE-MAPPING
            ((8 SB-SYS:SIGNED-SAP-REF-8 SB-SYS:SAP-REF-8)
             (16 SB-SYS:SIGNED-SAP-REF-16 SB-SYS:SAP-REF-16)
             (32 SB-SYS:SIGNED-SAP-REF-32 SB-SYS:SAP-REF-32)
             (64 SB-SYS:SIGNED-SAP-REF-64 SB-SYS:SAP-REF-64))
            ((:CHAR CHAR) (:UNSIGNED-CHAR UNSIGNED-CHAR) (:SHORT SHORT)
             (:UNSIGNED-SHORT UNSIGNED-SHORT) (:INT INT)
             (:UNSIGNED-INT UNSIGNED-INT) (:LONG LONG)
             (:UNSIGNED-LONG UNSIGNED-LONG) (:LONG-LONG LONG-LONG)
             (:UNSIGNED-LONG-LONG UNSIGNED-LONG-LONG)
             (:FLOAT SINGLE-FLOAT SB-SYS:SAP-REF-SINGLE)
             (:DOUBLE DOUBLE-FLOAT SB-SYS:SAP-REF-DOUBLE) ...))

I receive the same error when using 0.0, 4.0, and 2.0 and my fumbling around inside the GTK and GOBJ namespaces doesn't return anything that looks like DOUBLE-FLOAT to me.

Request for Extra Example: Using Async

As it says in the title: could you please add an example for using Asynchronous programming. I'm particularly interested in using GAsyncReadyCallback as it's required as an input to some functions (like the file dialogs).

Thanks!

Working with GTK Picture objects

I need to add images to my game. In cl-cffi-gtk, they did this via PixBufs but it seems like the Picture Class is the way I need to go. But I cannot get it to load. Here is my current code

  (let ((frame (gtk:make-frame :label (cu/full-name u)))
        (statblock (gtk:make-box :orientation gtk:+orientation-vertical+ :spacing 5))
        (img (gtk:make-picture :filename (namestring (cu/display u)))))
    (setf (gtk:frame-child frame) statblock)
    (gtk:box-append statblock img)
    frame)

frame is rendered in another function. This same code works when I replace gtk:make-picture with gtk:make-image, but it seems like make-image is for displaying images at a fixed size, not at natural size (which is what I want).

EDIT: Extraneous code rendering labels and other rows of this stat block have been removed. But the code fails whether they are commented out or not. And I am sure that (cu/display u) contains the path to the correct file because gtk:make-image puts a very tiny rendering of that image inside the frame whereas gtk:make-picture does not.

Library needs more documentation

Hello!
I have high hopes for this library. I hope it will be a serious, thorough, long-term project.
Every serious library needs serious documentation. So far it's pretty bad.
Please write docstrings at least for the macros you write. Please!
You can use these tools:
https://github.com/Shinmera/staple
https://github.com/Shinmera/documentation-utils
If need be, I'm willing to put the documentation in a nice way, I'd be very happy to do so. Just please write a description of macros, please.

Getting the "root" window

What's the best way to get the current root window? Should I be storing it in a global variable or is there already a global variable that has it?

In the game I am building, there are different phases of play, each phase of play needs to modify the contents of the window. I'm just now getting to the point where I need to find the best way to manage the transitions between phases and I'm running into a conceptual problem figuring out the best way to handle passing the window around to change it.

So for example, I have created a *game* global variable which has a CLOS class containing all the relevant global variables for the game's state (current turn, current phase, list of units, initiative order, etc). Then I write a advance-phase function that calls (incf (game/current-phase *game*)) which dispatches to a set of functions that I have written to build the display for each screen, like draw-initiative-phase, draw-deployment-phase. Each of those functions creates a gtk:container such as (let ((layout (gtk:make-grid))) ...) or make-box. How do I then get that container passed to my main window?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.