Skip to content

The window system

The desktop is split in two. The kernel owns a window registry and routes input; everything you can see is drawn by ordinary userspace processes.

kernel/src/window/ is small on purpose. The registry tracks, per window: an id, the owning pid, a rectangle, z-order, focus and a title. It answers questions the compositor and the input router need, such as which window is at this pixel, which one has focus and what the visible set in z-order is. It destroys a process’s windows when the process dies.

A window-input kernel thread routes keyboard and pointer events to the focused window. It reports ready less than a second into boot:

[0.942643] <cpu-0:window-input:k:15> Window input routing thread started

Windowing syscalls let a process create and destroy windows, set properties, list them, and receive events.

Program Role
edos-wm the compositor: composites window buffers to the screen, draws decorations, handles dragging, resizing, minimize, maximize and focus, draws the cursor, and owns the desktop right-click menu
edos-taskbar the panel along the bottom: a launcher and applications menu on the left, a centred button per window, and volume, network and clock on the right
edos-terminal a terminal emulator that spawns /bin/sh on a PTY
edos_render the shared library: outline fonts, text, icons, theme, widgets, layout, and the window syscall wrappers

edos-wm targets roughly 60 frames per second and tracks dirty rectangles so it repaints only what changed.

Moving, resizing, framing, minimizing and posting events to a window are things a shell does to windows belonging to other processes, so they cannot be gated on ownership. They are gated on a privilege instead. The kernel starts exactly one process, bin/edos-init, and what a session consists of is init’s decision, so init holds the privilege and appoints the compositor and the panel as it spawns them. The grant is per pid, follows a process’s threads, and is dropped when the process exits.

An ordinary program is refused: wintest carries the negative control and asserts at startup that it cannot move, put away, or post events to a window it does not own.

Chrome is set in Lato and character grids in JetBrains Mono, rasterized at runtime by edos_render::font from faces in /share/fonts, with a glyph cache. A missing face falls back to a built-in bitmap font, so a bad install costs type rather than the session. Text is measured rather than counted, which is what lets a button size to its label and the panel truncate a window title by pixels.

A window’s contents live in a shared-memory region. The client draws into it, the compositor maps the same region and reads it, with no copy through the kernel per frame. The shared memory registry is a ranked lock (90) precisely because both sides touch it.

edos_render::widgets provides labels, buttons, text inputs, checkboxes and sliders with box layout, each with hover, focus and disabled states. wintest in /bin is the demo that exercises all of them.

Moving a window away can leave the window underneath holding stale pixels until something forces it to redraw: damage from an unmapped or moved region is not always propagated to the windows it exposed. It shows up immediately if you drag a window off another one.