DesktopManager: add per-screen support

This commit is contained in:
Peter Fajdiga
2024-07-08 19:27:44 +02:00
parent b85c86e7db
commit d7df3901e2
4 changed files with 59 additions and 29 deletions

View File

@@ -8,6 +8,7 @@ type Workspace = {
readonly currentDesktop: KwinDesktop;
readonly currentActivity: string;
readonly activeScreen: Output;
readonly screens: Output[];
readonly windows: KwinClient[];
readonly cursorPos: Readonly<QmlPoint>;
@@ -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]>

View File

@@ -3,53 +3,62 @@ class DesktopManager {
private readonly config: Desktop.Config;
public readonly layoutConfig: LayoutConfig;
private readonly desktops: Map<string, Desktop>; // key is activityId|desktopId
private kwinScreens: Set<Output>;
private kwinActivities: Set<string>;
private kwinDesktops: Set<KwinDesktop>;
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;
}
}
}
}

View File

@@ -49,6 +49,7 @@ class World {
clamper: config.scrollingLazy ? new EdgeClamper() : new CenterClamper(),
},
layoutConfig,
Workspace.activeScreen,
Workspace.currentActivity,
Workspace.currentDesktop,
);

View File

@@ -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;
}
}