Fire a single batched event internally to update all webview view states

Previously we fired one event per webview. This change switches to fire on event per update
This commit is contained in:
Matt Bierner 2019-08-20 16:20:42 -07:00
parent 4d9460470a
commit b1dd95c883
3 changed files with 47 additions and 49 deletions

View file

@ -12,7 +12,7 @@ import { localize } from 'vs/nls';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions, WebviewPanelViewStateData } from 'vs/workbench/api/common/extHost.protocol';
import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
import { WebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewEditorService';
@ -23,6 +23,7 @@ import { extHostNamedCustomer } from '../common/extHostCustomers';
import { IProductService } from 'vs/platform/product/common/product';
import { startsWith } from 'vs/base/common/strings';
import { Webview } from 'vs/workbench/contrib/webview/browser/webview';
import { find } from 'vs/base/common/arrays';
interface OldMainThreadWebviewState {
readonly viewType: string;
@ -241,39 +242,34 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
}
private updateWebviewViewStates() {
const activeEditor = this._editorService.activeControl;
if (!this._webviewEditorInputs.size) {
return;
}
const webviews = new Map<WebviewEditorInput, {
group: number,
visible: boolean,
active: boolean,
}>();
const activeInput = this._editorService.activeControl && this._editorService.activeControl.input;
const viewStates: WebviewPanelViewStateData = {};
for (const group of this._editorGroupService.groups) {
for (const input of group.editors) {
if (!(input instanceof WebviewEditorInput)) {
continue;
}
webviews.set(input, {
group: group.id,
visible: input === group.activeEditor,
active: !!activeEditor && input === activeEditor.input
});
const handle = find(
map.keys(this._webviewEditorInputs),
handle => input === this._webviewEditorInputs.get(handle));
if (handle) {
viewStates[handle] = {
visible: input === group.activeEditor,
active: input === activeInput,
position: editorGroupToViewColumn(this._editorGroupService, group.id || 0),
};
}
}
}
for (const webview of map.keys(webviews)) {
const state = webviews.get(webview)!;
for (const handle of map.keys(this._webviewEditorInputs)) {
const input = this._webviewEditorInputs.get(handle)!;
if (input === webview) {
this._proxy.$onDidChangeWebviewPanelViewState(handle, {
active: state.active,
visible: state.visible,
position: editorGroupToViewColumn(this._editorGroupService, state.group || 0),
});
break;
}
}
if (Object.keys(viewStates).length) {
this._proxy.$onDidChangeWebviewPanelViewStates(viewStates);
}
}

View file

@ -549,15 +549,17 @@ export interface MainThreadWebviewsShape extends IDisposable {
$unregisterSerializer(viewType: string): void;
}
export interface WebviewPanelViewState {
readonly active: boolean;
readonly visible: boolean;
readonly position: EditorViewColumn;
export interface WebviewPanelViewStateData {
[handle: string]: {
readonly active: boolean;
readonly visible: boolean;
readonly position: EditorViewColumn;
};
}
export interface ExtHostWebviewsShape {
$onMessage(handle: WebviewPanelHandle, message: any): void;
$onDidChangeWebviewPanelViewState(handle: WebviewPanelHandle, newState: WebviewPanelViewState): void;
$onDidChangeWebviewPanelViewStates(newState: WebviewPanelViewStateData): void;
$onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise<void>;
$deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
}

View file

@ -5,15 +5,15 @@
import { Emitter, Event } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import * as modes from 'vs/editor/common/modes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import * as vscode from 'vscode';
import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewState } from './extHost.protocol';
import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewStateData } from './extHost.protocol';
import { Disposable } from './extHostTypes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import * as modes from 'vs/editor/common/modes';
import { WebviewInitData, asWebviewUri } from 'vs/workbench/api/common/shared/webview';
import { generateUuid } from 'vs/base/common/uuid';
type IconPath = URI | { light: URI, dark: URI };
@ -298,21 +298,21 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
}
}
public $onDidChangeWebviewPanelViewState(
handle: WebviewPanelHandle,
newState: WebviewPanelViewState
): void {
const panel = this.getWebviewPanel(handle);
if (!panel || panel._isDisposed) {
return;
}
public $onDidChangeWebviewPanelViewStates(newStates: WebviewPanelViewStateData): void {
for (const handle of Object.keys(newStates)) {
const panel = this.getWebviewPanel(handle);
if (!panel || panel._isDisposed) {
continue;
}
const viewColumn = typeConverters.ViewColumn.to(newState.position);
if (panel.active !== newState.active || panel.visible !== newState.visible || panel.viewColumn !== viewColumn) {
panel._setActive(newState.active);
panel._setVisible(newState.visible);
panel._setViewColumn(viewColumn);
panel._onDidChangeViewStateEmitter.fire({ webviewPanel: panel });
const newState = newStates[handle];
const viewColumn = typeConverters.ViewColumn.to(newState.position);
if (panel.active !== newState.active || panel.visible !== newState.visible || panel.viewColumn !== viewColumn) {
panel._setActive(newState.active);
panel._setVisible(newState.visible);
panel._setViewColumn(viewColumn);
panel._onDidChangeViewStateEmitter.fire({ webviewPanel: panel });
}
}
}