Closed Bug 1798213 Opened 2 years ago Closed 2 years ago

window.screen returns physical dimensions instead of virtual when read from backgroundscript (high-DPI display issue)

Categories

(WebExtensions :: General, defect)

Firefox 103
defect

Tracking

(firefox-esr102 unaffected, firefox106 wontfix, firefox107 wontfix, firefox108 verified, firefox109 verified)

VERIFIED FIXED
109 Branch
Tracking Status
firefox-esr102 --- unaffected
firefox106 --- wontfix
firefox107 --- wontfix
firefox108 --- verified
firefox109 --- verified

People

(Reporter: stig, Assigned: emilio)

References

(Regression)

Details

(Keywords: regression)

Attachments

(3 files)

Attached file xIFr-issuelog.zip

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0

Steps to reproduce:

From backgroundscript in a webextension of mine, I read window.screen properties (width, availWidth, height, availHeight) to calculate positioning and size for a popup. This has worked flawlessly until recently, but suddenly popups started to be misplaced and oversized on high-density monitors (when display setup has a scaling-factor).
I have tried logging the values found for width, availWidth, height, availHeigh in the backgroundscript, and it looks like window.screen suddenly returns the monitors' physical pixel dimensions instead of virtual pixel dimension as it used to (and other browsers do).
I have also done a test reading window.screen properties from a "frontend-script" (webpage), and here everything seems to behave normal with window.screen still returning "virtual pixel dimensions". So problem seems to be specific for webextensions (maybe specific for backgroundscripts?).

Problem started very recently, so I think it was introduced with Firefox 106.

Actual results:

The following is log-output from inspecting backgroundscript in a modified version of my webextension, which I will attach to this bugreport (It is "modified" to add the console.log statements). I ran the tests with Firefox 106, Waterfox G5 (Firefox 102 ESR) and with Chrome 107, and I ran tests on two Windows PCs. A PC without display-scaling, and a laptop with display-scaling (125%). The results:

PC, Windows 11, Firefox 106
Display 27” 2560x1440 with display-scaling: none (100%)
window.screen.width: 2560
window.screen.availWidth: 2560
window.screen.height: 1440
window.screen.availHeight: 1392

PC, Windows 11, Waterfox G5 (Based on Firefox 102 ESR)
Display 27” 2560x1440 with display-scaling: none (100%)
window.screen.width: 2560
window.screen.availWidth: 2560
window.screen.height: 1440
window.screen.availHeight: 1392

PC, Windows 11, Chrome 107
Display 27” 2560x1440 with display-scaling: none (100%)
window.screen.width: 2560
window.screen.availWidth: 2560
window.screen.height: 1440
window.screen.availHeight: 1392


Laptop, Windows 11, Firefox 106
Display 15” 1920x1080 with display-scaling: 125%
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1080

Laptop, Windows 11, Waterfox G5 (Based on Firefox 102 ESR)
Display 15” 1920x1080 with display-scaling: 125%
window.screen.width: 1536
window.screen.availWidth: 1536
window.screen.height: 864
window.screen.availHeight: 864

Laptop, Windows 11, Chrome 107
Display: 15” 1920x1080 with display-scaling: 125%
window.screen.width: 1536
window.screen.availWidth: 1536
window.screen.height: 864
window.screen.availHeight: 864

Expected results:

On the PC/display with no scaling (virtual = physical pixel dimensions), everything behaves as it uses to. All three browsers writes the same to the log:

window.screen.width: 2560
window.screen.availWidth: 2560
window.screen.height: 1440
window.screen.availHeight: 1392

HOWEVER on the laptop with a display-scaling of 125%, Firefox 106 doesn't return the expected or same as Waterfox (Firefox ESR 102) or Chrome 107 does.

Firefox 106 returns physical pixel dimensions:
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1080

Chrome and Waterfox (Firefox 102 ESR) returns virtual pixel dimensions:
window.screen.width: 1536
window.screen.availWidth: 1536
window.screen.height: 864
window.screen.availHeight: 864

Comment on attachment 9300981 [details]
xIFr-issuelog.zip

