Conversation
…PerryTS#10167) A responsive centered column could not be built. widgetSetWidth pins an exact width and widgetMatchParentWidth fills the parent, so neither grows to a cap then stops. widgetSetMaxWidth is the CSS max-width plus margin:auto behaviour. It fills the parent below the cap, then stops and centers at or above it. The method lowers through PERRY_UI_TABLE as perry_ui_widget_set_max_width. Constraint backends get the real three-constraint layout. Android fills and centers without the hard cap. watchOS is a no-op. Web maps to CSS max-width. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126quMdA2DoCLU5EokB54rp
…S#10167) Running each backend showed three that recorded the cap but never enforced it. GTK4 used size_request as a minimum and filled; Android forced MATCH_PARENT and ignored the value; web set max-width but the block shrank to its content instead of filling up to the cap. watchOS was a plain no-op. GTK4 now wraps the child in a MaxWidthBin widget whose measure and allocate cap and center it. Android wraps the child in a PerryMaxWidthLayout whose onMeasure clamps and centers. web adds width:100% so the element fills up to the cap. watchOS stores a frame_max_width the SwiftUI host reads for .frame(maxWidth:, alignment: .center). Adds a runnable doc-example, ui/layout/max_width_centered.ts, that the iOS simulator harness runs. Verified: macOS pixel-measured, iOS run on a real simulator, web measured in a browser, the GTK4 bin proven with a standalone GTK4 program. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126quMdA2DoCLU5EokB54rp
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The fragment was named after the issue while the PR number was unknown; the changelog.d convention keys the filename on the PR number. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0126quMdA2DoCLU5EokB54rp
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.
Problem
There is no way to give a widget a max-width.
widgetSetWidthpins an exact width andwidgetMatchParentWidthfills the parent, so a responsive centered content column — grow with the parent up to a cap, then stop and center — cannot be built (#10167).Solution
Add
widgetSetMaxWidth(widget, maxWidth): the CSSmax-width+margin: autobehaviour. Below the cap the widget fills the available width; at and abovemaxWidthit stops at the cap and centers, so the side gutters grow with the window.This PR
Wires
widgetSetMaxWidthend to end on every UI backend, plus theperry-solidmaxWidthprop, docs, and a runnable doc-example.Changes
MethodRowinPERRY_UI_TABLE(widgetSetMaxWidth→perry_ui_widget_set_max_width,[Widget, F64]) and thetypes/perry/ui/index.d.tsdeclaration. The LLVM backend lowers it generically; JS/WASM codegen resolve it through the existingui_method_to_runtimefall-through, so no per-backend codegen change.width <= maxWidth(required),width == superview.widthat priority 999 (grow to fill until the cap binds),centerX == superview.centerX. Idempotent.MaxWidthBinwidget subclass (GTK4 has no max-width property) whosemeasure/size_allocatecap the child and center it; the child is re-parented through the bin.max_widthfield honoured at Win32 layout time (clamp + center); WinUI usesMaxWidth+HorizontalAlignment::Stretch.PerryMaxWidthLayout(FrameLayoutwhoseonMeasureclamps and centers);widgetSetMaxWidthre-parents the child through it via JNI..frame(maxWidth:, alignment: .center)from a newframe_max_widthintrospection field.width: 100%+max-width+margin: auto..width('100%').constraintSize({ maxWidth }).alignSelf(ItemAlign.Center).maxWidthprop in theperry-solidrenderer, a styling-page section, anddocs/examples/ui/layout/max_width_centered.ts(run by the iOS simulator harness).Verification
Every backend was pushed to a real run where the environment allows it. Writing each one and then running it caught three backends that recorded the cap but never enforced it (GTK4, Android, web) — each is fixed here.
Run-verified:
--target ios-simulator, ran on a real iPhone 17 simulator--target web, measured the DOM in a browserMaxWidthBinmeasure/allocate reproduced in a standalone GTK4 programVerified by build only, with the reason a run was not possible in the authoring environment (a macOS host):
windows-buildcompiles both crates onwindows-latestwidget_set_max_width_emits_constraint_size_and_center)Not verifiable in this environment — the honest limits:
perry-ui-gtk4is#![cfg(target_os = "linux")], so it does not compile on the macOS host, and no CI job builds it. The layout mechanism is pixel-proven standalone (above); the integration rests on that plus review.cargo checkneeds the Android NDK (acc-rsbuild script), the KotlinPerryMaxWidthLayoutis compiled by no CI job, the CI cross-build is non-fatal, and there is no emulator. It rests on review and a real Android build.