Reputation: 106
I am developing browser add-ons for Firefox, Chrome and IE. On click on add-on to open add-on's popup, the popup overflows the browser's window to the right monitor. This bug does not appear when only using one monitor.
Is there a way to tell a browser to ignore multi-monitors? Or is there some one way to solve this problem?
This bug appears on Firefox and Chrome. Possibly on IE too, but there is currently no way to test/debug IE here.
Thanks in advance!
EDIT:
EDIT 2:
Here is the working example:
Upvotes: 0
Views: 264
Reputation: 33356
General comments regarding application level vs system level User interface policies:
This is a system UI issue, not specific to any application (e.g. the browser). The operating system is treating the monitors as one large display area. This is indicated because you can have a single window spanning the two displays instead of the OS user-interface being such that all windows have to jump from fully in one physical display to fully in the other physical display.
There is no direct, platform-agnostic way to do this in a browser extension. While it may be possible to use/develop an OS specific low-level interface that exposes this information to the browser add-on/extension, it probably should not be done unless your extension is specifically intended to dramatically change the look-and-feel of how the user interacts with the system just for the browser.
The reason it should not be done is that doing so would violate the system-level user-interface expectations of the user. It is, generally, a bad idea for a piece of code that exists at one level of a user interface hierarchy to specifically violate the policies (look-and-feel) which have been established at a higher level. In this instance, it would be that at the application level (the browser) you would be violating the look-and-feel established on a system level for use across all applications. While there are reasons to do this, it is generally something which should not be done, unless it is the specific purpose of the code to change the user interface for the application to be something different than that established by the user for the system. This is so even if the user did not specifically know they were setting/establishing the system-level policy, or even if they do not normally have the ability to set that policy.
Now it may be that at a system level the user has specified that popups (windows, menus, etc.) should be created on the display from which they were initiated, or be forced onto one display, or the other. If it is set such that the popup is supposed to be opened on the display on which it is initiated, then the screenshot you provided it showing correct operation. In other words, it appears to be functioning exactly how it is supposed to be functioning.
Basically, this is a system-level user-interface choice. It is not something that should, generally, be addressed by a browser add-on/extension, unless that is the specific purpose of the add-on/extension.
If it is something that the user desires to change, it is much more appropriately done at the system level, or with a system-level application which specifically provides this capability on a per window/application basis.
Restating the problem so we can have an acceptable solution:
The problem that you are wanting to solve is not "How do I override the OS' choice of where to open my window?" That may, or may not be a solvable problem. You may, or may not, be able to get the OS/browser to open the window where you want it. You may, or may not, be able to have the popup open at the coordinates on the screen which you specify. You have not provided any code, so we have no idea what you have already tried. In a Firefox extension you can take control of where the popup opens by manually opening the popup and specifying the location where it should open (more below).
However, the problem you are really trying to solve is: "How do I make it appear to the user that my window opened at the location which I have chosen? Thus, even if you are unable to get the OS/Browser to obey the coordinates you manually provide, you can move the popup to the location you desire either immediately upon the load event firing, or after a very short timer has expired. This will cause the window to be moved to the position you desire prior to the human user being able to perceive that it was not actually opened at the location where you eventually want it to be.
In one extension, I have one menu which is opened from any of multiple buttons. There is no real difference in what is displayed in the popup, only in what and how it affects things (it affects the element from which it was opened). Usually, you can just use openPopup() and provide a position relative to an anchor element. In my case, I found that failed to open the popup in the desired location regardless of the combination of parameters I tried. So I had to resort to using openPopupAtScreen(). However, this means that I needed to explicitly tell the popup exactly where to appear on the screen. In my case that was relative to another element. Thus, it was necessary to determine the location of the other element first and then compute the offset from that point. In my case it was a bit more complicated in that I wanted this sub-menu to appear appear equally spaced below any other menu (i.e. in what feels to the user as the normal location). Thus it was necessary to determine the offset by finding the difference in position of yet another element. In addition, all of the references you get are relative to the window, while you need to provide a reference relative to the screen. So...
/**
* We want to open menu popup that is shared.
*/
function guiOpenSharedMenu(relativeEl) {
//Get the element for the popup we want to open.
let addPopupEl = document.getElementById('ID-of-shared-menu');
//The two reference elements that are located the same distance apart
// vertically as it is desired that the popup being opened is apart from
// relativeEl.
let addEl = document.getElementById('A--some-sub-menu-one-above-B');
let changeEl = document.getElementById('B--some-sub-menu-one-below-A');
//Get the X,Y coordinate of the browser window. All of the rects are
// relative to the browser window, but a screen-relative position
// is needed.
let winScreenX = window.screenX;
let winScreenY = window.screenY;
//relativeEl is the element passed to this function as the one to
// which this popup is to be positioned relative to.
let rectRelative = relativeEl.getBoundingClientRect()
//addEl and changeEl are known to be positioned relative to each other
// the same distance vertically as this popup is to be positioned relative
// to the relativeEL. This distance is possibly changeable based on any
// user Firefox theme.
// Thus, it must be calculated instead of being hard-coded.
let rectAdd = addEl.getBoundingClientRect()
let rectChange = changeEl.getBoundingClientRect()
//offsetY is the additional vertical offset from one pull-right menu
// to another.
let offsetY = rectChange.bottom - rectAdd.bottom;
let offsetX = 0;
addPopupEl.openPopupAtScreen(rectRelative.right + winScreenX + offsetX,
rectRelative.bottom + winScreenY + offsetY, false);
},
So, that may have appeared to be sidetracking, but it shows the process of how to get the screen absolute position for your popup when what you want is for your popup to be positioned relative to the element within the browser window which is opening it. You can have a popupshown
event (on a basic no-content <menupopup>
) that calls the function to open the popup at the correct location.
In your case, you may just need to let the popup open and then either in a handler for the popupshown
event, or a short timeout after that event, use popup.moveTo()
. Now, you might be able to use that method's ability to have the popup automatically realign with the popup's anchor node. In which case, the discussion of needing to fined the absolute coordinates, is not needed. To use that you would do myPopupElement.moveTo(-1,-1);
.
However, without code from you as to how you have constructed your popup, etc., it is not that beneficial to try to provide a more detailed solution.
Upvotes: 2