Dai
Dai

Reputation: 155270

window.screenX and window.screen.availLeft both 0 in Chrome Extension

I'm writing a Chrome extension that is meant to resize and reposition the current window when my button is clicked, it is meant to reposition the window on the current monitor that the window is displayed on. It is meant to make the current Chrome window fill the current monitor but without being maximized.

Here's my code:

function start(tab) {
    // Type: `(tab: tabs.Tab): void`
    // `tabs.Tab`: https://developer.chrome.com/extensions/tabs#type-Tab

    chrome.windows.getCurrent( getCurrentWindowCallback );
}

function getCurrentWindowCallback( currentWindow ) {
    // Type: `(window: Window): void`
    // `Window`: https://developer.chrome.com/extensions/windows#type-Window

    if( !'id' in currentWindow ) return;

    var s = window.screen;

    var newState = {
        left: s.availLeft,
        top: s.availTop,
        width: s.width,
        height: s.availHeight,
        state: "normal"
    };

    chrome.windows.update(
        /*windowId:*/ currentWindow.id,
        /*updateInfo: */ newState,
        /*callback: */ null
    );
}

chrome.browserAction.onClicked.addListener( start );

However, when I run this the value of window.screen always corresponds to the first monitor on my computer, regardless of the screen that the current Chrome browser window is on.

{ availLeft: 0, availTop: 0, width: 1920, availHeight: 1170 }

The currentWindow object is a special Chrome extension API object and does not share the screen property that the global window object does. I suspect this is because the window refers to the hidden window that the Background Script executes in.

Is it possible to get the screen object for the current Chrome browser window without needing permission/access to the DOM?

Upvotes: 2

Views: 1709

Answers (1)

Dai
Dai

Reputation: 155270

I worked-around this problem by using chrome.tabs.executeScript to run a script which copies the window.screen object from the current window and passing it back to my script to reposition and resize the window:

var getScreenScript = `var screenInfo = {
    screen: {
        availTop   : window.screen.availTop,
        availLeft  : window.screen.availLeft,
        availHeight: window.screen.availHeight,
        availWidth : window.screen.availWidth,
        colorDepth : window.screen.colorDepth,
        height     : window.screen.height,
        left       : window.screen.left,
        orientation: window.screen.orientation,
        pixelDepth : window.screen.pixelDepth,
        top        : window.screen.top,
        width      : window.screen.width
    },
    screenX   : window.screenX,
    screenY   : window.screenY,
    screenLeft: window.screenLeft,
    screenTop : window.screenTop,
}; screenInfo`;

function start(tab) {
    // Type: `(tab: tabs.Tab): void`
    // `tabs.Tab`: https://developer.chrome.com/extensions/tabs#type-Tab

    if( !'id' in tab ) return;

    // Ensure the `tabId` is set, otherwise I got permissions errors.
    chrome.tabs.executeScript( /*tabId:*/ tab.id, { code: getScreenScript }, getScreenScriptResultCallback );
}

function getScreenScriptResultCallback( args ) {

    var screenInfo = args[0];

    chrome.windows.getCurrent( function(currentWindow) {

        if( !'id' in currentWindow ) return;

        transformWindow( currentWindow, screenInfo );
    } );
}

function transformWindow( currentWindow, screenInfo ) {
    // Type: `(currentWindow: Window, screenInfo: object): void`
    // `Window`: https://developer.chrome.com/extensions/windows#type-Window

    var newState = {
        left  : screenInfo.screen.availLeft, // `availLeft` is the X coordinate of the current screen in the multi-mon workspace.
        top   : screenInfo.screen.availTop,
        width : screenInfo.screen.availWidth,
        height: screenInfo.screen.availHeight,
        state: "normal"
    };

    chrome.windows.update( currentWindow.id, newState, /*callback: */ null );
}

chrome.browserAction.onClicked.addListener( start );

Upvotes: 1

Related Questions