diff options
| author | Stanton Burchett <sburchett@medallia.com> | 2026-07-30 14:50:01 -0600 |
|---|---|---|
| committer | Stanton Burchett <sburchett@medallia.com> | 2026-07-30 14:50:01 -0600 |
| commit | 64b564b52ba7d22ba8129821ab4b30542d971ff5 (patch) | |
| tree | 615cf77f12ac2281d671d4fcf0ed6925c353c7d7 | |
| parent | b08d308aba5fed8a20b83b63b71911732b1e53a4 (diff) | |
Focus the emitting tab when a notification is clicked
Resolve the OSC 9 onclick TODO: clicking a notification now brings the window to the front and selects the exact tab/pane that emitted the sequence. The title is read live from the tab each time instead of being captured once when the session is attached. Adds tabby-core as a dependency for AppService/HostWindowService.
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | package.json | 1 | ||||
| -rw-r--r-- | src/osc-notify-decorator.ts | 24 | ||||
| -rw-r--r-- | src/osc-notify-middleware.ts | 16 |
4 files changed, 36 insertions, 9 deletions
@@ -8,6 +8,10 @@ format: OSC 9 ; [message] ST ``` +Clicking the notification brings Tabby to the front and switches to the exact +tab/pane that emitted the sequence. The notification title reflects the tab's +current title at the time the sequence is received. + ### Example commands ```sh diff --git a/package.json b/package.json index c4b0764..52c828b 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "dependencies": { "@angular/core": "^16.2.3", "rxjs": "^7.8.1", + "tabby-core": "^1.0.197-nightly.1", "tabby-terminal": "^1.0.197-nightly.1" } } diff --git a/src/osc-notify-decorator.ts b/src/osc-notify-decorator.ts index 7d32f1c..abfb796 100644 --- a/src/osc-notify-decorator.ts +++ b/src/osc-notify-decorator.ts @@ -1,25 +1,41 @@ import OscNotifyMiddleware from "./osc-notify-middleware"; import { Injectable } from "@angular/core"; import { TerminalDecorator, BaseSession, BaseTerminalTabComponent } from "tabby-terminal"; +import { AppService, HostWindowService } from "tabby-core"; @Injectable() export default class OscNotifyDecorator extends TerminalDecorator { + constructor( + private app: AppService, + private hostWindow: HostWindowService, + ) { + super(); + } + attach(tab: BaseTerminalTabComponent<any>): void { // Subscribe to attach to future sessions in this tab tab.sessionChanged$.subscribe((session) => { if (session) { - this.attachToSession(session, (<any>tab).title); + this.attachToSession(session, tab); } }); // Attach the current session for this tab if (tab.session) { - this.attachToSession(tab.session, (<any>tab).title); + this.attachToSession(tab.session, tab); } } - private attachToSession(session: BaseSession, tabTitle: string) { - const middleware = new OscNotifyMiddleware(tabTitle); + private attachToSession(session: BaseSession, tab: BaseTerminalTabComponent<any>) { + const middleware = new OscNotifyMiddleware( + () => (<any>tab).title, + () => { + this.hostWindow.bringToFront(); + const parent = this.app.getParentTab(tab); + this.app.selectTab(parent ?? tab); + parent?.focus(tab); + }, + ); session.middleware.push(middleware); } diff --git a/src/osc-notify-middleware.ts b/src/osc-notify-middleware.ts index 15548f4..ad2946c 100644 --- a/src/osc-notify-middleware.ts +++ b/src/osc-notify-middleware.ts @@ -5,12 +5,14 @@ const oscPrefix = Buffer.from("\x1b]"); const oscSuffix = Buffer.from("\x07"); export default class OscNotifyMiddleware extends SessionMiddleware { - tabTitle: string; + getTitle: () => string; + onClick: () => void; - constructor(tabTitle: string) { + constructor(getTitle: () => string, onClick: () => void) { super(); - this.tabTitle = tabTitle; + this.getTitle = getTitle; + this.onClick = onClick; } get cwdReported$(): Observable<string> { @@ -22,6 +24,7 @@ export default class OscNotifyMiddleware extends SessionMiddleware { private cwdReported = new Subject<string>(); private copyRequested = new Subject<string>(); + private notifications: Notification[] = []; feedFromSession(data: Buffer): void { let startIndex = 0; @@ -36,10 +39,11 @@ export default class OscNotifyMiddleware extends SessionMiddleware { const oscCode = parseInt(oscCodeString); if (oscCode === 9) { - // TODO: onclick switch to tab - new Notification(this.tabTitle, { + const notification = new Notification(this.getTitle() || "Terminal", { body: oscParams[0] }); + notification.onclick = () => this.onClick(); + this.notifications.push(notification); } else { continue; } @@ -49,6 +53,8 @@ export default class OscNotifyMiddleware extends SessionMiddleware { } close(): void { + this.notifications.forEach((notification) => notification.close()); + this.notifications = []; this.cwdReported.complete(); this.copyRequested.complete(); super.close(); |
