Skip to content

Hide FScrollPane arrow buttons when their pane stops showing - #11906

Open
leriomaggio wants to merge 4 commits into
Card-Forge:masterfrom
leriomaggio:fix/scroll-arrow-cleanup
Open

leriomaggio wants to merge 4 commits into
Card-Forge:masterfrom
leriomaggio:fix/scroll-arrow-cleanup

Conversation

@leriomaggio

Copy link
Copy Markdown
Contributor

Fixes #11901

Problem

FScrollPane's arrow buttons are not children of the pane. FAbsolutePositioner.show()
adds them to one shared panel parented to the window's JLayeredPane, positioned in
window coordinates, so they float above every screen.

They are taken off that overlay in only two ways: the paint-time recompute in
updateArrowButton, and hideArrowButtons() via FScrollPane.setVisible(false).

A pane removed from its container with removeAll(), or one whose parent is hidden, gets
neither. It stops painting, so it cannot correct itself, and its arrows stay on the overlay
over whatever is drawn next, including a different screen. FAbsolutePositioner.hideAll()
would clear them but is only called from SLayoutIO on layout load and CHomeUI.itemClick
on a left-bar submenu click, so navigation within one submenu never reaches it.

Change

  • FScrollPane registers a HierarchyListener on SHOWING_CHANGED that calls the
    existing hideArrowButtons() when the pane is no longer showing. Registered only when
    the pane actually uses arrow buttons. Nothing restores them explicitly: paint() already
    shows whichever arrow is warranted once the pane shows again.
  • FAbsolutePositioner.hide() repaints the vacated bounds. Container.remove invalidates
    but does not repaint, and that panel has a null layout, so the pixels stayed until
    something else repainted the region. Its only caller is hideArrowButtons(), so the
    paint-time path is unchanged.

Testing

Reproduced the issue from #11901, then verified with the change that leaving the lobby
clears the arrow. Also checked that arrows still appear, switch direction and disappear
normally while scrolling.

leriomaggio and others added 4 commits September 13, 2026 22:29
FScrollPane's arrow buttons are not its children. FAbsolutePositioner parks them
on one shared overlay panel above every screen, and only paint() and
setVisible(false) ever take them off it. A pane removed from its container, or
one whose parent is hidden, gets neither: it stops painting, so it cannot
correct itself, and its arrows stay on the overlay over whatever is drawn next,
including a completely different screen.

Hide them from a HierarchyListener on SHOWING_CHANGED instead, so a pane cleans
up after itself rather than every caller having to remember. Registered only
when the pane actually uses arrow buttons. Nothing restores them explicitly:
paint() already shows whichever arrow is warranted once the pane shows again.

FAbsolutePositioner.hide now repaints the vacated bounds. Container.remove
invalidates but does not repaint, and that panel has a null layout, so the
pixels stayed until something else repainted the region. Its only caller is
hideArrowButtons, so the paint-time path is unaffected.
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.

FScrollPane arrow buttons stay on screen after their pane is hidden or torn down

1 participant