The status bar Xmobar works out of the box on the top edge of your screen and shows useful system info. However, if you want to make it look nice and change what information to show, you can customize it with a tiny bit of Haskell.
You can customize Xmobar by creating a file named .xmobarrc
in your home folder with
gedit ~/.xmobarrc
and copy-paste the following example content
Config
= "white"
{ bgColor = "black"
, fgColor = BottomB
, border = "black"
, borderColor = -- what information to show
, commands -- network activity monitor (dynamic interface resolution)
Run DynNetwork [] 10 -- network traffic
[ Run Memory ["-t" ,"RAM: <usedratio>%"] 10 -- RAM usage
, Run Battery [] 10 -- battery time
, Run Volume "default" "Master" [] 10
, Run Date "%d %b %T" "mydate" 10
, Run StdinReader -- text coming from xmonad
,
]-- where to show command information
= "%StdinReader% }{ %memory% | %default:Master% | %dynnetwork% | %battery% | %mydate% |"
, template }
which you should modify to your liking. It uses a single Haskell (record) datastructure called Config
where each field/option like bfColor
or border
is optional: If you don’t set a field, a default field value is used.
[How to create a Haskell datastructure?]
How to check a Xmobar config file for syntax errors?
To check if your config file is correct or contains errors, run
xmobar <path to xmobar.hs>
in a terminal. Normally this is
xmobar ~/.xmobarrc
The options that you surely want to tweak but may be difficult to understand are commands
and template
:
First, you define what information to show within commands
. It’s a list of small apps (called “commands” or System Monitor Plugins) which run with a certain frequency to retrieve and summarize (system) information into a small piece of text. Each command defines a “template identifier” or “alias” like %mydate%
or %memory%
. Some commands define them automatically but for others you have to define them manually. For example, the Memory
command defines the identifier %memory%
automatically, while the Date
command forces you to define an identifier like %mydate%
yourself.
[How to write commands?]
[How to write lists in Haskell?]
Second, you define where to show the information of a command along the Xmobar statusbar with the template
string. This is a string like
"%StdinReader% }{ %memory% | %default:Master% | %dynnetwork% | %battery% | %mydate% |"
which is printed literally into the statusbar after the “template identifiers” (like %mydate%
) have been replaced by the piece of text from the corresponding command in commands
. For example, the XMonad status text from the StdinReader
command, which corresponds to %StdinReader%
, will be printed on the left of the statusbar while the text from the Date
command, which corresponds to %mydate%
, will be printed on the far right.
Note that you can display a piece of text with color by wrapping it with “font color” HTML tags like
<fc=#FF0000>red text</fc> other text text
where the color is given in RGB hex notation.
Also note that the }{
symbol in template
will separate everything on its left as far away as possible from everything on its right. If you like, you can configure/change this symbol (and the %
symbol within the “template identifiers”) with:
Config
-- ...
{ = "%" -- symbol to recognize template identfiers/aliases
, sepChar = "}{" -- symbol to separate between left-center-right alignment
, alignSep -- ...
}
How to write commands
Every command roughly follow this pattern:
Run <command name> [<options>] <refreshrate>
- A command is named after its use, e.g.
Wireless
orVolume
. - Every command has an “id”, “template identifier” or “alias” that is used in the
template
string to define where on in the bar the command’s output should be shown. - Every command has a list of options. If you leave the list empty, some default options are used. Possibly the most important option is
"-t"
(for “template”) to further tweak what and how information is actually shown. Take a look at the documentation of a command to find out what options are available.
[How to write lists in Haskell?] - Every command has a refreshrate, which defines how frequently the command’s app is run. The unit for the refreshrate is a 10th of a second so that the default recommended refreshrate value of 10 updates your command every 1 second (divide the refreshrate value by 10 to get the number of seconds).
Show date and time
The abstract syntax for that is:
Run Date "<date formating>" "<template identifier>" <refreshrate>
For example, add the following line to your commands
list:
Run Date "%d %b %T" "mydate" 10
Item | Note |
---|---|
"%d %b %T
|
Show day of month (%d ), abbreviated month (%b ) and hour-minutes-seconds (%T ). You can heavily customize what to show and how..
|
"mydate"
|
The identifier to be used in template . Choose any name you like that is not yet used.
|
10
|
The date and time status is checked and updated every 1 second. |
To see the command’s output like
11 Oct 14:20:34
in Xmobar, add its identifier to template
as follows:
= ".... %mydate% .... " template
Show wifi connection information
The abstract syntax for that is:
Run Wireless "<wifi device name>" [<options>] <refreshrate>
For example, add the following line to your commands
list:
Run Wireless "wlp3s0" ["-t", "Wifi: [<qualitybar>] <essid>"] 10
You have to use your own wifi device name instead of "wlp3s0"
. Run iwconfig
in a terminal to find your wifi device name. The output should look like this:
lo no wireless extensions.
wlp3s0 IEEE 802.11 ESSID:"TP-LINK"... <-- contains your wifi device name
enp2s0 no wireless extensions.
Item | Note |
---|---|
"-t", "..."
|
How to output information. See options. |
<qualitybar>
|
To be replaced by ####:::: to represent the strength of your wireless connection.
|
<essid>
|
To be replaced by the name of your wifi network, e.g. TP-LINK .
|
10
|
The wireless connection status is checked and updated every 1 second. |
To see the command’s output like
Wifi: [####::::::] TP-LINK
in Xmobar, add its identifier to template
as follows:
= ".... %wlp3s0wi% .... " template
template
identifier like %wlp3s0wi%
, which is “wi” after your wifi device name (%wireless%
doesn’t work). So, theoretically you can run multiple wireless commands and show connection settings of multiple wireless devices.Check out the Wireless docs.
Show audio volume
The abstract syntax for that is:
Run Volume "<soundcard" "<channel>" [<options>] <refreshrate>
For example, add the following line to your commands
list:
Run Volume "default" "Master" ["-t", "Vol: [<volumebar>] <status>"] 10
Item | Note |
---|---|
"default"
|
The default soundcard to be used. Run alsamixer in your terminal to see a list of available soundcards.
|
"Master"
|
The channel (a “device” in Alsa terminology) whose volume you want to output. Run alsamixer in your terminal to see other channels. You may have to press F6 to try out other soundcards until you see Master .However, Master affects the volumen of all other channels and is therefore the most useful.
|
"-t", "..."
|
How to output information. See options. |
<volumebar>
|
To be replaced by ####:::: to represent your volume percentage.
|
<status>
|
To be replaced by [on] or [off] depending on whether your sound is active or muted.
|
10
|
The volume status is checked and updated every 1 second. |
To see the output like
Vol: [####::::::] [on]
of this command in Xmobar, add its identifier to template
as follows:
= ".... %default:Master% .... " template
If you don’t see any volume output, you can use this workaround.
- Copy this script into a
get-volume.sh
file in your/home/user/.xmonad/
folder. - Add the following line to your
commands
list:
Run Com ".xmonad/get-volume.sh" [] "myvolume" 10
Add its identifier to template
as follows:
= ".... %myvolume% .... " template
Note: The volume command automatically creates the template
identifier %soundcard:channel%
whoose values you may have to look up using alsamixer
(%volume%
doesn’t work). So, theoretically you can run multiple volume commands for and show volumes of multiple channels from possible different soundcards.
Check out the Volume docs.
Show the screen brightness
The abstract syntax for that is:
Run Brightness [<options>] <refreshrate>
For example, add the following line to your commands
list:
Run Brightness ["-t", "Brightness: [<bar>]"] 10
Item | Note |
---|---|
"-t", "..."
|
How to output information. See options.. If you can’t see any brightness status, you may have to set the --D option as in the workaround farther below.
|
<bar>
|
To be replaced by ####:::: to represent your brightness percentage.
|
10
|
The brightness status is checked and updated every 1 second. |
To see the output like
Brightness: [####::::::]
of this command in Xmobar, add its identifier to template
as follows:
= ".... %bright% .... " template
If you don’t see any brightness output, you should try this workaround.
To get the brightness value, the Brightness
command looks into the
/sys/class/backlight/
folder. There it expects a folder named acpi_video0
. This folder usually contains files named actual_brightness
and max_brightness
, which contain the current and maximal brightness values of your screen. Depending on your PC or Notebook, this acpi_video0
folder may be called differently, e.g., intel_backlight
or amdgpu_bl0
. So that you have to modify the brightness command to take that into account:
If you have an Intel CPU+GPU, try
Run Brightness ["-t", "Screen: [<bar>]", "--", "-D", "intel_backlight"] 10
With the "-D"
option, you change the name of the folder it expects. It has to come after the "-t"
option and needs to be separated with "--"
, because it’s a “monitor-specific” option, which means that it’s an option that only exists for this Brightness
command (in contrast to the "-t"
option, which exists for all commands).
If you have an AMD Ryzen Mobile CPU+GPU, try
Run Brightness ["-t", "Screen: [<bar>]", "--", "-D", "amdgpu_bl0"] 10
If you don’t know your CPU or you folder may be called differently, run
cd /sys/class/backlight/ && ls
in your terminal app, to find out how the expected folder is named.
Note: The brightness command automatically creates the template
identifier %bright%
(%brightness%
doesn’t work).
Check out the Brightness docs.
Run your own terminal apps/scripts
The abstract syntax for that is:
Run Com "<terminal app/script>" [<app arguments>] <template identifier> <refreshrate>
For example, add the following line to your commands
list:
Run Com "whoami" [] "myuser" 0
to get the currently logged-in user or
Run Com "uname" ["-r"] "mykernel" 0
to get the current Linux kernel version.
Item | Note |
---|---|
"whoami" , uname
|
The terminal app to run. You can run anything that you can run in your terminal, e.g. scripts. |
[] , ["-r"]
|
App arguments. This will run whoami and uname -r in a terminal
|
"myuser" , "mykernel"
|
The identifier to be used in template . Choose any name you like that is not yet used.
|
0
|
The refreshrate. With 0 this command runs only once and is not updated again.
|
To see the output of these commands in Xmobar, add their identifiers to template
as follows:
= ".... %myuser% .... %mykernel% ..." template