This is "xIFr", my EXIF reader webextension. It is "cross-browser" (can also run with basic functionality in Chromium browsers).
Install it temporary with "Debug Addon" and choose "Inspect" to view log-lines from backgroundscript.
To trigger xIFr to read window.screen and write the properties to log, you need to right-click an image and choose "View EXIF data".

Product: Firefox → WebExtensions

Hello,

I’m not entirely sure how to interpret the results I got on my end using a 15” laptop with a 24” monitor connected to it, running Windows 10 x64.
I tested 3 different browsers, Nightly (108.0a1/20221031214452), Release (106.0.3/20221030091646) and ESR 102.4.0 (102.4.0esr/20221010114559) moving the browser window from the 24” monitor to the laptop display, triggering the read function on the extension and checking the logs as per Comment 1.

All logged values were the same regardless of used browser or display. Please see below for more details and maybe you can make more sense of them.

NIGHTLY (108.0a1/20221031214452)
24” monitor connected to laptop with no-scaling (100%) 1920x1080
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1040

browser.windows.Window.width: 1936
browser.windows.Window.height: 1056
browser.windows.Window.top: -8
browser.windows.Window.left: -8

15“ Laptop display with scaling (125%) 1920x1080
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1040

browser.windows.Window.width: 1550
browser.windows.Window.height: 838
browser.windows.Window.top: -7
browser.windows.Window.left: -3079

RELEASE (106.0.3/20221030091646)
24” monitor connected to laptop with no-scaling (100%) 1920x1080
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1040

browser.windows.Window.width: 1936
browser.windows.Window.height: 1056
browser.windows.Window.top: -8
browser.windows.Window.left: -8

15“ Laptop display with scaling (125%) 1920x1080
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1040

browser.windows.Window.width: 1550
browser.windows.Window.height: 838
browser.windows.Window.top: -7
browser.windows.Window.left: -3079

ESR (102.4.0esr/20221010114559)
24” monitor connected to laptop with no-scaling (100%) 1920x1080
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1040

browser.windows.Window.width: 1936
browser.windows.Window.height: 1056
browser.windows.Window.top: -8
browser.windows.Window.left: -8

15“ Laptop display with scaling (125%) 1920x1080
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1040

browser.windows.Window.width: 1550
browser.windows.Window.height: 838
browser.windows.Window.top: -7
browser.windows.Window.left: -3079

Hmm @Alex, that was not exactly what I was expeciting.
First of all, the browser.windows.Window properties are for current browser-window (via browser.windows.getCurrent()). I didn't include it in my original post, because they looked consistent and correct. And so do yours I think.

Your logs from NIGHTLY and RELEASE confirms the behaviour I see (incorrectly showing physical instead of virtual pixel dimensions). But I'm surprised to see also that behaviour from your ESR. I have to ask if you are absolutely sure this is the results you get from ESR when display-scaling 125%?:
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1040

If true, maybe there's an unknown factor involved here? :-/

I repeated my test on my setup at Work. It confirms my original described behaviour:

Work, Windows 10, Firefox 106
4K Monitor 27" 3840x2160 with display-scaling: 175%
window.screen.width: 3840
window.screen.availWidth: 3840
window.screen.height: 2160
window.screen.availHeight: 2108

Work, Windows 10, Firefox 102 ESR (Waterfox)
4K Monitor 27" 3840x2160 with display-scaling: 175%
window.screen.width: 2176
window.screen.availWidth: 2176
window.screen.height: 1224
window.screen.availHeight: 1195

@Stig Nygaard

Retried the STR several times just to make sure I did not make any mistake on ESR 102.4.0.

I got the same results as before.

On the 15” laptop display with 125% scaling the results are:
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1040

On the 24” monitor connected to the laptop, with no-scaling (100%) the results are:
window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1040

Same as before and same as on Release, Beta and Nightly.

Attached image 2022-11-02_08h51_33.png

Hi @Alex
Thanks for trying again. And sorry for my scepticism regarding your result.

I wonder what values of window.screen properties is "client-side" (javascript on a webpage) on your 125% scaled setup....
Could you try "Try it yourself " buttons on https://www.w3schools.com/js/js_window_screen.asp ?
I always get the "virtual" pixel dimensions from window.screen clientside. But I wonder if you still/also get the actual "physical" dimensions there?

