... |
... |
@@ -4,6 +4,7 @@ |
4
|
4
|
* You can obtain one at https://mozilla.org/MPL/2.0/. */
|
5
|
5
|
|
6
|
6
|
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
|
7
|
+import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
|
7
|
8
|
import * as constants from "resource://gre/modules/RFPTargetConstants.sys.mjs";
|
8
|
9
|
|
9
|
10
|
const kPrefResistFingerprinting = "privacy.resistFingerprinting";
|
... |
... |
@@ -21,6 +22,8 @@ const kPrefLetterboxingGradient = |
21
|
22
|
"privacy.resistFingerprinting.letterboxing.gradient";
|
22
|
23
|
const kPrefLetterboxingDidForceSize =
|
23
|
24
|
"privacy.resistFingerprinting.letterboxing.didForceSize";
|
|
25
|
+const kPrefLetterboxingRememberSize =
|
|
26
|
+ "privacy.resistFingerprinting.letterboxing.rememberSize";
|
24
|
27
|
|
25
|
28
|
const kTopicDOMWindowOpened = "domwindowopened";
|
26
|
29
|
|
... |
... |
@@ -519,22 +522,23 @@ class _RFPHelper { |
519
|
522
|
}
|
520
|
523
|
}
|
521
|
524
|
|
|
525
|
+ stepping(aDimension, aIsWidth) {
|
|
526
|
+ if (aDimension <= 500) {
|
|
527
|
+ return 50;
|
|
528
|
+ } else if (aDimension <= 1600) {
|
|
529
|
+ return aIsWidth ? 200 : 100;
|
|
530
|
+ }
|
|
531
|
+ return 200;
|
|
532
|
+ }
|
|
533
|
+
|
522
|
534
|
/**
|
523
|
535
|
* Given a width or height, rounds it with the proper stepping.
|
524
|
536
|
*/
|
525
|
537
|
steppedSize(aDimension, aIsWidth = false) {
|
526
|
|
- let stepping;
|
527
|
538
|
if (aDimension <= 50) {
|
528
|
|
- return 0;
|
529
|
|
- } else if (aDimension <= 500) {
|
530
|
|
- stepping = 50;
|
531
|
|
- } else if (aDimension <= 1600) {
|
532
|
|
- stepping = aIsWidth ? 200 : 100;
|
533
|
|
- } else {
|
534
|
|
- stepping = 200;
|
|
539
|
+ return aDimension;
|
535
|
540
|
}
|
536
|
|
-
|
537
|
|
- return aDimension - (aDimension % stepping);
|
|
541
|
+ return aDimension - (aDimension % this.stepping(aDimension, aIsWidth));
|
538
|
542
|
}
|
539
|
543
|
|
540
|
544
|
/**
|
... |
... |
@@ -806,6 +810,7 @@ class _RFPHelper { |
806
|
810
|
}
|
807
|
811
|
|
808
|
812
|
_attachWindow(aWindow) {
|
|
813
|
+ this._fixRounding(aWindow);
|
809
|
814
|
aWindow.addEventListener("sizemodechange", windowResizeHandler);
|
810
|
815
|
aWindow.shrinkToLetterbox = this.shrinkToLetterbox;
|
811
|
816
|
aWindow.addEventListener("dblclick", this._onWindowDoubleClick);
|
... |
... |
@@ -865,6 +870,52 @@ class _RFPHelper { |
865
|
870
|
);
|
866
|
871
|
}
|
867
|
872
|
|
|
873
|
+ _fixRounding(aWindow) {
|
|
874
|
+ if (
|
|
875
|
+ !this.rfpEnabled ||
|
|
876
|
+ Services.prefs.getBoolPref(kPrefLetterboxingRememberSize, false)
|
|
877
|
+ ) {
|
|
878
|
+ return;
|
|
879
|
+ }
|
|
880
|
+
|
|
881
|
+ // tor-browser#43205: in case of subpixels, new windows might have a wrong
|
|
882
|
+ // size because of platform-specific bugs (e.g., Bug 1947439 on Windows).
|
|
883
|
+ const contentContainer = aWindow.document.getElementById("browser");
|
|
884
|
+ const rect = contentContainer.getBoundingClientRect();
|
|
885
|
+ const steppingWidth = this.stepping(rect.width, true);
|
|
886
|
+ const steppingHeight = this.stepping(rect.height, false);
|
|
887
|
+ const deltaWidth =
|
|
888
|
+ rect.width - steppingWidth * Math.round(rect.width / steppingWidth);
|
|
889
|
+ const deltaHeight =
|
|
890
|
+ rect.height - steppingHeight * Math.round(rect.height / steppingHeight);
|
|
891
|
+
|
|
892
|
+ // It seems that under X11, a window cannot have all the possible (integer)
|
|
893
|
+ // sizes (see the videos on tor-browser#43205 and Bug 1947439)...
|
|
894
|
+ // We observed this behavior with 1.25 scaling, but we could not find
|
|
895
|
+ // where it happens exactly, so this code might be wrong.
|
|
896
|
+ // On the same system, this problem does not happen with Wayland.
|
|
897
|
+ if (AppConstants.platform === "linux") {
|
|
898
|
+ let targetWidth = aWindow.outerWidth - deltaWidth;
|
|
899
|
+ let targetHeight = aWindow.outerHeight - deltaHeight;
|
|
900
|
+ const x11Size = s =>
|
|
901
|
+ Math.floor(
|
|
902
|
+ // This first rounding is done by Gecko, rather than X11.
|
|
903
|
+ Math.round(s * aWindow.devicePixelRatio) / aWindow.devicePixelRatio
|
|
904
|
+ );
|
|
905
|
+ const x11Width = x11Size(targetWidth);
|
|
906
|
+ const x11Height = x11Size(targetHeight);
|
|
907
|
+ if (x11Width < targetWidth) {
|
|
908
|
+ targetWidth = x11Width + 2;
|
|
909
|
+ }
|
|
910
|
+ if (x11Height < targetHeight) {
|
|
911
|
+ targetHeight = x11Height + 2;
|
|
912
|
+ }
|
|
913
|
+ aWindow.resizeTo(targetWidth, targetHeight);
|
|
914
|
+ } else {
|
|
915
|
+ aWindow.resizeBy(deltaWidth, deltaHeight);
|
|
916
|
+ }
|
|
917
|
+ }
|
|
918
|
+
|
868
|
919
|
getTargets() {
|
869
|
920
|
return constants.Targets;
|
870
|
921
|
}
|