Skip to content

Point Dialog::important_area at the focused button - #884

Merged
gyscos merged 1 commit into
gyscos:mainfrom
hdimer:fix-dialog-important-area-button
Sep 9, 2026
Merged

gyscos merged 1 commit into
gyscos:mainfrom
hdimer:fix-dialog-important-area-button

Conversation

@hdimer

@hdimer hdimer commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #813.

Dialog::important_area() always returned the content's area, even when a button
had focus - there was a // TODO: if a button is focused, return the button position instead. sitting on that line. So a ScrollView wrapping a tall
Dialog scrolled to the content and stopped, and the buttons below stayed
unreachable once focus moved to them.

Now it matches on self.focus: content focus keeps the existing calculation,
button focus asks the focused button for its important area and translates it by
the offset the button already records. That is the same shape FixedLayout,
LinearLayout and ListView use for their focused child.

The test lays out and draws a 20x5 dialog with two buttons and asserts the
important area for all three focus states. Coordinates are hardcoded rather than
derived from offset/size, so it cannot just restate the implementation - I
checked it fails on master and on the plausible wrong versions (hardcoded button
index; adding borders + padding to the button arm by symmetry with the content
arm).

Two things worth flagging:

  • Button offsets are written in draw_buttons(), not in layout(), so before
    the first draw they are still zero. In practice focus only reaches a button
    after an event, and run() refreshes before the first step(), so the offsets
    are current by then; the degenerate case is a scroll to the top for one frame,
    not a panic. It is the same contract check_focus_grab() already relies on for
    mouse hit-testing. Moving the button positioning into layout() would remove
    the hazard, but it duplicates the alignment math and felt like more than this
    fix needed - say the word if you would prefer it.
  • This only covers the buttons half of your comment on [BUG] ScrollView on LinearLayout with Dialog doesn't scroll properly #813. The border is still
    excluded from the important area, which is consistent with the content arm but
    means the bottom border row can stay clipped. Happy to include it if that is
    what you want.

cargo fmt, clippy and the full test suite are clean. Two files, theme.rs
and backends/curses/n.rs, are already rustfmt-dirty on master; I left those
alone.

Written with AI assistance; I reproduced the bug, verified the fix and ran the
tests myself.

Dialog::important_area always returned the content's area, so a ScrollView
wrapping a tall Dialog never scrolled far enough to reveal the buttons once
focus moved to them.

Match on the focus instead: content focus keeps the existing calculation,
button focus delegates to the focused button and translates by its recorded
offset, the same shape FixedLayout and LinearLayout use.

Fixes gyscos#813
@gyscos

gyscos commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Hi, and thanks for the work! Looks good!

@gyscos
gyscos marked this pull request as ready for review September 9, 2026 14:00
@gyscos
gyscos merged commit 4ea34f4 into gyscos:main Sep 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] ScrollView on LinearLayout with Dialog doesn't scroll properly

2 participants