Skip to content

Commit 5f293ad

Browse files
mmstickjackpot51
authored andcommitted
fix: When moving window across workspaces, place on nearest window in new space
1 parent 58f21bc commit 5f293ad

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/extension.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as Forest from 'forest';
55
import * as Ecs from 'ecs';
66
import * as Events from 'events';
77
import * as Focus from 'focus';
8+
import * as Geom from 'geom';
89
import * as GrabOp from 'grab_op';
910
import * as Keybindings from 'keybindings';
1011
import * as Lib from 'lib';
@@ -28,7 +29,7 @@ import * as scheduler from 'scheduler';
2829

2930
import type { Entity } from 'ecs';
3031
import type { ExtEvent } from 'events';
31-
import type { Rectangle } from 'rectangle';
32+
import { Rectangle } from 'rectangle';
3233
import type { Indicator } from 'panel_settings';
3334
import type { Launcher } from 'launcher';
3435

@@ -1250,6 +1251,7 @@ export class Ext extends Ecs.System<ExtEvent> {
12501251
win.meta.unmaximize(Meta.MaximizeFlags.VERTICAL);
12511252
win.meta.unmaximize(Meta.MaximizeFlags.BOTH);
12521253
}
1254+
12531255
this.register(Events.window_move(this, win, rect));
12541256
} else {
12551257
win.move(this, rect, () => {});
@@ -1300,12 +1302,45 @@ export class Ext extends Ecs.System<ExtEvent> {
13001302
return last;
13011303
}
13021304

1305+
/** Places window onto the nearest window of a given workspace */
1306+
const place_on_nearest_window = (auto_tiler: auto_tiler.AutoTiler, ws: Meta.Workspace, monitor: number) => {
1307+
const src = win.meta.get_frame_rect()
1308+
1309+
auto_tiler.detach_window(this, win.entity);
1310+
1311+
const index = ws.index()
1312+
const coord: [number, number] = [src.x, src.y]
1313+
1314+
let nearest_window = null
1315+
let nearest_distance = null
1316+
1317+
for (const [entity, window] of this.windows.iter()) {
1318+
const other_monitor = window.meta.get_monitor()
1319+
const other_index = window.meta.get_workspace().index()
1320+
if (!this.contains_tag(entity, Tags.Floating) && other_monitor == monitor && other_index === index && !Ecs.entity_eq(win.entity, window.entity)) {
1321+
const other_rect = window.rect()
1322+
const other_coord: [number, number] = [other_rect.x, other_rect.y]
1323+
const distance = Geom.distance(coord, other_coord)
1324+
if (nearest_distance === null || nearest_distance > distance) {
1325+
nearest_window = window
1326+
nearest_distance = distance
1327+
}
1328+
}
1329+
}
1330+
1331+
if (nearest_window === null) {
1332+
auto_tiler.attach_to_workspace(this, win, [monitor, index]);
1333+
} else {
1334+
auto_tiler.attach_to_window(this, nearest_window, win, { src }, false)
1335+
}
1336+
}
1337+
13031338
const move_to_neighbor = (neighbor: Meta.Workspace) => {
13041339
const monitor = win.meta.get_monitor();
13051340
if (this.auto_tiler && win.is_tilable(this)) {
13061341
win.ignore_detach = true;
1307-
this.auto_tiler.detach_window(this, win.entity);
1308-
this.auto_tiler.attach_to_workspace(this, win, [monitor, neighbor.index()]);
1342+
1343+
place_on_nearest_window(this.auto_tiler, neighbor, monitor)
13091344

13101345
if (win.meta.minimized) {
13111346
this.size_signals_block(win);

src/forest.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,12 @@ export class Forest extends Ecs.World {
264264
} else {
265265
fork.right = right_node;
266266
fork.set_ratio(fork.length() / 2);
267+
268+
if ("src" in place_by) {
269+
const [left, right] = area_of_halves(fork)
270+
place_by_keyboard(fork, place_by.src, left, right)
271+
}
272+
267273
return this._attach(onto_entity, new_entity, this.on_attach, entity, fork, null);
268274
}
269275
} else if (fork.left.is_in_stack(onto_entity)) {

0 commit comments

Comments
 (0)