| 
Commits:
6 changed files:
Changes:
browser/app/profile/001-base-profile.js
 
| ... | ... | @@ -379,6 +379,8 @@ pref("privacy.resistFingerprinting.letterboxing", true); |  
| 379 | 379 |  pref("privacy.resistFingerprinting.letterboxing.vcenter", true);
 |  
| 380 | 380 |  // tor-browser#41917 letterboxing gradient background
 |  
| 381 | 381 |  pref("privacy.resistFingerprinting.letterboxing.gradient", true);
 |  
|  | 382 | +// tor-browser#41918: should we reuse last window sizes if letterboxing is enabled
 |  
|  | 383 | +pref("privacy.resistFingerprinting.letterboxing.rememberSize", false);
 |  
| 382 | 384 |  // tor-browser#41695: how many warnings we show if user closes them without restoring the window size
 |  
| 383 | 385 |  pref("privacy.resistFingerprinting.resizeWarnings", 3);
 |  
| 384 | 386 |  // tor-browser#33282: new windows start at 1400x900 when there's enough screen space, otherwise down by 200x100 blocks
 |  dom/base/nsContentUtils.cpp
 
 
| ... | ... | @@ -2663,6 +2663,18 @@ void nsContentUtils::CalcRoundedWindowSizeForResistingFingerprinting( |  
| 2663 | 2663 |    *aOutputHeight = resultHeight;
 |  
| 2664 | 2664 |  }
 |  
| 2665 | 2665 |  
 |  
|  | 2666 | +bool nsContentUtils::ShouldRoundWindowSizeForResistingFingerprinting() {
 |  
|  | 2667 | +  return !(
 |  
|  | 2668 | +      Preferences::GetBool("privacy.resistFingerprinting.letterboxing",
 |  
|  | 2669 | +                           false) &&
 |  
|  | 2670 | +      // We want to round window size at least once in the browser's life time:
 |  
|  | 2671 | +      // AppWindow::ForceRoundedDimensions() will set this preference to true.
 |  
|  | 2672 | +      Preferences::GetBool(
 |  
|  | 2673 | +          "privacy.resistFingerprinting.letterboxing.didForceSize", false) &&
 |  
|  | 2674 | +      Preferences::GetBool(
 |  
|  | 2675 | +          "privacy.resistFingerprinting.letterboxing.rememberSize", false));
 |  
|  | 2676 | +}
 |  
|  | 2677 | +
 |  
