aboutsummaryrefslogtreecommitdiff
path: root/river/SeatStatus.zig
blob: d06c7dda3b4ea4a0bf5f2f8590fb87cf3edd3e2a (plain) (blame)
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
// This file is part of river, a dynamic tiling wayland compositor.
//
// Copyright 2020 The River Developers
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

const Self = @This();

const std = @import("std");
const wayland = @import("wayland");
const wl = wayland.server.wl;
const zriver = wayland.server.zriver;

const server = &@import("main.zig").server;
const util = @import("util.zig");

const Seat = @import("Seat.zig");
const Output = @import("Output.zig");
const View = @import("View.zig");

seat: *Seat,
seat_status: *zriver.SeatStatusV1,

pub fn init(self: *Self, seat: *Seat, seat_status: *zriver.SeatStatusV1) void {
    self.* = .{ .seat = seat, .seat_status = seat_status };

    seat_status.setHandler(*Self, handleRequest, handleDestroy, self);

    // Send all info once on bind
    seat_status.sendMode(server.config.modes.items[seat.mode_id].name);
    self.sendOutput(.focused);
    self.sendFocusedView();
}

fn handleRequest(seat_status: *zriver.SeatStatusV1, request: zriver.SeatStatusV1.Request, _: *Self) void {
    switch (request) {
        .destroy => seat_status.destroy(),
    }
}

fn handleDestroy(_: *zriver.SeatStatusV1, self: *Self) void {
    const node = @fieldParentPtr(std.SinglyLinkedList(Self).Node, "data", self);
    self.seat.status_trackers.remove(node);
    util.gpa.destroy(node);
}

pub fn sendOutput(self: Self, state: enum { focused, unfocused }) void {
    const client = self.seat_status.getClient();
    var it = self.seat.focused_output.wlr_output.resources.iterator(.forward);
    while (it.next()) |wl_output| {
        if (wl_output.getClient() == client) switch (state) {
            .focused => self.seat_status.sendFocusedOutput(wl_output),
            .unfocused => self.seat_status.sendUnfocusedOutput(wl_output),
        };
    }
}

pub fn sendFocusedView(self: Self) void {
    const title: [*:0]const u8 = if (self.seat.focused == .view)
        self.seat.focused.view.getTitle() orelse ""
    else
        "";
    self.seat_status.sendFocusedView(title);
}