Eingehender Ruf: Firefox-Tab aktivieren und Fenster nativ nach vorn holen

Protokollversion 9: neue Plugin-Aktion activate und der Eintrag
IncomingCallTabTitle in websocket.json. Beginnt eine Leitung zu klingeln,
holt SwyxTray den ersten Firefox-Tab mit passendem Titel ueber das Plugin
nach vorn, ohne ihn neu zu laden.

Das Plugin allein scheitert dabei am Foreground-Lock von Windows: es kann
den Tab aktivieren, das Fenster bleibt aber hinter der gerade fokussierten
Anwendung. FirefoxWindow uebernimmt deshalb den nativen Teil - EnumWindows
auf MozillaWindowClass, minimierte Fenster wiederherstellen, dann
SetForegroundWindow mit AttachThreadInput, notfalls ALT-Tastendruck.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-28 14:33:51 +02:00
co-authored by Claude Fable 5
parent 6d03d31a95
commit 748687ce1c
8 changed files with 391 additions and 29 deletions
+9 -7
View File
@@ -50,8 +50,9 @@ internal sealed class ClientCommand
public bool? Ok { get; set; }
/// <summary>
/// Bei <c>closetab</c> (Hauptport): der zu schliessende Tab. Bei
/// <c>tabresult</c> auf <c>open</c> (Plugin-Port): Id des neuen Tabs.
/// Bei <c>closetab</c> und <c>activatetab</c> (Hauptport): der gemeinte
/// Tab. Bei <c>tabresult</c> auf <c>open</c> (Plugin-Port): Id des neuen
/// Tabs.
/// </summary>
public int? TabId { get; set; }
@@ -115,12 +116,13 @@ internal sealed record ResultMessage(
}
/// <summary>
/// Auftrag an das Firefox-Plugin, nur auf dem Plugin-Port. Drei Aktionen:
/// Auftrag an das Firefox-Plugin, nur auf dem Plugin-Port. Vier Aktionen:
/// <c>list</c> (offene Tabs melden), <c>open</c> (neuen Tab mit <c>Url</c>
/// oeffnen), <c>close</c> (Tab <c>TabId</c> schliessen). Das Plugin antwortet
/// jeweils mit <c>{"cmd":"tabresult","id":…,"ok":…}</c> — bei <c>list</c>
/// zusaetzlich mit <c>tabs</c>, bei <c>open</c> mit <c>tabId</c>. Die Id
/// stammt hier vom Server, nicht von einer Webseite.
/// oeffnen), <c>close</c> (Tab <c>TabId</c> schliessen), <c>activate</c>
/// (Tab <c>TabId</c> nach vorn holen, ohne ihn neu zu laden). Das Plugin
/// antwortet jeweils mit <c>{"cmd":"tabresult","id":…,"ok":…}</c> — bei
/// <c>list</c> zusaetzlich mit <c>tabs</c>, bei <c>open</c> mit <c>tabId</c>.
/// Die Id stammt hier vom Server, nicht von einer Webseite.
/// </summary>
internal sealed record TabRequestMessage(int Id, string Action, string? Url = null, int? TabId = null)
{