A polybar with dwm
Go to file
2016-06-10 12:18:17 +02:00
.hooks feat(git): Update old tag refs in README.md using pre-commit hook 2016-05-24 17:02:33 +02:00
cmake fix(build): Improved dependency checks 2016-05-24 04:06:29 +02:00
contrib task(build): Bumped version to 0.2.0 2016-06-10 01:16:01 +02:00
examples fix(config): Include more fields in example config 2016-06-10 12:18:17 +02:00
include fix(volume): Improve mixer event handling 2016-06-10 01:09:54 +02:00
scripts feat(dsl): DSL patching script 2016-05-31 19:45:56 +02:00
src fix(volume): Improve mixer event handling 2016-06-10 01:09:54 +02:00
.exrc init(git): Base commit 2016-05-19 20:23:45 +02:00
.gitignore init(git): Base commit 2016-05-19 20:23:45 +02:00
.gitmodules fix(git): Fixate submodules 2016-05-31 05:13:22 +02:00
.travis.yml fix(ci): Irc notification template 2016-05-31 16:53:03 +02:00
.ycm_extra_conf.py init(git): Base commit 2016-05-19 20:23:45 +02:00
build.sh fix(build.sh): Add newline after prompt 2016-05-24 04:44:02 +02:00
CMakeLists.txt task(build): Bumped version to 0.2.0 2016-06-10 01:16:01 +02:00
config feat(core): Throttle writes to stdout 2016-06-01 01:07:23 +02:00
LICENSE init(git): Base commit 2016-05-19 20:23:45 +02:00
README.md task(build): Bumped version to 0.2.0 2016-06-10 01:16:01 +02:00

Lemonbuddy

A fast and easy-to-use tool for Lemonbar.

Lemonbuddy aims to help users build beautiful and highly customizable status bars without messing with named pipes, MacGyver-like scripting or non-blocking loops lobotomizing your CPU.

Please note that the project is still in early development, so please report any anomalies by creating an issue ticket here on GitHub. I welcome pull requests with fixes or improvements.

Here's a screenshot showing you an example of what it could look like:

bspwm workspace

Installation

Arch Linux

Install the AUR package lemonbuddy-git to get the latest version, or lemonbuddy for the latest stable release.

Void Linux

A package will be written for XBPS so stay tuned.

Dependencies:

A C++ compiler with C++14 support. For example clang.

  • lemonbar
  • cmake
  • boost
  • libx11
  • libxrandr
  • wireless_tools (optional: used by the network module)
  • alsa-lib (optional: used by the volume module)
  • libmpdclient (optional: used by the mpd module)
  • libsigc++ (optional: used by the i3 module)

NOTE: The application has only been tested against the single-mon fork. If you have trouble running it with your current version, install the one included in contrib/lemonbar-sm-git. Plans are to make lemonbar an internal module.

Install dependencies using pacman:

$ sudo pacman -S cmake boost libx11 libxrandr wireless_tools alsa-lib libmpdclient libsigc++
$ yaourt ttf-font-awesome

Install dependencies using xbps-install:

$ sudo xbps-install cmake alsa-lib-devel boost-devel i3-devel libX11-devel libXrandr-devel libmpdclient-devel libsigc++-devel wireless_tools-devel
$ sudo xbps-install font-awesome

Install dependencies using apt-get:

NOTE: To get support for the mpd and i3 modules, the universe repository needs to be added to the list of sources in /etc/apt/sources.list.

Packages in the universe repository: libmpdclient-dev fonts-font-awesome

$ sudo apt-get install cmake libxrandr-dev libboost-dev libiw-dev libasound2-dev libmpdclient-dev libsigc++-2.0-dev
$ sudo apt-get install fonts-font-awesome

Building from source

NOTE: In Void Linux you will need to install git-perl to get support for submodules.

$ git clone --branch 0.2.0 --recursive https://github.com/jaagr/lemonbuddy.git
$ mkdir lemonbuddy/build
$ cd lemonbuddy/build
$ cmake ..
# Optionally list and edit build settings before compiling
# $ make edit_cache
$ sudo make install

Running

