1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
open! Oxbow_core
open! Oxbow_state
open! Oxbow_layout
let arrange (wm : Wm.t) (output : Output.t) =
let windows = List.filter Window.tag_visible output.focus_stack in
let n = List.length windows in
if n = 0
then ()
else (
let bw = wm.config.borders.width |> Int32.to_int in
let gaps =
Params.Gaps.{ inner = output.overview.gaps; outer = output.overview.gaps }
in
let usable = Gaps.pre gaps output.usable in
let cols = min 3 n in
let row_h = usable.h / 2 in
let widths = Strip.split ~total:usable.w ~count:cols |> Array.of_list in
let _, xs = Array.fold_left_map (fun x w -> x + w, x) usable.x widths in
let max_offset = (n - 1) / cols * row_h in
let offset =
match Output.focused_window output with
| Some f ->
(match List.find_index (( == ) f) windows with
| Some i ->
let row = i / cols in
Strip.scroll
~align:Visible
~viewport_w:usable.h
~max_offset
~offset:output.overview.offset
~col:(row * row_h, row_h)
| None -> min output.overview.offset max_offset |> max 0)
| None -> min output.overview.offset max_offset |> max 0
in
output.overview.offset <- offset;
List.iteri
(fun i window ->
let col = i mod cols in
let row = i / cols in
let rect =
Rect.
{ x = xs.(col)
; y = usable.y + (row * row_h) - offset
; w = widths.(col)
; h = row_h
}
in
let cell = Gaps.post gaps rect in
Rect.inset ~by:bw cell |> Window.clamp window |> Window.set_geom window;
let bound = Rect.intersect cell output.usable in
Option.is_none bound |> Window.set_offscreen window;
Window.set_clip_within window ~tag:`Overview ~bw ~bound)
windows)
;;