summaryrefslogtreecommitdiff
path: root/scripts/desktop/i3status-wrapper
blob: cbe02685aa7e5c3e4a9a57a883572f53f250b752 (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
#!/usr/bin/env perl

# originally based on Michael Stapelberg's i3status-wrapper; added forking
# i3status ourselves, user@host, and scanning for caffeinated mark

use 5.032;
use strict;
use warnings;
use JSON;

use IO::Pipe;
use Sys::Hostname;

$| = 1;

my $pipe = IO::Pipe->new;
my $i3status = fork // die "couldn't fork()!";
unless ($i3status) {
    $pipe->writer;
    open STDOUT, ">&=", $pipe->fileno
      or die "couldn't open child's STDOUT";
    exec "i3status";
}
$pipe->reader;

# Skip the first line which contains the version header.
print scalar <$pipe>;

# The second line contains the start of the infinite array.
print scalar <$pipe>;

my $caffeinated;
my $username = $ENV{LOGNAME} || $ENV{USER} || getpwuid($<);
my $hostname = hostname;

`which i3-msg`;
my $exec = $? == 0 ? "i3-msg" : "swaymsg";

expensive();
$SIG{USR1} = sub { kill USR1 => $i3status; expensive() };

# Read lines forever, ignore a comma at the beginning if it exists.
while (my ($statusline) = (<$pipe> =~ /^,?(.*)/)) {
    my @blocks = @{ decode_json $statusline };

    unshift @blocks,
      { full_text => "Caffeinated: $caffeinated", name => "caffeinated" }
      if $caffeinated;

    unshift @blocks,
      { full_text => $username . "@" . $hostname, name => "hostinfo" };

    print encode_json(\@blocks) . ",\n";
}

sub expensive {
    my %marks;
    walk_tree(\%marks, decode_json `$exec -t get_tree`);
    $caffeinated = exists $marks{caffeinated} ? $marks{caffeinated} : undef;
}

sub walk_tree {
    my ($marks, $tree) = @_;
    $marks->{$_} = $tree->{name} for $tree->{marks}->@*;
    walk_tree($marks, $_) for $tree->{nodes}->@*;
}