Before customizing the bar, make sure everything works as expected by trying out one of the example configurations installed with the application. The following code will get you started:

# Create the config root directory
$ mkdir -p ${XDG_CONFIG_HOME:-$HOME/.config}/lemonbuddy
$ cd ${XDG_CONFIG_HOME:-$HOME/.config}/lemonbuddy

# Copy sample config for the running wm (uses a wm agnostic config as fallback)
$ __wm=$(pgrep -l -x "(bspwm|i3)"); __prefix=$(which lemonbuddy)
$ cp "${__prefix%%/bin*}/share/examples/lemonbuddy/config${__wm:+.${__wm##* }}" config

# Launch the bar
# (where "example" is the name of the bar as defined by [bar/NAME] in the config)
$ lemonbuddy_wrapper.sh example

NOTE: If you are running i3 or bspwm and you don't see the workspace icons it probably depends on the font. Install font-awesome and relaunch the bar. ...or replace the icons in the config.

It is recommended to always use lemonbuddy_wrapper.sh when launching the bars.

lemonbuddy_wrapper.sh is just a simple shell script that takes care of redirecting the in-/output streams between lemonbuddy and lemonbar.

If you handle the in-/output stream redirection's manually, the internal command handlers (e.g. mpd or volume controls) might stop working. It won't change the output of the bar but you will miss out on the internal API calls, which is one of the main advantages of using the application.

The lemonbuddy_wrapper.sh will be deprecated once lemonbar is integrated into the project.

Launching the bar in your wm's bootstrap routine

When using the wrapper to start the bar in in your wm's autostart routine, make sure to include a kill directive before launching the bar. This is done to make sure that any previously spawned processes gets terminated before before we launch the new ones. For example in $HOME/.config/bspwmrc:

# Terminate already running bar instances
pgrep -f '(lemonbuddy_wrapper.sh|^lemonb(uddy|ar))' | xargs kill -9 >/dev/null 2>&1

# Launch bar1 and bar2
lemonbuddy_wrapper.sh bar1 &
lemonbuddy_wrapper.sh bar2 &

echo "Bars launched..."

Configuration

The configuration syntax is very much WIP. An upcoming change will replace all occurences of colon's with dashes in the parameter names. If you have any feedback or suggestions, please create an issue ticket.

When working with unicode symbols, remember that fonts render them differently. Changing font can change the quality of your generated output drastically. One must-have font is Unifont, which has great unicode coverage.

Also try different icon fonts, such as Font Awesome and Material Icons.

The values used in the examples below are to be considered placeholder values, and the resulting output might not be award-winning.

🟊 = module is still flagged as work in progress

Application settings

[settings]
; Limit the amount of events sent to lemonbar within a set timeframe:
; - "Allow <throttle_limit> updates within <throttle_ms> of time"
; Default values:
;throttle_limit = 5
;throttle_ms = 50

Bar settings

[bar/example]
; Use the following command to list available outputs:
; $ xrandr -q | grep " connected" | cut -d ' ' -f1
monitor = HDMI1

; Omit the % to specify the width in pixels
width = 100%
height = 30

; Offset value defined in pixels
;offset_x = 0
;offset_y = 0

; Put the bar at the bottom of the screen
bottom = true

; Weather to force docking mode or not
dock = false

; This value is used as a multiplier when adding spaces between elements
spacing = 3

; Height of under-/overline
lineheight = 14

; Colors
background = #222222
foreground = #eefafafa
linecolor = ${bar/example.background}

; Amount of spaces to add at the start/end of the whole bar
padding_left = 5
padding_right = 2

; Amount of spaces to add before/after each module
module_margin_left = 3
module_margin_right = 3

; Fonts are defined using: <FontName>;<Offset>
font:0 = NotoSans-Regular:size=8;0
font:1 = MaterialIcons:size=10;0
font:2 = Termsynu:size=8;-1
font:3 = FontAwesome:size=10;0

; The separator will be inserted between the output of each module
;separator = |

; This value is used by Lemonbar and it specifies the clickable
; areas available -> %{A:action:}...%{A}
clickareas = 30

