User Tools

Site Tools


panels

Compiler's panel

This panel is really informative, and based on a mixture of conky, trayer and dzen2. The info part is drawed by conky (without dzen2), but the tags are drawed by dzen2 because conky can't listen to hlwm hooks.

Screenshot:

conkyrc
# Florian Bruhin <me@the-compiler.org>
 
use_xft yes
xftfont profont:size=8
override_utf8_locale yes
 
update_interval 1
total_run_times 0
 
own_window yes
own_window_type panel
own_window_hints undecorated,sticky,skip_taskbar,skip_pager
 
border_inner_margin 0
border_outer_margin 0
draw_borders no
draw_graph_borders no
 
background no
 
# Eliminate flickering
double_buffer yes 
minimum_size 1050 8
maximum_width 1050
 
# Use KiB/MiB/... instead of just bytes
format_human_readable yes
# Print used memory with buffers
no_buffers no
# Display k, G, ... instead of kiB, GiB, ...
short_units yes
 
default_color d0d0d0
own_window_colour 1c1c1c
 
use_spacer left
if_up_strictness address
pad_percents 2
 
alignment top_left
gap_x 172
gap_y 0
 
default_graph_size 8 30
color0 d0d0d0
color1 afdf87
 
TEXT
${color1}cpu  1${color0} ${cpugraph cpu0 8,20 afdf87 afdf87}${goto 70}${freq_g 1} ${color1}2 ${color0} ${cpugraph cpu1 8,20 afdf87 afdf87} ${goto 144}${freq_g 2} ${color1}3${color0} ${cpugraph cpu2 8,20 afdf87 afdf87}${goto 212}${freq_g 3} ${goto 242}${color1}4${color0} ${cpugraph cpu3 8,20 afdf87 afdf87} ${freq_g 4}   \
${color1}load${color0} ${loadavg}   \
${color1}temp${color0}${hwmon 0 temp 1}/${hwmon 1 temp 1}°   \
${goto 528}${color1}fan${color0}  ${ibm_fan}rpm   \
${goto 628}${color1}mem${color0}  ${memperc}% (${mem}/${memmax})   \
${goto 765}${color1}batt${color0} ${battery_short} (${battery_time})   \
${goto 915}${color1}up${color0}${goto 985}${uptime_short} \
 
${color1}disk${color0} \
${color1}/${color0}${goto 76}${fs_used_perc /}%   \
${goto 100}\
${color1}/home${color0}${goto 148}${fs_used_perc /home}% \
${if_mounted /mnt}${color1}/mnt${color0}${goto 218}${fs_used_perc /mnt}%  ${endif}\
${if_up eth0}${goto 242}${color1}eth0${color0} ${addrs eth0} \
${goto 528}${color1}up${color0}${offset -18}${upspeedf eth0} (${offset -6}${totalup eth0}) \
${goto 628}${color1}down${color0}${offset -18}${downspeedf eth0} (${totaldown eth0})   ${endif}\
${if_up wlan0}${goto 242}${color1}wlan0${color0} \
${wireless_essid wlan0} (${offset -12}${wireless_link_qual_perc wlan0}%) ${addrs wlan0} \
${goto 528}${color1}up${color0} ${offset -20}${upspeedf wlan0} (${totalup wlan0}) \
${goto 628}${color1}down${color0}${goto 663}${downspeedf wlan0} (${totaldown wlan0})   ${endif}\
${goto 766}${color1}time${color0}${goto 873}${time %R}   \
${goto 915}${color1}date${color0} ${time %a %d.%m.%Y}   \
tags.sh
#!/bin/bash
# vim: set fileencoding=utf-8 ts=4 sts=4 sw=4 tw=80 expandtab :
# Florian Bruhin <me@the-compiler.org>
 
dzen_fg="#d0d0d0"
dzen_bg="#1c1c1c"
normal_fg=""
normal_bg=
viewed_fg="#000000"
viewed_bg="#afdf87"
urgent_fg=
urgent_bg="#df8787"
used_fg="#afdf87"
used_bg=
 
herbstclient --idle 2>/dev/null | {
    tags=( $(herbstclient tag_status) )
    while true; do
        for tag in "${tags[@]}" ; do
            case ${tag:0:1} in
                '#') cstart="^fg($viewed_fg)^bg($viewed_bg)" ;;
                '+') cstart="^fg($viewed_fg)^bg($viewed_bg)" ;;
                ':') cstart="^fg($used_fg)^bg($used_bg)"     ;;
                '!') cstart="^fg($urgent_fg)^bg($urgent_bg)" ;;
                *)   cstart=''                               ;;
            esac
            dzenstring="${cstart}^ca(1,herbstclient use ${tag:1}) ${tag:1} "
            dzenstring+="^ca()^fg()^bg()"
            echo -n "$dzenstring"
        done
        echo 
        read hook || exit
        case "$hook" in
            tag*) tags=( $(herbstclient tag_status) ) ;;
            quit_panel*) exit ;;
        esac
    done
} | dzen2 -h 23 -fn '-*-profont-*-*-*-*-11-*-*-*-*-*-*-*' -ta l -sa l \
          -w 162 -fg "$dzen_fg" -bg "$dzen_bg" -e 'button3='
