Skip to content

Commit

Permalink
Add onDidChangeActiveEditor API
Browse files Browse the repository at this point in the history
Part of #43713

Adds a new api `onDidChangeActiveEditor` which generalizes `onDidChangeActiveTextEditor` to also detect switches to and from webviews.

This API replaces the `Webview.onBecameActive` and `Webview.onBecameInactive` events previously prototyped.
  • Loading branch information
mjbvz committed Feb 16, 2018
1 parent e1f33fb commit 70dac6a
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 54 deletions.
12 changes: 4 additions & 8 deletions extensions/markdown/src/features/previewContentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@ export class MarkdownPreviewWebviewManager {
vscode.workspace.onDidChangeTextDocument(event => {
this.update(event.document.uri);
}, null, this.disposables);

vscode.window.onDidChangeActiveEditor(editor => {
vscode.commands.executeCommand('setContext', 'markdownPreview', editor && editor.editorType === 'webview');
}, null, this.disposables);
}

public dispose(): void {
Expand Down Expand Up @@ -362,14 +366,6 @@ export class MarkdownPreviewWebviewManager {
vscode.commands.executeCommand(e.command, ...e.args);
});

view.onBecameActive(() => {
vscode.commands.executeCommand('setContext', 'markdownPreview', true);
});

view.onBecameInactive(() => {
vscode.commands.executeCommand('setContext', 'markdownPreview', false);
});

this.webviews.set(resource.fsPath, view);
return view;
}
Expand Down
4 changes: 4 additions & 0 deletions src/vs/vscode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,10 @@ declare module 'vscode' {
* Represents an editor that is attached to a [document](#TextDocument).
*/
export interface TextEditor {
/**
* Type identifying the editor as a text editor.
*/
readonly editorType: 'texteditor';

/**
* The document associated with this text editor. The document will be the same for the entire lifetime of this text editor.
Expand Down
17 changes: 7 additions & 10 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,11 @@ declare module 'vscode' {
* A webview is an editor with html content, like an iframe.
*/
export interface Webview {
/**
* Type identifying the editor as a webview editor.
*/
readonly editorType: 'webview';

/**
* Title of the webview.
*/
Expand All @@ -551,16 +556,6 @@ declare module 'vscode' {
*/
readonly onMessage: Event<any>;

/**
* Fired when the webview becomes the active editor.
*/
readonly onBecameActive: Event<void>;

/**
* Fired when the webview stops being the active editor
*/
readonly onBecameInactive: Event<void>;

/**
* Post a message to the webview content.
*
Expand All @@ -585,5 +580,7 @@ declare module 'vscode' {
* @param options Webview content options.
*/
export function createWebview(title: string, column: ViewColumn, options: WebviewOptions): Webview;

export const onDidChangeActiveEditor: Event<TextEditor | Webview | undefined>;
}
}
21 changes: 7 additions & 14 deletions src/vs/workbench/api/electron-browser/mainThreadWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ import URI from 'vs/base/common/uri';

interface WebviewEvents {
onMessage(message: any): void;
onFocus(): void;
onBlur(): void;
}

class WebviewInput extends EditorInput {
Expand Down Expand Up @@ -290,9 +288,7 @@ export class MainThreadWebview implements MainThreadWebviewShape {

$createWebview(handle: number): void {
const webview = new WebviewInput('', {}, '', {
onMessage: (message) => this._proxy.$onMessage(handle, message),
onFocus: () => this._proxy.$onBecameActive(handle),
onBlur: () => this._proxy.$onBecameInactive(handle)
onMessage: (message) => this._proxy.$onMessage(handle, message)
});
this._webviews.set(handle, webview);
}
Expand Down Expand Up @@ -345,28 +341,25 @@ export class MainThreadWebview implements MainThreadWebviewShape {

private onEditorsChanged() {
const activeEditor = this._editorService.getActiveEditor();
let newActiveWebview: WebviewInput | undefined = undefined;
let newActiveWebview: { input: WebviewInput, handle: number } | undefined = undefined;
if (activeEditor.input instanceof WebviewInput) {
for (const handle of map.keys(this._webviews)) {
const input = this._webviews.get(handle);
if (input.matches(activeEditor.input)) {
newActiveWebview = input;
newActiveWebview = { input, handle };
break;
}
}
}

if (newActiveWebview) {
if (!this._activeWebview || !newActiveWebview.matches(this._activeWebview)) {
if (this._activeWebview) {
this._activeWebview.events.onBlur();
}
newActiveWebview.events.onFocus();
this._activeWebview = newActiveWebview;
if (!this._activeWebview || !newActiveWebview.input.matches(this._activeWebview)) {
this._proxy.$onDidChangeActiveWeview(newActiveWebview.handle);
this._activeWebview = newActiveWebview.input;
}
} else {
if (this._activeWebview) {
this._activeWebview.events.onBlur();
this._proxy.$onDidChangeActiveWeview(undefined);
this._activeWebview = undefined;
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/vs/workbench/api/node/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ export function createApiFactory(
rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService);
const extHostHeapService = rpcProtocol.set(ExtHostContext.ExtHostHeapService, new ExtHostHeapService());
const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, new ExtHostDecorations(rpcProtocol));
const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, new ExtHostDocumentsAndEditors(rpcProtocol));
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol));
const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, new ExtHostDocumentsAndEditors(rpcProtocol, extHostWebviews));
const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors));
const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors));
const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadTextEditors)));
Expand All @@ -117,7 +118,6 @@ export function createApiFactory(
const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, new ExtHostTask(rpcProtocol, extHostWorkspace));
const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol));
rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService);
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol));

