← home · docs · spec · guide

ketiwe — X11 pixels, no GTK, no deps

From-scratch X11. One window, raw pixels, your loop. Perfect for games, tools, raycasters. No HTML, no Electron.

1open a window

minimal.sb
SB
pls bring ketiwe.
ketiwe_window with "My Window" and 800 and 600.
while ketiwe_poll with is 0 then
  ketiwe_clear with "#1a1a2e".
  ketiwe_rect with 100 and 100 and 200 and 100 and "#e05252".
  ketiwe_flip with.
  sleep_ms with 16.
end

2draw — the primitives

callwhat it does
ketiwe_clear with "#rrggbb"fill whole window
ketiwe_rect with x and y and w and h and "#rrggbb"filled rect
ketiwe_rect_outline with x and y and w and h and "#rrggbb"outline
ketiwe_circle with cx and cy and r and "#rrggbb"filled circle
ketiwe_line with x1 and y1 and x2 and y2 and "#rrggbb"line
ketiwe_text with x and y and "hi"text — only x y text (color arg ignored). fixed font, ~8×13
ketiwe_button with x and y and w and h and "label"button primitive — returns 1 on click
Font: ketiwe_text uses X11 fixed, baseline y. Measure with (length with s) times 8 ≈ width, height 13.

3input — poll, then read

while ketiwe_poll with is 0 then
  set k to ketiwe_key_press with.  # one-shot keysym, cleared on read
  if k is 119 then say "w". end  # 119 w 97 a 115 s 100 d 32 space 49-52 1-4 113 q 65361-65364 arrows
  if ketiwe_mouse_down with is 1 then say "click". end
  set mx to ketiwe_mouse_x with.
  ketiwe_flip with.
end

4pattern — UI toolkit in 60 lines

# immediate-mode, poll → draw → flip
ketiwe_clear with "#0a0a1a".
ketiwe_rect with 20 and 20 and 760 and 560 and "#1a1a2e".
ketiwe_rect_outline with 20 and 20 and 760 and 28 and "#16213e".
ketiwe_text with 30 and 30 and "My Panel".
if ketiwe_button with 30 and 70 and 120 and 32 and "Click" is 1 then say "clicked". end

That's how shimmm (the toolkit behind Shotout) is built — panels, buttons, sliders, minimap, DDA raycaster all on ketiwe primitives.