Skip to content

Fixes #5635. Hide active popover on DeRegister to clear stale cells - #5657

Merged
tig merged 5 commits into
developfrom
cursor/dropdown-stale-popover-enter-f842
Sep 3, 2026
Merged

Fixes #5635. Hide active popover on DeRegister to clear stale cells#5657
tig merged 5 commits into
developfrom
cursor/dropdown-stale-popover-enter-f842

Conversation

@tig

@tig tig commented Sep 3, 2026

Copy link
Copy Markdown
Member

Fixes

Summary

A read-only DropDownList left the dropped list's text on screen after Enter when Accepting was handled and focus moved. Selection and focus were correct. The popover was no longer active. The cells it covered were not repainted. Mouse accept already repainted.

The keyboard path lost focus and called DeRegister while the popover was still the active one. DeRegister cleared _activePopover without Hide. Hide is the method that calls TopRunnableView.SetNeedsDraw(). A later Visible=false Hide then no-oped because the popover was no longer active.

I hide the active popover so the covered region is invalidated. I unregister it first so a VisibleChanged handler cannot call Show during Hide and leave the popover visible, active, or registered.

Changes

  • ApplicationPopover.DeRegister removes the popover from the registry, then hides it if it was active.
  • After Hide, it clears a restored active pointer and removes again if MakeVisible re-registered.
  • DropDownList.OnHasFocusChanging hides the list popover before DeRegister on focus loss.

Testing

I wrote tests that fail on develop and pass with this change.

  • DeRegister_ActivePopover_HidesAndInvalidatesTopRunnable asserts Hide and NeedsDraw.
  • DeRegister_VisibleChangedShow_LeavesUnregisteredInactiveAndHidden failed on fa930207 because Hide still saw the popover as registered. After unregister-before-Hide it passes: not registered, not active, not visible.
  • Enter_HandledAccepting_DoesNotLeaveStalePopoverCells is the issue repro.
  • MouseAccept_HandledAccepting_DoesNotLeaveStalePopoverCells keeps the mouse path honest.

CI follow-up

macOS Integration Tests failed on WithListView_NavigatesItems (dotnet driver) at SHA 766b96f00. That test is ListView cursor navigation. It is not a DropDownList or popover test.

The NRE was in AppTestHelper.WaitIteration during Stop/Dispose. CleanupApplication can already have nulled ExternalCancellationTokenSource while Stop still calls WaitIteration. WaitIteration used ! on that source.

This is a helper shutdown race. It is not caused by the DeRegister change. I did not Ignore the integration test.

I capture the CTS, treat a null or cancelled source as already stopped, and set Finished before clearing the source.

WaitIteration_WhenExternalCancellationTokenSourceIsNull_DoesNotThrow failed on the old ! dereference and passes after the harden.

CI is green on 16d45a112, including Integration Tests on macOS, Ubuntu, and Windows.

Pull Request checklist:

  • I've named my PR in the form of "Fixes #issue. Terse description."
  • My code follows the style guidelines of Terminal.Gui
  • My code follows the Terminal.Gui library design guidelines
  • I ran dotnet test before commit
  • I have made corresponding changes to the API documentation (using /// style comments)
  • My changes generate no new warnings
  • I have checked my code and corrected any poor grammar or misspellings
  • I conducted basic QA to assure all features are working

To pull down this PR locally:

git fetch origin cursor/dropdown-stale-popover-enter-f842
git checkout cursor/dropdown-stale-popover-enter-f842
Open in Web Open in Cursor 

cursoragent and others added 2 commits September 3, 2026 12:32
DeRegister cleared the active popover without Hide, so SetNeedsDraw
never ran. Keyboard Enter with a handled Accepting handler that moved
focus took that path and left the dropped list's cells behind.

Co-authored-by: Tig <tig@users.noreply.github.com>
The buffer-only check still passed without the fix because a later
draw could hide the stale cells. Assert NeedsDraw on the dialog and
the covered label immediately after Enter.

Co-authored-by: Tig <tig@users.noreply.github.com>
@tig
tig marked this pull request as ready for review September 3, 2026 12:39
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-03T12:43:51.988984Z a7465b0 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@tig

tig commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

Reviewed the production diff: Hide-before-unregister in ApplicationPopover.DeRegister is the right semantic, and the DropDownList OnHasFocusChanging Hide is a cheap extra for the keyboard Accepting+Handled path. Tests asserting NeedsDraw immediately after Enter (not just the later buffer) are the right proof.

Waiting on remaining Windows/macOS checks. Do not merge until those are green.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a7465b0bd3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Terminal.Gui/App/ApplicationPopover.cs
cursoragent and others added 3 commits September 3, 2026 12:46
Hide raises VisibleChanged. A handler can call Show and restore
_activePopover before DeRegister returns. Clear that pointer after
unregistering so the popover cannot stay active and unregistered.

Co-authored-by: Tig <tig@users.noreply.github.com>
A VisibleChanged handler could call Show during Hide while the popover
was still registered, leaving it visible. The new test failed on that
order. DeRegister now removes from the registry first, then Hide, so
Show cannot run. SetNeedsDraw still happens for #5635.

Co-authored-by: Tig <tig@users.noreply.github.com>
WaitIteration used ExternalCancellationTokenSource! during Stop/Dispose.
CleanupApplication can already have nulled that source, which produced the
macOS IntegrationTests NRE on WithListView_NavigatesItems.

Co-authored-by: Tig <tig@users.noreply.github.com>
@tig
tig merged commit b2b26ae into develop Sep 3, 2026
14 checks passed
@tig
tig deleted the cursor/dropdown-stale-popover-enter-f842 branch September 3, 2026 18:53
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.

DropDownList leaves stale popover contents after handled Enter

2 participants