fix(capi): permitted-values probe call returned 0 before querying - #58
Merged
Merged
Conversation
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>
This was referenced Aug 25, 2026
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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: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->stringValuesand 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_valuesin 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.