@@ -5,6 +5,7 @@ import * as Forest from 'forest';
5
5
import * as Ecs from 'ecs' ;
6
6
import * as Events from 'events' ;
7
7
import * as Focus from 'focus' ;
8
+ import * as Geom from 'geom' ;
8
9
import * as GrabOp from 'grab_op' ;
9
10
import * as Keybindings from 'keybindings' ;
10
11
import * as Lib from 'lib' ;
@@ -28,7 +29,7 @@ import * as scheduler from 'scheduler';
28
29
29
30
import type { Entity } from 'ecs' ;
30
31
import type { ExtEvent } from 'events' ;
31
- import type { Rectangle } from 'rectangle' ;
32
+ import { Rectangle } from 'rectangle' ;
32
33
import type { Indicator } from 'panel_settings' ;
33
34
import type { Launcher } from 'launcher' ;
34
35
@@ -1250,6 +1251,7 @@ export class Ext extends Ecs.System<ExtEvent> {
1250
1251
win . meta . unmaximize ( Meta . MaximizeFlags . VERTICAL ) ;
1251
1252
win . meta . unmaximize ( Meta . MaximizeFlags . BOTH ) ;
1252
1253
}
1254
+
1253
1255
this . register ( Events . window_move ( this , win , rect ) ) ;
1254
1256
} else {
1255
1257
win . move ( this , rect , ( ) => { } ) ;
@@ -1300,12 +1302,45 @@ export class Ext extends Ecs.System<ExtEvent> {
1300
1302
return last ;
1301
1303
}
1302
1304
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
+
1303
1338
const move_to_neighbor = ( neighbor : Meta . Workspace ) => {
1304
1339
const monitor = win . meta . get_monitor ( ) ;
1305
1340
if ( this . auto_tiler && win . is_tilable ( this ) ) {
1306
1341
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 )
1309
1344
1310
1345
if ( win . meta . minimized ) {
1311
1346
this . size_signals_block ( win ) ;
0 commit comments