Btw, I'm not 100% sure exactly what version of Firefox ESR my Waterfox is based on. The signature says "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0", so it looks like it might be an older engine-version than your ESR 102.4.0. Maybe that causes the difference...

Hello @Stig
Tried the method you proposed in Comment 7, on the 15” laptop display that has 125% scaling, on Nightly, Release and ESR. This is what I got:

Nightly (108.0a1/20221102174350), 15” laptop display at 125% scaling
Screen width is 1536
Screen height is 864
Available screen width is 1536
Available screen height is 824

Release (106.0.3/20221030091646), 15” laptop display a 125% scaling
Screen width is 1536
Screen height is 864
Available screen width is 1536
Available screen height is 824

ESR (102.4.0esr/20221010114559), 15” laptop display a 125% scaling
Screen width is 1536
Screen height is 864
Available screen width is 1536
Available screen height is 824

So it seems I get the “virtual” pixel dimensions on the 15” display using this method.

On the 24” monitor with no scaling I get the same values as in my previous comments, on all browsers I tested:

Screen width is 1920
Screen height is 1080
Available screen width is 1920
Available screen height is 1040

Thanks a lot @Alex.
I think I will skip looking at my Waterfox because I don't know what exact subversion of ESR 102 it is based on.
Will try to find a way to find run various versions of Firefox 102-106 and Firefox ESR 102.x to find out when problem starts.
I hope the issue is related to browser version, otherwise it becomes so much more complicated I guess ...

Hi again @Alex
If you are not tired of helping me yet, could you re-try your ESR 125% scaling webextension-test on your laptop "standalone" (without the external monitor connected).
I have done some thorough testing with various browser-versions, and I'm pretty sure ESR is not affected by the issue and still returns "virtual pixel dimensions". I strongly suspect that in your laptop-tests, you see the dimensions of your 24" non-scaled external monitor instead of your laptop's scaled display. It might be an issue in my webextension not properly handling multi-monitor setups, but I don't think it is related to this (assumed) browser-bug.

I'll post my findings in a few minutes...

I have now systematically tested with a wider range of browser versions, including some past versions thanks to Firefox Portable Edition distributions. I have tested log-output from attached browserextension (see comment 1) with:

Chrome 107.0.5304.88
Firefox 108.0a1 (2022-11-04) Nightly
Firefox 107.0b9 Developer Ed.
Firefox 106.0.5
Firefox 106.0(.0) Portable Ed.
Firefox 105.0.3 Portable Ed.
Firefox 105.0(.0) Portable Ed.
Firefox 103.0(.0) Portable Ed.
Firefox 102.0.1 Portable Ed.
Firefox ESR 102.4.0 Portable Ed.
Firefox ESR 102.3.0 Portable Ed.

First, all browsers correctly returns the expected "virtual pixel dimension" when window.screen properties are read from a usual "client-side" webpage script. F.ex. via the "Try it yourself" buttons on https://www.w3schools.com/js/js_window_screen.asp

However when reading window.screen properties from a backgroundscript in a webextension, something seems to have changed from Firefox 103.0... ESR102 versions does not seem to be affected according to my tests (See my previous comment to Alex).

Chrome 107.0.5304.88 - ✅ virtual pixel dimensions
Firefox 108.0a1 (2022-11-04) Nightly - ❌ physical pixel dimensions
Firefox 107.0b9 Developer Ed. - ❌ physical pixel dimensions
Firefox 106.0.5 - ❌ physical pixel dimensions
Firefox 106.0(.0) Portable Ed. - ❌ physical pixel dimensions
Firefox 105.0.3 Portable Ed. - ❌ physical pixel dimensions
Firefox 105.0(.0) Portable Ed. - ❌ physical pixel dimensions
Firefox 103.0(.0) Portable Ed. - ❌ physical pixel dimensions
Firefox 102.0.1 Portable Ed. - ✅ virtual pixel dimensions
Firefox ESR 102.4.0 Portable Ed. - ✅ virtual pixel dimensions
Firefox ESR 102.3.0 Portable Ed. - ✅ virtual pixel dimensions

I used Firefox Portable Editions from
https://sourceforge.net/projects/portableapps/files/Mozilla%20Firefox%2C%20Portable%20Ed./

