Skip to content

Fix dock hover animation on monitors with a non-zero offset - #355

Open
benny-png wants to merge 1 commit into
icedman:mainfrom
benny-png:fix-multimonitor-strut-offset
Open

Fix dock hover animation on monitors with a non-zero offset#355
benny-png wants to merge 1 commit into
icedman:mainfrom
benny-png:fix-multimonitor-strut-offset

Conversation

@benny-png

Copy link
Copy Markdown

Symptom

With more than one monitor connected, icon magnification never triggers — hovering the dock does nothing. The dock renders and its icons stay clickable; only the animation is dead. Everything works again as soon as the setup is back to a single monitor.

This only reproduces when autohide is disabled.

Root cause

In animator.js, dock.struts.x is assigned only inside the autohide_dash branch:

if (dock.extension.autohide_dash) {
  dock.struts.x = dock._background.x + dock._monitor.x;
  dock.struts.width = dock._background.width;
}

// dock.struts.x = dock.x;      <-- commented out

With autohide off, that branch never runs and the line that would set it is commented out, so struts.x keeps its default of 0.

_isWithinDash() (dock.js) hit-tests the pointer against exactly that rect:

let xy = this.struts.get_transformed_position();
let wh = [this.struts.width, this.struts.height];
if (isInRect([xy[0], xy[1], wh[0], wh[1]], p, 20)) { ... }

and Animator.animate() gates all magnification on its result:

let isWithin = dock._isWithinDash([px, py]);
let animated = isWithin;

So on a layout where the dock's monitor has a non-zero x offset, the strut rect sits over a different monitor than the one the dock is drawn on. The pointer is never inside it, animated stays false, and no icon ever scales.

On a single monitor the offset is 0, which is why the missing assignment is invisible there.

The vertical branch has the same problem for y (// dock.struts.y = dock.y;, same file), so a left/right dock on a monitor with a non-zero y offset should fail the same way.

Fix

Assign the strut origin in the non-autohide case, as an else on the existing branch so the autohide values are not overwritten. Both orientations changed for symmetry.

Because the new code lives in an else of if (dock.extension.autohide_dash), this is a no-op when autohide is enabled.

Verification

Ubuntu, GNOME Shell 46.0, X11, dock at bottom, autohide disabled, dodge enabled. Two 1920x1080 monitors, the dock's monitor being the primary at offset +1920+413:

  • Before: hovering dock icons produced no magnification at all.
  • After: magnification works normally.

Also confirmed as a side effect: with the strut rect now on the correct monitor, maximized windows on that monitor stop above the dock instead of extending underneath it, which is what affectsStruts was supposed to be doing.

Testing was on v92 with the patch applied by hand; the surrounding code in both branches is identical at HEAD (v100), where this diff is taken from.

Not tested: vertical (left/right) dock positions — that hunk is the symmetric change and is reasoned-about rather than reproduced. Wayland, and any autohide-enabled configuration, were not exercised; per the above the latter is untouched by this change.

dock.struts.x (and .y in the vertical branch) was only ever assigned
inside the `autohide_dash` branch, so with autohide disabled the strut
actor kept its default position of 0.

_isWithinDash() hit-tests the pointer against the strut rect, so on a
multi-monitor layout where the dock's monitor has a non-zero offset the
rect sits over a different monitor and the pointer is never considered
to be inside the dock. Icon magnification therefore never triggers.

This is invisible on a single-monitor setup because the offset is 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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