Skip to content
Snippets Groups Projects
Commit f833549c authored by Jiří Kalvoda's avatar Jiří Kalvoda
Browse files

Add Developer documentation

parent 102294d4
No related branches found
No related tags found
No related merge requests found
......@@ -10,8 +10,6 @@
(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
......@@ -33,3 +31,90 @@ 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.
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.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment