Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,20 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Gaspar Chefdeville <[email protected]>
Date: Wed, 9 Jul 2025 17:25:14 +0200
From: Jean-Damien Thevenoux <[email protected]>
Date: Fri, 21 Nov 2025 18:15:16 +0100
Subject: [PATCH] feat: prevent IDE from entering fullscreen if not occupying
the entire screen

---
src/vs/base/browser/dom.ts | 14 +++++++++-----
src/vs/workbench/browser/web.main.ts | 2 +-
.../services/host/browser/browserHostService.ts | 2 +-
3 files changed, 11 insertions(+), 7 deletions(-)
src/vs/base/browser/dom.ts | 32 ++++++++++++++++---
src/vs/workbench/browser/layout.ts | 5 +--
src/vs/workbench/browser/web.main.ts | 2 +-
.../host/browser/browserHostService.ts | 2 +-
4 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts
index adfb9f657ae..6195106e703 100644
index adfb9f657ae..98cfab3ae62 100644
--- a/src/vs/base/browser/dom.ts
+++ b/src/vs/base/browser/dom.ts
@@ -1699,11 +1699,13 @@ export interface IDetectedFullscreen {
@@ -925,6 +925,26 @@ export function getActiveElement(_document = getActiveDocument()): Element | nul
return result;
}

