From bbb2e5bb889d0e69a8d63cc90e9ee66669e28944 Mon Sep 17 00:00:00 2001 From: Anton Kosyakov Date: Fri, 5 Apr 2019 13:22:29 +0000 Subject: [PATCH] [vscode] fix #4339: focus and reveal webviews properly Signed-off-by: Anton Kosyakov Signed-off-by: Doron Nahari doron.nahari@sap.com --- .../src/main/browser/webview/webview.ts | 10 ++++--- .../src/main/browser/webviews-main.ts | 26 ++++++++++++++++--- packages/plugin-ext/src/plugin/webviews.ts | 22 +++++++++++++--- packages/plugin/src/theia.d.ts | 11 ++++++++ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/packages/plugin-ext/src/main/browser/webview/webview.ts b/packages/plugin-ext/src/main/browser/webview/webview.ts index 96f653dbd50fa..c40334db4121c 100644 --- a/packages/plugin-ext/src/main/browser/webview/webview.ts +++ b/packages/plugin-ext/src/main/browser/webview/webview.ts @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { BaseWidget } from '@theia/core/lib/browser/widgets/widget'; +import { BaseWidget, Message } from '@theia/core/lib/browser/widgets/widget'; import { IdGenerator } from '../../../common/id-generator'; import { Disposable, DisposableCollection } from '@theia/core'; @@ -38,6 +38,7 @@ export class WebviewWidget extends BaseWidget { constructor(title: string, private options: WebviewWidgetOptions, private eventDelegate: WebviewEvents) { super(); + this.node.tabIndex = 0; this.id = WebviewWidget.ID.nextId(); this.title.closable = true; this.title.label = title; @@ -132,15 +133,16 @@ export class WebviewWidget extends BaseWidget { this.loadTimeout = undefined; onLoad(e.target, newFrame.contentWindow); } - }); + }, { once: true }); newFrame.contentDocument!.write(newDocument!.documentElement!.innerHTML); newFrame.contentDocument!.close(); this.updateSandboxAttribute(newFrame); } - focus() { - this.iframe.contentWindow!.focus(); + protected onActivateRequest(msg: Message): void { + super.onActivateRequest(msg); + this.node.focus(); } private reloadFrame() { diff --git a/packages/plugin-ext/src/main/browser/webviews-main.ts b/packages/plugin-ext/src/main/browser/webviews-main.ts index 0140e77ac3bf6..2db2002c573aa 100644 --- a/packages/plugin-ext/src/main/browser/webviews-main.ts +++ b/packages/plugin-ext/src/main/browser/webviews-main.ts @@ -85,10 +85,19 @@ export class WebviewsMainImpl implements WebviewsMain { this.onCloseView(viewId); }); this.views.set(viewId, view); - this.shell.addWidget(view, { area: showOptions.area ? showOptions.area : 'main' }); - this.shell.activateWidget(view.id); + const widgetOptions: ApplicationShell.WidgetOptions = { area: showOptions.area ? showOptions.area : 'main' }; + // FIXME translate all view columns properly + if (showOptions.viewColumn === -2) { + const ref = this.shell.currentWidget; + if (ref && this.shell.getAreaFor(ref) === widgetOptions.area) { + Object.assign(widgetOptions, { ref, mode: 'open-to-right' }); + } + } + this.shell.addWidget(view, widgetOptions); if (showOptions.preserveFocus) { - view.focus(); + this.shell.revealWidget(view.id); + } else { + this.shell.activateWidget(view.id); } } $disposeWebview(handle: string): void { @@ -98,7 +107,16 @@ export class WebviewsMainImpl implements WebviewsMain { } } $reveal(handle: string, showOptions: WebviewPanelShowOptions): void { - throw new Error('Method not implemented.'); + const webview = this.getWebview(handle); + if (webview.isDisposed) { + return; + } + // FIXME handle view column here too! + if (showOptions.preserveFocus) { + this.shell.revealWidget(webview.id); + } else { + this.shell.activateWidget(webview.id); + } } $setTitle(handle: string, value: string): void { const webview = this.getWebview(handle); diff --git a/packages/plugin-ext/src/plugin/webviews.ts b/packages/plugin-ext/src/plugin/webviews.ts index 2b4da44fb2f0f..3d5ff196daf71 100644 --- a/packages/plugin-ext/src/plugin/webviews.ts +++ b/packages/plugin-ext/src/plugin/webviews.ts @@ -298,12 +298,28 @@ export class WebviewPanelImpl implements theia.WebviewPanel { this._visible = value; } - reveal(area?: WebviewPanelTargetArea, viewColumn?: theia.ViewColumn, preserveFocus?: boolean): void { + reveal(arg0?: theia.ViewColumn | WebviewPanelTargetArea, arg1?: theia.ViewColumn | boolean, arg2?: boolean): void { + let area: WebviewPanelTargetArea | undefined = undefined; + let viewColumn: theia.ViewColumn | undefined = undefined; + let preserveFocus: boolean | undefined = undefined; + if (typeof arg0 === 'number') { + viewColumn = arg0; + } else { + area = arg0; + } + if (typeof arg1 === 'number') { + viewColumn = arg1; + } else { + preserveFocus = arg1; + } + if (typeof arg2 === 'boolean') { + preserveFocus = arg2; + } this.checkIsDisposed(); this.proxy.$reveal(this.viewId, { - area: area, + area, viewColumn: viewColumn ? fromViewColumn(viewColumn) : undefined, - preserveFocus: !!preserveFocus + preserveFocus }); } diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts index e8bb232868da0..7820b12c13c42 100644 --- a/packages/plugin/src/theia.d.ts +++ b/packages/plugin/src/theia.d.ts @@ -2663,6 +2663,17 @@ declare module '@theia/plugin' { */ readonly onDidDispose: Event; + /** + * Show the webview panel in a given column. + * + * A webview panel may only show in a single column at a time. If it is already showing, this + * method moves it to a new column. + * + * @param viewColumn View column to show the panel in. Shows in the current `viewColumn` if undefined. + * @param preserveFocus When `true`, the webview will not take focus. + */ + reveal(viewColumn?: ViewColumn, preserveFocus?: boolean): void; + /** * Show the webview panel according to a given options. *