Skip to content

Instantly share code, notes, and snippets.

@kjetilho
Created June 5, 2020 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kjetilho/00fda94909945eff7b02fdcc8fa67015 to your computer and use it in GitHub Desktop.
Save kjetilho/00fda94909945eff7b02fdcc8fa67015 to your computer and use it in GitHub Desktop.
wrapper for i3status which adjusts output and warns when battery is low
#! /usr/bin/perl -CSDL
use warnings;
use strict;
use utf8;
use JSON;
# Don't die when instant update is requested with a sloppy
# pkill -USR1 i3status
$SIG{USR1} = undef;
# See if this workstation has a directly attached display (== laptop)
my $xrandr = `xrandr`;
my $builtin_panel = $xrandr =~ /^(LVDS|eDP)-?\d+ connected/m;
open(my $i3, '-|', 'i3status') or die "i3status: $!\n";
$| = 1;
my $json = JSON->new->utf8(0);
my $previous_battery_level = 100;
# We wing it and don't bother to look at partial JSON data. Let's just copy
# data until the line contains a full_text.
while (<$i3>) {
if (/full_text/) {
my $comma = s/^,//;
my $info = $json->decode($_);
if ($builtin_panel) {
unshift(@{$info}, brightness());
}
check_battery(find_section($info, 'battery'));
$info = filter_master_volume($info);
$_ = ($comma ? "," : ''). $json->encode($info) . "\n";
}
print $_;
}
sub find_section {
my ($info, $title) = @_;
my $i = -1;
while (++$i < scalar @{$info}) {
return $info->[$i] if $info->[$i]->{name} eq $title;
}
die;
}
sub brightness {
chomp(my $brightness = `light`);
return {"name" => "brightness 0", "full_text" => "[☼ ${brightness}%]"};
}
sub check_battery {
my ($info) = @_;
if ($info->{full_text} =~ /(\d+)%/) {
my $level = $1;
if ($level <= 5 && $level < $previous_battery_level) {
system("zenity --warning --text 'Only $level% battery left!' &");
}
$previous_battery_level = $level;
} else {
# charging or something? resetting.
$previous_battery_level = 100;
}
}
# Only keep the first volume section with information
sub filter_master_volume {
my ($info) = @_;
my @keep = ();
my $seen_volume;
for (@{$info}) {
if ($_->{name} eq 'volume') {
next unless $_->{full_text};
next if $seen_volume++; # only include first
}
push(@keep, $_);
}
\@keep;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment