window.open() on a multi-monitor/dual-monitor system - where does window pop up?
Asked Answered
U

8

50

When using javascript window.open() on a multi-monitor system, how do you control which monitor, or where in the display space the popup opens? It seems out of control to me and otherwise random in it's behavior.

Unimpeachable answered 3/5, 2013 at 16:22 Comment(2)
None of the answers below is answering the "how do you control which monitor" part of the question properly. see e.g. missing answer for webmasters.stackexchange.com/questions/103269/…Quadruplex
see https://mcmap.net/q/355856/-what-needs-to-be-done-to-make-multiple-screen-support-for-javascript-happen for an alternative approach to open full screen on a specific monitor.Quadruplex
G
26

Result of "window.open dual-screen" search revealed this fancy nugget: Dual Monitors and Window.open

"When the user clicks on a link that opens a new window using window.open. Make the window appear on the same monitor as its' parent."

// Find Left Boundry of the Screen/Monitor
function FindLeftScreenBoundry()
{
    // Check if the window is off the primary monitor in a positive axis
    // X,Y                  X,Y                    S = Screen, W = Window
    // 0,0  ----------   1280,0  ----------
    //     |          |         |  ---     |
    //     |          |         | | W |    |
    //     |        S |         |  ---   S |
    //      ----------           ----------
    if (window.leftWindowBoundry() > window.screen.width)
    {
        return window.leftWindowBoundry() - (window.leftWindowBoundry() - window.screen.width);
    }

    // Check if the window is off the primary monitor in a negative axis
    // X,Y                  X,Y                    S = Screen, W = Window
    // 0,0  ----------  -1280,0  ----------
    //     |          |         |  ---     |
    //     |          |         | | W |    |
    //     |        S |         |  ---   S |
    //      ----------           ----------
    // This only works in Firefox at the moment due to a bug in Internet Explorer opening new windows into a negative axis
    // However, you can move opened windows into a negative axis as a workaround
    if (window.leftWindowBoundry() < 0 && window.leftWindowBoundry() > (window.screen.width * -1))
    {
        return (window.screen.width * -1);
    }

    // If neither of the above, the monitor is on the primary monitor whose's screen X should be 0
    return 0;
}

window.leftScreenBoundry = FindLeftScreenBoundry;

Now that the code is written, you can now use window.open to open a window on the monitor the parent window is on.

window.open(thePage, 'windowName', 'resizable=1, scrollbars=1, fullscreen=0, height=200, width=650, screenX=' + window.leftScreenBoundry() + ' , left=' + window.leftScreenBoundry() + ', toolbar=0, menubar=0, status=1');

If it successfully allows you to open a popup on the same screen as the document launching it, then with similar effort one should be able to modify it to behave differently.

Note that, as the length of code implies, there is no built-in function for understanding multiple monitors in jquery/javascript/browsers, only that the dual-screen desktop is simply an enlarged single cartesian plane instead of two discrete planes.

Update

The link is dead. Use this waybackmachine link

Glyptography answered 3/5, 2013 at 16:43 Comment(3)
Your code is returnign 'window.leftWindowBoundry is not a function'. I am trying in chrome 63.0.3239.132.Subaquatic
Read the document at the wayback link he posted.Escobedo
This is all very fancy, and I like it. But why not just use window.screenX?Brewton
M
23

window.screenX will give the position of the current monitor screen.

suppose monitor width is 1360

for monitor 1 window.screenX = 0;

for monitor 2 window.screenX = 1360;

so by adding left position with window.screenX, popup open in expected position.

function openWindow() {

    var width = 650;
    var left = 200;

    left += window.screenX;

    window.open(thePage,'windowName','resizable=1,scrollbars=1,fullscreen=0,height=200,width=' + width + '  , left=' + left + ', toolbar=0, menubar=0,status=1');    
    return 0;

}
Mob answered 29/4, 2014 at 13:10 Comment(6)
I am trying to solve placing popup on another monitor using this technique. It's working as expected in firefox and IE. But in chrome, its not working. Its placing popup on right edge of the window. Any idea?Horsehide
@RumitParakhiya have you get any solution ? i got same issue it's working on firefox but not in chromeVial
@Heroic: Nope, didn't get any solution for Chrome. The solution mentioned in the answer works on FF, but Chrome doesn't allow to place popups this way, because of security. I came through an official Chrome thread at that time confirming this. The url isn't handy at this time.Horsehide
Wouldn't screenX for monitor 2 be 1361?Bellows
Worked for me on latest chromium.Fledgy
worked on latest chromium...and FFManhood
M
10

FUNCTION:

