Skip to content

fix(core): getTooltip disappears when autoHighlight: true and interleaved: true in MapboxOverlay (deck.gl)#9889

Merged
felixpalmer merged 4 commits intovisgl:masterfrom
Spacerat:joe/tooltip-hover-fix
Dec 5, 2025
Merged

fix(core): getTooltip disappears when autoHighlight: true and interleaved: true in MapboxOverlay (deck.gl)#9889
felixpalmer merged 4 commits intovisgl:masterfrom
Spacerat:joe/tooltip-hover-fix

Conversation

@Spacerat
Copy link
Contributor

@Spacerat Spacerat commented Dec 2, 2025

Closes #9599

Background

This PR seems to fix the issue in #9599 where tooltips disappear when autoHighlight is set in interleaved mode with MapBox.

I am going to be honest, I produced this with heavy Claude Code collaboration - I can't really claim to understand deeply what's going on here.

That being said, I did a decent amount of testing, by tweaking the getting-started/mapbox example and running it locally against these changes.

I also checked whether both pieces of the solution seem to be essential to it, and they are. Take out the .equals change, or the lastViewport source change, and the fix stops working.

Testing

With a tooltip added:

  • Before fix:
    • Enable interleaved and autoHighlight: tooltip disappears
    • Enable just one of them: bug does not occur
  • After fix:
    • Bug never shows up

I also tested the "radio" example, since it seemed like the one place where it might matter where onHover gets its viewport from. It worked before and after the fix.

I also tried flinging the camera and then keeping the cursor still so that an object moves under it. That is now also improved, but still not perfect.

  • Before the fix: after the viewport moves cursor over the highlighted object, the tooltip doesn't appear and doesn't appear even if I move the cursor around over it
  • After the fix: after the viewport moves the cursor over the highlighted object, the tooltip doesn't appear, but it does after I move the cursor around over it

Claude Code also wrote a test. It fails without the fix, and passes with it. This is the failure without the fix:

  TooltipWidget#onViewportChange

    ✖ lastViewport is set
    ✖ lastViewport is updated
    ✖ Tooltip is hidden when camera moves

Claude Code's explanation

Here's an explanation I managed to wrangle from Claude Code. Take it with a grain of salt, of course.

Claude Code summary

Fixes tooltip disappearing immediately when cursor stops moving with autoHighlight: true and interleaved: true in MapboxOverlay.

Root cause: When autoHighlight is enabled, hovering triggers layer.setNeedsRedraw() (layer.ts:1240) to render the highlight effect. This redraw calls onViewportChange with a viewport from the render loop (widget-manager.ts:100-110). The problem is that onHover had previously stored info.viewport (from picking) as lastViewport. These are different object instances even though the camera hasn't moved, causing the condition viewport !== this.lastViewport to be true and incorrectly clearing the tooltip.

Why interleaved mode: In interleaved mode, deck.gl hooks into the base map's render loop via map.on('render', ...) (deck-utils.ts:97-99). Each render cycle calls afterRender, which calls deck._drawLayers and creates a fresh viewport via view.makeViewport() (deck-utils.ts:327). This new viewport instance triggers onViewportChange immediately after autoHighlight's redraw, causing the mismatch with the picking viewport stored in lastViewport.

Why viewports differ: Picking retrieves viewports from viewManager.getViewports() (deck.ts:737), which returns cached viewport instances. However, the render loop (especially in interleaved mode) creates new viewport objects via view.makeViewport() (view-manager.ts:361). Even with identical camera parameters, these are different object instances, so viewport !== this.lastViewport evaluates to true.

Why autoHighlight: Without autoHighlight, hover events don't trigger redraws. The tooltip appears and stays visible because onViewportChange is only called when the camera actually moves. With autoHighlight, every hover that changes the highlighted object forces a redraw via _updateAutoHighlight (layer.ts:1228-1241), which immediately triggers the false "camera moved" detection.

The fix: Always update lastViewport from the render loop in onViewportChange, and remove the viewport assignment from onHover. This ensures viewport comparisons use a consistent source, correctly detecting only actual camera movement.

Change List

  • tooltip-widget.ts updated to use onViewportChange as its source of lastViewport instead of onHover.

@Spacerat Spacerat changed the title Joe/tooltip hover fix Fix tooltip hover with interleaved and autoHighlight Dec 2, 2025
@Spacerat Spacerat changed the title Fix tooltip hover with interleaved and autoHighlight fix(core): Ensure tooltip doesn't disappear with interleaved and autoHighlight on Dec 2, 2025
@Spacerat Spacerat changed the title fix(core): Ensure tooltip doesn't disappear with interleaved and autoHighlight on fix(core): getTooltip disappears when autoHighlight: true and interleaved: true in MapboxOverlay (deck.gl) Dec 2, 2025
@coveralls
Copy link

coveralls commented Dec 3, 2025

Coverage Status

coverage: 91.147% (+0.01%) from 91.136%
when pulling 0a5aad5 on Spacerat:joe/tooltip-hover-fix
into e716a4c on visgl:master.

Copy link
Collaborator

@felixpalmer felixpalmer left a comment

Choose a reason for hiding this comment

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

Thanks. Tested and the behavior is much better!

@felixpalmer felixpalmer merged commit 8403594 into visgl:master Dec 5, 2025
3 checks passed
felixpalmer pushed a commit that referenced this pull request Dec 8, 2025
@chrisgervang chrisgervang added this to the v9.2 patch releases milestone Feb 3, 2026
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] getTooltip disappears when autoHighlight: true and interleaved: true in MapboxOverlay (deck.gl)

4 participants