From de2312301d23d868c75dc22b41ba92febbf7c0a3 Mon Sep 17 00:00:00 2001 From: hackademix <giorgio@maone.net> Date: Thu, 23 Mar 2023 23:29:21 +0100 Subject: [PATCH] Bug 41631: Prevent weird initial window dimensions caused by subpixel computations --- .../resistfingerprinting/RFPHelper.sys.mjs | 108 ++++++++++-------- 1 file changed, 63 insertions(+), 45 deletions(-) diff --git a/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs b/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs index a890074653cdd..c76ba3152eb2f 100644 --- a/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs +++ b/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs @@ -16,16 +16,31 @@ const kPrefLetterboxingTesting = "privacy.resistFingerprinting.letterboxing.testing"; const kTopicDOMWindowOpened = "domwindowopened"; -var logConsole; -function log(msg) { - if (!logConsole) { - logConsole = console.createInstance({ - prefix: "RFPHelper.jsm", - maxLogLevelPref: "privacy.resistFingerprinting.jsmloglevel", - }); - } +const lazy = {}; + +XPCOMUtils.defineLazyGetter(lazy, "logConsole", () => + console.createInstance({ + prefix: "RFPHelper.jsm", + maxLogLevelPref: "privacy.resistFingerprinting.jsmloglevel", + }) +); - logConsole.log(msg); +function log(...args) { + lazy.logConsole.log(...args); +} + +function forEachWindow(callback) { + const windowList = Services.wm.getEnumerator("navigator:browser"); + while (windowList.hasMoreElements()) { + const win = windowList.getNext(); + if (win.gBrowser && !win.closed) { + try { + callback(win); + } catch (e) { + lazy.logConsole.error(e); + } + } + } } class _RFPHelper { @@ -154,7 +169,11 @@ class _RFPHelper { (this.rfpEnabled = Services.prefs.getBoolPref(kPrefResistFingerprinting)) ) { this._addRFPObservers(); + Services.ww.registerNotification(this); + forEachWindow(win => this._attachWindow(win)); } else { + forEachWindow(win => this._detachWindow(win)); + Services.ww.unregisterNotification(this); this._removeRFPObservers(); } } @@ -291,12 +310,12 @@ class _RFPHelper { } _handleLetterboxingPrefChanged() { - if (Services.prefs.getBoolPref(kPrefLetterboxing, false)) { - Services.ww.registerNotification(this); - this._attachAllWindows(); - } else { - this._detachAllWindows(); - Services.ww.unregisterNotification(this); + this.letterboxingEnabled = Services.prefs.getBoolPref( + kPrefLetterboxing, + false + ); + if (this.rfpEnabled) { + forEachWindow(win => this._updateSizeForTabsInWindow(win)); } } @@ -398,11 +417,13 @@ class _RFPHelper { let logPrefix = `_roundContentSize[${Math.random()}]`; log(logPrefix); let win = aBrowser.ownerGlobal; + let browserContainer = aBrowser .getTabBrowser() .getBrowserContainer(aBrowser); let browserParent = aBrowser.parentElement; browserParent.classList.remove("exclude-letterboxing"); + let [ [contentWidth, contentHeight], [parentWidth, parentHeight], @@ -415,6 +436,22 @@ class _RFPHelper { ]) ); + if (!win._rfpSizeOffset) { + const BASELINE_ROUNDING = 10; + const offset = s => + s - Math.round(s / BASELINE_ROUNDING) * BASELINE_ROUNDING; + + win._rfpSizeOffset = { + width: offset(parentWidth), + height: offset(parentHeight), + }; + log( + `${logPrefix} Window size offsets %o (from %s, %s)`, + win._rfpSizeOffset, + parentWidth, + parentHeight + ); + } log( `${logPrefix} contentWidth=${contentWidth} contentHeight=${contentHeight} parentWidth=${parentWidth} parentHeight=${parentHeight} containerWidth=${containerWidth} containerHeight=${containerHeight}${ isNewTab ? " (new tab)." : "." @@ -433,6 +470,16 @@ class _RFPHelper { }); let result; + + if (!this.letterboxingEnabled) { + const offset = win._rfpSizeOffset; + result = r(aWidth - offset.width, aHeight - offset.height); + log( + `${logPrefix} Letterboxing disabled, applying baseline rounding offsets: (${aWidth}, ${aHeight}) => ${result.width} x ${result.height})` + ); + return result; + } + log(`${logPrefix} roundDimensions(${aWidth}, ${aHeight})`); // If the set is empty, we will round the content with the default // stepping size. @@ -493,7 +540,7 @@ class _RFPHelper { try { change(); } catch (e) { - logConsole.error(e); + lazy.logConsole.error(e); } } }); @@ -550,7 +597,6 @@ class _RFPHelper { _updateSizeForTabsInWindow(aWindow) { let tabBrowser = aWindow.gBrowser; - tabBrowser.tabpanels?.classList.add("letterboxing"); for (let tab of tabBrowser.tabs) { @@ -580,20 +626,6 @@ class _RFPHelper { this._updateSizeForTabsInWindow(aWindow); } - _attachAllWindows() { - let windowList = Services.wm.getEnumerator("navigator:browser"); - - while (windowList.hasMoreElements()) { - let win = windowList.getNext(); - - if (win.closed || !win.gBrowser) { - continue; - } - - this._attachWindow(win); - } - } - _detachWindow(aWindow) { let tabBrowser = aWindow.gBrowser; tabBrowser.removeTabsProgressListener(this); @@ -611,20 +643,6 @@ class _RFPHelper { } } - _detachAllWindows() { - let windowList = Services.wm.getEnumerator("navigator:browser"); - - while (windowList.hasMoreElements()) { - let win = windowList.getNext(); - - if (win.closed || !win.gBrowser) { - continue; - } - - this._detachWindow(win); - } - } - _handleDOMWindowOpened(win) { let self = this; -- GitLab