Opened 6 hours ago

Last modified 4 hours ago

#19249 new bug

Invalidating a view doesn't invalidate its children

Reported by: jackburton Owned by: axeld
Priority: normal Milestone: Unscheduled
Component: Servers/app_server Version: R1/beta5
Keywords: Cc:
Blocked By: Blocking:
Platform: All

Description

Maybe I understood it wrong, but I thought that Invalidating a view would also invalidate its children. About Invalidate(), the bebook says:

"Invalidates the rect portion of the view, causing update messages—and consequently Draw() notifications—to be generated for the BView and all descendants that lie wholly or partially within the rectangle. The rectangle is stated in the BView's coordinate system. "

Here's a test case to show it doesn't. Attached is also a clip of how the test case result should look.

Note that adding B_DRAW_ON_CHILDREN to the view flag "fixes" the issue, but it doesn't feel correct, since the views don't need to draw on their children.

Attachments (2)

BViewInvalidate.zip (5.5 KB ) - added by jackburton 6 hours ago.
Test case
clip.mpg (50.0 KB ) - added by jackburton 6 hours ago.
clip

Download all attachments as: .zip

Change History (7)

by jackburton, 6 hours ago

Attachment: BViewInvalidate.zip added

Test case

by jackburton, 6 hours ago

Attachment: clip.mpg added

clip

comment:1 by X512, 5 hours ago

It is expected behavior. Child views are excluded from current view invalidation region if B_TRANSPARENT_BACKGROUND flag is not specified for child views. Invalidation should cause no effect to child view without B_TRANSPARENT_BACKGROUND because it will overwrite all parent view contents.

comment:2 by jackburton, 5 hours ago

Makes sense in some way, but what if the parent view is just a "container" ? Should I use B_TRANSPARENT_BACKGROUND then ?

comment:3 by X512, 5 hours ago

Makes sense in some way, but what if the parent view is just a "container" ?

What are you trying to achieve? What is a problem with calling Invalidate to child views?

Invalidate() call it intended to mark specific view contents that do not match view state and should be repainted later. Calling Invalidate() on a view that is not changed to repaint child views is an API misuse.

comment:4 by jackburton, 4 hours ago

In my case (not the test case), I created a custom BView which, beside doing other things, contains a BOutlineListView (with layout, of course), let's call it ContainerView. Users of ContainerView don't need to know about the inner BOutlineListView, so if they want to trigger invalidation for some reason, they call the ContainerView::Invalidate(). When ContainerView is invalidated it needs to trigger invalidation also for the inner BOutlineView.

comment:5 by X512, 4 hours ago

so if they want to trigger invalidation for some reason, they call the ContainerView::Invalidate().

Invalidate() usually shouldn't be called by client. BView itself should call it according to its state changes.

Note: See TracTickets for help on using tickets.