Skip to content

fix(capi): permitted-values probe call returned 0 before querying - #58

Merged
willwade merged 1 commit into
mainfrom
fix/capi-permitted-values-probe
Aug 25, 2026
Merged

willwade merged 1 commit into
mainfrom
fix/capi-permitted-values-probe

Conversation

@willwade

Copy link
Copy Markdown

Found the hard way: Dasher-GTK's footer alphabet dropdown was blank despite the engine carrying 475 alphabets.

Root cause

dasher_get_parameter_string_values(ctx, key, nullptr, 0) — the documented count-only probe — had its early-out before the engine query:

if (!out_names || max_out <= 0) return 0;   // returned 0 without querying

Every caller using the two-call pattern (probe for count, then fetch — exactly what Dasher-GTK's bridge does) got an empty list for every permitted-values parameter: alphabets, palettes, input filters.

Fix

The probe now populates ctx->stringValues and returns the full count; callers size a buffer and call again as documented. Verified with a standalone harness against the engine: 475 alphabet names enumerate, and the engine's current alphabet is present in the list (index 105).

Test

string_values in test_capi_extended now asserts: probe count > 0, probe count == fetch count, and the current alphabet is among the permitted values. Full suite 39/39 green.

Same family as the GTK blank-picker symptoms (its dropdown refresh landed app-side, but the list API itself was the blocker).

DCO signed.

dasher_get_parameter_string_values(ctx, key, nullptr, 0) - the documented
count-only probe - returned 0 without ever asking the engine, because the
early-out for a null buffer preceded the query. Every caller following
the two-call pattern got an empty list: frontends rendered blank
alphabet/palette pickers (seen live on Dasher-GTK, where the footer
alphabet dropdown was empty despite the engine carrying 475 alphabets).

The probe now populates ctx->stringValues and returns the full count, so
callers can size a buffer and call again. Verified: 475 alphabet names
enumerate and the engine current alphabet is present in the list.

Regression test extends string_values: probe count matches the fetch
count and the current alphabet is among the permitted values.

Signed-off-by: will wade <willwade@gmail.com>
greptile-apps[bot]

This comment was marked as low quality.

@willwade
willwade merged commit 026fcfb into main Aug 25, 2026
14 checks passed
willwade added a commit to dasher-project/Dasher-Apple that referenced this pull request Aug 26, 2026
…abel metrics (#42)

Fixes #41. Ports the [Dasher-Windows
#36](dasher-project/Dasher-Windows#36)
choppiness diagnosis to every Apple target.

## 1. macOS frame pacing — the Windows bug, verbatim
`MacDasherCanvas` drove `draw(_:)` with a free-running `Timer(1/60)` —
decoupled from the compositor, beat-frequency judder, skipped/doubled
frames, worst at slow zoom. Now **`CVDisplayLink`** locked to vsync
(retained self in the callback context, hops to main; stopped + released
on leaving the window). iOS/visionOS already used `CADisplayLink` and
are untouched.

## 2. Clamped engine timeline — all four targets
The engine consumes raw deltas as zoom amount; every canvas passed
unclamped wall-clock `Date()`. A pause (settings sheet over canvas,
backgrounded app where `CADisplayLink` stops) injected a **multi-second
delta = giant zoom jump** on resume. Bridges now convert timestamps via
`timelineMs(forWallMs:)`: deltas capped at 50 ms, backwards clocks hold
position, own monotonic accumulation (`resetTimeline()` for recreation).
Mirrors Windows' `EngineTimelineTests` contract.

## 3. Real label metrics — all four targets
`dasher_set_text_size_callback` was never wired here, so the engine
measured labels with its code-point × fontSize/2 estimate — the exact
cause of Windows' **squashed/jumbled deep-zoom labels**. Each bridge now
measures with the same font opcode-5 draws with (`fontName` is now a
bridge property shared by both paths), **returning 0 on success** per
the dasher.h contract (the inversion Windows suffered). Frontend cache
keyed text+font+size, bounded at 4096, invalidated on `SP_DASHER_FONT`
change (`dasher_text_metrics_changed`).

## 4. DasherCore v0.2.5 + probe-then-fetch
The old 64-slot `getStringValues` buffer silently truncated longer lists
— `SP_DASHER_FONT` runs to hundreds. Now probes the count first (needs
v0.2.5's [DasherCore
#58](dasher-project/DasherCore#58) fix) and
fetches into an exact-size buffer.

## Builds
All four schemes compile clean: DasherMac (macOS), DasherApp (iOS
device), DasherKeyboard, DasherVision. (iOS *Simulator* x86_64 slice
fails on a pre-existing `speechmarkdown_rust` artifact gap — unrelated
to this PR, present before it.)

## Not done here
Windows pinned their invariants in tests (#37); worth a follow-up once
we have a test target strategy for the bridges.

Signed-off-by: will wade <willwade@gmail.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.

1 participant