function PopupCenter(url, title, w, h, opts) {
   var _innerOpts = '';
   if(opts !== null && typeof opts === 'object' ){
       for (var p in opts ) {
           if (opts.hasOwnProperty(p)) {
               _innerOpts += p + '=' + opts[p] + ',';
           }
       }
   }
     // Fixes dual-screen position, Most browsers, Firefox
   var dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : screen.left;
   var dualScreenTop = window.screenTop != undefined ? window.screenTop : screen.top;

   var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
   var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;

   var left = ((width / 2) - (w / 2)) + dualScreenLeft;
   var top = ((height / 2) - (h / 2)) + dualScreenTop;
   var newWindow = window.open(url, title, _innerOpts + ' width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);

// Puts focus on the newWindow
   if (window.focus) {
       newWindow.focus();
   }
}

USAGE:

PopupCenter('http://www.google.com','google.com','900','500', {toolbar:1, resizable:1, location:1, menubar:1, status:1}); 

It will also work on minimized windows

Moten answered 27/5, 2015 at 16:57 Comment(6)
This worked great! I wanted top left corner though, so I just exaggerated what the the first width and height is divided with, then divided the second one (w and h) with 1. Never understood what the function of 'google.com' was in the usage, but discovered that it could be anything, as long as it was anything.Quietus
@drymoon do you know why this opens each link in the same window instead of a new one? Really annoying /:Quietus
Seems it's only for links with the same core URL.Quietus
@drymoon The second parameter of window.open() is called windowName. This won't be used as the display title of the window, instead works the way like the target attribute of eg. <a> elements. (See developer.mozilla.org/en-US/docs/Web/API/Window/open) If it is set to _blank (or call PopupCenter with '_blank' on the second parameter, a new window will be opened always.Scud
@Moten for me this is always opening the window on the same screen. How I can open it on other screen?Wahlstrom
see also #4068873Pascasia
M
2

None of the above solutions are works correctly. in terms of exact Center,

I tried this , It works fine for me in chrome and firefox

var sY = screenY;
        if (sY < 0) {
            sY = 0;
        }
        var totalScreenWidth = (screenX + window.outerWidth + sY);
        if (totalScreenWidth > screen.width) {
            totalScreenWidth = totalScreenWidth / 2;
        } else {
            totalScreenWidth = 0;
        }
        windowobj.moveTo(totalScreenWidth + ((screen.width - h) / 2), ((screen.height - h) / 2));

But this also have issue if the second monitors browser is viewed half in first and another half in second.

Mert answered 17/5, 2016 at 13:57 Comment(0)
R
2

screen.isExtended is true if there are one or more additional displays.

window.getScreenDetails returns an object including an array of screens, with dimensions and position. The left value for your non-primary screen would be what to target to move a new window to that screen.

const doSetup = async () => {
  const screenDetails = await window.getScreenDetails()
  if (screen.isExtended && screenDetails.screens.length > 1) {
    const newChildWindow = window.open(
      url,
      'New Child Window',
      `popup,width=${800},height=${600},left=0,top=0`
    )
    newChildWindow.moveTo(screenDetails.screens[1].left, 0)
  }
}

Very thorough explanation here: https://web.dev/multi-screen-window-placement/

Richmal answered 21/6, 2022 at 20:56 Comment(0)
B
1

A javascript-based solution does not work because of security reasons.

I have another idea for you, why not use a chrome extension for handling the positioning. (no security problem there) It is of course, only for chrome(maybe thats fine for you).

Background: We had related difficulties. Internal webapp that opens multiple documents in windows, and need to be placed in other monitors. The javascript does not support this, for security reasons and only a native extension can properly work with the tabs/windows objects.

Therefore, we have created an open source chrome extension for doing exactly that: flexible windows position across multi-monitor setups.

In your case you could easily define a rule per monitor where and how it would appear. You can do it in the options page of the chrome extension. (as shorcut you can, after installation, go directly there using)

The chrome extension is called "MultiWindow Positioner" and its complete free. You can get it at the chrome store here

The actual source code you find in github in the project chrome-multiwindow-positioner

Disclaimer: I am the maintainer of the open source (MIT) github project. If there any interesting idea, or comments feel free to share them here.

UPDATE 21/09/2020 I'm no longer maintainer of the open source project as I left that company. That said, I don't understand the downvotes, the browsers do not provide window.APIs that allow you to cleary understand multiple monitors because its a clear security restriction/violation. Thats where browser plugin extensions help, as they are not a webpage they get access to additional APIs that allow exactly to find/list monitors and windows. They follow a different security context, and therefore the additional power. Not all browsers offer the require extension.APIs for mutlmonitor support. Mozilla Firefox mostly does not. Chrome and latest MS Edge yes. After so many years of experience, I'm still 100% there is NO plain javascript solution, and the only way is a solution that involves a browser plugin/extension.

Belongings answered 23/11, 2016 at 15:50 Comment(3)
“why not use a chrome extension”... Well, because asking random visitors of our website to install an extension just to position a popup doesn't sound ideal.Agminate
yes, in that sense, that won't do. It is actually a gray zone. Browers-based applications that require more and more features that want to go the scope of the browser tab, while the browser has to protect the users from security issues. Its a contradiction.Belongings
And, from personal experience, I can give feedback that a lot of people in the company I work for, cannot live anymore without this extension. It really makes the life a lot easier for power users of browser-based applications as well as developers. I got requests to port it to other browsers, but its not possible as the FF or IE do not have the required interfaces :(Belongings
T
0
/**
 * Display popup window in the center of the screen.
 */
function popupWindow(url, title, w, h) {
  // Use window.screenX to center the window horizontally on multi-monitor 
  // setup. 
  var left = window.screenX + (screen.width / 2) - (w / 2);
  var top = (screen.height / 2) - (h / 2);
  return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
},
Tripod answered 14/9, 2014 at 5:41 Comment(0)
V
0

Here is a solution:

function openWindow( url, winnm, options)
{
    var wLeft = parseInt( typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft );

    var left = 0;

    if( (result = /left=(\d+)/g.exec(options)) ) {
        left = parseInt(result[1]);
    }

    if(options)
    {
       options = options.replace("left="+left,"left="+(parseInt(left) + wLeft));        
       w = window.open( url, winnm, options );
    }
    else
    {
       w = window.open( url, winnm );
    }

    if(w)
         w.focus();

    return w;
}

You just need to replace in your js files: window.open to openWindow

Virgulate answered 24/11, 2019 at 18:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.