summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2022-08-14 16:00:07 -0700
committerSean Whitton <spwhitton@spwhitton.name>2022-08-17 10:52:29 -0700
commitfaf9bffe02a1407990373453935705f5b8de378d (patch)
tree8704c31b2199734c4928a7ffd2622513cdcaf1fd /scripts
parente20a00bebf2bb0fa1d19edd674d34395d6dcbd24 (diff)
downloaddotfiles-faf9bffe02a1407990373453935705f5b8de378d.tar.gz
use IPC subscription for caffeinated status
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/desktop/i3status-wrapper92
1 files changed, 61 insertions, 31 deletions
diff --git a/scripts/desktop/i3status-wrapper b/scripts/desktop/i3status-wrapper
index e9df86c8..5c4a25c8 100755
--- a/scripts/desktop/i3status-wrapper
+++ b/scripts/desktop/i3status-wrapper
@@ -1,7 +1,21 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
-# originally based on Michael Stapelberg's i3status-wrapper; added forking
-# i3status ourselves, user@host, and scanning for caffeinated mark
+# i3status-wrapper -- wrapper for i3status(1), plus other monitoring
+#
+# Copyright (C) 2019, 2021-2022 Sean Whitton
+#
+# 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, either version 3 of the License, or (at
+# your option) any later version.
+#
+# 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 <http://www.gnu.org/licenses/>.
use 5.032;
use strict;
@@ -11,11 +25,13 @@ use lib "$ENV{HOME}/src/dotfiles/perl5";
use JSON;
use Local::Desktop;
use IO::Pipe;
+use IPC::Shareable;
use Sys::Hostname;
$| = 1;
my $pipe = IO::Pipe->new;
+
my $i3status = fork // die "couldn't fork()!";
unless ($i3status) {
$pipe->writer;
@@ -23,43 +39,57 @@ unless ($i3status) {
or die "couldn't open child's STDOUT";
exec "i3status";
}
-$pipe->reader;
-# Skip the first line which contains the version header.
-print scalar <$pipe>;
+tie my %info, "IPC::Shareable", undef, { destroy => 1 };
-# The second line contains the start of the infinite array.
-print scalar <$pipe>;
+unless (fork // die "couldn't fork()!") {
+ $pipe->reader;
+ open STDIN, "<&=", $pipe->fileno
+ or die "couldn't reopen child's STDIN!";
-my $caffeinated;
-my $username = $ENV{LOGNAME} || $ENV{USER} || getpwuid($<);
-my $hostname = hostname;
+ # Following based on Michael Stapelberg's sample i3status-wrapper script.
-expensive();
-$SIG{USR1} = sub { kill USR1 => $i3status; expensive() };
+ my $hostname = hostname;
+ my $username = $ENV{LOGNAME} || $ENV{USER} || getpwuid($<);
-# Read lines forever, ignore a comma at the beginning if it exists.
-while (my ($statusline) = (<$pipe> =~ /^,?(.*)/)) {
- my @blocks = @{ decode_json $statusline };
+ # Skip the first line which contains the version header.
+ print scalar <>;
- unshift @blocks,
- { full_text => "Caffeinated: $caffeinated", name => "caffeinated" }
- if $caffeinated;
+ # The second line contains the start of the infinite array.
+ print scalar <>;
- unshift @blocks,
- { full_text => $username . "@" . $hostname, name => "hostinfo" };
+ # Read lines forever, ignore a comma at the beginning if it exists.
+ while (my ($statusline) = (<> =~ /^,?(.*)/)) {
+ my @blocks = @{ decode_json $statusline };
- print encode_json(\@blocks) . ",\n";
-}
+ unshift @blocks,
+ {
+ name => "caffeinated",
+ full_text => "Caffeinated: " . $info{caffeinated_name} }
+ if $info{caffeinated_name};
+
+ unshift @blocks,
+ { name => "hostinfo", full_text => $username . "@" . $hostname };
-sub expensive {
- my %marks;
- walk_tree(\%marks, decode_json `$wmipc -t get_tree`);
- $caffeinated = exists $marks{caffeinated} ? $marks{caffeinated} : undef;
+ print encode_json(\@blocks) . ",\n";
+ }
}
-sub walk_tree {
- my ($marks, $tree) = @_;
- $marks->{$_} = $tree->{name} for $tree->{marks}->@*;
- walk_tree($marks, $_) for $tree->{nodes}->@*;
+my $caffeinated_id;
+
+open my $events, "-|",
+ $wmipc, "-t", "subscribe", "-m", '[ "window" ]';
+
+while (my $event = decode_json <$events>) {
+ if ($event->{change} eq "mark") {
+ if (grep $_ eq "caffeinated", $event->{container}{marks}->@*) {
+ $caffeinated_id = $event->{container}{id};
+ $info{caffeinated_name} = $event->{container}{name};
+ kill USR1 => $i3status;
+ } elsif ($caffeinated_id
+ and $caffeinated_id == $event->{container}{id}) {
+ undef $caffeinated_id, undef $info{caffeinated_name};
+ kill USR1 => $i3status;
+ }
+ }
}