Fix window opening larger than the screen under display scaling - #694
Open
pratyush618 wants to merge 4 commits into
Open
Fix window opening larger than the screen under display scaling#694pratyush618 wants to merge 4 commits into
pratyush618 wants to merge 4 commits into
Conversation
get_screen_cons() bounds the generated fingerprint to the monitor, but BrowserForge honours a Screen constraint only when its pool has a match: FingerprintGenerator.partial_csp catches the filtering failure and deletes the constraint unless strict=True. So a 1366x768 laptop routinely gets a 2560x1440 fingerprint with window.outerWidth 1920, and browser-init resizes the real chrome window to it -- rendering past the edge of the monitor. Re-apply the bound after generation instead of trusting BrowserForge with it, and pull screenX/screenY back inside the shrunken screen. Headful only. headless has no window to overflow, and headless='virtual' runs a 1x1 Xvfb whose "monitor" would otherwise shrink the fingerprint to 1x1. Fixes daijro#499
headless='virtual' reaches launch_options as headless=False with virtual_display set (async_api rewrites it), so the headful gate fired and clamped the fingerprint to Xvfb's 1x1 stub. fix_screen_no_taskbar then drove availHeight to -39 and validate_config rejected the launch outright.
screeninfo makes the process per-monitor DPI aware, so it reports physical pixels, while Firefox lays windows out in CSS pixels. At 150% Windows scaling a 1920x1080 panel is 1280x720 CSS px, so bounding the fingerprint by the physical size lets the window open 1.5x larger than the screen. Refs daijro#425
get_screen_cons() was gated on DISPLAY being set, which only ever happens on Linux, so headful runs on Windows and macOS generated fingerprints with no monitor bound at all. Fixes daijro#425
|
When will this be shipped? I was forced to do a very hacky fix myself for now but it was causing flags with a lot of captchas |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #425.
Problem
With Windows display scaling enabled (150% / 200%), the browser window opens larger than the monitor.
Cause
Two independent defects, both in
get_screen_cons()'s contract.1. The bound is computed in the wrong unit.
screeninfo's Windows enumerator callsSetProcessDpiAwareness(2)before enumerating, explicitly so that it reports physical pixels:Firefox lays windows out in CSS pixels. Nothing in this repo pins
layout.css.devPixelsPerPx, so it stays at-1and tracks the system scale factor.browser-init.patchthen callswindow.resizeTo(outerWidth, outerHeight)with a value the Python layer derived from physical pixels.At 150% on a 1920x1080 panel the CSS screen is 1280x720, so a fingerprint bounded at "1920x1080" produces a window of 2880x1620 device pixels — 1.5x the screen on both axes.
2. The bound is never applied on Windows or macOS.
DISPLAYis X11-only. On Windows and macOS it is never set, so headful runs took theheadless is Falseearly return and generated with no monitor bound at all — the scaling mismatch above then applied to whatever BrowserForge picked, up to 2560x1440.Change
camoufox/display.py(new) — probes the host monitor in CSS pixels.largest_display()returns aDisplaySizein CSS px. On Windows it divides the physical size by the monitor's effective DPI (shcore!GetDpiForMonitorviaMonitorFromPoint); macOS (NSScreen.frame) and X11 already report CSS px, so scaling is Windows-only.shcoremissing, non-zeroHRESULT), so behaviour is unchanged where it does not apply.ctypes.WinDLLhandles rather than the process-widectypes.windllcache, so annotating the prototypes cannot leak into other libraries in the same process.has_display(env)replaces the'DISPLAY' in envprobe: always true off Linux,DISPLAYorWAYLAND_DISPLAYon Linux.get_screen_cons()keeps its signature and now returns CSS-pixel bounds.Scope
Untouched: headless (no window to overflow),
headless='virtual'(excluded by #674's gate), any caller passingscreen=orwindow=, and any host whose display cannot be probed.Windows without scaling is also unaffected —
GetDpiForMonitorreturns 96 DPI, the scale factor is 1.0, and the bound is the physical size as before.Tests
pythonlib/tests/test_display.py(new) — the DPI conversion table (96/120/144/192 -> 1.0/1.25/1.5/2.0), the Windows-only guard, both fallback paths, monitor selection, andhas_displayper platform.pythonlib/tests/test_launch_geometry.py— addsTestHeadfulFitsOnDisplay: 15 randomised headful launches against a 1280x720 CSS display, asserting noscreen.*orwindow.outer*value exceeds it, plus the geometry invariants and the unprobeable-host case. Asserts the outcome rather than the constraint, since BrowserForge silently drops constraints it cannot satisfy.Full pythonlib suite: 89 passed. The 2
test_virtdisplay.pyfailures are pre-existing (no Xvfb on this host) and reproduce unchanged on a clean tree.Not addressed
Launching the binary directly, without the Python package, still uses the hardcoded
window.resizeTo(1280, 1040)inbrowser-init.patch, which can overflow a small scaled display. That needs a patch regeneration throughmake edits.