; Value to be used to set the WM_NAME atom
; This defaults to "lemonbuddy-BARNAME_MONITOR"
;wm_name = mybar

; Locale used to localize module output (for example date)
;locale = sv_SE.UTF-8

; Define what modules to output
modules:left = cpu ram
modules:center = label
modules:right = clock

Module internal/backlight

[module/backlight]
type = internal/backlight

; Use the following command to list available cards:
; $ ls -1 /sys/class/backlight/
card = intel_backlight
Extra formatting (example)
; Available tags:
;   <label> (default)
;   <ramp>
;   <bar>
format = <ramp> <bar>

; Available tokens:
;   %percentage% (default)
label = %percentage%

ramp:0 = 🌕
ramp:1 = 🌔
ramp:2 = 🌓
ramp:3 = 🌒
ramp:4 = 🌑

bar:width = 10
bar:indicator = |
bar:fill = 
bar:empty = 

Module internal/battery

[module/battery]
type = internal/battery

; This is useful in case the battery never reports 100% charge
;full_at = 99

; Use the following command to list batteries and adapters:
; $ ls -1 /sys/class/power_supply/
;battery = BAT0
;adapter = ADP1

; Seconds between reading battery capacity.
; If set to 0, polling will be disabled.
;poll_interval = 3
Extra formatting (example)
; Available tags:
;   <label:charging> (default)
;   <bar:capaity>
;   <ramp:capacity>
;   <animation:charging>
format:charging = <animation:charging> <label:charging>

; Available tags:
;   <label:discharging> (default)
;   <bar:capaity>
;   <ramp:capacity>
format:discharging = <ramp:capacity> <label:discharging>

; Available tags:
;   <label:full> (default)
;   <bar:capaity>
;   <ramp:capacity>
;format:full = <ramp:capacity> <label:full>

; Available tokens:
;   %percentage% (default)
label:charging = Charging %percentage%

; Available tokens:
;   %percentage% (default)
label:discharging = Discharging %percentage%

; Available tokens:
;   %percentage% (default)
label:full = Fully charged

ramp:capacity:0 = 
ramp:capacity:1 = 
ramp:capacity:2 = 
ramp:capacity:3 = 
ramp:capacity:4 = 

bar:capacity:width = 10

animation:charging:0 = 
animation:charging:1 = 
animation:charging:2 = 
animation:charging:3 = 
animation:charging:4 = 
animation:charging:framerate_ms = 750

Module internal/bspwm

[module/bspwm]
type = internal/bspwm
Extra formatting (example)
; workspace_icon:[0-9]+ = label;icon
workspace_icon:0 = code;♚
workspace_icon:1 = office;♛
workspace_icon:2 = graphics;♜
workspace_icon:3 = mail;♝
workspace_icon:4 = web;♞
workspace_icon:default = 

; Available tags:
;   <label:state> (default) - gets replaced with <label:(active|urgent|occupied|empty)>
;   <label:mode> - gets replaced with <label:(monocle|tiled|fullscreen|floating|locked|sticky|private)>
format = <label:state> <label:mode>

; If any values for label:dimmed:N area defined, the workspace/mode colors will get overridden
; with those values if the monitor is out of focus
label:dimmed:foreground = #555
label:dimmed:underline = ${BAR.background}

; Available tokens:
;   %name%
;   %icon%
;   %index%
; Default: %icon%  %name%
label:active = %icon%
label:active:foreground = #ffffff
label:active:background = #3f3f3f
label:active:underline = #fba922

; Available tokens:
;   %name%
;   %icon%
;   %index%
; Default: %icon%  %name%
label:occupied = %icon%
label:occupied:underline = #555555

; Available tokens:
;   %name%
;   %icon%
;   %index%
; Default: %icon%  %name%
label:urgent = %icon%
label:urgent:foreground = #000000
label:urgent:background = #bd2c40
label:urgent:underline = #9b0a20

; Available tokens:
;   %name%
;   %icon%
;   %index%
; Default: %icon%  %name%
label:empty = %icon%
label:empty:foreground = #55ffffff

