-
Notifications
You must be signed in to change notification settings - Fork 23
Bar Modules
The content of the bar is controlled by individual modules that handles drawing of content and button clicks in isolation.
What this means is that the modules do not need to be concerned about other modules present on the bar.
This page outlines how bar modules work in general.
Here is a list of the modules that are available by default:
Module | Description |
---|---|
workspaces | Shows workspace icons on the bar |
systray | Positions the systray on the bar |
ltsymbol | Indicates the current layout used using symbols |
flexwintitle | Draws window titles on the bar |
status | Shows user defined content on the bar |
wintitle_hidden | Shows window titles for clients that are hidden |
wintitle_floating | Shows window titles for clients that are floating |
powerline | Adds powerline separators between bar modules |
Refer to the individual pages above for more information about configuration options and what features they provide.
Prior to the bar being drawn the scheme for the bar is derived from the layout used by the active workspace.
This scheme is then used for the bar border (if enabled) as well as window title separators.
The bar rules are checked in the order they are defined in the barrules
array in
config.h.
static const BarRule barrules[] = {
/* monitor bar scheme lpad rpad value alignment sizefunc drawfunc clickfunc hoverfunc name */
{ -1, 0, 0, 0, 5, 0, BAR_ALIGN_LEFT, size_workspaces, draw_workspaces, click_workspaces, hover_workspaces, "workspaces" },
{ 'A', 0, 0, 5, 5, 0, BAR_ALIGN_RIGHT, size_systray, draw_systray, click_systray, NULL, "systray" },
...
};
If the bar index as well as the monitor matches that of the current bar then the rule applies.
Refer to the Bar Rules page for further setup details on this.
A bar argument will be passed to the functions (sizefunc
, drawfunc
, clickfunc
, hoverfunc
)
that belong to the bar module and this argument will hold several values indicating where the
module is to be drawn and how much space is available.
Here is the struct for said argument:
typedef struct {
int x;
int y;
int h;
int w;
int lpad;
int rpad;
int value;
int scheme;
} BarArg;
The x
, y
, h
and w
values determine the size and position of the bar module.
The left and right padding (lpad
and rpad
) are taken as-is from the bar rule. These determine
the amount of space to between modules on either side.
The arbitrary value
is taken as-is from the bar rule and provides module specific hints to the
bar module. This is primarily used for the status module for status updates and
status click handling.
If the rule specifies a colour scheme
then that scheme is passed to the bar module as part of the
argument. This scheme will be used for the bar module unless it manages colours on its own.
The bar modules engine keeps track of the space available on the bar to draw modules.
It makes a call to the size function which should return the space required to draw the module.
Most bar modules will return the minimum space required to draw the module, but functions that draw window titles tend to claim all the available space hence such modules are defined last in the rules array.
The engine will then check the alignment
part of the bar rule which determines where on the bar
the module is placed.
Refer to the alignment section of the bar rules page for a description of the various options.
If a module is to be centered within the available space then the bar is split into two:
- the remaining space on the left of the center module and
- the remaining space on the right of the center module
Note that this will occur only once. If a bar module is centered again on the remaining space on the right hand side of the center module then the space on the right of the module will be lost indefinitely.
If you find yourself in a situation like this then consider splitting the bar into multiple bars instead.
When the final position of the bar module has been determined the bar argument is passed in a call to the draw function of the module. This should return a positive value if something was drawn and 0 otherwise.
If nothing was drawn on the bar after going through all the rules then the bar will be hidden automatically.
Likewise if something was drawn and the bar was hidden then it will be shown.
The exact position and size of each bar module is recorded for the bar as these are later used when
handling mouse clicks on the bar which are handled separately in the barpress
function.
This will loop through the bar rules that apply to the bar and use the stored positions of each bar module to determine which of the modules the clicked.
If the module has a click function then this will be called and the function can perform its own calculations as and if needed, e.g. to work out which of the window titles were clicked on.
The click function is expected to return a value from the click enum (e.g. ClkLtSymbol
) allowing
for button bindings to evaluate bespoke user defined actions.
Below there is more information about the different module functions should you want to implement your own. You may also want to refer to existing implementations if anything is unclear.
Signature:
static int size_<module>(Bar *bar, BarArg *a);
The function is expected to return an integer value representing the amount of pixels needed to draw the module.
The bar argument a->w
will represent the maximum space available for the module. This value is
the available space less the left and right padding for the bar rule which means that the bar module
does not need to take padding into account when giving its size requirements.
Signature:
static int draw_<module>(Bar *bar, BarArg *a);
The function is expected to draw the module and to return an integer value representing the amount of pixels that were drawn (or at a minimum a positive value to indicate that something was drawn).
The bar arguments of a->x
, a->y
, a->w
and a->h
determine the position where the module is
to be drawn and the size. If the module draws content beyond this size then it will bleed into
other modules.
The module does not have to take a->lpad
and a->rpad
into account because these are have
already been accounted for in the size and position values above. The padding values are still there
for reference should the module need this information.
Unless the module manages colours on its own then it is expected that it uses the colour scheme
as indicated by a->scheme
by default.
The module has no obligation to take the a->value
parameter into account, but it can use this to
elicit varying behaviour across module instances. The value is arbitrary and its interpretation is
entirely module specific.
Signature:
static int click_<module>(Bar *bar, Arg *arg, BarArg *a);
This function is optional and can be NULL
in the bar rules configuration.
The click function does not know which button was clicked and as such can not differentiate between a left click and a right click for example. This is intentional and by design.
The reason for this is that the intention of the click function is merely to indicate what was clicked and leave the actionable bit to button bindings.
As such the function is expected to return one of the click enum values in dusk.c (search for
ClkLtSymbol
). A new click enum value can be added if needed, e.g. ClkNameOfModule
.
The arg
reference will be passed to the function called if there is a button binding that matches
both the mouse click and the click type returned by the click function. This is true as long as the
button binding itself does not explicitly pass in an argument.
This means that the click function can set the arg
value to something that the function for the
button binding will take into account.
For example the wintitle modules will set arg->v
to be a reference to the client of which the
window title was clicked. Another example would be the workspace module setting arg->v
to be a
reference to the workspace that was clicked.
Also refer to the Button Bindings page.
Signature:
static int hover_<module>(Bar *bar, BarArg *a, XMotionEvent *ev);
This function is optional and can be NULL
in the bar rules configuration.
The a->x
and a->y
coordinates refer to the mouse position relative to the bar module.
The XMotionEvent ev->x
and ev->y
coordinates are relative to the bar window. To get
absolute mouse pointer coordinates take bar->bx
and bar->by
into account as well.
This function will be triggered if a user hovers the mouse over the given module.
For an example implementation refer to the WorkspacePreview functionality.
Back to Bar.
Concepts | Configuration | Features | Flags | Functionality | Functions