diff --git a/js/ui/boxpointer.js b/js/ui/boxpointer.js index 4f6a2fb5a..00da8a238 100644 --- a/js/ui/boxpointer.js +++ b/js/ui/boxpointer.js @@ -46,6 +46,7 @@ BoxPointer.prototype = { this._yOffset = 0; this._xPosition = 0; this._yPosition = 0; + this._sourceAlignment = 0.5; }, show: function(animate, onComplete) { @@ -180,7 +181,7 @@ BoxPointer.prototype = { this.bin.allocate(childBox, flags); if (this._sourceActor && this._sourceActor.mapped) - this._reposition(this._sourceActor, this._alignment); + this._reposition(this._sourceActor, this._arrowAlignment); }, _drawBorder: function(area) { @@ -312,18 +313,31 @@ BoxPointer.prototype = { this.actor.show(); this._sourceActor = sourceActor; - this._alignment = alignment; + this._arrowAlignment = alignment; this._reposition(sourceActor, alignment); }, + setSourceAlignment: function(alignment) { + this._sourceAlignment = alignment; + + if (!this._sourceActor) + return; + + // We need to show it now to force an allocation, + // so that we can query the correct size. + this.actor.show(); + + this._reposition(this._sourceActor, this._arrowAlignment); + }, + _reposition: function(sourceActor, alignment) { // Position correctly relative to the sourceActor let sourceNode = sourceActor.get_theme_node(); let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box()); let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor); - let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) / 2; - let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) / 2; + let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment; + let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment; let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size(); // We also want to keep it onscreen, and separated from the diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js index d5048a272..2b5a3d9f8 100644 --- a/js/ui/popupMenu.js +++ b/js/ui/popupMenu.js @@ -1142,10 +1142,10 @@ function PopupMenu() { PopupMenu.prototype = { __proto__: PopupMenuBase.prototype, - _init: function(sourceActor, alignment, arrowSide) { + _init: function(sourceActor, arrowAlignment, arrowSide) { PopupMenuBase.prototype._init.call (this, sourceActor, 'popup-menu-content'); - this._alignment = alignment; + this._arrowAlignment = arrowAlignment; this._arrowSide = arrowSide; this._boxPointer = new BoxPointer.BoxPointer(arrowSide, @@ -1198,13 +1198,17 @@ PopupMenu.prototype = { this._boxPointer.setArrowOrigin(origin); }, + setSourceAlignment: function(alignment) { + this._boxPointer.setSourceAlignment(alignment); + }, + open: function(animate) { if (this.isOpen) return; this.isOpen = true; - this._boxPointer.setPosition(this.sourceActor, this._alignment); + this._boxPointer.setPosition(this.sourceActor, this._arrowAlignment); this._boxPointer.show(animate); this.actor.raise_top();