I did my testing on laptop with 15" 1920x1080 display, and display-scaling set to 125%.
So physical pixel-width is 1920, and virtual pixel-width should be 1536.

Summary: (since Firefox 106?) window.screen returns physical dimensions instead of virtual when read from backgroundscript → (since Firefox 103) window.screen returns physical dimensions instead of virtual when read from backgroundscript
Version: Firefox 106 → Firefox 103
Summary: (since Firefox 103) window.screen returns physical dimensions instead of virtual when read from backgroundscript → window.screen returns physical dimensions instead of virtual when read from backgroundscript (high-DPI display issue)

Hey Stig ! No worries, I’ll keep checking until the issue is clarified.

So I re-did the tests on the laptop display with 125% scaling and 1920x1080 resolution with all other external monitors not connected to the laptop, and the results are below:

ESR 125% 1920x1080

window.screen.width: 1536
window.screen.availWidth: 1536
window.screen.height: 864
window.screen.availHeight: 824

RELEASE 125% 1920x1080

window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1030

NIGHTLY 125% 1920x1080

window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1030

And you were right. ESR does not seem to be affected as this time virtual pixel dimensions have been logged to console while on Nightly and Release on the same setup, physical pixel dimensions are returned.

I’ll set this issue to NEW then and mark the affected versions accordingly.

Status: UNCONFIRMED → NEW
Ever confirmed: true
Duplicate of this bug: 1785861

Hey Alex, can you please find a regression window for this?

Flags: needinfo?(acornestean)

Hello,
I ran a bisection spanning Firefox 102 to Firefox 103 and found this:

2022-11-08T09:44:06.921000: DEBUG : Found commit message:
Bug 1773813 - Incorporate OS zoom factor in window sizing calculations. r=tnikkel

In bug 1773342 I made OS text scale factor behave like a full zoom
factor which applies to all pages (including the browser chrome). That's
generally straight forward but it makes some callsites that use unzoomed
CSS coordinates misbehave (or behave correctly accidentally actually in
some other cases).

The main fix here is making
nsIBaseWindow::UnscaledDevicePixelsPerCSSPixel() and
nsIScreen::GetDefaultCSSScaleFactor() account for OS zoom as necessary.
However, I also went through the relevant code and cleaned it up to use
typed units and operations when possible.

The setup means:

  • nsIWidget::GetDefaultScale() doesn't account for OS full zoom.
  • nsIBaseWindow and nsIScreen does.

These are the places where this should matter and stuff can get
confused, but this works surprisingly well for all callers (except one
nsDeviceContext one which we use only for PuppetWidget and we can
remove by falling back to 1.0 like all other widgets until the update
comes).

Differential Revision: https://phabricator.services.mozilla.com/D149033

Pushlog: https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=6aec2c04836d1f850cb3a9286c395a8fbd9c4f25&tochange=33fd5efbb2a8ded2b5639b6ffcf625d8b20cf01a

Flags: needinfo?(acornestean)
Regressed by: 1773813

:emilio, since you are the author of the regressor, bug 1773813, could you take a look? Also, could you set the severity field?

For more information, please visit auto_nag documentation.

Flags: needinfo?(emilio)

That's so weird. I can repro, thanks.

Assignee: nobody → emilio

Ah, I see what's going on. It seems likely caused by this change: https://hg.mozilla.org/integration/autoland/rev/33fd5efbb2a8ded2b5639b6ffcf625d8b20cf01a#l7.31

Before that, when a page has never been shown in any screen, we fell back to the primary screen's scale factor. Which in this case it happened to work, but now we use a scale factor of 1. I think the current code is more correct, if the page hasn't been shown in any screen using a scale factor of 1 seems pretty fair. Before it was working ~by chance...

I believe the main fix for this issue is that the WebExtensions APIs need to convert to physical pixels first using the background page's coordinate system when opening a window...

Yeah, the code was already broken in multi-monitor set-ups when the window you were manipulating isn't in a primary screen.

Tomislav, Rob, do you know how can I hook browser.windows.{create,update} to send the child background page's window.devicePixelRatio? I see the parent side of the extension, but no idea how can I get the child's DPI there...