; Available tokens:
;   None
label:monocle = 
;label:tiled = 
;label:fullscreen = 
;label:floating = 
label:locked = 
label:locked:foreground = #bd2c40
label:sticky = 
label:sticky:foreground = #fba922
label:private = 
label:private:foreground = #bd2c40

Module internal/cpu

[module/cpu]
type = internal/cpu

; Seconds to sleep between updates
;interval = 0.5
Extra formatting (example)
; Available tags:
;   <label> (default)
;   <bar:load>
;   <ramp:load>
;   <ramp:load_per_core>
format = <label> <ramp:load_per_core>

; Available tokens:
;   %percentage% (default) - total cpu load
label = CPU %percentage%

ramp:load_per_core:0 = 
ramp:load_per_core:1 = 
ramp:load_per_core:2 = 
ramp:load_per_core:3 = 
ramp:load_per_core:4 = 
ramp:load_per_core:5 = 
ramp:load_per_core:6 = 
ramp:load_per_core:7 = 

Module internal/date

[module/date]
type = internal/date

; Seconds to sleep between updates
;interval = 1.0

; see "man date" for details on how to format the date string
; NOTE: if you want to use lemonbar tags here you need to use %%{...}
date = %Y-%m-%d% %H:%M

; if date_detailed is defined, clicking the area will toggle between formats
date_detailed = %%{F#888}%A, %d %B %Y%  %%{F#fff}%H:%M%%{F#666}:%%{F#fba922}%S%%{F-}
Extra formatting (example)
; Available tags:
;   <date> (default)
format = 🕓 <date>
format:background = #55ff3399
format:foreground = #fff

🟊 Module internal/i3

Requires the project to be built with support for i3. For more information, see the dependency section.

The module is still marked as WIP since it needs more testing. If you notice any anomalies, please create an issue.

See the bspwm module for details on label:dimmed.

[module/i3]
type = internal/i3
Extra formatting (example)
; workspace_icon:[0-9]+ = label;icon
workspace_icon:0 = 1;♚
workspace_icon:1 = 2;♛
workspace_icon:2 = 3;♜
workspace_icon:3 = 4;♝
workspace_icon:4 = 5;♞
workspace_icon:default = 

; Available tags:
;   <label:state> (default) - gets replaced with <label:(focused|unfocused|visible|urgent)>
;format = <label:state>

; Available tokens:
;   %name%
;   %icon%
;   %index%
; Default: %icon%  %name%
label:focused = %icon%
label:focused:foreground = #ffffff
label:focused:background = #3f3f3f
label:focused:underline = #fba922
label:focused:padding = 4

; Available tokens:
;   %name%
;   %icon%
;   %index%
; Default: %icon%  %name%
label:unfocused = %icon%
label:unfocused:padding = 4

; Available tokens:
;   %name%
;   %icon%
;   %index%
; Default: %icon%  %name%
label:visible = %icon%
label:visible:underline = #555555
label:visible:padding = 4

; Available tokens:
;   %name%
;   %icon%
;   %index%
; Default: %icon%  %name%
label:urgent = %icon%
label:urgent:foreground = #000000
label:urgent:background = #bd2c40
label:urgent:padding = 4

Module internal/memory

[module/memory]
type = internal/memory

; Seconds to sleep between updates
;interval = 1.0
Extra formatting (example)
; Available tags:
;   <label> (default)
;   <bar:used>
;   <bar:free>
format = <label> <bar:used>

; Available tokens:
;   %percentage_used% (default)
;   %percentage_free%
;   %gb_used%
;   %gb_free%
;   %gb_total%
;   %mb_used%
;   %mb_free%
;   %mb_total%
label = RAM %percentage_used%

bar:used:width = 50
bar:used:foreground:0 = #55aa55
bar:used:foreground:1 = #557755
bar:used:foreground:2 = #f5a70a
bar:used:foreground:3 = #ff5555
bar:used:fill = 
bar:used:empty = 
bar:used:empty:foreground = #444444

Module internal/mpd

[module/mpd]
type = internal/mpd

;host = 127.0.0.1
;port = 6600
;password = mypassword

; Seconds to sleep between progressbar/song timer sync
;interval = 0.5
Extra formatting (example)
; Available tags:
;   <label:song> (default)
;   <label:time>
;   <bar:progress>
;   <toggle> - gets replaced with <icon:(pause|play)>
;   <icon:random>
;   <icon:repeat>
;   <icon:repeatone>
;   <icon:prev>
;   <icon:stop>
;   <icon:play>
;   <icon:pause>
;   <icon:next>
format:online = <icon:prev> <icon:stop> <toggle> <icon:next>  <icon:repeat> <icon:random>  <bar:progress> <label:time>  <label:song>

; Available tags:
;   <label:offline>
;format:offline = <label:offline>

; Available tokens:
;   %artist%
;   %album%
;   %title%
; Default: %artist% - %title%
;label:song = 𝄞 %artist% - %title%

; Available tokens:
;   %elapsed%
;   %total%
; Default: %elapsed% / %total%
;label:time = %elapsed% / %total%

; Available tokens:
;   None
label:offline = 🎜 mpd is offline

icon:play = 
icon:pause = 
icon:stop = 
icon:prev = 
icon:next = 
icon:random = 🔀
icon:repeat = 🔁
;icon:repeatone = 🔂

; Used to display the state of random/repeat/repeatone
toggle_on:foreground = #ff
toggle_off:foreground = #55

bar:progress:width = 45
bar:progress:indicator = |
bar:progress:fill = 
bar:progress:empty = 

Module internal/network

NOTE: If you use both a wired and a wireless network, just add 2 module definitions. For example:

[module/wired-network]
type = internal/network
interface = eth1

[module/wireless-network]
type = internal/network
interface = wlan1
[module/network]
type = internal/network
interface = wlan1

; Seconds to sleep between updates
interval = 3.0

; Test connectivity every Nth update
; A value of 0 disables the feature
; Recommended minimum value: round(10 / interval)
;   - which would test the connection approx. every 10th sec.
; Default: 0
;ping_interval = 3
Extra formatting (example)
; Available tags:
;   <label:connected> (default)
;   <ramp:signal>
format:connected = <ramp:signal> <label:connected>

; Available tags:
;   <label:disconnected> (default)
;format:disconnected = <label:disconnected>

; Available tags:
;   <label:connected> (default)
;   <label:packetloss>
;   <animation:packetloss>
format:packetloss = <animation:packetloss> <label:connected>

; Available tokens:
;   %ifname%    [wireless+wired]
;   %local_ip%  [wireless+wired]
;   %essid%     [wireless]
;   %signal%    [wireless]
;   %linkspeed% [wired]
; Default: %ifname% %local_ip%
label:connected = %essid%
label:connected:foreground = #eefafafa

; Available tokens:
;   %ifname%    [wireless+wired]
; Default: (none)
;label:disconnected = not connected
;label:disconnected:foreground = #66ffffff

; Available tokens:
;   %ifname%    [wireless+wired]
;   %local_ip%  [wireless+wired]
;   %essid%     [wireless]
;   %signal%    [wireless]
;   %linkspeed% [wired]
; Default: (none)
;label:packetloss = %essid%
;label:packetloss:foreground = #eefafafa

ramp:signal:0 = 😱
ramp:signal:1 = 😠
ramp:signal:2 = 😒
ramp:signal:3 = 😊
ramp:signal:4 = 😃
ramp:signal:5 = 😈

animation:packetloss:0 = 
animation:packetloss:0:foreground = #ffa64c
animation:packetloss:1 = 📶
animation:packetloss:1:foreground = #000000
animation:packetloss:framerate_ms = 500

🟊 Module internal/volume

This module is still WIP.

Mute and volume changes should affect the appropriate mixers depending on weather the headphones are plugged in or not. Still need to add separate output formats to indicate it.

[module/volume]
type = internal/volume
;master_mixer = Master

; Use the following command to list available mixer controls:
; $ amixer scontrols | sed -nr "s/.*'([[:alnum:]]+)'.*/\1/p"
speaker_mixer = Speaker
headphone_mixer = Headphone

; NOTE: This is required if headphone_mixer is defined
; Use the following command to list available device controls
; $ amixer controls | sed -r "/CARD/\!d; s/.*=([0-9]+).*name='([^']+)'.*/printf '%3.0f: %s\n' '\1' '\2'/e" | sort
headphone_control_numid = 9
Extra formatting (example)
; Available tags:
;   <label:volume> (default)
;   <ramp:volume>
;   <bar:volume>
format:volume = <ramp:volume> <label:volume>

; Available tags:
;   <label:muted> (default)
;   <ramp:volume>
;   <bar:volume>
;format:muted = <label:muted>

; Available tokens:
;   %percentage% (default)
;label:volume = %percentage%

; Available tokens:
;   %percentage% (default)
label:muted = 🔇 muted
label:muted:foreground = #66

; Required if <ramp:volume> is used
ramp:volume:0 = 🔈
ramp:volume:1 = 🔉
ramp:volume:2 = 🔊

Module custom/menu

[module/menu-apps]
type = custom/menu

; "menu:LEVEL:N" has the same properties as "label:NAME" with
; the additional "exec" property
;
; Available exec commands:
;   menu_open:LEVEL
;   menu_close
; Other commands will be executed using "/usr/bin/env sh -c $COMMAND"

menu:0:0 = Browsers
menu:0:0:exec = menu_open:1
menu:0:0:foreground = #fba922
menu:0:2 = Multimedia
menu:0:2:exec = menu_open:3
menu:0:2:foreground = #fba922

menu:1:0 = Firefox
menu:1:0:exec = firefox &
menu:1:0:foreground = #fba922
menu:1:1 = Chromium
menu:1:1:exec = chromium &
menu:1:1:foreground = #fba922

menu:2:0 = Gimp
menu:2:0:foreground = #fba922
menu:2:0:exec = gimp &
menu:2:1 = Scrot
menu:2:1:exec = scrot &
menu:2:1:foreground = #fba922
Extra formatting (example)
; Available tags:
;   <label:toggle> (default) - gets replaced with <label:(open|close)>
;   <menu> (default)
;format = <label:toggle> <menu>

label:open = Apps
label:close = x

Module custom/script

[module/pkgupdates-available]
type = custom/script

; Available tokens:
;   %counter%
; The "exec" command will be executed using "/usr/bin/env sh -c [command]"
exec = count=$(sudo pacman -Syup --noprogressbar 2>/dev/null | sed '/Starting full/,~1!d;/Starting full/d' | wc -l); [ $count -gt 0 ] && echo "Updates available: $count"
;exec = count=$(echo n | sudo xbps-install -Su >/dev/null 2>&1; sudo xbps-install -Sun | wc -l); [ $count -gt 0 ] && echo "Updates available: $count"

; Seconds to sleep between updates
interval = 90
Extra formatting (example)
; Available tags:
;   <output> (default)
;format = <output>
format:background = #999
format:foreground = #000
format:padding = 4

; Available tokens:
;   %counter%
;
; "click:(left|middle|right)" will be executed using "/usr/bin/env sh -c [command]"
click:left = echo left %counter%
click:middle = echo middle %counter%
click:right = echo right %counter%

; Available tokens:
;   %counter%
;
; "scroll:(up|down)" will be executed using "/usr/bin/env sh -c [command]"
scroll:up = echo scroll up %counter%
scroll:down = echo scroll down %counter%
Useful example

Show title of the currently focused window.

[module/xtitle]
type = custom/script
exec = xtitle
interval = 0.25

Module custom/text

[module/my-text-label]
type = custom/text
content = Some random label
Extra formatting (example)
; "content" has the same properties as "format:NAME"
content:background = #000
content:foreground = #fff
content:padding = 4

; "click:(left|middle|right)" will be executed using "/usr/bin/env sh -c $COMMAND"
click:left = echo left
click:middle = echo middle
click:right = echo right

; "scroll:(up|down)" will be executed using "/usr/bin/env sh -c $COMMAND"
scroll:up = echo scroll up
scroll:down = echo scroll down

License

Lemonbuddy is licensed under the MIT license. See LICENSE for more information.