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

Fix popovers one-frame-twitching in specific circumstances #6335

Merged
merged 3 commits into from
Jul 18, 2024

Conversation

bdach
Copy link
Collaborator

@bdach bdach commented Jul 17, 2024

Closes ppy/osu#28865.

The issue is caused specifically by the "arrow" part of the popover. The feedback loop involved in this is as follows:

  • A popover is added to the scene graph. The automatic anchor selection logic chooses an anchor and a position for it. For the arrow part specifically, this is compounded with a counteracting adjustment that ensures that the popover arrow continues to point at its target drawable:

    // Even if the popover was moved, the arrow should stay fixed in place and point at the target's centre.
    // In such a case, apply a counter-adjustment to the arrow position.
    // The reason why just the body isn't moved is that the popover's autosize does not play well with that
    // (setting X/Y on the body can lead BoundingBox to be larger than it actually needs to be, causing 1-frame-errors)
    currentPopover.Arrow.Position = -adjustment;

  • The base Popover class uses autosize on both axes of its BoundingBoxContainer, whose bounds are used to calculate the best anchor:

    public abstract partial class Popover : OverlayContainer

    The arrow is under the bounding box container. Adjusting a drawable's position affects autosize by way of changing
    RequiredParentSizeToFit, which means that if the drawable's target is significantly off screen, the calculated autosize of the container rapidly balloons.

  • If the popover size increases enough, then no anchors will be considered fitting (because to the automatic layouting logic, it looks like the popover won't fit in any direction). Thus, the popover's anchor is changed from whatever it was on the previous frame to Centre, and the arrow's position is reset to zero.

  • The resetting of the arrow position to zero brings us back to the situation from the first point, completing the feedback cycle.

To counteract this, exclude the popover arrow from participating in autosize calculations.

Also includes 4367d01 which fell out in testing.

Closes ppy/osu#28865.

The issue is caused specifically by the "arrow" part of the popover.
The feedback loop involved in this is as follows:

- A popover is added to the scene graph. The automatic anchor selection
  logic chooses an anchor and a position for it. For the arrow part
  specifically, this is compounded with a counteracting adjustment
  that ensures that the popover arrow continues to point at its target
  drawable:

    https://github.com/ppy/osu-framework/blob/691d8671be5f65f76b4800e85141bb6fde67e139/osu.Framework/Graphics/Cursor/PopoverContainer.cs#L143-L147

- The base `Popover` class uses autosize on both axes of its
  `BoundingBoxContainer`, whose bounds are used to calculate the best
  anchor:

    https://github.com/ppy/osu-framework/blob/691d8671be5f65f76b4800e85141bb6fde67e139/osu.Framework/Graphics/UserInterface/Popover.cs#L21

  The arrow is under the bounding box container. Adjusting a drawable's
  position affects autosize by way of changing
  `RequiredParentSizeToFit`, which means that if the drawable's target
  is significantly off screen, the calculated autosize of the container
  rapidly balloons.

- If the popover size increases enough, then no anchors will be
  considered fitting (because to the automatic layouting logic, it looks
  like the popover won't fit in *any* direction). Thus, the popover's
  anchor is changed from whatever it was on the previous frame to
  `Centre`, and the arrow's position is reset to zero.

- The resetting of the arrow position to zero brings us back to
  the situation from the first point, completing the feedback cycle.

To counteract this, exclude the popover arrow from participating in
autosize calculations.
@peppy peppy enabled auto-merge July 18, 2024 04:12
@peppy peppy disabled auto-merge July 18, 2024 04:12
@peppy peppy merged commit ff053db into ppy:master Jul 18, 2024
19 of 21 checks passed
@bdach bdach deleted the fix-popover-seizure branch July 18, 2024 05:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Editor precise Scale and Rotate tools starts blinking when hovering over right toolbox
2 participants