Skip to content

Commit 4aac6ba

Browse files
authored
window - fix window state validation to actually apply properly and add more logging (microsoft#205677)
1 parent 73ad7fb commit 4aac6ba

File tree

4 files changed

+45
-17
lines changed

4 files changed

+45
-17
lines changed

src/vs/platform/auxiliaryWindow/electron-main/auxiliaryWindowsMainService.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { AuxiliaryWindow, IAuxiliaryWindow } from 'vs/platform/auxiliaryWindow/e
1212
import { IAuxiliaryWindowsMainService } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows';
1313
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
1414
import { ILogService } from 'vs/platform/log/common/log';
15-
import { IWindowState } from 'vs/platform/window/electron-main/window';
15+
import { IWindowState, defaultAuxWindowState } from 'vs/platform/window/electron-main/window';
1616
import { WindowStateValidator, defaultBrowserWindowOptions, getLastFocused } from 'vs/platform/windows/electron-main/windows';
1717

1818
export class AuxiliaryWindowsMainService extends Disposable implements IAuxiliaryWindowsMainService {
@@ -79,7 +79,7 @@ export class AuxiliaryWindowsMainService extends Disposable implements IAuxiliar
7979
});
8080
}
8181

82-
private validateWindowState(details: HandlerDetails): IWindowState | undefined {
82+
private validateWindowState(details: HandlerDetails): IWindowState {
8383
const windowState: IWindowState = {};
8484

8585
const features = details.features.split(','); // for example: popup=yes,left=270,top=14.5,width=800,height=600
@@ -101,7 +101,11 @@ export class AuxiliaryWindowsMainService extends Disposable implements IAuxiliar
101101
}
102102
}
103103

104-
return WindowStateValidator.validateWindowState(this.logService, windowState);
104+
const state = WindowStateValidator.validateWindowState(this.logService, windowState) ?? defaultAuxWindowState();
105+
106+
this.logService.trace('[aux window] using window state', state);
107+
108+
return state;
105109
}
106110

107111
registerWindow(webContents: WebContents): void {

src/vs/platform/window/electron-main/window.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { BrowserWindow, Rectangle } from 'electron';
6+
import { BrowserWindow, Rectangle, screen } from 'electron';
77
import { CancellationToken } from 'vs/base/common/cancellation';
88
import { Event } from 'vs/base/common/event';
99
import { IDisposable } from 'vs/base/common/lifecycle';
@@ -145,6 +145,30 @@ export const defaultWindowState = function (mode = WindowMode.Normal): IWindowSt
145145
};
146146
};
147147

148+
export const defaultAuxWindowState = function (): IWindowState {
149+
150+
// Auxiliary windows are being created from a `window.open` call
151+
// that sets `windowFeatures` that encode the desired size and
152+
// position of the new window (`top`, `left`).
153+
// In order to truly override this to a good default window state
154+
// we need to set not only width and height but also x and y to
155+
// a good location on the primary display.
156+
157+
const width = 800;
158+
const height = 600;
159+
const workArea = screen.getPrimaryDisplay().workArea;
160+
const x = Math.max(workArea.x + (workArea.width / 2) - (width / 2), 0);
161+
const y = Math.max(workArea.y + (workArea.height / 2) - (height / 2), 0);
162+
163+
return {
164+
x,
165+
y,
166+
width,
167+
height,
168+
mode: WindowMode.Normal
169+
};
170+
};
171+
148172
export const enum WindowMode {
149173
Maximized,
150174
Normal,

src/vs/platform/windows/electron-main/windowImpl.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,6 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
570570
}
571571
});
572572

573-
574573
// Create the browser window
575574
mark('code/willCreateCodeBrowserWindow');
576575
this._win = new BrowserWindow(options);

