Fix Container clipBehavior not clipping decoration painting#184561
Fix Container clipBehavior not clipping decoration painting#184561ishaquehassan wants to merge 12 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request modifies the Container widget to ensure that its decoration is clipped when clipBehavior is set. This is achieved by reordering the widget composition so that DecoratedBox is a child of ClipPath. Corresponding tests, including a golden test and a widget hierarchy check, have been added to verify this behavior. I have no feedback to provide.
victorsanni
left a comment
There was a problem hiding this comment.
This is basically a revert of #64362, is this intended?
Split BoxDecoration with shadows into two DecoratedBoxes when clipBehavior is set: shadow paints outside the clip, background and content paint inside. Fix typo clipBehaviour to clipBehavior in test names and golden file names.
|
Good catch on #64362! The initial commit was indeed a straight revert of that fix. Updated the approach in the latest commit to preserve shadow visibility while properly clipping the decoration background. When clipBehavior is set and the decoration is a BoxDecoration with shadows, the decoration is now split into two DecoratedBoxes:
For decorations without shadows, ClipPath simply wraps the single DecoratedBox. Also fixed the typo in test names and golden file names (clipBehaviour -> clipBehavior). |
Piinks
left a comment
There was a problem hiding this comment.
Thank you for contributing a solution. While this approach addresses the immediate issue of BoxDecoration shadows being clipped, it introduces several long-term maintenance and architectural concerns for the framework.
Specifically, the current implementation manually destructures and restructures BoxDecoration properties inside Container.build. This manual mapping is strictly limited to BoxDecoration and creates a maintenance risk; any future properties added to the BoxDecoration class would also need to be manually updated here to ensure they aren't lost during the split. Furthermore, this approach does not provide a fix for other common decorations, such as ShapeDecoration or custom subclasses.
A more robust and scalable solution would be to implement clipBehavior support directly within DecoratedBox and its corresponding RenderDecoratedBox. This would provide a first-class mechanism for clipping backgrounds while naturally allowing external effects like shadows to remain visible, benefiting all decoration types across the entire framework rather than just those inside a Container.
Given these concerns, I suggest we close this PR and move the technical discussion to issue #154780, which tracks the addition of clipBehavior to DecoratedBox. This will ensure we land a sustainable, framework-wide solution that maintains the integrity of the Container composition logic.
Description
Container'sclipBehaviorproperty was not clipping the decoration painting becauseClipPathwas placed as a child ofDecoratedBoxin the widget tree. This meant only the child content was clipped, while the decoration itself (background color, gradient, border, shadow) was painted outside the clip boundary.This caused visible artifacts when a
Containerwith a roundedBoxDecorationandclipBehaviorset was placed inside a parent with a solid background color: the parent's color would show through at the corners of the rounded decoration, andclipBehaviorhad no effect on the decoration's visual output.Before (broken):
After (fixed):
This fix swaps the order of
ClipPathandDecoratedBoxinContainer.build()so thatClipPathwrapsDecoratedBox, ensuring the clip applies to the entire visual output of the container (decoration + child content).Shadow behavior change
Previously,
boxShadowwas not clipped becauseDecoratedBoxpainted it outside theClipPath. With this fix, shadows are now also clipped to the decoration shape whenclipBehavioris set. This is the correct behavior because:clipBehaviordefaults toClip.none, so shadows are unaffected unless the developer explicitly opts into clippingclipBehaviorexpect the container's visual bounds to be constrained to the decoration shapeClipRRectandClipPathwork when wrapping decorated contentThe shadow golden test has been updated to reflect this corrected behavior.
Fixes #85268
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.