diff --git a/.github/workflows/wiki.yml b/.github/workflows/wiki.yml new file mode 100644 index 00000000..e88ffb95 --- /dev/null +++ b/.github/workflows/wiki.yml @@ -0,0 +1,22 @@ +name: Sync Wiki + +on: + push: + branches: [ "master" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Sync Wiki + uses: joeizzard/action-wiki-sync@master + with: + username: JakeStanger + access_token: ${{ secrets.GITHUB_TOKEN }} + wiki_folder: docs + commit_username: 'Jake Stanger' + commit_email: 'mail@jstanger.dev' + commit_message: 'sync wiki from main repo' \ No newline at end of file diff --git a/docs/Configuration guide.md b/docs/Configuration guide.md new file mode 100644 index 00000000..3b7b3dd8 --- /dev/null +++ b/docs/Configuration guide.md @@ -0,0 +1,268 @@ +By default, you get a single bar at the bottom of all your screens. +To change that, you'll unsurprisingly need a config file. + +## 1. Create config file + +The config file lives inside the `ironbar` directory in your XDG_CONFIG_DIR, which is usually `~/.config/ironbar`. + +Ironbar supports a range of configuration formats, so you can pick your favourite: + +- `config.json` +- `config.toml` +- `config.yaml` +- `config.corn` (Experimental, includes variable support for re-using blocks. + See [here](https://github.com/jakestanger/corn) for info) + +You can also override the default config path using the `IRONBAR_CONFIG` environment variable. + +## 2. Pick your use-case + +Ironbar gives you a few ways to configure the bar to suit your needs. +This allows you to keep your config simple and relatively flat if your use-case is simple, +and make it more complex if required. + +### a) I want the same bar across all monitors + +Place the bar config inside the top-level object. This is automatically applied to each of your monitors. + +
+JSON + +```json +{ + "position": "bottom", + "height": 42, + "start": [], + "center": [], + "end": [] +} +``` + +
+ +
+TOML + +```toml +position = "bottom" +height = 42 +start = [] +center = [] +end = [] +``` + +
+ +
+YAML + +```yaml +position: "bottom" +height: 42 +start: [ ] +center: [ ] +end: [ ] +``` + +
+ +
+Corn + +``` +{ + position = "bottom" + height = 42 + start = [] + center = [] + end = [] +} +``` + +
+ +### b) I want my config to differ across one or more monitors + +Create a map/object called `monitors` inside the top-level object. +Each of the map's keys should be an output name, +and each value should be an object containing the bar config. + +To find your output names, run `wayland-info | grep wl_output -A1`. + +
+JSON + +```json +{ + "monitors": { + "DP-1": { + "start": [] + }, + "DP-2": { + "position": "bottom", + "height": 30, + "start": [] + } + } +} +``` + +
+ +
+TOML + +```toml +[monitors] + +[monitors.DP-1] +start = [] + +[monitors.DP-2] +position = "bottom" +height = 30 +start = [] +``` + +
+ +
+YAML + +```yaml +monitors: + DP-1: + start: [ ] + DP-2: + position: "bottom" + height: 30 + start: [ ] +``` + +
+ +
+Corn + +``` +{ + monitors.DP-1.start = [] + monitors.DP-2 = { + position = "bottom" + height = 30 + start = [] + } +} +``` + +
+ +### c) I want one or more monitors to have multiple bars + +Create a map/object called `monitors` inside the top-level object. +Each of the map's keys should be an output name. +If you want the screen to have multiple bars, use an array of bar config objects. +If you want the screen to have a single bar, use an object. + +To find your output names, run `wayland-info | grep wl_output -A1`. + +
+JSON + +```json +{ + "monitors": { + "DP-1": [ + { + "start": [] + }, + { + "position": "top", + "start": [] + } + ], + "DP-2": { + "position": "bottom", + "height": 30, + "start": [] + } + } +} +``` + +
+ +
+TOML + +```toml +[monitors] + +[[monitors.DP-1]] +start = [] + +[[monitors.DP-2]] +position = "top" +start = [] + +[monitors.DP-2] +position = "bottom" +height = 30 +start = [] +``` + +
+ +
+YAML + +```yaml +monitors: + DP-1: + - start: [ ] + - position: "top" + start: [ ] + DP-2: + position: "bottom" + height: 30 + start: [ ] +``` + +
+ +
+Corn + +``` +{ + monitors.DP-1 = [ + { start = [] } + { position = "top" start = [] } + ] + monitors.DP-2 = { + position = "bottom" + height = 30 + start = [] + } +} +``` + +
+ +## 3. Write your bar config(s) + +Once you have the basic config structure set up, it's time to actually configure your bar(s). + +The following table describes each of the top-level bar config options. +For details on available modules and each of their config options, check the sidebar. + +| Name | Type | Default | Description | +|-------------------|----------------------------------------|----------|-----------------------------------------------------------------------------------------| +| `position` | `top` or `bottom` or `left` or `right` | `bottom` | The bar's position on screen. | +| `anchor_to_edges` | `boolean` | `false` | Whether to anchor the bar to the edges of the screen. Setting to false centres the bar. | +| `height` | `integer` | `42` | The bar's height in pixels. | +| `start` | `Module[]` | `[]` | Array of left or top modules. | +| `center` | `Module[]` | `[]` | Array of center modules. | +| `end` | `Module[]` | `[]` | Array of right or bottom modules. | + +Check [here](config) for an example config file for a fully configured bar in each format. \ No newline at end of file diff --git a/docs/Home.md b/docs/Home.md new file mode 100644 index 00000000..04d17898 --- /dev/null +++ b/docs/Home.md @@ -0,0 +1,4 @@ +Welcome to the Ironbar wiki. + +Detail about each module, and their configuration and styling options can be found on the sidebar. +You can also find an example configuration and stylesheet there. \ No newline at end of file diff --git a/docs/Styling guide.md b/docs/Styling guide.md new file mode 100644 index 00000000..3c350e84 --- /dev/null +++ b/docs/Styling guide.md @@ -0,0 +1,20 @@ +Ironbar ships with no styles by default, so will fall back to the default GTK styles. + +To style the bar, create a file at `~/.config/ironbar/style.css`. + +Style changes are hot-loaded so there is no need to reload the bar. + +A reminder: since the bar is GTK-based, it uses GTK's implementation of CSS, +which only includes a subset of the full web spec (plus a few non-standard properties). + +The below table describes the selectors provided by the bar itself. +Information on styling individual modules can be found on their pages in the sidebar. + +| Selector | Description | +|----------------|-------------------------------------------| +| `.background` | Top-level window | +| `#bar` | Bar root box | +| `#bar #start` | Bar left or top modules container box | +| `#bar #center` | Bar center modules container box | +| `#bar #end` | Bar right or bottom modules container box | +| `.container` | All of the above | diff --git a/docs/Sys-Info.md b/docs/Sys-Info.md new file mode 100644 index 00000000..dca0d7be --- /dev/null +++ b/docs/Sys-Info.md @@ -0,0 +1,176 @@ +Displays one or more labels containing system information. + +Separating information across several labels allows for styling each one independently. +Pango markup is supported. + +![Screenshot showing sys-info module with widgets for all of the types of formatting tokens](https://user-images.githubusercontent.com/5057870/196059090-4056d083-69f0-4e6f-9673-9e35dc29d9f0.png) + + +## Configuration + +> Type: `sys-info` + +| Name | Type | Default | Description | +|--------------------|--------------------|---------|--------------------------------------------------------------------------------------------------------------------------------| +| `format` | `string[]` | `null` | Array of strings including formatting tokens. For available tokens see below. | +| `interval` | `integer` or `Map` | `5` | Seconds between refreshing. Can be a single value for all data or a map of individual refresh values for different data types. | +| `interval.memory` | `integer` | `5` | Seconds between refreshing memory data | +| `interval.cpu` | `integer` | `5` | Seconds between refreshing cpu data | +| `interval.temps` | `integer` | `5` | Seconds between refreshing temperature data | +| `interval.disks` | `integer` | `5` | Seconds between refreshing disk data | +| `interval.network` | `integer` | `5` | Seconds between refreshing network data | + +
+JSON + +```json +{ + "end": [ + { + "format": [ + " {cpu-percent}% | {temp-c:k10temp-Tccd1}°C", + " {memory-used} / {memory-total} GB ({memory-percent}%)", + "| {swap-used} / {swap-total} GB ({swap-percent}%)", + " {disk-used:/} / {disk-total:/} GB ({disk-percent:/}%)", + "李 {net-down:enp39s0} / {net-up:enp39s0} Mbps", + "猪 {load-average:1} | {load-average:5} | {load-average:15}", + " {uptime}" + ], + "interval": { + "cpu": 1, + "disks": 300, + "memory": 30, + "networks": 3, + "temps": 5 + }, + "type": "sys-info" + } + ] +} +``` + +
+ +
+TOML + +```toml +[[end]] +type = 'sys-info' +format = [ + ' {cpu-percent}% | {temp-c:k10temp-Tccd1}°C', + ' {memory-used} / {memory-total} GB ({memory-percent}%)', + '| {swap-used} / {swap-total} GB ({swap-percent}%)', + ' {disk-used:/} / {disk-total:/} GB ({disk-percent:/}%)', + '李 {net-down:enp39s0} / {net-up:enp39s0} Mbps', + '猪 {load-average:1} | {load-average:5} | {load-average:15}', + ' {uptime}', +] + +[end.interval] +cpu = 1 +disks = 300 +memory = 30 +networks = 3 +temps = 5 + + +``` + +
+ +
+YAML + +```yaml +end: +- format: + -  {cpu-percent}% | {temp-c:k10temp-Tccd1}°C + -  {memory-used} / {memory-total} GB ({memory-percent}%) + - '| {swap-used} / {swap-total} GB ({swap-percent}%)' + -  {disk-used:/} / {disk-total:/} GB ({disk-percent:/}%) + - 李 {net-down:enp39s0} / {net-up:enp39s0} Mbps + - 猪 {load-average:1} | {load-average:5} | {load-average:15} + -  {uptime} + interval: + cpu: 1 + disks: 300 + memory: 30 + networks: 3 + temps: 5 + type: sys-info +``` + +
+ +
+Corn + +```corn +{ + end = [ + { + type = "sys-info" + + interval.memory = 30 + interval.cpu = 1 + interval.temps = 5 + interval.disks = 300 + interval.networks = 3 + + format = [ + " {cpu-percent}% | {temp-c:k10temp-Tccd1}°C" + " {memory-used} / {memory-total} GB ({memory-percent}%)" + "| {swap-used} / {swap-total} GB ({swap-percent}%)" + " {disk-used:/} / {disk-total:/} GB ({disk-percent:/}%)" + "李 {net-down:enp39s0} / {net-up:enp39s0} Mbps" + "猪 {load-average:1} | {load-average:5} | {load-average:15}" + " {uptime}" + ] + } + ] +} +``` + +
+ +### Formatting Tokens + +The following tokens can be used in the `format` configuration option: + +| Token | Description | +|--------------------------|------------------------------------------------------------------------------------| +| **CPU** | | +| `{cpu-percent}` | Total CPU utilisation percentage | +| **Memory** | | +| `{memory-free}` | Memory free in GB. | +| `{memory-used}` | Memory used in GB. | +| `{memory-total}` | Memory total in GB. | +| `{memory-percent}` | Memory utilisation percentage. | +| `{swap-free}` | Swap free in GB. | +| `{swap-used}` | Swap used in GB. | +| `{swap-total}` | Swap total in GB. | +| `{swap-percent}` | Swap utilisation percentage. | +| **Temperature** | | +| `{temp-c:[sensor]}` | Temperature in degrees C. Replace `[sensor]` with the sensor label. | +| `{temp-f:[sensor]}` | Temperature in degrees F. Replace `[sensor]` with the sensor label. | +| **Disk** | | +| `{disk-free:[mount]}` | Disk free space in GB. Replace `[mount]` with the disk mountpoint. | +| `{disk-used:[mount]}` | Disk used space in GB. Replace `[mount]` with the disk mountpoint. | +| `{disk-total:[mount]}` | Disk total space in GB. Replace `[mount]` with the disk mountpoint. | +| `{disk-percent:[mount]}` | Disk utilisation percentage. Replace `[mount]` with the disk mountpoint. | +| **Network** | | +| `{net-down:[adapter]}` | Average network download speed in Mbps. Replace `[adapter]` with the adapter name. | +| `{net-up:[adapter]}` | Average network upload speed in Mbps. Replace `[adapter]` with the adapter name. | +| **System** | | +| `{load-average:1}` | 1-minute load average. | +| `{load-average:5}` | 5-minute load average. | +| `{load-average:15}` | 15-minute load average. | +| `{uptime}` | System uptime formatted as `HH:mm`. | + +## Styling + +| Selector | Description | +|------------------|------------------------------| +| `#sysinfo` | Sysinfo widget box | +| `#sysinfo #item` | Individual information label | \ No newline at end of file diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md new file mode 100644 index 00000000..d274cec9 --- /dev/null +++ b/docs/_Sidebar.md @@ -0,0 +1,21 @@ +# Guides + +- [Configuration guide](configuration-guide) +- [Styling guide](styling-guide) + +# Examples + +- [Config](config) +- [Stylesheet](stylesheet) + +# Modules + +- [Clock](clock) +- [Custom](custom) +- [Focused](focused) +- [Launcher](launcher) +- [MPD](mpd) +- [Script](script) +- [Sys-info](sys-info) +- [Tray](tray) +- [Workspaces](workspaces) \ No newline at end of file diff --git a/docs/examples/Config.md b/docs/examples/Config.md new file mode 100644 index 00000000..ea808a12 --- /dev/null +++ b/docs/examples/Config.md @@ -0,0 +1,202 @@ +The below config shows a module of each type being used. + +The Corn format makes heavy use of variables +to show how module configs can be easily referenced to improve readability +and reduce config length when using multiple bars. + +
+JSON + +```json +{ + "start": [ + { + "all_monitors": false, + "name_map": { + "1": "ﭮ", + "2": "", + "3": "", + "Code": "", + "Games": "" + }, + "type": "workspaces" + }, + { + "favorites": [ + "firefox", + "discord", + "Steam" + ], + "icon_theme": "Paper", + "show_icons": true, + "show_names": false, + "type": "launcher" + } + ], + "end": [ + { + "music_dir": "/home/jake/Music", + "type": "mpd" + }, + { + "host": "chloe:6600", + "type": "mpd" + }, + { + "path": "/home/jake/bin/phone-battery", + "type": "script" + }, + { + "format": [ + "{cpu-percent}% ", + "{memory-percent}% " + ], + "type": "sys-info" + }, + { + "type": "clock" + } + ] +} +``` + +
+ +
+TOML + +```toml +[[start]] +all_monitors = false +type = 'workspaces' + +[start.name_map] +1 = 'ﭮ' +2 = '' +3 = '' +Code = '' +Games = '' + +[[start]] +icon_theme = 'Paper' +show_icons = true +show_names = false +type = 'launcher' +favorites = [ + 'firefox', + 'discord', + 'Steam', +] + +[[end]] +music_dir = '/home/jake/Music' +type = 'mpd' + +[[end]] +host = 'chloe:6600' +type = 'mpd' + +[[end]] +path = '/home/jake/bin/phone-battery' +type = 'script' + +[[end]] +type = 'sys-info' +format = [ + '{cpu-percent}% ', + '{memory-percent}% ', +] + +[[end]] +type = 'clock' +``` + +
+ +
+YAML + +```yaml +--- +start: + - all_monitors: false + name_map: + "1": ﭮ + "2":  + "3":  + Code:  + Games:  + type: workspaces + - favorites: + - firefox + - discord + - Steam + icon_theme: Paper + show_icons: true + show_names: false + type: launcher +end: + - music_dir: /home/jake/Music + type: mpd + - host: "chloe:6600" + type: mpd + - path: /home/jake/bin/phone-battery + type: script + - format: + - "{cpu-percent}% " + - "{memory-percent}% " + type: sys-info + - type: clock +``` +
+ +
+Corn + +```corn +let { + $workspaces = { + type = "workspaces" + all_monitors = false + name_map = { + 1 = "ﭮ" + 2 = "" + 3 = "" + Games = "" + Code = "" + } + } + + $launcher = { + type = "launcher" + favorites = ["firefox" "discord" "Steam"] + show_names = false + show_icons = true + icon_theme = "Paper" + } + + $mpd_local = { type = "mpd" music_dir = "/home/jake/Music" } + $mpd_server = { type = "mpd" host = "chloe:6600" } + + $sys_info = { + type = "sys-info" + format = ["{cpu-percent}% " "{memory-percent}% "] + } + + $tray = { type = "tray" } + $clock = { type = "clock" } + + $phone_battery = { + type = "script" + path = "/home/jake/bin/phone-battery" + } + + $start = [ $workspaces $launcher ] + $end = [ $mpd_local $mpd_server $phone_battery $sys_info $clock ] +} +in { + start = $start + end = $end +} +``` +
\ No newline at end of file diff --git a/docs/examples/Stylesheet.md b/docs/examples/Stylesheet.md new file mode 100644 index 00000000..08efa521 --- /dev/null +++ b/docs/examples/Stylesheet.md @@ -0,0 +1,142 @@ +The below example is a full stylesheet for all modules: + +```css +* { + /* a nerd font is required to be installed for icons */ + font-family: Noto Sans Nerd Font, sans-serif; + font-size: 16px; + border: none; +} + +#bar { + border-top: 1px solid #424242; +} + +.container { + background-color: #2d2d2d; +} + +.container#end > * + * { + margin-left: 20px; +} + +.popup { + background-color: #2d2d2d; + border: 1px solid #424242; +} + +#workspaces .item { + color: white; + background-color: #2d2d2d; + border-radius: 0; +} + +#workspaces .item.focused { + box-shadow: inset 0 -3px; + background-color: #1c1c1c; +} + +#workspaces *:not(.focused):hover { + box-shadow: inset 0 -3px; +} + +#launcher .item { + border-radius: 0; + background-color: #2d2d2d; + margin-right: 4px; +} + +#launcher .item:not(.focused):hover { + background-color: #1c1c1c; +} + +#launcher .open { + border-bottom: 2px solid #6699cc; +} + +#launcher .focused { + color: white; + background-color: black; + border-bottom: 4px solid #6699cc; +} + +#launcher .urgent { + color: white; + background-color: #8f0a0a; +} + +#script { + color: white; +} + +#sysinfo { + color: white; +} + +#tray .item { + background-color: #2d2d2d; +} + +#mpd { + background-color: #2d2d2d; + color: white; +} + +#popup-mpd { + color: white; + padding: 1em; +} + +#popup-mpd #album-art { + margin-right: 1em; +} + +#popup-mpd #title .icon, #popup-mpd #title .label { + font-size: 1.7em; +} + +#popup-mpd #controls * { + border-radius: 0; + background-color: #2d2d2d; + color: white; +} + +#popup-mpd #controls *:disabled { + color: #424242; +} + +#clock { + color: white; + background-color: #2d2d2d; + font-weight: bold; +} + +#popup-clock { + padding: 1em; +} + +#popup-clock #calendar-clock { + color: white; + font-size: 2.5em; + padding-bottom: 0.1em; +} + +#popup-clock #calendar { + background-color: #2d2d2d; + color: white; +} + +#popup-clock #calendar .header { + padding-top: 1em; + border-top: 1px solid #424242; + font-size: 1.5em; +} + +#popup-clock #calendar:selected { + background-color: #6699cc; +} + +#focused { + color: white; +} +``` \ No newline at end of file diff --git a/docs/modules/Clock.md b/docs/modules/Clock.md new file mode 100644 index 00000000..d2e84e9a --- /dev/null +++ b/docs/modules/Clock.md @@ -0,0 +1,77 @@ +Displays the current date and time. +Clicking on the widget opens a popup with the time and a calendar. + +![Screenshot of clock widget with popup open](https://user-images.githubusercontent.com/5057870/184540521-2278bdec-9742-46f0-9ac2-58a7b6f6ea1d.png) + + +## Configuration + +> Type: `clock` + +| Name | Type | Default | Description | +|----------|--------|------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +| `format` | `string` | `%d/%m/%Y %H:%M` | Date/time format string. Detail on available tokens can be found here: | + +
+JSON + +```json +{ + "end": [ + { + "type": "clock", + "format": "%d/%m/%Y %H:%M" + } + ] +} + +``` + +
+ +
+TOML + +```toml +[[end]] +type = "clock" +format = "%d/%m/%Y %H:%M" +``` + +
+ +
+YAML + +```yaml +end: + - type: "clock" + format: "%d/%m/%Y %H:%M" +``` + +
+ +
+Corn + +```corn +{ + end = [ + { + type = "clock" + format = "%d/%m/%Y %H:%M" + } + ] +} +``` + +
+ +## Styling + +| Selector | Description | +|-------------------------------|------------------------------------------------------------------------------------| +| `#clock` | Clock widget button | +| `#popup-clock` | Clock popup box | +| `#popup-clock #calendar-clock` | Clock inside the popup | +| `#popup-clock #calendar` | Calendar widget inside the popup. GTK provides some OOTB styling options for this. | \ No newline at end of file diff --git a/docs/modules/Custom.md b/docs/modules/Custom.md new file mode 100644 index 00000000..04c0f07f --- /dev/null +++ b/docs/modules/Custom.md @@ -0,0 +1,237 @@ +Allows you to compose custom modules consisting of multiple widgets, including popups. +Buttons can interact with the bar or execute commands on click. + +![Custom module with a button on the bar, and the popup open. The popup contains a header, shutdown button and restart button.](https://user-images.githubusercontent.com/5057870/196058785-042ef171-7e77-4d5c-921a-eca03c6424bd.png) + +## Configuration + +> Type: `custom` + +This module can be quite fiddly to configure as you effectively have to build a tree of widgets by hand. +It is well worth looking at the examples. + +| Name | Type | Default | Description | +|---------|------------|---------|--------------------------------------| +| `class` | `string` | `null` | Container class name. | +| `bar` | `Widget[]` | `null` | List of widgets to add to the bar. | +| `popup` | `Widget[]` | `[]` | List of widgets to add to the popup. | + +### `Widget` + +| Name | Type | Default | Description | +|---------------|------------------------------|--------------|---------------------------------------------------------------------------| +| `widget_type` | `box` or `label` or `button` | `null` | Type of GTK widget to create. | +| `name` | `string` | `null` | Widget name. | +| `class` | `string` | `null` | Widget class name. | +| `label` | `string` | `null` | [`label` and `button`] Widget text label. Pango markup supported. | +| `exec` | `string` | `null` | [`button`] Command to execute. More on this [below](#commands). | +| `orientation` | `horizontal` or `vertical` | `horizontal` | [`box`] Whether child widgets should be horizontally or vertically added. | +| `widgets` | `Widget[]` | `[]` | [`box`] List of widgets to add to this box. | + +### Commands + +Buttons can execute commands that interact with the bar, +as well as any arbitrary shell command. + +To execute shell commands, prefix them with an `!`. +For example, if you want to run `~/.local/bin/my-script.sh` on click, +you'd set `exec` to `!~/.local/bin/my-script.sh`. + +The following bar commands are supported: + +- `popup:toggle` +- `popup:open` +- `popup:close` + +XML is arguably better-suited and easier to read for this sort of markup, +but currently not supported. +Nonetheless, it may be worth comparing the examples to the below equivalent +to help get your head around what's going on: + + +```xml + + + +