commit a581007def8ef5baf0f922046f338116eb69843c
parent cd7681f62c6a2ab2fa4cdf00a561db31f0c2126b
Author: hackademix <giorgio@maone.net>
Date: Fri, 24 Mar 2023 19:40:19 +0100
BB 41695: Warn on window maximization without letterboxing in RFPHelper module
Diffstat:
2 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/browser/app/profile/001-base-profile.js b/browser/app/profile/001-base-profile.js
@@ -529,6 +529,8 @@ pref("privacy.resistFingerprinting.letterboxing.vcenter", true);
pref("privacy.resistFingerprinting.letterboxing.gradient", true);
// tor-browser#41918: Should we reuse last window sizes if letterboxing is enabled
pref("privacy.resistFingerprinting.letterboxing.rememberSize", false);
+// tor-browser#41695: How many warnings we show if user closes them without restoring the window size
+pref("privacy.resistFingerprinting.resizeWarnings", 3);
// tor-browser#43402: Avoid a resize from the skeleton to the newwin size.
// Should be fixed in ESR-140 with Bug 1448423.
pref("browser.startup.blankWindow", false);
diff --git a/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs b/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
@@ -30,6 +30,8 @@ const kTopicFullscreenNavToolbox = "fullscreen-nav-toolbox";
const kPrefVerticalTabs = "sidebar.verticalTabs";
+const kPrefResizeWarnings = "privacy.resistFingerprinting.resizeWarnings";
+
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
@@ -60,6 +62,84 @@ function forEachWindow(callback) {
}
}
+async function windowResizeHandler(aEvent) {
+ if (RFPHelper.letterboxingEnabled || !RFPHelper.rfpEnabled) {
+ return;
+ }
+ if (Services.prefs.getIntPref(kPrefResizeWarnings) <= 0) {
+ return;
+ }
+
+ const window = aEvent.currentTarget;
+
+ // Wait for end of execution queue to ensure we have correct windowState.
+ await new Promise(resolve => window.setTimeout(resolve, 0));
+ switch (window.windowState) {
+ case window.STATE_MAXIMIZED:
+ case window.STATE_FULLSCREEN:
+ break;
+ default:
+ return;
+ }
+
+ // Do not add another notification if one is already showing.
+ const kNotificationName = "rfp-window-resize-notification";
+ let box = window.gNotificationBox;
+ if (box.getNotificationWithValue(kNotificationName)) {
+ return;
+ }
+
+ // Rate-limit showing our notification if needed.
+ if (Date.now() - (windowResizeHandler.timestamp || 0) < 1000) {
+ return;
+ }
+ windowResizeHandler.timestamp = Date.now();
+
+ const decreaseWarningsCount = () => {
+ const currentCount = Services.prefs.getIntPref(kPrefResizeWarnings);
+ if (currentCount > 0) {
+ Services.prefs.setIntPref(kPrefResizeWarnings, currentCount - 1);
+ }
+ };
+
+ const [label, accessKey] = await window.document.l10n.formatValues([
+ { id: "basebrowser-rfp-restore-window-size-button-label" },
+ { id: "basebrowser-rfp-restore-window-size-button-ak" },
+ ]);
+
+ const buttons = [
+ {
+ label,
+ accessKey,
+ popup: null,
+ callback() {
+ // reset notification timer to work-around resize race conditions
+ windowResizeHandler.timestamp = Date.now();
+ // restore the original (rounded) size we had stored on window startup
+ let { _rfpOriginalSize } = window;
+ window.setTimeout(() => {
+ window.resizeTo(_rfpOriginalSize.width, _rfpOriginalSize.height);
+ }, 0);
+ },
+ },
+ ];
+
+ box.appendNotification(
+ kNotificationName,
+ {
+ label: { "l10n-id": "basebrowser-rfp-maximize-warning-message" },
+ priority: box.PRIORITY_WARNING_LOW,
+ eventCallback(event) {
+ if (event === "dismissed") {
+ // user manually dismissed the notification
+ decreaseWarningsCount();
+ }
+ },
+ },
+ buttons
+ );
+}
+
class _RFPHelper {
_resizeObservers = new WeakMap();
@@ -756,6 +836,7 @@ class _RFPHelper {
_attachWindow(aWindow) {
this._fixRounding(aWindow);
+ aWindow.addEventListener("sizemodechange", windowResizeHandler);
aWindow.gBrowser.addTabsProgressListener(this);
aWindow.addEventListener("TabOpen", this);
let resizeObserver = new aWindow.ResizeObserver(entries => {
@@ -1084,6 +1165,7 @@ class _RFPHelper {
let browser = tab.linkedBrowser;
this._resetContentSize(browser);
}
+ aWindow.removeEventListener("sizemodechange", windowResizeHandler);
aWindow.removeEventListener("nativethemechange", this);
this._updateLetterboxingColors(aWindow, false);