Compare commits
4 Commits
master
...
signal-gro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d68494d257 | ||
|
|
679d1d488c | ||
|
|
ce4884c48a | ||
|
|
1c89391739 |
62
src/lib/utils/SignalGrouping.ts
Normal file
62
src/lib/utils/SignalGrouping.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
namespace SignalGrouping {
|
||||||
|
export class Group {
|
||||||
|
private argsBySignal: Map<QSignal<[any]>, [[any]]> = new Map();
|
||||||
|
private delayer = new Delayer(50, () => this.fire());
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private handlers: Handler<any>[], // in order of decreasing priority
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public connect(manager: SignalManager) {
|
||||||
|
const signals = collectSignals(this.handlers);
|
||||||
|
for (const signal of signals) {
|
||||||
|
manager.connect(signal, (...args: any) => {
|
||||||
|
this.argsBySignal.set(signal, args);
|
||||||
|
this.delayer.run();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fire() {
|
||||||
|
for (const handler of this.handlers) {
|
||||||
|
const args = this.getGroupArgs(handler.signals);
|
||||||
|
if (args !== null) {
|
||||||
|
handler.f(args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.argsBySignal.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private getGroupArgs(signals: QSignal<[any]>[]) {
|
||||||
|
const groupArgs = signals.map(signal => this.argsBySignal.get(signal));
|
||||||
|
if (groupArgs.some(args => args === undefined)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return groupArgs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectSignals<S extends QSignal<any>[]>(handlers: Handler<S>[]) {
|
||||||
|
const signals: S[number][] = [];
|
||||||
|
for (const handler of handlers) {
|
||||||
|
for (const signal of handler.signals) {
|
||||||
|
if (!signals.includes(signal)) {
|
||||||
|
signals.push(signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return signals;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Handler<S extends QSignal<any>[]> {
|
||||||
|
constructor(
|
||||||
|
public signals: [...S],
|
||||||
|
public f: (...args: [...GroupArgs<S>]) => void,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
type GroupArgs<S extends QSignal<any>[]> = {
|
||||||
|
[K in keyof S]: S[K] extends QSignal<infer A> ? A : never;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -7,22 +7,40 @@ function initWorkspaceSignalHandlers(world: World, focusPasser: FocusPassing.Pas
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
manager.connect(Workspace.windowRemoved, (kwinClient: KwinClient) => {
|
new SignalGrouping.Group([
|
||||||
world.do((clientManager, desktopManager) => {
|
new SignalGrouping.Handler(
|
||||||
clientManager.removeClient(kwinClient, FocusPassing.Type.Immediate);
|
[Workspace.windowRemoved, Workspace.windowActivated] as const,
|
||||||
});
|
(windowRemovedArgs, windowActivatedArgs) => {
|
||||||
});
|
const kwinClient = windowRemovedArgs[0];
|
||||||
|
world.do((clientManager, desktopManager) => {
|
||||||
manager.connect(Workspace.windowActivated, (kwinClient: KwinClient|null) => {
|
clientManager.removeClient(kwinClient, FocusPassing.Type.Immediate);
|
||||||
if (kwinClient === null) {
|
});
|
||||||
focusPasser.activate();
|
},
|
||||||
} else {
|
),
|
||||||
focusPasser.clearIfDifferent(kwinClient);
|
new SignalGrouping.Handler(
|
||||||
world.do((clientManager, desktopManager) => {
|
[Workspace.windowRemoved],
|
||||||
clientManager.onClientFocused(kwinClient);
|
(windowRemovedArgs) => {
|
||||||
});
|
const kwinClient = windowRemovedArgs[0];
|
||||||
}
|
world.do((clientManager, desktopManager) => {
|
||||||
});
|
clientManager.removeClient(kwinClient, FocusPassing.Type.Immediate);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
new SignalGrouping.Handler(
|
||||||
|
[Workspace.windowActivated],
|
||||||
|
(windowActivatedArgs) => {
|
||||||
|
const kwinClient = windowActivatedArgs[0];
|
||||||
|
if (kwinClient === null) {
|
||||||
|
focusPasser.activate();
|
||||||
|
} else {
|
||||||
|
focusPasser.clearIfDifferent(kwinClient);
|
||||||
|
world.do((clientManager, desktopManager) => {
|
||||||
|
clientManager.onClientFocused(kwinClient);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]).connect(manager);
|
||||||
|
|
||||||
manager.connect(Workspace.currentDesktopChanged, () => {
|
manager.connect(Workspace.currentDesktopChanged, () => {
|
||||||
world.do(() => {}); // re-arrange desktop
|
world.do(() => {}); // re-arrange desktop
|
||||||
|
|||||||
@@ -54,12 +54,14 @@ class MockWorkspace {
|
|||||||
public removeWindow(window: MockKwinClient) {
|
public removeWindow(window: MockKwinClient) {
|
||||||
this.activeWindow = null;
|
this.activeWindow = null;
|
||||||
runReorder(
|
runReorder(
|
||||||
|
() => {
|
||||||
|
if (this.activeWindow === null) {
|
||||||
|
activateRandomWindowOnDesktop(this.currentDesktop);
|
||||||
|
};
|
||||||
|
},
|
||||||
() => this.windows.splice(this.windows.indexOf(window), 1),
|
() => this.windows.splice(this.windows.indexOf(window), 1),
|
||||||
() => this.windowRemoved.fire(window),
|
() => this.windowRemoved.fire(window),
|
||||||
);
|
);
|
||||||
if (this.activeWindow === null) {
|
|
||||||
activateRandomWindowOnDesktop(this.currentDesktop);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public moveWindow(window: MockKwinClient, ...deltas: QmlPoint[]) {
|
public moveWindow(window: MockKwinClient, ...deltas: QmlPoint[]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user