summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2023-02-01 11:31:07 -0700
committerSean Whitton <spwhitton@spwhitton.name>2023-02-01 12:05:27 -0700
commitd4911881471dec9cbf3c5b1b6e39a989ceceb638 (patch)
treee14002a4b1010ab34027e5281fac25bcb72885ec /scripts
parent41dc871da7633ff1864a2e0e58b2a809f7b2b235 (diff)
downloaddotfiles-d4911881471dec9cbf3c5b1b6e39a989ceceb638.tar.gz
i3status-wrapper: swap parent and child processes
This should ensure the filtering loop stays alive in more circumstances.
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/desktop/i3status-wrapper168
1 files changed, 84 insertions, 84 deletions
diff --git a/scripts/desktop/i3status-wrapper b/scripts/desktop/i3status-wrapper
index 91f83032..0f8f96ec 100755
--- a/scripts/desktop/i3status-wrapper
+++ b/scripts/desktop/i3status-wrapper
@@ -42,108 +42,108 @@ unless ($i3status) {
tie my %info, "IPC::Shareable", undef, { destroy => 1 };
-unless (fork // die "couldn't fork()!") {
- $pipe->reader;
- open STDIN, "<&=", $pipe->fileno
- or die "couldn't reopen child's STDIN!";
+unless (fork // warn "couldn't fork monitoring loop") {
+ my $caffeinated_id;
- # Following based on Michael Stapelberg's sample i3status-wrapper script.
+ open my $events, "-|",
+ $wmipc, "-t", "subscribe", "-m", '[ "window", "workspace" ]';
- my $hostname = hostname;
- my $username = $ENV{LOGNAME} || $ENV{USER} || getpwuid($<);
-
- # Skip the first line which contains the version header.
- print scalar <>;
-
- # The second line contains the start of the infinite array.
- print scalar <>;
+ sub register_caffeinated {
+ $caffeinated_id = $_[0]->{id};
+ $info{caffeinated_name} = $_[0]->{name};
+ kill USR1 => $i3status;
+ }
- # Read lines forever, ignore a comma at the beginning if it exists.
- while (my ($statusline) = (<> =~ /^,?(.*)/)) {
- # If there is a decoding error, just skip this line, to minimise
- # status bar freezes. This should be fine here because this filtering
- # loop is in itself stateless. It's only if the decoding error
- # involves newlines in the wrong places, or similar, that this skip
- # could cause us to produce invalid output.
- my $blocks = eval { decode_json $statusline } // next;
+ sub clear_caffeinated {
+ undef $caffeinated_id;
+ undef $info{caffeinated_name};
+ kill USR1 => $i3status;
+ }
- unshift @$blocks,
- {
- name => "caffeinated",
- full_text => "Caffeinated: " . $info{caffeinated_name} }
- if $info{caffeinated_name};
+ # Determine the initial state -- the WM might just have been reloaded.
- unshift @$blocks,
- { name => "hostinfo", full_text => $username . "@" . $hostname };
+ my $workspaces = @{ decode_json `$wmipc -t get_workspaces` };
+ wsbuttons($workspaces > 1 ? "yes" : "no");
- print encode_json($blocks) . ",\n";
+ my @trees = decode_json `$wmipc -t get_tree`;
+ while (@trees) {
+ for ((shift @trees)->{nodes}->@*) {
+ if (grep $_ eq "caffeinated", $_->{marks}->@*) {
+ register_caffeinated($_);
+ last;
+ } else {
+ unshift @trees, $_;
+ }
+ }
}
+
+ # Now loop forever reading events, assuming no exceptions.
+
+ eval {
+ while (my $event = decode_json <$events>) {
+ if ($event->{change} eq "mark") {
+ if (grep $_ eq "caffeinated", $event->{container}{marks}->@*)
+ {
+ register_caffeinated($event->{container});
+ } elsif ($caffeinated_id
+ and $caffeinated_id == $event->{container}{id}) {
+ clear_caffeinated();
+ }
+ } elsif ($event->{change} eq "init") {
+ ++$workspaces == 2 and wsbuttons("yes");
+ } elsif ($event->{change} eq "empty") {
+ --$workspaces == 1 and wsbuttons("no");
+ # For simplicity, only fresh-workspace script calls
+ # compact_workspaces atm. For greater consistency we could
+ # call it here, too, without supplying a leave_gap argument.
+ }
+ }
+ };
+
+ # Give up if there's a decoding error. We can't ignore the problem
+ # because we don't want our ideas regarding how many workspaces there are,
+ # and whether anything is caffeinated, to get out of sync.
+ #
+ # The user can use the WM's "reload" command to restart this loop.
+ $@ and wsbuttons("yes"), clear_caffeinated();
}
-my $caffeinated_id;
+$pipe->reader;
+open STDIN, "<&=", $pipe->fileno or die "couldn't reopen STDIN!";
-open my $events, "-|",
- $wmipc, "-t", "subscribe", "-m", '[ "window", "workspace" ]';
+# Following based on Michael Stapelberg's sample i3status-wrapper script.
-# Determine the initial state -- the WM might just have been reloaded.
+my $hostname = hostname;
+my $username = $ENV{LOGNAME} || $ENV{USER} || getpwuid($<);
-my $workspaces = @{ decode_json `$wmipc -t get_workspaces` };
-wsbuttons($workspaces > 1 ? "yes" : "no");
+# Skip the first line which contains the version header.
+print scalar <>;
-my @trees = decode_json `$wmipc -t get_tree`;
-while (@trees) {
- for ((shift @trees)->{nodes}->@*) {
- if (grep $_ eq "caffeinated", $_->{marks}->@*) {
- register_caffeinated($_);
- last;
- } else {
- unshift @trees, $_;
- }
- }
-}
+# The second line contains the start of the infinite array.
+print scalar <>;
-# Now loop forever reading events, assuming no exceptions.
+# Read lines forever, ignore a comma at the beginning if it exists.
+while (my ($statusline) = (<> =~ /^,?(.*)/)) {
+ # If there is a decoding error, just skip this line, to minimise status
+ # bar freezes. This should be fine here because this filtering loop is in
+ # itself stateless. It's only if the decoding error involves newlines in
+ # the wrong places, or similar, that this skip could cause us to produce
+ # invalid output.
+ my $blocks = eval { decode_json $statusline } // next;
-eval {
- while (my $event = decode_json <$events>) {
- if ($event->{change} eq "mark") {
- if (grep $_ eq "caffeinated", $event->{container}{marks}->@*) {
- register_caffeinated($event->{container});
- } elsif ($caffeinated_id
- and $caffeinated_id == $event->{container}{id}) {
- clear_caffeinated();
- }
- } elsif ($event->{change} eq "init") {
- ++$workspaces == 2 and wsbuttons("yes");
- } elsif ($event->{change} eq "empty") {
- --$workspaces == 1 and wsbuttons("no");
- # For simplicity, only fresh-workspace script calls
- # compact_workspaces atm. For greater consistency we could call
- # it here, too, without supplying a leave_gap argument.
- }
- }
-};
+ unshift @$blocks,
+ {
+ name => "caffeinated",
+ full_text => "Caffeinated: " . $info{caffeinated_name} }
+ if $info{caffeinated_name};
-# Here we give up if there's a decoding error. We can't ignore the problem
-# because we don't want our ideas regarding how many workspaces there are, and
-# whether anything is caffeinated, to get out of sync.
-#
-# The user can use the WM's "reload" command to restart the loop.
-$@ and wsbuttons("yes"), clear_caffeinated();
+ unshift @$blocks,
+ { name => "hostinfo", full_text => $username . "@" . $hostname };
+
+ print encode_json($blocks) . ",\n";
+}
sub wsbuttons {
return unless $ENV{XDG_CURRENT_DESKTOP} eq "sway";
wmipc "bar bar-0 workspace_buttons $_[0]";
}
-
-sub register_caffeinated {
- $caffeinated_id = $_[0]->{id};
- $info{caffeinated_name} = $_[0]->{name};
- kill USR1 => $i3status;
-}
-
-sub clear_caffeinated {
- undef $caffeinated_id;
- undef $info{caffeinated_name};
- kill USR1 => $i3status;
-}