Regions for window managers.
Given a list of overlapping windows, how can they be efficiently rendered? Ideally, areas of windows covered by other windows are never drawn:
+------------+ +--------+
| | | |
| +-----------+ |
| | a | |
| +-----------+----+
| |
+------------+
But how to represent the above area after subtracting a
?
+------------+ +--------+
| | | c |
| +---+ +---+ |
| b | | |
| +---+ +----+
| |
+------------+
One method is to divide the area into a series of mutually exclusive horizontal bands:
+------------+ +--------+
| | | |
+--------+---+ +---+----+
| a | b | c | d <- 2nd band with walls at a, b, c, d.
+--------+---+ +----+
| |
+------------+
Each band is a vertical interval and a list of walls. Each contiguous pair of walls indicates a new rect in the band. A Region is a list of sorted, mutually exclusive bands.
To use regions
, construct an initial Region, r
, from some rect and iteratively +
, -
, &
, or ^
with other regions:
let
r = Rect(x: 0, y: 0, w: 60, h: 60).to_region
s = Rect(x: 0, y: 20, w: 40, h: 20).to_region
t = Rect(x: 0, y: 40, w: 20, h: 20).to_region
echo r - s - t
for rect in rects(r - s - t):
echo rect
Output:
Region(Band(y1: 0, y2: 20, walls: @[0, 60]), Band(y1: 20, y2: 40, walls: @[40, 60]), Band(y1: 40, y2: 60, walls: @[20, 60]))
Rect(x: 0, y: 0, w: 60, h: 20)
Rect(x: 40, y: 20, w: 20, h: 20)
Rect(x: 20, y: 40, w: 40, h: 20)