A lightweight yet feature-rich status bar for i3bar or swaybar.
It is written completely in C/C++ to make it as lightweight as possible and specifically, to avoid creating new processes every second as in bash script.
It uses libraries like libasound
and glibc function getifaddrs
to retrieve volume information as opposed to using amixer
and ip addr
.
For battery, backlight, load, and meminfo, it reads directly from /sys/class/power_supply
,
/sys/class/backlight
, /proc/loadavg
and /proc/meminfo
.
libasound.so.2
libjson-c.so.5
(also used by sway and swaybar)libsensors.so.5
Install clang
(must have lto support), lld
, make
and pkg-config
, then run
git clone --recurse-submodules https://github.com/NobodyXu/swaystatus
cd swaystatus/src
make -j $(nproc)
You can customize ou build via environment variable:
BUILD_DIR
: affects where the built object will be put. Default is.
.TARGET_DIR
: where the executable will be installed whenmake install
is executed. Default is/usr/local/bin
PYTHON
: whether to include embeded python interpreter support inswaystatus
, can betrue
orfalse
. Default istrue
.DEBUG
: whether to have a debug build or release build.true
for debug build andfalse
for release build. Default isfalse
.EXCEPTION
: whether to enable C++ exception.false
to disable C++ exception.
To install, run sudo make install
, which by default will install a single binary swaystatus
to /usr/local/bin
.
swaystatus: Usage: swaystatus [options] configuration_filename
--help Show help message and exit
--interval=unsigned_msec Specify update interval in milliseconds, must be an unsigner integer.
By default, the interval is set to 1000 ms.
To reload swaystatus
, send SIGUSR1
to swaystatus
process.
{
"order": ["network_interface", "time"],
"_comment": "element order specify the order of which blocks will appear.",
"_comment2": "If a block is not specified in order, it will not appear.",
"name": {
"format": "Hello, {variable_name}",
"short_format": "hello",
"update_interval": 20,
"color": "##RRGGBBA",
"background: "##RRGGBBA",
"border": "##RRGGBBA",
"border_top": 1,
"border_bottom": 1,
"border_left": 1,
"border_right": 1,
"min_width": 1,
"align": "center",
"separator": true,
"separator_block_width": 9,
"markup": "none",
"click_event_handler": {
"type": "python",
"module_name": "hello",
"function_name": "handler"
}
},
"_comment": "Any variable starts with '_' is a comment"
}
All property present for "name" above are optional.
For volume, you can also set property "mix_name" and "card".
The following values are valid name:
-
brightness
-
volume
-
battery
The configuration block of battery support
excluded_model
to exclude certain battery devices from the output ofswaystatus
. -
network_interface
-
load
-
memory_usage
-
time
-
sensors
Any unrecognized parameters will be ignored.
It is used internally to generate the "full_text" that will be passed to swaybar.
Formatting for blocks other than time is done using fmt - Format String Syntax.
Formatting for block time is parsed by strftime
.
In the format string, user is capable of taking advantage of format variables to customize the output.
It is used to generate "short_text", which is used by swaybar
when it decided that the
"full_text" is too long.
TO enable click event handling for a block, add json object "click_event_handler" to the block that block.
The return value of it can be or
ed from the following values:
0
do nothing1
force the module to update2
force the module to reload
Currently, the handler can be written in python or C/C++.
For loading python handler, add "type": "python"
to your "click_event_handler", then specify
the "module_name" and "function_name" of the handler.
swaystatus
will attempt to load the module from the same directory of your configuration file,
your current working dir, any path you specified with environment variable PYTHONPATH
and your
system module paths.
If instead you want to embed the python code into your configuration file, add "code" to your "click_event_handler" and assign your code as value to it.
The python function is expected to have signature (Check here for more information):
(instance: str, click_pos: Tuple[int, int], button: int, event: int, relative_click_pos: Tuple[int, int], blocksize: Tuple[int, int]) -> int
Your function is expected to return 0 and any exception thrown in your function must be handled,
otherwise swaystatus
will print that error and exit.
You C/C++ code has to be compiled with -fPIC -shared
.
For loading python handler, add "type": "dynlib"
to your "click_event_handler", then specify
the "module_name" and "function_name" of the handler.
Just like loading python, swaystatus
will attemp to load the shared library from the same
directory of your configuration file, your current working dir.
It is loaded using dlopen
, so LD_LIBRARY_PATH
, /etc/ld.so.cache
, /lib
and /usr/lib
is
also searched.
You can also specify the path instead of a name directly in the module_name
, which is perfectly
valid.
The C/C++ function is expected to be export
ed in "C"
and have signature:
#include <stdint.h>
struct Pos {
uint64_t x;
uint64_t y;
};
typedef struct Pos ClickPos;
typedef struct Pos BlockSize;
int f(
const char *instance,
const ClickPos *pos,
uint64_t button,
uint64_t event,
const ClickPos *relative_pos,
const BlockSize *size
)
Your function is expected to return 0.
If you want to disable a certain feature, say brightness, then add the following to your configuration:
{
"brightness": false,
}
Or if you are using element "order" for specifing block order, then you can simply remove the name from "order".
Note that {"brightness": false}
overrides "order":
If block specified in "order" is disabled by setting it to false
, then the block
will not appear.
Using this block, you can import a python/c module and display whatever you want in this block.
You need to provide update_callback
and do_print_callback
, which need to have the
same fields as click event handler type
, module_name
, function_name
,
(optional code
for python).
Check example-config.json
for example configuration of this
block.
If specified, then the block will update at update_interval * main_loop_interval ms
,
where main_loop_interval
is the value passed by cmdline arg --interval=
or 1000 ms
by default.
The sensors on computer are so many that they cannot be fitted into one line, so swaystatus
instead, print one sensor each time and once update_interval
is reached, next sensor is shown
at the swaybar
.
When all sensors are shown, swaystatus
will then update the sensors reading from the computer.
-
has_battery
: check whether battery device exists -
per_battery_fmt_str
, which is used to print every battery on this system.It contains the following variables:
name
present
technology
model_name
manufacturer
serial_number
status
cycle_count
voltage_min_design
voltage_now
charge_full_design
charge_full
charge_now
capacity
capacity_level
is_charging
(Check section "Conditional Variable" for usage)is_discharging
is_not_charging
is_full
MemTotal
MemFree
MemAvailable
Buffers
Cached
SwapCached
Active
Inactive
Mlocked
SwapTotal
SwapFree
Dirty
Writeback
AnonPages
Mapped
Shmem
The unit (supports 'BKMGTPEZY') of the variables printed can be specified.
For example, '{MemTotal:K}' will print MemTotal in KiloBytes.
volume
loadavg_1m
loadavg_5m
loadavg_15m
running_kthreads_cnt
total_kthreads_cnt
last_created_process_pid
NOTE that these variables are evaluated per backlight_device.
backlight_device
brightness
max_brightness
has_multiple_backlight_devices
(this is a Conditional Variable)
-
is_connected
-
is_not_connected
-
per_interface_fmt_str
: The specification for this variable will be formatted once for each interface.It contains subvariables that can be used inside:
HAS_UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
has_broadcast_support
is_pointopoint
has_no_arp_support
is_in_promisc_mode
is_in_notrailers_mode
is_master
is_slave
has_multicast_support
has_portsel_support
is_automedia_active
is_dhcp
rx_packets
tx_packets
rx_bytes
(Supports unit specification, checks Memry Usage Variables for more info)tx_bytes
(Supports unit specification, checks Memry Usage Variables for more info)rx_errors
tx_errors
rx_dropped
tx_dropped
multicast
collisions
rx_length_errors
rx_over_errors
rx_crc_errors
rx_frame_errors
rx_fifo_errors
rx_missed_errors
tx_aborted_errors
tx_carrier_errors
tx_fifo_errors
tx_heartbeat_errors
tx_window_errors
rx_compressed
tx_compressed
ipv4_addrs
ipv6_addrs
Limit of number of ip address can be done via
{ipv4_addrs:1}
and{ipv6_addrs:1}
Optionally if
HAS_UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
, the following variables are also defined:is_lower_up
is_dormant
is_echo_device
To limit number of ip addresses in output, please use {ipv4_config:1}
.
prefix
: the name of the devicepath
: the path to the device in/sys
addr
: the internal address of the device inlibsensors
bus_type
: the type of devicebus_nr
: unclearreading_number
: the internal index for the specific sensor readingreading_temp
: the temperature reading from the sensor
Conditional variables are used to conditionally evaulate part of the format string.
For example, setting "format" in "battery" to "{is_charging:Charging}" will print "Charging" only when the battery is charging.
All variables start with "is" and "has" are conditional variables.
In additional to printing strings conditionally, conditional variables can also be used to print other variables conditionally.
For example, "{is_charging:{level}%}" will print "98%" when charging, where "98" is the actual level of battery.
Check example-config.json
for the example configuration.
bar {
status_command swaystatus
}