SFWBAR(1) | General Commands Manual | SFWBAR(1) |
SFWBar - S* Floating Window taskBar
sfwbar [options]
SFWBar is a taskbar for wayland compositors. Originally written for Sway, it should work with any compositor supporting layer-shell protocol. SFWBar assists in handling of floating windows on a wayland desktop. It provides a taskbar, a pager, a task switcher, a system tray, a floating window placement engine, a simple widget set for display data extracted from various system files. SFWBar can work with any wayland compositor supporting layer shell protocol. Taskbar and switcher require either sway or wlr-foreign-toplevel protocol support. Placer and pager require sway.
SFWBar executable can be invoked with the following options:
SFWBar reads configuration from a config file (sfwbar.config by default). The program checks users XDG config directory (usually ~/.config/sfwbar/) for this file, followed by system xdg data directories. Additionally, user can specify a location and a name of the config file using -f command line option.
Appearance of the program can be specified using CSS properties, these are sourced either from the css section of the main configuration file or from a file with a .css extension with the same base name as the config file located in the same directory as the config file. The name of the css file can be also specified using -c option.
The config file consists of the following top level sections:
Placer section enables intelligent placement of new floating windows. If enabled the program will first attempt to place the window in a location, where it won't overlap with other windows. If such location doesn't exist, the window will be placed in a cascading pattern from top-left to bottom-right. The Placer declaration accepts parameters "xstep" and "ystep" that specify the steps in the window cascade. These are specified in percentage of the desktop dimensions. The cascade placement will start at a location specified by "xorigin" "yorigin" parameters. I.e.:
placer { xorigin = 5 yorigin = 5 xstep = 5 ystep = 5 children = false }
"children" parameter specifies if new windows opened by a program with other windows already opened should be placed. These are usually dialog windows and SFWBar won't place them by default. If the placer section is not present in the file, SFWBar will let the compositor determine the locations for new windows.
Task switcher implements a keyboard shortcut to cycle focus across windows (i.e. Alt-Tab). The action is triggered upon receiving a change in a bar hidden_state property or signal SIGUSR1. This can be configured in Sway, via one of the following bindings:
bindsym Alt-Tab bar hidden_state toggle or bindsym Alt-Tab exec killall -SIGUSR1 sfwbar
(for non-sway compositors, use SIGUSR1 trigger)
NixOS + Hyprland (probably other non-sway compositors) use:
bind = ALT, Tab, exec, killall -SIGUSR1 .sfwbar-wrapped
Task switcher is configured in the "switcher" section of the configuration file. The following parameters are accepted:
Defines the layout of the taskbar. The layout holds a set of widgets. Widgets can be nested in case of a grid widget, which acts as a container.
The following widget types are supported:
Each widget is placed within the parent grid. By default, widgets are placed next to the previous widget along the "direction" of the grid (left to right by default). You can specify widget's positions within a grid by using a property "loc(x,y[,w,h])" with the first two parameters specifying the location of the widget within the parent grid and the last two parameters specifying the widget dimensions in grid cells:
layout "id" { label { style = "mystyle" value = SwapUsed / SwapTotal + "%" loc(2,1,1,1) } }
The optional "id" string of the layout, specifies the bar to populate and can control positioning of the grid within a bar using syntax of "name:position", valid positions are start, center and end. This allows placement of some widgets in the center of the bar. In case of a single bar, the name of a bar can be omitted, i.e. ":center". External widgets can be included in layout using the following syntax:
layout { include("MyWidget.widget") }
The above will include all scanner variables data and widget sub-layout from file MyWidget.widget
Grid widgets can contain other widgets, these are declared within the grid definition i.e.
grid { css = "* { border: none }" label "id" { ... } }
Widgets can optionally have unique id's assigned to them in order to allow manipulating them in the future. Widgets can have the following properties:
Taskbar widget may contain the following options
Pager widget may contain the following options
tray widget may contain the following options
popup window may contain the following options
Popup windows can be defined the same way as layouts. The only difference is that popup's are not part of a bar and will not be displayed by default. Instead they are displayed when a PopUp action is invoked on a widget. i.e.:
PopUp "MyPopup" { label { value = "test" } } Layout { label { value = "click me" action = PopUp "MyPopup" } }
The PopUp action toggles visibility of the popup window. I.e. the first time it's invoked, the window will pop up and on the second invocation it will pop down. As a result it should be safe to bind the PopUp to multiple widgets.
User defined menus can be attached to any widget (see action widget property). Menus are defined using a Menu section in the config file. The example syntax is as following:
menuclear("menu_name") menu ("menu_name") { item("item1", Exec "command") separator submenu("sub","mysubmenu") { item("item2", SwayCmd "focus next") } }
Command MenuClear deletes any existing items from a menu. Each menu has a name used to link the menu to the widget action and a list of menu items. If a menu with the same name is defined more than once, the items from subsequence declarations will be appended to the original menu. If you want to re-define the menu, use MenuClear action to clear the original menu.
The following menu items are supported:
Triggers are emitted in response to various events, such as compositor state changes, real time signals or notifications from modules. Some triggers can be defined as part of the configuration (i.e. SocketClient or ExecClient scanner sources), others are built in, or defined in modules.
Built-in triggers are:
SIGRTMIN+X | RT signal SIGRTMIN+X has been received (X is a number) |
sway | Data has been received on SwayClient scanner source |
mpd | Data has been received on MpdClient scanner source |
<output>-connected | an output has been connected (i.e. eDP-1-connected) |
<output>-disconnected | an output has been disconnected |
Actions can be attached to click and scroll events for any widget or to items within a menu. Actions can be conditional on a state of a window or a widget they refer to and some actions may require a parameter. Conditions are specified in square brackets prior to the action i.e. [Minimized] and can be inverted using ! or joined using | i.e. [!Minimized | Focused]. All conditions on the list must be satisfied. Supported conditions are: Minimized, Maximized, Focused, FullScreen and UserState
Actions can be activated upon receipt of a trigger from one of the client type sources, using TriggerAction top-level keyword. I.e.
TriggerAction "mytrigger", Exec "MyCommand"
Parameters are specified as strings immediately following the relevant action. I.e. Menu "WindowOps". Some actions apply to a window, if the action is attached to taskbar button, the action will be applied to a window referenced by the button, otherwise, it will apply to the currently focused window. The following action types are supported:
Functions are sequences of actions. They are used when multiple actions need to be execute on a single triggeer. A good example of this functionality is dynamically constructed menus generated by an external script:
function("fancy_menu") { MenuClear "dynamic_menu" PipeRead "$HOME/bin/buildmenu.sh" Menu "dynamic_menu" }
The above example clears a menu, executes a script that builds a menu again and opens the resulting menu.
Function "SfwBarInit" executed on startup. You can use this functions to set initial parameters for the bar, such as default monitor and layer.
SFWBar widgets display data obtained from various sources. These can be files or output of commands.
Each source section contains one or more variables that SFWBar will poll periodically and populate with the data parsed from the source. The sources and variables linked to them as configured in the section scanner
scanner { file("/proc/swaps",NoGlob) { SwapTotal = RegEx("[\t ]([0-9]+)") SwapUsed = RegEx("[\t ][0-9]+[\t ]([0-9]+)") } exec("getweather.sh") { $WeatherTemp = Json(".forecast.today.degrees") } }
Each declaration within the scanner section specifies a source. This can be one of the following:
The file source also accepts further optional arguments specifying how scanner should handle the source, these can be:
Variables are extracted from sources using parsers, currently the following parsers are supported:
Optional aggregators specify how multiple occurrences of numeric data are treated. The following aggregators are supported:
For string variables, Sum and Product aggregators are treated as Last.
Values in widgets can contain basic arithmetic and string manipulation expressions. These allow transformation of data obtained by the scanner before it is displayed by the widgets.
The numeric operations are:
Operation | Description |
+ | addition |
- | subtraction |
* | multiplication |
/ | division |
% | remainder of an integer division |
> | greater than |
>= | greater than or equal |
< | less than |
>= | less than or equal |
= | equal |
Val | convert a string into a number, the argument is a string or a string expression to convert. |
If | conditional: If(condition,expr1,expr2) |
Cached | get last value from a variable without updating it: Cached(identifier) |
Ident | Check if an identifier exists either as a variable or a function |
The string operations are:
Operation | Description |
+ | concatenate strings i.e. "'String'+$Var". |
Mid | extract substring i.e. Mid($Var,2,5) |
Extract | extract a regex pattern i.e. Extract($Var,'FindThis: (GrabThat)') |
Str | convert a number into a string, the first argument is a number (or a numeric expression), the second argument is decimal precision. If precision is omitted, the number is rounded to the nearest integer. |
Pad | pad a string to be n characters long, the first parameter is a string to pad, the second is the desired number of characters, if the number is negative, the string is padded at the end, if positive, the string is padded at the front. The third optional string parameter specifies the character to pad the string with. |
Upper | Convert a string to upper case |
Lower | Convert a string to lower case |
Lookup | lookup a numeric value within a list of tuplets, the function call is Lookup(Value, Threshold1, String1, ..., DefaultString). The function checks value against a thresholds and returns a String associated with the highest threshold matched by the Value. If the Value is lower than all thresholds, DefaultString is returned. Thresholds in the function call must be in decreasing order. |
Map | Match a string within a list of tuplets, the usage is: Map(Value, Match1,String`,...,DefaultString). THe function will match Value against all Match strings and will return a corresponding String, if none of the Match strings match, the function will return DefaultString. |
In addition the following query functions are supported
Function | Description |
Time | get current time as a string, the first optional argument specifies the format, the second argument specifies a timezone. Return a string |
Disk | get disk utilization data. You need to specify a mount point as a first argument and data field as a second. The supported data fields are "total", "avail", "free", "%avail", "%free" or "%used". Returns a number. |
ActiveWin | get the title of currently focused window. Returns a string. |
GtkEvent | Get the location of an event that triggered the action. This function is only applicable in action command expressions where an action is called as a result of button click. The function returns location of the click within the widget. The value is returned as percentage of the widget width or height. Acceptable arguments are "X","Y" and "Dir". X and Y select an axis for which to return the event location, Dir returns the event location along the widget direction property. |
WidgetID | Obtain an ID of the current widget (i.e. a widget in respect to which the expression is being evaluated. |
Each numeric variable contains four values
By default, the value of the variable is the value of .val. String variables are prefixed with $, i.e. $StringVar The following string operation are supported. For example:
$MyString + Str((MyValue - MyValue.pval)/MyValue.time),2)
User defined expression macros are supported via top-level define keyword. I.e.
define MyExpr = VarA + VarB * VarC + Val($Complex) ... value = Str(MyExpr,2)
The above will expand the expression into:
value = Str(VarA + VarB * VarC + Val($Complex),2)
Macro's don't have types, as they perform substitution before the expression is evaluated.
Intermediate variables can be declared using a toplevel set keyword I.e.
set MyExpr = VarA + VarB * VarC + Val($Complex ... value = Str(MyExpr,2)
In the above example, value of the MyExpr variable will be calculated and the result will be used in computing the value expression. Intermediate variables have type and have all of the fields of a scan variable (i.e. val, pval, time etc). They can be used the same way as scan variables.
If the icon is missing for a specific program in the taskbar or switcher, it is likely due to an missing icon or application not setting app_id correctly. You can check app_id's of running programs by running sfwbar -d -g app_id. if app_id is present, you need to add an icon with the appropriate name to your icon theme. If it's blank, you can try mapping it from the program's title (please note that the title may change during runtime, so matching it can be tricky). Mapping is supported via top-level MapAppId keyword. I.e.
MapAppId app_id, pattern
where app_id is the desired app_id and pattern is a regular expression to match the title against.
If you are using an XWayland app, they usually do not have an app_id set. If an icon is not showing, you can add your icon to the following locations: 1. $HOME/.icons 2. One of the directories listed in $XDG_DATA_DIRS/icons 3. /usr/share/pixmaps 4. Location of the main config file currently in use 5. $XDG_CONFIG_HOME/sfwbar/
If an app_id is not set, and sway is being used, sfwbar will fallback to using the instance in the window-properties.
You can find the app_id that is being used with sfwbar by using the sfwbar -d -g app_id command, which will show a list of running applications if your compositor supports the wlr-foreign-toplevel protocol (i.e. labwc, wayfire, sway): ` 14:49:25.41 app_id: 'jetbrains-clion', title 'sfwbar – pager.c' `
Alternatively your desktop environment might have a command to display a list: - Sway: swaymsg -t get_tree - Hyperland: hyprctl -j clients
When using swaymsg -t get_tree, with CLion this will show the following:
"window_properties": { "class": "jetbrains-clion", "instance": "jetbrains-clion", "title": "sfwbar – trayitem.c", "transient_for": null, "window_type": "normal" }
So we can put an icon called jetbrains-clion.svg (or other formats, see the [Arch wiki](https://wiki.archlinux.org/title/desktop_entries#Icons)) for information about file formats.
SFWBar uses gtk+ widgets and can accept all css properties supported by gtk+. SFWBar widgets correspond to gtk+ widgets as following:
SFWBar widget | gtk+ widget | css class |
label | GtkLabel | label |
image | GtkImage | image |
button | GtkButton | button |
scale | GtkProgressBar | progressbar, trough, progress |
Taskbar, Pager, Tray and Switcher use combinations of these widgets and can be themed using gtk+ nested css convention, i.e. grid#taskbar button { ... } (this example assumes you assigned style = taskbar to your taskbar widget).
In addition to standard gtk+ css properties SFWBar implements several additional properties. These are:
property | description |
-GtkWidget-align | specify text alignment for a label, defined as a fraction. (0 = left aligned, 1 = right aligned, 0.5 = centered) |
-GtkWidget-ellipsize | specify whether a text in a label should be ellipsized if it's too long to fit in allocated space |
-GtkWidget-direction | specify a direction for a widget. For scale, it's a direction towards which scale grows. For a grid, it's a direction in which a new widget is position relative to the last placed widget. For a window it's an edge along which the bar is positioned. Possible values [top|bottom|left|right] |
-GtkWidget-max-width | Limit maximum width of a widget (in pixels) |
-GtkWidget-max-height | Limit maximum height of a widget (in pixels) |
-GtkWidget-hexpand | specify if a widget should expand horizontally to occupy available space. [true|false] |
-GtkWidget-vexpand | as above, for vertical expansion. |
-GtkWidget-halign | Horizontally align widget within any free space allocated to it, values supported are: fill, start, end, center and baseline. The last vertically aligns widgets to align text within. |
-GtkWidget-valign | Vertically align widget. |
-GtkWidget-visible | Control visibility of a widget. If set to false, widget will be hidden. |
-ScaleImage-color | Specify a color to repaint an image with. The image will be painted with this color using image's alpha channel as a mask. The color's own alpha value can be used to tint an image. |
-ScaleImage-symbolic | Render an image as a symbolic icon. If set to true, the image will be re-colored to the gtk theme foreground color, preserving the image alpha channel. This property is ignored if -ScaleImage-color is specified. |
Taskbar and pager buttons are assigned the following styles
style name | description |
sfwbar | toplevel bar window |
layout | top level layout grid |
taskbar_normal | taskbar button for a window |
taskbar_active | taskbar button for currently focused window |
pager_normal | pager button for a workspace |
pager_visible | pager button for a visible workspace |
pager_focused | pager button for a currently focused workspace |
switcher | switcher window and top level grid |
switcher_active | switcher active window representation |
switcher_normal | switcher inactive window representation |
tray | tray menus and menu items |
tray_active | active tray icon |
tray_attention | tray icon requiring user attention |
tray_passive | passive tray icon |
menu_item | menu items (each contains an image and a label) |
For example you can style top level grid using grid#layout { }.
GPLv3+