From dc58f0c6a9be3e457633519f19dc762032aa38ab Mon Sep 17 00:00:00 2001 From: eleksir Date: Sat, 19 Jun 2021 14:15:41 +0300 Subject: [PATCH] i3status-anyevent moved to separate repo - i3status-ae --- i3status-anyevent | 817 ----------------------------------------- i3status-anyevent.json | 294 --------------- 2 files changed, 1111 deletions(-) delete mode 100644 i3status-anyevent delete mode 100644 i3status-anyevent.json diff --git a/i3status-anyevent b/i3status-anyevent deleted file mode 100644 index 953572c..0000000 --- a/i3status-anyevent +++ /dev/null @@ -1,817 +0,0 @@ -#!/usr/bin/perl - -# TODO: on i3wm reload (i3status restart), restore active windows status -# TODO: make battery plugin take into account charge level, add ability to call suspend2disk on critical charge level -# TODO: More complex PA-plugin with volume adjustment of default sink - -# we need to disable hash shuffling in order to make as less prints to stdout as possible -BEGIN { - unless (defined $ENV{PERL_PERTURB_KEYS}) { - $ENV{PERL_PERTURB_KEYS} = 0; - exec ( $^X, $0, @ARGV ); - exit 0; # we actually never get here - } -} - -use 5.018; -use strict; -use warnings; -use utf8; -use open qw (:std :utf8); -use Fcntl qw (:seek); -use AnyEvent; -use AnyEvent::Timer::Cron; -use AnyEvent::I3; -use JSON::XS; -use Encode; -use IO::Socket qw (AF_INET SOCK_STREAM SHUT_WR); -use POSIX qw (setsid); - -local $| = 1; - -sub add_events (); -sub spawn (@); -sub find_caps_led (); -sub to_hours ($); -sub readconf (); -sub active_win_borders (); - -my $CONF = readconf (); -my $i3 = i3 (); -my $done = AnyEvent->condvar; -$i3->connect->recv or die 'Unable to connect to i3'; - -# event pool -my @EP; - -# reload config and re-apply it on SIGHUP -local $SIG{HUP} = sub { - $CONF = readconf (); - active_win_borders (); - $#EP = -1; - add_events (); -}; - -my @month = ('Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'); -my @week_day = ('Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'); - -# File handler pool -my $LAHANDLE; -my $MEMINFOHANDLE; -my $CPUTEMPHANDLE; -my $CAPSHANDLE; - -# everything for text labels on i3bar -my $wallclock = ''; -my $la = ''; -my $meminfo = ''; -my $cputemp = ''; -my $caps_state = ''; -my $charge = ''; -my $tcp_check = 0; -my $file_check = 0; -my $file_check_mtime = 0; -my $simple_volume_pa = '♪ ??%'; -my $interfaces = '??'; -my $output_string; -my $old_output_string = ''; -my $STDIN_FIRST_LINE_DROPPED = 0; -# hp, kernel 5.4.x -my $BATTERY_CHARGE_NOW_FILE = sprintf '%s/charge_now', $CONF->{battery}->{sys_dir}; - -unless (-f $BATTERY_CHARGE_NOW_FILE) { - # lenovo, kernel 4.4.x - $BATTERY_CHARGE_NOW_FILE = sprintf '%s/energy_now', $CONF->{battery}->{sys_dir}; -} - -# hp, kernel 5.4.x -my $BATTERY_CHARGE_FULL_FILE = sprintf '%s/charge_full', $CONF->{battery}->{sys_dir}; - -unless (-f $BATTERY_CHARGE_FULL_FILE) { - # lenovo, kernel 4.4.x - $BATTERY_CHARGE_FULL_FILE = sprintf '%s/energy_full', $CONF->{battery}->{sys_dir}; -} - -my $CAPS_LED_PATH = find_caps_led (); - -# opened windows info storage ref -my $win; - -# capture click events and do not override sigstop and sigcont numbers -print << 'EOJSON'; -{"version": 1, "click_events": true} -[ [], -EOJSON - -# i3 events should persist over config relads -my $i3_subscription->{window} = sub { - my $w = shift; - - if (defined $w->{change}) { - if ($w->{change} eq 'new' ) { - if (defined $w->{container}->{window_properties}->{instance}) { - if (defined $win->{instance}->{$w->{container}->{window_properties}->{instance}}) { - $win->{instance}->{$w->{container}->{window_properties}->{instance}}++; - } else { - $win->{instance}->{$w->{container}->{window_properties}->{instance}} = 1; - } - } - } elsif ($w->{change} eq 'close') { - if (defined $w->{container}->{window_properties}->{instance}) { - if (defined $win->{instance}->{$w->{container}->{window_properties}->{instance}}) { - if ($win->{instance}->{$w->{container}->{window_properties}->{instance}} > 1) { - $win->{instance}->{$w->{container}->{window_properties}->{instance}} --; - } else { - delete $win->{instance}->{$w->{container}->{window_properties}->{instance}}; - } - } - } - } - - active_win_borders (); - } -}; - -$i3_subscription->{_error} = sub { - my ($msg) = @_; - die "Connection to i3 closed: $msg"; -}; - -$i3->subscribe($i3_subscription)->recv->{success} || die 'Unable to subscribe to i3 events'; - -# now we can add other events -add_events (); - -# and start eventloop -$done->recv (); -exit 0; - - -sub add_events () { - # Register callbacks/event handlers - - # Actually print messages there - push @EP, AnyEvent->timer ( - after => 1, # sleep 1 second - interval => 0.3, # then invoke every ~1/3 second - cb => sub { # the callback to invoke - my $OUTPUT; - - if ($CONF->{app_buttons}) { - @{$OUTPUT} = @{$CONF->{apps}}; - } - - if ($CONF->{capslock}->{enabled}) { - if ($caps_state) { - push @{$OUTPUT}, { - background => $CONF->{capslock}->{color}, - color => $CONF->{capslock}->{background}, - border => $CONF->{capslock}->{background}, - full_text => 'caps', - markup => 'pango' - }; - } else { - push @{$OUTPUT}, { - color => $CONF->{capslock}->{color}, - background => $CONF->{capslock}->{background}, - border => $CONF->{capslock}->{background}, - full_text => 'caps', - markup => 'pango' - }; - } - } - - if ($CONF->{cpu_temp}->{enabled}) { - push @{$OUTPUT}, { color => $CONF->{color}, full_text => $cputemp }; - } - - if ($CONF->{mem}) { - push @{$OUTPUT}, { color => $CONF->{color}, full_text => $meminfo }; - } - - if ($CONF->{la}) { - push @{$OUTPUT}, { color => $CONF->{color}, full_text => "LA: $la" }; - } - - my $vpn_str = 'VPN:'; - - if ($CONF->{vpn}->{enabled}) { - if ($file_check) { - $vpn_str .= '⍋'; - } else { - $vpn_str .= '⍒'; - } - } - - if ($CONF->{vpn}->{tcp_check}->{enabled}) { - if ($CONF->{vpn}->{enabled}) { - $vpn_str .= ':'; - } - - if ($tcp_check) { - $vpn_str .= '✔'; - } else { - $vpn_str .= '✘'; - } - } - - if ($CONF->{vpn}->{tcp_check}->{enabled} || $CONF->{vpn}->{enabled}) { - push @{$OUTPUT}, { color => $CONF->{color}, full_text => $vpn_str }; - } - - if ($CONF->{'net-if'}->{enabled}) { - push @{$OUTPUT}, { color => $CONF->{color}, full_text => $interfaces, markup => 'pango' }; - } - - if ($CONF->{battery}->{enabled}) { - push @{$OUTPUT}, { color => $CONF->{color}, full_text => $charge, markup => 'pango' }; - } - - if ($CONF->{'simple-volume-pa'}) { - push @{$OUTPUT}, { - color => $CONF->{color}, - full_text => sprintf ('♪ %s%%', $simple_volume_pa), - markup => 'pango' - }; - } - - if ($CONF->{clock}->{enabled}) { - push @{$OUTPUT}, { name => 'wallclock', color => $CONF->{clock}->{color}, full_text => "$wallclock", markup => 'pango'}; - } - - $output_string = eval { encode_json $OUTPUT }; - - if (defined $output_string) { - if ($output_string ne $old_output_string) { - print decode ('UTF-8', $output_string) . ",\n"; - $old_output_string = $output_string; - } - } else { - warn $@; - } - - @{$OUTPUT} = -1; - } - ); - - - # read STDIN - push @EP, AnyEvent->io ( - fh => \*STDIN, - poll => 'r', - cb => sub { - my $msg = <>; - - unless ($STDIN_FIRST_LINE_DROPPED) { - $msg = <>; - $STDIN_FIRST_LINE_DROPPED = 1; - } - - if ($msg) { - # drop leading ',' if present - if (substr ($msg, 0, 1) eq ',') { - $msg = substr $msg, 1; - } - - my $j = eval { decode_json $msg }; - - if (defined $j) { - # left button click, without shift, ctrl, alt, etc - if (($j->{button} == 1) && ($#{$j->{modifiers}} < 0)) { - foreach (@{$CONF->{apps}}) { - unless (defined $_->{name}) { - next; - } - - unless (defined $j->{name}) { - next; - } - - if ($j->{name} eq $_->{name}) { - spawn ($_->{cmd}); - last; - } - } - } - - if (($j->{name} eq 'wallclock') && ($CONF->{clock}->{enabled})) { - if ($CONF->{clock}->{left_click}->{enabled}) { - if (($j->{button} == 1) && ($#{$j->{modifiers}} < 0)) { - spawn ($CONF->{clock}->{left_click}->{cmd}); - } - } elsif ($CONF->{clock}->{right_click}->{enabled}) { - if (($j->{button} == 2) && ($#{$j->{modifiers}} < 0)) { - spawn ($CONF->{clock}->{right_click}->{cmd}); - } - } - } - } - } - } - ); - - # poll caps lock status, on one of my laptop there is no led for this :( - if ($CONF->{capslock}->{enabled}) { - push @EP, AnyEvent->timer ( - after => 0, # first invoke ASAP - interval => 0.3, # then invoke every 0.3 seconds - cb => sub { # the callback to invoke - if (defined $CAPS_LED_PATH) { - if (defined $CAPSHANDLE) { - if (tell ($CAPSHANDLE) == -1) { - unless (open $CAPSHANDLE, '<', $CAPS_LED_PATH) { - $CAPS_LED_PATH = undef; - $caps_state = 2; - } - } - } else { - unless (open $CAPSHANDLE, '<', $CAPS_LED_PATH) { - $CAPS_LED_PATH = undef; - $caps_state = 2 - } - } - } else { - $caps_state = 2; - } - - if ($caps_state ne '2') { - $caps_state = eval { readline ($CAPSHANDLE) }; - seek $CAPSHANDLE, SEEK_SET, 0; - chomp $caps_state; - } - } - ); - } - - # poll clock by timer - if ($CONF->{clock}->{enabled}) { - push @EP, AnyEvent->timer ( - after => 0, # first invoke ASAP - interval => 1, # then invoke every 1 second - cb => sub { # the callback to invoke - # Fetch time for clock - my ($sec, $min, $hour, $mday, $mon, $year, $wday) = (localtime)[0,1,2,3,4,5,6]; - $year = $year + 1900; - $wallclock = sprintf ' %s, %s %s %s %02s:%02s ', $week_day[$wday], $mday, $month[$mon], $year, $hour, $min; - } - ); - } - - # poll battery status via upower or /sys - if ($CONF->{battery}->{enabled}) { - # borrow data from upower output - if ($CONF->{battery}->{driver} eq 'upower') { - push @EP, AnyEvent->timer ( - after => 0, # first invoke ASAP - interval => 10, # then invoke every 10 seconds - cb => sub { # the callback to invoke - my @up; - my $str = `upower -i $CONF->{battery}->{upower_device}`; - $charge = '⚡ ??% • 00:00'; - - if ($?) { - return; - } - - @up = split /\n/, $str; - my $percentage; - my $time_to; # full or empty - my $state; - my $hours = 0; - my $minutes = 0; - - while ($str = pop (@up)) { - if (substr ($str, 4, 10) eq 'percentage') { - $percentage = substr $str, 25; - chomp $percentage; - } elsif (substr ($str, 4, 5) eq 'state') { - if (substr ($str, 25, 11) eq 'discharging') { - $state = '▼'; - } elsif (substr ($str, 25, 8) eq 'charging') { - $state = '▲'; - } else { - $state = '•'; - } - } elsif (substr ($str, 4, 13) eq 'time to empty') { - $time_to = substr $str, 25; - } elsif (substr ($str, 4, 12) eq 'time to full') { - $time_to = substr $str, 25; - } - } - - unless (defined $percentage && defined $state) { - return; - } - - if (defined $time_to) { - chomp $time_to; - - if (substr ($time_to, -7) eq 'minutes') { - $minutes = substr $time_to, 0, -8; - $minutes =~ tr/\,/./; - $minutes = int $minutes; - } elsif (substr ($time_to, -5) eq 'hours') { - $hours = substr $time_to, 0, -6; - $hours =~ tr/\,/./; - $minutes = int (60 * ($hours - int ($hours))); - } - - $time_to = sprintf '%02d:%02d', $hours, $minutes; - } else { - $time_to = '00:00'; - } - - $charge = sprintf '⚡ %s %s %s', $percentage, $state, $time_to; - } - ); - } else { - # fallback borrow data from /sys - push @EP, AnyEvent->timer ( - after => 0, # first invoke ASAP - interval => 10, # then invoke every 10 seconds - cb => sub { # the callback to invoke - my $current_charge; - my $charge_max; - my $state; - my ($CH, $CCM, $STH); - - unless (open $CH, '<', $BATTERY_CHARGE_NOW_FILE) { - $charge = '⚡ ??% •'; - return; - } - - $current_charge = <$CH>; - chomp $current_charge; - close $CH; - - unless (open $CCM, '<', $BATTERY_CHARGE_FULL_FILE) { - $charge = '⚡ ??% •'; - return; - } - - $charge_max = <$CCM>; - chomp $charge_max; - close $CCM; - - unless (open $STH, '<', sprintf '%s/status', $CONF->{battery}->{sys_dir}) { - $charge = '⚡ ??% •'; - return; - } - - $state = <$STH>; - chomp $state; - close $STH; - - if ($state eq 'Charging') { - $state = '▲'; - } elsif ($state eq 'Discharging') { - $state = '▼'; - } else { - $state = '•'; - } - - my $capacity = int (100 * ($current_charge / $charge_max)); - $charge = sprintf '⚡ %s%% %s', $capacity, $state; - } - ); - } - } - - # put all fast accessable stats in one callback - push @EP, AnyEvent->timer ( - after => 0, # first invoke ASAP - interval => 3, # then invoke every 3 second - cb => sub { # the callback to invoke - - # Fetch Load Average - if ($CONF->{la}) { - if (defined $LAHANDLE) { - if (tell ($LAHANDLE) == -1) { - open $LAHANDLE, '<', '/proc/loadavg'; - } - } else { - open $LAHANDLE, '<', '/proc/loadavg'; - } - - $la = readline $LAHANDLE; - seek $LAHANDLE, SEEK_SET, 0; - $la = (split / /ms, $la, 2)[0]; - } - - # populate memory statistics - if ($CONF->{mem}) { - if (defined $MEMINFOHANDLE) { - if (tell ($MEMINFOHANDLE) == -1) { - open $MEMINFOHANDLE, '<', '/proc/meminfo'; - } - } else { - open $MEMINFOHANDLE, '<', '/proc/meminfo'; - } - - my @mem; - - while ( ! eof ($MEMINFOHANDLE) ) { - push @mem, readline ($MEMINFOHANDLE); - } - - seek $MEMINFOHANDLE, SEEK_SET, 0; - @mem = map { substr $_, 0, -4 } @mem; - my $memtotal = (split /\s+/xms, $mem[0])[1]; - my $memavail = (split /\s+/xms, $mem[2])[1]; - my $swaptotal = (split /\s+/xms, $mem[14])[1]; - my $swapfree = (split /\s+/xms, $mem[15])[1]; - my $shmem = (split /\s+/xms, $mem[20])[1]; - my $memused = int (($memtotal - $memavail) / ($memtotal / 100)); - - $meminfo = sprintf ( - 'M:%d%% SHM:%dM SW:%dM', - $memused, - int ($shmem / 1024), - int (($swaptotal - $swapfree) / 1024) - ); - } - - # populate cpu temperature info - if ($CONF->{cpu_temp}->{enabled}) { - my $hwmon = 1; - - if (defined $CPUTEMPHANDLE) { - if (tell $CPUTEMPHANDLE == -1) { - if (open $CPUTEMPHANDLE, '<', $CONF->{cpu_temp}->{file}) { - $hwmon = 1; - } else { - $hwmon = 0; - } - } - } else { - unless (open $CPUTEMPHANDLE, '<', $CONF->{cpu_temp}->{file}) { - $hwmon = 0; - }; - } - - if ($hwmon) { - $cputemp = readline $CPUTEMPHANDLE; - seek $CPUTEMPHANDLE, SEEK_SET, 0; - chomp $cputemp; - $cputemp = int $cputemp; - - if ($cputemp > 1000) { - $cputemp = int ($cputemp / 1000); - } - - $cputemp = sprintf '%s°', $cputemp; - } - } - }, - ); - - # check openvpn state-file mtime - if ($CONF->{vpn}->{enabled}) { - push @EP, AnyEvent->timer ( - after => 0, # first invoke ASAP - interval => 3, # then invoke every 3 seconds - cb => sub { # the callback to invoke - my $mtime = (stat $CONF->{vpn}->{statusfile}) [9]; - - if (defined $mtime) { - if ((time () - $mtime) < $CONF->{vpn}->{mtime_threshold}) { - $file_check = 1; - } else { - $file_check = 0; - } - - $file_check_mtime = $mtime; - } else { - $mtime = 0; - $file_check = 0; - } - } - ); - - # Try to tcp connect to server in vpn network - if ($CONF->{vpn}->{tcp_check}->{enabled}) { - push @EP, AnyEvent->timer ( - after => 0, # first invoke ASAP - interval => 5, # then invoke every 5 seconds - cb => sub { # the callback to invoke - if ( - my $sock = IO::Socket->new ( - Domain => AF_INET, - proto => 'tcp', - PeerHost => $CONF->{vpn}->{tcp_check}->{host}, - PeerPort => $CONF->{vpn}->{tcp_check}->{port}, - Type => SOCK_STREAM, - Timeout => $CONF->{vpn}->{tcp_check}->{timeout} - ) - ) { - $sock->shutdown (SHUT_WR); - $sock->close (); - $tcp_check = 1; - } else { - $tcp_check = 0; - } - } - ); - } - } - - # poll pulseaudio volume on first sink in list - if ($CONF->{'simple-volume-pa'}) { - push @EP, AnyEvent->timer ( - after => 0, # first invoke ASAP - interval => 1, # then invoke every 1 second - cb => sub { # the callback to invoke - my $pactl = `LC_ALL=C pactl list sinks`; - - if ($?) { - # we've some error here, so quit further processing - return; - } - - foreach my $str (split /\n/, $pactl) { - if ($str =~ /^\s+Volume\:\s+[a-z|A-Z\\-]+\:\s+\d+\s+\/\s+(\d+)% /xms ) { - $simple_volume_pa = $1; - last; - } - } - } - ); - } - - # poll operstate for given net ifs - if ($CONF->{'net-if'}->{enabled}) { - push @EP, AnyEvent->timer ( - after => 0, # first invoke ASAP - interval => 1, # then invoke every 1 second - cb => sub { # the callback to invoke - my @ifstate; - - foreach my $if (@{$CONF->{'net-if'}->{if}}) { - if (open my $STATEFH, '<', "$if->{dir}/operstate") { - my $state = <$STATEFH>; - close $STATEFH; - chomp $state; - - if ($state eq 'up') { - push @ifstate, sprintf '%s:▲', $if->{name}, $CONF->{'net-if'}->{up_color}; - } else { - push @ifstate, sprintf '%s:▼', $if->{name}, $CONF->{'net-if'}->{down_color}; - } - } - } - - if ($#ifstate >=0 ) { - $interfaces = join ' ', @ifstate; - } - } - ); - } - - # run all cron jobs from config - if ($CONF->{'cron'}->{enabled}) { - foreach my $task (@{$CONF->{'cron'}->{tasks}}) { - push @EP, AnyEvent::Timer::Cron->new ( - time_zone => 'local', - cron => $task->{time}, - cb => sub { - foreach my $cmd (@{$task->{cmd}}) { - `$cmd`; - } - } - ) - } - } - - return; -} - -sub spawn (@) { - my @args = @_; - my $pid = fork (); - - if ($pid) { - # Parent, work done, return - return; - } elsif ($pid == 0) { # Child - setsid (); - # it seems that at least vscode creashes if we close stdio handles - open STDOUT, '>', '/dev/null'; - open STDERR, '>', '/dev/null'; - open STDIN, '<', '/dev/null'; - $pid = fork (); - - if ($pid) { # Parent - # in this place parent quits - exit 0; - } elsif ($pid == 0) { # Child - setsid (); - my $prg = shift @args; - # weird situation, silently quit here :) - exit 0 unless (defined $prg); - - if (@args > 0) { - exec $prg, @args; - } else { - exec $prg; - } - } - # else - we just unable to fork, so silently ignore event - } - - return; -} - -sub find_caps_led () { - my $str; - opendir my $C, '/sys/class/input'; - my $cnt = 0; - - while (readdir $C) { - if (-f sprintf ('/sys/class/input/%s/input0::capslock/brightness', $_)) { - $str = sprintf '/sys/class/input/%s/input0::capslock/brightness', $_; - last; - } - - if (-f sprintf ('/sys/class/input/%s/input%s::capslock/brightness', $_, $cnt)) { - $str = sprintf '/sys/class/input/%s/input%s::capslock/brightness', $_, $cnt; - last; - } - - $cnt++; - } - - closedir $C; - return $str; -} - -sub to_hours ($) { - my $sec = shift; - - my $hrs = int ($sec / (60 * 60)); - my $min = int (($sec - ($hrs * 60 * 60)) / 60); - - return sprintf '%02d:%02d', $hrs, $min; -} - -sub readconf () { - my $i3dir = "$ENV{HOME}/.config/i3"; - - unless (-d $i3dir) { - $i3dir = "$ENV{HOME}/.i3"; - } - - my $file = "$i3dir/i3status-anyevent.json"; - - unless (-f $file) { - $file = "$i3dir/config.json"; - } - - my $FH; - - unless (open $FH, '<', $file) { - die "Unable to open $file: $!\n"; - } - - my $len = (stat $file)[7]; - my $data; - use bytes; - my $readlen = read $FH, $data, $len; - no bytes; - close $FH; - - unless (defined $readlen) { - die "Unable to read $file: $!\n"; - } - - if ($readlen != $len) { - die "Unable to read $file: read $readlen, but stat() reports that file is $len bytes\n"; - } - - my $config = eval { JSON::XS->new->utf8->relaxed->decode ($data) }; - - unless ($config) { - die "Unable to decode $file: $@\n"; - } - - return $config; -} - -sub active_win_borders () { - foreach my $app (@{$CONF->{apps}}) { - unless (defined $app->{border_inactive}) { - $app->{border_inactive} = $app->{border}; - } - - unless (defined $app->{border_active}) { - $app->{border_active} = $app->{border}; - } - - if (defined ($app->{instance}) && defined ($win->{instance}->{$app->{instance}})) { - $app->{border} = $app->{border_active}; - } else { - $app->{border} = $app->{border_inactive}; - } - } - - return; -} diff --git a/i3status-anyevent.json b/i3status-anyevent.json deleted file mode 100644 index 67d8071..0000000 --- a/i3status-anyevent.json +++ /dev/null @@ -1,294 +0,0 @@ -# Enable "plugin" 1, disable "plugin" 0 -{ -# default text and background colors -"color" : "#3e78fd", -"background" : "#edeceb", - -# Load Average -"la" : 1, - -# Memory stats -"mem" : 1, - -# Just clock -"clock": { - "enabled" : 1, -# html (actually, pango) color notation - "color" : "#000000", - "left_click" : { - "enabled" : 1, - "cmd" : "orage" - }, - "right_click" : { - "enabled" : 0, - "cmd" : "true" - } -}, - -# Battery -"battery": { - "enabled" : 1, -# can be upower or something else to use /sys polling instead of periodic run of upower binary - "driver" : "upower", -# where we can find charge_{now,full} and status files - "sys_dir" : "/sys/class/power_supply/BAT0", -# invoke 'upower --enumerate' and choose one - "upower_device" : "/org/freedesktop/UPower/devices/battery_BAT0" -}, - -# 0-th core temperature -"cpu_temp": { - "enabled": 1, - "file": "/sys/class/hwmon/hwmon0/temp1_input" -}, - -# Caps Lock status -"capslock": { - "enabled" : 1, - "background" : "#edeceb", - "color" : "#3e78fd" -}, - -# OpenVPN status. Note that directive status in openvpn.conf should point to -# state file and update its timestamp at least as frequent as mtime_threshold in seconds -"vpn": { - "enabled": 0, - "statusfile" : "/tmp/openvpn-status.stat", - "mtime_threshold": 10, -# Also we can tcp-ping some service inside vpn network to ensure that connection is not stoned - "tcp_check" : { - "enabled": 0, - "host": "somehost.tld", - "port": 443, - "timeout" : 3 - } -}, - -# Simplified volume indicator -# it periodically polls pulseaudio via "pactl list sinks" command -# so it's not light on system resources as i'd like -"simple-volume-pa": 0, - -"net-if" : { - "enabled" : 0, -# html (actually, pango) notation - "down_color" : "red", - "up_color" : "green", - "if" : [ - { - "name" : "eth0", - "dir" : "/sys/class/net/eth0" - }, - { - "name" : "wlan0", - "dir" : "/sys/class/net/wlan0" - } - ] -}, - -# Intended for use with desktop notifications -# Because it inherits all env vars from i3, it can intercat with dbus and other -# such user session services. -"cron" : { - "enabled" : 0, - "tasks" : [ - { - "time" : "55 23 * * *", - "cmd" : [ - "notify-send 'Sleeping Time!' 'Take a nap.'", - "mpg123 -q /usr/share/sounds/complete_quest_requirement.mp3" - ] - }, - - { -# time in crontab format - "time" : "55 12 * * 2,4", -# commands as it should be invoked in bash script - "cmd" : [ - "notify-send 'Pizza time!' 'M-m-m, tasty!'", - "mpg123 -q /usr/share/sounds/complete_quest_requirement.mp3" - ] - } - ] -}, - -# Weather to display Application Buttons -"app_buttons": 1, - -# Buttons - application launch "buttons" -"apps": [ - { - "full_text" : " X ", - "name" : "kill_fbpanel", - "cmd" : "killall -9 fbpanel", - "color": "#aa0000", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - -# text displayed on button - "full_text" : " Term ", - -# internal application name, must be unique - "name" : "lilyterm", - -# actual commad to be performed if button clicked - "cmd" : "lilyterm", - -# WM_CLASS(STRING) = "irssi", "URxvt" -# ^-instance ^-class - -# window instance as reported by xprop - "instance" : "lilyterm", - -# window class as reported by xprop - "class" : "LilyTerm", - -# text color - "color" : "#666666", - -# normal border color - "border": "#adadad", - -# border color if there is at lest one app window on desktop - "border_active": "#3e78fd", - -# if true - '|' will be drawn on panel to the right side of the "button" - "separator": false, - -# amount of space in pixels between buttons - "separator_block_width": 2 - }, - { - "full_text" : " Ff ", - "name" : "firefox", - "cmd" : "firefox", - "instance" : "Navigator", - "class" : "Firefox", - "color" : "#ffa500", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " V ", - "name" : "vivaldi", - "cmd" : "vivaldi", - "instance" : "vivaldi-stable", - "class" : "Vivaldi-stable", - "color" : "#ffa500", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " Chr ", - "name" : "chrome", - "cmd" : "chrome", - "instance" : "google-chrome", - "class" : "Google-chrome", - "color" : "#ffa500", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " O ", - "name" : "opera", - "cmd" : "opera", - "instance" : "Opera", - "class" : "Opera", - "color" : "#ffa500", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " @ ", - "name" : "thunderbird", - "cmd" : "thunderbird", - "instance" : "Mail", - "class" : "Thunderbird", - "color" : "#006994", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " Tg ", - "name" : "telegram", - "cmd" : "Telegram", - "instance" : "Telegram", - "class" : "TelegramDesktop", - "color" : "#5a8850", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " M ", - "name" : "myteam", - "cmd" : "myteam", - "instance" : "myteam", - "class" : "myteam", - "color" : "#5a8850", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " S ", - "name" : "slack", - "cmd" : "slack", - "instance" : "slack", - "class" : "Slack", - "color" : "#5a8850", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " Txt ", - "name" : "mousepad", - "cmd" : "mousepad", - "instance" : "mousepad", - "class" : "Mousepad", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " VSC ", - "name" : "code", - "cmd" : "code", - "instance" : "code", - "class" : "Code", - "border": "#adadad", - "border_active": "#3e78fd", - "separator": false, - "separator_block_width": 2 - }, - { - "full_text" : " K ", - "name" : "keepassxc", - "cmd" : "keepassxc", - "instance" : "keepassxc", - "class" : "KeePassXC", - "color" : "#7ec850", - "border" : "#adadad", - "border_active" : "#3e78fd" - } - ] -}