// Check that no named customers are missing
const expected: ProxyIdentifier<any>[] = Object.keys(ExtHostContext).map((key) => ExtHostContext[key]);
Expand Down Expand Up @@ -401,7 +401,10 @@ export function createApiFactory(
}),
createWebview: proposedApiFunction(extension, (name: string, column: vscode.ViewColumn, options: vscode.WebviewOptions) => {
return extHostWebviews.createWebview(name, column, options);
})
}),
onDidChangeActiveEditor: proposedApiFunction(extension, (listener, thisArg?, disposables?) => {
return extHostDocumentsAndEditors.onDidChangeActiveEditor(listener, thisArg, disposables);
}),
};

// namespace: workspace
Expand Down
3 changes: 1 addition & 2 deletions src/vs/workbench/api/node/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,7 @@ export interface MainThreadWebviewShape extends IDisposable {
}
export interface ExtHostWebviewsShape {
$onMessage(handle: number, message: any): void;
$onBecameActive(handle: number): void;
$onBecameInactive(handle: number): void;
$onDidChangeActiveWeview(handle: number | undefined): void;
}

export interface MainThreadWorkspaceShape extends IDisposable {
Expand Down
30 changes: 29 additions & 1 deletion src/vs/workbench/api/node/extHostDocumentsAndEditors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,51 @@ import { ExtHostTextEditor } from './extHostTextEditor';
import * as assert from 'assert';
import * as typeConverters from './extHostTypeConverters';
import URI from 'vs/base/common/uri';
import { ExtHostWebview, ExtHostWebviews } from './extHostWebview';
import { Disposable } from './extHostTypes';

export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsShape {

private _disposables: Disposable[] = [];

private _activeEditorId: string;
private _activeWebview: ExtHostWebview;

private readonly _editors = new Map<string, ExtHostTextEditor>();
private readonly _documents = new Map<string, ExtHostDocumentData>();

private readonly _onDidAddDocuments = new Emitter<ExtHostDocumentData[]>();
private readonly _onDidRemoveDocuments = new Emitter<ExtHostDocumentData[]>();
private readonly _onDidChangeVisibleTextEditors = new Emitter<ExtHostTextEditor[]>();
private readonly _onDidChangeActiveTextEditor = new Emitter<ExtHostTextEditor>();
private readonly _onDidChangeActiveEditor = new Emitter<ExtHostTextEditor | ExtHostWebview>();

readonly onDidAddDocuments: Event<ExtHostDocumentData[]> = this._onDidAddDocuments.event;
readonly onDidRemoveDocuments: Event<ExtHostDocumentData[]> = this._onDidRemoveDocuments.event;
readonly onDidChangeVisibleTextEditors: Event<ExtHostTextEditor[]> = this._onDidChangeVisibleTextEditors.event;
readonly onDidChangeActiveTextEditor: Event<ExtHostTextEditor> = this._onDidChangeActiveTextEditor.event;
readonly onDidChangeActiveEditor: Event<ExtHostTextEditor | ExtHostWebview> = this._onDidChangeActiveEditor.event;

constructor(
private readonly _mainContext: IMainContext
private readonly _mainContext: IMainContext,
_extHostWebviews?: ExtHostWebviews
) {
if (_extHostWebviews) {
_extHostWebviews.onDidChangeActiveWebview(webview => {
if (webview) {
if (webview !== this._activeWebview) {
this._onDidChangeActiveEditor.fire(webview);
this._activeWebview = webview;
}
} else {
this._activeWebview = webview;
}
}, this, this._disposables);
}
}

dispose() {
this._disposables = dispose(this._disposables);
}

$acceptDocumentsAndEditorsDelta(delta: IDocumentsAndEditorsDelta): void {
Expand Down Expand Up @@ -117,6 +142,9 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
}
if (delta.newActiveEditor !== undefined) {
this._onDidChangeActiveTextEditor.fire(this.activeEditor());

const activeEditor = this.activeEditor();
this._onDidChangeActiveEditor.fire(activeEditor || this._activeWebview);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/node/extHostTextEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions {

export class ExtHostTextEditor implements vscode.TextEditor {

public readonly type = 'texteditor';
public readonly editorType = 'texteditor';

private readonly _proxy: MainThreadTextEditorsShape;
private readonly _id: string;
Expand Down
24 changes: 9 additions & 15 deletions src/vs/workbench/api/node/extHostWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@

import { MainContext, MainThreadWebviewShape, IMainContext, ExtHostWebviewsShape } from './extHost.protocol';
import * as vscode from 'vscode';
import { Emitter } from 'vs/base/common/event';
import Event, { Emitter } from 'vs/base/common/event';
import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters';

class ExtHostWebview implements vscode.Webview {
export class ExtHostWebview implements vscode.Webview {
public readonly editorType = 'webview';

private _title: string;
private _html: string;
private _options: vscode.WebviewOptions;
Expand All @@ -17,13 +19,7 @@ class ExtHostWebview implements vscode.Webview {


public readonly onMessageEmitter = new Emitter<any>();
public readonly onMessage = this.onMessageEmitter.event;

public readonly onBecameActiveEmitter = new Emitter<void>();
public readonly onBecameActive = this.onBecameActiveEmitter.event;

public readonly onBecameInactiveEmitter = new Emitter<void>();
public readonly onBecameInactive = this.onBecameInactiveEmitter.event;
public readonly onMessage: Event<any> = this.onMessageEmitter.event;

constructor(
private readonly _proxy: MainThreadWebviewShape,
Expand Down Expand Up @@ -114,13 +110,11 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
webview.onMessageEmitter.fire(message);
}

$onBecameActive(handle: number): void {
$onDidChangeActiveWeview(handle: number | undefined): void {
const webview = this._webviews.get(handle);
webview.onBecameActiveEmitter.fire();
this._onDidChangeActiveWebview.fire(webview);
}

$onBecameInactive(handle: number): void {
const webview = this._webviews.get(handle);
webview.onBecameInactiveEmitter.fire();
}
private readonly _onDidChangeActiveWebview = new Emitter<ExtHostWebview | undefined>();
public readonly onDidChangeActiveWebview = this._onDidChangeActiveWebview.event;
}

0 comments on commit 70dac6a

Please sign in to comment.