Skip to content

Commit

Permalink
Merge pull request #4 from JJoeDev/dev
Browse files Browse the repository at this point in the history
README, Custom file parser, Launch args, Examples, Workflow
  • Loading branch information
JJoeDev authored Aug 10, 2024
2 parents d119523 + 17ba917 commit 09e2cbb
Show file tree
Hide file tree
Showing 12 changed files with 351 additions and 78 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: C/C++ CI

on:
push:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
sudo apt update
sudo apt install -y cmake build-essential libxcb-dev libsol2-dev
- name: Run cmake
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
- name: Build
run: make -j
95 changes: 86 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,27 @@ MiBar is a simple Linux X11 status bar built with the C++ programming language.

MiBar is supposed to be customizable and easy to configure. This is the reason for using the Lua language for plugins as it makes it easy to develop for MiBar.

## Contents

* [Getting Started](#getting-started)

* * [Dependencies](#dependencies)

* * [Installing](#installing)

* * [Running MiBar](#running-mibar)

* [Configuration](#configuring)

* [Images](#images)

* [Plugin Development](#plugin-development)

* [License](#license)

## Getting Started

Currently the only way to use MiBar is by building from source.
MiBar has migrated from a C header file for configuration, to a .bar configuration file. This means you can now build MiBar once and change settings without having to build again.

### Dependencies

Expand All @@ -29,9 +47,7 @@ Currently the only way to use MiBar is by building from source.

### Installing

MiBar can only be run by building from source until a future release.

But until then this is how you can use MiBar
Building from source is as quick as running the following commands once.

```
$ git clone https://github.com/JJoeDev/MiBar.git
Expand All @@ -40,18 +56,79 @@ $ cmake -DCMAKE_BUILD_TYPE=Release .
$ make
```

### Executing program
### Running MiBar

Once MiBar has bin built from source the executable can be found in the bin directory
MiBar can be run without any arguments, this will make it look for its own configuration file `config.bar` in `~/.config/MiBar` if this file does not exist the app cannot launch. There is an example file in the example repo
```
$ ./bin/MiBar
```

## Configuring
MiBar can also be run with some arguments

```bash
./bin/MiBar -h
./bin/MiBar --help
```

using the -h or --help flag MiBar will just display a very short help list

```bash
./bin/MiBar -c filename
./bin/MiBar --config filename
```

Currently the bar uses a C header file for its configuration, when changing this file you will need to recompile the application again.
using the -c or --config flag you can specify a custom configuration file name. MiBar will still look in `~/.config/MiBar` for this file.

The configuration file can be found in [src/general.config.h](./src/general.config.h)
Note that adding a file extention with this flag does not help. If the .txt extension is added MiBar will look for `filename.txt.bar`

## Configuration

MiBar uses its own configuration format that is designed to be really simple to use. For a demonstration, here is the example config file included in this repo

```bar
* Comment. Comments can only be placed before the ':' as to not interfer with some settings
* Colors. Colors use the hexadecimal format and are prefixed with 0x
* Hexadecimal values go from 0 to F (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F)
* The colors are formatted as 0xRR GG BB where RR, GG, and BB reprecent red green and blue
* MiBar has support for 5 colors, all assigned a value as below
* Currently not all values are in use, but they will be in the future
Background: 0x111111
Foreground: 0x999999
Color1: 0x777777
Color2: 0x555555
Color3: 0x333333
* TargetMonitor is the monitor MiBar should locate and move to
TargetMonitor: HDMI-0
* Currently MiBar only supports fronts built in to X.
* These fonts can be listed with a utility like 'xlsfonts' in a terminal
Font: lucidasans-10
FontFallback: fixed
* The transform values are additive to the information recieved from TargetMonitor
* This means if the monitor is 1920 wide and BarWidth is 0 then the bar is also 1920 wide
* To make the bar slimmer BarWidth needs to be a negative number
* BarHeight is not aditive and is 0 high by default
* BarX and BarY is the monitor coordinates for where to draw the bar at
BarWidth: 0
BarHeight: 32
BarX: 0
BarY: 0
* The following settings are to render a small line under every rendered component on the bar
* UseUnderline will be false unless its value is directly "true"
UseUnderlines: true
UnderlineHeight: 3
UnderlineOffsetX: 0
UnderlineOffsetY: 0
```

## Images

Expand Down
42 changes: 42 additions & 0 deletions examples/config.bar
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
* Comment. Comments can only be placed before the ':' as to not interfer with some settings

* Colors. Colors use the hexadecimal format and are prefixed with 0x
* Hexadecimal values go from 0 to F (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F)
* The colors are formatted as 0xRR GG BB where RR, GG, and BB reprecent red green and blue
* MiBar has support for 5 colors, all assigned a value as below
* Currently not all values are in use, but they will be in the future

Background: 0x111111
Foreground: 0x999999
Color1: 0x777777
Color2: 0x555555
Color3: 0x333333

* TargetMonitor is the monitor MiBar should locate and move to

TargetMonitor: HDMI-0

* Currently MiBar only supports fronts built in to X.
* These fonts can be listed with a utility like 'xlsfonts' in a terminal

Font: lucidasans-10
FontFallback: fixed

* The transform values are additive to the information recieved from TargetMonitor
* This means if the monitor is 1920 wide and BarWidth is 0 then the bar is also 1920 wide
* To make the bar slimmer BarWidth needs to be a negative number
* BarHeight is not aditive and is 0 high by default
* BarX and BarY is the monitor coordinates for where to draw the bar at

BarWidth: 0
BarHeight: 32
BarX: 0
BarY: 0

* The following settings are to render a small line under every rendered component on the bar
* UseUnderline will be false unless its value is directly "true"

UseUnderlines: true
UnderlineHeight: 3
UnderlineOffsetX: 0
UnderlineOffsetY: 0
4 changes: 4 additions & 0 deletions examples/time.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
local time = os.date("%a %d // %H:%M")

-- DrawString takes a string, alignment option, and additive x axis value
DrawString(time, Alignment.CENTER, 0)
32 changes: 21 additions & 11 deletions src/bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@
#include <thread>
#endif

mibar::mibar(){
MiBar::MiBar(const std::string& file){
//ConfigParser cfg(file);
m_cfg.Parse(file);

m_configX = std::stoi(m_cfg.GetConfig(BAR_X));
m_configY = std::stoi(m_cfg.GetConfig(BAR_Y));
m_configW = std::stoi(m_cfg.GetConfig(BAR_W));
m_configH = std::stoi(m_cfg.GetConfig(BAR_H));

m_conn = xcb_connect(nullptr, nullptr);
if(xcb_connection_has_error(m_conn)){
m_logger.Log(__FILE_NAME__, __LINE__, "Could not connect to X server!", LogLvl::ERROR);
Expand All @@ -22,12 +30,12 @@ mibar::mibar(){
m_winValues[1] = XCB_EVENT_MASK_EXPOSURE;

Randr r(m_conn, m_screen);
const auto mon = r.GetDisplayInfo(TARGET_MONITOR);
const auto mon = r.GetDisplayInfo(m_cfg.GetConfig(TARGET_MON));

m_x = mon->x + BAR_X;
m_y = mon->y + BAR_Y;
m_w = mon->width + BAR_WIDTH;
m_h = BAR_HEIGHT;
m_x = mon->x + m_configX;
m_y = mon->y + m_configY;
m_w = mon->width + m_configW;
m_h = m_configH;

m_window = xcb_generate_id(m_conn);
xcb_create_window(m_conn,
Expand All @@ -48,23 +56,25 @@ mibar::mibar(){

// EWMH (Extended Window Manager Hint) Reserve space for bar
xcb_atom_t wmStrutPartialAtom = GetAtom(m_conn, "_NET_WM_STRUT_PARTIAL");
uint32_t strut[12] = {0}; // https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html
uint32_t strut[12]{}; // https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html section 5.10
strut[2] = m_h + m_configY;

xcb_change_property(m_conn, XCB_PROP_MODE_REPLACE, m_window, wmStrutPartialAtom, XCB_ATOM_CARDINAL, 32, 12, strut);

// Set window title
xcb_change_property(m_conn, XCB_PROP_MODE_REPLACE, m_window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, sizeof(char*), 5, "MiBar"); // 5 = 5 chars
std::string windowTitle = "MiBar_" + m_cfg.GetConfig(TARGET_MON);
xcb_change_property(m_conn, XCB_PROP_MODE_REPLACE, m_window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, sizeof(char*), windowTitle.size(), windowTitle.c_str());

xcb_map_window(m_conn, m_window);
xcb_flush(m_conn);
}

mibar::~mibar(){
MiBar::~MiBar(){

}

void mibar::EventLoop() {
Renderer r(m_screen, m_conn, m_window);
void MiBar::EventLoop() {
Renderer r(m_screen, m_conn, m_window, m_cfg);

PluginManager pmgr;
pmgr.ExposeFuncToLua("DrawString", [&r](const std::string& str, ALIGNMENT align, const int x){r.DrawStr(str, align, x);});
Expand Down
14 changes: 11 additions & 3 deletions src/bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,31 @@
#include <xcb/xcb.h>

#include "logger.h"
#include "configParser.h"

class mibar{
class MiBar{
public:
mibar();
~mibar();
MiBar(const std::string& file);
~MiBar();

/**
Run the XCB event loop. This loop waits for exposure events to know when to re-render the bar
*/
void EventLoop();

private:
ConfigParser m_cfg;

// Basic connections
xcb_connection_t* m_conn = nullptr;
xcb_screen_t* m_screen = nullptr;
xcb_window_t m_window = 0;

int m_configX = 0;
int m_configY = 0;
int m_configW = 0;
int m_configH = 0;

int m_x, m_y, m_w, m_h;

uint32_t m_winMask = 0;
Expand Down
46 changes: 46 additions & 0 deletions src/configParser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <algorithm>
#include <filesystem>
#include <fstream>

#include "configParser.h"

ConfigParser::ConfigParser(){

}

void ConfigParser::Parse(const std::string& file){
auto configDir = std::filesystem::path(getenv("HOME")) / ".config/MiBar";

if(file.empty()){
configDir /= "config";
}
else{
configDir /= file;
}

configDir += ".bar";

// Parsing config file
std::fstream infile(configDir);

std::string line;
while(std::getline(infile, line)){
std::istringstream isLine(line);
std::string key;

if(std::getline(isLine, key, ':')){
if(key.find('*') != std::string::npos) continue;

std::string value;
if(std::getline(isLine, value)){
value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end());
m_configs[key] = value;
}
}
}
}

const std::string ConfigParser::GetConfig(const int key) const {
auto it = m_configs.find(m_configTable[key]);
return it->second;
}
Loading

0 comments on commit 09e2cbb

Please sign in to comment.