I can hard-code 1-times-OS-zoom and it'd be correct right now but that's not quite ideal, it'd be great to get it from the child properly.

Flags: needinfo?(tomica)
Flags: needinfo?(rob)
Flags: needinfo?(emilio)

We are in RC week, wontfix 106. Could we get a severity set to this bug to help with regression triage? Thanks

(In reply to Emilio Cobos Álvarez (:emilio) from comment #19)

Yeah, the code was already broken in multi-monitor set-ups when the window you were manipulating isn't in a primary screen.

It would be difficult to fix that situation, unless extensions know which screen they are targeting + the dimensions of those. There was a request for a system.display API before at bug 1738348 (but that namespace is a kitchen sink of lots of functionality, some specific to ChromeOS, so I am not keen on "just" implementing it).

Tomislav, Rob, do you know how can I hook browser.windows.{create,update} to send the child background page's window.devicePixelRatio? I see the parent side of the extension, but no idea how can I get the child's DPI there...

Why do you specifically want to know the "child background page's window.devicePixelRatio"? The background script is not running in any visible location, so it's unclear how the background page's window.devicePixelRatio relates to whatever the user is doing.

For tabs.getCurrent calls from a browser tab, you could get the browser window (ProxyContextParent.xulBrowser) that hosts the tab with context.xulBrowser?.ownerGlobal.devicePixelRatio || 1.

But if any window is as good as any, you could also use windowTracker.topWindow?.devicePixelRatio || 1.

If for some reason you really need window.devicePixelRatio from the child's window (and not the parent), then you would have to add child/ext-windows.js, define the create / update APIs, compute the numbers if you'd like with context.contentWindow.devicePixelRatio, and then call the parent/ext-windows.js side of the implementation, context.childManager.callParentAsyncFunction("windows.create", [createData]). You can see examples of the pattern where the child side preprocesses some data before invoking the parent, at https://searchfox.org/mozilla-central/search?q=callParentAsyncFunction&path=child%2Fext-&case=false&regexp=false.

Flags: needinfo?(tomica)
Flags: needinfo?(rob)

Disclaimer: I have no insight or understanding into the technical implementation and design details discussed in previous comments. Also at least when it comes to handling a multi-display setup, I don't know if there are some specs we are expected to follow or some "Chromium-parity" we strive for. I mean, my comment might not be as relevant as I hope. But still, here it comes...
When building xIFr webextension and the code to control where my "popup window" opens, it felt kind of strange I had to get properties about current browser-window (size and positioning) from a Window-object returned asynchronously (a promise) from browser.windows.getCurrent(), while screen dimensions had to be read directly from the "normal" window.screen object. Would it makes things easier if Window object returned from browser.windows.getCurrent() also included the screen details? In my opinion it would be natural to look for both on same Window object? I remember looking for the screen object on Window returned from browser.windows.getCurrent(), but there's none.

We do need the devicePixelRatio from the child's window. That said, comment 22 (exposing screen size properties for a given window) would make sense to me as well (and allows the multi-monitor use-case to work properly).

Flags: needinfo?(emilio)

To answer more concretely:

(In reply to Rob Wu [:robwu] from comment #21)

Why do you specifically want to know the "child background page's window.devicePixelRatio"? The background script is not running in any visible location, so it's unclear how the background page's window.devicePixelRatio relates to whatever the user is doing.

Well, the CSS pixels that the background page can compute are relative to its own devicePixelRatio. So if the background page's dpi is different from the current page's dpi, then there's a mismatch and the pixels are too big (or too small).

If for some reason you really need window.devicePixelRatio from the child's window (and not the parent), then you would have to add child/ext-windows.js, define the create / update APIs, compute the numbers if you'd like with context.contentWindow.devicePixelRatio, and then call the parent/ext-windows.js side of the implementation, context.childManager.callParentAsyncFunction("windows.create", [createData]). You can see examples of the pattern where the child side preprocesses some data before invoking the parent, at https://searchfox.org/mozilla-central/search?q=callParentAsyncFunction&path=child%2Fext-&case=false&regexp=false.

Thanks, will give that a try.

Rob, probably returning screen values from browser.windows.getCurrent() etc would also be pretty sensible, given the above... Would that make sense?

Flags: needinfo?(rob)

(In reply to Emilio Cobos Álvarez (:emilio) from comment #24)

Rob, probably returning screen values from browser.windows.getCurrent() etc would also be pretty sensible, given the above... Would that make sense?

What do you have in mind as an addition to https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows/Window ? When multiple monitors are supported, it wouldn't be immediately obvious to me what kind of screen information you'd return. Screens may be separate, with different pixel ratios, and not even be aligned at all, so that the whole screen doesn't fit nicely in a rectangle.

And before changing anything, it would be nice to have some consistency within the browser and across browsers. If the units used for width / left / top / height parts of the windows extension API are consistent wih the units of the screen DOM API, then we wouldn't have this bug (nor a need to return extra information from the windows API.

Stig, could you run your tests on Chrome and report the numbers? Then we can compare that with the test results that you have shared before.

Flags: needinfo?(rob)

The Bugbug bot thinks this bug should belong to the 'Core::Widget: Win32' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Widget: Win32
Product: WebExtensions → Core

(In reply to Rob Wu [:robwu] from comment #25)

Stig, could you run your tests on Chrome and report the numbers? Then we can compare that with the test results that you have shared before.

I have already include Chrome 107 in my previous test results?
Or are you asking for some new tests looking specifically at how it handles a multi-display setup (which was never really subject in my tests)?

Meanwhile, that bugbot is wrong, isn't it?:

(In reply to Release mgmt bot [:suhaib / :marco/ :calixte] from comment #26)

The Bugbug bot thinks this bug should belong to the 'Core::Widget: Win32' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Widget: Win32 → General
Product: Core → WebExtensions

(In reply to Stig Nygaard from comment #27)

(In reply to Rob Wu [:robwu] from comment #25)

Stig, could you run your tests on Chrome and report the numbers? Then we can compare that with the test results that you have shared before.

I have already include Chrome 107 in my previous test results?

I looked again and did find my answers in comment 3 + comment 4 together (* more details below). That confirms that the windows extension API uses zoom-adjusted dimensions (virtual pixels). Because screen has started to return the physical dimensions of the screen, regardless of zoom, the result is indeed as reported: misplaced/oversized screens.

Since the extension APIs are consistent, and the web platform APIs are different, I wonder why we are focusing on patching the extension API. From the point of view of extension developers, code that previously worked (i.e. combining screen.availWidth etc with the windows extension API) started to fail. Here is an example from an extension that I authored that attempts to center a new window https://github.com/Rob--W/open-in-browser/blob/aa056020b8f6b4c90b0067e9e7af68d94562cf4d/extension/dialog.js#L101-L119. The assumption of logic like that is that the extension APIs and screen APIs all use the same unit for the dimensions.

* In comment 4, you wrote "First of all, the browser.windows.Window properties are for current browser-window (via browser.windows.getCurrent()). I didn't include it in my original post, because they looked consistent and correct. And so do yours I think.". After reading this again, I think that this may be offering the answer I was seeking: Your comment consistency between Chrome and Firefox. Combined with Alex's results from comment 3, I suppose that the implication is that the windows extension API across all browsers continue to report the virtual pixels as expected:

RELEASE (106.0.3/20221030091646)
...
15“ Laptop display with scaling (125%) 1920x1080
...
browser.windows.Window.width: 1550
browser.windows.Window.height: 838
browser.windows.Window.top: -7
browser.windows.Window.left: -3079

ESR (102.4.0esr/20221010114559)
...
15“ Laptop display with scaling (125%) 1920x1080
...
browser.windows.Window.width: 1550
browser.windows.Window.height: 838
browser.windows.Window.top: -7
browser.windows.Window.left: -3079

(In reply to Rob Wu [:robwu] from comment #28)

I looked again and did find my answers in comment 3 + comment 4 together (* more details below). That confirms that the windows extension API uses zoom-adjusted dimensions (virtual pixels). Because screen has started to return the physical dimensions of the screen, regardless of zoom, the result is indeed as reported: misplaced/oversized screens.

For the record, this is not correct. screen always returns CSS pixels of the relevant page. The main difference is that the window.devicePixelRatio for web extension background pages before the regressing patch landed was the primary screen's devicePixelRatio. Now it's 1 (plus OS full-zoom really), and the extensions code just doesn't do any coordinate space conversions so stuff gets confused.

I don't think the previous behavior made any sense, specially in multi-monitor situations, since the background page doesn't show in any screen... Another option is just "restore previous behavior somehow by making sure windowless browsers use the DPI of the default screen", but that's also not amazing...

Man, this is a bit confusing.

Please be aware, that I'm just a hobby programmer still learning webextension development, and I don't have a 100% understanding of either webextension or browser/firefox architecture (for the later actually close to none).
I think I understand somehow what you are saying, which means you understand why I made this bug. But just in case, let me re-phrase...

Both Chrome and older versions of Firefox returned what I call "virtual pixel dimensions" (= CSS pixels) from window.screen when read from backgroundscript (similar to what window.screen returns in normal webpage "client" script, for both Chrome and Firefox). But recent versions of Firefox has started to return "physical dimension" when reading properties of window.screen from backgroundscript.

I have never really been sure window.screen always found the right screen in multi-display setup, but in my own practical use I have seen it worked fine, thus multi-display handling was not originally a subject of this bugreport. But it became relevant/involved with Alex's test results that at first didn't comply with mine.

Looking back..
In backgroundscripts, I always thought it was weird I had to get screen properties from another source than the properties for current window, when I in "client script" finds both via the "normal" window object. But I probably just added confusion by bringing browser.windows.getCurrent() into the discussion... It would be nice if just window.screen returned to same behaviour it used to have, and same behaviour it has in Chrome (at least in most cases, not sure about always consistency when multi-display setup). And by that I mean window.screen returning "virtual dimensions".

But in conclusion. The most obvious fix ( = work as it used to) would be to get window.screen to return "virtual pixel dimensions" when read from a backgroundscript. Just as it still does in "frontend" (webpage scripting). And if it didn't handle multi-display setups 100% as one would expect in the old days, I would say it handled it okay for most users. Good enough for me to not investigating time on it at least.

(Another disclaimer: I'm slightly drunk when writing this. I hope it makes sense 😊)

(In reply to Stig Nygaard from comment #30)

I think I understand somehow what you are saying,

Previous comment was meant as a reply to Rob's comment :-)

Both Chrome and older versions of Firefox returned what I call "virtual pixel dimensions" (= CSS pixels) from window.screen when read from backgroundscript (similar to what window.screen returns in normal webpage "client" script, for both Chrome and Firefox). But recent versions of Firefox has started to return "physical dimension" when reading properties of window.screen from backgroundscript.

This is not true. Chrome and Firefox both return CSS pixels for screen APIs. The difference is what the CSS-to-device pixel ratio (window.devicePixelRatio) is on the page.

CSS pixels are specific to a given page (think of e.g. zoom: when you zoom in, the CSS lengths should scale, and all lengths do, except screen coordinates in Chrome because of Chrome bug 1294796). That means that when communicating pixel values across pages, you either need to make sure they have the same CSS-to-device ratio, or convert between them.

Before bug 1773813, the coordinate space of webext background scripts and a browser window in the primary screen happened to match, because we fell back to primary screen DPI instead of 1 for a code-path that happened to be hit for background pages.

Anyways, maybe keeping the fallback is the easiest way to "fix" the regression, but there'd still be a bug in multi-monitor-with-different-dpi setups. Maybe that just is not worth fixing properly. In any case, nobody is challenging that there's a bug, the main discussion is about how to fix it :)

(In reply to Emilio Cobos Álvarez (:emilio) from comment #32)

Both Chrome and older versions of Firefox returned what I call "virtual pixel dimensions" (= CSS pixels) from window.screen when read from backgroundscript (similar to what window.screen returns in normal webpage "client" script, for both Chrome and Firefox). But recent versions of Firefox has started to return "physical dimension" when reading properties of window.screen from backgroundscript.

This is not true. Chrome and Firefox both return CSS pixels for screen APIs. The difference is what the CSS-to-device pixel ratio

I don't understand what you are saying. Maybe I was wrong saying "virtual pixel" equals "CSS pixels" (but in most cases it does?).
As I said, I'm slightly drunk. I promise, next time I look or respond to this bug I'm sober :-)

(but remember, I'm seeing this as an "end-user". I don't know what's happening in the engine)

(In reply to Stig Nygaard from comment #33)

(In reply to Emilio Cobos Álvarez (:emilio) from comment #32)

This is not true. Chrome and Firefox both return CSS pixels for screen APIs. The difference is what the CSS-to-device pixel ratio
I don't understand what you are saying. Maybe I was wrong saying "virtual pixel" equals "CSS pixels" (but in most cases it does?).
As I said, I'm slightly drunk. I promise, next time I look or respond to this bug I'm sober :-)
(but remember, I'm seeing this as an "end-user". I don't know what's happening in the engine)

What I mean, is as an end-user (extension and webpage developer) I want the screen properties to use "same unit" as CSS does when it comes to pixels. When on a system with a 2x (200%) scale factor in display settings for a 4K monitor, a full-width element on a maximized webpage will be 2K wide in CSS pixels. And window.screen.width will/should be 2K too if given in what I call "virtual pixels".
Do we agree?

This restores the previous behavior in a somewhat more principled way.

The extensions code is still broken in multi-monitor cases, but that's a
more complicated fix.

Flags: needinfo?(emilio)

Set release status flags based on info from the regressing bug 1773813

Pushed by ealvarez@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/0f84b85f120f For widget-less pages keep defaulting to primary screen scale factor. r=tnikkel,layout-reviewers,extension-reviewers,robwu
Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 109 Branch

The patch landed in nightly and beta is affected.
:emilio, is this bug important enough to require an uplift?

  • If yes, please nominate the patch for beta approval.
  • If no, please set status-firefox108 to wontfix.

For more information, please visit auto_nag documentation.

Flags: needinfo?(emilio)

Comment on attachment 9303290 [details]
Bug 1798213 - For widget-less pages keep defaulting to primary screen scale factor. r=tnikkel,#layout

Beta/Release Uplift Approval Request

  • User impact if declined: Relatively simple fix.
  • Is this code covered by automated tests?: Yes
  • Has the fix been verified in Nightly?: Yes
  • Needs manual test from QE?: Yes
  • If yes, steps to reproduce: comment 0
  • List of other uplifts needed: none
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Rather targeted fix, includes tests for various edge cases.
  • String changes made/needed: none
  • Is Android affected?: Yes
Flags: needinfo?(emilio)
Attachment #9303290 - Flags: approval-mozilla-beta?
Flags: qe-verify+

Comment on attachment 9303290 [details]
Bug 1798213 - For widget-less pages keep defaulting to primary screen scale factor. r=tnikkel,#layout

Approved for 108.0b3

Attachment #9303290 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Duplicate of this bug: 1787649
Duplicate of this bug: 1343688

Verified as Fixed on the latest Nightly (109.0a1/20221117214129) and Beta (108.0b3/20221117185908). Tested on Windows 10 x64.
These are the results I obtained using the attached extension and provided STR:

Nightly (109.0a1/20221117214129) - 15” laptop display with 125% scaling, 1920x1080 and no external monitors connected

window.screen.width: 1536
window.screen.availWidth: 1536
window.screen.height: 864
window.screen.availHeight: 824

Beta (108.0b3/20221117185908) - 15” laptop display with 125% scaling, 1920x1080 and no external monitors connected

window.screen.width: 1536
window.screen.availWidth: 1536
window.screen.height: 864
window.screen.availHeight: 824

I’ve also tested Release again just to have a comparison. Results are below.

Release (107.0/20221110173214) - 15” laptop display with 125% scaling, 1920x1080 and no external monitors connected

window.screen.width: 1920
window.screen.availWidth: 1920
window.screen.height: 1080
window.screen.availHeight: 1030

The results on Nightly and Beta appear to be the ones that were desired, thus confirming the fix.

Status: RESOLVED → VERIFIED
Flags: qe-verify+

I have also with success verified on both latest nightly and beta 3 (Developer Edition). And it seems to be back to previous behavior, which works perfect for me and I believe in most practical use-cases.

Regarding the issue found for multi-display setups, I might create a new bug on that. But for now very happy with fix of this issue. It is a pleasure to report an issue when response and fixing happens this fast. Thanks! 😊

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: