diff --git a/i3/config.lemonbar b/i3/config.lemonbar new file mode 100644 index 0000000..87045d4 --- /dev/null +++ b/i3/config.lemonbar @@ -0,0 +1,214 @@ +# Tango colors +# $i3-status + +set color_bad = #CC0000 +set color_degraded = #EDD400 +set color_good = #73D216 + +set $mod Mod4 + +# Fuente para títulos de ventanas +font pango:DejaVu Sans Mono 10 + +# Usar Ratón+$mod para mover las ventanas flotantes +floating_modifier $mod + +# Display +set $display LVDS1 +set $display2 VGA1 + +# volver a la misma ventana que estaba apretando el mismo worskpace +workspace_auto_back_and_forth yes + +# abrir una terminal +bindsym $mod+Return exec termite + +# cerrat ventana +bindsym $mod+Shift+Q kill + +# arrancar dmenu +bindsym $mod+d exec dmenu_run + +# Reinicia i3 +bindsym $mod+Shift+r restart + +# Cambiar foco +bindsym $mod+j focus down +bindsym $mod+k focus up +bindsym $mod+l focus right +bindsym $mod+gXG focus right + +# Cambiar foco con las flechas +bindsym $mod+Left focus left +bindsym $mod+Down focus down +bindsym $mod+Up focus up +bindsym $mod+Right focus right + +# Mover de workspace +bindsym $mod+Shift+j move left +bindsym $mod+Shift+k move down +bindsym $mod+Shift+l move up +bindsym $mod+Shift+semicolon move right + +# Mover de workspace usando las flechas +bindsym $mod+Shift+Left move left +bindsym $mod+Shift+Down move down +bindsym $mod+Shift+Up move up +bindsym $mod+Shift+Right move right + +# Cambiar la orientación en horizontal +bindsym $mod+h split h + +# Cambiar la orientación en vertical +bindsym $mod+v split v + +# Fullscreen +bindsym $mod+f fullscreen + +# Cambiar layout +bindsym $mod+s layout stacking +bindsym $mod+w layout tabbed +bindsym $mod+e layout default + +# Cambiar entre tiling / floating +bindsym $mod+Shift+space floating toggle + +# Cambiar foco entre tiling / floating windows +bindsym $mod+space focus mode_toggle + +# Foco al padre +bindsym $mod+a focus parent + +# Definir workspaces +set $ws1 1 +set $ws2 2 +set $ws3 3 +set $ws4 4 +set $ws5 5 +set $ws6 6 +set $ws7 7 +set $ws8 8 +set $ws9 9 +set $ws10 10 + +# Cambiar a workspace +bindsym $mod+1 workspace $ws1 +bindsym $mod+2 workspace $ws2 +bindsym $mod+3 workspace $ws3 +bindsym $mod+4 workspace $ws4 +bindsym $mod+5 workspace $ws5 +bindsym $mod+6 workspace $ws6 +bindsym $mod+7 workspace $ws7 +bindsym $mod+8 workspace $ws8 +bindsym $mod+9 workspace $ws9 +bindsym $mod+0 workspace $ws10 + +# Mover a workspace +bindsym $mod+Shift+1 move container to workspace $ws1 +bindsym $mod+Shift+2 move container to workspace $ws2 +bindsym $mod+Shift+3 move container to workspace $ws3 +bindsym $mod+Shift+4 move container to workspace $ws4 +bindsym $mod+Shift+5 move container to workspace $ws5 +bindsym $mod+Shift+6 move container to workspace $ws6 +bindsym $mod+Shift+7 move container to workspace $ws7 +bindsym $mod+Shift+8 move container to workspace $ws8 +bindsym $mod+Shift+9 move container to workspace $ws9 +bindsym $mod+Shift+0 move container to workspace $ws10 + +# Workspace a monitores +workspace $ws2 output $display2 +workspace $ws8 output $display1 + +# Cambiar tamaño de ventana +mode "Resize" { + # These bindings trigger as soon as you enter the resize mode + bindsym j resize shrink width 10 px or 10 ppt + bindsym k resize grow height 10 px or 10 ppt + bindsym l resize shrink height 10 px or 10 ppt + bindsym ntilde resize grow width 10 px or 10 ppt + + # same bindings, but for the arrow keys + bindsym Left resize shrink width 1 px or 1 ppt + bindsym Down resize grow height 1 px or 1 ppt + bindsym Up resize shrink height 1 px or 1 ppt + bindsym Right resize grow width 1 px or 1 ppt + + # back to normal: Enter or Escape + bindsym Return mode "default" + bindsym Escape mode "default" +} + +bindsym $mod+r mode "Resize" + +# Barra principal +bar { + status_command ~/.i3/lemonbar/i3_lemonbar.sh + mode invisible +} + +# Modo sistema +set $mode_system System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown +mode "$mode_system" { + bindsym l exec --no-startup-id ~/.i3/scripts/exit lock, mode "default" + bindsym s exec --no-startup-id ~/.i3/scripts/exit pm-suspend, mode "default" + bindsym r exec --no-startup-id ~/.i3/scripts/exit reboot, mode "default" + bindsym e exec --no-startup-id ~/.i3/scripts/exit logout, mode "default" + + # back to normal: Enter or Escape + bindsym Return mode "default" + bindsym Escape mode "default" +} + +bindsym $mod+Escape mode "$mode_system" +new_window pixel + +# Colors de las ventanas +# class border backgr text indicator +client.focused #990099 #222222 #ffffff #729FCF +client.focused_inactive #222222 #222222 #ffffff #729FCF +client.unfocused #222222 #222222 #ffffff #729FCF +client.urgent #FF0000 #8C5665 #ffffff #FF0000 + +# Wallpaper +exec --no-startup-id feh --bg-scale ~/Imagenes/Fondos\ de\ Pantalla/hacking-matrix_azul.png + +# Autostart +exec --no-startup-id xbacklight -set 100 +exec --no-startup-id bash ~/.i3/scripts/autolock.sh +exec --no-startup-id parcellite +exec --no-startup-id compton +exec --no-startup-id mpd + +# Mover programas automáticamente a workspace +assign [title="(?i)emacs"] $ws1 +assign [class="(?i)firefox"] $ws2 +assign [class="(?i)tor"] $ws2 +assign [class="(?i)qutebrowser"] $ws2 +assign [class="(?i)icecat"] $ws2 +assign [title="bittorrent"] $ws3 +assign [class="(?i)keepassx"] $ws5 +assign [title="Steam"] $ws7 +assign [class="(?i)mumble"] $ws8 +assign [class="(?i)mpv"] $ws8 +assign [class="(?i)transmission"] $ws8 +assign [class="(?i)thunderbird"] $ws9 +assign [title="mutt"] $ws9 + +# Hacer ventanas flotantes automáticamente +for_window [window_role="Preferences"] floating enable +for_window [window_role="help-browser"] floating enable +for_window [class="(?i)xcalc"] floating enable +for_window [window_role="pop-up"] floating enable +for_window [window_role="About"] floating enable +for_window [class="(?i)wicd"] floating enable +for_window [class="(?i)plasma-desktop"] floating enable +for_window [class="(?i)klipper"] floating enable +for_window [class="(?i)feh"] floating enable +for_window [class="Progreso de operación de archivo"] floating enable +for_window [title="emacsclient"] floating enable + +# i3-gaps +gaps inner 10 +gaps outer 10 +smart_borders on +smart_gaps on diff --git a/i3/lemonbar/README.md b/i3/lemonbar/README.md new file mode 100644 index 0000000..ccb6659 --- /dev/null +++ b/i3/lemonbar/README.md @@ -0,0 +1,148 @@ +# Esto es un fork +Mas o menos. En realidad "solo" he copiado la configuración de lemonbar de ![Electro7] (https://github.com/electro7/dotfiles/) y la he modificado. Dejo el README como referencia. Los cambios vienen a ser, cambiar formato de la hora y fecha y quitar el wifi de conky, cambiar el script de gmail por uno de notmuch, cambiar colores y añadir Font Awesome. + +# I3 LemonBar + +A functional config for lemonbar to work with i3wm. + +![lemonbar full] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_full.png) + +### Requeriments + +* Of course, [lemonbar] (https://github.com/LemonBoy/bar) + +* Alsa-utils for volume indicator. + +* Conky for CPU, MEM, NET and DISK usage. + +* Curl for gmail alert. + +* Weechat for private messages alert. Bitlbee for twitter and chat protocols + integration. + +* MPD and mpc for song info. + +* xprop for focus app indicator. + +* And finally, [i3wm] (https://i3wm.org) + +### Basically, how it works? + +***i3_lemonbar.sh*** bash script read the configuration from +***i3_lemonbar_config*** file. + +Later, execute the requested apps for the diferent meter sections. The output +is redirected to fifo file, adding 3 letters ID for each. + +Finally, run a ***i3_lemonbar_parser.sh*** that read from fifo, check the ID +meter, and converts it with lemonbar format. + +### Configuration + +* Change the bar section on i3wm config: + + ``` + bar { + i3bar_command ~./.i3/lemonbar/i3_lemonbar.sh + } + ``` +* Adjust bar settings editing i3_lemonnar_config. Settings for: + + * Fifo file. + * Bar geometry. + * Normal and icon font. [Here are my fonts used] (https://github.com/electro7/dotfiles/tree/master/.fonts) + * CPU and NET usage alerts. + * Colors + * Specials symbols for separator (powerline). + * Icons glyps. + +### Sections + +#### Workspace + +Workspace changes are received from ***i3_workspace.pl*** perl script. + +![lemonbar wsp] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_wsp.png) + +#### Focus window title + +Window title is received from xprop spy process. + +![lemonbar title] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_title.png) + +#### Time and date + +Time and date is received from conky process. Conky config file is +***i3_lemonbar_conky*** and refresh meters every 2 seconds. + +![lemonbar date] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_date.png) + +#### Volume + +Volume is received asking amixer every 3 seconds. If is muted show a cross. + +Volume channel can be set in "snd_cha" variable at config file. + +![lemonbar volume] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_vol.png) + +#### Net use + +ETH and WLAN use is received from conky process. If a interface is down, the +section is displayed gray with cross. + +Net use alert can be set in "net_alert" var at config file (Kb). + +![lemonbar net off] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_net_off.png) +![lemonbar net on] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_net_on.png) + +#### Disk use + +Show HOME and / disk use, in %. Meter is received fron conky process. + +![lemonbar disk] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_disk.png) + +#### RAM and CPU use + +Is received from conky process. CPU use alert can be set at "cpu_alert" var in +config file. + +![lemonbar cpu off] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_cpu_off.png) +![lemonbar cpu on] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_cpu_on.png) + +#### GMAIL unread message count + +Is received from [gmail.sh] (https://github.com/electro7/dotfiles/blob/master/bin/gmail.sh) +bash script using curl. The script is run every five minutes. Less time +can block the gmail external check. + +The account user and password are read from ***~/.private/accounts***, example: + + MAIL_USER="guest" + MAIL_PASS="1234" + +![lemonbar mail off] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_mail_off.png) +![lemonbar mail on] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_mail_on.png) + +#### IRC private warning + +Show a count of private messages in weechat and the last nick. + +Is received from [irc_warn.sh] (https://github.com/electro7/dotfiles/blob/master/bin/irc_warn) +bash script. This script is executed by weechat every time a private message is +received. + +For this, a beep trigger in weechat must be set with this: + + "/exec -bg ~/bin/irc_warn ${tg_date} ${tg_tag_nick}" + +For reset the warning, run ***irc_warn*** without parameters. + +![lemonbar irc off] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_irc_off.png) +![lemonbar irc on] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_irc_on.png) + +#### MPD song info + +Show autor and title of current song. Use mpd and mpc. + +![lemonbar mpd off] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_mpd_off.png) +![lemonbar mpd on] (https://dl.dropboxusercontent.com/u/60065791/screenshots/lemonbar/i3bar_mpd_on.png) diff --git a/i3/lemonbar/i3_lemonbar.sh b/i3/lemonbar/i3_lemonbar.sh new file mode 100755 index 0000000..403c66e --- /dev/null +++ b/i3/lemonbar/i3_lemonbar.sh @@ -0,0 +1,64 @@ +#! /bin/bash +# +# I3 bar with https://github.com/LemonBoy/bar + +. $(dirname $0)/i3_lemonbar_config + +if [ $(pgrep -cx $(basename $0)) -gt 1 ] ; then + printf "%s\n" "The status bar is already running." >&2 + exit 1 +fi + +trap 'trap - TERM; kill 0' INT TERM QUIT EXIT + +[ -e "${panel_fifo}" ] && rm "${panel_fifo}" +mkfifo "${panel_fifo}" + +### EVENTS METERS + +# Window title, "WIN" +xprop -spy -root _NET_ACTIVE_WINDOW | sed -un 's/.*\(0x.*\)/WIN\1/p' > "${panel_fifo}" & + +# i3 Workspaces, "WSP" +# TODO : Restarting I3 breaks the IPC socket con. :( +$(dirname $0)/i3_workspaces.pl > "${panel_fifo}" & + +# Conky, "SYS" +conky -c $(dirname $0)/i3_lemonbar_conky > "${panel_fifo}" & + +### UPDATE INTERVAL METERS +cnt_vol=${upd_vol} +cnt_mail=${upd_mail} +cnt_mpd=${upd_mpd} + +while :; do + # Volume, "VOL" + if [ $((cnt_vol++)) -ge ${upd_vol} ]; then + amixer get Master | grep "${snd_cha}" | awk -F'[]%[]' '/%/ {if ($7 == "off") {print "VOL×\n"} else {printf "VOL%d%%%%\n", $2}}' > "${panel_fifo}" & + cnt_vol=0 + fi + + # MAIL, "MAI" + if [ $((cnt_mail++)) -ge ${upd_mail} ]; then + printf "%s%s\n" "MAI" "$(~/.i3/scripts/notmuch)" > "${panel_fifo}" + cnt_mail=0 + fi + + # MPD + if [ $((cnt_mpd++)) -ge ${upd_mpd} ]; then + #printf "%s%s\n" "MPD" "$(ncmpcpp --now-playing '{%a - %t}|{%f}' | head -c 60)" > "${panel_fifo}" + printf "%s%s\n" "MPD" "$(mpc -h 127.0.0.1 current -f '[[%artist% - ]%title%]|[%file%]' 2>&1 | head -c 70)" > "${panel_fifo}" + cnt_mpd=0 + fi + + # Finally, wait 1 second + sleep 1s; + +done & + +#### LOOP FIFO + +cat "${panel_fifo}" | $(dirname $0)/i3_lemonbar_parser.sh \ + | lemonbar -p -f "${font}" -f "${iconfont}" -f "${iconfont2}" -g "${geometry}" -B "${color_back}" -F "${color_fore}" & + +wait diff --git a/i3/lemonbar/i3_lemonbar_config b/i3/lemonbar/i3_lemonbar_config new file mode 100644 index 0000000..74cc84b --- /dev/null +++ b/i3/lemonbar/i3_lemonbar_config @@ -0,0 +1,63 @@ +#!\bin\bash +# i3 panel config. Powerline style. + +panel_fifo="/tmp/i3_lemonbar_${USER}" +geometry="x14" +font="-xos4-terminesspowerline-medium-r-normal--12-120-72-72-c-60-iso10646-1" +iconfont="-xos4-terminusicons2mono-medium-r-normal--12-120-72-72-m-60-iso8859-1" +iconfont2="-misc-fontawesome-medium-r-normal--0-0-0-0-p-0-iso10646-1" +res_w=$(xrandr -d :0 | grep "current" | awk '{print $8a}') +snd_cha=$(amixer get Master | grep "Playback channels:" | awk '{if ($4 == "") {printf "%s: Playback", $3} else {printf "%s %s: Playback", $3, $4}}') + +# Alarm settings +cpu_alert=75 # % cpu use +net_alert=5 # K net use + +# update setting, in seconds (conky update in i3_lemonbar_conky +upd_vol=3 # Volume update +upd_mail=300 # Mail check update +upd_mpd=5 # MPD song update + +# color definitions +color_back="#1D1F21" # Default background +color_fore="#979997" # Default foreground +color_head="#5097E2" # Background for first element +color_sec_b1="#282A2E" # Background for section 1 +color_sec_b2="#454A4F" # Background for section 2 +color_sec_b3="#60676E" # Background for section 3 +color_icon="#979997" # For icons +color_mail="#CE935F" # Background color for mail alert +color_chat="#CC6666" # Background color for chat alert +color_cpu="#C125C1" # Background color for cpu alert +color_net="#5E8D87" # Background color for net alert +color_disable="#1D1F21" # Foreground for disable elements +color_wsp="#3774B6" # Background for selected workspace + +#default space between sections +if [ ${res_w} -gt 1024 ]; then + stab=' ' +else + stab=' ' +fi + +# Char glyps for powerline fonts +sep_left="" # Powerline separator left +sep_right="" # Powerline separator right +sep_l_left="" # Powerline light separator left +sep_l_right="" # Powerline light sepatator right + +# Icon glyphs from Terminusicons2 +icon_clock="Õ" # Clock icon +icon_cpu="Ï" # CPU icon +icon_mem="Þ" # MEM icon +icon_dl="Ð" # Download icon +icon_ul="Ñ" # Upload icon +icon_vol="Ô" # Volume icon +icon_hd="À" # HD / icon +icon_home="Æ" # HD /home icon +icon_mail="Ó" # Mail icon +icon_chat="Ò" # IRC/Chat icon +icon_music="Î" # Music icon +icon_prog="Â" # Window icon +icon_contact="Á" # Contact icon +icon_wsp="É" # Workspace icon diff --git a/i3/lemonbar/i3_lemonbar_conky b/i3/lemonbar/i3_lemonbar_conky new file mode 100644 index 0000000..354d13b --- /dev/null +++ b/i3/lemonbar/i3_lemonbar_conky @@ -0,0 +1,22 @@ +# Conky for external bar +# out simple text to console + +background no +update_interval 2 +total_run_times 0 +override_utf8_locale yes +short_units yes +uppercase no +out_to_console yes +out_to_x no +if_up_strictness address +format_human_readable true + +TEXT +SYS\ +${time %d/%m/%Y %H:%M} \ +${cpu} \ +${mem} \ +${fs_used_perc /home} \ +${if_up eth0}${downspeedf eth0} ${upspeedf eth0} \ +${else}down down${endif}\ diff --git a/i3/lemonbar/i3_lemonbar_parser.sh b/i3/lemonbar/i3_lemonbar_parser.sh new file mode 100755 index 0000000..2d4a9ca --- /dev/null +++ b/i3/lemonbar/i3_lemonbar_parser.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# +# Input parser for i3 bar +# 14 ago 2015 - Electro7 + +# config +. $(dirname $0)/i3_lemonbar_config + +# min init +irc_n_high=0 +title="%{F${color_head} B${color_sec_b2}}${sep_right}%{F${color_head} B${color_sec_b2}%{T2} ${icon_prog} %{F${color_sec_b2} B-}${sep_right}%{F- B- T1}" + +# parser +while read -r line ; do + case $line in + SYS*) + # conky=, 0 = wday, 1 = mday, 2 = month, 3 = time, 4 = cpu, 5 = mem, 6 = disk /, 7 = disk /home, 8-9 = up/down wlan, 10-11 = up/down eth, 12-13=speed + sys_arr=(${line#???}) + # date + date="${sys_arr[0]}" + date="%{F${color_sec_b1}}${sep_left}%{F${color_icon} B${color_sec_b1}} %{T2}${icon_clock}%{F- T1} ${date}" + # time + time="%{F${color_head}}${sep_left}%{F${color_back} B${color_head}} ${sys_arr[1]} %{F- B-}" + # cpu + if [ ${sys_arr[2]} -gt ${cpu_alert} ]; then + cpu_cback=${color_cpu}; cpu_cicon=${color_back}; cpu_cfore=${color_back}; + else + cpu_cback=${color_sec_b2}; cpu_cicon=${color_icon}; cpu_cfore=${color_fore}; + fi + cpu="%{F${cpu_cback}}${sep_left}%{F${cpu_cicon} B${cpu_cback}} %{T2}${icon_cpu}%{F${cpu_cfore} T1} ${sys_arr[2]}%%" + # mem + mem="%{F${cpu_cicon}}${sep_l_left} %{T2}${icon_mem}%{F${cpu_cfore} T1} ${sys_arr[3]}" + # disk home + diskh="%{F${color_icon}}${sep_l_left} %{T2}${icon_home}%{F- T1} ${sys_arr[4]}%%" + # eth + if [ "${sys_arr[5]}" == "down" ]; then + ethd_v="×"; ethu_v="×"; + eth_cback=${color_sec_b1}; eth_cicon=${color_disable}; eth_cfore=${color_disable}; + else + ethd_v=${sys_arr[5]}K; ethu_v=${sys_arr[6]}K; + if [ ${ethd_v:0:-3} -gt ${net_alert} ] || [ ${ethu_v:0:-3} -gt ${net_alert} ]; then + eth_cback=${color_net}; eth_cicon=${color_back}; eth_cfore=${color_back}; + else + eth_cback=${color_sec_b1}; eth_cicon=${color_icon}; eth_cfore=${color_fore}; + fi + fi + ethd="%{F${eth_cback}}${sep_left}%{F${eth_cicon} B${eth_cback}} %{T2}${icon_dl}%{F${eth_cfore} T1} ${ethd_v}" + ethu="%{F${eth_cicon}}${sep_l_left} %{T2}${icon_ul}%{F${eth_cfore} T1} ${ethu_v}" + ;; + VOL*) + # Volume + vol="%{F${color_sec_b2}}${sep_left}%{F${color_icon} B${color_sec_b2}} %{T2}${icon_vol}%{F- T1} ${line#???}" + ;; + MAI*) + # Mail + mail="${line#???}" + if [ "${mail}" != "0" ]; then + mail_cback=${color_mail}; mail_cicon=${color_back}; mail_cfore=${color_back} + else + mail_cback=${color_sec_b1}; mail_cicon=${color_icon}; mail_cfore=${color_fore} + fi + mail="%{F${mail_cback}}${sep_left}%{F${mail_cicon} B${mail_cback}} %{T2}${icon_mail}%{F${mail_cfore} T1} ${mail}" + ;; + IRC*) + # IRC highlight (script irc_warn) + if [ "${line#???}" != "0" ]; then + echo "${line#???}" + ((irc_n_high++)); irc_high="${line#???}"; + irc_cback=${color_chat}; irc_cicon=${color_back}; irc_cfore=${color_back} + else + irc_n_high=0; [ -z "${irc_high}" ] && irc_high="None"; + irc_cback=${color_sec_b2}; irc_cicon=${color_icon}; irc_cfore=${color_fore} + fi + irc="%{F${irc_cback}}${sep_left}%{F${irc_cicon} B${irc_cback}} %{T2}${icon_chat}%{F${irc_cfore} T1} ${irc_n_high} %{F${irc_cicon}}${sep_l_left} %{T2}${icon_contact}%{F${irc_cfore} T1} ${irc_high}" + ;; + MPD*) + # Music + mpd_arr=(${line#???}) + if [ -z "${line#???}" ]; then + song="None"; + elif [ "${mpd_arr[0]}" == "error:" ]; then + song="mpd off"; + else + song="${line#???}"; + fi + mpd="%{F${color_sec_b2}}${sep_left}%{B${color_sec_b2}}%{F${color_sec_b1}}${sep_left}%{F${color_icon} B${color_sec_b1}} %{T2}${icon_music}%{F${color_fore} T1} ${song}" + ;; + WSP*) + # I3 Workspaces + wsp="%{F${color_back} B${color_head}} %{T2}${icon_wsp}%{T1}" + set -- ${line#???} + while [ $# -gt 0 ] ; do + case $1 in + FOC*) + wsp="${wsp}%{F${color_head} B${color_wsp}}${sep_right}%{F${color_back} B${color_wsp} T1} ${1#???} %{F${color_wsp} B${color_head}}${sep_right}" + ;; + INA*|URG*|ACT*) + wsp="${wsp}%{F${color_disable} T1} ${1#???} " + ;; + esac + shift + done + ;; + WIN*) + # window title + title=$(xprop -id ${line#???} | awk '/_NET_WM_NAME/{$1=$2="";print}' | cut -d'"' -f2) + title="%{F${color_head} B${color_sec_b2}}${sep_right}%{F${color_head} B${color_sec_b2} T2} ${icon_prog} %{F${color_sec_b2} B-}${sep_right}%{F- B- T1} ${title}" + ;; + esac + + # And finally, output + printf "%s\n" "%{l}${wsp}${title} %{r}${mpd}${stab}${irc}${stab}${mail}${stab}${cpu}${stab}${mem}${stab}${diskh}${stab}${wlanu}${stab}${ethd}${stab}${ethu}${stab}${vol}${stab}${date}${stab}${time}" +done diff --git a/i3/lemonbar/i3_workspaces.pl b/i3/lemonbar/i3_workspaces.pl new file mode 100755 index 0000000..0feb3bb --- /dev/null +++ b/i3/lemonbar/i3_workspaces.pl @@ -0,0 +1,138 @@ +#!/usr/bin/env perl +# vim:ts=4:sw=4:expandtab:ft=perl +# +# Print i3 workspaces on every change. +# +# Format: +# For every workspace (x = workspace name) +# - "FOCx" -> Focused workspace +# - "INAx" -> Inactive workspace +# - "ACTx" -> Ative workspace +# - "URGx" -> Urgent workspace +# +# Uses AnyEvent I3 0.8 -> https://metacpan.org/module/AnyEvent::I3 +# Based in i3-wsbar of Michael Stapelberg -> http://code.stapelberg.de/git/i3/tree/contrib/i3-wsbar +# +# 16 feb 2015 - Electro7 + +use strict; +use warnings; +use AnyEvent::I3; +use AnyEvent; +use v5.10; + +my $socket_path = undef; +my ($workspaces, $outputs) = ([], {}); +my $w = AnyEvent->timer( + after => 3, + cb => sub { + die "Connection to i3 timed out. Verify socket path ($socket_path)"; + exit 1; + } +); + + +my $i3 = i3($socket_path); + +# Disable buffering +$| = 1; +STDERR->autoflush; +STDOUT->autoflush; + +# Wait a short amount of time and try to connect to i3 again +sub reconnect { + print "reconecting\n"; + my $timer; + $i3 = i3($socket_path); + if (!defined($w)) { + $w = AnyEvent->timer( + after => 3, + cb => sub { + die "Connection to i3 timed out. Verify socket path ($socket_path)"; + exit 1; + } + ); + } + + my $c = sub { + $timer = AnyEvent->timer( + after => 0.01, + cb => sub { $i3->connect->cb(\&connected) } + ); + }; + $c->(); +} + +# Connection attempt succeeded or failed +sub connected { + my ($cv) = @_; + + if (!$cv->recv) { + reconnect(); + return; + } + + $w = undef; + + $i3->subscribe({ + workspace => \&ws_change, + output => \&output_change, + _error => sub { reconnect() } + }); + ws_change(); + output_change(); +} + +# Called when a ws changes +sub ws_change { + # Request the current workspaces and update the output afterwards + $i3->get_workspaces->cb( + sub { + my ($cv) = @_; + $workspaces = $cv->recv; + update_output(); + }); +} + +# Called when the reply to the GET_OUTPUTS message arrives +sub got_outputs { + my $reply = shift->recv; + my %new = map { ($_->{name}, $_) } grep { $_->{active} } @{$reply}; + + for my $name (keys %new) { + $outputs->{$name} = $new{$name}; + } + + update_output(); +} + +sub output_change { + $i3->get_outputs->cb(\&got_outputs) +} + +sub update_output { + my $out; + + for my $name (keys %{$outputs}) { + $out .= "WSP"; + + for my $ws (@{$workspaces}) { + my $state = "INA"; + $state = "ACT" if $ws->{visible}; + $state = "URG" if $ws->{urgent}; + $state = "FOC" if $ws->{focused}; + my $name = $ws->{name}; + # strip workspace number + $name = substr($name, 1, 2); + $out .= qq|$state$name |; + } + + $out .= "\n"; + print $out; + } +} + +$i3->connect->cb(\&connected); + +# let AnyEvent do the rest ("endless loop") +AnyEvent->condvar->recv diff --git a/i3/lemonbar/i3_workspaces.py b/i3/lemonbar/i3_workspaces.py new file mode 100755 index 0000000..97db5fe --- /dev/null +++ b/i3/lemonbar/i3_workspaces.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# +# Print i3 workspaces on every change. +# +# Format: +# For every workspace (x = workspace name) +# - "FOCx" -> Focused workspace +# - "INAx" -> Inactive workspace +# - "ACTx" -> Ative workspace +# - "URGx" -> Urgent workspace +# +# Uses i3py.py -> https://github.com/ziberna/i3-py +# Based in wsbar.py en examples dir +# +# 16 feb 2015 - Electro7 + + +import sys +import time +import subprocess + +import i3 + +class State(object): + # workspace states + focused = 'FOC' + active = 'ACT' + inactive = 'INA' + urgent = 'URG' + + def get_state(self, workspace, output): + if workspace['focused']: + if output['current_workspace'] == workspace['name']: + return self.focused + else: + return self.active + if workspace['urgent']: + return self.urgent + else: + return self.inactive + + +class i3ws(object): + ws_format = '%s%s ' + end_format = 'WSP%s' + state = State() + + def __init__(self, state=None): + if state: + self.state = state + # socket + self.socket = i3.Socket() + # Output to console + workspaces = self.socket.get('get_workspaces') + outputs = self.socket.get('get_outputs') + self.display(self.format(workspaces, outputs)) + # Subscribe to an event + callback = lambda data, event, _: self.change(data, event) + self.subscription = i3.Subscription(callback, 'workspace') + + def change(self, event, workspaces): + # Receives event and workspace data + if 'change' in event: + outputs = self.socket.get('get_outputs') + text = self.format(workspaces, outputs) + self.display(text) + + def format(self, workspaces, outputs): + # Formats the text according to the workspace data given. + out = '' + for workspace in workspaces: + output = None + for output_ in outputs: + if output_['name'] == workspace['output']: + output = output_ + break + if not output: + continue + st = self.state.get_state(workspace, output) + name = workspace['name'] + item= self.ws_format % (st, name) + out += item + return self.end_format % out + + def display(self, text): + # Displays the text in stout + print(text) + sys.stdout.flush() + + def quit(self): + # Quits the i3ws; closes the subscription and terminates + self.subscription.close() + +if __name__ == '__main__': + ws = i3ws() + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + print('') # force new line + finally: + ws.quit()