~andreafeletto/levee

ref: f2b74950b7431f6024814ff54cbc0949e29e9a5d levee/src/Bar.zig -rw-r--r-- 3.5 KiB
f2b74950Andrea Feletto add args for help and modules 5 months ago
                                                                                
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
const std = @import("std");
const mem = std.mem;

const wl = @import("wayland").client.wl;
const zwlr = @import("wayland").client.zwlr;

const Buffer = @import("Buffer.zig");
const Monitor = @import("wayland.zig").Monitor;
const render = @import("render.zig");
const State = @import("main.zig").State;
const Bar = @This();

monitor: *Monitor,

layerSurface: *zwlr.LayerSurfaceV1,
background: struct {
    surface: *wl.Surface,
    buffer: Buffer,
},

tags: Widget,
clock: Widget,
modules: Widget,

configured: bool,
width: u16,
height: u16,

pub const Widget = struct {
    surface: *wl.Surface,
    subsurface: *wl.Subsurface,
    buffers: [2]Buffer,

    pub fn init(state: *State, background: *wl.Surface) !Widget {
        const globals = &state.wayland.globals;

        const surface = try globals.compositor.createSurface();
        const subsurface = try globals.subcompositor.getSubsurface(
            surface,
            background,
        );

        return Widget{
            .surface = surface,
            .subsurface = subsurface,
            .buffers = mem.zeroes([2]Buffer),
        };
    }

    pub fn deinit(self: *Widget) void {
        self.surface.destroy();
        self.subsurface.destroy();
        self.buffers[0].deinit();
        self.buffers[1].deinit();
    }
};

pub fn create(monitor: *Monitor) !*Bar {
    const state = monitor.state;
    const globals = &state.wayland.globals;

    const self = try state.gpa.create(Bar);
    self.monitor = monitor;
    self.configured = false;

    self.background.surface = try globals.compositor.createSurface();
    self.layerSurface = try globals.layerShell.getLayerSurface(
        self.background.surface,
        monitor.output,
        .top,
        "levee",
    );
    self.background.buffer = mem.zeroes(Buffer);

    self.tags = try Widget.init(state, self.background.surface);
    self.clock = try Widget.init(state, self.background.surface);
    self.modules = try Widget.init(state, self.background.surface);

    // setup layer surface
    self.layerSurface.setSize(0, state.config.height);
    self.layerSurface.setAnchor(
        .{ .top = true, .left = true, .right = true, .bottom = false },
    );
    self.layerSurface.setExclusiveZone(state.config.height);
    self.layerSurface.setMargin(0, 0, 0, 0);
    self.layerSurface.setListener(*Bar, layerSurfaceListener, self);

    self.tags.surface.commit();
    self.clock.surface.commit();
    self.modules.surface.commit();
    self.background.surface.commit();

    return self;
}

pub fn destroy(self: *Bar) void {
    self.monitor.bar = null;

    self.background.surface.destroy();
    self.layerSurface.destroy();
    self.background.buffer.deinit();

    self.tags.deinit();
    self.clock.deinit();
    self.modules.deinit();

    self.monitor.state.gpa.destroy(self);
}

fn layerSurfaceListener(
    layerSurface: *zwlr.LayerSurfaceV1,
    event: zwlr.LayerSurfaceV1.Event,
    bar: *Bar,
) void {
    switch (event) {
        .configure => |data| {
            bar.configured = true;
            bar.width = @intCast(u16, data.width);
            bar.height = @intCast(u16, data.height);

            layerSurface.ackConfigure(data.serial);

            render.renderBackground(bar) catch return;
            render.renderTags(bar) catch return;
            render.renderClock(bar) catch return;
            render.renderModules(bar) catch return;

            bar.tags.surface.commit();
            bar.clock.surface.commit();
            bar.modules.surface.commit();
            bar.background.surface.commit();
        },
        .closed => bar.destroy(),
    }
}