Table of Contents
Errors and Logging
xkb-error
Every error cl-xkbcommon signals is an xkb-error, a subtype of error.
xkb-error-message returns its message, which is also what the condition
prints as.
(handler-case (xkb:make-keymap context :layout "nosuchlayout")
(xkb:xkb-error (condition)
(format *error-output* "~A~%" condition)
(xkb:make-keymap context :layout "us")))
An xkb-error is signalled when
| Situation | Example message |
|---|---|
| a keymap does not compile | libxkbcommon could not compile a keymap for layout "nosuchlayout". libxkbcommon said: ... |
| a keymap text does not compile | libxkbcommon could not compile a keymap from a string of 17 characters. libxkbcommon said: ... |
| a compose table cannot be made | libxkbcommon could not compile a compose table for the locale "xx_NOWHERE". libxkbcommon said: ... |
| a string names no modifier of the keymap | #<KEYMAP {...}> has no modifier "Nope". It has Shift, Lock, Control, ... |
| a destroyed object is used | #<CONTEXT (destroyed) {...}> has been destroyed and cannot be used. |
| libxkbcommon fails to allocate a context, keyboard state or compose state | libxkbcommon could not make a context. |
A modifier keyword that the keymap lacks, such as :hyper in a keymap
without Hyper, is not an error: it is never in effect. Nor is a locale
without a compose table, if you ask make-compose-table with
:errorp nil: it returns nil, and take-log-messages says why.
Arguments of the wrong type signal a type-error instead: a string where
a keycode is expected, or a keyword that names no modifier, which is no
modifier-keyword. SBCL words the message:
The value
:HYPERR
is not of type
(OR STRING
(MEMBER :SCROLL-LOCK :HYPER :META :LEVEL-5 :LEVEL-3 :SUPER :NUM-LOCK :ALT
:CONTROL :CAPS-LOCK :SHIFT))
when binding CL-XKBCOMMON::MODIFIER
Functions that look something up return nil when it is not there; they
do not signal. These are find-key, find-keysym, key-name,
keysym-name, keysym-character, character-keysym, key-keysym,
key-shortcut, key-text, key-press-text, compose-text and
compose-keysym.
What libxkbcommon logs
libxkbcommon reports why compiling failed only through its log. cl-xkbcommon collects the log of each context:
-
When a keymap or compose table fails to compile, the messages logged while compiling go into the
xkb-error's message, afterlibxkbcommon said::libxkbcommon could not compile a keymap for layout "nosuchlayout". libxkbcommon said: error: [XKB-338] Couldn't find file "symbols/nosuchlayout" in include paths error: [XKB-338] 1 include paths searched: error: [XKB-338] /usr/share/X11/xkb ... error: [XKB-822] Failed to compile keymapThe
[XKB-nnn]codes are explained at https://xkbcommon.org/doc/current/error-index.html. -
Messages logged when compiling succeeds, such as the lines of a compose table that were skipped, stay in the context.
take-log-messagesreturns them, oldest first, and empties the log:(xkb:take-log-messages context) ;; => ((:ERROR "(input string):2:19: unrecognized keysym \"bogus\" on right-hand side")) (xkb:take-log-messages context) ;; => NIL
Each message is a list (level text). The level is :critical, :error or
:warning, which are the levels libxkbcommon logs by default. Messages that
went into an error are not returned again by take-log-messages.
A context keeps its 100 newest messages, or as many as the :log-limit
given to make-context. Call take-log-messages after compiling if you
want to show warnings to the user. Messages you never take cost nothing
beyond those the context keeps. An error reports only the messages logged
while the failed keymap or compose table compiled, however full the
context is.
Platforms
libxkbcommon passes its log messages as a C va_list. cl-xkbcommon can
format them only on x86-64. On other platforms the messages go to standard
error, as libxkbcommon writes them by default. There, take-log-messages
always returns nil, and error messages do not include
libxkbcommon said:. See Platforms and Testing.