Skip to content

BoxPointer: Use X/Y actor positioning instead of an anchor point

Currently all the widgets using BoxPointer and so popup actors are always drawn at screen origin and then shifted at paint time in the proper position.

This doesn't work when using resource scale, since the widgets need to know in which monitor they currently are in order to use properly scaled resources.

So, basically revert commit 22c22e0d and go back using the actual actor coordinates, as the relayouting issues of the past seem to be gone now.

There's also a fix on commit 96e14dcb which made the above change to be possible (otherwise it would have caused failures on opening the dash/dock menus also in horizontally aligned monitors).


I went for this path after some discussion with Jonas, however the same behavior can be also just done with


diff --git a/js/ui/boxpointer.js b/js/ui/boxpointer.js
index 3387b31bb..45a649e5e 100644
--- a/js/ui/boxpointer.js
+++ b/js/ui/boxpointer.js
@@ -615,8 +615,8 @@ var BoxPointer = GObject.registerClass({
         // allocation loops and warnings. Instead we do the positioning via
         // the anchor point, which is independent of allocation, and leave
         // x == y == 0.
-        this.set_anchor_point(-(this._xPosition + this._xOffset),
-                              -(this._yPosition + this._yOffset));
+        this.set_position(this._xPosition + this._xOffset,
+                          this._yPosition + this._yOffset);
     }
 
     _calculateArrowSide(arrowSide) {

But this would keep some unneeded code around.


If instead we want to preserve the optimized way (and this was actually my preferred), avoiding the relayouting that changing actor coordinates implies, the other option is instead to use something like:

diff --git a/js/ui/boxpointer.js b/js/ui/boxpointer.js
index 3387b31bb..c396f6023 100644
--- a/js/ui/boxpointer.js
+++ b/js/ui/boxpointer.js
@@ -615,8 +615,11 @@ var BoxPointer = GObject.registerClass({
         // allocation loops and warnings. Instead we do the positioning via
         // the anchor point, which is independent of allocation, and leave
         // x == y == 0.
-        this.set_anchor_point(-(this._xPosition + this._xOffset),
-                              -(this._yPosition + this._yOffset));
+        let monitor = Main.layoutManager.findMonitorForActor(this.sourceActor || this._sourceActor);
+
+        this.set_position(monitor.x, monitor.y);
+        this.set_anchor_point(monitor.x - (this._xPosition + this._xOffset),
+                              monitor.y - (this._yPosition + this._yOffset));
     }
 
     _calculateArrowSide(arrowSide) {

With this, basically we'd just move the actor to the origin of the source monitor so that resource scale will be properly recomputed if that changed, but at the same time we avoid doing all these calculations if the widget has just been moved around in the same monitor (as it might happen with BackgroundMenu).

Edited by Marco Trevisan

Merge request reports