Search guides and the APICtrl K
  1. API reference
  2. Native GUI

gfx/window_x11.h

The X11 window, so the native UI is not a Windows-only thing.

#include <sonore/gfx/window_x11.h>
On this page

Design notes

Why this is small

The rasteriser is shared. Everything with a rule in it -- coverage, winding, gradients, text, hit-testing, gestures -- already ran and was checked before this file existed, and is byte-for-byte identical on every platform. What is left for a platform is three things: make a window, put a rectangle of pixels in it, and turn its input into MouseEvents. That is the whole file.

Why libX11 is opened rather than linked

Same reasoning as the GTK webview next door. A plugin that links libX11 hard fails to LOAD on a host that does not have it -- a Wayland-only session, a headless render farm -- and it fails with a loader error, which is the least diagnosable failure a plugin can have. Opened at runtime, the plugin loads, says why it has no native window, and the wrapper falls back.

The headers, though

XEvent is a union of thirty structures and its layout is the ABI. Hand-rolling it the way the AU shim hand-rolls Apple's declarations would be inviting a silent mismatch, so this compiles against <X11/Xlib.h> when it is there and compiles to "unavailable, and here is why" when it is not. Nothing links.

Including them is not free, and the cost is names. Xlib puts Window, Font, Cursor, Screen and Time into the GLOBAL namespace as typedefs, and None, Bool, Success, Always and Complex in as MACROS. The macros are put away at the bottom of this file. The typedefs cannot be -- they are types, not definitions -- and two of them collide with names this SDK already has:

sonore::gfx::Font
vs ::Font (an XID for a server-side font)
sonore::Window
vs ::Window (fft.h has a window-function selector)

Inside this file every X11 type is spelled ::Window, ::Font and so on. A file that says using namespace sonore::gfx AND includes this one has to spell ours out the same way. There is no version of this that costs nothing.

Input methods (XIM) -- compiled, not run

As of 2026-10-14 the XIM half of this file has been compiled against the real Xlib.h and never run: there is no X server here, and the CI that runs x11_window_test under Xvfb has no input method server either. What a Linux developer runs to see it work is tests/x11_input_selftest.cpp.

Opened LAZILY, the first time a text field takes the focus: an editor of knobs never talks to an input method server at all. Then:

  • XOpenIM after XSetLocaleModifiers(""), which is how XMODIFIERS (@im=ibus, @im=fcitx) picks the server. No server means no XIM; the peer says so, registers to be told when one starts, and types as before.
  • XCreateIC with the first style the server offers, in this order: on-the-spot (XIMPreeditCallbacks) -- the composition drawn in the field through gfx/text_input.h, as on macOS -- then over-the-spot (XIMPreeditPosition: the server draws it at XNSpotLocation, the caret), then root-window (XIMPreeditNothing: the server's own window). In a locale that is not UTF-8 over-the-spot comes first: Xlib converts the preedit into the locale's encoding before the callbacks see it, and Japanese does not survive the C locale. SONORE_XIM_STYLE overrides the order (callbacks, position, nothing); SONORE_X11_NO_IME turns it off.
  • XFilterEvent on every event first, as the protocol requires, and Xutf8LookupString for committed text -- which arrives as a KeyPress the server sends back, and may be a whole word.
  • XSetICFocus while a text field has the focus and the window has the X focus; XUnsetICFocus otherwise, so the input method does not compose over a knob's shortcuts.

Every failure is reported in inputMethodStatus() and, once per process, on stderr: an input method that silently does nothing is indistinguishable from one nobody wrote.

Types 3

The pieces of Xlib this needs, resolved once.

Deliberately a short list. Every entry here is a thing a plugin window genuinely cannot do without, and the list not growing is the measure of whether the shared-rasteriser design held.

The XDND atoms.

X has no drag-and-drop of its own. XDND is a CONVENTION built on client messages and selections, and every desktop implements it because there is nothing else. It is a real handshake, not a notification: the source asks whether we will take the drop and WAITS for an answer before the user is even allowed to release, which is why the X11 peer can light a target on hover where the Win32 one cannot.

Interned once per display, because a round trip per atom per drag event would be a dozen round trips a frame while the pointer moves.

A component tree in an X window, with the same surface as the Win32 one.

Identical API on purpose: NativeEditor holds one or the other and knows nothing about which, so a difference between the platforms has to be written deliberately rather than arrived at.

Functions 1

Constants 3

Macros 1

↑↓ to move↵ to openEvery public name in the headers, and every guide