6 Errors and Logging
dxtr edited this page 2026-10-18 16:16:25 +02:00

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, after libxkbcommon 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 keymap
    

    The [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-messages returns 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.