-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement paint and accessibility passes #522
Conversation
(This is very much a draft, more so than usual. |
df31c3e
to
ca13a0d
Compare
8481254
to
cbb10c0
Compare
I think this is ready for review now. I left some things for later (notably removing I don't intend to add a default implementation for paint and accessibility, because I think widgets that don't need to do anything with them will be rare (even eg Flex will get properties like a background color); for accessibility in particular, I think we should encourage people to look at accessibility tree values before decide they don't need any, and having a default impl goes against that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I just have one minor comment.
self.widget_state.request_accessibility = true; | ||
self.widget_state.needs_accessibility = true; | ||
self.widget_state.needs_paint = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen this repeated at least three times. It may make sense to create a function just for marking the state change for needing paint and accessibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to keep these kinds of refactor for last, especially if we're only factoring three lines or less. I think there's a benefit to being able to see directly what the code does instead of jumping to another function.
@@ -165,7 +165,7 @@ pub fn root_on_text_event( | |||
handled | |||
} | |||
|
|||
pub fn root_on_access_event( | |||
pub(crate) fn root_on_access_event( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Had commented directly on the commit, but then that doesn't show up here ...)
I use this in my own event loop integration. I need some way to pump an access event into the system ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake. I'm calling this on RenderRoot
, not this one here.
First thought when reviewing. The only thing which renders in |
This is also the case on main. Bisecting to find the culprit... |
Apparently #527 introduced the regression. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really good! I don't have any blocking concerns, but there are a few bits of clarification I'd like to see.
state.item.request_accessibility = false; | ||
state.item.needs_accessibility = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose that since AccessCtx
doesn't have these methods, it doesn't matter when these values are set, so long as it's after they are read?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that by "these methods" you mean "the methods that gave me problems in the layout PR"?
To be honest, I haven't decided on (or documented) a principled solution for that class of problem. I'm mostly deferring it until all passes are implemented.
But yeah, your reasoning makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, I meant request_accessibility
. I hadn't checked if get_raw_mut
were available in AccessCtx
// This may have knock-on effects we'd need to document. | ||
if state.item.is_stashed { | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | |
} | |
// TODO: If child is completely outside of parent's clip path, don't paint it | |
// The naïve solution breaks if the widget overflows its layout box; ideally, widgets | |
// wouldn't do that, but they are currently allowed to do so. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also the fact that, if we adopt compositor layers, then you'll want to display some offscreen stuff so you don't get caught flatfooted when the user scrolls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a comment here.
masonry/src/passes/paint.rs
Outdated
widget_state: state.item, | ||
widget_state_children: state.children.reborrow_mut(), | ||
widget_children: widget.children.reborrow_mut(), | ||
depth, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is depth
expected to be used for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it was used in Druid for z-order stuff? I guess it's obsolete now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed it.
masonry/src/widget/widget_arena.rs
Outdated
@@ -87,6 +93,20 @@ impl WidgetArena { | |||
.expect("get_state_mut: widget state not in widget tree") | |||
} | |||
|
|||
#[track_caller] | |||
pub(crate) fn get_scene(&mut self, widget_id: WidgetId) -> &Scene { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These methods are never used...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed them.
@@ -65,7 +65,9 @@ pub struct WidgetState { | |||
// TODO - Document | |||
pub(crate) is_portal: bool, | |||
|
|||
pub(crate) request_compose: bool, | |||
// TODO - Use general Shape |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// TODO - Use general Shape | |
// The clip is a rectangle to maintain compatibility with system compositor APIs, which only know about rectangles. | |
// Note that we don't currently integrate with the system compositor. | |
// A future extension to use an arbitrary shape may be possible if there is a significant need for it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather support arbitrary shapes. Or at the very least, rectangles with rounded corners. The reason I'm doing rectangles only is that Kurbo doesn't provide you with a type to store an arbitrary shape.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right - I guess a solution for rounded rectangles and similar is to draw the parent surface "above" the child surfaces, and have a transparent cutout for the composited view. If compositors can implement that performantly, that would work well
My mistake, I think arbitrary paths are probably fine then, although it probably requires some careful use of blend modes to punch through a transparent region.
masonry/src/widget/widget_arena.rs
Outdated
pub(crate) widget_states: TreeArena<WidgetState>, | ||
pub(crate) scenes: HashMap<WidgetId, Scene>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not obvious why this isn't a field on the WidgetState
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are cases where you want to separately borrow both.
Wait, no. I think it's because Scene doesn't implement Debug and I didn't want to manually implement it in WidgetState.
masonry/src/widget/widget_arena.rs
Outdated
pub(crate) widget_states: TreeArena<WidgetState>, | ||
pub(crate) scenes: HashMap<WidgetId, Scene>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these ever get cleaned up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
I think I've addressed all review comments. This is a big one, so I'll wait until tomorrow to merge it, in case there's any concerns left. |
e248536
to
def14c0
Compare
Fix stashed child handling. Handle scrolling in compose pass. Fix set_child_translation method.
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
def14c0
to
61cfb07
Compare
Recursing is done inside the paint and accessibility passes since ff7635e. I believe this is the correct continuation of #522, with the removal of these methods "left for later" as mentioned in #522 (comment). One note is that Flex now debug-paints its baseline under its children, rather than over them.
No description provided.