| 2666 | 2678 |  bool nsContentUtils::ThreadsafeIsCallerChrome() {
 |  
| 2667 | 2679 |    return NS_IsMainThread() ? IsCallerChrome()
 |  
| 2668 | 2680 |                             : IsCurrentThreadRunningChromeWorker();
 |  dom/base/nsContentUtils.h
 
 
| ... | ... | @@ -406,6 +406,10 @@ class nsContentUtils { |  
| 406 | 406 |        bool aSetOuterWidth, bool aSetOuterHeight, int32_t* aOutputWidth,
 |  
| 407 | 407 |        int32_t* aOutputHeight);
 |  
| 408 | 408 |  
 |  
|  | 409 | +  // Tell if we actually want to round size of new windows for RFP,
 |  
|  | 410 | +  // depending on letterboxing status and user's preference.
 |  
|  | 411 | +  static bool ShouldRoundWindowSizeForResistingFingerprinting();
 |  
|  | 412 | +
 |  
| 409 | 413 |    /**
 |  
| 410 | 414 |     * Returns the parent node of aChild crossing document boundaries, but skips
 |  
| 411 | 415 |     * any cross-process parent frames and continues with the nearest in-process
 |  toolkit/components/resistfingerprinting/RFPHelper.sys.mjs
 
 
| ... | ... | @@ -18,6 +18,8 @@ const kPrefLetterboxingVcenter = |  
| 18 | 18 |    "privacy.resistFingerprinting.letterboxing.vcenter";
 |  
| 19 | 19 |  const kPrefLetterboxingGradient =
 |  
| 20 | 20 |    "privacy.resistFingerprinting.letterboxing.gradient";
 |  
|  | 21 | +const  kPrefLetterboxingDidForceSize =
 |  
|  | 22 | +  "privacy.resistFingerprinting.letterboxing.didForceSize";
 |  
| 21 | 23 |  
 |  
| 22 | 24 |  const kTopicDOMWindowOpened = "domwindowopened";
 |  
| 23 | 25 |  
 |  
| ... | ... | @@ -221,6 +223,7 @@ class _RFPHelper { |  
| 221 | 223 |    _handlePrefChanged(data) {
 |  
| 222 | 224 |      switch (data) {
 |  
| 223 | 225 |        case kPrefResistFingerprinting:
 |  
|  | 226 | +        Service.prefs.clearUserPref(kPrefLetterboxingDidForceSize);
 |  
| 224 | 227 |          this._handleResistFingerprintingChanged();
 |  
| 225 | 228 |          break;
 |  
| 226 | 229 |        case kPrefSpoofEnglish:
 |  
| ... | ... | @@ -228,6 +231,7 @@ class _RFPHelper { |  
| 228 | 231 |          this._handleSpoofEnglishChanged();
 |  
| 229 | 232 |          break;
 |  
| 230 | 233 |        case kPrefLetterboxing:
 |  
|  | 234 | +        Service.prefs.clearUserPref(kPrefLetterboxingDidForceSize);
 |  
| 231 | 235 |        case kPrefLetterboxingVcenter:
 |  
| 232 | 236 |        case kPrefLetterboxingGradient:
 |  
| 233 | 237 |          this._handleLetterboxingPrefChanged();
 |  toolkit/components/windowwatcher/nsWindowWatcher.cpp
 
 
| ... | ... | @@ -2333,7 +2333,9 @@ static void SizeOpenedWindow(nsIDocShellTreeOwner* aTreeOwner, |  
| 2333 | 2333 |            screenDesktopRect.Size() / screenCssToDesktopScale;
 |  
| 2334 | 2334 |  
 |  
| 2335 | 2335 |        if (aSizeSpec.SizeSpecified()) {
 |  
| 2336 |  | -        if (!nsContentUtils::ShouldResistFingerprinting()) {
 |  
|  | 2336 | +        if (!(nsContentUtils::ShouldResistFingerprinting() &&
 |  
|  | 2337 | +              nsContentUtils::
 |  
|  | 2338 | +                  ShouldRoundWindowSizeForResistingFingerprinting())) {
 |  
| 2337 | 2339 |            /* Unlike position, force size out-of-bounds check only if
 |  
| 2338 | 2340 |               size actually was specified. Otherwise, intrinsically sized
 |  
| 2339 | 2341 |               windows are broken. */
 |  xpfe/appshell/AppWindow.cpp
 
 
| ... | ... | @@ -1123,8 +1123,9 @@ NS_IMETHODIMP AppWindow::GetAvailScreenSize(int32_t* aAvailWidth, |  
| 1123 | 1123 |    return NS_OK;
 |  
| 1124 | 1124 |  }
 |  
| 1125 | 1125 |  
 |  
| 1126 |  | -// Rounds window size to 1000x1000, or, if there isn't enough available
 |  
| 1127 |  | -// screen space, to a multiple of 200x100.
 |  
|  | 1126 | +// Rounds window size to privacy.window.maxInnerWidth x
 |  
|  | 1127 | +// privacy.window.maxInnerWidth, or, if there isn't enough available screen
 |  
|  | 1128 | +// space, to a multiple of 200x100.
 |  
| 1128 | 1129 |  NS_IMETHODIMP AppWindow::ForceRoundedDimensions() {
 |  
| 1129 | 1130 |    if (mIsHiddenWindow) {
 |  
| 1130 | 1131 |      return NS_OK;
 |  
| ... | ... | @@ -1164,6 +1165,11 @@ NS_IMETHODIMP AppWindow::ForceRoundedDimensions() { |  
| 1164 | 1165 |  
 |  
| 1165 | 1166 |    SetPrimaryContentSize(targetSizeDev.width, targetSizeDev.height);
 |  
| 1166 | 1167 |  
 |  
|  | 1168 | +  // Ensure we force initial rounded size at least once, as checked by
 |  
|  | 1169 | +  // nsContentUtils::ShouldRoundWindowSizeForResistingFingerprinting().
 |  
|  | 1170 | +  Preferences::SetBool("privacy.resistFingerprinting.letterboxing.didForceSize",
 |  
|  | 1171 | +                       true);
 |  
|  | 1172 | +
 |  
| 1167 | 1173 |    return NS_OK;
 |  
| 1168 | 1174 |  }
 |  
| 1169 | 1175 |  
 |  
| ... | ... | @@ -2703,7 +2709,8 @@ void AppWindow::SizeShell() { |  
| 2703 | 2709 |    if (nsContentUtils::ShouldResistFingerprinting(
 |  
| 2704 | 2710 |            "if RFP is enabled we want to round the dimensions of the new"
 |  
| 2705 | 2711 |            "new pop up window regardless of their origin") &&
 |  
| 2706 |  | -      windowType.EqualsLiteral("navigator:browser")) {
 |  
|  | 2712 | +      windowType.EqualsLiteral("navigator:browser") &&
 |  
|  | 2713 | +      nsContentUtils::ShouldRoundWindowSizeForResistingFingerprinting()) {
 |  
| 2707 | 2714 |      // Once we've got primary content, force dimensions.
 |  
| 2708 | 2715 |      if (mPrimaryContentShell || mPrimaryBrowserParent) {
 |  
| 2709 | 2716 |        ForceRoundedDimensions();
 |  
 |