src/vs/platform/windows/electron-main/windows.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export interface IOpenConfiguration extends IBaseOpenConfiguration {
115115

116116
export interface IOpenEmptyConfiguration extends IBaseOpenConfiguration { }
117117

118-
export function defaultBrowserWindowOptions(accessor: ServicesAccessor, windowState?: IWindowState, overrides?: BrowserWindowConstructorOptions): BrowserWindowConstructorOptions & { experimentalDarkMode: boolean } {
118+
export function defaultBrowserWindowOptions(accessor: ServicesAccessor, windowState: IWindowState, overrides?: BrowserWindowConstructorOptions): BrowserWindowConstructorOptions & { experimentalDarkMode: boolean } {
119119
const themeMainService = accessor.get(IThemeMainService);
120120
const productService = accessor.get(IProductService);
121121
const configurationService = accessor.get(IConfigurationService);
@@ -129,10 +129,14 @@ export function defaultBrowserWindowOptions(accessor: ServicesAccessor, windowSt
129129
minHeight: WindowMinimumSize.HEIGHT,
130130
title: productService.nameLong,
131131
...overrides,
132+
x: windowState.x,
133+
y: windowState.y,
134+
width: windowState.width,
135+
height: windowState.height,
132136
webPreferences: {
133137
enableWebSQL: false,
134138
spellcheck: false,
135-
zoomFactor: zoomLevelToZoomFactor(windowState?.zoomLevel ?? windowSettings?.zoomLevel),
139+
zoomFactor: zoomLevelToZoomFactor(windowState.zoomLevel ?? windowSettings?.zoomLevel),
136140
autoplayPolicy: 'user-gesture-required',
137141
// Enable experimental css highlight api https://chromestatus.com/feature/5436441440026624
138142
// Refs https://github.com/microsoft/vscode/issues/140098
@@ -143,13 +147,6 @@ export function defaultBrowserWindowOptions(accessor: ServicesAccessor, windowSt
143147
experimentalDarkMode: true
144148
};
145149

146-
if (windowState) {
147-
options.x = windowState.x;
148-
options.y = windowState.y;
149-
options.width = windowState.width;
150-
options.height = windowState.height;
151-
}
152-
153150
if (isLinux) {
154151
options.icon = join(environmentMainService.appRoot, 'resources/linux/code.png'); // always on Linux
155152
} else if (isWindows && !environmentMainService.isBuilt) {
@@ -246,8 +243,9 @@ export namespace WindowStateValidator {
246243
// some pixels (128) visible on the screen for the user to drag it back.
247244
if (displays.length === 1) {
248245
const displayWorkingArea = getWorkingArea(displays[0]);
246+
logService.trace('window#validateWindowState: single monitor working area', displayWorkingArea);
247+
249248
if (displayWorkingArea) {
250-
logService.trace('window#validateWindowState: 1 monitor working area', displayWorkingArea);
251249

252250
function ensureStateInDisplayWorkingArea(): void {
253251
if (!state || typeof state.x !== 'number' || typeof state.y !== 'number' || !displayWorkingArea) {
@@ -320,10 +318,13 @@ export namespace WindowStateValidator {
320318
try {
321319
display = screen.getDisplayMatching({ x: state.x, y: state.y, width: state.width, height: state.height });
322320
displayWorkingArea = getWorkingArea(display);
321+
322+
logService.trace('window#validateWindowState: multi-monitor working area', displayWorkingArea);
323323
} catch (error) {
324324
// Electron has weird conditions under which it throws errors
325325
// e.g. https://github.com/microsoft/vscode/issues/100334 when
326326
// large numbers are passed in
327+
logService.error('window#validateWindowState: error finding display for window state', error);
327328
}
328329

329330
if (
@@ -334,11 +335,11 @@ export namespace WindowStateValidator {
334335
state.x < displayWorkingArea.x + displayWorkingArea.width && // prevent window from falling out of the screen to the right
335336
state.y < displayWorkingArea.y + displayWorkingArea.height // prevent window from falling out of the screen to the bottom
336337
) {
337-
logService.trace('window#validateWindowState: multi-monitor working area', displayWorkingArea);
338-
339338
return state;
340339
}
341340

341+
logService.trace('window#validateWindowState: state is outside of the multi-monitor working area');
342+
342343
return undefined;
343344
}
344345

0 commit comments

Comments
 (0)