diff --git a/src/lib/extern/kwin.ts b/src/lib/extern/kwin.ts index 43a32ec..a91a27c 100644 --- a/src/lib/extern/kwin.ts +++ b/src/lib/extern/kwin.ts @@ -8,6 +8,7 @@ type Workspace = { readonly currentDesktop: KwinDesktop; readonly currentActivity: string; readonly activeScreen: Output; + readonly screens: Output[]; readonly windows: KwinClient[]; readonly cursorPos: Readonly; @@ -44,7 +45,10 @@ const enum MaximizedMode { } type Tile = unknown; -type Output = unknown; + +type Output = { + name: string; +}; interface KwinClient { readonly shadeable: boolean; @@ -81,6 +85,7 @@ interface KwinClient { readonly fullScreenChanged: QSignal<[]>; readonly desktopsChanged: QSignal<[]>; + readonly outputChanged: QSignal<[]>; readonly activitiesChanged: QSignal<[]>; readonly minimizedChanged: QSignal<[]>; readonly maximizedAboutToChange: QSignal<[MaximizedMode]> diff --git a/src/lib/world/DesktopManager.ts b/src/lib/world/DesktopManager.ts index c473a0c..b9dec25 100644 --- a/src/lib/world/DesktopManager.ts +++ b/src/lib/world/DesktopManager.ts @@ -3,53 +3,62 @@ class DesktopManager { private readonly config: Desktop.Config; public readonly layoutConfig: LayoutConfig; private readonly desktops: Map; // key is activityId|desktopId + private kwinScreens: Set; private kwinActivities: Set; private kwinDesktops: Set; - constructor(pinManager: PinManager, config: Desktop.Config, layoutConfig: LayoutConfig, currentActivity: string, currentDesktop: KwinDesktop) { + constructor( + pinManager: PinManager, + config: Desktop.Config, + layoutConfig: LayoutConfig, + currentScreen: Output, + currentActivity: string, + currentDesktop: KwinDesktop + ) { this.pinManager = pinManager; this.config = config; this.layoutConfig = layoutConfig; this.desktops = new Map(); + this.kwinScreens = new Set(Workspace.screens); this.kwinActivities = new Set(Workspace.activities); this.kwinDesktops = new Set(Workspace.desktops); - this.addDesktop(currentActivity, currentDesktop); + this.addDesktop(currentScreen, currentActivity, currentDesktop); } - public getDesktop(activity: string, kwinDesktop: KwinDesktop) { - const desktopKey = DesktopManager.getDesktopKey(activity, kwinDesktop); + public getDesktop(screen: Output, activity: string, kwinDesktop: KwinDesktop) { + const desktopKey = DesktopManager.getDesktopKey(screen, activity, kwinDesktop); const desktop = this.desktops.get(desktopKey); if (desktop !== undefined) { return desktop; } else { - return this.addDesktop(activity, kwinDesktop); + return this.addDesktop(screen, activity, kwinDesktop); } } public getCurrentDesktop() { - return this.getDesktop(Workspace.currentActivity, Workspace.currentDesktop); + return this.getDesktop(Workspace.activeScreen, Workspace.currentActivity, Workspace.currentDesktop); } public getDesktopInCurrentActivity(kwinDesktop: KwinDesktop) { - return this.getDesktop(Workspace.currentActivity, kwinDesktop); + return this.getDesktop(Workspace.activeScreen, Workspace.currentActivity, kwinDesktop); } public getDesktopForClient(kwinClient: KwinClient) { if (kwinClient.activities.length !== 1 || kwinClient.desktops.length !== 1) { return undefined; } - return this.getDesktop(kwinClient.activities[0], kwinClient.desktops[0]); + return this.getDesktop(kwinClient.output, kwinClient.activities[0], kwinClient.desktops[0]); } - private addDesktop(activity: string, kwinDesktop: KwinDesktop) { - const desktopKey = DesktopManager.getDesktopKey(activity, kwinDesktop); + private addDesktop(screen: Output, activity: string, kwinDesktop: KwinDesktop) { + const desktopKey = DesktopManager.getDesktopKey(screen, activity, kwinDesktop); const desktop = new Desktop(kwinDesktop, this.pinManager, this.config, this.layoutConfig); this.desktops.set(desktopKey, desktop); return desktop; } - private static getDesktopKey(activity: string, kwinDesktop: KwinDesktop) { - return activity + "|" + kwinDesktop.id; + private static getDesktopKey(screen: Output, activity: string, kwinDesktop: KwinDesktop) { + return screen.name + "|" + activity + "|" + kwinDesktop.id; } public updateActivities() { @@ -73,19 +82,23 @@ class DesktopManager { } private removeActivity(activity: string) { - for (const kwinDesktop of this.kwinDesktops) { - this.destroyDesktop(activity, kwinDesktop); + for (const kwinScreen of this.kwinScreens) { + for (const kwinDesktop of this.kwinDesktops) { + this.destroyDesktop(kwinScreen, activity, kwinDesktop); + } } } private removeKwinDesktop(kwinDesktop: KwinDesktop) { - for (const activity of this.kwinActivities) { - this.destroyDesktop(activity, kwinDesktop); + for (const kwinScreen of this.kwinScreens) { + for (const activity of this.kwinActivities) { + this.destroyDesktop(kwinScreen, activity, kwinDesktop); + } } } - private destroyDesktop(activity: string, kwinDesktop: KwinDesktop) { - const desktopKey = DesktopManager.getDesktopKey(activity, kwinDesktop); + private destroyDesktop(screen: Output, activity: string, kwinDesktop: KwinDesktop) { + const desktopKey = DesktopManager.getDesktopKey(screen, activity, kwinDesktop); const desktop = this.desktops.get(desktopKey); if (desktop !== undefined) { desktop.destroy(); @@ -106,20 +119,23 @@ class DesktopManager { } public getDesktopsForClient(kwinClient: KwinClient) { - const desktops = this.getDesktops(kwinClient.activities, kwinClient.desktops); // workaround for QTBUG-109880 + const desktops = this.getDesktops([kwinClient.output], kwinClient.activities, kwinClient.desktops); // workaround for QTBUG-109880 return desktops; } // empty array means all - public *getDesktops(activities: string[], kwinDesktops: KwinDesktop[]) { + public *getDesktops(screens: Output[], activities: string[], kwinDesktops: KwinDesktop[]) { + const matchedScreens = screens.length > 0 ? screens : this.kwinScreens.keys(); const matchedActivities = activities.length > 0 ? activities : this.kwinActivities.keys(); const matchedDesktops = kwinDesktops.length > 0 ? kwinDesktops : this.kwinDesktops.keys(); - for (const matchedActivity of matchedActivities) { - for (const matchedDesktop of matchedDesktops) { - const desktopKey = DesktopManager.getDesktopKey(matchedActivity, matchedDesktop); - const desktop = this.desktops.get(desktopKey); - if (desktop !== undefined) { - yield desktop; + for (const matchedScreen of matchedScreens) { + for (const matchedActivity of matchedActivities) { + for (const matchedDesktop of matchedDesktops) { + const desktopKey = DesktopManager.getDesktopKey(matchedScreen, matchedActivity, matchedDesktop); + const desktop = this.desktops.get(desktopKey); + if (desktop !== undefined) { + yield desktop; + } } } } diff --git a/src/lib/world/World.ts b/src/lib/world/World.ts index 33f4f28..90b98bc 100644 --- a/src/lib/world/World.ts +++ b/src/lib/world/World.ts @@ -49,6 +49,7 @@ class World { clamper: config.scrollingLazy ? new EdgeClamper() : new CenterClamper(), }, layoutConfig, + Workspace.activeScreen, Workspace.currentActivity, Workspace.currentDesktop, ); diff --git a/src/lib/world/clientState/Pinned.ts b/src/lib/world/clientState/Pinned.ts index 2d09199..73926fe 100644 --- a/src/lib/world/clientState/Pinned.ts +++ b/src/lib/world/clientState/Pinned.ts @@ -61,7 +61,7 @@ namespace ClientState { [] : union(oldDesktops, kwinClient.desktops); world.do((clientManager, desktopManager) => { - for (const desktop of desktopManager.getDesktops(kwinClient.activities, changedDesktops)) { + for (const desktop of desktopManager.getDesktops([kwinClient.output], kwinClient.activities, changedDesktops)) { desktop.onPinsChanged(); } }); @@ -73,13 +73,21 @@ namespace ClientState { [] : union(oldActivities, kwinClient.activities); world.do((clientManager, desktopManager) => { - for (const desktop of desktopManager.getDesktops(changedActivities, kwinClient.desktops)) { + for (const desktop of desktopManager.getDesktops([kwinClient.output], changedActivities, kwinClient.desktops)) { desktop.onPinsChanged(); } }); oldActivities = kwinClient.activities; }); + manager.connect(kwinClient.outputChanged, () => { + world.do((clientManager, desktopManager) => { + for (const desktop of desktopManager.getDesktops([kwinClient.output], kwinClient.activities, kwinClient.desktops)) { + desktop.onPinsChanged(); + } + }); + }); + return manager; } }