tray.sh
#!/bin/bash
# vim: set fileencoding=utf-8 ts=4 sts=4 sw=4 tw=80 expandtab :
# Florian Bruhin <me@the-compiler.org>
 
trayer --edge top --align right --widthtype request --heighttype pixel \
       --height 22 --expand true --tint 0x222222 --transparent true \
       --alpha 0
panel2.sh
#!/bin/bash
# vim: set fileencoding=utf-8 ts=4 sts=4 sw=4 tw=80 expandtab :
# Florian Bruhin <me@the-compiler.org>
 
[[ $0 == /* ]] && script="$0" || script="${PWD}/${0#./}"
panelfolder=${script%/*}
trap 'herbstclient emit_hook quit_panel' TERM
herbstclient pad 0 24
herbstclient emit_hook quit_panel
 
dzen2 -p -h 1 -w 1366 -x 0 -y 23 -bg '#afdf87' &
pids+=($!)
 
"$panelfolder/tray.sh" &
pids+=($!)
 
"$panelfolder/tags.sh" &
pids+=($!)
 
conky -c "$panelfolder/conkyrc" &
pids+=($!)
 
herbstclient --wait '^(quit_panel|reload).*'
kill -TERM "${pids[@]}" >/dev/null 2>&1
exit 0

tomahhunt's panel

This is a rewrite of the default herbstluftwm panel in perl. It performs the re-keybinding of use and move when a new tag arrives or dissapears. It uses shortcuts 1-9,0 and then a different command for a second set.

The Defaults are: Mod4-$i → use $i Mod4-Shift$i → move $i Mod4-Alt-$i → use $i (next set) Mod4-Alt-Shift-$i → move $i (next set)

There are some variables at the top of script to alter these and the fonts used.

panel.pl
# Tom Hunt <tomahhunt@gmail.com>
 
#!/usr/bin/perl
use strict;
use warnings;
use IO::Pipe;
use Switch;
 
my $font_width = 6;
my $height=16;
my $separator="^fg(#ffffff)^ro(1x$height)^fg()";
my $num_monitors = `herbstclient list_monitors | wc -l`;
my $font = "-*-clean-bold-r-*-*-10-*-*-*-*-*-*-*";
my $use_key = "Mod4";
my $move_key = "Mod4-Shift";
my $use2_key = "Mod4-Alt";
my $move2_key = "Mod4-Alt-Shift";
 
my $acpi_on = 0;
 
sub get_date {
  return `date +'date ^fg(#efefef)%H:%M - ^fg(#efefef)%A - %d %B %Y'`;
}
 
sub date_for_dzen {
  my ($date) = @_;
  $date =~ s/date //;
  my $text="$separator^bg(#000000) $date $separator";
  my $text_only = $text;
  $text_only =~ s/\^\w+\([#\w+]*\)//g;
  my $width = (length($text_only) + 2) * $font_width;
  return "^p(_RIGHT)^p(-$width)$text^ca()";
}
 
my %TAGS;
sub update_status {
  my ($reason) = @_;
  if ($reason =~ /removed/) { for (keys %TAGS) { delete $TAGS{$_};} }
  for (my $mon = 0 ; $mon < $num_monitors ; $mon++) {
    my $status = `herbstclient tag_status $mon`;
    $status =~ s/^\t(.*)\n/$1/;
    my @array = split(/\t/, $status);
    my $i = 1;
    foreach my $entry (@array) {
      $TAGS{$mon}{$i++} = $entry;
    }
  }
}
 
sub update_tag {
  my ($reason, $monitor) = @_;
 
  my $tags_string = "";
  update_status($reason) if($monitor == 0);  #Only update from herbstclient once
  # draw tags
  foreach my $curr_tag (sort { $a <=> $b } keys %{$TAGS{$monitor}}) {
    my $tag_name = substr($TAGS{$monitor}{$curr_tag},1);
 
    switch (substr($TAGS{$monitor}{$curr_tag},0,1)) {
      case '#' { $tags_string .= "^bg(#00ff00)^fg(#000000)"; }
      case '+' { $tags_string .= "^bg(#00ff00)^fg(#000000)"; }
      case ':' { $tags_string .= "^bg(#000000)^fg(#ffffff)"; }
      case '-' { $tags_string .= "^bg(#FF0000)^fg(#000000)"; }
      case '%' { $tags_string .= "^bg(#FF0000)^fg(#000000)"; }
      case '!' { $tags_string .= "^bg(#FF0675)^fg(#000000)"; }
      case '.' { $tags_string .= "^bg(#aaaaaa)^fg(#000000)"; }
      else     { $tags_string .= "^bg()^fg()"; }
    }
    my $tag_comb = $tag_name;
    if ($curr_tag <= 10) {
      $curr_tag = 0 if ($curr_tag == 10);
      $tag_comb = "$curr_tag:$tag_name" if ($tag_name ne $curr_tag);
      if ($reason =~ /first|added|removed|renamed/) {
        system("herbstclient keybind '${use_key}-$curr_tag' use '$tag_name'");
        system("herbstclient keybind '${move_key}-$curr_tag' move '$tag_name'");
      }
    } else {
      $curr_tag = $curr_tag - 10 ;
      $tag_comb = "A:$curr_tag:$tag_name" if ($tag_name ne $curr_tag);
      if ($reason =~ /first|added|removed|renamed/) {
        system("herbstclient keybind '${use2_key}-$curr_tag' use '$tag_name'");
        system("herbstclient keybind '${move2_key}-$curr_tag' move '$tag_name'");
      }
    }
    $tags_string .= "^ca(1, herbstclient focus_monitor $monitor && herbstclient use $tag_name)";
    $tags_string .= "^ca(3, herbstclient merge_tag $tag_name)";
    $tags_string .= " $tag_comb ^ca()^ca()$separator";
  }
  return $tags_string;
}
 
my $pipe = IO::Pipe->new();
 
my $acpi_test;
if ($acpi_on == 1) {
  $acpi_test = `which acpi 2>&1`;
  if ($acpi_test =~ /which: no acpi/) {
    $acpi_test = 0;
  } else {
    my $acpi_test2 = `acpi 2>&1`;
    if ($acpi_test2 =~ /No support for device type: power_supply/) {
      $acpi_test = 0;
    } else {
      $acpi_test = 1;
    }
  }
} else {
  $acpi_test = 0;
}
 
my $pid_date = fork();
 
my $pid_acpi = 1;
if ($acpi_test == 1) {
  $pid_acpi = fork();
}
 
if ($pid_date == 0) { #Spawn Date Generator Child
  $pipe->writer();
  $pipe->autoflush();
  my $last_date = "";
  while (1) {
    my $date = get_date();
    if ($last_date ne $date) {
      $last_date = $date;
      print $pipe "$date\n";
    }
    sleep(5);
  }
} elsif ($pid_acpi == 0) {
  $pipe->writer();
  $pipe->autoflush();
  my $last_acpi = "";
  while (1) {
    my $acpi = `acpi`;
    chomp($acpi);
    if ($last_acpi ne $acpi) {
      $last_acpi = $acpi;
      print $pipe "$acpi\n";
    }
    sleep(5);
  }
} elsif (fork() == 0) { #Spawn Herbstclient Idle Child
  $pipe->writer();
  $pipe->autoflush();
  open (HERB,"herbstclient --idle |");
  while (<HERB>) { print $pipe $_; }
  kill 9, $pid_date;
  kill 9, $pid_acpi;
} elsif (fork() == 0) { #Spawn Dzen Child
  #Initial Data
 
  my $date_dzen_store = date_for_dzen(get_date());
  my $acpi_dzen_store = "";
  if ($acpi_test == 1) {
    $acpi_dzen_store = `acpi`;
    chomp($acpi_dzen_store);
    $acpi_dzen_store =~ s/Battery 0: /                /;
  }
  my %tags_dzen_store;
  for (my $mon = 0 ; $mon < $num_monitors ; $mon++) {
    $tags_dzen_store{$mon} = update_tag("tag_added", $mon);
  }
 
  my %dzen;
  #Spawn DZEN instances
  for (my $mon = 0 ; $mon < $num_monitors ; $mon++) {
    system("herbstclient pad $mon $height");
    my @geometry = split(/ /,`herbstclient monitor_rect $mon`);
    open ($dzen{$mon}, "| dzen2 -e ''\\
                          -w $geometry[2]\\
                          -x $geometry[0]\\
                          -y $geometry[1]\\
                          -fn '$font'\\
                          -h $height\\
                          -ta l\\
                          -bg '#000000'\\
                          -fg '#efefef'");
    autoflush {$dzen{$mon}} 1;
  }
 
  $pipe->reader();
  #Main Loop for new data
  while (<$pipe>) {
    chomp $_;
    if ($_ =~ /^date/) {
      $date_dzen_store = date_for_dzen($_);
    } elsif ($_ =~ /tag/) {
      for (my $mon = 0 ; $mon < $num_monitors ; $mon++) {
        $tags_dzen_store{$mon} = update_tag($_, $mon);
      }
    } elsif ($_ =~ /Battery/) {
      $acpi_dzen_store = $_;
      $acpi_dzen_store =~ s/Battery 0: /                /;
    } 
 
    for (my $mon = 0 ; $mon < $num_monitors ; $mon++) {
      print {$dzen{$mon}} $tags_dzen_store{$mon} . $acpi_dzen_store . $date_dzen_store;
      print {$dzen{$mon}} "\n";
    }
  }
}

toggleable tray

tray-toggle
#!/bin/sh
 
tray=trayer-srg
 
if pkill -x $tray; then
    exit
fi
 
m=$(herbstclient list_monitors | grep FOCUS | cut -d : -f 1)
case $m in
    0|1) m=0 ;;
    2|3) m=1 ;;
esac
 
$tray \
    --edge right \
    --distancefrom right \
    --distance -1 \
    --margin 17 \
    --widthtype request \
    --align left \
    --monitor $m &
panels.txt · Last modified: 2013/01/31 20:14 by tg