[[https://docs.gtk.org/gtk4/gtk-logo.svg]]
GTK4/Libadwaita/WebKit bindings for Common Lisp.
(let ((label (make-label :str "0")) (count 0)) (bt:make-thread (lambda () (loop :repeat 5 :do (setf (label-text label) (format nil "~A" (incf count))) (sleep 1)))))
GLib provides ~idle_add~ and ~timeout_add~ to add a function to execute in the main event loop, which is thread-safe so that it can be called in other threads. [[https://github.com/bohonghuang/cl-glib][cl-glib]] wraps ~idle_add~ and ~timeout_add~, and [[https://github.com/bohonghuang/cl-gtk4][cl-gtk4]] create restarts for the handler passed for them to be invoked safely, even when conditions are signaled. It also provides the API for convenience:
(let ((label (make-label :str "0")) (count 0)) (bt:make-thread (lambda () (loop :repeat 5 :do (gtk:run-in-main-event-loop (setf (label-text label) (format nil "~A" (incf count)))) (sleep 1))))) ; Don't put this into `gtk:run-in-main-event-loop'
** Interactive Programming *** Live Reload You can reload the application without closing the window constructed in ~define-main-window~ by recompiling the ~define-application~ macro in top-level (Simply stroke =C-c C-c= if using Slime/Sly in Emacs):
[[file:screenshots/live-reload.gif]] *** Restarts The API in ~cl-gtk4~ handles almost all possible recoverable errors by providing restarts, by which you can recover the program or safely exit the GTK application when encountering an error.
Please note that stack unwinding into FFI functions is unsafe and may cause you to be unable to run the GTK application in the current session again, or even freeze or crash the Lisp implementation. Therefore, it is important to always use the restarts provided by ~cl-gtk4~ or other restarts that do not unwind the stack into FFI functions to recover or exit the application.
Additionally, when you attempt to interrupt a GTK program through Slime/Sly, such as =C-c C-c= in Emacs' REPL, remember to choose =ABORT-APPLICATION= provided by ~cl-gtk4~ instead of =ABORT= provided by the Lisp implementation.
The highlighted restarts as follows, for example, are safe, while the rest perform stack unwinding and are therefore unsafe in GTK applications:
[[file:screenshots/restart-1.png]]
[[file:screenshots/restart-2.png]]
(asdf:operate :program-op :cl-gtk4/example)
Then you could find the executable file under the ~examples~ folder.
Note that:
(asdf:make-build :cl-gtk4/example :type :program :epilogue-code '(progn (uiop:symbol-call :gtk4.example :simple) (si:exit)))
On Microsoft Windows, it's recommended to launch your application via [[https://www.dependencywalker.com/][Dependency Walker]], then the shared libraries used by your application would appear in it. You should copy all these ~.dll~ files into the folder where you place the executable file. If you are using MSYS2, the folder structure might be like this:
. ├── bin │ ├── gdbus.exe │ ├── libgio-2.0-0.dll │ ├── libgirepository-1.0-1.dll │ ├── libglib-2.0-0.dll │ ├── libgobject-2.0-0.dll │ ├── libgtk-4-1.dll │ ├── your_application.exe │ └── ... ├── lib │ ├── girepository-1.0 │ ├── gtk-4.0 │ └── ... └── share ├── icons └── ...
The folder ~lib/girepository-1.0~ is mandatory, without which your application won't work as expected.