Skip to content

Run apps on the desktop: SDK emulator, plus two fixes it exposed - #1

Open
ihrfv wants to merge 4 commits into
wonderbeel:emulator-getcanvas-fallbackfrom
ihrfv:emulator
Open

ihrfv wants to merge 4 commits into
wonderbeel:emulator-getcanvas-fallbackfrom
ihrfv:emulator

Conversation

@ihrfv

@ihrfv ihrfv commented Jul 22, 2026

Copy link
Copy Markdown

Stacked on top of simmsb#24 (simmsb/inkview-rs), whose GetCanvas() fallback this branch needs — the base
here is emulator-getcanvas-fallback rather than master, so this shows only the five commits it
adds. It should land after simmsb#24 does.

What this adds

A desktop emulator. Some PocketBook SDK archives ship a host x86_64 build of libinkview.so
alongside the ARM one. Because inkview dlopens its library instead of linking it, building for
x86_64-unknown-linux-gnu and putting that directory on the loader path runs the real app on a
developer machine, in an X11 window:

just fetch-emu-assets                              # one-time, ~1.3 GB download, ~40 MB kept
just emu-image                                     # one-time, builds the container
just build-emu-app inkview-slint-demo
just pb_emu_resmode=3 run-emu inkview-slint-demo   # a window
just screenshot-emu inkview-slint-demo             # headless -> target/emu/screenshot.png

screenshot-emu runs against a throwaway Xvfb, so it works headlessly and in CI — the first
rendering check this repo has had.

Two fixes the emulator exposed, both independent of the tooling and revertible on their own:

  • Screen::new now takes the panel down on the GetCanvas() path. Once the panel is active that
    canvas starts PanelHeightFBOffset() rows into the framebuffer (75 at 828x1200) while still
    reporting the full height, so everything drawn landed that far down and the last rows wrapped to
    the top. It only shows up when drawing happens after the Init handler — i.e. from the worker
    thread inkview-slint apps use — which is why it went unnoticed.
  • inkview-slint announces the scale factor before setting the window size. set_size resolves its
    argument against the window's current scale, so passing a logical size first made slint record it
    as the physical one: an 828x1200 screen came out as a 331x480 window. Rendering was unaffected;
    what Window::size() reported was not.

Notes for review

  • The host library is a GTK2/X11 binary built against Debian 9, so it runs in a debian:stretch-slim
    container (utils/emulator/Dockerfile) and binaries target glibc 2.24. utils/emulator/README.md
    covers when to reach for the firmware-level emulator instead.
  • Only the 6.8 archive on the flxzt mirror ships the host subtree; utils/emulator/peek-sdk-archive.py
    checks another release by reading the 7z index over HTTP range requests, without downloading it.
  • On macOS run-emu sets XQuartz up itself, including re-granting xhost on every run — XQuartz
    quits with its last client and comes back with an empty access list.
  • Verified by running: the slint demo renders correctly under the emulator at several geometries,
    takes touch input, and each commit here builds on its own.

🤖 Generated with Claude Code

wonderbeel and others added 4 commits July 23, 2026 04:04
…mmsb#24)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Once the panel is active, GetCanvas() hands back a canvas whose origin is
PanelHeightFBOffset() rows into the framebuffer (75 rows at 828x1200),
while still reporting the full screen height. Everything an app drew
landed that far down and the last rows wrapped around to the top.

Only apps that fall back to GetCanvas() are affected — the emulator,
where GetTaskFramebuffer() is always NULL — and only once the panel has
been set up, so drawing from the Init handler looked correct while
drawing later from a worker thread (as inkview-slint apps do) did not.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
set_size resolves its argument against the window's current scale
factor, so passing a logical size before announcing the scale made slint
record that logical size as the physical one — a 828x1200 screen came
out as a 331x480 window. Announce the scale first and pass physical
pixels, which needs no conversion at all.

Rendering is unchanged; it is what Window::size() reports that was wrong.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The SDK's host build of libinkview lets an app run on a desktop, which is not
obvious from anything in this repo. Links the external tool that packages it,
without taking on the tooling itself.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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