6 Home
dxtr edited this page 2026-10-18 15:09:28 +02:00

cl-wl

Wayland clients in Common Lisp, through libwayland-client. cl-wl connects to a compositor, binds its globals and sends requests. It delivers events to handlers you write in Lisp. Protocol values arrive as Lisp values: integers, keywords, strings, floats and proxies. Errors are conditions.

The bindings are generated from the protocol XML by cl-wl's own scanner, and the generated code is committed. Loading cl-wl therefore needs only the libwayland-client shared library. It needs no C compiler, no headers and no XML parser.

(asdf:load-system :cl-wl/xdg-shell)

(defpackage #:example
  (:use #:cl)
  (:local-nicknames (#:wl #:cl-wl)
                    (#:wlp #:cl-wl/wayland)
                    (#:xdg #:cl-wl/xdg-shell)))
(in-package #:example)

(wl:with-display (display)
  (let* ((compositor (wl:bind display 'wlp:wl-compositor))
         (wm-base (wl:bind display 'xdg:xdg-wm-base))
         (surface (wlp:wl-compositor-create-surface compositor))
         (xdg-surface (xdg:xdg-wm-base-get-xdg-surface wm-base surface))
         (toplevel (xdg:xdg-surface-get-toplevel xdg-surface)))
    (wl:set-event-handlers xdg-surface
                           :configure (lambda (xdg-surface serial)
                                        (xdg:xdg-surface-ack-configure xdg-surface serial)))
    (wl:set-event-handlers wm-base
                           :ping (lambda (wm-base serial)
                                   (xdg:xdg-wm-base-pong wm-base serial)))
    (wl:set-event-handlers toplevel
                           :configure (lambda (toplevel width height states)
                                        (declare (ignore toplevel))
                                        (format t "~&Configure: ~Dx~D ~A~%" width height states))
                           :close (lambda (toplevel)
                                    (declare (ignore toplevel))
                                    (format t "~&Close requested~%")))
    (xdg:xdg-toplevel-set-title toplevel "Hello")
    (wlp:wl-surface-commit surface)
    (wl:dispatch display :timeout 1)))
;; Configure: 0x0 NIL

Pages

Start here

  • Getting Started: installing, loading, and a first program that puts a window on screen.
  • Concepts: displays, proxies, globals, requests, events and versions, and how protocol names become Lisp names.

Guides

  • Globals: binding the compositor's globals, choosing versions, optional interfaces, and following globals that come and go.
  • Requests and Events: sending requests, handling events, and the Lisp value of every wire type, including enums, bitfields and arrays.
  • Event Loops: dispatch, roundtrip, timeouts, waiting on the connection's fd, and an event thread with read-events.
  • Protocol Bindings: the protocols cl-wl ships, their packages and interfaces, and how to read a binding's documentation.
  • Cursors: cursors by name through cursor-shape-v1, or from the user's cursor theme through libwayland-cursor.
  • Recipes: shared-memory buffers, frame callbacks, keyboards with cl-xkbcommon, pointers, outputs and scale, decorations, the clipboard, and Vulkan surfaces.
  • Testing with the Test Compositor: testing your own Wayland code without a real compositor.

Reference

  • API Reference: every exported symbol of cl-wl and cl-wl/test-compositor.
  • Errors: the conditions, what each means, and how to handle a broken connection.
  • Lifetimes and Threads: destroying proxies, which objects may be shared between threads, and what allocates.
  • The Scanner: how the bindings are generated, and how to add a protocol.
  • Raw FFI Layer: cl-wl/ffi, the direct transcription of libwayland-client, on cl-ffi.
  • Internals: how events and requests travel between Lisp and libwayland, for contributors.
  • Platforms and Testing: requirements, operating systems, and running the test suite.

Systems

System What it is
cl-wl The library: displays, proxies, dispatch, globals, and the core protocol in package cl-wl/wayland.
cl-wl/xdg-shell Bindings for xdg-shell: windows and popups.
cl-wl/xdg-decoration Bindings for xdg-decoration: asking the compositor to draw title bars.
cl-wl/viewporter Bindings for viewporter: showing a buffer cropped and scaled.
cl-wl/fractional-scale Bindings for fractional-scale-v1: scales such as 1.5.
cl-wl/tablet Bindings for tablet-v2: drawing tablets, their tools and pads.
cl-wl/cursor-shape Bindings for cursor-shape-v1: cursors the compositor draws by name. Loads cl-wl/tablet.
cl-wl/text-input Bindings for text-input-v3: input methods, with text being composed and text chosen.
cl-wl/pointer-constraints Bindings for pointer-constraints-v1: locking the pointer or confining it to a surface.
cl-wl/relative-pointer Bindings for relative-pointer-v1: the pointer's motion as it is, which goes on while it is locked.
cl-wl/xdg-dialog Bindings for xdg-dialog-v1: a window with a parent as a dialog of it, modal or not.
cl-wl/cursor Cursor themes through libwayland-cursor, for setting cursor images yourself.
cl-wl/cursor-ffi The raw layer of libwayland-cursor, on cl-ffi, under cl-wl/cursor.
cl-wl/test-compositor An in-process compositor for testing code built on cl-wl.
cl-wl/ffi The raw layer, on cl-ffi. No error checking and no memory management.
cl-wl/scanner Build-time tool that generates the bindings from protocol XML.
cl-wl/test The Parachute test suite.

License

MIT. The protocol files in protocols/ keep their own licences, which are stated in each file.