+/**
+ * Returns the fullscreen element, if any, by walking through
+ * nested shadow roots.
+ * Only element-based fullscreen created via requestFullscreen() is returned.
+*/
+export function getFullscreenElement(_document = getActiveDocument()): Element | null {
+ const _getFullscreenElement = (node: Document | ShadowRoot): Element | null =>
+ node.fullscreenElement ??
+ (<any>node).webkitFullscreenElement ??
+ null
+
+ let result = _getFullscreenElement(_document);
+
+ while (result?.shadowRoot) {
+ result = _getFullscreenElement(result.shadowRoot);
+ }
+
+ return result;
+}
+
export function getRootContainer(element: Element) {
let container: Node = element.getRootNode();
if (container instanceof Document) {
@@ -1699,11 +1719,11 @@ export interface IDetectedFullscreen {
guess: boolean;
}

Expand All @@ -24,14 +52,12 @@ index adfb9f657ae..6195106e703 100644
// Browser fullscreen: use DOM APIs to detect
- // eslint-disable-next-line local/code-no-any-casts
- if (targetWindow.document.fullscreenElement || (<any>targetWindow.document).webkitFullscreenElement || (<any>targetWindow.document).webkitIsFullScreen) {
+ const fullscreenElement: Element | undefined =
+ // eslint-disable-next-line local/code-no-any-casts
+ targetWindow.document.fullscreenElement ?? (<any>targetWindow.document).webkitFullscreenElement ?? (<any>targetWindow.document).webkitIsFullScreen;
+ const fullscreenElement = getFullscreenElement(targetWindow.document)
+ if (fullscreenElement === containerElement) {
return { mode: DetectedFullscreenMode.DOCUMENT, guess: false };
}

@@ -1712,7 +1714,9 @@ export function detectFullscreen(targetWindow: Window): IDetectedFullscreen | nu
@@ -1712,7 +1732,9 @@ export function detectFullscreen(targetWindow: Window): IDetectedFullscreen | nu
// height and comparing that to window height, we can guess
// it though.

Expand All @@ -42,7 +68,7 @@ index adfb9f657ae..6195106e703 100644
// if the height of the window matches the screen height, we can
// safely assume that the browser is fullscreen because no browser
// chrome is taking height away (e.g. like toolbars).
@@ -1721,7 +1725,7 @@ export function detectFullscreen(targetWindow: Window): IDetectedFullscreen | nu
@@ -1721,7 +1743,7 @@ export function detectFullscreen(targetWindow: Window): IDetectedFullscreen | nu

if (platform.isMacintosh || platform.isLinux) {
// macOS and Linux do not properly report `innerHeight`, only Windows does
Expand All @@ -51,6 +77,29 @@ index adfb9f657ae..6195106e703 100644
// if the height of the browser matches the screen height, we can
// only guess that we are in fullscreen. It is also possible that
// the user has turned off taskbars in the OS and the browser is
diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts
index 057bfdb82c9..99aa6df59fa 100644
--- a/src/vs/workbench/browser/layout.ts
+++ b/src/vs/workbench/browser/layout.ts
@@ -5,7 +5,7 @@

import { Disposable, DisposableMap, DisposableStore, IDisposable, toDisposable } from '../../base/common/lifecycle.js';
import { Event, Emitter } from '../../base/common/event.js';
-import { EventType, addDisposableListener, getClientArea, size, IDimension, isAncestorUsingFlowTo, computeScreenAwareSize, getActiveDocument, getWindows, getActiveWindow, isActiveDocument, getWindow, getWindowId, getActiveElement, Dimension } from '../../base/browser/dom.js';
+import { EventType, addDisposableListener, getClientArea, size, IDimension, isAncestorUsingFlowTo, computeScreenAwareSize, getActiveDocument, getWindows, getActiveWindow, isActiveDocument, getWindow, getWindowId, getActiveElement, Dimension, getFullscreenElement } from '../../base/browser/dom.js';
import { onDidChangeFullscreen, isFullscreen, isWCOEnabled } from '../../base/browser/browser.js';
import { isWindows, isLinux, isMacintosh, isWeb, isIOS } from '../../base/common/platform.js';
import { EditorInputCapabilities, GroupIdentifier, isResourceEditorInput, IUntypedEditorInput, pathsToEditors } from '../common/editor.js';
@@ -1633,7 +1633,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi

layout(): void {
if (!this.disposed) {
- this._mainContainerDimension = getClientArea(this.state.runtime.mainWindowFullscreen ?
+ const fullscreenElement = getFullscreenElement(mainWindow.document)
+ this._mainContainerDimension = getClientArea(this.state.runtime.mainWindowFullscreen && this.mainContainer === fullscreenElement ?
mainWindow.document.body : // in fullscreen mode, make sure to use <body> element because
this.parent, // in that case the workbench will span the entire site
this.contextService.getWorkbenchState() === WorkbenchState.EMPTY ? DEFAULT_EMPTY_WINDOW_DIMENSIONS : DEFAULT_WORKSPACE_WINDOW_DIMENSIONS // running with fallback to ensure no error is thrown (https://github.com/microsoft/vscode/issues/240242)
diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts
index fedadefc0b3..98275b2829b 100644
--- a/src/vs/workbench/browser/web.main.ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ Subject: [PATCH] feat: support loading VSCode in an iframe
8 files changed, 45 insertions(+), 43 deletions(-)

diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts
index 6195106e703..69a03f6a062 100644
index 98cfab3ae62..100ddac2639 100644
--- a/src/vs/base/browser/dom.ts
+++ b/src/vs/base/browser/dom.ts
@@ -1050,68 +1050,55 @@ function createHeadElement<K extends keyof HTMLElementTagNameMap>(tagName: K, co
@@ -1070,68 +1070,55 @@ function createHeadElement<K extends keyof HTMLElementTagNameMap>(tagName: K, co
}

export function isHTMLElement(e: unknown): e is HTMLElement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ Subject: [PATCH] feat: mark elements created outside of the VSCode container
2 files changed, 2 insertions(+)

diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts
index 69a03f6a062..53fc806dcda 100644
index 100ddac2639..0a34cb15839 100644
--- a/src/vs/base/browser/dom.ts
+++ b/src/vs/base/browser/dom.ts
@@ -1045,6 +1045,7 @@ export function createLinkElement(container: HTMLElement = mainWindow.document.h
@@ -1065,6 +1065,7 @@ export function createLinkElement(container: HTMLElement = mainWindow.document.h

function createHeadElement<K extends keyof HTMLElementTagNameMap>(tagName: K, container: HTMLElement = mainWindow.document.head): HTMLElementTagNameMap[K] {
const element = document.createElement(tagName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,10 @@ Subject: [PATCH] feat: centralize element creation, to be able to create them
190 files changed, 648 insertions(+), 570 deletions(-)

diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts
index 53fc806dcda..9932da557fa 100644
index 0a34cb15839..fa02fea7607 100644
--- a/src/vs/base/browser/dom.ts
+++ b/src/vs/base/browser/dom.ts
@@ -1043,13 +1043,43 @@ export function createLinkElement(container: HTMLElement = mainWindow.document.h
@@ -1063,13 +1063,43 @@ export function createLinkElement(container: HTMLElement = mainWindow.document.h
return createHeadElement('link', container);
}

Expand Down Expand Up @@ -246,7 +246,7 @@ index 53fc806dcda..9932da557fa 100644
export function isHTMLElement(e: unknown): e is HTMLElement {
return e instanceof mainWindow.HTMLElement || e instanceof getWindow(e as Node).HTMLElement;
}
@@ -1336,9 +1366,9 @@ function _$<T extends Element>(namespace: Namespace, description: string, attrs?
@@ -1356,9 +1386,9 @@ function _$<T extends Element>(namespace: Namespace, description: string, attrs?
let result: T;

if (namespace !== Namespace.HTML) {
Expand All @@ -258,7 +258,7 @@ index 53fc806dcda..9932da557fa 100644
}

if (match[3]) {
@@ -1389,7 +1419,7 @@ export function join(nodes: Node[], separator: Node | string): Node[] {
@@ -1409,7 +1439,7 @@ export function join(nodes: Node[], separator: Node | string): Node[] {
if (separator instanceof Node) {
result.push(separator.cloneNode());
} else {
Expand All @@ -267,7 +267,7 @@ index 53fc806dcda..9932da557fa 100644
}
}

@@ -1591,7 +1621,7 @@ export function triggerDownload(dataOrUri: Uint8Array | URI, name: string): void
@@ -1611,7 +1641,7 @@ export function triggerDownload(dataOrUri: Uint8Array | URI, name: string): void
// points to the file to download.
// See also https://developers.google.com/web/updates/2011/08/Downloading-resources-in-HTML5-a-download
const activeWindow = getActiveWindow();
Expand All @@ -276,7 +276,7 @@ index 53fc806dcda..9932da557fa 100644
activeWindow.document.body.appendChild(anchor);
anchor.download = name;
anchor.href = url;
@@ -1608,7 +1638,7 @@ export function triggerUpload(): Promise<FileList | undefined> {
@@ -1628,7 +1658,7 @@ export function triggerUpload(): Promise<FileList | undefined> {
// input element of type `file` and click it
// to gather the selected files
const activeWindow = getActiveWindow();
Expand All @@ -285,7 +285,7 @@ index 53fc806dcda..9932da557fa 100644
activeWindow.document.body.appendChild(input);
input.type = 'file';
input.multiple = true;
@@ -2059,7 +2089,7 @@ export function h(tag: string, ...args: [] | [attributes: { $: string } & Partia
@@ -2077,7 +2107,7 @@ export function h(tag: string, ...args: [] | [attributes: { $: string } & Partia
}

const tagName = match.groups['tag'] || 'div';
Expand All @@ -294,7 +294,7 @@ index 53fc806dcda..9932da557fa 100644

if (match.groups['id']) {
el.id = match.groups['id'];
@@ -2163,7 +2193,7 @@ export function svgElem(tag: string, ...args: [] | [attributes: { $: string } &
@@ -2181,7 +2211,7 @@ export function svgElem(tag: string, ...args: [] | [attributes: { $: string } &

const tagName = match.groups['tag'] || 'div';
// eslint-disable-next-line local/code-no-any-casts
Expand All @@ -303,7 +303,7 @@ index 53fc806dcda..9932da557fa 100644

if (match.groups['id']) {
el.id = match.groups['id'];
@@ -2429,7 +2459,7 @@ export abstract class ObserverNode<T extends HTMLOrSVGElement = HTMLOrSVGElement
@@ -2447,7 +2477,7 @@ export abstract class ObserverNode<T extends HTMLOrSVGElement = HTMLOrSVGElement
attributes: ElementAttributeKeys<T>,
children: ChildNode
) {
Expand Down Expand Up @@ -3369,15 +3369,15 @@ index 93d0b4cc089..fd0751d3ebf 100644
activeDocument.body.appendChild(hoverFeedback);
disposables.add(toDisposable(() => hoverFeedback.remove()));
diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts
index 057bfdb82c9..e083fd0ccb9 100644
index 99aa6df59fa..7bd4c09ebf7 100644
--- a/src/vs/workbench/browser/layout.ts
+++ b/src/vs/workbench/browser/layout.ts
@@ -3,51 +3,51 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

+import { isFullscreen, isWCOEnabled, onDidChangeFullscreen } from '../../base/browser/browser.js';
+import { addDisposableListener, computeScreenAwareSize, createElement, Dimension, EventType, getActiveDocument, getActiveElement, getActiveWindow, getClientArea, getWindow, getWindowId, getWindows, IDimension, isActiveDocument, isAncestorUsingFlowTo, size } from '../../base/browser/dom.js';
+import { addDisposableListener, computeScreenAwareSize, createElement, Dimension, EventType, getActiveDocument, getActiveElement, getActiveWindow, getClientArea, getWindow, getWindowId, getWindows, IDimension, isActiveDocument, isAncestorUsingFlowTo, size, getFullscreenElement } from '../../base/browser/dom.js';
+import { setContainerElement } from '../../base/browser/domStylesheets.js';
+import { Direction, ISerializableView, ISerializedGrid, ISerializedLeafNode, ISerializedNode, IViewSize, Orientation, SerializableGrid, Sizing } from '../../base/browser/ui/grid/grid.js';
+import { CodeWindow, mainWindow } from '../../base/browser/window.js';
Expand All @@ -3386,7 +3386,7 @@ index 057bfdb82c9..e083fd0ccb9 100644
+import { Emitter, Event } from '../../base/common/event.js';
import { Disposable, DisposableMap, DisposableStore, IDisposable, toDisposable } from '../../base/common/lifecycle.js';
-import { Event, Emitter } from '../../base/common/event.js';
-import { EventType, addDisposableListener, getClientArea, size, IDimension, isAncestorUsingFlowTo, computeScreenAwareSize, getActiveDocument, getWindows, getActiveWindow, isActiveDocument, getWindow, getWindowId, getActiveElement, Dimension } from '../../base/browser/dom.js';
-import { EventType, addDisposableListener, getClientArea, size, IDimension, isAncestorUsingFlowTo, computeScreenAwareSize, getActiveDocument, getWindows, getActiveWindow, isActiveDocument, getWindow, getWindowId, getActiveElement, Dimension, getFullscreenElement } from '../../base/browser/dom.js';
-import { onDidChangeFullscreen, isFullscreen, isWCOEnabled } from '../../base/browser/browser.js';
-import { isWindows, isLinux, isMacintosh, isWeb, isIOS } from '../../base/common/platform.js';
-import { EditorInputCapabilities, GroupIdentifier, isResourceEditorInput, IUntypedEditorInput, pathsToEditors } from '../common/editor.js';
Expand Down
2 changes: 1 addition & 1 deletion vscode-patches/0078-feat-add-customEditorRestore.patch
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Subject: [PATCH] feat: add customEditorRestore
2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts
index e083fd0ccb9..f273af42391 100644
index 7bd4c09ebf7..5bd0bad173a 100644
--- a/src/vs/workbench/browser/layout.ts
+++ b/src/vs/workbench/browser/layout.ts
@@ -20,7 +20,7 @@ import { isCodeEditor } from '../../editor/browser/editorBrowser.js';
Expand Down