diff --git a/i3status-timers b/i3status-timers new file mode 100644 index 0000000..681ba67 --- /dev/null +++ b/i3status-timers @@ -0,0 +1,237 @@ +#!/usr/bin/perl +# vim: set ai noet ts=8 sw=8 sts=8 ft=perl : + +# set username +# set uptime +# set time +# set xtitle of focused window +# set list of windows for current tag +# set list of windows for all tags +# set la +# set current language +# set battery charge + +# main loop impl. : +# save cur. str and compare it with prev. if it differs - update + +# proposed: 3 types of loop: +# slow loop for batt charge, la +# 1 second loop for time, uptime - generally, it looks like we do not need poll every second +# timers if clock granularity set to 1 minute or even coarse +# main (fast) loop for window name, language, it looks like we have some room here for greater +# improvement, when it'll be more clear how get info directly from x server + +binmode STDOUT; +binmode STDERR; + +sub onesec_cron(); +sub slow_cron(); + +sub gettimestr(); +sub getfocusedwidowtitlestr(); +sub getlangstr(); +sub getuptimestr(); +sub getlastr(); +sub getbatterychargestr1(); +sub getbatterychargestr2(); +sub meminfo(); + + +my $slow_timer = 360; # 0.333 * 360 ~= 2 min +my $onesec_timer = 3; # 0.333 * 3 ~= 1 sec + +my @months = ('Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'); +my @wdays = ('Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'); + +my $pstr = ''; + +my $charge; +my $la; +my $uptime; +my $time; +my $mem; + +sleep 1; + +while (1) { + if ($onesec_timer >= 3) { + onesec_cron(); + $onesec_timer = 0; + } + + if ($slow_timer >= 360) { + slow_cron(); + $slow_timer = 0; + } + + $str = ''; +# $str .= getfocusedwidowtitlestr(); +# $str .= "$ENV{'USER'}"; + $str .= getlangstr(); + $str .= $uptime; + $str .= $la; + $str .= $mem; + $str .= $charge; + $str .= $time; + + if ($pstr ne $str) { + syswrite STDOUT, "$str\n"; + $pstr = $str; + } + +# tick timers + $slow_timer++; + $onesec_timer++; + +# sleep for 0.333 second; + select(undef, undef, undef, 0.333); +} + +sub slow_cron() { + $charge = getbatterychargestr2(); + $la = getlastr(); +} + +sub onesec_cron() { + $uptime = getuptimestr(); + $time = gettimestr(); +# as we report time with precision of 1 minute, update 1/60 seconds + $mem = meminfo(); +} + + +sub gettimestr() { + my ($sec, $min, $hour, $mday, $mon, $year, $wday) = (localtime)[0,1,2,3,4,5,6]; + $year = $year + 1900; + my $str .= sprintf(" | %s, %s %s %s %02s:%02s ", $wdays[$wday], $mday, $months[$mon], $year, $hour, $min); + + return $str; +} + +sub getfocusedwidowtitlestr() { + my $str; + + if (-x '/usr/bin/xdotool') { + $str = `xdotool getactivewindow getwindowname`; + } elsif (-x '/usr/bin/xprop') { + $str = (split( / = /, `xprop -id \$(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5) _NET_WM_NAME`))[1]; + chop $str; chop $str; + } + + chomp($str); + + if (length($str) != 0) { + if (length($str) > 64){ + $str = '...' . substr($str, 0, -61); + } + $str = '['. $str .'] | '; + } else { + $str = '| '; + } + + return $str; +} + +sub getuptimestr() { + open UPTIME, "/proc/uptime" if (tell(UPTIME) == -1); + + $u = ; + seek UPTIME, SEEK_SET, 0; + $u = (split(/ /, $u, 2))[0]; + $days = int($u / 86400); # 86400 = 1 day + $hours = int(($u - (86400 * $days)) / 3600); # 3600 = 1 hour + $minutes = int(($u - (86400 * $days) - (3600 * $hours)) / 60); + $seconds = int($u - (86400 * $days) - (3600 * $hours) - (60 * $minutes)); + my $str = sprintf(" | up: %sd,%02sh,%02sm ", $days, $hours, $minutes); + + return $str; +} + +sub getlastr() { + open LA, "/proc/loadavg" if (tell(LA) == -1); + + my $la = ; + seek LA, SEEK_SET, 0; + $la = (split(/ /, $la, 2))[0]; + + return (" | LA: $la "); +} + +sub getbatterychargestr1() { + my $str = ''; + + if (-f "/sys/class/power_supply/BAT0/present") { + open A, "/sys/class/power_supply/BAT0/present"; + $P = ; + close A; + chomp($P); + + if ($P eq '1') { + open A, "/sys/class/power_supply/BAT0/energy_full"; + my $full_charge = ; + close A; + chomp($full_charge); + + open A, "/sys/class/power_supply/BAT0/energy_now"; + my $current_charge = ; + close A; + chomp($current_charge); + + $str .= sprintf(" | Bat: %03d%% ", int(($current_charge / $full_charge) * 100) ); + undef $current_charge; undef $full_charge; + } + } + + return $str; +} + +sub getbatterychargestr2() { + my $str .= " | Power: "; + open AC,"/sys/class/power_supply/ADP1/online"; + + if ( == 1) { + $str .= "AC"; + } else { + $str .= "DC"; + } + + close AC; # display % charge only if possible + + if (open DC,"/sys/class/power_supply/BAT0/capacity") { + $str .= ' '. ; + close DC; + chomp $str; + $str .= '%'; + } + + return $str; +} + +sub getlangstr() { + my $str .= " | Lang: "; + + if (`xset -q` =~ /Group 2: on /o) { + $str .= "RU"; + } else { + $str .= "EN"; + } + + return $str; +} + +sub meminfo() { + open (M, "/proc/meminfo"); + my @mem = ; + close M; + @mem = map { substr($_, 0, -4) } @mem; + + my $memavail = (split(/\s+/, @mem[2]))[1]; + my $swaptotal = (split(/\s+/, @mem[15]))[1]; + my $swapfree = (split(/\s+/, @mem[16]))[1]; + + return sprintf ( + " | mem: %s M | sw: %s M", + int($memavail / 1024), + int(($swaptotal - $swapfree) / 1024) + ); +}