Skip to content

Viewer (Linux): native Wayland, coalesced redraws, crisp text and shapes - #59

Open
HttpKiwi wants to merge 1 commit into
TomasUribe:masterfrom
HttpKiwi:linux-ui-crisp-and-responsive
Open

HttpKiwi wants to merge 1 commit into
TomasUribe:masterfrom
HttpKiwi:linux-ui-crisp-and-responsive

Conversation

@HttpKiwi

Copy link
Copy Markdown

On niri (Wayland, 1920x1080 at scale 1) the desktop viewer took around 4 s from a click to the settings drawer opening, and its text and rounded UI looked jagged. This fixes both.

Responsiveness

  • Native Wayland on every Wayland session except GNOME. sdl2-compat still prefers X11, so outside KDE the viewer ran under XWayland (xwayland-satellite on niri). GNOME still gets SDL's default. An explicit SDL_VIDEODRIVER / SFT_VIDEO_DRIVER / --video-driver still wins, and the existing fallback stays in place.
  • Redraws are merged per batch of events. app_events redrew the home screen or drawer, and waited for vsync, on every event, mouse moves included. A high-polling-rate mouse queued up seconds of presents ahead of a click: app_events measured up to 2.3 s per call. Redraws requested while handling events now set a flag and run once after the queue is empty, which brought the worst case to 4.5 ms. During a Win32 live resize (g_in_size_move) it still draws immediately.

Crisp text and shapes

The UI drew everything from bitmaps made at one size and bilinear-scaled: a 32/56 px font atlas drawn at 11–20 px, and a 96 px disc and icons drawn at radius 4–20 px. At 3–8× minification that skips texels and comes out jagged.

  • Text: rasterized by stb_truetype v1.26 (vendored in third_party/stb, MIT or public domain) at the exact on-screen pixel size, from DejaVu Sans and Bold subset to ASCII and embedded (24 KB). Glyphs are cached, placed at quarter-pixel positions, kerned, and copied texel for texel. The size is computed in device pixels, so the scaled stats overlay and HiDPI windows stay sharp. font_dejavu.h goes from 188 KB to 69 KB, and gen_font.py now only subsets and embeds the fonts.
  • Rounded rects, pills and knobs: anti-aliased geometry (SDL_RenderGeometry, a 1 px fading edge) at any size.
  • Gear and pin icons: rasterized at their pixel size (same shape functions, 4×4 coverage) and cached by that size.
  • The text_draw / text_width / ui_rrect signatures are unchanged, so callers didn't change.
  • The Windows, macOS and portable Linux packaging scripts copy stb_truetype's licence into licenses/.

Testing

  • Built on Arch (sdl2-compat 2.32, gcc) with no new warnings.
  • Home screen, settings drawer and stats overlay checked with --shot at 1896×1031 and 838×628 (0.85 UI density).
  • tools/sft_stream_test.py: raw-view decoded all 40 packets with the expected single lost frame. The PyAV check couldn't run here (no av module).
  • Not built or tested on Windows or macOS.

🤖 Generated with Claude Code

- Every Wayland session but GNOME now uses SDL's Wayland driver. On niri,
  sway and similar, sdl2-compat picked X11, which went through
  xwayland-satellite and made the UI take seconds per click.
- app_events defers redraws until the event queue is empty. Drawing and
  waiting for vsync on every mouse move let a fast mouse queue up seconds
  of redraws ahead of a click.
- Text is rasterized by stb_truetype (third_party/stb, v1.26) at the exact
  pixel size it lands on screen, from DejaVu Sans / Bold subset to ASCII
  and embedded (24 KB), with a glyph cache, quarter-pixel positions and
  kerning. This replaces the 32/56 px atlas that was bilinear-scaled
  3-4x down and came out jagged. font_dejavu.h goes from 188 KB to 69 KB.
- Rounded rects, pills and knobs are anti-aliased geometry
  (SDL_RenderGeometry); the gear and pin icons are rasterized at their
  pixel size. This replaces the 96 px disc/icon textures scaled down.
- Packaging scripts ship stb_truetype's licence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TomasUribe

Copy link
Copy Markdown
Owner

Thanks! The coalesced redraws are a clear win. One blocker: SDL_RenderGetWindow (menu.h unit_xform) needs SDL 2.0.22, so make fails on Ubuntu 22.04 (SDL 2.0.20); g_paint_win holds the same window. The Windows cross-build compiles; could you (or someone) check the text on Windows and macOS before it goes in, since the font path is shared?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants