Skip to content
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

Prevent selection repaint in the middle of multicolumn flow destruction #28678

Merged
merged 1 commit into from
May 17, 2024

Conversation

robert-jenner
Copy link
Contributor

@robert-jenner robert-jenner commented May 16, 2024

54cc63f

Prevent selection repaint in the middle of multicolumn flow destruction
https://bugs.webkit.org/show_bug.cgi?id=263180
rdar://128090627

Reviewed by Alan Baradlay.

During multicolumn fragmented flow destruction, spanners are moved back
to their original DOM position in the tree. This is done through calls
to RenderTreeBuilderBlock::Block::detach(RenderBlockFlow&), which also
calls the more general RenderBlock ::detach() method for each spanner.
The former method results in the destruction of the spanner placeholders
and the merging of the necessary multicolumn sets, but this is not done
immediately, so the tree is temporarily inconsistent, before the
RenderBlock detach() method is called.

RenderTreeBuilderBlock::Block::detach(RenderBlock&), however,
might inadvertely end up triggering a repaint of the selection that the
tree is not ready for. I assume that this is an oversight from the possibility
that this method gets called during RenderBlockFlow detachment. This repaint
happens because RenderTreeBuilder::detachFromRenderElement() clears the
selection if the child being detached is to be destroyed. As
WillBeDestroyed::Yes is the default value in the definition of
detachFromRenderElement(), this is assumed to be the case, even when
that's not what happens during fragmented flow destruction.

The problem with this is that the selection repaint will eventually find itself
needing a consistent tree, and the fact that multicolumn sets are not merged
yet and there are spanners without a placehoder will break assumptions made
in RenderObject::propagateRepaintToParentWithOutlineAutoIfNeeded().

Fix this by making it possible for both detach() methods to propagate
WillBeDestroyed, with a default value of WillBeDestroyed::Yes to preserve
current behavior everywhere, but explicitly passing WillBeDestroyed::No
during fragmented flow destruction when detaching spanners, as this is what
is actually happening. This prevents the selection repaint from happening
before the tree is in a consistent state.

* LayoutTests/fast/block/multicolumn-with-outline-auto-expected.txt: Added.
* LayoutTests/fast/block/multicolumn-with-outline-auto.html: Added.

Originally-landed-as: 274097.6@webkit-2024.2-embargoed (00414cbd744c). rdar://128090627
Canonical link: https://commits.webkit.org/278918@main

4a4cd83

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ§ͺ api-wpe
βœ… πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 ⏳ πŸ›  wpe-skia
βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 βœ… πŸ›  gtk
βœ… πŸ›  tv βœ… πŸ§ͺ mac-AS-debug-wk2 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2-stress βœ… πŸ§ͺ api-gtk
βœ… πŸ›  watch
βœ… πŸ›  πŸ§ͺ unsafe-merge βœ… πŸ›  watch-sim

@robert-jenner robert-jenner self-assigned this May 16, 2024
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 16, 2024
@robert-jenner robert-jenner removed the merging-blocked Applied to prevent a change from being merged label May 17, 2024
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 17, 2024
@robert-jenner robert-jenner removed the merging-blocked Applied to prevent a change from being merged label May 17, 2024
@robert-jenner robert-jenner added the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label May 17, 2024
https://bugs.webkit.org/show_bug.cgi?id=263180
rdar://128090627

Reviewed by Alan Baradlay.

During multicolumn fragmented flow destruction, spanners are moved back
to their original DOM position in the tree. This is done through calls
to RenderTreeBuilderBlock::Block::detach(RenderBlockFlow&), which also
calls the more general RenderBlock ::detach() method for each spanner.
The former method results in the destruction of the spanner placeholders
and the merging of the necessary multicolumn sets, but this is not done
immediately, so the tree is temporarily inconsistent, before the
RenderBlock detach() method is called.

RenderTreeBuilderBlock::Block::detach(RenderBlock&), however,
might inadvertely end up triggering a repaint of the selection that the
tree is not ready for. I assume that this is an oversight from the possibility
that this method gets called during RenderBlockFlow detachment. This repaint
happens because RenderTreeBuilder::detachFromRenderElement() clears the
selection if the child being detached is to be destroyed. As
WillBeDestroyed::Yes is the default value in the definition of
detachFromRenderElement(), this is assumed to be the case, even when
that's not what happens during fragmented flow destruction.

The problem with this is that the selection repaint will eventually find itself
needing a consistent tree, and the fact that multicolumn sets are not merged
yet and there are spanners without a placehoder will break assumptions made
in RenderObject::propagateRepaintToParentWithOutlineAutoIfNeeded().

Fix this by making it possible for both detach() methods to propagate
WillBeDestroyed, with a default value of WillBeDestroyed::Yes to preserve
current behavior everywhere, but explicitly passing WillBeDestroyed::No
during fragmented flow destruction when detaching spanners, as this is what
is actually happening. This prevents the selection repaint from happening
before the tree is in a consistent state.

* LayoutTests/fast/block/multicolumn-with-outline-auto-expected.txt: Added.
* LayoutTests/fast/block/multicolumn-with-outline-auto.html: Added.

Originally-landed-as: 274097.6@webkit-2024.2-embargoed (00414cb). rdar://128090627
Canonical link: https://commits.webkit.org/278918@main
@webkit-commit-queue
Copy link
Collaborator

Committed 278918@main (54cc63f): https://commits.webkit.org/278918@main

Reviewed commits have been landed. Closing PR #28678 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit 54cc63f into WebKit:main May 17, 2024
@webkit-commit-queue webkit-commit-queue removed the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants