mirror of
https://github.com/Microsoft/vscode
synced 2024-10-30 04:17:37 +00:00
aux window - fixes for webview
support (#207695)
This commit is contained in:
parent
8caaab7a3e
commit
686bdd6278
10 changed files with 43 additions and 22 deletions
|
@ -346,6 +346,8 @@ class MainThreadCustomEditorModel extends ResourceWorkingCopy implements ICustom
|
|||
// this seed.
|
||||
readonly typeId = NO_TYPE_ID;
|
||||
|
||||
readonly isTextBased = false;
|
||||
|
||||
public static async create(
|
||||
instantiationService: IInstantiationService,
|
||||
proxy: extHostProtocol.ExtHostCustomEditorsShape,
|
||||
|
|
|
@ -349,10 +349,15 @@ export interface IInternalEditorCloseOptions extends IInternalEditorTitleControl
|
|||
readonly context?: EditorCloseContext;
|
||||
}
|
||||
|
||||
export interface IInternalMoveCopyOptions extends IInternalEditorOpenOptions {
|
||||
export interface IInternalEditorMoveCopyOpenOptions extends IInternalEditorOpenOptions {
|
||||
|
||||
/**
|
||||
* Whether to close the editor at the source or keep it.
|
||||
*/
|
||||
readonly keepCopy?: boolean;
|
||||
|
||||
/**
|
||||
* The source group an editor is moved or copied from.
|
||||
*/
|
||||
readonly sourceGroup?: IEditorGroupView;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
|||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
import { Emitter, Relay } from 'vs/base/common/event';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Dimension, trackFocus, addDisposableListener, EventType, EventHelper, findParentWithClass, isAncestor, IDomNodePagePosition, isMouseEvent, isActiveElement, getWindow, getActiveElement } from 'vs/base/browser/dom';
|
||||
import { Dimension, trackFocus, addDisposableListener, EventType, EventHelper, findParentWithClass, isAncestor, IDomNodePagePosition, isMouseEvent, isActiveElement, getWindow, getActiveElement, getWindowById } from 'vs/base/browser/dom';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
|
||||
|
@ -28,7 +28,7 @@ import { DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common
|
|||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { DeferredPromise, Promises, RunOnceWorker } from 'vs/base/common/async';
|
||||
import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
||||
import { IEditorGroupsView, IEditorGroupView, fillActiveEditorViewState, EditorServiceImpl, IEditorGroupTitleHeight, IInternalEditorOpenOptions, IInternalMoveCopyOptions, IInternalEditorCloseOptions, IInternalEditorTitleControlOptions, IEditorPartsView } from 'vs/workbench/browser/parts/editor/editor';
|
||||
import { IEditorGroupsView, IEditorGroupView, fillActiveEditorViewState, EditorServiceImpl, IEditorGroupTitleHeight, IInternalEditorOpenOptions, IInternalEditorMoveCopyOpenOptions, IInternalEditorCloseOptions, IInternalEditorTitleControlOptions, IEditorPartsView } from 'vs/workbench/browser/parts/editor/editor';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IAction, SubmenuAction } from 'vs/base/common/actions';
|
||||
|
@ -1049,7 +1049,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
});
|
||||
}
|
||||
|
||||
private async doOpenEditor(editor: EditorInput, options?: IEditorOptions, internalOptions?: IInternalEditorOpenOptions): Promise<IEditorPane | undefined> {
|
||||
private async doOpenEditor(editor: EditorInput, options?: IEditorOptions, internalOptions?: IInternalEditorMoveCopyOpenOptions): Promise<IEditorPane | undefined> {
|
||||
|
||||
// Guard against invalid editors. Disposed editors
|
||||
// should never open because they emit no events
|
||||
|
@ -1146,7 +1146,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
return showEditorResult;
|
||||
}
|
||||
|
||||
private doShowEditor(editor: EditorInput, context: { active: boolean; isNew: boolean }, options?: IEditorOptions, internalOptions?: IInternalEditorOpenOptions): Promise<IEditorPane | undefined> {
|
||||
private doShowEditor(editor: EditorInput, context: { active: boolean; isNew: boolean }, options?: IEditorOptions, internalOptions?: IInternalEditorMoveCopyOpenOptions): Promise<IEditorPane | undefined> {
|
||||
|
||||
// Show in editor control if the active editor changed
|
||||
let openEditorPromise: Promise<IEditorPane | undefined>;
|
||||
|
@ -1253,7 +1253,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
// through a method that allows for bulk updates but only
|
||||
// when moving to a different group where many editors
|
||||
// are more likely to occur.
|
||||
const internalOptions: IInternalMoveCopyOptions = {
|
||||
const internalOptions: IInternalEditorMoveCopyOpenOptions = {
|
||||
skipTitleUpdate: this !== target
|
||||
};
|
||||
|
||||
|
@ -1270,7 +1270,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
}
|
||||
}
|
||||
|
||||
moveEditor(editor: EditorInput, target: EditorGroupView, options?: IEditorOptions, internalOptions?: IInternalMoveCopyOptions): void {
|
||||
moveEditor(editor: EditorInput, target: EditorGroupView, options?: IEditorOptions, internalOptions?: IInternalEditorMoveCopyOpenOptions): void {
|
||||
|
||||
// Move within same group
|
||||
if (this === target) {
|
||||
|
@ -1320,7 +1320,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
}
|
||||
}
|
||||
|
||||
private doMoveOrCopyEditorAcrossGroups(editor: EditorInput, target: EditorGroupView, openOptions?: IEditorOpenOptions, internalOptions?: IInternalMoveCopyOptions): void {
|
||||
private doMoveOrCopyEditorAcrossGroups(editor: EditorInput, target: EditorGroupView, openOptions?: IEditorOpenOptions, internalOptions?: IInternalEditorMoveCopyOpenOptions): void {
|
||||
const keepCopy = internalOptions?.keepCopy;
|
||||
|
||||
// When moving/copying an editor, try to preserve as much view state as possible
|
||||
|
@ -1342,11 +1342,21 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
}
|
||||
|
||||
// A move to another group is an open first...
|
||||
target.doOpenEditor(keepCopy ? editor.copy() : editor, options, internalOptions);
|
||||
target.doOpenEditor(keepCopy ? editor.copy() : editor, options, { ...internalOptions, sourceGroup: this });
|
||||
|
||||
// ...and a close afterwards (unless we copy)
|
||||
if (!keepCopy) {
|
||||
this.doCloseEditor(editor, true /* do not focus next one behind if any */, { ...internalOptions, context: EditorCloseContext.MOVE });
|
||||
let canCloseEditor = true;
|
||||
if (
|
||||
editor.hasCapability(EditorInputCapabilities.AuxWindowUnsupported) &&
|
||||
getWindowById(target.windowId) !== getWindowById(this.windowId)
|
||||
) {
|
||||
canCloseEditor = false; // do not close the editor if it does not support aux windows
|
||||
}
|
||||
|
||||
if (canCloseEditor) {
|
||||
this.doCloseEditor(editor, true /* do not focus next one behind if any */, { ...internalOptions, context: EditorCloseContext.MOVE });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1361,7 +1371,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
// through a method that allows for bulk updates but only
|
||||
// when moving to a different group where many editors
|
||||
// are more likely to occur.
|
||||
const internalOptions: IInternalMoveCopyOptions = {
|
||||
const internalOptions: IInternalEditorMoveCopyOpenOptions = {
|
||||
skipTitleUpdate: this !== target
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la
|
|||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IEditorProgressService, LongRunningOperation } from 'vs/platform/progress/common/progress';
|
||||
import { IEditorGroupView, DEFAULT_EDITOR_MIN_DIMENSIONS, DEFAULT_EDITOR_MAX_DIMENSIONS, IInternalEditorOpenOptions } from 'vs/workbench/browser/parts/editor/editor';
|
||||
import { IEditorGroupView, DEFAULT_EDITOR_MIN_DIMENSIONS, DEFAULT_EDITOR_MAX_DIMENSIONS, IInternalEditorOpenOptions, IInternalEditorMoveCopyOpenOptions } from 'vs/workbench/browser/parts/editor/editor';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { ErrorPlaceholderEditor, IErrorEditorPlaceholderOptions, WorkspaceTrustRequiredPlaceholderEditor } from 'vs/workbench/browser/parts/editor/editorPlaceholder';
|
||||
|
@ -28,7 +28,6 @@ import { ILogService } from 'vs/platform/log/common/log';
|
|||
import { IDialogService, IPromptButton, IPromptCancelButton } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IBoundarySashes } from 'vs/base/browser/ui/sash/sash';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { mainWindow } from 'vs/base/browser/window';
|
||||
|
||||
export interface IOpenEditorResult {
|
||||
|
||||
|
@ -127,12 +126,12 @@ export class EditorPanes extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
async openEditor(editor: EditorInput, options: IEditorOptions | undefined, internalOptions: IInternalEditorOpenOptions | undefined, context: IEditorOpenContext = Object.create(null)): Promise<IOpenEditorResult> {
|
||||
async openEditor(editor: EditorInput, options: IEditorOptions | undefined, internalOptions: IInternalEditorMoveCopyOpenOptions | undefined, context: IEditorOpenContext = Object.create(null)): Promise<IOpenEditorResult> {
|
||||
try {
|
||||
|
||||
// Assert the `EditorInputCapabilities.AuxWindowUnsupported` condition
|
||||
if (getWindowById(this.groupView.windowId, true).window !== mainWindow && editor.hasCapability(EditorInputCapabilities.AuxWindowUnsupported)) {
|
||||
return await this.doShowError(createEditorOpenError(localize('editorUnsupportedInAuxWindow', "This type of editor cannot be opened in other windows yet."), [
|
||||
if (getWindowById(this.groupView.windowId) !== getWindowById(internalOptions?.sourceGroup?.windowId, true) && editor.hasCapability(EditorInputCapabilities.AuxWindowUnsupported)) {
|
||||
return await this.doShowError(createEditorOpenError(localize('editorUnsupportedInAuxWindow', "Save the editor first before opening in this window."), [
|
||||
toAction({
|
||||
id: 'workbench.editor.action.closeEditor', label: localize('openFolder', "Close Editor"), run: async () => {
|
||||
return this.groupView.closeEditor(editor);
|
||||
|
|
|
@ -793,7 +793,7 @@ export const enum EditorInputCapabilities {
|
|||
|
||||
/**
|
||||
* Signals that the editor does not support opening in
|
||||
* auxiliary windows yet.
|
||||
* auxiliary windows.
|
||||
*/
|
||||
AuxWindowUnsupported = 1 << 10
|
||||
}
|
||||
|
|
|
@ -152,10 +152,13 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput {
|
|||
|
||||
if (this.resource.scheme === Schemas.untitled) {
|
||||
capabilities |= EditorInputCapabilities.Untitled;
|
||||
capabilities |= EditorInputCapabilities.AuxWindowUnsupported;
|
||||
}
|
||||
|
||||
if (this.isDirty()) {
|
||||
if (this.isModified() && !this._modelRef?.object.isTextBased && !this.backupId) {
|
||||
// Non-text based modified custom editors without associated
|
||||
// backup should prevent to be moved across windows to prevent
|
||||
// data loss. Their modified state is potentially stored within
|
||||
// the `iframe` which will reset when moved across windows.
|
||||
capabilities |= EditorInputCapabilities.AuxWindowUnsupported;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ export interface ICustomEditorModel extends IDisposable {
|
|||
readonly viewType: string;
|
||||
readonly resource: URI;
|
||||
readonly backupId: string | undefined;
|
||||
readonly isTextBased: boolean;
|
||||
|
||||
isReadonly(): boolean | IMarkdownString;
|
||||
readonly onDidChangeReadonly: Event<void>;
|
||||
|
|
|
@ -16,6 +16,8 @@ import { ITextFileEditorModel, ITextFileService, TextFileEditorModelState } from
|
|||
|
||||
export class CustomTextEditorModel extends Disposable implements ICustomEditorModel {
|
||||
|
||||
readonly isTextBased = true;
|
||||
|
||||
public static async create(
|
||||
instantiationService: IInstantiationService,
|
||||
viewType: string,
|
||||
|
|
|
@ -34,7 +34,7 @@ export class ExtensionsInput extends EditorInput {
|
|||
}
|
||||
|
||||
override get capabilities(): EditorInputCapabilities {
|
||||
return EditorInputCapabilities.Readonly | EditorInputCapabilities.Singleton | EditorInputCapabilities.AuxWindowUnsupported;
|
||||
return EditorInputCapabilities.Readonly | EditorInputCapabilities.Singleton;
|
||||
}
|
||||
|
||||
override get resource() {
|
||||
|
|
|
@ -815,8 +815,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
|||
}
|
||||
|
||||
try {
|
||||
this.element.parentElement?.focus(); // this helps to move floating windows to the front if any...
|
||||
this.element.contentWindow?.focus(); // ...because `contentWindow` is not able to do so
|
||||
this.element.contentWindow?.focus();
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue