Giter Club home page Giter Club logo

cl-gtk4's Introduction

cl-gtk4

Requirement

Before getting started, please ensure these libraries are available in your system:

  • GTK4
  • GObject Introspection
  • WebKit2GTK (optional)
  • libadwaita (optional)

Theoretically, 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). The examples are tested to run on following implementations:

Usage

  1. Currently, cl-gtk4 is available on Ultralisp, so it can be downloaded via Quicklisp with Ultralisp installed as its distribution. To install cl-gtk4 manually, you can clone this repository along with the following dependencies into the local-projects under your Quicklisp installation root:
  2. Load the library with:
    • (ql:quickload :cl-gtk4)
    • (ql:quickload :cl-gtk4.adw) (if you need libadwaita)
    • (ql:quickload :cl-gtk4.webkit2) (if you need WebKit2GTK)
  3. For GTK4 usage, please refer to GTK API reference and check out the conversion rules for these APIs.

Multi-threading

Please note that GTK runs in a single thread and is NOT thread-safe, so all the UI-related operations must happen in GTK main event loop, which means you cannot write the code like this:

(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. cl-glib wraps idle_add and timeout_add, so that you can pass Lisp functions to them. It also provides these two APIs for convenience:

  • glib:with-main-event-loop
    Execute the body in GTK main event loop, in which you can access the UI safely:
    (let ((label (make-label :str "0"))
          (count 0))
      (bt:make-thread
       (lambda ()
         (loop :repeat 5
               :do (glib:with-main-event-loop
                     (setf (label-text label) (format nil "~A" (incf count))))
                   (sleep 1)))))    ; Don't put this into `glib:with-main-event-loop'
        
  • glib:funcall
    Just like cl:funcall, it calls a function with the rest of its arguments, but within GTK main event loop:
    (let ((window (make-application-window :application app)))
      (bt:make-thread
       (lambda ()
         (sleep 1)
         (glib:funcall #'window-present window))))
        

Examples

examples/screenshots/gtk4-simple.png

To run this example, eval the following in your REPL:

(ql:quickload :cl-gtk4/example)
(gtk4.example:simple)

Fibonacci Calculator (Multi-threading)

examples/screenshots/gtk4-fibonacci.png

To run this example, eval the following in your REPL:

(ql:quickload :cl-gtk4/example)
(gtk4.example:fibonacci)

Simple Lisp REPL (Libadwaita)

examples/screenshots/adw.png

To run this example, eval the following in your REPL:

(ql:quickload :cl-gtk4.adw/example)
(adw.example:main)

Simple Web Browser (WebKit2GTK)

examples/screenshots/webkit2.png

To run this example, eval the following in your REPL:

(ql:quickload :cl-gtk4.webkit2/example)
(webkit2.example:main)

Deployment

The examples are ready for being built into executable if the implementation supports :program-op:

(asdf:operate :program-op :cl-gtk4/example)

Then you could find the executable file under the examples folder.

Note that:

  • On ECL, for unknown reason, the :entry-point of the ASDF system is ignored. This command should be used instead:
    (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 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.

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.