@@ -18,6 +18,7 @@ public class Gala.WindowCloneContainer : ActorTarget {
1818
1919 public WindowManager wm { get ; construct; }
2020 public WindowListModel windows { get ; construct; }
21+ public int monitor { get ; construct; }
2122 public float monitor_scale { get ; construct set ; }
2223 public bool overview_mode { get ; construct; }
2324
@@ -29,8 +30,8 @@ public class Gala.WindowCloneContainer : ActorTarget {
2930 */
3031 private unowned WindowClone ? current_window = null ;
3132
32- public WindowCloneContainer (WindowManager wm, WindowListModel windows, float monitor_scale, bool overview_mode = false ) {
33- Object (wm: wm, windows: windows, monitor_scale: monitor_scale, overview_mode: overview_mode);
33+ public WindowCloneContainer (WindowManager wm, WindowListModel windows, int monitor, float monitor_scale, bool overview_mode = false ) {
34+ Object (wm: wm, windows: windows, monitor : monitor, monitor_scale: monitor_scale, overview_mode: overview_mode);
3435 }
3536
3637 construct {
@@ -140,14 +141,7 @@ public class Gala.WindowCloneContainer : ActorTarget {
140141 return (int ) (seq_b - seq_a);
141142 });
142143
143- Mtk . Rectangle area = {
144- padding_left,
145- padding_top,
146- (int ) width - padding_left - padding_right,
147- (int ) height - padding_top - padding_bottom
148- };
149-
150- foreach (var tilable in calculate_grid_placement (area, windows)) {
144+ foreach (var tilable in calculate_window_clones_placement (windows)) {
151145 tilable. clone. take_slot (tilable. rect, ! view_toggle);
152146 }
153147 }
@@ -322,10 +316,95 @@ public class Gala.WindowCloneContainer : ActorTarget {
322316 Mtk . Rectangle rect;
323317 }
324318
319+ private bool windows_overlap (GLib . List<TilableWindow ?> windows) {
320+ var checked_rects = new GLib .List<Mtk . Rectangle ?> ();
321+ foreach (var tilable in windows) {
322+ var window_rect = tilable. clone. window. get_frame_rect ();
323+ foreach (var checked_rect in checked_rects) {
324+ if (window_rect. overlap (checked_rect)) {
325+ return true ;
326+ }
327+ }
328+
329+ checked_rects. append (window_rect);
330+ }
331+
332+ return false ;
333+ }
334+
335+ private bool window_out_of_screen (GLib . List<TilableWindow ?> windows) {
336+ foreach (var tilable in windows) {
337+ unowned var window = tilable. clone. window;
338+ var window_rect = window. get_frame_rect ();
339+ var monitor_geometry = window. display. get_monitor_geometry (window. get_monitor ());
340+ if (window_rect. x < monitor_geometry. x ||
341+ window_rect. y < monitor_geometry. y ||
342+ window_rect. x + window_rect. width > monitor_geometry. width ||
343+ window_rect. y + window_rect. height > monitor_geometry. height
344+ ) {
345+ return true ;
346+ }
347+ }
348+
349+ return false ;
350+ }
351+
352+ private Mtk . Rectangle get_rectangle_with_padding () {
353+ return {
354+ padding_left,
355+ padding_top,
356+ (int ) width - padding_left - padding_right,
357+ (int ) height - padding_top - padding_bottom
358+ };
359+ }
360+
361+ private GLib . List<TilableWindow ?> calculate_window_clones_placement (GLib . List<TilableWindow ?> windows) {
362+ if (windows_overlap (windows) || window_out_of_screen (windows)) {
363+ return calculate_grid_placement (windows);
364+ } else {
365+ Mtk . Rectangle area;
366+ if (overview_mode) {
367+ area = { 0 , 0 , (int ) width, (int ) height };
368+ } else {
369+ area = get_rectangle_with_padding ();
370+ }
371+
372+ var monitor_geometry = wm. get_display (). get_monitor_geometry (monitor);
373+ var scale = (float ) area. width / monitor_geometry. width;
374+
375+ var result = new GLib .List<TilableWindow ?> ();
376+ foreach (var tilable in windows) {
377+ Mtk . Rectangle rect;
378+ #if HAS_MUTTER46
379+ tilable. rect. scale_double (scale, Mtk . RoundingStrategy . ROUND , out rect);
380+ #else
381+ rect = {
382+ 0 ,
383+ 0 ,
384+ Utils . scale_to_int (tilable. rect. width, scale),
385+ Utils . scale_to_int (tilable. rect. height, scale)
386+ };
387+ #endif
388+
389+ var x_ratio = (float ) tilable. rect. x / monitor_geometry. width;
390+ rect. x = area. x + Utils . scale_to_int (area. width, x_ratio);
391+
392+ var y_ratio = (float ) tilable. rect. y / monitor_geometry. height;
393+ rect. y = area. y + Utils . scale_to_int (area. height, y_ratio);
394+
395+ result. append ({ tilable. clone, rect });
396+ }
397+
398+ return result;
399+ }
400+ }
401+
325402 /**
326403 * Careful: List<TilableWindow?> windows will be modified in place and shouldn't be used afterwards.
327404 */
328- private GLib . List<TilableWindow ?> calculate_grid_placement (Mtk . Rectangle area, GLib . List<TilableWindow ?> windows) {
405+ private GLib . List<TilableWindow ?> calculate_grid_placement (GLib . List<TilableWindow ?> windows) {
406+ var area = get_rectangle_with_padding ();
407+
329408 uint window_count = windows. length ();
330409 int columns = (int ) Math . ceil (Math . sqrt (window_count));
331410 int rows = (int ) Math . ceil (window_count / (double ) columns);
0 commit comments