summaryrefslogtreecommitdiff
path: root/src/clients/tile.rs
blob: 4a2d4fc6e8686fe5e4e711fc884062d9a03d0bd2 (plain)
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
56
57
58
59
60
61
62
63
64
65
66
67
68
use std::cmp::min;

use crate::conn_info::Connection;

use super::{MonitorGeometry, MonitorInfo};

/// A simple tiling function
#[allow(
    clippy::cast_sign_loss,
    clippy::cast_possible_wrap,
    clippy::cast_possible_truncation,
    clippy::cast_lossless
)]
pub fn tile(mon: &mut MonitorInfo, conn: &Connection<'_>) {
    if mon.clients.is_empty() {
        return;
    }

    let n = mon.clients_tiled_mut().count();
    let nmaster = 1;
    let mfact = 0.6;

    let MonitorGeometry {
        x_org,
        y_org,
        width: mon_width,
        height: mon_height,
    } = mon.screen_info;

    let main_width = if nmaster == 0 {
        0
    } else if n > nmaster {
        ((mon.screen_info.width as f64) * mfact) as u16
    } else {
        mon.screen_info.width
    };

    let (mut main_y, mut second_y) = (0, 0);
    for (i, c) in mon.clients_tiled_mut().enumerate() {
        if i < nmaster {
            let h = (mon_height - main_y) / (min(nmaster, n) - i) as u16;
            c.set_geom(
                conn,
                x_org,
                y_org + main_y as i16,
                main_width - (2 * c.border_width()),
                h - (2 * c.border_width()),
                c.border_width(),
            );

            main_y += h;
        } else {
            let h = (mon_height - second_y) / (n - i) as u16;
            c.set_geom(
                conn,
                x_org + main_width as i16,
                y_org + second_y as i16,
                mon_width - main_width - (2 * c.border_width()),
                h - (2 * c.border_width()),
                c.border_width(),
            );

            second_y += h;
        }

        c.ensure_mapped(conn);
    }
}