mirror of
https://github.com/bitwarden/clients.git
synced 2026-07-04 21:05:54 +08:00
[PM-24289] fix popout windows on wayland (browser) (#15825)
Co-authored-by: Derek Nance <dnance@bitwarden.com>
This commit is contained in:
parent
d5177bae5d
commit
086c625762
@ -149,6 +149,9 @@ describe("BrowserPopupUtils", () => {
|
||||
incognito: false,
|
||||
width: PopupWidthOptions.default,
|
||||
});
|
||||
jest.spyOn(BrowserApi, "getPlatformInfo").mockResolvedValue({
|
||||
os: "win",
|
||||
} as chrome.runtime.PlatformInfo);
|
||||
jest.spyOn(BrowserApi, "createWindow").mockImplementation();
|
||||
});
|
||||
|
||||
@ -267,6 +270,54 @@ describe("BrowserPopupUtils", () => {
|
||||
url: `chrome-extension://id/${url}?uilocation=popout&singleActionPopout=123`,
|
||||
});
|
||||
});
|
||||
|
||||
it("omits position when on Linux with Wayland-like coordinates (left=0, top=0)", async () => {
|
||||
const url = "popup/index.html";
|
||||
jest.spyOn(BrowserApi, "getWindow").mockReset().mockResolvedValueOnce({
|
||||
id: 2,
|
||||
left: 0,
|
||||
top: 0,
|
||||
focused: false,
|
||||
alwaysOnTop: false,
|
||||
incognito: false,
|
||||
width: PopupWidthOptions.default,
|
||||
});
|
||||
jest.spyOn(BrowserApi, "getPlatformInfo").mockResolvedValue({
|
||||
os: "linux",
|
||||
} as chrome.runtime.PlatformInfo);
|
||||
jest.spyOn(BrowserPopupUtils as any, "isSingleActionPopoutOpen").mockResolvedValueOnce(false);
|
||||
|
||||
await BrowserPopupUtils.openPopout(url);
|
||||
|
||||
expect(BrowserApi.createWindow).toHaveBeenCalledWith({
|
||||
type: "popup",
|
||||
focused: true,
|
||||
width: PopupWidthOptions.default,
|
||||
height: 630,
|
||||
url: `chrome-extension://id/${url}?uilocation=popout`,
|
||||
});
|
||||
});
|
||||
|
||||
it("includes position when on Linux with non-zero window coordinates", async () => {
|
||||
const url = "popup/index.html";
|
||||
// Uses the beforeEach window (left: 100, top: 100) — non-zero, so not Wayland-like.
|
||||
jest.spyOn(BrowserApi, "getPlatformInfo").mockResolvedValue({
|
||||
os: "linux",
|
||||
} as chrome.runtime.PlatformInfo);
|
||||
jest.spyOn(BrowserPopupUtils as any, "isSingleActionPopoutOpen").mockResolvedValueOnce(false);
|
||||
|
||||
await BrowserPopupUtils.openPopout(url);
|
||||
|
||||
expect(BrowserApi.createWindow).toHaveBeenCalledWith({
|
||||
type: "popup",
|
||||
focused: true,
|
||||
width: PopupWidthOptions.default,
|
||||
height: 630,
|
||||
left: 85,
|
||||
top: 190,
|
||||
url: `chrome-extension://id/${url}?uilocation=popout`,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("openCurrentPagePopout", () => {
|
||||
|
||||
@ -150,10 +150,25 @@ export default class BrowserPopupUtils {
|
||||
const offsetTop = 90;
|
||||
const popupWidth = defaultPopoutWindowOptions.width;
|
||||
const senderWindow = await BrowserApi.getWindow(senderWindowId);
|
||||
|
||||
// On Wayland, browser window coordinates are not being precisely reported. This is
|
||||
// particularly troublesome for multi-monitor configurations, where the popup can be placed
|
||||
// far enough outside the visible area that the browser refuses to create the window and emits
|
||||
// an error: Invalid value for bounds. Bounds must be at least 50% within visible screen space.
|
||||
// It is acceptable that this heuristic may fire for X11 sessions.
|
||||
const operatingSystemIsLinux = (await BrowserApi.getPlatformInfo()).os === "linux";
|
||||
const coordsMaybeNotPrecise = senderWindow.left === 0 && senderWindow.top === 0;
|
||||
const canPositionWindow = !(operatingSystemIsLinux && coordsMaybeNotPrecise);
|
||||
const positionOptions = canPositionWindow
|
||||
? {
|
||||
left: senderWindow.left + senderWindow.width - popupWidth - offsetRight,
|
||||
top: senderWindow.top + offsetTop,
|
||||
}
|
||||
: {};
|
||||
|
||||
const popoutWindowOptions = {
|
||||
left: senderWindow.left + senderWindow.width - popupWidth - offsetRight,
|
||||
top: senderWindow.top + offsetTop,
|
||||
...defaultPopoutWindowOptions,
|
||||
...positionOptions,
|
||||
...windowOptions,
|
||||
url: BrowserPopupUtils.buildPopoutUrl(extensionUrlPath, singleActionKey),
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user