Skip to content

Status Module

Bakkeby edited this page Apr 14, 2024 · 12 revisions

The Status module displays custom (user defined) information in the bar.

If you are familiar with dwm and how the status is updated there via the X root name using tools like xsetroot, slstatus, dwmblocks, and many many others then you will find that the status here is handled very differently.

Rather than having a single status area that is updated via the X root name you have as many status areas as you want (by default there are 10) and each status is updated independently.

The benefit of this is that:

  • each status area (or block) is updated independently
  • status areas are updated asynchronously
  • there is no need to include special markers indicating which status block is which
  • there is no need for complex calculations to work out which of the statuses the user clicked on
  • updates to one status area does not affect other areas
  • click handling of one area does not affect the updating of other areas
  • you can place each individual status anywhere you want on the bar

Combined this gives a very smooth and stable experience.

Configuration

The status areas that are available are defined by these entries in the barrules array in config.h.

static const BarRule barrules[] = {
  /* monitor  bar scheme lpad rpad value  alignment        sizefunc     drawfunc     clickfunc     hoverfunc, name */
  ...
  {  0,       0,  0,     10,  0,   0,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, NULL,      "status0" },
  {  0,       0,  0,     10,  0,   1,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, NULL,      "status1" },
  {  0,       0,  0,     10,  0,   2,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, NULL,      "status2" },
  {  0,       0,  0,     10,  0,   3,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, NULL,      "status3" },
  {  0,       0,  0,     10,  0,   4,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, NULL,      "status4" },
  {  0,       0,  0,     10,  0,   5,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, NULL,      "status5" },
  {  0,       0,  0,     10,  0,   6,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, NULL,      "status6" },
  {  0,       0,  0,     10,  0,   7,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, NULL,      "status7" },
  {  0,       0,  0,     10,  0,   8,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, NULL,      "status8" },
  ...
  { 'A',      1,  0,     10,  10,  9,     BAR_ALIGN_RIGHT, size_status, draw_status, click_status, "status9" },

Note the value option that has a different number for each of the statuses. This must be a unique number and it determines the ID of each status and is used when 1) updating the status and 2) when handling status button clicks.

If you are adding more statuses than the default 10 above then you also have to update the NUM_STATUSES macro in dusk.c and also increase the BARRULES macro.

Refer to the Bar Rules page for general information on configuring rules.

Clicks

Clicks on the status module will result in a ClkStatusText click type that can be filtered on in the button bindings.

Example bindings as per the default configuration:

{ ClkStatusText, 0, Button1, statusclick, {.i = 1 } }, // sends mouse button presses to statusclick script when clicking on status modules
{ ClkStatusText, 0, Button2, statusclick, {.i = 2 } },
{ ClkStatusText, 0, Button3, statusclick, {.i = 3 } },
...

Status button clicks are handles by a single external script that can delegate to other scripts based on environment variables that indicate which status was clicked and which mouse button was clicked.

Refer to the statusclick function write-up that goes into this in depth.

Also see the Button Bindings page.

Updating the status

The status is updated via external commands that refer to the status to update via the setstatus function, e.g.

$ duskc run_command setstatus 0 "hello world"  # sets status 0 to "hello world"
$ duskc run_command setstatus 9 "$(date +%T)"  # sets status 9 to the current time

Here is an example shell script that continuously updates the status by evaluating other scripts:

status_updater.sh
#!/bin/bash

for pid in $(pidof -x "status_updater.sh"); do
    if [ $pid != $$ ]; then
        echo "$(date +"%F %T"): status_updater.sh is already running with PID $pid, killing"
        kill $pid
    fi
done

# Add an artificial sleep to wait for the IPC handler to be ready to process requests
sleep 0.5

SETSTATUS="duskc --ignore-reply run_command setstatus"

$SETSTATUS 7 "$(~/bin/statusbar/statusbutton)" &

secs=0
while true; do

    $SETSTATUS 0 "$(~/bin/statusbar/clock)" &
    $SETSTATUS 2 "$(~/bin/statusbar/mem)" &
    $SETSTATUS 3 "$(~/bin/statusbar/cpu)" &

    if [ $((secs % 60)) = 0 ]; then
        $SETSTATUS 5 "$(~/bin/statusbar/mouse_battery)" &
        $SETSTATUS 1 "$(~/bin/statusbar/volume)" &
    fi

    if [ $((secs % 3600)) = 0 ]; then
        $SETSTATUS 4 "$(~/bin/statusbar/sysupdates_paru)" &
    fi

    ((secs+=1))
    sleep 1
done

Refer to the dusk.resources repository for more example scripts.

Custom colours in the status

All statuses have support for the status2d markup which allows for control of text foreground and background colours as well as simple drawing mechanisms.

Additionally custom colour schemes can be created and set as the scheme value for the workspace modules in the barrules array (defaults to SchemeNorm).

Can I still use dwmblocks?

No you can't. dwmblocks main purpose is to update the whole status in one go via the X root name and it achieves this by caching data for the individual blocks internally.

There is nothing that reads from the X root name here hence dwmblocks and similar tools will have no effect.

Alternatively you could have a look at slstatus-for-dusk which is a variant that adds support for updating the individual statuses of dusk on a per block basis.


Back to Bar > Bar Modules.

Clone this wiki locally