Fix settings window disappearing on macOS when dragged to another monitor (#3006)

* Fix settings window disappearing on macOS when dragged to another monitor

* Force other windows to show on the same screen as the main window when created

* Try to center the window relative to the main window

* Fix test
This commit is contained in:
Devin Binnie
2024-04-15 17:15:18 -04:00
committed by GitHub
parent 4fc768c1ba
commit d2414c286f
4 changed files with 70 additions and 21 deletions

View File

@@ -50,7 +50,11 @@ export function handleAppBrowserWindowCreated(event: Event, newWindow: BrowserWi
log.debug('handleAppBrowserWindowCreated');
// Screen cannot be required before app is ready
resizeScreen(newWindow);
if (app.isReady()) {
resizeScreen(newWindow);
} else {
newWindow.once('restore', () => resizeScreen(newWindow));
}
}
export function handleAppWillFinishLaunching() {

View File

@@ -7,6 +7,7 @@ import {dialog, screen} from 'electron';
import JsonFileManager from 'common/JsonFileManager';
import {updatePaths} from 'main/constants';
import MainWindow from 'main/windows/mainWindow';
import {getDeeplinkingURL, resizeScreen, migrateMacAppStore} from './utils';
@@ -52,7 +53,10 @@ jest.mock('main/menus/app', () => ({}));
jest.mock('main/menus/tray', () => ({}));
jest.mock('main/tray/tray', () => ({}));
jest.mock('main/views/viewManager', () => ({}));
jest.mock('main/windows/mainWindow', () => ({}));
jest.mock('main/windows/mainWindow', () => ({
get: jest.fn(),
getSize: jest.fn(),
}));
jest.mock('./initialize', () => ({
mainProtocol: 'mattermost',
@@ -130,6 +134,38 @@ describe('main/app/utils', () => {
expect(browserWindow.setPosition).not.toHaveBeenCalled();
expect(browserWindow.center).toHaveBeenCalled();
});
it('should snap to main window if it exists', () => {
MainWindow.get.mockReturnValue({
getPosition: () => [450, 350],
getSize: () => [1280, 720],
});
const browserWindow = {
getPosition: () => [500, 400],
getSize: () => [1280, 720],
setPosition: jest.fn(),
center: jest.fn(),
once: jest.fn(),
};
resizeScreen(browserWindow);
expect(browserWindow.setPosition).toHaveBeenCalledWith(450, 350);
});
it('should snap to the middle of the main window', () => {
MainWindow.get.mockReturnValue({
getPosition: () => [450, 350],
getSize: () => [1280, 720],
});
const browserWindow = {
getPosition: () => [500, 400],
getSize: () => [800, 600],
setPosition: jest.fn(),
center: jest.fn(),
once: jest.fn(),
};
resizeScreen(browserWindow);
expect(browserWindow.setPosition).toHaveBeenCalledWith(690, 410);
});
});
describe('migrateMacAppStore', () => {

View File

@@ -144,26 +144,36 @@ function getValidWindowPosition(state: Rectangle) {
return {x: state.x, y: state.y};
}
export function resizeScreen(browserWindow: BrowserWindow) {
function handle() {
log.debug('resizeScreen.handle');
const position = browserWindow.getPosition();
const size = browserWindow.getSize();
const validPosition = getValidWindowPosition({
x: position[0],
y: position[1],
width: size[0],
height: size[1],
});
if (typeof validPosition.x !== 'undefined' || typeof validPosition.y !== 'undefined') {
browserWindow.setPosition(validPosition.x || 0, validPosition.y || 0);
} else {
browserWindow.center();
}
function getNewWindowPosition(browserWindow: BrowserWindow) {
const mainWindow = MainWindow.get();
if (!mainWindow) {
return browserWindow.getPosition();
}
browserWindow.once('restore', handle);
handle();
const newWindowSize = browserWindow.getSize();
const mainWindowSize = mainWindow.getSize();
const mainWindowPosition = mainWindow.getPosition();
return [
mainWindowPosition[0] + ((mainWindowSize[0] - newWindowSize[0]) / 2),
mainWindowPosition[1] + ((mainWindowSize[1] - newWindowSize[1]) / 2),
];
}
export function resizeScreen(browserWindow: BrowserWindow) {
const position = getNewWindowPosition(browserWindow);
const size = browserWindow.getSize();
const validPosition = getValidWindowPosition({
x: position[0],
y: position[1],
width: size[0],
height: size[1],
});
if (typeof validPosition.x !== 'undefined' || typeof validPosition.y !== 'undefined') {
browserWindow.setPosition(validPosition.x || 0, validPosition.y || 0);
} else {
browserWindow.center();
}
}
export function flushCookiesStore() {

View File

@@ -46,7 +46,6 @@ export class SettingsWindow {
const preload = getLocalPreload('internalAPI.js');
const spellcheck = (typeof Config.useSpellChecker === 'undefined' ? true : Config.useSpellChecker);
this.win = new BrowserWindow({
parent: mainWindow,
title: 'Desktop App Settings',
fullscreen: false,
webPreferences: {