Repository navigation
GTK4: 4 widget overlay/reorder FFIs not wired — blocks docs/examples/ui/layout/snippets.ts on Linux CI #217
Copy link
Copy link
Closed
Labels
enhancementNew capability or improvementNew capability or improvement
Description
Context
docs/examples/ui/layout/snippets.ts declares // platforms: macos, linux, windows and imports widgetReorderChild, widgetRemoveChild, widgetAddOverlay, widgetSetOverlayFrame from perry/ui. The example compiles + links cleanly on macOS but fails on the GTK4-on-Ubuntu doc-tests CI runner with:
/usr/bin/ld: perry_llvm_*.ll:(.text+...): undefined reference to `perry_ui_widget_reorder_child'
/usr/bin/ld: perry_llvm_*.ll:(.text+...): undefined reference to `perry_ui_widget_remove_child'
/usr/bin/ld: perry_llvm_*.ll:(.text+...): undefined reference to `perry_ui_widget_add_overlay'
/usr/bin/ld: perry_llvm_*.ll:(.text+...): undefined reference to `perry_ui_widget_set_overlay_frame'
Origin/main is currently red on the gtk4 doc-tests gate because of these (and 2 SplitView FFIs + 1 folder-dialog FFI, filed separately).
What's missing
| FFI | macOS impl | GTK4 mapping |
|---|---|---|
perry_ui_widget_reorder_child |
NSView subview reordering |
Box::reorder_child_after(&child, sibling) |
perry_ui_widget_remove_child |
NSView removeFromSuperview |
Box::remove(&child) |
perry_ui_widget_add_overlay |
NSView overlay subview with frame |
Overlay::add_overlay(&child) |
perry_ui_widget_set_overlay_frame |
setFrame: on overlay subview |
GTK4 has no direct equivalent; closest is positioning via Fixed parent or absolute via set_margin_*. May require wrapping the overlay child in a Fixed container, or stub-with-state if positioning isn't representable on GTK4 |
Implementation notes
Overlay::add_overlayis the natural GTK4 primitive for the overlay pattern. Caveat: GTK4Overlayonly supports one main child + multiple overlay children — verify the macOS API's contract matches.- For
set_overlay_frame, GTK4's layout model is constraint-based, not absolute-frame. If the macOS API expects pixel-precise positioning, GTK4 may need either:- A
Fixedwrapper widget that supports absolute positioning - Stub-with-state (
SHADOW_PARAMS-style) likeperry_ui_widget_set_shadowdid on Windows in v0.5.297, with a follow-up to render properly
- A
- Reorder/remove are straightforward
Box/OverlayAPI calls.
Acceptance
- All 4 FFIs exported as
#[no_mangle] pub extern "C" fnincrates/perry-ui-gtk4/src/lib.rs. - If any of these have rows in
crates/perry-ui/src/styling_matrix.rs, flip the GTK4 cell fromMissingtoWired. Run./target/release/styling-matrix --checkclean +--gento regeneratedocs/src/ui/styling-matrix.md. -
cargo build --release -p perry-ui-gtk4succeeds. - After re-running the doc-tests harness,
docs/examples/ui/layout/snippets.tscompiles + links cleanly on Linux (assuming the SplitView FFIs from the sibling issue are also wired). - No regression on the macOS doc-tests gate.
Pointers
- macOS implementations: search
crates/perry-ui-macos/src/for eachperry_ui_widget_*symbol. - Existing GTK4 widget-tree FFIs to mirror: search
crates/perry-ui-gtk4/src/forwidget_add_child/widget_clear_children(those wire ontoBox::append/remove_all). - Failing doc-test:
docs/examples/ui/layout/snippets.ts.
Related
- I hope it is easy and convenient to modify the component's style, similar to the
styleattribute in HTML. #185 (UI cross-platform audit) - GTK4: 4 styling FFI gaps surfaced by #185 Phase B audit #202 (closed — same shape, 4 GTK4 styling FFIs)
- GTK4:
perry_ui_open_folder_dialognot wired — blocks docs/examples/ui/dialogs/snippets.ts on Linux CI #216 (sibling: GTK4 folder dialog, same doc-tests gate) - (sibling: GTK4 SplitView FFIs)
Estimated size
Medium — ~80-150 LOC. Reorder/remove are quick; the Overlay+frame pair may need 30+ LOC if a Fixed wrapper is needed for absolute-frame semantics.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew capability or improvementNew capability or improvement
Activity
fix(ui-gtk4): wire 7 missing FFIs blocking Linux doc-tests gate (v0.5…
proggeramlug commentedon Apr 27, 2026
All 4 wired in v0.5.322 (commit e58ff60). Implementations live in
crates/perry-ui-gtk4/src/widgets/mod.rsand exported fromlib.rs:widget_remove_child— dispatches by parent kind (Box::remove,ScrolledWindow::set_child(None),Overlaymain vs overlay arm,Frameinner-box). The WIDGETS vec doesn't shrink (handles are positional indices); only the GTK4 parent link is severed, mirroringremoveFromSuperview.widget_reorder_child(parent, from, to)— snapshots Box siblings viafirst_child()walk, thenBox::reorder_child_after(&child, anchor)with anchor index =towhen moving forward orto-1when moving back. Out-of-range indices clamp.widget_add_overlay— usesgtk4::Overlay::add_overlaywhen parent is an Overlay; otherwise warns + falls through toadd_child(GTK4 widgets have a single immutable parent slot — can't retroactively wrap a non-Overlay parent). Doc example updated in commit 4406f37 to wrap overlay parents in ZStack for true float semantics on every platform.widget_set_overlay_frame(handle, x, y, w, h)— approximates NSView's absolute-frame usinghalign/valign = Start+set_margin_start(x)+set_margin_top(y)+set_size_request(w, h). Works correctly when parent is a ZStack (the recommended cross-platform pattern).docs/examples/ui/layout/snippets.tsnow compiles + links + exits 0 in test mode on Linux GTK4.