Getting the screen resolution from a background script


(Ariel) #1

Hi, is there a way to get the screen resolution of a tab or window from a background script, something like

browser.tabs.query({}).then(function(tabs){
    for (let tab of tabs) {
             // get the *screen* resolution with tab.id or with tab.windowId
        }
    }
}, () => {});

(Niklas Gollenstede) #2

What’s “the resolution of a tab”?
The tab objects have a .height and .width property, which are “The height [/width] of the tab in pixels.” (whatever that includes).
The same goes for windows (but the documentation is more precise here).


(Ariel) #3

I knew about the height and width of the tab/window but I’m looking for the screen resolution, is there a way to obtain it?

Edit: What I meant by the resolution of the tab, is the resolution of the monitor where a tab/window is currently on.


(Niklas Gollenstede) #4

Yes. just window.screen (in the background page) will give you an object with the dimensions of the primary display, of which .height and .width are useful.
I don’t think you can get more than that (at least not easily). Lats I checked devicePixelRatio was always 1 in the background page.

Edit: The tabs Window has a top and a left property, which are offsets from the top left corner of the primary display. Using these and the dimensions of the tab and the primary display, you can at least figure out whether a tab is displayed on the primary monitor.


(Ariel) #5

Cool thanks, something to investigate.


(Juraj Masiar) #6

I was facing the same problem so I implemented script that will inject file with this code:

[window.screen.availWidth, window.screen.availHeight - (Math.max(window.outerHeight - window.innerHeight, 0) || 78)];

into one tab in every opened window:

async function extractResolutions() {
  const windows = await browser.windows.getAll({populate: true, windowTypes: [browser.windows.WindowType.NORMAL]});
  const tabs = flatten(windows.map(win => win.tabs.find(tab => !tab.discarded && tab.url.startsWith('http')))).filter(x => x);
  return await Promise.all(tabs.map(tab => browser.tabs.executeScript(tab.id, {allFrames: false, file: 'cs_screen_size.js', runAt: 'document_start'}).then(([x]) => x).catch(() => false)).filter(x => x));
}

const flatten = arrayOfArrays => Array.prototype.concat.apply([], arrayOfArrays);

Note that:

  1. browser.tabs.executeScript returns value of last statement in your content script (in this case array [width, height]
  2. only NORMAL windows and http(s) pages are used, because you cannot inject script into pages like about:
  3. you may need to tweak the script - there is a magic number 78 that should represent default browser toolbar size
  4. it returns array of tuples, for example: [[1920, 1079], [2560, 1319]]

(Ariel) #7

Great, thanks for the snippet.


(jscher2000) #8

As a footnote, reported screen.width and screen.height are affected by the zoom level. See:

https://www.jeffersonscher.com/res/resolution.php

(Not sure why window.outerWidth exceeds window.innerWidth on a maximized window. I didn’t notice that when I created the page…)