{"id":26009261,"url":"https://github.com/bohonghuang/cl-gtk4","last_synced_at":"2025-03-05T22:06:55.539Z","repository":{"id":59608767,"uuid":"537031694","full_name":"bohonghuang/cl-gtk4","owner":"bohonghuang","description":"GTK4/Libadwaita/WebKit2 bindings for Common Lisp.","archived":false,"fork":false,"pushed_at":"2025-01-11T03:49:09.000Z","size":1456,"stargazers_count":222,"open_issues_count":25,"forks_count":10,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-01-11T04:38:41.888Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bohonghuang.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-15T13:07:19.000Z","updated_at":"2025-01-11T03:49:12.000Z","dependencies_parsed_at":"2023-01-30T19:01:08.928Z","dependency_job_id":"be4f1602-2e96-4f57-9646-290d2f552834","html_url":"https://github.com/bohonghuang/cl-gtk4","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bohonghuang%2Fcl-gtk4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bohonghuang%2Fcl-gtk4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bohonghuang%2Fcl-gtk4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bohonghuang%2Fcl-gtk4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bohonghuang","download_url":"https://codeload.github.com/bohonghuang/cl-gtk4/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242111444,"owners_count":20073433,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-05T22:02:02.380Z","updated_at":"2025-03-05T22:06:55.533Z","avatar_url":"https://github.com/bohonghuang.png","language":"Common Lisp","funding_links":[],"categories":["Python ##","Miscellaneous ##"],"sub_categories":[],"readme":"#+TITLE: cl-gtk4\n[[https://docs.gtk.org/gtk4/gtk-logo.svg]]\n\nGTK4/Libadwaita/WebKit bindings for Common Lisp.\n* Requirement\nBefore getting started, please ensure these libraries are available in your system:\n- GTK4\n- GObject Introspection\n- WebkitGTK (optional)\n- libadwaita (optional)\nTheoretically, the application built with ~cl-gtk4~ can run on most systems supported by GTK4 and most implementations that support CFFI callback (required by ~cl-gobject-introspection~).\nThe [[file:examples/][examples]] are tested to run on following implementations:\n- SBCL\n  - Microsoft Windows \\\\\n    [[file:examples/screenshots/adw-win.png]]\n  - MacOS \\\\\n    See: [[https://ibb.co/7KZz3r2]]\n  - GNU/Linux \\\\\n    See the screenshots in the [[examples][Examples]] section.\n- CCL\n- ECL\n- ABCL\n* Usage\n1. Currently, ~cl-gtk4~ is available on [[https://ultralisp.org][Ultralisp]],  so it can be downloaded via Quicklisp with Ultralisp installed as its distribution.\n   To install ~cl-gtk4~ manually, you can clone this repository along with the following dependencies into the ~local-projects~ under your Quicklisp installation root:\n   - [[https://github.com/bohonghuang/cl-gobject-introspection-wrapper][cl-gobject-introspection-wrapper]]\n   - [[https://github.com/bohonghuang/cl-glib][cl-glib]]\n2. Load the library with:\n   - ~(ql:quickload :cl-gtk4)~\n   - ~(ql:quickload :cl-gtk4.adw)~ (if you need libadwaita)\n   - ~(ql:quickload :cl-gtk4.webkit)~ (if you need WebkitGTK)\n3. For GTK4 usage, please refer to [[https://docs.gtk.org/gtk4/][GTK API reference]] and check out the [[https://github.com/bohonghuang/cl-gobject-introspection-wrapper#conversion-rules][conversion rules]] for these APIs.\n** Multi-threading\nPlease note that GTK runs in a single thread and is NOT thread-safe, so all the UI-related operations must happen in GTK [[https://docs.gtk.org/glib/main-loop.html][main event loop]],\nwhich means you cannot write the code like this:\n\n#+BEGIN_SRC lisp\n  (let ((label (make-label :str \"0\"))\n        (count 0))\n    (bt:make-thread\n     (lambda ()\n       (loop :repeat 5\n             :do (setf (label-text label) (format nil \"~A\" (incf count)))\n                 (sleep 1)))))\n#+END_SRC\n\nGLib provides ~idle_add~ and ~timeout_add~ to add a function to execute in the main event loop,\nwhich is thread-safe so that it can be called in other threads.\n[[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,\neven when conditions are signaled.\nIt also provides the API for convenience:\n- ~gtk:run-in-main-event-loop~ \\\\\n  Execute the body in GTK main event loop, in which we can access the UI safely:\n  #+BEGIN_SRC lisp\n    (let ((label (make-label :str \"0\"))\n          (count 0))\n      (bt:make-thread\n       (lambda ()\n         (loop :repeat 5\n               :do (gtk:run-in-main-event-loop\n                     (setf (label-text label) (format nil \"~A\" (incf count))))\n                   (sleep 1)))))    ; Don't put this into `gtk:run-in-main-event-loop'\n  #+END_SRC\n** Interactive Programming\n*** Live Reload\nYou 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):\n\n[[file:screenshots/live-reload.gif]]\n*** Restarts\nThe 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.\nAdditionally, you can interrupt and quit the GTK program by typing =C-c C-c= in Emacs(Slime/Sly)'s REPL.\n* Examples\nSee the [[file:examples/][examples]] folder.\n* Deployment\nThe [[file:examples/][examples]] are ready for being built into executable if the implementation supports ~:program-op~:\n#+BEGIN_SRC lisp\n  (asdf:operate :program-op :cl-gtk4/example)\n#+END_SRC\nThen you could find the executable file under the ~examples~ folder.\n\nNote that: \n- On ECL, for unknown reason, the ~:entry-point~ of the ASDF system is ignored.\n  This command should be used instead:\n  #+BEGIN_SRC lisp\n    (asdf:make-build :cl-gtk4/example :type :program :epilogue-code '(progn (uiop:symbol-call :gtk4.example :simple) (si:exit)))\n  #+END_SRC\n- 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.\n  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:\n\n  #+BEGIN_EXAMPLE\n    .\n    ├── bin\n    │   ├── gdbus.exe\n    │   ├── libgio-2.0-0.dll\n    │   ├── libgirepository-1.0-1.dll\n    │   ├── libglib-2.0-0.dll\n    │   ├── libgobject-2.0-0.dll\n    │   ├── libgtk-4-1.dll\n    │   ├── your_application.exe\n    │   └── ...\n    ├── lib\n    │   ├── girepository-1.0\n    │   ├── gtk-4.0\n    │   └── ...\n    └── share\n        ├── icons\n        └── ...\n  #+END_EXAMPLE\n\n  The folder ~lib/girepository-1.0~ is mandatory, without which your application won't work as expected.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbohonghuang%2Fcl-gtk4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbohonghuang%2Fcl-gtk4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbohonghuang%2Fcl-gtk4/lists"}