Skip to content

fix(ui): every tooltip answers the pointer, through one class handler - #337

Merged
Shman4ik merged 3 commits into
mainfrom
fix/dead-tooltips
Oct 1, 2026
Merged

Shman4ik merged 3 commits into
mainfrom
fix/dead-tooltips

Conversation

@Shman4ik

@Shman4ik Shman4ik commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

What and why

#332 found that a TextBlock or panel with no Background is not hit-testable, glyphs included: 0 of 4,536 points over the status text reached the text block, so its tooltip never opened. It patched the status bar only.

A new headless walk (TooltipReachTests) hit-tests every tooltip-bearing element in every Scenarios.All window. On main it finds 203 failures, about 50 distinct elements:

  • history rows (statement and run detail) and saved-query rows
  • connection list endpoints
  • Activity and Slow Queries query text
  • Database Overview's cache-hit tiles, the Security window's "connected as"
  • raw filter chips, row details' "Reviewed before commit"
  • the schema tree's column types
  • every results-grid column header (its tip is set in code, in CreateColumnHeader)

The pointer landed on the list item, card or header border behind each one. The schema tree's function, index, role and extension rows, NotifyMonitor's error lines, the conflict dialog's cut cells and the lock icon are the same shape; the fixtures don't show them, but the fix covers them by construction.

One mechanism, not a patch per site. Nimbus.Ui.Controls.ToolTipHitTesting, installed from App.Initialize, is a class handler. Any Panel, TextBlock, Border, ContentPresenter or templated control that gets a tooltip and has no background gets Brushes.Transparent as a current value:

  • a background the markup or a style sets still wins
  • one that goes back to null (a style that stops matching) is filled again
  • disabled controls are left alone: Avalonia skips them in the hit test on purpose, and ToolTip.ShowOnDisabled is the opt-in

#332's two per-site Background="Transparent" setters are removed. TextBlock.statusMessage and CutTextTip move to nimbusUi, since nothing about them is Postgres-specific, and become DESIGN.md rule 21. CLAUDE.md records the evidence.

Paired PRs: Shman4ik/nimbusUi#6 (this subtree, plus the backlog nimbusUi had missed since 2026-09-28); Shman4ik/kubeNimbus#127 (the same handler there: 189 dead tooltips in 130 of 186 scenarios before, none after).

Verified

  • dotnet build PgNimbus.slnx -t:Rebuild, and dotnet build src/PgNimbus.App -c Release -t:Rebuild: 0 warnings (trim/AOT analyzers on)
  • PgNimbus.Core.Tests: not run; nothing in Core changed
  • PgNimbus.App.Tests: 763 total, 749 passed, 14 skipped (the ones gated on a live database)
  • TooltipReachTests goes red without the handler: 3 of 3 fail (the walk lists 203 dead elements)
  • NativeAOT publish: not run
  • Baselines: unchanged. Every scenario was rendered on main and on this branch, Windows, Release. 83 of 100 frames are byte-identical. The other 17 (security ×8, activity ×3, overview ×2, slow queries ×4) differ just as much between two renders of main, from their animated tab strips. The harness's own --baseline comparison passes.
  • Published screenshots: nothing they show changed, so not re-rendered.

Anything left unverified: hovering in the real app on Windows/macOS by hand. The test hovers a history row with real pointer input on the headless platform, and the tooltip opens.

Checklist

🤖 Generated with Claude Code

Shman4ik and others added 3 commits October 1, 2026 11:47
A TextBlock or panel with no background is not hit-testable, glyphs
included, so a tooltip on one never opens: the pointer reaches the list
item, card or column header behind it. #332 patched the status bar with two
transparent backgrounds. A walk of every scenario window found the same
defect in about 50 more places: history and saved-query rows, connection
endpoints, the Activity and Slow Queries query text, Database Overview's
cache-hit tiles, the Security window's "connected as", raw filter chips, the
schema tree's column types, and every results-grid column header.

Nimbus.Ui.Controls.ToolTipHitTesting (installed from App.Initialize) gives
any panel, text block, border, presenter or templated control that gets a
tooltip a transparent background as a current value. A background the markup
or a style sets still wins, and one that goes back to null is filled again.
Renders of every scenario are byte-identical before and after, except the
windows whose tab animation differs between any two renders.

TextBlock.statusMessage and CutTextTip move to nimbusUi too (DESIGN.md
rule 21), and the per-site backgrounds from #332 go, so the handler is the
only mechanism.

TooltipReachTests walks every window in Scenarios.All and hit-tests each
tooltip-bearing element's text (203 failures without the handler), hovers a
history row for real, and pins the handler's priority.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kubeNimbus's wide and narrow grids put probe points inside the window but
outside a scroll viewport, which read as dead tooltips. Same probe in both
apps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Shman4ik
Shman4ik merged commit 4e1f952 into main Oct 1, 2026
2 checks passed
@Shman4ik
Shman4ik deleted the fix/dead-tooltips branch October 1, 2026 10:24
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.

1 participant