===================================================================
i3csstatus
==========
Alternative generator of i3 status bar written in c#
Sample configuration file
-------------------------
(c) 2022 Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.
===================================================================
User documentation
See output of i3csstatus -h
and documented configuration file at
sample.conf
.
Developer documentation
Overview
Main class of the program is RootStatusBar
. This class will parse the configuration and then it start main loop.
Main loop is responsible for constructing status bar and printing it. Output formats are defined in RootStatusBar
sub classes. Waiting for print the status bar could be interrupted from other threads.
Status bar block
Each state of the status bar is a sequence of blocks.
Blocks correspond almost one to one to i3bar blocks.
See i3bar protocol documentation:
https://i3wm.org/docs/i3bar-protocol.html
In addition to i3bar block there is OnClick
member.
You can store there a function which will be called when somebody
clicks on the buttton. Function will receive ClickEvent
as its only argument.
Note that this function can be called from a different thread.
Please write it thread safe.
Modules
A module is responsible for preparing part of the status bar. It can handle more than one block (or zero blocks if the module should be hidden).
It should be easy to add your own modules. Before that please check that any of the next possibilities is not better for your use case:
- Write some extra program and then use exec module with some parser For some of languages (As python or bash) you can write program directly in config.
- Write only parser, not whole module Good if you want read some file / pipe / HTTP API and then process it. Your parser will be available for all modules using parsers.
A module must implement Module
interface and have [ModuleName(string)]
attribute.
Any other registration is not needed.
You can configure and prepare module via Init
function.
This function receives a part of configuration file and ModuleParent
object (see below).
On Get
method the module should return a list (exactly IEnumerable
) of Blocks to show.
Note that the return value should be immutable!
It is possible to use ModuleParent
to schedule next render of the status bar
(Schedule method). This function is thread safe.
For module cooperation it is possible to use ModuleParent.GetGlobal<T>
.
It will return an instance of T
shared across all modules in status bar.
T
should implement GlobalModuleResource
interface. There are methods
which are called before and after status bar initialization and generation.
For excepted behavior it is important to call GetGlobal
from Init
.
It is possible to create a bar as a part of the module.
See InnerStatusBar
class and usage. It is a viable option to
show some user specified constant blocks.
Parsers
Parser is an object for translating string to a part of the status bar. It is often used as part of modules fetching some text. Normally parsers share part of configuration file with the module.
If module uses is multithreaded, it must call parser from the main thread for each Get
.
Parse could have different output for the same text (for example based on current time).
Each parser must implement Parser
interface.
If the parser is allowed to be used in the configuration file by typing its name
then it must have [ParserName(string)]
attribute.
Parser can be configured via Init
function. In such case, it must return part of bar on each call of Parse
method.
Module wrappers
In the configuration file, user can add one or more module wrappers as options.
By convention these options start with _
.
Module wrapper is able change behavior of the Module as it has access to any
communication between Module and Status Bar (ModuleParent
interface).
Wrappers are created by StatusBar.addStandardModuleWrappers
.
Output formats
Each format is represented as RootStatusBar
subclass.
It must implement format(TextWriter w, List<Block> elements)
method,
which outputs elements
to w
.
Configuration of the output formats is done using command line arguments.
Configuration file must be output independent.
For adding an output format you need to add new Command
in the Program.Main
function.