diff --git a/packages/theia-integration/src/browser/diagram/glsp-diagram-widget.ts b/packages/theia-integration/src/browser/diagram/glsp-diagram-widget.ts index 8bf33c4..ec52ba2 100644 --- a/packages/theia-integration/src/browser/diagram/glsp-diagram-widget.ts +++ b/packages/theia-integration/src/browser/diagram/glsp-diagram-widget.ts @@ -20,6 +20,7 @@ import { EditorContextService, EnableToolPaletteAction, FocusStateChangedAction, + FocusTracker, GLSP_TYPES, IActionDispatcher, ICopyPasteHandler, @@ -32,11 +33,11 @@ import { TYPES } from "@eclipse-glsp/client"; import { Message } from "@phosphor/messaging/lib"; -import { ApplicationShell, Saveable, SaveableSource } from "@theia/core/lib/browser"; +import { ApplicationShell, Saveable, SaveableSource, Widget } from "@theia/core/lib/browser"; import { Disposable, DisposableCollection, Emitter, Event, MaybePromise } from "@theia/core/lib/common"; import { EditorPreferences } from "@theia/editor/lib/browser"; import { Container } from "inversify"; -import { DiagramWidget, DiagramWidgetOptions, TheiaSprottyConnector } from "sprotty-theia"; +import { DiagramWidget, DiagramWidgetOptions, isDiagramWidgetContainer, TheiaSprottyConnector } from "sprotty-theia"; import { GLSPWidgetOpenerOptions, GLSPWidgetOptions } from "./glsp-diagram-manager"; import { DirtyStateNotifier, GLSPTheiaDiagramServer } from "./glsp-theia-diagram-server"; @@ -99,16 +100,6 @@ export class GLSPDiagramWidget extends DiagramWidget implements SaveableSource { } } - listenToFocusState(shell: ApplicationShell) { - this.toDispose.push(shell.onDidChangeActiveWidget((event) => { - if (event.newValue === undefined || (event.newValue && event.newValue.id !== this.id)) { - this.actionDispatcher.dispatch(new FocusStateChangedAction(false)); - } else if ((event.newValue && event.newValue.id === this.id)) { - this.actionDispatcher.dispatch(new FocusStateChangedAction(true)); - } - })); - } - get diagramType(): string { return this.options.diagramType; } @@ -138,6 +129,43 @@ export class GLSPDiagramWidget extends DiagramWidget implements SaveableSource { this.copyPasteHandler.handlePaste(e); } } + + listenToFocusState(shell: ApplicationShell): void { + this.toDispose.push(shell.onDidChangeActiveWidget((event) => { + const focusedWidget = event.newValue; + if (this.hasFocus && !this.isThisWidget(focusedWidget)) { + this.actionDispatcher.dispatch(new FocusStateChangedAction(false)); + } else if (!this.hasFocus && this.isThisWidget(focusedWidget)) { + this.actionDispatcher.dispatch(new FocusStateChangedAction(true)); + } + })); + } + + protected isThisWidget(widget: Widget | null): boolean { + if (widget === null) return false; + const diagramWidget = getDiagramWidget(widget); + return diagramWidget !== undefined && diagramWidget.id === this.id; + } + + get hasFocus(): boolean | undefined { + let focusTracker: FocusTracker | undefined; + if (this.diContainer.isBound(FocusTracker)) { + focusTracker = this.diContainer.get(FocusTracker); + } + if (focusTracker) { + return focusTracker.hasFocus; + } + return undefined; + } +} + +export function getDiagramWidget(widget: Widget): GLSPDiagramWidget | undefined { + if (widget instanceof GLSPDiagramWidget) { + return widget as GLSPDiagramWidget; + } else if (isDiagramWidgetContainer(widget) && widget.diagramWidget instanceof GLSPDiagramWidget) { + return widget.diagramWidget as GLSPDiagramWidget; + } + return undefined; } export class SaveableGLSPModelSource implements Saveable, Disposable { diff --git a/packages/theia-integration/src/browser/diagram/glsp-theia-diagram-configuration.ts b/packages/theia-integration/src/browser/diagram/glsp-theia-diagram-configuration.ts index d0b5069..bdbe3ef 100644 --- a/packages/theia-integration/src/browser/diagram/glsp-theia-diagram-configuration.ts +++ b/packages/theia-integration/src/browser/diagram/glsp-theia-diagram-configuration.ts @@ -61,7 +61,9 @@ export abstract class GLSPTheiaDiagramConfiguration implements DiagramConfigurat container.bind(OpenerService).toConstantValue(this.openerService); container.bind(CommandService).toConstantValue(this.commandService); container.bind(ExternalModelSourceChangedHandler).toConstantValue(this.modelSourceChangedHandler); - container.rebind(CommandPalette).to(TheiaCommandPalette); + if (container.isBound(CommandPalette)) { + container.rebind(CommandPalette).to(TheiaCommandPalette); + } connectTheiaContextMenuService(container, this.contextMenuServiceFactory); connectTheiaMarkerManager(container, this.theiaMarkerManager, this.diagramType); diff --git a/packages/theia-integration/src/browser/theia-model-source-changed-handler.ts b/packages/theia-integration/src/browser/theia-model-source-changed-handler.ts index 2a4aea5..9035e1e 100644 --- a/packages/theia-integration/src/browser/theia-model-source-changed-handler.ts +++ b/packages/theia-integration/src/browser/theia-model-source-changed-handler.ts @@ -16,9 +16,8 @@ import { Action, ExternalModelSourceChangedHandler, ViewerOptions } from "@eclipse-glsp/client"; import { ApplicationShell, ConfirmDialog, Widget } from "@theia/core/lib/browser"; import { inject, injectable } from "inversify"; -import { isDiagramWidgetContainer } from "sprotty-theia"; -import { GLSPDiagramWidget } from "./diagram"; +import { getDiagramWidget } from "./diagram/glsp-diagram-widget"; @injectable() export class TheiaModelSourceChangedHandler extends ExternalModelSourceChangedHandler { @@ -37,7 +36,7 @@ export class TheiaModelSourceChangedHandler extends ExternalModelSourceChangedHa } protected async notifyModelSourceChangedWithWidget(widget: Widget, modelSourceName: string): Promise { - const diagramWidget = this.getDiagramWidget(widget); + const diagramWidget = getDiagramWidget(widget); if (!diagramWidget) { return []; } @@ -57,15 +56,6 @@ export class TheiaModelSourceChangedHandler extends ExternalModelSourceChangedHa return false; } - protected getDiagramWidget(widget: Widget): GLSPDiagramWidget | undefined { - if (widget instanceof GLSPDiagramWidget) { - return widget as GLSPDiagramWidget; - } else if (isDiagramWidgetContainer(widget) && widget.diagramWidget instanceof GLSPDiagramWidget) { - return widget.diagramWidget as GLSPDiagramWidget; - } - return undefined; - } - protected showDialog(widgetTitle: string, modelSourceName: string): Promise { const dialog = new ConfirmDialog({ title: `Source of editor '${widgetTitle}' changed`,