11From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2- From:
Jean-Damien Thevenoux <[email protected] >
3- Date: Fri, 21 Nov 2025 18:15:16 +0100
2+ From:
Gaspar Chefdeville <[email protected] >
3+ Date: Wed, 9 Jul 2025 17:25:14 +0200
44Subject: [PATCH] feat: prevent IDE from entering fullscreen if not occupying
55 the entire screen
66
77---
8- src/vs/base/browser/dom.ts | 32 ++++++++++++++++---
9- src/vs/workbench/browser/layout.ts | 5 + --
8+ src/vs/base/browser/dom.ts | 34 ++++++++++++++++---
9+ src/vs/workbench/browser/layout.ts | 19 ++++++--- --
1010 src/vs/workbench/browser/web.main.ts | 2 +-
1111 .../host/browser/browserHostService.ts | 2 +-
12- 4 files changed, 32 insertions(+), 9 deletions(-)
12+ 4 files changed, 41 insertions(+), 16 deletions(-)
1313
1414diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts
15- index adfb9f657ae..98cfab3ae62 100644
15+ index adfb9f657ae..4604c6e7aaf 100644
1616--- a/src/vs/base/browser/dom.ts
1717+++ b/src/vs/base/browser/dom.ts
18- @@ -925,6 +925,26 @@ export function getActiveElement(_document = getActiveDocument()): Element | nul
18+ @@ -925,6 +925,28 @@ export function getActiveElement(_document = getActiveDocument()): Element | nul
1919 return result;
2020 }
2121
@@ -27,8 +27,10 @@ index adfb9f657ae..98cfab3ae62 100644
2727+ export function getFullscreenElement(_document = getActiveDocument()): Element | null {
2828+ const _getFullscreenElement = (node: Document | ShadowRoot): Element | null =>
2929+ node.fullscreenElement ??
30+ + // eslint-disable-next-line local/code-no-any-casts
3031+ (<any>node).webkitFullscreenElement ??
31- + null
32+ + null;
33+ +
3234+
3335+ let result = _getFullscreenElement(_document);
3436+
@@ -42,7 +44,7 @@ index adfb9f657ae..98cfab3ae62 100644
4244 export function getRootContainer(element: Element) {
4345 let container: Node = element.getRootNode();
4446 if (container instanceof Document) {
45- @@ -1699,11 +1719 ,11 @@ export interface IDetectedFullscreen {
47+ @@ -1699,11 +1721 ,11 @@ export interface IDetectedFullscreen {
4648 guess: boolean;
4749 }
4850
@@ -52,12 +54,12 @@ index adfb9f657ae..98cfab3ae62 100644
5254 // Browser fullscreen: use DOM APIs to detect
5355- // eslint-disable-next-line local/code-no-any-casts
5456- if (targetWindow.document.fullscreenElement || (<any>targetWindow.document).webkitFullscreenElement || (<any>targetWindow.document).webkitIsFullScreen) {
55- + const fullscreenElement = getFullscreenElement(targetWindow.document)
57+ + const fullscreenElement = getFullscreenElement(targetWindow.document);
5658+ if (fullscreenElement === containerElement) {
5759 return { mode: DetectedFullscreenMode.DOCUMENT, guess: false };
5860 }
5961
60- @@ -1712,7 +1732 ,9 @@ export function detectFullscreen(targetWindow: Window): IDetectedFullscreen | nu
62+ @@ -1712,7 +1734 ,9 @@ export function detectFullscreen(targetWindow: Window): IDetectedFullscreen | nu
6163 // height and comparing that to window height, we can guess
6264 // it though.
6365
@@ -68,7 +70,7 @@ index adfb9f657ae..98cfab3ae62 100644
6870 // if the height of the window matches the screen height, we can
6971 // safely assume that the browser is fullscreen because no browser
7072 // chrome is taking height away (e.g. like toolbars).
71- @@ -1721,7 +1743 ,7 @@ export function detectFullscreen(targetWindow: Window): IDetectedFullscreen | nu
73+ @@ -1721,7 +1745 ,7 @@ export function detectFullscreen(targetWindow: Window): IDetectedFullscreen | nu
7274
7375 if (platform.isMacintosh || platform.isLinux) {
7476 // macOS and Linux do not properly report `innerHeight`, only Windows does
@@ -78,24 +80,62 @@ index adfb9f657ae..98cfab3ae62 100644
7880 // only guess that we are in fullscreen. It is also possible that
7981 // the user has turned off taskbars in the OS and the browser is
8082diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts
81- index 057bfdb82c9..99aa6df59fa 100644
83+ index 057bfdb82c9..990f04d8acd 100644
8284--- a/src/vs/workbench/browser/layout.ts
8385+++ b/src/vs/workbench/browser/layout.ts
84- @@ -5,7 +5,7 @@
86+ @@ -3,10 +3,15 @@
87+ * Licensed under the MIT License. See License.txt in the project root for license information.
88+ *--------------------------------------------------------------------------------------------*/
8589
90+ + import { isFullscreen, isWCOEnabled, onDidChangeFullscreen } from '../../base/browser/browser.js';
91+ + import { addDisposableListener, computeScreenAwareSize, Dimension, EventType, getActiveDocument, getActiveElement, getActiveWindow, getClientArea, getFullscreenElement, getWindow, getWindowId, getWindows, IDimension, isActiveDocument, isAncestorUsingFlowTo, size } from '../../base/browser/dom.js';
92+ + import { setContainerElement } from '../../base/browser/domStylesheets.js';
93+ + import { Direction, ISerializableView, ISerializedGrid, ISerializedLeafNode, ISerializedNode, IViewSize, Orientation, SerializableGrid, Sizing } from '../../base/browser/ui/grid/grid.js';
94+ + import { CodeWindow, mainWindow } from '../../base/browser/window.js';
95+ + import { coalesce } from '../../base/common/arrays.js';
96+ + import { DeferredPromise, Promises } from '../../base/common/async.js';
97+ + import { Emitter, Event } from '../../base/common/event.js';
8698 import { Disposable, DisposableMap, DisposableStore, IDisposable, toDisposable } from '../../base/common/lifecycle.js';
87- import { Event, Emitter } from '../../base/common/event.js';
99+ - import { Event, Emitter } from '../../base/common/event.js';
88100- import { EventType, addDisposableListener, getClientArea, size, IDimension, isAncestorUsingFlowTo, computeScreenAwareSize, getActiveDocument, getWindows, getActiveWindow, isActiveDocument, getWindow, getWindowId, getActiveElement, Dimension } from '../../base/browser/dom.js';
89- + import { EventType, addDisposableListener, getClientArea, size, IDimension, isAncestorUsingFlowTo, computeScreenAwareSize, getActiveDocument, getWindows, getActiveWindow, isActiveDocument, getWindow, getWindowId, getActiveElement, Dimension, getFullscreenElement } from '../../base/browser/dom.js';
90- import { onDidChangeFullscreen, isFullscreen, isWCOEnabled } from '../../base/browser/browser.js';
101+ - import { onDidChangeFullscreen, isFullscreen, isWCOEnabled } from '../../base/browser/browser.js';
91102 import { isWindows, isLinux, isMacintosh, isWeb, isIOS } from '../../base/common/platform.js';
92103 import { EditorInputCapabilities, GroupIdentifier, isResourceEditorInput, IUntypedEditorInput, pathsToEditors } from '../common/editor.js';
104+ import { SidebarPart } from './parts/sidebar/sidebarPart.js';
105+ @@ -23,12 +28,10 @@ import { IHostService } from '../services/host/browser/host.js';
106+ import { IBrowserWorkbenchEnvironmentService } from '../services/environment/browser/environmentService.js';
107+ import { IEditorService } from '../services/editor/common/editorService.js';
108+ import { EditorGroupLayout, GroupOrientation, GroupsOrder, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';
109+ - import { SerializableGrid, ISerializableView, ISerializedGrid, Orientation, ISerializedNode, ISerializedLeafNode, Direction, IViewSize, Sizing } from '../../base/browser/ui/grid/grid.js';
110+ import { Part } from './part.js';
111+ import { IStatusbarService } from '../services/statusbar/browser/statusbar.js';
112+ import { IFileService } from '../../platform/files/common/files.js';
113+ import { isCodeEditor } from '../../editor/browser/editorBrowser.js';
114+ - import { coalesce } from '../../base/common/arrays.js';
115+ import { assertReturnsDefined } from '../../base/common/types.js';
116+ import { INotificationService, NotificationsFilter } from '../../platform/notification/common/notification.js';
117+ import { IThemeService } from '../../platform/theme/common/themeService.js';
118+ @@ -40,14 +43,11 @@ import { DiffEditorInput } from '../common/editor/diffEditorInput.js';
119+ import { mark } from '../../base/common/performance.js';
120+ import { IExtensionService } from '../services/extensions/common/extensions.js';
121+ import { ILogService } from '../../platform/log/common/log.js';
122+ - import { DeferredPromise, Promises } from '../../base/common/async.js';
123+ import { IBannerService } from '../services/banner/browser/bannerService.js';
124+ import { IPaneCompositePartService } from '../services/panecomposite/browser/panecomposite.js';
125+ import { AuxiliaryBarPart } from './parts/auxiliarybar/auxiliaryBarPart.js';
126+ import { ITelemetryService } from '../../platform/telemetry/common/telemetry.js';
127+ import { IAuxiliaryWindowService } from '../services/auxiliaryWindow/browser/auxiliaryWindowService.js';
128+ - import { CodeWindow, mainWindow } from '../../base/browser/window.js';
129+ - import { setContainerElement } from '../../base/browser/domStylesheets.js';
130+
131+ //#region Layout Implementation
132+
93133@@ -1633,7 +1633,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
94134
95135 layout(): void {
96136 if (!this.disposed) {
97137- this._mainContainerDimension = getClientArea(this.state.runtime.mainWindowFullscreen ?
98- + const fullscreenElement = getFullscreenElement(mainWindow.document)
138+ + const fullscreenElement = getFullscreenElement(mainWindow.document);
99139+ this._mainContainerDimension = getClientArea(this.state.runtime.mainWindowFullscreen && this.mainContainer === fullscreenElement ?
100140 mainWindow.document.body : // in fullscreen mode, make sure to use <body> element because
101141 this.parent, // in that case the workbench will span the entire site
0 commit comments