Skip to content

Commit

Permalink
feat: Add some streaming executors which support delays
Browse files Browse the repository at this point in the history
  • Loading branch information
mmstick committed Jan 12, 2021
1 parent fb9f2ed commit ad72dee
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 62 deletions.
62 changes: 62 additions & 0 deletions src/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,65 @@ export class GLibExecutor<T> implements Executor<T> {
});
}
}

export class OnceExecutor<X, T extends Iterable<X>> {
#iterable: T
#signal: SignalID | null = null

constructor(iterable: T) {
this.#iterable = iterable
}

start(delay: number, apply: (v: X) => boolean, then?: () => void) {
this.stop()

const iterator = this.#iterable[Symbol.iterator]()

this.#signal = GLib.timeout_add(GLib.PRIORITY_DEFAULT, delay, () => {
const next: X = iterator.next().value

if (typeof next === 'undefined') {
if (then) GLib.timeout_add(GLib.PRIORITY_DEFAULT, delay, () => {
then()
return false
})

return false
}

return apply(next)
})
}

stop() {
if (this.#signal !== null) GLib.source_remove(this.#signal)
}
}

export class ChannelExecutor<X> {
#channel: Array<X> = new Array()

#signal: null | number = null

clear() { this.#channel.splice(0) }

get length(): number { return this.#channel.length }

send(v: X) {
this.#channel.push(v)
}

start(delay: number, apply: (v: X) => boolean) {
this.stop()

this.#signal = GLib.timeout_add(GLib.PRIORITY_DEFAULT, delay, () => {
const e = this.#channel.shift();

return typeof e === 'undefined' ? true : apply(e)
});
}

stop() {
if (this.#signal !== null) GLib.source_remove(this.#signal)
}
}
86 changes: 29 additions & 57 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as Executor from 'executor';
import * as movement from 'movement';
import * as stack from 'stack';
import * as add_exception from 'dialog_add_exception';
import * as exec from 'executor';

import type { Entity } from 'ecs';
import type { ExtEvent } from 'events';
Expand Down Expand Up @@ -195,10 +196,6 @@ export class Ext extends Ecs.System<ExtEvent> {
/** Calculates window placements when tiling and focus-switching */
tiler: Tiling.Tiler = new Tiling.Tiler(this);

tiler_active: boolean = false;

tiler_queue: null | SignalID = null;

constructor() {
super(new Executor.GLibExecutor());

Expand Down Expand Up @@ -1454,29 +1451,10 @@ export class Ext extends Ecs.System<ExtEvent> {
signals_attach() {
this.conf_watch = this.attach_config();

this.tiler_queue = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, () => {
if (this.tiler_active) return true;

const m = this.tiler.movements.shift();

if (m) {
this.tiler_active = true;

const callback = () => {
m();
this.tiler_active = false;
};

if (!this.schedule_idle(() => {
callback();
return false;
})) {
callback();
}
}

return true;
});
this.tiler.queue.start(100, (movement) => {
movement()
return true
})

const workspace_manager = wom;

Expand Down Expand Up @@ -1661,9 +1639,7 @@ export class Ext extends Ecs.System<ExtEvent> {
this.conf_watch = null;
}

if (this.tiler_queue !== null) {
GLib.source_remove(this.tiler_queue)
}
this.tiler.queue.stop()

this.signals.clear();
}
Expand Down Expand Up @@ -1888,41 +1864,37 @@ export class Ext extends Ecs.System<ExtEvent> {
}
}

let migrations: Array<[Fork, number, Rectangle, boolean]> = new Array()
type Migration = [Fork, number, Rectangle, boolean]

let migrations: Array<Migration> = new Array()

const apply_migrations = (assigned_monitors: Set<number>) => {
if (!migrations) return

const iterator = migrations[Symbol.iterator]()

GLib.timeout_add(GLib.PRIORITY_LOW, 500, () => {
let next: null | [Fork, number, Rectangle, boolean] = iterator.next().value;

if (next) {
const [fork, new_monitor, workspace, find_workspace] = next
let new_workspace

if (find_workspace) {
if (assigned_monitors.has(new_monitor)) {
[new_workspace] = this.find_unused_workspace(new_monitor)
new exec.OnceExecutor<Migration, Migration[]>(migrations)
.start(
500,
([fork, new_monitor, workspace, find_workspace]) => {
let new_workspace

if (find_workspace) {
if (assigned_monitors.has(new_monitor)) {
[new_workspace] = this.find_unused_workspace(new_monitor)
} else {
assigned_monitors.add(new_monitor)
new_workspace = 0
}
} else {
assigned_monitors.add(new_monitor)
new_workspace = 0
new_workspace = fork.workspace
}
} else {
new_workspace = fork.workspace
}

fork.migrate(this, forest, workspace, new_monitor, new_workspace);
fork.set_ratio(fork.length() / 2)
fork.migrate(this, forest, workspace, new_monitor, new_workspace);
fork.set_ratio(fork.length() / 2)

return true
}

update_tiling()

return false
})
return true
},
() => update_tiling()
)
}

function mark_for_reassignment(ext: Ext, fork: Ecs.Entity) {
Expand Down
11 changes: 6 additions & 5 deletions src/tiling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import * as Tags from 'tags';
import * as Tweener from 'tweener';
import * as window from 'window';
import * as geom from 'geom';
import * as exec from 'executor';

import type { Entity } from './ecs';
import type { Rectangle } from './rectangle';
Expand All @@ -35,12 +36,12 @@ export class Tiler {

window: Entity | null = null;

movements: Array<() => void> = new Array();

moving: boolean = false;

private swap_window: Entity | null = null;

queue: exec.ChannelExecutor<() => void> = new exec.ChannelExecutor()

constructor(ext: Ext) {
this.keybindings = {
"management-orientation": () => {
Expand Down Expand Up @@ -187,8 +188,8 @@ export class Tiler {
move(ext: Ext, x: number, y: number, w: number, h: number, direction: Direction, focus: () => window.ShellWindow | number | null) {
if (!this.window) return;
if (ext.auto_tiler && !ext.contains_tag(this.window, Tags.Floating)) {
if (this.movements.length === 2) return;
this.movements.push(() => {
if (this.queue.length === 2) return;
this.queue.send(() => {
const focused = ext.focus_window();
if (focused) {
// The window that the focused window is being moved onto
Expand Down Expand Up @@ -662,7 +663,7 @@ export class Tiler {
}

exit(ext: Ext) {
this.movements.splice(0);
this.queue.clear()

if (this.window) {
this.window = null;
Expand Down

0 comments on commit ad72dee

Please sign in to comment.