Skip to content
Snippets Groups Projects
Commit 99824eb8 authored by ma1's avatar ma1 Committed by Pier Angelo Vendrame
Browse files

Bug 41695: Warn on window maximization without letterboxing in RFPHelper module

parent e082b667
No related branches found
No related tags found
No related merge requests found
......@@ -370,6 +370,8 @@ pref("security.remote_settings.intermediates.enabled", false);
pref("dom.use_components_shim", false);
// Enable letterboxing
pref("privacy.resistFingerprinting.letterboxing", true);
// tor-browser#41695: how many warnings we show if user closes them without restoring the window size
pref("privacy.resistFingerprinting.resizeWarnings", 3);
// tor-browser#33282: new windows start at 1400x900 when there's enough screen space, otherwise down by 200x100 blocks
pref("privacy.window.maxInnerWidth", 1400);
pref("privacy.window.maxInnerHeight", 900);
......
......@@ -16,6 +16,8 @@ const kPrefLetterboxingTesting =
"privacy.resistFingerprinting.letterboxing.testing";
const kTopicDOMWindowOpened = "domwindowopened";
const kPrefResizeWarnings = "privacy.resistFingerprinting.resizeWarnings";
const lazy = {};
XPCOMUtils.defineLazyGetter(lazy, "logConsole", () =>
......@@ -43,6 +45,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 {
// ============================================================================
// Shared Setup
......@@ -443,7 +523,12 @@ class _RFPHelper {
])
);
if (!win._rfpSizeOffset) {
if (
!win._rfpSizeOffset ||
(win._rfpOriginalSize &&
win.outerWidth === win._rfpOriginalSize.width &&
win.outerHeight === win._rfpOriginalSize.height)
) {
const BASELINE_ROUNDING = 10;
const offset = s =>
s - Math.round(s / BASELINE_ROUNDING) * BASELINE_ROUNDING;
......@@ -613,10 +698,18 @@ class _RFPHelper {
// we need to add this class late because otherwise new windows get maximized
aWindow.setTimeout(() => {
tabBrowser.tabpanels?.classList.add("letterboxing-ready");
if (!aWindow._rfpOriginalSize) {
aWindow._rfpOriginalSize = {
width: aWindow.outerWidth,
height: aWindow.outerHeight,
};
log("Recording original window size", aWindow._rfpOriginalSize);
}
});
}
_attachWindow(aWindow) {
aWindow.addEventListener("sizemodechange", windowResizeHandler);
aWindow.gBrowser.addTabsProgressListener(this);
aWindow.addEventListener("TabOpen", this);
const resizeObserver = (aWindow._rfpResizeObserver =
......@@ -648,6 +741,7 @@ class _RFPHelper {
let browser = tab.linkedBrowser;
this._resetContentSize(browser);
}
aWindow.removeEventListener("sizemodechange", windowResizeHandler);
}
_handleDOMWindowOpened(win) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment