Errors
Conditions
Every error cl-windowing signals is a windowing-error:
error
└── windowing-error
├── window-system-error the window system cannot be reached, or the connection failed
├── no-backend-error the backend asked for, or the platform's, is not loaded
├── popup-error a popup breaks the window system's rules
├── dialog-error a dialog cannot be made
├── unsupported-error the window system cannot do what was asked
└── closed-error a closed window system or a destroyed window was used
Arguments of the wrong type signal a standard type-error at the public
function they were passed to. Every public function declares its
arguments' types, which SBCL checks as the function is entered, so the
error names the declared type, with the library's types expanded:
The value :NONSENSE is not of type (MEMBER :NUM-LOCK :CAPS-LOCK :SUPER
:ALT :CONTROL :SHIFT) when binding CL-WINDOWING:MODIFIER
A call with a constant of the wrong type makes SBCL warn as it compiles the call.
window-system-error
The window system cannot be reached, or the connection to it failed:
open-window-systemfinds no compositor, or one that lacks what cl-windowing needs;- the compositor closes the connection;
- the compositor reports a protocol error.
(window-system-error-message condition) returns the message, which says
what went wrong and what to check:
Cannot connect to the Wayland compositor "no-such-socket": Could not
connect to the Wayland display "no-such-socket". Is a compositor running,
and is $WAYLAND_DISPLAY or :DISPLAY-NAME right?
The Wayland compositor does not offer xdg_wm_base, which cl-windowing
needs to open windows.
The Wayland compositor reported a protocol error: The compositor raised
protocol error 3 on xdg_surface 8.
After a window-system-error from process-events, the connection is
gone, and the window system cannot be used again. Release its windows and
close it, as the with- macros do on the way out: releasing succeeds on a
failed connection, so the error that broke it is the one that propagates.
To recover, open a new window system.
no-backend-error
open-window-system was asked for a backend that is not loaded, or none
was asked for and the platform's, :win32 on Windows and :wayland
elsewhere, is not loaded. (no-backend-error-backend condition) returns
that backend, a keyword.
The window system backend :WIN32 is not loaded. Load the system
cl-windowing/win32 first. Loaded backends: :WAYLAND.
popup-error
create-popup and reposition-popup were asked for a popup that breaks
the window system's rules: a popup that grabs made on a top-level window
while another popup grabs, on a popup that does not grab, or on a popup
that grabs but is not the newest one that does; or moving a popup on a
Wayland compositor whose xdg_wm_base is older than version 3. Setting
window-fullscreen-p on a popup signals it too.
(popup-error-message condition) returns the message. See
Popups.
dialog-error
create-window was asked for a dialog it cannot make: a modal window
without a :parent, or a :parent that is a popup or belongs to another
window system. A dialog opened from a popup, as from a menu, is made on
the top-level window the popup is on. (dialog-error-message condition)
returns the message. See Dialogs.
unsupported-error
The window system cannot do what was asked, as confining or capturing the
pointer on a Wayland compositor without pointer-constraints-v1 and
relative-pointer-v1. (unsupported-error-message condition) returns the
message. window-system-capabilities says beforehand what it can do: here,
:pointer-capture.
closed-error
A window system was used after close-window-system, or a window after
destroy-window. (closed-error-object condition) returns it.
#<WAYLAND-WINDOW "" 800x600 (destroyed)> has been closed and cannot be used.
Functions that act on the platform signal it:
| On a closed window system | On a destroyed window |
|---|---|
process-events, create-window, window-system-capabilities, close-window-system |
destroy-window, (setf window-title), adopt-window-size, create-vulkan-surface |
Functions that only read what the object knows keep working, such as
window-size, window-title and poll-event, so that code that handles
the last queued events of a destroyed window does not fail. Check
window-alive-p and window-system-open-p when you need to know.
Warnings
On Wayland, a keymap the compositor sends that libxkbcommon cannot compile is ignored with a warning, and the previous keymap stays.
Handling errors on the event thread
An event thread should stop when the window system fails:
(handler-case
(loop until *stop*
do (win:process-events window-system :timeout 0.05)
(loop while (win:poll-event window-system event)
do (handle event)))
(win:windowing-error (condition)
(warn "The window system failed, stopping: ~A" condition)
(setf *stop* t)))
Lifetimes
| Made by | Released by | Macro |
|---|---|---|
open-window-system |
close-window-system |
with-window-system |
create-window |
destroy-window |
with-window |
create-popup |
destroy-window, or with its parent |
|
create-vulkan-surface |
cl-vk:destroy-surface |
Release in the reverse order of making: surfaces before their windows,
windows before their window system. close-window-system destroys the
windows that are still alive, but not their Vulkan surfaces.
The with- macros release on any exit, by a non-local exit or an error
included, and do nothing if the object was released already in the body.
Releasing never fails because the connection has: when the compositor has
gone, the window and the window system are still released, and the next
process-events reports the failure.