Bug 1401477 - limit autoscroll popup coordinates so we always display it full-size, instead of having the popup code constrain its size to fit on-screen, r?dao
MozReview-Commit-ID: 6XQNfkkjadC
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -1285,43 +1285,73 @@
</body>
</method>
<method name="startScroll">
<parameter name="scrolldir"/>
<parameter name="screenX"/>
<parameter name="screenY"/>
<body><![CDATA[
+ const POPUP_SIZE = 28;
if (!this._autoScrollPopup) {
if (this.hasAttribute("autoscrollpopup")) {
// our creator provided a popup to share
this._autoScrollPopup = document.getElementById(this.getAttribute("autoscrollpopup"));
} else {
// we weren't provided a popup; we have to use the global scope
this._autoScrollPopup = this._createAutoScrollPopup();
document.documentElement.appendChild(this._autoScrollPopup);
this._autoScrollNeedsCleanup = true;
}
+ this._autoScrollPopup.removeAttribute("hidden");
+ this._autoScrollPopup.setAttribute("noautofocus", "true");
+ this._autoScrollPopup.style.height = POPUP_SIZE + "px";
+ this._autoScrollPopup.style.width = POPUP_SIZE + "px";
+ this._autoScrollPopup.style.margin = -POPUP_SIZE / 2 + "px";
}
+ let screenManager = Components.classes["@mozilla.org/gfx/screenmanager;1"]
+ .getService(Components.interfaces.nsIScreenManager);
+ let screen = screenManager.screenForRect(screenX, screenY, 1, 1);
+
// we need these attributes so themers don't need to create per-platform packages
if (screen.colorDepth > 8) { // need high color for transparency
// Exclude second-rate platforms
this._autoScrollPopup.setAttribute("transparent", !/BeOS|OS\/2/.test(navigator.appVersion));
// Enable translucency on Windows and Mac
this._autoScrollPopup.setAttribute("translucent", /Win|Mac/.test(navigator.platform));
}
- this._autoScrollPopup.removeAttribute("hidden");
- this._autoScrollPopup.setAttribute("noautofocus", "true");
this._autoScrollPopup.setAttribute("scrolldir", scrolldir);
this._autoScrollPopup.addEventListener("popuphidden", this, true);
+
+ // Sanitize screenX/screenY for available screen size with half the size
+ // of the popup removed. The popup uses negative margins to center on the
+ // coordinates we pass. Unfortunately `window.screen.availLeft` can be negative
+ // on Windows in multi-monitor setups, so we use nsIScreenManager instead:
+ let left = {}, top = {}, width = {}, height = {};
+ screen.GetAvailRectDisplayPix(left, top, width, height);
+
+ // We need to get screen CSS-pixel (rather than display-pixel) coordinates.
+ // With 175% DPI, the actual ratio of display pixels to CSS pixels is
+ // 1.7647 because of rounding inside gecko. Unfortunately defaultCSSScaleFactor
+ // returns the original 1.75 dpi factor. While window.devicePixelRatio would
+ // get us the correct ratio, if the window is split between 2 screens,
+ // window.devicePixelRatio isn't guaranteed to match the screen we're
+ // autoscrolling on. So instead we do the same math as Gecko.
+ const scaleFactor = 60 / Math.round(60 / screen.defaultCSSScaleFactor);
+ let minX = left.value / scaleFactor + 0.5 * POPUP_SIZE;
+ let maxX = (left.value + width.value) / scaleFactor - 0.5 * POPUP_SIZE;
+ let minY = top.value / scaleFactor + 0.5 * POPUP_SIZE;
+ let maxY = (top.value + height.value) / scaleFactor - 0.5 * POPUP_SIZE;
+ let popupX = Math.max(minX, Math.min(maxX, screenX));
+ let popupY = Math.max(minY, Math.min(maxY, screenY));
this._autoScrollPopup.showPopup(document.documentElement,
- screenX,
- screenY,
+ popupX,
+ popupY,
"popup", null, null);
this._ignoreMouseEvents = true;
this._scrolling = true;
this._startX = screenX;
this._startY = screenY;
window.addEventListener("mousemove", this, true);
window.addEventListener("mousedown", this, true);
--- a/toolkit/themes/linux/global/global.css
+++ b/toolkit/themes/linux/global/global.css
@@ -269,20 +269,17 @@ popupnotificationcontent {
margin-top: .5em;
}
%include ../../shared/notification-popup.inc.css
/* :::::: autoscroll popup ::::: */
.autoscroller {
- height: 28px;
- width: 28px;
border: none;
- margin: -14px;
padding: 0;
background-image: url("chrome://global/skin/icons/autoscroll.svg");
background-size: contain;
background-color: transparent;
background-repeat: no-repeat;
-moz-appearance: none;
}
--- a/toolkit/themes/osx/global/global.css
+++ b/toolkit/themes/osx/global/global.css
@@ -282,20 +282,17 @@ popupnotificationcontent {
margin-top: .5em;
}
%include ../../shared/notification-popup.inc.css
/* :::::: autoscroll popup ::::: */
.autoscroller {
- height: 28px;
- width: 28px;
border: none;
- margin: -14px;
padding: 0;
background-image: url("chrome://global/skin/icons/autoscroll.svg");
background-size: contain;
background-color: transparent;
background-position: right top;
background-repeat: no-repeat;
-moz-appearance: none;
-moz-window-shadow: none;
--- a/toolkit/themes/windows/global/global.css
+++ b/toolkit/themes/windows/global/global.css
@@ -291,20 +291,17 @@ popupnotificationcontent {
margin-top: .5em;
}
%include ../../shared/notification-popup.inc.css
/* :::::: autoscroll popup ::::: */
.autoscroller {
- height: 28px;
- width: 28px;
border: none;
- margin: -14px;
padding: 0;
background-image: url("chrome://global/skin/icons/autoscroll.svg");
background-size: contain;
background-color: transparent;
background-repeat: no-repeat;
-moz-appearance: none;
}