Compare commits

..

No commits in common. "master" and "0.9.8" have entirely different histories.

240 changed files with 4733 additions and 18272 deletions

View File

@ -1,5 +1,6 @@
--- ---
BasedOnStyle: Google BasedOnStyle: Google
AlignConsecutiveDeclarations: false AlignConsecutiveDeclarations: true
BinPackArguments: false
ColumnLimit: 100 ColumnLimit: 100
... ...

View File

@ -1 +0,0 @@
use flake

View File

@ -4,26 +4,20 @@ on: [ push, pull_request ]
jobs: jobs:
clang: clang:
# Run actions in a FreeBSD VM on the macos-12 runner runs-on: macos-latest # until https://github.com/actions/runner/issues/385
# https://github.com/actions/runner/issues/385 - for FreeBSD runner support
# https://github.com/actions/virtual-environments/issues/4060 - for lack of VirtualBox on MacOS 11 runners
runs-on: macos-12
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Test in FreeBSD VM - name: Test in FreeBSD VM
uses: vmactions/freebsd-vm@v0 uses: vmactions/freebsd-vm@v0.1.4 # aka FreeBSD 12.2
with: with:
mem: 2048
usesh: true usesh: true
prepare: | prepare: |
export CPPFLAGS=-isystem/usr/local/include LDFLAGS=-L/usr/local/lib # sndio export CPPFLAGS=-isystem/usr/local/include LDFLAGS=-L/usr/local/lib # sndio
sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
pkg install -y git # subprojects/date pkg install -y git # subprojects/date
pkg install -y catch evdev-proto gtk-layer-shell gtkmm30 jsoncpp \ pkg install -y evdev-proto gtk-layer-shell gtkmm30 jsoncpp libdbusmenu \
libdbusmenu libevdev libfmt libmpdclient libudev-devd meson \ libevdev libfmt libmpdclient libudev-devd meson pkgconf pulseaudio \
pkgconf pulseaudio scdoc sndio spdlog wayland-protocols upower \ scdoc sndio spdlog
libinotify
run: | run: |
meson build -Dman-pages=enabled meson build -Dman-pages=enabled
ninja -C build ninja -C build
meson test -C build --no-rebuild --print-errorlogs --suite waybar

View File

@ -1,14 +0,0 @@
name: Linter
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: DoozyX/clang-format-lint-action@v0.13
with:
source: '.'
extensions: 'h,cpp,c'
clangFormatVersion: 12

View File

@ -12,21 +12,14 @@ jobs:
- debian - debian
- fedora - fedora
- opensuse - opensuse
- gentoo
cpp_std: [c++20]
include:
- distro: fedora
cpp_std: c++20
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: alexays/waybar:${{ matrix.distro }} image: alexays/waybar:${{ matrix.distro }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: configure - name: configure
run: meson -Dman-pages=enabled -Dcpp_std=${{matrix.cpp_std}} build run: meson -Dman-pages=enabled build
- name: build - name: build
run: ninja -C build run: ninja -C build
- name: test
run: make test

3
.gitignore vendored
View File

@ -2,8 +2,6 @@
*~ *~
vgcore.* vgcore.*
/.vscode /.vscode
/.idea
/.cache
*.swp *.swp
packagecache packagecache
/subprojects/**/ /subprojects/**/
@ -43,4 +41,3 @@ packagecache
*.exe *.exe
*.out *.out
*.app *.app
/.direnv/

View File

@ -2,4 +2,4 @@
FROM alpine:latest FROM alpine:latest
RUN apk add --no-cache git meson alpine-sdk libinput-dev wayland-dev wayland-protocols mesa-dev libxkbcommon-dev eudev-dev pixman-dev gtkmm3-dev jsoncpp-dev pugixml-dev libnl3-dev pulseaudio-dev libmpdclient-dev sndio-dev scdoc libxkbcommon tzdata playerctl-dev RUN apk add --no-cache git meson alpine-sdk libinput-dev wayland-dev wayland-protocols mesa-dev libxkbcommon-dev eudev-dev pixman-dev gtkmm3-dev jsoncpp-dev pugixml-dev libnl3-dev pulseaudio-dev libmpdclient-dev sndio-dev scdoc libxkbcommon

View File

@ -3,5 +3,4 @@
FROM archlinux:base-devel FROM archlinux:base-devel
RUN pacman -Syu --noconfirm && \ RUN pacman -Syu --noconfirm && \
pacman -S --noconfirm git meson base-devel libinput wayland wayland-protocols pixman libxkbcommon mesa gtkmm3 jsoncpp pugixml scdoc libpulse libdbusmenu-gtk3 libmpdclient gobject-introspection libxkbcommon playerctl iniparser fftw && \ pacman -S git meson base-devel libinput wayland wayland-protocols pixman libxkbcommon mesa gtkmm3 jsoncpp pugixml scdoc libpulse libdbusmenu-gtk3 libmpdclient gobject-introspection --noconfirm libxkbcommon
sed -Ei 's/#(en_(US|GB)\.UTF)/\1/' /etc/locale.gen && locale-gen

View File

@ -3,5 +3,5 @@
FROM debian:sid FROM debian:sid
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y build-essential meson ninja-build git pkg-config libinput10 libpugixml-dev libinput-dev wayland-protocols libwayland-client0 libwayland-cursor0 libwayland-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libxkbcommon-dev libudev-dev libpixman-1-dev libgtkmm-3.0-dev libjsoncpp-dev scdoc libdbusmenu-gtk3-dev libnl-3-dev libnl-genl-3-dev libpulse-dev libmpdclient-dev gobject-introspection libgirepository1.0-dev libxkbcommon-dev libxkbregistry-dev libxkbregistry0 libplayerctl-dev && \ apt-get install -y build-essential meson ninja-build git pkg-config libinput10 libpugixml-dev libinput-dev wayland-protocols libwayland-client0 libwayland-cursor0 libwayland-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libxkbcommon-dev libudev-dev libpixman-1-dev libgtkmm-3.0-dev libjsoncpp-dev scdoc libdbusmenu-gtk3-dev libnl-3-dev libnl-genl-3-dev libpulse-dev libmpdclient-dev gobject-introspection libgirepository1.0-dev libxkbcommon-dev libxkbregistry-dev libxkbregistry0 && \
apt-get clean apt-get clean

View File

@ -2,33 +2,11 @@
FROM fedora:latest FROM fedora:latest
RUN dnf install -y @c-development \ RUN dnf install -y @c-development git-core meson scdoc 'pkgconfig(date)' \
git-core glibc-langpack-en meson scdoc \ 'pkgconfig(dbusmenu-gtk3-0.4)' 'pkgconfig(fmt)' 'pkgconfig(gdk-pixbuf-2.0)' \
'pkgconfig(catch2)' \ 'pkgconfig(gio-unix-2.0)' 'pkgconfig(gtk-layer-shell-0)' 'pkgconfig(gtkmm-3.0)' \
'pkgconfig(date)' \ 'pkgconfig(jsoncpp)' 'pkgconfig(libinput)' 'pkgconfig(libmpdclient)' \
'pkgconfig(dbusmenu-gtk3-0.4)' \ 'pkgconfig(libnl-3.0)' 'pkgconfig(libnl-genl-3.0)' 'pkgconfig(libpulse)' \
'pkgconfig(fmt)' \ 'pkgconfig(libudev)' 'pkgconfig(pugixml)' 'pkgconfig(sigc++-2.0)' 'pkgconfig(spdlog)' \
'pkgconfig(gdk-pixbuf-2.0)' \ 'pkgconfig(wayland-client)' 'pkgconfig(wayland-cursor)' 'pkgconfig(wayland-protocols)' 'pkgconfig(xkbregistry)' && \
'pkgconfig(gio-unix-2.0)' \
'pkgconfig(gtk-layer-shell-0)' \
'pkgconfig(gtkmm-3.0)' \
'pkgconfig(jack)' \
'pkgconfig(jsoncpp)' \
'pkgconfig(libevdev)' \
'pkgconfig(libinput)' \
'pkgconfig(libmpdclient)' \
'pkgconfig(libnl-3.0)' \
'pkgconfig(libnl-genl-3.0)' \
'pkgconfig(libpulse)' \
'pkgconfig(libudev)' \
'pkgconfig(playerctl)' \
'pkgconfig(pugixml)' \
'pkgconfig(sigc++-2.0)' \
'pkgconfig(spdlog)' \
'pkgconfig(upower-glib)' \
'pkgconfig(wayland-client)' \
'pkgconfig(wayland-cursor)' \
'pkgconfig(wayland-protocols)' \
'pkgconfig(wireplumber-0.4)' \
'pkgconfig(xkbregistry)' && \
dnf clean all -y dnf clean all -y

View File

@ -1,11 +0,0 @@
# vim: ft=Dockerfile
FROM gentoo/stage3:latest
RUN export FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox -sandbox -usersandbox" && \
emerge --sync && \
eselect news read --quiet new 1>/dev/null 2>&1 && \
emerge --verbose --update --deep --with-bdeps=y --backtrack=30 --newuse @world && \
USE="wayland gtk3 gtk -doc X pulseaudio minimal" emerge dev-vcs/git dev-libs/wayland dev-libs/wayland-protocols =dev-cpp/gtkmm-3.24.6 x11-libs/libxkbcommon \
x11-libs/gtk+:3 dev-libs/libdbusmenu dev-libs/libnl sys-power/upower media-libs/libpulse dev-libs/libevdev media-libs/libmpdclient \
media-sound/sndio gui-libs/gtk-layer-shell app-text/scdoc media-sound/playerctl dev-libs/iniparser sci-libs/fftw

View File

@ -6,4 +6,4 @@ RUN zypper -n up && \
zypper addrepo https://download.opensuse.org/repositories/X11:Wayland/openSUSE_Tumbleweed/X11:Wayland.repo | echo 'a' && \ zypper addrepo https://download.opensuse.org/repositories/X11:Wayland/openSUSE_Tumbleweed/X11:Wayland.repo | echo 'a' && \
zypper -n refresh && \ zypper -n refresh && \
zypper -n install -t pattern devel_C_C++ && \ zypper -n install -t pattern devel_C_C++ && \
zypper -n install git meson clang libinput10 libinput-devel pugixml-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel libxkbregistry-devel scdoc playerctl-devel zypper -n install git meson clang libinput10 libinput-devel pugixml-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel libxkbregistry-devel scdoc

View File

@ -16,12 +16,5 @@ install: build
run: build run: build
./build/waybar ./build/waybar
debug-run: build-debug
./build/waybar --log-level debug
test:
meson test -C build --no-rebuild --verbose --suite waybar
.PHONY: test
clean: clean:
rm -rf build rm -rf build

View File

@ -1,32 +1,26 @@
# Waybar [![Licence](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Paypal Donate](https://img.shields.io/badge/Donate-Paypal-2244dd.svg)](https://paypal.me/ARouillard)<br>![Waybar](https://raw.githubusercontent.com/alexays/waybar/master/preview-2.png) # Waybar [![Travis](https://travis-ci.org/Alexays/Waybar.svg?branch=master)](https://travis-ci.org/Alexays/Waybar) [![Licence](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Paypal Donate](https://img.shields.io/badge/Donate-Paypal-2244dd.svg)](https://paypal.me/ARouillard)<br>![Waybar](https://raw.githubusercontent.com/alexays/waybar/master/preview-2.png)
> Highly customizable Wayland bar for Sway and Wlroots based compositors.<br> > Highly customizable Wayland bar for Sway and Wlroots based compositors.<br>
> Available in Arch [extra](https://www.archlinux.org/packages/extra/x86_64/waybar/) or > Available in Arch [community](https://www.archlinux.org/packages/community/x86_64/waybar/) or
[AUR](https://aur.archlinux.org/packages/waybar-git/), [Gentoo](https://packages.gentoo.org/packages/gui-apps/waybar), [openSUSE](https://build.opensuse.org/package/show/X11:Wayland/waybar), and [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=waybar).<br> [AUR](https://aur.archlinux.org/packages/waybar-git/), [openSUSE](https://build.opensuse.org/package/show/X11:Wayland/waybar), and [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=waybar)<br>
> *Waybar [examples](https://github.com/Alexays/Waybar/wiki/Examples)* > *Waybar [examples](https://github.com/Alexays/Waybar/wiki/Examples)*
#### Current features #### Current features
- Sway (Workspaces, Binding mode, Focused window name) - Sway (Workspaces, Binding mode, Focused window name)
- River (Mapping mode, Tags, Focused window name)
- Hyprland (Focused window name)
- DWL (Tags) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
- Tray [#21](https://github.com/Alexays/Waybar/issues/21) - Tray [#21](https://github.com/Alexays/Waybar/issues/21)
- Local time - Local time
- Battery - Battery
- UPower
- Network - Network
- Bluetooth - Bluetooth
- Pulseaudio - Pulseaudio
- Wireplumber
- Disk - Disk
- Memory - Memory
- Cpu load average - Cpu load average
- Temperature - Temperature
- MPD - MPD
- Custom scripts - Custom scripts
- Custom image
- Multiple output configuration - Multiple output configuration
- And many more customizations - And much more customizations
#### Configuration and Styling #### Configuration and Styling
@ -75,8 +69,6 @@ libdbusmenu-gtk3 [Tray module]
libmpdclient [MPD module] libmpdclient [MPD module]
libsndio [sndio module] libsndio [sndio module]
libevdev [KeyboardState module] libevdev [KeyboardState module]
xkbregistry
upower [UPower battery module]
``` ```
**Build dependencies** **Build dependencies**
@ -88,7 +80,7 @@ scdoc
wayland-protocols wayland-protocols
``` ```
On Ubuntu, you can install all the relevant dependencies using this command (tested with 19.10 and 20.04): On Ubuntu you can install all the relevant dependencies using this command (tested with 19.10 and 20.04):
``` ```
sudo apt install \ sudo apt install \
@ -109,15 +101,12 @@ sudo apt install \
libsigc++-2.0-dev \ libsigc++-2.0-dev \
libspdlog-dev \ libspdlog-dev \
libwayland-dev \ libwayland-dev \
scdoc \ scdoc
upower \
libxkbregistry-dev
``` ```
Contributions welcome!<br> Contributions welcome! - have fun :)<br>
Have fun :)<br> The style guidelines is [Google's](https://google.github.io/styleguide/cppguide.html)
The style guidelines are [Google's](https://google.github.io/styleguide/cppguide.html)
## License ## License

View File

@ -1,10 +0,0 @@
(import
(
let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
)
{ src = ./.; }
).defaultNix

129
flake.lock generated
View File

@ -1,129 +0,0 @@
{
"nodes": {
"devshell": {
"inputs": {
"nixpkgs": "nixpkgs",
"systems": "systems"
},
"locked": {
"lastModified": 1692523566,
"narHash": "sha256-VDJDihK6jNebVw9y3qKCVD6+6QaC/x8kxZzL4MaIPPY=",
"owner": "numtide",
"repo": "devshell",
"rev": "d208c58e2f7afef838add5f18a9936b12a71d695",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1689068808,
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1677383253,
"narHash": "sha256-UfpzWfSxkfXHnb4boXZNaKsAcUrZT9Hw+tao1oZxd08=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9952d6bc395f5841262b006fbace8dd7e143b634",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1692638711,
"narHash": "sha256-J0LgSFgJVGCC1+j5R2QndadWI1oumusg6hCtYAzLID4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "91a22f76cd1716f9d0149e8a5c68424bb691de15",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"devshell": "devshell",
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_2"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View File

@ -1,89 +0,0 @@
{
description = "Highly customizable Wayland bar for Sway and Wlroots based compositors.";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
devshell.url = "github:numtide/devshell";
flake-utils.url = "github:numtide/flake-utils";
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
};
outputs = { self, flake-utils, devshell, nixpkgs, flake-compat }:
let
inherit (nixpkgs) lib;
genSystems = lib.genAttrs [
"x86_64-linux"
];
pkgsFor = genSystems (system:
import nixpkgs {
inherit system;
});
mkDate = longDate: (lib.concatStringsSep "-" [
(builtins.substring 0 4 longDate)
(builtins.substring 4 2 longDate)
(builtins.substring 6 2 longDate)
]);
in
{
overlays.default = final: prev: {
waybar = final.callPackage ./nix/default.nix {
version = prev.waybar.version + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
};
};
packages = genSystems
(system:
(self.overlays.default pkgsFor.${system} pkgsFor.${system})
// {
default = self.packages.${system}.waybar;
});
} //
flake-utils.lib.eachDefaultSystem (system: {
devShell =
let pkgs = import nixpkgs {
inherit system;
overlays = [ devshell.overlays.default ];
};
in
pkgs.devshell.mkShell {
imports = [ "${pkgs.devshell.extraModulesDir}/language/c.nix" ];
devshell.packages = with pkgs; [
clang-tools
gdb
# from nativeBuildInputs
gnumake
meson
ninja
pkg-config
scdoc
] ++ (map lib.getDev [
# from buildInputs
wayland wlroots gtkmm3 libsigcxx jsoncpp spdlog gtk-layer-shell howard-hinnant-date libxkbcommon
# optional dependencies
gobject-introspection glib playerctl python3.pkgs.pygobject3
libevdev libinput libjack2 libmpdclient playerctl libnl
libpulseaudio sndio sway libdbusmenu-gtk3 udev upower wireplumber
# from propagated build inputs?
at-spi2-atk atkmm cairo cairomm catch2 fmt_8 fontconfig
gdk-pixbuf glibmm gtk3 harfbuzz pango pangomm wayland-protocols
]);
env = with pkgs; [
{ name = "CPLUS_INCLUDE_PATH"; prefix = "$DEVSHELL_DIR/include"; }
{ name = "PKG_CONFIG_PATH"; prefix = "$DEVSHELL_DIR/lib/pkgconfig"; }
{ name = "PKG_CONFIG_PATH"; prefix = "$DEVSHELL_DIR/share/pkgconfig"; }
{ name = "PATH"; prefix = "${wayland.bin}/bin"; }
{ name = "LIBRARY_PATH"; prefix = "${lib.getLib sndio}/lib"; }
{ name = "LIBRARY_PATH"; prefix = "${lib.getLib zlib}/lib"; }
{ name = "LIBRARY_PATH"; prefix = "${lib.getLib howard-hinnant-date}/lib"; }
];
};
});
}

View File

@ -1,27 +0,0 @@
#pragma once
#include <gtkmm/box.h>
#include <gtkmm/image.h>
#include "AIconLabel.hpp"
namespace waybar {
class AAppIconLabel : public AIconLabel {
public:
AAppIconLabel(const Json::Value &config, const std::string &name, const std::string &id,
const std::string &format, uint16_t interval = 0, bool ellipsize = false,
bool enable_click = false, bool enable_scroll = false);
virtual ~AAppIconLabel() = default;
auto update() -> void override;
protected:
void updateAppIconName(const std::string &app_identifier,
const std::string &alternative_app_identifier);
void updateAppIcon();
unsigned app_icon_size_{24};
bool update_app_icon_{true};
std::string app_icon_name_;
};
} // namespace waybar

View File

@ -1,25 +0,0 @@
#pragma once
#include <gtkmm/box.h>
#include <gtkmm/image.h>
#include "ALabel.hpp"
namespace waybar {
class AIconLabel : public ALabel {
public:
AIconLabel(const Json::Value &config, const std::string &name, const std::string &id,
const std::string &format, uint16_t interval = 0, bool ellipsize = false,
bool enable_click = false, bool enable_scroll = false);
virtual ~AIconLabel() = default;
auto update() -> void override;
protected:
Gtk::Image image_;
Gtk::Box box_;
bool iconEnabled() const;
};
} // namespace waybar

View File

@ -3,7 +3,6 @@
#include <glibmm/markup.h> #include <glibmm/markup.h>
#include <gtkmm/label.h> #include <gtkmm/label.h>
#include <json/json.h> #include <json/json.h>
#include "AModule.hpp" #include "AModule.hpp"
namespace waybar { namespace waybar {
@ -11,21 +10,20 @@ namespace waybar {
class ALabel : public AModule { class ALabel : public AModule {
public: public:
ALabel(const Json::Value &, const std::string &, const std::string &, const std::string &format, ALabel(const Json::Value &, const std::string &, const std::string &, const std::string &format,
uint16_t interval = 0, bool ellipsize = false, bool enable_click = false, uint16_t interval = 0, bool ellipsize = false, bool enable_click = false, bool enable_scroll = false);
bool enable_scroll = false);
virtual ~ALabel() = default; virtual ~ALabel() = default;
auto update() -> void override; virtual auto update() -> void;
virtual std::string getIcon(uint16_t, const std::string &alt = "", uint16_t max = 0); virtual std::string getIcon(uint16_t, const std::string &alt = "", uint16_t max = 0);
virtual std::string getIcon(uint16_t, const std::vector<std::string> &alts, uint16_t max = 0); virtual std::string getIcon(uint16_t, const std::vector<std::string> &alts, uint16_t max = 0);
protected: protected:
Gtk::Label label_; Gtk::Label label_;
std::string format_; std::string format_;
const std::chrono::seconds interval_; const std::chrono::seconds interval_;
bool alt_ = false; bool alt_ = false;
std::string default_format_; std::string default_format_;
bool handleToggle(GdkEventButton *const &e) override; virtual bool handleToggle(GdkEventButton *const &e);
virtual std::string getState(uint8_t value, bool lesser = false); virtual std::string getState(uint8_t value, bool lesser = false);
}; };

View File

@ -11,53 +11,31 @@ namespace waybar {
class AModule : public IModule { class AModule : public IModule {
public: public:
AModule(const Json::Value &, const std::string &, const std::string &, bool enable_click = false,
bool enable_scroll = false);
virtual ~AModule(); virtual ~AModule();
auto update() -> void override; virtual auto update() -> void;
virtual auto refresh(int) -> void{}; virtual operator Gtk::Widget &();
operator Gtk::Widget &() override;
auto doAction(const std::string &name) -> void override;
Glib::Dispatcher dp; Glib::Dispatcher dp;
protected: protected:
// Don't need to make an object directly
// Derived classes are able to use it
AModule(const Json::Value &, const std::string &, const std::string &, bool enable_click = false,
bool enable_scroll = false);
enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT }; enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT };
SCROLL_DIR getScrollDir(GdkEventScroll *e); SCROLL_DIR getScrollDir(GdkEventScroll *e);
bool tooltipEnabled(); bool tooltipEnabled();
const std::string name_; const std::string name_;
const Json::Value &config_; const Json::Value &config_;
Gtk::EventBox event_box_; Gtk::EventBox event_box_;
virtual bool handleToggle(GdkEventButton *const &ev); virtual bool handleToggle(GdkEventButton *const &ev);
virtual bool handleScroll(GdkEventScroll *); virtual bool handleScroll(GdkEventScroll *);
private: private:
std::vector<int> pid_; std::vector<int> pid_;
gdouble distance_scrolled_y_; gdouble distance_scrolled_y_;
gdouble distance_scrolled_x_; gdouble distance_scrolled_x_;
std::map<std::string, std::string> eventActionMap_;
static const inline std::map<std::pair<uint, GdkEventType>, std::string> eventMap_{
{std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), "on-click"},
{std::make_pair(1, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click"},
{std::make_pair(1, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click"},
{std::make_pair(2, GdkEventType::GDK_BUTTON_PRESS), "on-click-middle"},
{std::make_pair(2, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-middle"},
{std::make_pair(2, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-middle"},
{std::make_pair(3, GdkEventType::GDK_BUTTON_PRESS), "on-click-right"},
{std::make_pair(3, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-right"},
{std::make_pair(3, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-right"},
{std::make_pair(8, GdkEventType::GDK_BUTTON_PRESS), "on-click-backward"},
{std::make_pair(8, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-backward"},
{std::make_pair(8, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-backward"},
{std::make_pair(9, GdkEventType::GDK_BUTTON_PRESS), "on-click-forward"},
{std::make_pair(9, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-forward"},
{std::make_pair(9, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-forward"}};
}; };
} // namespace waybar } // namespace waybar

View File

@ -7,9 +7,8 @@ namespace waybar {
class IModule { class IModule {
public: public:
virtual ~IModule() = default; virtual ~IModule() = default;
virtual auto update() -> void = 0; virtual auto update() -> void = 0;
virtual operator Gtk::Widget&() = 0; virtual operator Gtk::Widget &() = 0;
virtual auto doAction(const std::string& name) -> void = 0;
}; };
} // namespace waybar } // namespace waybar

View File

@ -8,9 +8,6 @@
#include <gtkmm/window.h> #include <gtkmm/window.h>
#include <json/json.h> #include <json/json.h>
#include <memory>
#include <vector>
#include "AModule.hpp" #include "AModule.hpp"
#include "xdg-output-unstable-v1-client-protocol.h" #include "xdg-output-unstable-v1-client-protocol.h"
@ -19,8 +16,8 @@ namespace waybar {
class Factory; class Factory;
struct waybar_output { struct waybar_output {
Glib::RefPtr<Gdk::Monitor> monitor; Glib::RefPtr<Gdk::Monitor> monitor;
std::string name; std::string name;
std::string identifier; std::string identifier;
std::unique_ptr<struct zxdg_output_v1, decltype(&zxdg_output_v1_destroy)> xdg_output = { std::unique_ptr<struct zxdg_output_v1, decltype(&zxdg_output_v1_destroy)> xdg_output = {
nullptr, &zxdg_output_v1_destroy}; nullptr, &zxdg_output_v1_destroy};
@ -39,19 +36,6 @@ struct bar_margins {
int left = 0; int left = 0;
}; };
struct bar_mode {
bar_layer layer;
bool exclusive;
bool passthrough;
bool visible;
};
#ifdef HAVE_SWAY
namespace modules::sway {
class BarIpcClient;
}
#endif // HAVE_SWAY
class BarSurface { class BarSurface {
protected: protected:
BarSurface() = default; BarSurface() = default;
@ -70,56 +54,38 @@ class BarSurface {
class Bar { class Bar {
public: public:
using bar_mode_map = std::map<std::string_view, struct bar_mode>;
static const bar_mode_map PRESET_MODES;
static const std::string_view MODE_DEFAULT;
static const std::string_view MODE_INVISIBLE;
Bar(struct waybar_output *w_output, const Json::Value &); Bar(struct waybar_output *w_output, const Json::Value &);
Bar(const Bar &) = delete; Bar(const Bar &) = delete;
~Bar(); ~Bar() = default;
void setMode(const std::string_view &);
void setVisible(bool visible); void setVisible(bool visible);
void toggle(); void toggle();
void handleSignal(int); void handleSignal(int);
struct waybar_output *output; struct waybar_output *output;
Json::Value config; Json::Value config;
struct wl_surface *surface; struct wl_surface * surface;
bool visible = true; bool exclusive = true;
bool vertical = false; bool visible = true;
Gtk::Window window; bool vertical = false;
Gtk::Window window;
#ifdef HAVE_SWAY
std::string bar_id;
#endif
private: private:
void onMap(GdkEventAny *); void onMap(GdkEventAny *);
auto setupWidgets() -> void; auto setupWidgets() -> void;
void getModules(const Factory &, const std::string &, Gtk::Box *); void getModules(const Factory &, const std::string &);
void setupAltFormatKeyForModule(const std::string &module_name); void setupAltFormatKeyForModule(const std::string &module_name);
void setupAltFormatKeyForModuleList(const char *module_list_name); void setupAltFormatKeyForModuleList(const char *module_list_name);
void setMode(const bar_mode &);
/* Copy initial set of modes to allow customization */ std::unique_ptr<BarSurface> surface_impl_;
bar_mode_map configured_modes = PRESET_MODES; bar_layer layer_;
std::string last_mode_{MODE_DEFAULT}; Gtk::Box left_;
Gtk::Box center_;
std::unique_ptr<BarSurface> surface_impl_; Gtk::Box right_;
Gtk::Box left_; Gtk::Box box_;
Gtk::Box center_; std::vector<std::unique_ptr<waybar::AModule>> modules_left_;
Gtk::Box right_; std::vector<std::unique_ptr<waybar::AModule>> modules_center_;
Gtk::Box box_; std::vector<std::unique_ptr<waybar::AModule>> modules_right_;
std::vector<std::shared_ptr<waybar::AModule>> modules_left_;
std::vector<std::shared_ptr<waybar::AModule>> modules_center_;
std::vector<std::shared_ptr<waybar::AModule>> modules_right_;
#ifdef HAVE_SWAY
using BarIpcClient = modules::sway::BarIpcClient;
std::unique_ptr<BarIpcClient> _ipc_client;
#endif
std::vector<std::shared_ptr<waybar::AModule>> modules_all_;
}; };
} // namespace waybar } // namespace waybar

View File

@ -3,10 +3,11 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <gdk/gdk.h> #include <gdk/gdk.h>
#include <gdk/gdkwayland.h> #include <gdk/gdkwayland.h>
#include <unistd.h>
#include <wayland-client.h> #include <wayland-client.h>
#include <wordexp.h>
#include "bar.hpp" #include "bar.hpp"
#include "config.hpp"
struct zwlr_layer_shell_v1; struct zwlr_layer_shell_v1;
struct zwp_idle_inhibitor_v1; struct zwp_idle_inhibitor_v1;
@ -17,27 +18,31 @@ namespace waybar {
class Client { class Client {
public: public:
static Client *inst(); static Client *inst();
int main(int argc, char *argv[]); int main(int argc, char *argv[]);
void reset(); void reset();
Glib::RefPtr<Gtk::Application> gtk_app; Glib::RefPtr<Gtk::Application> gtk_app;
Glib::RefPtr<Gdk::Display> gdk_display; Glib::RefPtr<Gdk::Display> gdk_display;
struct wl_display *wl_display = nullptr; struct wl_display * wl_display = nullptr;
struct wl_registry *registry = nullptr; struct wl_registry * registry = nullptr;
struct zwlr_layer_shell_v1 *layer_shell = nullptr; struct zwlr_layer_shell_v1 * layer_shell = nullptr;
struct zxdg_output_manager_v1 *xdg_output_manager = nullptr; struct zxdg_output_manager_v1 * xdg_output_manager = nullptr;
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager = nullptr; struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager = nullptr;
std::vector<std::unique_ptr<Bar>> bars; std::vector<std::unique_ptr<Bar>> bars;
Config config;
std::string bar_id;
private: private:
Client() = default; Client() = default;
const std::string getStyle(const std::string &style); std::tuple<const std::string, const std::string> getConfigs(const std::string &config,
void bindInterfaces(); const std::string &style) const;
void handleOutput(struct waybar_output &output); void bindInterfaces();
auto setupCss(const std::string &css_file) -> void; const std::string getValidPath(const std::vector<std::string> &paths) const;
struct waybar_output &getOutput(void *); void handleOutput(struct waybar_output &output);
bool isValidOutput(const Json::Value &config, struct waybar_output &output);
auto setupConfig(const std::string &config_file, int depth) -> void;
auto resolveConfigIncludes(Json::Value &config, int depth) -> void;
auto mergeConfig(Json::Value &a_config_, Json::Value &b_config_) -> void;
auto setupCss(const std::string &css_file) -> void;
struct waybar_output & getOutput(void *);
std::vector<Json::Value> getOutputConfigs(struct waybar_output &output); std::vector<Json::Value> getOutputConfigs(struct waybar_output &output);
static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name, static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
@ -46,12 +51,13 @@ class Client {
static void handleOutputDone(void *, struct zxdg_output_v1 *); static void handleOutputDone(void *, struct zxdg_output_v1 *);
static void handleOutputName(void *, struct zxdg_output_v1 *, const char *); static void handleOutputName(void *, struct zxdg_output_v1 *, const char *);
static void handleOutputDescription(void *, struct zxdg_output_v1 *, const char *); static void handleOutputDescription(void *, struct zxdg_output_v1 *, const char *);
void handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor); void handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor);
void handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor); void handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor);
void handleDeferredMonitorRemoval(Glib::RefPtr<Gdk::Monitor> monitor); void handleDeferredMonitorRemoval(Glib::RefPtr<Gdk::Monitor> monitor);
Json::Value config_;
Glib::RefPtr<Gtk::StyleContext> style_context_; Glib::RefPtr<Gtk::StyleContext> style_context_;
Glib::RefPtr<Gtk::CssProvider> css_provider_; Glib::RefPtr<Gtk::CssProvider> css_provider_;
std::list<struct waybar_output> outputs_; std::list<struct waybar_output> outputs_;
}; };

View File

@ -1,40 +0,0 @@
#pragma once
#include <json/json.h>
#include <optional>
#include <string>
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
namespace waybar {
class Config {
public:
static const std::vector<std::string> CONFIG_DIRS;
static const char *CONFIG_PATH_ENV;
/* Try to find any of provided names in the supported set of config directories */
static std::optional<std::string> findConfigPath(
const std::vector<std::string> &names, const std::vector<std::string> &dirs = CONFIG_DIRS);
Config() = default;
void load(const std::string &config);
Json::Value &getConfig() { return config_; }
std::vector<Json::Value> getOutputConfigs(const std::string &name, const std::string &identifier);
private:
void setupConfig(Json::Value &dst, const std::string &config_file, int depth);
void resolveConfigIncludes(Json::Value &config, int depth);
void mergeConfig(Json::Value &a_config_, Json::Value &b_config_);
std::string config_file_;
Json::Value config_;
};
} // namespace waybar

View File

@ -1,39 +1,24 @@
#pragma once #pragma once
#include <json/json.h> #include <json/json.h>
#if defined(HAVE_CHRONO_TIMEZONES) || defined(HAVE_LIBDATE) #ifdef HAVE_LIBDATE
#include "modules/clock.hpp" #include "modules/clock.hpp"
#else #else
#include "modules/simpleclock.hpp" #include "modules/simpleclock.hpp"
#endif #endif
#ifdef HAVE_SWAY #ifdef HAVE_SWAY
#include "modules/sway/language.hpp"
#include "modules/sway/mode.hpp" #include "modules/sway/mode.hpp"
#include "modules/sway/scratchpad.hpp"
#include "modules/sway/window.hpp" #include "modules/sway/window.hpp"
#include "modules/sway/workspaces.hpp" #include "modules/sway/workspaces.hpp"
#include "modules/sway/language.hpp"
#endif #endif
#ifdef HAVE_WLR #ifdef HAVE_WLR
#include "modules/wlr/taskbar.hpp" #include "modules/wlr/taskbar.hpp"
#include "modules/wlr/workspace_manager.hpp"
#endif #endif
#ifdef HAVE_RIVER #ifdef HAVE_RIVER
#include "modules/river/layout.hpp"
#include "modules/river/mode.hpp"
#include "modules/river/tags.hpp" #include "modules/river/tags.hpp"
#include "modules/river/window.hpp"
#endif #endif
#ifdef HAVE_DWL #if defined(__linux__) && !defined(NO_FILESYSTEM)
#include "modules/dwl/tags.hpp"
#endif
#ifdef HAVE_HYPRLAND
#include "modules/hyprland/backend.hpp"
#include "modules/hyprland/language.hpp"
#include "modules/hyprland/submap.hpp"
#include "modules/hyprland/window.hpp"
#include "modules/hyprland/workspaces.hpp"
#endif
#if defined(__FreeBSD__) || (defined(__linux__) && !defined(NO_FILESYSTEM))
#include "modules/battery.hpp" #include "modules/battery.hpp"
#endif #endif
#if defined(HAVE_CPU_LINUX) || defined(HAVE_CPU_BSD) #if defined(HAVE_CPU_LINUX) || defined(HAVE_CPU_BSD)
@ -47,9 +32,6 @@
#ifdef HAVE_DBUSMENU #ifdef HAVE_DBUSMENU
#include "modules/sni/tray.hpp" #include "modules/sni/tray.hpp"
#endif #endif
#ifdef HAVE_MPRIS
#include "modules/mpris/mpris.hpp"
#endif
#ifdef HAVE_LIBNL #ifdef HAVE_LIBNL
#include "modules/network.hpp" #include "modules/network.hpp"
#endif #endif
@ -59,12 +41,6 @@
#ifdef HAVE_LIBEVDEV #ifdef HAVE_LIBEVDEV
#include "modules/keyboard_state.hpp" #include "modules/keyboard_state.hpp"
#endif #endif
#ifdef HAVE_GAMEMODE
#include "modules/gamemode.hpp"
#endif
#ifdef HAVE_UPOWER
#include "modules/upower/upower.hpp"
#endif
#ifdef HAVE_LIBPULSE #ifdef HAVE_LIBPULSE
#include "modules/pulseaudio.hpp" #include "modules/pulseaudio.hpp"
#endif #endif
@ -74,24 +50,14 @@
#ifdef HAVE_LIBSNDIO #ifdef HAVE_LIBSNDIO
#include "modules/sndio.hpp" #include "modules/sndio.hpp"
#endif #endif
#ifdef HAVE_GIO_UNIX
#include "modules/bluetooth.hpp"
#include "modules/inhibitor.hpp"
#endif
#ifdef HAVE_LIBJACK
#include "modules/jack.hpp"
#endif
#ifdef HAVE_LIBWIREPLUMBER
#include "modules/wireplumber.hpp"
#endif
#ifdef HAVE_LIBCAVA
#include "modules/cava.hpp"
#endif
#include "bar.hpp" #include "bar.hpp"
#include "modules/custom.hpp" #include "modules/custom.hpp"
#include "modules/image.hpp"
#include "modules/temperature.hpp" #include "modules/temperature.hpp"
#include "modules/user.hpp" #if defined(__linux__)
# ifdef WANT_RFKILL
# include "modules/bluetooth.hpp"
# endif
#endif
namespace waybar { namespace waybar {
@ -101,7 +67,7 @@ class Factory {
AModule* makeModule(const std::string& name) const; AModule* makeModule(const std::string& name) const;
private: private:
const Bar& bar_; const Bar& bar_;
const Json::Value& config_; const Json::Value& config_;
}; };

View File

@ -1,22 +0,0 @@
#pragma once
#include <gtkmm/box.h>
#include <gtkmm/widget.h>
#include <json/json.h>
#include "AModule.hpp"
#include "bar.hpp"
#include "factory.hpp"
namespace waybar {
class Group : public AModule {
public:
Group(const std::string&, const std::string&, const Json::Value&, bool);
~Group() = default;
auto update() -> void override;
operator Gtk::Widget&() override;
Gtk::Box box;
};
} // namespace waybar

View File

@ -6,7 +6,6 @@
#include <vector> #include <vector>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "giomm/dbusproxy.h"
#include "util/json.hpp" #include "util/json.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
@ -19,29 +18,26 @@ class Backlight : public ALabel {
class BacklightDev { class BacklightDev {
public: public:
BacklightDev() = default; BacklightDev() = default;
BacklightDev(std::string name, int actual, int max, bool powered); BacklightDev(std::string name, int actual, int max);
std::string_view name() const; std::string_view name() const;
int get_actual() const; int get_actual() const;
void set_actual(int actual); void set_actual(int actual);
int get_max() const; int get_max() const;
void set_max(int max); void set_max(int max);
bool get_powered() const;
void set_powered(bool powered);
friend inline bool operator==(const BacklightDev &lhs, const BacklightDev &rhs) { friend inline bool operator==(const BacklightDev &lhs, const BacklightDev &rhs) {
return lhs.name_ == rhs.name_ && lhs.actual_ == rhs.actual_ && lhs.max_ == rhs.max_; return lhs.name_ == rhs.name_ && lhs.actual_ == rhs.actual_ && lhs.max_ == rhs.max_;
} }
private: private:
std::string name_; std::string name_;
int actual_ = 1; int actual_ = 1;
int max_ = 1; int max_ = 1;
bool powered_ = true;
}; };
public: public:
Backlight(const std::string &, const Json::Value &); Backlight(const std::string &, const Json::Value &);
virtual ~Backlight(); ~Backlight();
auto update() -> void override; auto update() -> void;
private: private:
template <class ForwardIt> template <class ForwardIt>
@ -51,19 +47,15 @@ class Backlight : public ALabel {
template <class ForwardIt, class Inserter> template <class ForwardIt, class Inserter>
static void enumerate_devices(ForwardIt first, ForwardIt last, Inserter inserter, udev *udev); static void enumerate_devices(ForwardIt first, ForwardIt last, Inserter inserter, udev *udev);
bool handleScroll(GdkEventScroll *e) override; const std::string preferred_device_;
const std::string preferred_device_;
static constexpr int EPOLL_MAX_EVENTS = 16; static constexpr int EPOLL_MAX_EVENTS = 16;
std::optional<BacklightDev> previous_best_; std::optional<BacklightDev> previous_best_;
std::string previous_format_; std::string previous_format_;
std::mutex udev_thread_mutex_; std::mutex udev_thread_mutex_;
std::vector<BacklightDev> devices_; std::vector<BacklightDev> devices_;
// thread must destruct before shared data // thread must destruct before shared data
util::SleeperThread udev_thread_; util::SleeperThread udev_thread_;
Glib::RefPtr<Gio::DBus::Proxy> login_proxy_;
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -6,15 +6,11 @@
#include <filesystem> #include <filesystem>
#endif #endif
#include <fmt/format.h> #include <fmt/format.h>
#if defined(__linux__)
#include <sys/inotify.h> #include <sys/inotify.h>
#endif
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <vector> #include <vector>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
@ -29,30 +25,29 @@ namespace fs = std::filesystem;
class Battery : public ALabel { class Battery : public ALabel {
public: public:
Battery(const std::string&, const Json::Value&); Battery(const std::string&, const Json::Value&);
virtual ~Battery(); ~Battery();
auto update() -> void override; auto update() -> void;
private: private:
static inline const fs::path data_dir_ = "/sys/class/power_supply/"; static inline const fs::path data_dir_ = "/sys/class/power_supply/";
void refreshBatteries(); void refreshBatteries();
void worker(); void worker();
const std::string getAdapterStatus(uint8_t capacity) const; const std::string getAdapterStatus(uint8_t capacity) const;
const std::tuple<uint8_t, float, std::string, float> getInfos(); const std::tuple<uint8_t, float, std::string, float> getInfos();
const std::string formatTimeRemaining(float hoursRemaining); const std::string formatTimeRemaining(float hoursRemaining);
int global_watch; int global_watch;
std::map<fs::path, int> batteries_; std::map<fs::path,int> batteries_;
fs::path adapter_; fs::path adapter_;
int battery_watch_fd_; int battery_watch_fd_;
int global_watch_fd_; int global_watch_fd_;
std::mutex battery_list_mutex_; std::mutex battery_list_mutex_;
std::string old_status_; std::string old_status_;
bool warnFirstTime_{true};
util::SleeperThread thread_; util::SleeperThread thread_;
util::SleeperThread thread_battery_update_; util::SleeperThread thread_battery_update_;
util::SleeperThread thread_timer_; util::SleeperThread thread_timer_;
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -1,80 +1,18 @@
#pragma once #pragma once
#include "ALabel.hpp" #include "ALabel.hpp"
#ifdef WANT_RFKILL
#include "util/rfkill.hpp" #include "util/rfkill.hpp"
#endif
#include <gio/gio.h>
#include <optional>
#include <string>
#include <vector>
namespace waybar::modules { namespace waybar::modules {
class Bluetooth : public ALabel { class Bluetooth : public ALabel {
struct ControllerInfo {
std::string path;
std::string address;
std::string address_type;
// std::string name; // just use alias instead
std::string alias;
bool powered;
bool discoverable;
bool pairable;
bool discovering;
};
// NOTE: there are some properties that not all devices provide
struct DeviceInfo {
std::string path;
std::string paired_controller;
std::string address;
std::string address_type;
// std::optional<std::string> name; // just use alias instead
std::string alias;
std::optional<std::string> icon;
bool paired;
bool trusted;
bool blocked;
bool connected;
bool services_resolved;
// NOTE: experimental feature in bluez
std::optional<unsigned char> battery_percentage;
};
public: public:
Bluetooth(const std::string&, const Json::Value&); Bluetooth(const std::string&, const Json::Value&);
virtual ~Bluetooth() = default; ~Bluetooth() = default;
auto update() -> void override; auto update() -> void;
private: private:
static auto onInterfaceAddedOrRemoved(GDBusObjectManager*, GDBusObject*, GDBusInterface*,
gpointer) -> void;
static auto onInterfaceProxyPropertiesChanged(GDBusObjectManagerClient*, GDBusObjectProxy*,
GDBusProxy*, GVariant*, const gchar* const*,
gpointer) -> void;
auto getDeviceBatteryPercentage(GDBusObject*) -> std::optional<unsigned char>;
auto getDeviceProperties(GDBusObject*, DeviceInfo&) -> bool;
auto getControllerProperties(GDBusObject*, ControllerInfo&) -> bool;
// Returns std::nullopt if no controller could be found
auto findCurController() -> std::optional<ControllerInfo>;
auto findConnectedDevices(const std::string&, std::vector<DeviceInfo>&) -> void;
#ifdef WANT_RFKILL
util::Rfkill rfkill_; util::Rfkill rfkill_;
#endif
const std::unique_ptr<GDBusObjectManager, void (*)(GDBusObjectManager*)> manager_;
std::string state_;
std::optional<ControllerInfo> cur_controller_;
std::vector<DeviceInfo> connected_devices_;
DeviceInfo cur_focussed_device_;
std::string device_enumerate_;
std::vector<std::string> device_preference_;
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -1,46 +0,0 @@
#pragma once
#include "ALabel.hpp"
#include "util/sleeper_thread.hpp"
extern "C" {
#include <cava/common.h>
}
namespace waybar::modules {
using namespace std::literals::chrono_literals;
class Cava final : public ALabel {
public:
Cava(const std::string&, const Json::Value&);
virtual ~Cava();
auto update() -> void override;
auto doAction(const std::string& name) -> void override;
private:
util::SleeperThread thread_;
util::SleeperThread thread_fetch_input_;
struct error_s error_ {}; // cava errors
struct config_params prm_ {}; // cava parameters
struct audio_raw audio_raw_ {}; // cava handled raw audio data(is based on audio_data)
struct audio_data audio_data_ {}; // cava audio data
struct cava_plan* plan_; //{new cava_plan{}};
// Cava API to read audio source
ptr input_source_;
// Delay to handle audio source
std::chrono::milliseconds frame_time_milsec_{1s};
// Text to display
std::string text_{""};
int rePaint_{1};
std::chrono::seconds fetch_input_delay_{4};
std::chrono::seconds suspend_silence_delay_{0};
bool silence_{false};
int sleep_counter_{0};
// Cava method
void pause_resume();
// ModuleActionMap
static inline std::map<const std::string, void (waybar::modules::Cava::*const)()> actionMap_{
{"mode", &waybar::modules::Cava::pause_resume}};
};
} // namespace waybar::modules

View File

@ -1,79 +1,42 @@
#pragma once #pragma once
#include <fmt/format.h>
#if FMT_VERSION < 60000
#include <fmt/time.h>
#else
#include <fmt/chrono.h>
#endif
#include <date/tz.h>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/date.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
namespace waybar::modules { namespace waybar::modules {
const std::string kCalendarPlaceholder = "calendar"; struct waybar_time {
const std::string KTimezonedTimeListPlaceholder = "timezoned_time_list"; std::locale locale;
date::zoned_seconds ztime;
enum class WeeksSide {
LEFT,
RIGHT,
HIDDEN,
}; };
enum class CldMode { MONTH, YEAR }; class Clock : public ALabel {
class Clock final : public ALabel {
public: public:
Clock(const std::string&, const Json::Value&); Clock(const std::string&, const Json::Value&);
virtual ~Clock() = default; ~Clock() = default;
auto update() -> void override; auto update() -> void;
auto doAction(const std::string& name) -> void override;
private: private:
util::SleeperThread thread_; util::SleeperThread thread_;
std::locale locale_; std::locale locale_;
std::vector<const date::time_zone*> time_zones_; const date::time_zone* time_zone_;
int current_time_zone_idx_; bool fixed_time_zone_;
bool is_calendar_in_tooltip_; int time_zone_idx_;
bool is_timezoned_list_in_tooltip_; date::year_month_day cached_calendar_ymd_ = date::January/1/0;
std::string cached_calendar_text_;
bool handleScroll(GdkEventScroll* e);
auto calendar_text(const waybar_time& wtime) -> std::string;
auto weekdays_header(const date::weekday& first_dow, std::ostream& os) -> void;
auto first_day_of_week() -> date::weekday; auto first_day_of_week() -> date::weekday;
const date::time_zone* current_timezone();
auto timezones_text(std::chrono::system_clock::time_point now) -> std::string;
/*Calendar properties*/
WeeksSide cldWPos_{WeeksSide::HIDDEN};
/*
0 - calendar.format.months
1 - calendar.format.weekdays
2 - calendar.format.days
3 - calendar.format.today
4 - calendar.format.weeks
5 - tooltip-format
*/
std::map<int, std::string const> fmtMap_;
CldMode cldMode_{CldMode::MONTH};
uint cldMonCols_{3}; // Count of the month in the row
int cldMonColLen_{20}; // Length of the month column
int cldWnLen_{3}; // Length of the week number
date::year_month_day cldYearShift_;
date::year_month cldMonShift_;
date::months cldCurrShift_{0};
date::months cldShift_{0};
std::string cldYearCached_{};
std::string cldMonCached_{};
date::day cldBaseDay_{0};
/*Calendar functions*/
auto get_calendar(const date::year_month_day& today, const date::year_month_day& ymd,
const date::time_zone* tz) -> const std::string;
/*Clock actions*/
void cldModeSwitch();
void cldShift_up();
void cldShift_down();
void tz_up();
void tz_down();
// ModuleActionMap
static inline std::map<const std::string, void (waybar::modules::Clock::*const)()> actionMap_{
{"mode", &waybar::modules::Clock::cldModeSwitch},
{"shift_up", &waybar::modules::Clock::cldShift_up},
{"shift_down", &waybar::modules::Clock::cldShift_down},
{"tz_up", &waybar::modules::Clock::tz_up},
{"tz_down", &waybar::modules::Clock::tz_down}};
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -1,14 +1,12 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include <cstdint> #include <cstdint>
#include <fstream> #include <fstream>
#include <numeric> #include <numeric>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
@ -17,15 +15,15 @@ namespace waybar::modules {
class Cpu : public ALabel { class Cpu : public ALabel {
public: public:
Cpu(const std::string&, const Json::Value&); Cpu(const std::string&, const Json::Value&);
virtual ~Cpu() = default; ~Cpu() = default;
auto update() -> void override; auto update() -> void;
private: private:
double getCpuLoad(); double getCpuLoad();
std::tuple<std::vector<uint16_t>, std::string> getCpuUsage(); std::tuple<uint16_t, std::string> getCpuUsage();
std::tuple<float, float, float> getCpuFrequency(); std::tuple<float, float, float> getCpuFrequency();
std::vector<std::tuple<size_t, size_t>> parseCpuinfo(); std::vector<std::tuple<size_t, size_t>> parseCpuinfo();
std::vector<float> parseCpuFrequencies(); std::vector<float> parseCpuFrequencies();
std::vector<std::tuple<size_t, size_t>> prev_times_; std::vector<std::tuple<size_t, size_t>> prev_times_;

View File

@ -1,11 +1,8 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include <fmt/args.h>
#include <csignal> #include <csignal>
#include <string> #include <string>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/command.hpp" #include "util/command.hpp"
#include "util/json.hpp" #include "util/json.hpp"
@ -16,9 +13,9 @@ namespace waybar::modules {
class Custom : public ALabel { class Custom : public ALabel {
public: public:
Custom(const std::string&, const std::string&, const Json::Value&); Custom(const std::string&, const std::string&, const Json::Value&);
virtual ~Custom(); ~Custom();
auto update() -> void override; auto update() -> void;
void refresh(int /*signal*/) override; void refresh(int /*signal*/);
private: private:
void delayWorker(); void delayWorker();
@ -26,21 +23,19 @@ class Custom : public ALabel {
void parseOutputRaw(); void parseOutputRaw();
void parseOutputJson(); void parseOutputJson();
void handleEvent(); void handleEvent();
bool handleScroll(GdkEventScroll* e) override; bool handleScroll(GdkEventScroll* e);
bool handleToggle(GdkEventButton* const& e) override; bool handleToggle(GdkEventButton* const& e);
const std::string name_; const std::string name_;
std::string text_; std::string text_;
std::string id_; std::string alt_;
std::string alt_; std::string tooltip_;
std::string tooltip_;
std::vector<std::string> class_; std::vector<std::string> class_;
fmt::dynamic_format_arg_store<fmt::format_context> fields_; int percentage_;
int percentage_; FILE* fp_;
FILE* fp_; int pid_;
int pid_; util::command::res output_;
util::command::res output_; util::JsonParser parser_;
util::JsonParser parser_;
util::SleeperThread thread_; util::SleeperThread thread_;
}; };

View File

@ -1,21 +1,19 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include <sys/statvfs.h>
#include <fstream> #include <fstream>
#include <sys/statvfs.h>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/format.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
#include "util/format.hpp"
namespace waybar::modules { namespace waybar::modules {
class Disk : public ALabel { class Disk : public ALabel {
public: public:
Disk(const std::string&, const Json::Value&); Disk(const std::string&, const Json::Value&);
virtual ~Disk() = default; ~Disk() = default;
auto update() -> void override; auto update() -> void;
private: private:
util::SleeperThread thread_; util::SleeperThread thread_;

View File

@ -1,34 +0,0 @@
#pragma once
#include <gtkmm/button.h>
#include <wayland-client.h>
#include "AModule.hpp"
#include "bar.hpp"
#include "dwl-ipc-unstable-v2-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h"
namespace waybar::modules::dwl {
class Tags : public waybar::AModule {
public:
Tags(const std::string &, const waybar::Bar &, const Json::Value &);
virtual ~Tags();
// Handlers for wayland events
void handle_view_tags(uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused);
void handle_primary_clicked(uint32_t tag);
bool handle_button_press(GdkEventButton *event_button, uint32_t tag);
struct zdwl_ipc_manager_v2 *status_manager_;
struct wl_seat *seat_;
private:
const waybar::Bar &bar_;
Gtk::Box box_;
std::vector<Gtk::Button> buttons_;
struct zdwl_ipc_output_v2 *output_status_;
};
} /* namespace waybar::modules::dwl */

View File

@ -1,77 +0,0 @@
#pragma once
#include <iostream>
#include <map>
#include <string>
#include "ALabel.hpp"
#include "giomm/dbusconnection.h"
#include "giomm/dbusproxy.h"
#include "glibconfig.h"
#include "gtkmm/box.h"
#include "gtkmm/image.h"
#include "gtkmm/label.h"
#include "gtkmm/overlay.h"
namespace waybar::modules {
class Gamemode : public AModule {
public:
Gamemode(const std::string &, const Json::Value &);
virtual ~Gamemode();
auto update() -> void override;
private:
const std::string DEFAULT_ICON_NAME = "input-gaming-symbolic";
const std::string DEFAULT_FORMAT = "{glyph}";
const std::string DEFAULT_FORMAT_ALT = "{glyph} {count}";
const std::string DEFAULT_TOOLTIP_FORMAT = "Games running: {count}";
const std::string DEFAULT_GLYPH = "";
void appear(const Glib::RefPtr<Gio::DBus::Connection> &connection, const Glib::ustring &name,
const Glib::ustring &name_owner);
void disappear(const Glib::RefPtr<Gio::DBus::Connection> &connection, const Glib::ustring &name);
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name, const Glib::ustring &object_path,
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters);
void notify_cb(const Glib::ustring &sender_name, const Glib::ustring &signal_name,
const Glib::VariantContainerBase &arguments);
void getData();
bool handleToggle(GdkEventButton *const &) override;
// Config
std::string format = DEFAULT_FORMAT;
std::string format_alt = DEFAULT_FORMAT_ALT;
std::string tooltip_format = DEFAULT_TOOLTIP_FORMAT;
std::string glyph = DEFAULT_GLYPH;
bool tooltip = true;
bool hideNotRunning = true;
bool useIcon = true;
uint iconSize = 20;
uint iconSpacing = 4;
std::string iconName = DEFAULT_ICON_NAME;
Gtk::Box box_;
Gtk::Image icon_;
Gtk::Label label_;
const std::string dbus_name = "com.feralinteractive.GameMode";
const std::string dbus_obj_path = "/com/feralinteractive/GameMode";
const std::string dbus_interface = "org.freedesktop.DBus.Properties";
const std::string dbus_get_interface = "com.feralinteractive.GameMode";
uint gameCount = 0;
std::string lastStatus;
bool showAltText = false;
guint login1_id;
Glib::RefPtr<Gio::DBus::Proxy> gamemode_proxy;
Glib::RefPtr<Gio::DBus::Connection> system_connection;
bool gamemodeRunning;
guint gamemodeWatcher_id;
};
} // namespace waybar::modules

View File

@ -1,40 +0,0 @@
#pragma once
#include <functional>
#include <list>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include "util/json.hpp"
namespace waybar::modules::hyprland {
class EventHandler {
public:
virtual void onEvent(const std::string& ev) = 0;
virtual ~EventHandler() = default;
};
class IPC {
public:
IPC() { startIPC(); }
void registerForIPC(const std::string&, EventHandler*);
void unregisterForIPC(EventHandler*);
std::string getSocket1Reply(const std::string& rq);
Json::Value getSocket1JsonReply(const std::string& rq);
private:
void startIPC();
void parseIPC(const std::string&);
std::mutex callbackMutex;
util::JsonParser parser_;
std::list<std::pair<std::string, EventHandler*>> callbacks;
};
inline std::unique_ptr<IPC> gIPC;
inline bool modulesReady = false;
}; // namespace waybar::modules::hyprland

View File

@ -1,38 +0,0 @@
#include <fmt/format.h>
#include "ALabel.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
#include "util/json.hpp"
namespace waybar::modules::hyprland {
class Language : public waybar::ALabel, public EventHandler {
public:
Language(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Language();
auto update() -> void override;
private:
void onEvent(const std::string&) override;
void initLanguage();
struct Layout {
std::string full_name;
std::string short_name;
std::string variant;
std::string short_description;
};
auto getLayout(const std::string&) -> Layout;
std::mutex mutex_;
const Bar& bar_;
util::JsonParser parser_;
Layout layout_;
};
} // namespace waybar::modules::hyprland

View File

@ -1,26 +0,0 @@
#include <fmt/format.h>
#include "ALabel.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
#include "util/json.hpp"
namespace waybar::modules::hyprland {
class Submap : public waybar::ALabel, public EventHandler {
public:
Submap(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Submap();
auto update() -> void override;
private:
void onEvent(const std::string&) override;
std::mutex mutex_;
const Bar& bar_;
util::JsonParser parser_;
std::string submap_;
};
} // namespace waybar::modules::hyprland

View File

@ -1,60 +0,0 @@
#include <fmt/format.h>
#include "AAppIconLabel.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
#include "util/json.hpp"
namespace waybar::modules::hyprland {
class Window : public waybar::AAppIconLabel, public EventHandler {
public:
Window(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Window();
auto update() -> void override;
private:
struct Workspace {
int id;
int windows;
std::string last_window;
std::string last_window_title;
static auto parse(const Json::Value&) -> Workspace;
};
struct WindowData {
bool floating;
int monitor = -1;
std::string class_name;
std::string initial_class_name;
std::string title;
std::string initial_title;
bool fullscreen;
bool grouped;
static auto parse(const Json::Value&) -> WindowData;
};
auto getActiveWorkspace(const std::string&) -> Workspace;
auto getActiveWorkspace() -> Workspace;
void onEvent(const std::string&) override;
void queryActiveWorkspace();
void setClass(const std::string&, bool enable);
bool separate_outputs;
std::mutex mutex_;
const Bar& bar_;
util::JsonParser parser_;
WindowData window_data_;
Workspace workspace_;
std::string solo_class_;
std::string last_solo_class_;
bool solo_;
bool all_floating_;
bool swallowing_;
bool fullscreen_;
};
} // namespace waybar::modules::hyprland

View File

@ -1,91 +0,0 @@
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <memory>
#include "AModule.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
namespace waybar::modules::hyprland {
class Workspace {
public:
Workspace(const Json::Value& workspace_data);
std::string& select_icon(std::map<std::string, std::string>& icons_map);
Gtk::Button& button() { return button_; };
int id() const { return id_; };
std::string name() const { return name_; };
std::string output() const { return output_; };
bool active() const { return active_; };
bool is_special() const { return is_special_; };
bool is_persistent() const { return is_persistent_; };
bool is_empty() const { return windows_ == 0; };
bool is_urgent() const { return is_urgent_; };
auto handle_clicked(GdkEventButton* bt) -> bool;
void set_active(bool value = true) { active_ = value; };
void set_persistent(bool value = true) { is_persistent_ = value; };
void set_urgent(bool value = true) { is_urgent_ = value; };
void set_windows(uint value) { windows_ = value; };
void update(const std::string& format, const std::string& icon);
private:
int id_;
std::string name_;
std::string output_;
uint windows_;
bool active_ = false;
bool is_special_ = false;
bool is_persistent_ = false;
bool is_urgent_ = false;
Gtk::Button button_;
Gtk::Box content_;
Gtk::Label label_;
};
class Workspaces : public AModule, public EventHandler {
public:
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
~Workspaces() override;
void update() override;
void init();
auto all_outputs() const -> bool { return all_outputs_; }
auto show_special() const -> bool { return show_special_; }
auto get_bar_output() const -> std::string { return bar_.output->name; }
private:
void onEvent(const std::string&) override;
void update_window_count();
void sort_workspaces();
void create_workspace(Json::Value& value);
void remove_workspace(std::string name);
void set_urgent_workspace(std::string windowaddress);
bool all_outputs_ = false;
bool show_special_ = false;
void fill_persistent_workspaces();
void create_persistent_workspaces();
std::vector<std::string> persistent_workspaces_to_create_;
bool persistent_created_ = false;
std::string format_;
std::map<std::string, std::string> icons_map_;
bool with_icon_;
uint64_t monitor_id_;
std::string active_workspace_name_;
std::vector<std::unique_ptr<Workspace>> workspaces_;
std::vector<Json::Value> workspaces_to_create_;
std::vector<std::string> workspaces_to_remove_;
std::mutex mutex_;
const Bar& bar_;
Gtk::Box box_;
};
} // namespace waybar::modules::hyprland

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "bar.hpp" #include "bar.hpp"
#include "client.hpp" #include "client.hpp"
@ -9,22 +8,19 @@
namespace waybar::modules { namespace waybar::modules {
class IdleInhibitor : public ALabel { class IdleInhibitor : public ALabel {
sigc::connection timeout_;
public: public:
IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&); IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~IdleInhibitor(); ~IdleInhibitor();
auto update() -> void override; auto update() -> void;
static std::list<waybar::AModule*> modules; static std::list<waybar::AModule*> modules;
static bool status; static bool status;
private: private:
bool handleToggle(GdkEventButton* const& e) override; bool handleToggle(GdkEventButton* const& e);
void toggleStatus();
const Bar& bar_; const Bar& bar_;
struct zwp_idle_inhibitor_v1* idle_inhibitor_; struct zwp_idle_inhibitor_v1* idle_inhibitor_;
int pid_; int pid_;
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -1,40 +0,0 @@
#pragma once
#include <fmt/format.h>
#include <gtkmm/image.h>
#include <csignal>
#include <string>
#include "ALabel.hpp"
#include "gtkmm/box.h"
#include "util/command.hpp"
#include "util/json.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules {
class Image : public AModule {
public:
Image(const std::string&, const Json::Value&);
virtual ~Image() = default;
auto update() -> void override;
void refresh(int /*signal*/) override;
private:
void delayWorker();
void handleEvent();
void parseOutputRaw();
Gtk::Box box_;
Gtk::Image image_;
std::string path_;
std::string tooltip_;
int size_;
int interval_;
util::command::res output_;
util::SleeperThread thread_;
};
} // namespace waybar::modules

View File

@ -1,27 +0,0 @@
#pragma once
#include <gio/gio.h>
#include <memory>
#include "ALabel.hpp"
#include "bar.hpp"
namespace waybar::modules {
class Inhibitor : public ALabel {
public:
Inhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Inhibitor();
auto update() -> void override;
auto activated() -> bool;
private:
auto handleToggle(::GdkEventButton* const& e) -> bool override;
const std::unique_ptr<::GDBusConnection, void (*)(::GDBusConnection*)> dbus_;
const std::string inhibitors_;
int handle_ = -1;
};
} // namespace waybar::modules

View File

@ -1,44 +0,0 @@
#pragma once
#include <fmt/format.h>
#include <jack/jack.h>
#include <jack/thread.h>
#include <fstream>
#include "ALabel.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules {
class JACK : public ALabel {
public:
JACK(const std::string &, const Json::Value &);
virtual ~JACK() = default;
auto update() -> void override;
int bufSize(jack_nframes_t size);
int sampleRate(jack_nframes_t rate);
int xrun();
void shutdown();
private:
std::string JACKState();
jack_client_t *client_;
jack_nframes_t bufsize_;
jack_nframes_t samplerate_;
unsigned int xruns_;
float load_;
bool running_;
std::mutex mutex_;
std::string state_;
util::SleeperThread thread_;
};
} // namespace waybar::modules
int bufSizeCallback(jack_nframes_t size, void *obj);
int sampleRateCallback(jack_nframes_t rate, void *obj);
int xrunCallback(void *obj);
void shutdownCallback(void *obj);

View File

@ -1,18 +1,18 @@
#pragma once #pragma once
#include <fmt/format.h>
#if FMT_VERSION < 60000
#include <fmt/time.h>
#else
#include <fmt/chrono.h> #include <fmt/chrono.h>
#include <gtkmm/label.h> #endif
#include <set>
#include <unordered_map>
#include "AModule.hpp" #include "AModule.hpp"
#include "bar.hpp" #include "bar.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
#include <gtkmm/label.h>
extern "C" { extern "C" {
#include <libevdev/libevdev.h> #include <libevdev/libevdev.h>
#include <libinput.h>
} }
namespace waybar::modules { namespace waybar::modules {
@ -20,16 +20,16 @@ namespace waybar::modules {
class KeyboardState : public AModule { class KeyboardState : public AModule {
public: public:
KeyboardState(const std::string&, const waybar::Bar&, const Json::Value&); KeyboardState(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~KeyboardState(); ~KeyboardState();
auto update() -> void override; auto update() -> void;
private: private:
auto tryAddDevice(const std::string&) -> void; static auto openDevice(const std::string&) -> std::pair<int, libevdev*>;
Gtk::Box box_; Gtk::Box box_;
Gtk::Label numlock_label_; Gtk::Label numlock_label_;
Gtk::Label capslock_label_; Gtk::Label capslock_label_;
Gtk::Label scrolllock_label_; Gtk::Label scrolllock_label_;
std::string numlock_format_; std::string numlock_format_;
std::string capslock_format_; std::string capslock_format_;
@ -37,13 +37,11 @@ class KeyboardState : public AModule {
const std::chrono::seconds interval_; const std::chrono::seconds interval_;
std::string icon_locked_; std::string icon_locked_;
std::string icon_unlocked_; std::string icon_unlocked_;
std::string devices_path_;
struct libinput* libinput_; int fd_;
std::unordered_map<std::string, struct libinput_device*> libinput_devices_; libevdev* dev_;
std::set<int> binding_keys;
util::SleeperThread libinput_thread_, hotplug_thread_; util::SleeperThread thread_;
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -1,10 +1,8 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include <fstream> #include <fstream>
#include <unordered_map> #include <unordered_map>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
@ -13,11 +11,11 @@ namespace waybar::modules {
class Memory : public ALabel { class Memory : public ALabel {
public: public:
Memory(const std::string&, const Json::Value&); Memory(const std::string&, const Json::Value&);
virtual ~Memory() = default; ~Memory() = default;
auto update() -> void override; auto update() -> void;
private: private:
void parseMeminfo(); void parseMeminfo();
std::unordered_map<std::string, unsigned long> meminfo_; std::unordered_map<std::string, unsigned long> meminfo_;

View File

@ -22,8 +22,8 @@ class MPD : public ALabel {
// Not using unique_ptr since we don't manage the pointer // Not using unique_ptr since we don't manage the pointer
// (It's either nullptr, or from the config) // (It's either nullptr, or from the config)
const char* server_; const char* server_;
const unsigned port_; const unsigned port_;
const std::string password_; const std::string password_;
unsigned timeout_; unsigned timeout_;
@ -31,18 +31,17 @@ class MPD : public ALabel {
detail::unique_connection connection_; detail::unique_connection connection_;
detail::unique_status status_; detail::unique_status status_;
mpd_state state_; mpd_state state_;
detail::unique_song song_; detail::unique_song song_;
public: public:
MPD(const std::string&, const Json::Value&); MPD(const std::string&, const Json::Value&);
virtual ~MPD() noexcept = default; virtual ~MPD() noexcept = default;
auto update() -> void override; auto update() -> void;
private: private:
std::string getTag(mpd_tag_type type, unsigned idx = 0) const; std::string getTag(mpd_tag_type type, unsigned idx = 0) const;
std::string getFilename() const; void setLabel();
void setLabel();
std::string getStateIcon() const; std::string getStateIcon() const;
std::string getOptionIcon(std::string optionName, bool activated) const; std::string getOptionIcon(std::string optionName, bool activated) const;

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <fmt/format.h>
#include <mpd/client.h> #include <mpd/client.h>
#include <fmt/format.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <condition_variable> #include <condition_variable>
@ -57,7 +57,7 @@ class State {
}; };
class Idle : public State { class Idle : public State {
Context* const ctx_; Context* const ctx_;
sigc::connection idle_connection_; sigc::connection idle_connection_;
public: public:
@ -80,7 +80,7 @@ class Idle : public State {
}; };
class Playing : public State { class Playing : public State {
Context* const ctx_; Context* const ctx_;
sigc::connection timer_connection_; sigc::connection timer_connection_;
public: public:
@ -102,7 +102,7 @@ class Playing : public State {
}; };
class Paused : public State { class Paused : public State {
Context* const ctx_; Context* const ctx_;
sigc::connection timer_connection_; sigc::connection timer_connection_;
public: public:
@ -124,7 +124,7 @@ class Paused : public State {
}; };
class Stopped : public State { class Stopped : public State {
Context* const ctx_; Context* const ctx_;
sigc::connection timer_connection_; sigc::connection timer_connection_;
public: public:
@ -146,7 +146,7 @@ class Stopped : public State {
}; };
class Disconnected : public State { class Disconnected : public State {
Context* const ctx_; Context* const ctx_;
sigc::connection timer_connection_; sigc::connection timer_connection_;
public: public:
@ -170,7 +170,7 @@ class Disconnected : public State {
class Context { class Context {
std::unique_ptr<State> state_; std::unique_ptr<State> state_;
waybar::modules::MPD* mpd_module_; waybar::modules::MPD* mpd_module_;
friend class State; friend class State;
friend class Playing; friend class Playing;
@ -188,18 +188,18 @@ class Context {
state_->entry(); state_->entry();
} }
bool is_connected() const; bool is_connected() const;
bool is_playing() const; bool is_playing() const;
bool is_paused() const; bool is_paused() const;
bool is_stopped() const; bool is_stopped() const;
constexpr std::size_t interval() const; constexpr std::size_t interval() const;
void tryConnect() const; void tryConnect() const;
void checkErrors(mpd_connection*) const; void checkErrors(mpd_connection*) const;
void do_update(); void do_update();
void queryMPD() const; void queryMPD() const;
void fetchState() const; void fetchState() const;
constexpr mpd_state state() const; constexpr mpd_state state() const;
void emit() const; void emit() const;
[[nodiscard]] unique_connection& connection(); [[nodiscard]] unique_connection& connection();
public: public:

View File

@ -8,11 +8,13 @@ inline bool Context::is_paused() const { return mpd_module_->paused(); }
inline bool Context::is_stopped() const { return mpd_module_->stopped(); } inline bool Context::is_stopped() const { return mpd_module_->stopped(); }
constexpr inline std::size_t Context::interval() const { return mpd_module_->interval_.count(); } constexpr inline std::size_t Context::interval() const { return mpd_module_->interval_.count(); }
inline void Context::tryConnect() const { mpd_module_->tryConnect(); } inline void Context::tryConnect() const { mpd_module_->tryConnect(); }
inline unique_connection& Context::connection() { return mpd_module_->connection_; } inline unique_connection& Context::connection() { return mpd_module_->connection_; }
constexpr inline mpd_state Context::state() const { return mpd_module_->state_; } constexpr inline mpd_state Context::state() const { return mpd_module_->state_; }
inline void Context::do_update() { mpd_module_->setLabel(); } inline void Context::do_update() {
mpd_module_->setLabel();
}
inline void Context::checkErrors(mpd_connection* conn) const { mpd_module_->checkErrors(conn); } inline void Context::checkErrors(mpd_connection* conn) const { mpd_module_->checkErrors(conn); }
inline void Context::queryMPD() const { mpd_module_->queryMPD(); } inline void Context::queryMPD() const { mpd_module_->queryMPD(); }

View File

@ -1,88 +0,0 @@
#pragma once
#include <iostream>
#include <optional>
#include <string>
#include "gtkmm/box.h"
#include "gtkmm/label.h"
extern "C" {
#include <playerctl/playerctl.h>
}
#include "ALabel.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules::mpris {
class Mpris : public ALabel {
public:
Mpris(const std::string&, const Json::Value&);
virtual ~Mpris();
auto update() -> void override;
bool handleToggle(GdkEventButton* const&) override;
private:
static auto onPlayerNameAppeared(PlayerctlPlayerManager*, PlayerctlPlayerName*, gpointer) -> void;
static auto onPlayerNameVanished(PlayerctlPlayerManager*, PlayerctlPlayerName*, gpointer) -> void;
static auto onPlayerPlay(PlayerctlPlayer*, gpointer) -> void;
static auto onPlayerPause(PlayerctlPlayer*, gpointer) -> void;
static auto onPlayerStop(PlayerctlPlayer*, gpointer) -> void;
static auto onPlayerMetadata(PlayerctlPlayer*, GVariant*, gpointer) -> void;
struct PlayerInfo {
std::string name;
PlayerctlPlaybackStatus status;
std::string status_string;
std::optional<std::string> artist;
std::optional<std::string> album;
std::optional<std::string> title;
std::optional<std::string> length; // as HH:MM:SS
std::optional<std::string> position; // same format
};
auto getPlayerInfo() -> std::optional<PlayerInfo>;
auto getIconFromJson(const Json::Value&, const std::string&) -> std::string;
auto getArtistStr(const PlayerInfo&, bool) -> std::string;
auto getAlbumStr(const PlayerInfo&, bool) -> std::string;
auto getTitleStr(const PlayerInfo&, bool) -> std::string;
auto getLengthStr(const PlayerInfo&, bool) -> std::string;
auto getPositionStr(const PlayerInfo&, bool) -> std::string;
auto getDynamicStr(const PlayerInfo&, bool, bool) -> std::string;
// config
std::string format_playing_;
std::string format_paused_;
std::string format_stopped_;
std::string tooltip_;
std::string tooltip_playing_;
std::string tooltip_paused_;
std::string tooltip_stopped_;
int artist_len_;
int album_len_;
int title_len_;
int dynamic_len_;
std::vector<std::string> dynamic_prio_;
std::vector<std::string> dynamic_order_;
std::string dynamic_separator_;
bool truncate_hours_;
bool tooltip_len_limits_;
std::string ellipsis_;
std::string player_;
std::vector<std::string> ignored_players_;
PlayerctlPlayerManager* manager;
PlayerctlPlayer* player;
std::string lastStatus;
std::string lastPlayer;
util::SleeperThread thread_;
std::chrono::time_point<std::chrono::system_clock> last_update_;
};
} // namespace waybar::modules::mpris

View File

@ -7,9 +7,6 @@
#include <netlink/genl/genl.h> #include <netlink/genl/genl.h>
#include <netlink/netlink.h> #include <netlink/netlink.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <optional>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
#ifdef WANT_RFKILL #ifdef WANT_RFKILL
@ -21,8 +18,8 @@ namespace waybar::modules {
class Network : public ALabel { class Network : public ALabel {
public: public:
Network(const std::string&, const Json::Value&); Network(const std::string&, const Json::Value&);
virtual ~Network(); ~Network();
auto update() -> void override; auto update() -> void;
private: private:
static const uint8_t MAX_RETRY = 5; static const uint8_t MAX_RETRY = 5;
@ -34,58 +31,54 @@ class Network : public ALabel {
void askForStateDump(void); void askForStateDump(void);
void worker(); void worker();
void createInfoSocket(); void createInfoSocket();
void createEventSocket(); void createEventSocket();
void parseEssid(struct nlattr**); void parseEssid(struct nlattr**);
void parseSignal(struct nlattr**); void parseSignal(struct nlattr**);
void parseFreq(struct nlattr**); void parseFreq(struct nlattr**);
bool associatedOrJoined(struct nlattr**); bool associatedOrJoined(struct nlattr**);
bool checkInterface(std::string name); bool checkInterface(std::string name);
auto getInfo() -> void; auto getInfo() -> void;
const std::string getNetworkState() const; const std::string getNetworkState() const;
void clearIface(); void clearIface();
bool wildcardMatch(const std::string& pattern, const std::string& text) const; bool wildcardMatch(const std::string& pattern, const std::string& text) const;
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
int ifid_; int ifid_;
sa_family_t family_; sa_family_t family_;
struct sockaddr_nl nladdr_ = {0}; struct sockaddr_nl nladdr_ = {0};
struct nl_sock* sock_ = nullptr; struct nl_sock* sock_ = nullptr;
struct nl_sock* ev_sock_ = nullptr; struct nl_sock* ev_sock_ = nullptr;
int efd_; int efd_;
int ev_fd_; int ev_fd_;
int nl80211_id_; int nl80211_id_;
std::mutex mutex_; std::mutex mutex_;
bool want_route_dump_; bool want_route_dump_;
bool want_link_dump_; bool want_link_dump_;
bool want_addr_dump_; bool want_addr_dump_;
bool dump_in_progress_; bool dump_in_progress_;
bool is_p2p_;
unsigned long long bandwidth_down_total_; unsigned long long bandwidth_down_total_;
unsigned long long bandwidth_up_total_; unsigned long long bandwidth_up_total_;
std::string state_; std::string state_;
std::string essid_; std::string essid_;
bool carrier_; bool carrier_;
std::string ifname_; std::string ifname_;
std::string ipaddr_; std::string ipaddr_;
std::string gwaddr_;
std::string netmask_; std::string netmask_;
int cidr_; int cidr_;
int32_t signal_strength_dbm_; int32_t signal_strength_dbm_;
uint8_t signal_strength_; uint8_t signal_strength_;
std::string signal_strength_app_; uint32_t frequency_;
uint32_t route_priority; uint32_t route_priority;
util::SleeperThread thread_; util::SleeperThread thread_;
util::SleeperThread thread_timer_; util::SleeperThread thread_timer_;
#ifdef WANT_RFKILL #ifdef WANT_RFKILL
util::Rfkill rfkill_; util::Rfkill rfkill_;
#endif #endif
float frequency_;
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -3,10 +3,8 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
#include <pulse/volume.h> #include <pulse/volume.h>
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include "ALabel.hpp" #include "ALabel.hpp"
namespace waybar::modules { namespace waybar::modules {
@ -14,8 +12,8 @@ namespace waybar::modules {
class Pulseaudio : public ALabel { class Pulseaudio : public ALabel {
public: public:
Pulseaudio(const std::string&, const Json::Value&); Pulseaudio(const std::string&, const Json::Value&);
virtual ~Pulseaudio(); ~Pulseaudio();
auto update() -> void override; auto update() -> void;
private: private:
static void subscribeCb(pa_context*, pa_subscription_event_type_t, uint32_t, void*); static void subscribeCb(pa_context*, pa_subscription_event_type_t, uint32_t, void*);
@ -25,27 +23,27 @@ class Pulseaudio : public ALabel {
static void serverInfoCb(pa_context*, const pa_server_info*, void*); static void serverInfoCb(pa_context*, const pa_server_info*, void*);
static void volumeModifyCb(pa_context*, int, void*); static void volumeModifyCb(pa_context*, int, void*);
bool handleScroll(GdkEventScroll* e) override; bool handleScroll(GdkEventScroll* e);
const std::vector<std::string> getPulseIcon() const; const std::vector<std::string> getPulseIcon() const;
pa_threaded_mainloop* mainloop_; pa_threaded_mainloop* mainloop_;
pa_mainloop_api* mainloop_api_; pa_mainloop_api* mainloop_api_;
pa_context* context_; pa_context* context_;
// SINK // SINK
uint32_t sink_idx_{0}; uint32_t sink_idx_{0};
uint16_t volume_; uint16_t volume_;
pa_cvolume pa_volume_; pa_cvolume pa_volume_;
bool muted_; bool muted_;
std::string port_name_; std::string port_name_;
std::string form_factor_; std::string form_factor_;
std::string desc_; std::string desc_;
std::string monitor_; std::string monitor_;
std::string current_sink_name_; std::string current_sink_name_;
bool current_sink_running_; bool current_sink_running_;
// SOURCE // SOURCE
uint32_t source_idx_{0}; uint32_t source_idx_{0};
uint16_t source_volume_; uint16_t source_volume_;
bool source_muted_; bool source_muted_;
std::string source_port_name_; std::string source_port_name_;
std::string source_desc_; std::string source_desc_;
std::string default_source_name_; std::string default_source_name_;

View File

@ -1,33 +0,0 @@
#pragma once
#include <wayland-client.h>
#include "ALabel.hpp"
#include "bar.hpp"
#include "river-status-unstable-v1-client-protocol.h"
namespace waybar::modules::river {
class Layout : public waybar::ALabel {
public:
Layout(const std::string &, const waybar::Bar &, const Json::Value &);
virtual ~Layout();
// Handlers for wayland events
void handle_name(const char *name);
void handle_clear();
void handle_focused_output(struct wl_output *output);
void handle_unfocused_output(struct wl_output *output);
struct zriver_status_manager_v1 *status_manager_;
struct wl_seat *seat_;
private:
const waybar::Bar &bar_;
struct wl_output *output_; // stores the output this module belongs to
struct wl_output *focused_output_; // stores the currently focused output
struct zriver_output_status_v1 *output_status_;
struct zriver_seat_status_v1 *seat_status_;
};
} /* namespace waybar::modules::river */

View File

@ -1,28 +0,0 @@
#pragma once
#include <wayland-client.h>
#include "ALabel.hpp"
#include "bar.hpp"
#include "river-status-unstable-v1-client-protocol.h"
namespace waybar::modules::river {
class Mode : public waybar::ALabel {
public:
Mode(const std::string &, const waybar::Bar &, const Json::Value &);
virtual ~Mode();
// Handlers for wayland events
void handle_mode(const char *mode);
struct zriver_status_manager_v1 *status_manager_;
struct wl_seat *seat_;
private:
const waybar::Bar &bar_;
std::string mode_;
struct zriver_seat_status_v1 *seat_status_;
};
} /* namespace waybar::modules::river */

View File

@ -5,7 +5,6 @@
#include "AModule.hpp" #include "AModule.hpp"
#include "bar.hpp" #include "bar.hpp"
#include "river-control-unstable-v1-client-protocol.h"
#include "river-status-unstable-v1-client-protocol.h" #include "river-status-unstable-v1-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h" #include "xdg-output-unstable-v1-client-protocol.h"
@ -14,23 +13,17 @@ namespace waybar::modules::river {
class Tags : public waybar::AModule { class Tags : public waybar::AModule {
public: public:
Tags(const std::string &, const waybar::Bar &, const Json::Value &); Tags(const std::string &, const waybar::Bar &, const Json::Value &);
virtual ~Tags(); ~Tags();
// Handlers for wayland events // Handlers for wayland events
void handle_focused_tags(uint32_t tags); void handle_focused_tags(uint32_t tags);
void handle_view_tags(struct wl_array *tags); void handle_view_tags(struct wl_array *tags);
void handle_urgent_tags(uint32_t tags);
void handle_primary_clicked(uint32_t tag);
bool handle_button_press(GdkEventButton *event_button, uint32_t tag);
struct zriver_status_manager_v1 *status_manager_; struct zriver_status_manager_v1 *status_manager_;
struct zriver_control_v1 *control_;
struct wl_seat *seat_;
private: private:
const waybar::Bar &bar_; const waybar::Bar & bar_;
Gtk::Box box_; Gtk::Box box_;
std::vector<Gtk::Button> buttons_; std::vector<Gtk::Button> buttons_;
struct zriver_output_status_v1 *output_status_; struct zriver_output_status_v1 *output_status_;
}; };

View File

@ -1,33 +0,0 @@
#pragma once
#include <gtkmm/button.h>
#include <wayland-client.h>
#include "ALabel.hpp"
#include "bar.hpp"
#include "river-status-unstable-v1-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h"
namespace waybar::modules::river {
class Window : public waybar::ALabel {
public:
Window(const std::string &, const waybar::Bar &, const Json::Value &);
virtual ~Window();
// Handlers for wayland events
void handle_focused_view(const char *title);
void handle_focused_output(struct wl_output *output);
void handle_unfocused_output(struct wl_output *output);
struct zriver_status_manager_v1 *status_manager_;
struct wl_seat *seat_;
private:
const waybar::Bar &bar_;
struct wl_output *output_; // stores the output this module belongs to
struct wl_output *focused_output_; // stores the currently focused output
struct zriver_seat_status_v1 *seat_status_;
};
} /* namespace waybar::modules::river */

View File

@ -1,7 +1,11 @@
#pragma once #pragma once
#include <fmt/format.h>
#if FMT_VERSION < 60000
#include <fmt/time.h>
#else
#include <fmt/chrono.h> #include <fmt/chrono.h>
#endif
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
@ -10,8 +14,8 @@ namespace waybar::modules {
class Clock : public ALabel { class Clock : public ALabel {
public: public:
Clock(const std::string&, const Json::Value&); Clock(const std::string&, const Json::Value&);
virtual ~Clock() = default; ~Clock() = default;
auto update() -> void override; auto update() -> void;
private: private:
util::SleeperThread thread_; util::SleeperThread thread_;

View File

@ -1,9 +1,7 @@
#pragma once #pragma once
#include <sndio.h> #include <sndio.h>
#include <vector> #include <vector>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
@ -11,13 +9,13 @@ namespace waybar::modules {
class Sndio : public ALabel { class Sndio : public ALabel {
public: public:
Sndio(const std::string &, const Json::Value &); Sndio(const std::string&, const Json::Value&);
virtual ~Sndio(); ~Sndio();
auto update() -> void override; auto update() -> void;
auto set_desc(struct sioctl_desc *, unsigned int) -> void; auto set_desc(struct sioctl_desc *, unsigned int) -> void;
auto put_val(unsigned int, unsigned int) -> void; auto put_val(unsigned int, unsigned int) -> void;
bool handleScroll(GdkEventScroll *) override; bool handleScroll(GdkEventScroll *);
bool handleToggle(GdkEventButton *const &) override; bool handleToggle(GdkEventButton* const&);
private: private:
auto connect_to_sndio() -> void; auto connect_to_sndio() -> void;

View File

@ -4,43 +4,38 @@
#include <giomm.h> #include <giomm.h>
#include <glibmm/refptr.h> #include <glibmm/refptr.h>
#include <json/json.h> #include <json/json.h>
#include <tuple> #include <tuple>
#include "bar.hpp"
#include "modules/sni/item.hpp" #include "modules/sni/item.hpp"
namespace waybar::modules::SNI { namespace waybar::modules::SNI {
class Host { class Host {
public: public:
Host(const std::size_t id, const Json::Value&, const Bar&, Host(const std::size_t id, const Json::Value&, const std::function<void(std::unique_ptr<Item>&)>&,
const std::function<void(std::unique_ptr<Item>&)>&,
const std::function<void(std::unique_ptr<Item>&)>&); const std::function<void(std::unique_ptr<Item>&)>&);
~Host(); ~Host();
private: private:
void busAcquired(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring); void busAcquired(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring);
void nameAppeared(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring, void nameAppeared(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring,
const Glib::ustring&); const Glib::ustring&);
void nameVanished(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring); void nameVanished(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring);
static void proxyReady(GObject*, GAsyncResult*, gpointer); static void proxyReady(GObject*, GAsyncResult*, gpointer);
static void registerHost(GObject*, GAsyncResult*, gpointer); static void registerHost(GObject*, GAsyncResult*, gpointer);
static void itemRegistered(SnWatcher*, const gchar*, gpointer); static void itemRegistered(SnWatcher*, const gchar*, gpointer);
static void itemUnregistered(SnWatcher*, const gchar*, gpointer); static void itemUnregistered(SnWatcher*, const gchar*, gpointer);
std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string); std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string);
void addRegisteredItem(std::string service); void addRegisteredItem(std::string service);
std::vector<std::unique_ptr<Item>> items_; std::vector<std::unique_ptr<Item>> items_;
const std::string bus_name_; const std::string bus_name_;
const std::string object_path_; const std::string object_path_;
std::size_t bus_name_id_; std::size_t bus_name_id_;
std::size_t watcher_id_; std::size_t watcher_id_;
GCancellable* cancellable_ = nullptr; GCancellable* cancellable_ = nullptr;
SnWatcher* watcher_ = nullptr; SnWatcher* watcher_ = nullptr;
const Json::Value& config_; const Json::Value& config_;
const Bar& bar_;
const std::function<void(std::unique_ptr<Item>&)> on_add_; const std::function<void(std::unique_ptr<Item>&)> on_add_;
const std::function<void(std::unique_ptr<Item>&)> on_remove_; const std::function<void(std::unique_ptr<Item>&)> on_remove_;
}; };

View File

@ -14,8 +14,6 @@
#include <set> #include <set>
#include <string_view> #include <string_view>
#include "bar.hpp"
namespace waybar::modules::SNI { namespace waybar::modules::SNI {
struct ToolTip { struct ToolTip {
@ -25,31 +23,31 @@ struct ToolTip {
class Item : public sigc::trackable { class Item : public sigc::trackable {
public: public:
Item(const std::string&, const std::string&, const Json::Value&, const Bar&); Item(const std::string&, const std::string&, const Json::Value&);
~Item() = default; ~Item() = default;
std::string bus_name; std::string bus_name;
std::string object_path; std::string object_path;
int icon_size; int icon_size;
int effective_icon_size; int effective_icon_size;
Gtk::Image image; Gtk::Image image;
Gtk::EventBox event_box; Gtk::EventBox event_box;
std::string category; std::string category;
std::string id; std::string id;
std::string title; std::string title;
std::string icon_name; std::string icon_name;
Glib::RefPtr<Gdk::Pixbuf> icon_pixmap; Glib::RefPtr<Gdk::Pixbuf> icon_pixmap;
Glib::RefPtr<Gtk::IconTheme> icon_theme; Glib::RefPtr<Gtk::IconTheme> icon_theme;
std::string overlay_icon_name; std::string overlay_icon_name;
std::string attention_icon_name; std::string attention_icon_name;
std::string attention_movie_name; std::string attention_movie_name;
std::string icon_theme_path; std::string icon_theme_path;
std::string menu; std::string menu;
ToolTip tooltip; ToolTip tooltip;
DbusmenuGtkMenu* dbus_menu = nullptr; DbusmenuGtkMenu* dbus_menu = nullptr;
Gtk::Menu* gtk_menu = nullptr; Gtk::Menu* gtk_menu = nullptr;
/** /**
* ItemIsMenu flag means that the item only supports the context menu. * ItemIsMenu flag means that the item only supports the context menu.
* Default value is true because libappindicator supports neither ItemIsMenu nor Activate method * Default value is true because libappindicator supports neither ItemIsMenu nor Activate method
@ -58,7 +56,6 @@ class Item : public sigc::trackable {
bool item_is_menu = true; bool item_is_menu = true;
private: private:
void onConfigure(GdkEventConfigure* ev);
void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result); void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result);
void setProperty(const Glib::ustring& name, Glib::VariantBase& value); void setProperty(const Glib::ustring& name, Glib::VariantBase& value);
void setStatus(const Glib::ustring& value); void setStatus(const Glib::ustring& value);
@ -67,15 +64,15 @@ class Item : public sigc::trackable {
void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name, void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
const Glib::VariantContainerBase& arguments); const Glib::VariantContainerBase& arguments);
void updateImage(); void updateImage();
Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant); Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant);
Glib::RefPtr<Gdk::Pixbuf> getIconPixbuf(); Glib::RefPtr<Gdk::Pixbuf> getIconPixbuf();
Glib::RefPtr<Gdk::Pixbuf> getIconByName(const std::string& name, int size); Glib::RefPtr<Gdk::Pixbuf> getIconByName(const std::string& name, int size);
double getScaledIconSize(); double getScaledIconSize();
static void onMenuDestroyed(Item* self, GObject* old_menu_pointer); static void onMenuDestroyed(Item* self, GObject* old_menu_pointer);
void makeMenu(); void makeMenu();
bool handleClick(GdkEventButton* const& /*ev*/); bool handleClick(GdkEventButton* const& /*ev*/);
bool handleScroll(GdkEventScroll* const&); bool handleScroll(GdkEventScroll* const&);
// smooth scrolling threshold // smooth scrolling threshold
gdouble scroll_threshold_ = 0; gdouble scroll_threshold_ = 0;
@ -86,7 +83,7 @@ class Item : public sigc::trackable {
Glib::RefPtr<Gio::DBus::Proxy> proxy_; Glib::RefPtr<Gio::DBus::Proxy> proxy_;
Glib::RefPtr<Gio::Cancellable> cancellable_; Glib::RefPtr<Gio::Cancellable> cancellable_;
std::set<std::string_view> update_pending_; std::set<std::string_view> update_pending_;
}; };
} // namespace waybar::modules::SNI } // namespace waybar::modules::SNI

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include "AModule.hpp" #include "AModule.hpp"
#include "bar.hpp" #include "bar.hpp"
#include "modules/sni/host.hpp" #include "modules/sni/host.hpp"
@ -13,17 +12,17 @@ namespace waybar::modules::SNI {
class Tray : public AModule { class Tray : public AModule {
public: public:
Tray(const std::string&, const Bar&, const Json::Value&); Tray(const std::string&, const Bar&, const Json::Value&);
virtual ~Tray() = default; ~Tray() = default;
auto update() -> void override; auto update() -> void;
private: private:
void onAdd(std::unique_ptr<Item>& item); void onAdd(std::unique_ptr<Item>& item);
void onRemove(std::unique_ptr<Item>& item); void onRemove(std::unique_ptr<Item>& item);
static inline std::size_t nb_hosts_ = 0; static inline std::size_t nb_hosts_ = 0;
Gtk::Box box_; Gtk::Box box_;
SNI::Watcher::singleton watcher_; SNI::Watcher::singleton watcher_;
SNI::Host host_; SNI::Host host_;
}; };
} // namespace waybar::modules::SNI } // namespace waybar::modules::SNI

View File

@ -30,26 +30,26 @@ class Watcher {
typedef struct { typedef struct {
GfWatchType type; GfWatchType type;
Watcher *watcher; Watcher * watcher;
gchar *service; gchar * service;
gchar *bus_name; gchar * bus_name;
gchar *object_path; gchar * object_path;
guint watch_id; guint watch_id;
} GfWatch; } GfWatch;
void busAcquired(const Glib::RefPtr<Gio::DBus::Connection> &, Glib::ustring); void busAcquired(const Glib::RefPtr<Gio::DBus::Connection> &, Glib::ustring);
static gboolean handleRegisterHost(Watcher *, GDBusMethodInvocation *, const gchar *); static gboolean handleRegisterHost(Watcher *, GDBusMethodInvocation *, const gchar *);
static gboolean handleRegisterItem(Watcher *, GDBusMethodInvocation *, const gchar *); static gboolean handleRegisterItem(Watcher *, GDBusMethodInvocation *, const gchar *);
static GfWatch *gfWatchFind(GSList *list, const gchar *bus_name, const gchar *object_path); static GfWatch *gfWatchFind(GSList *list, const gchar *bus_name, const gchar *object_path);
static GfWatch *gfWatchNew(GfWatchType, const gchar *, const gchar *, const gchar *, Watcher *); static GfWatch *gfWatchNew(GfWatchType, const gchar *, const gchar *, const gchar *, Watcher *);
static void nameVanished(GDBusConnection *connection, const char *name, gpointer data); static void nameVanished(GDBusConnection *connection, const char *name, gpointer data);
static void gfWatchFree(gpointer data); static void gfWatchFree(gpointer data);
void updateRegisteredItems(SnWatcher *obj); void updateRegisteredItems(SnWatcher *obj);
uint32_t bus_name_id_; uint32_t bus_name_id_;
GSList *hosts_ = nullptr; GSList * hosts_ = nullptr;
GSList *items_ = nullptr; GSList * items_ = nullptr;
SnWatcher *watcher_ = nullptr; SnWatcher *watcher_ = nullptr;
}; };

View File

@ -1,60 +0,0 @@
#pragma once
#include <atomic>
#include <string>
#include "modules/sway/ipc/client.hpp"
#include "util/SafeSignal.hpp"
#include "util/json.hpp"
namespace waybar {
class Bar;
namespace modules::sway {
/*
* Supported subset of i3/sway IPC barconfig object
*/
struct swaybar_config {
std::string id;
std::string mode;
std::string hidden_state;
};
/**
* swaybar IPC client
*/
class BarIpcClient {
public:
BarIpcClient(waybar::Bar& bar);
private:
void onInitialConfig(const struct Ipc::ipc_response& res);
void onIpcEvent(const struct Ipc::ipc_response&);
void onCmd(const struct Ipc::ipc_response&);
void onConfigUpdate(const swaybar_config& config);
void onVisibilityUpdate(bool visible_by_modifier);
void onModeUpdate(bool visible_by_modifier);
void onUrgencyUpdate(bool visible_by_urgency);
void update();
bool isModuleEnabled(std::string name);
Bar& bar_;
util::JsonParser parser_;
Ipc ipc_;
swaybar_config bar_config_;
std::string modifier_reset_;
bool visible_by_mode_ = false;
bool visible_by_modifier_ = false;
bool visible_by_urgency_ = false;
std::atomic<bool> modifier_no_action_ = false;
SafeSignal<bool> signal_mode_;
SafeSignal<bool> signal_visible_;
SafeSignal<bool> signal_urgency_;
SafeSignal<swaybar_config> signal_config_;
};
} // namespace modules::sway
} // namespace waybar

View File

@ -4,13 +4,9 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <stdexcept>
#include <string>
#include "ipc.hpp" #include "ipc.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
@ -22,8 +18,8 @@ class Ipc {
~Ipc(); ~Ipc();
struct ipc_response { struct ipc_response {
uint32_t size; uint32_t size;
uint32_t type; uint32_t type;
std::string payload; std::string payload;
}; };
@ -37,16 +33,16 @@ class Ipc {
protected: protected:
static inline const std::string ipc_magic_ = "i3-ipc"; static inline const std::string ipc_magic_ = "i3-ipc";
static inline const size_t ipc_header_size_ = ipc_magic_.size() + 8; static inline const size_t ipc_header_size_ = ipc_magic_.size() + 8;
const std::string getSocketPath() const; const std::string getSocketPath() const;
int open(const std::string &) const; int open(const std::string &) const;
struct ipc_response send(int fd, uint32_t type, const std::string &payload = ""); struct ipc_response send(int fd, uint32_t type, const std::string &payload = "");
struct ipc_response recv(int fd); struct ipc_response recv(int fd);
int fd_; int fd_;
int fd_event_; int fd_event_;
std::mutex mutex_; std::mutex mutex_;
util::SleeperThread thread_; util::SleeperThread thread_;
}; };

View File

@ -1,10 +1,8 @@
#pragma once #pragma once
#include <cstdint>
#define event_mask(ev) (1u << (ev & 0x7F)) #define event_mask(ev) (1u << (ev & 0x7F))
enum ipc_command_type : uint32_t { enum ipc_command_type {
// i3 command types - see i3's I3_REPLY_TYPE constants // i3 command types - see i3's I3_REPLY_TYPE constants
IPC_COMMAND = 0, IPC_COMMAND = 0,
IPC_GET_WORKSPACES = 1, IPC_GET_WORKSPACES = 1,
@ -23,16 +21,16 @@ enum ipc_command_type : uint32_t {
IPC_GET_SEATS = 101, IPC_GET_SEATS = 101,
// Events sent from sway to clients. Events have the highest bits set. // Events sent from sway to clients. Events have the highest bits set.
IPC_EVENT_WORKSPACE = ((1U << 31) | 0), IPC_EVENT_WORKSPACE = ((1 << 31) | 0),
IPC_EVENT_OUTPUT = ((1U << 31) | 1), IPC_EVENT_OUTPUT = ((1 << 31) | 1),
IPC_EVENT_MODE = ((1U << 31) | 2), IPC_EVENT_MODE = ((1 << 31) | 2),
IPC_EVENT_WINDOW = ((1U << 31) | 3), IPC_EVENT_WINDOW = ((1 << 31) | 3),
IPC_EVENT_BARCONFIG_UPDATE = ((1U << 31) | 4), IPC_EVENT_BARCONFIG_UPDATE = ((1 << 31) | 4),
IPC_EVENT_BINDING = ((1U << 31) | 5), IPC_EVENT_BINDING = ((1 << 31) | 5),
IPC_EVENT_SHUTDOWN = ((1U << 31) | 6), IPC_EVENT_SHUTDOWN = ((1 << 31) | 6),
IPC_EVENT_TICK = ((1U << 31) | 7), IPC_EVENT_TICK = ((1 << 31) | 7),
// sway-specific event types // sway-specific event types
IPC_EVENT_BAR_STATE_UPDATE = ((1U << 31) | 20), IPC_EVENT_BAR_STATE_UPDATE = ((1<<31) | 20),
IPC_EVENT_INPUT = ((1U << 31) | 21), IPC_EVENT_INPUT = ((1<<31) | 21),
}; };

View File

@ -17,31 +17,25 @@ namespace waybar::modules::sway {
class Language : public ALabel, public sigc::trackable { class Language : public ALabel, public sigc::trackable {
public: public:
Language(const std::string& id, const Json::Value& config); Language(const std::string& id, const Json::Value& config);
virtual ~Language() = default; ~Language() = default;
auto update() -> void override; auto update() -> void;
private: private:
enum class DispayedShortFlag { None = 0, ShortName = 1, ShortDescription = 1 << 1 };
struct Layout { struct Layout {
std::string full_name; std::string full_name;
std::string short_name; std::string short_name;
std::string variant; std::string variant;
std::string short_description;
std::string country_flag() const;
}; };
class XKBContext { class XKBContext {
public: public:
XKBContext(); XKBContext();
~XKBContext(); ~XKBContext();
auto next_layout() -> Layout*; auto next_layout() -> Layout*;
private: private:
rxkb_context* context_ = nullptr; rxkb_context* context_ = nullptr;
rxkb_layout* xkb_layout_ = nullptr; rxkb_layout* xkb_layout_ = nullptr;
Layout* layout_ = nullptr; Layout* layout_ = nullptr;
std::map<std::string, rxkb_layout*> base_layouts_by_name_;
}; };
void onEvent(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&);
@ -53,15 +47,15 @@ class Language : public ALabel, public sigc::trackable {
const static std::string XKB_LAYOUT_NAMES_KEY; const static std::string XKB_LAYOUT_NAMES_KEY;
const static std::string XKB_ACTIVE_LAYOUT_NAME_KEY; const static std::string XKB_ACTIVE_LAYOUT_NAME_KEY;
Layout layout_; Layout layout_;
std::string tooltip_format_ = ""; std::string tooltip_format_ = "";
std::map<std::string, Layout> layouts_map_; std::map<std::string, Layout> layouts_map_;
XKBContext xkb_context_;
bool is_variant_displayed; bool is_variant_displayed;
std::byte displayed_short_flag = static_cast<std::byte>(DispayedShortFlag::None);
util::JsonParser parser_; util::JsonParser parser_;
std::mutex mutex_; std::mutex mutex_;
Ipc ipc_; Ipc ipc_;
}; };
} // namespace waybar::modules::sway } // namespace waybar::modules::sway

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "bar.hpp" #include "bar.hpp"
#include "client.hpp" #include "client.hpp"
@ -13,16 +12,16 @@ namespace waybar::modules::sway {
class Mode : public ALabel, public sigc::trackable { class Mode : public ALabel, public sigc::trackable {
public: public:
Mode(const std::string&, const Json::Value&); Mode(const std::string&, const Json::Value&);
virtual ~Mode() = default; ~Mode() = default;
auto update() -> void override; auto update() -> void;
private: private:
void onEvent(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&);
std::string mode_; std::string mode_;
util::JsonParser parser_; util::JsonParser parser_;
std::mutex mutex_; std::mutex mutex_;
Ipc ipc_; Ipc ipc_;
}; };
} // namespace waybar::modules::sway } // namespace waybar::modules::sway

View File

@ -1,35 +0,0 @@
#pragma once
#include <gtkmm/label.h>
#include <mutex>
#include <string>
#include "ALabel.hpp"
#include "bar.hpp"
#include "client.hpp"
#include "modules/sway/ipc/client.hpp"
#include "util/json.hpp"
namespace waybar::modules::sway {
class Scratchpad : public ALabel {
public:
Scratchpad(const std::string&, const Json::Value&);
virtual ~Scratchpad() = default;
auto update() -> void override;
private:
auto getTree() -> void;
auto onCmd(const struct Ipc::ipc_response&) -> void;
auto onEvent(const struct Ipc::ipc_response&) -> void;
std::string tooltip_format_;
bool show_empty_;
bool tooltip_enabled_;
std::string tooltip_text_;
int count_;
std::mutex mutex_;
Ipc ipc_;
util::JsonParser parser_;
};
} // namespace waybar::modules::sway

View File

@ -1,10 +1,8 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include <tuple> #include <tuple>
#include "ALabel.hpp"
#include "AAppIconLabel.hpp"
#include "bar.hpp" #include "bar.hpp"
#include "client.hpp" #include "client.hpp"
#include "modules/sway/ipc/client.hpp" #include "modules/sway/ipc/client.hpp"
@ -12,33 +10,29 @@
namespace waybar::modules::sway { namespace waybar::modules::sway {
class Window : public AAppIconLabel, public sigc::trackable { class Window : public ALabel, public sigc::trackable {
public: public:
Window(const std::string&, const waybar::Bar&, const Json::Value&); Window(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Window() = default; ~Window() = default;
auto update() -> void override; auto update() -> void;
private: private:
void setClass(std::string classname, bool enable); void onEvent(const struct Ipc::ipc_response&);
void onEvent(const struct Ipc::ipc_response&); void onCmd(const struct Ipc::ipc_response&);
void onCmd(const struct Ipc::ipc_response&); std::tuple<std::size_t, int, std::string, std::string> getFocusedNode(const Json::Value& nodes,
std::tuple<std::size_t, int, int, std::string, std::string, std::string, std::string, std::string> std::string& output);
getFocusedNode(const Json::Value& nodes, std::string& output); void getTree();
void getTree(); std::string rewriteTitle(const std::string& title);
const Bar& bar_; const Bar& bar_;
std::string window_; std::string window_;
int windowId_; int windowId_;
std::string app_id_; std::string app_id_;
std::string app_class_; std::string old_app_id_;
std::string layout_; std::size_t app_nb_;
std::string old_app_id_;
std::size_t app_nb_;
std::string shell_;
int floating_count_;
util::JsonParser parser_; util::JsonParser parser_;
std::mutex mutex_; std::mutex mutex_;
Ipc ipc_; Ipc ipc_;
}; };
} // namespace waybar::modules::sway } // namespace waybar::modules::sway

View File

@ -1,12 +1,10 @@
#pragma once #pragma once
#include <unordered_map>
#include <fmt/format.h> #include <fmt/format.h>
#include <gtkmm/button.h> #include <gtkmm/button.h>
#include <gtkmm/label.h> #include <gtkmm/label.h>
#include <string_view>
#include <unordered_map> #include <unordered_map>
#include "AModule.hpp" #include "AModule.hpp"
#include "bar.hpp" #include "bar.hpp"
#include "client.hpp" #include "client.hpp"
@ -18,36 +16,33 @@ namespace waybar::modules::sway {
class Workspaces : public AModule, public sigc::trackable { class Workspaces : public AModule, public sigc::trackable {
public: public:
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&); Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Workspaces() = default; ~Workspaces() = default;
auto update() -> void override; auto update() -> void;
private: private:
static constexpr std::string_view workspace_switch_cmd_ = "workspace {} \"{}\""; static inline const std::string workspace_switch_cmd_ = "workspace {} \"{}\"";
static constexpr std::string_view persistent_workspace_switch_cmd_ =
R"(workspace {} "{}"; move workspace to output "{}"; workspace {} "{}")";
static int convertWorkspaceNameToNum(std::string name); static int convertWorkspaceNameToNum(std::string name);
void onCmd(const struct Ipc::ipc_response&); void onCmd(const struct Ipc::ipc_response&);
void onEvent(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&);
bool filterButtons(); bool filterButtons();
Gtk::Button& addButton(const Json::Value&); Gtk::Button& addButton(const Json::Value&);
void onButtonReady(const Json::Value&, Gtk::Button&); void onButtonReady(const Json::Value&, Gtk::Button&);
std::string getIcon(const std::string&, const Json::Value&); std::string getIcon(const std::string&, const Json::Value&);
const std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const; const std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const;
uint16_t getWorkspaceIndex(const std::string& name) const; uint16_t getWorkspaceIndex(const std::string& name) const;
std::string trimWorkspaceName(std::string); std::string trimWorkspaceName(std::string);
bool handleScroll(GdkEventScroll*) override; bool handleScroll(GdkEventScroll*);
const Bar& bar_; const Bar& bar_;
std::vector<Json::Value> workspaces_; std::vector<Json::Value> workspaces_;
std::vector<std::string> high_priority_named_; std::vector<std::string> workspaces_order_;
std::vector<std::string> workspaces_order_; Gtk::Box box_;
Gtk::Box box_; util::JsonParser parser_;
util::JsonParser parser_;
std::unordered_map<std::string, Gtk::Button> buttons_; std::unordered_map<std::string, Gtk::Button> buttons_;
std::mutex mutex_; std::mutex mutex_;
Ipc ipc_; Ipc ipc_;
}; };
} // namespace waybar::modules::sway } // namespace waybar::modules::sway

View File

@ -1,9 +1,7 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include <fstream> #include <fstream>
#include "ALabel.hpp" #include "ALabel.hpp"
#include "util/sleeper_thread.hpp" #include "util/sleeper_thread.hpp"
@ -12,14 +10,14 @@ namespace waybar::modules {
class Temperature : public ALabel { class Temperature : public ALabel {
public: public:
Temperature(const std::string&, const Json::Value&); Temperature(const std::string&, const Json::Value&);
virtual ~Temperature() = default; ~Temperature() = default;
auto update() -> void override; auto update() -> void;
private: private:
float getTemperature(); float getTemperature();
bool isCritical(uint16_t); bool isCritical(uint16_t);
std::string file_path_; std::string file_path_;
util::SleeperThread thread_; util::SleeperThread thread_;
}; };

View File

@ -1,80 +0,0 @@
#pragma once
#include <libupower-glib/upower.h>
#include <iostream>
#include <map>
#include <string>
#include <unordered_map>
#include "ALabel.hpp"
#include "glibconfig.h"
#include "gtkmm/box.h"
#include "gtkmm/image.h"
#include "gtkmm/label.h"
#include "modules/upower/upower_tooltip.hpp"
namespace waybar::modules::upower {
class UPower : public AModule {
public:
UPower(const std::string &, const Json::Value &);
virtual ~UPower();
auto update() -> void override;
private:
typedef std::unordered_map<std::string, UpDevice *> Devices;
const std::string DEFAULT_FORMAT = "{percentage}";
const std::string DEFAULT_FORMAT_ALT = "{percentage} {time}";
static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data);
static void deviceRemoved_cb(UpClient *client, const gchar *objectPath, gpointer data);
static void deviceNotify_cb(UpDevice *device, GParamSpec *pspec, gpointer user_data);
static void prepareForSleep_cb(GDBusConnection *system_bus, const gchar *sender_name,
const gchar *object_path, const gchar *interface_name,
const gchar *signal_name, GVariant *parameters,
gpointer user_data);
static void upowerAppear(GDBusConnection *conn, const gchar *name, const gchar *name_owner,
gpointer data);
static void upowerDisappear(GDBusConnection *connection, const gchar *name, gpointer user_data);
void removeDevice(const gchar *objectPath);
void addDevice(UpDevice *device);
void setDisplayDevice();
void resetDevices();
void removeDevices();
bool show_tooltip_callback(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &tooltip);
bool handleToggle(GdkEventButton *const &) override;
std::string timeToString(gint64 time);
const std::string getDeviceStatus(UpDeviceState &state);
Gtk::Box box_;
Gtk::Image icon_;
Gtk::Label label_;
// Config
bool hideIfEmpty = true;
bool tooltip_enabled = true;
uint tooltip_spacing = 4;
uint tooltip_padding = 4;
uint iconSize = 20;
std::string format = DEFAULT_FORMAT;
std::string format_alt = DEFAULT_FORMAT_ALT;
Devices devices;
std::mutex m_Mutex;
UpClient *client;
UpDevice *displayDevice;
guint login1_id;
GDBusConnection *login1_connection;
UPowerTooltip *upower_tooltip;
std::string lastStatus;
bool showAltText;
bool upowerRunning;
guint upowerWatcher_id;
std::string nativePath_;
};
} // namespace waybar::modules::upower

View File

@ -1,32 +0,0 @@
#pragma once
#include <libupower-glib/upower.h>
#include <unordered_map>
#include "gtkmm/box.h"
#include "gtkmm/label.h"
#include "gtkmm/window.h"
namespace waybar::modules::upower {
class UPowerTooltip : public Gtk::Window {
private:
typedef std::unordered_map<std::string, UpDevice*> Devices;
const std::string getDeviceIcon(UpDeviceKind& kind);
Gtk::Box* contentBox;
uint iconSize;
uint tooltipSpacing;
uint tooltipPadding;
public:
UPowerTooltip(uint iconSize, uint tooltipSpacing, uint tooltipPadding);
virtual ~UPowerTooltip();
uint updateTooltip(Devices& devices);
};
} // namespace waybar::modules::upower

View File

@ -1,34 +0,0 @@
#pragma once
#include <fmt/chrono.h>
#include <gdkmm/pixbuf.h>
#include <glibmm/refptr.h>
#include "AIconLabel.hpp"
#include "util/sleeper_thread.hpp"
namespace waybar::modules {
class User : public AIconLabel {
public:
User(const std::string&, const Json::Value&);
virtual ~User() = default;
auto update() -> void override;
bool handleToggle(GdkEventButton* const& e) override;
private:
util::SleeperThread thread_;
static constexpr inline int defaultUserImageWidth_ = 20;
static constexpr inline int defaultUserImageHeight_ = 20;
long uptime_as_seconds();
std::string get_user_login() const;
std::string get_user_home_dir() const;
std::string get_default_user_avatar_path() const;
void init_default_user_avatar(int width, int height);
void init_user_avatar(const std::string& path, int width, int height);
void init_avatar(const Json::Value& config);
void init_update_worker();
};
} // namespace waybar::modules

View File

@ -1,46 +0,0 @@
#pragma once
#include <fmt/format.h>
#include <wp/wp.h>
#include <algorithm>
#include <array>
#include "ALabel.hpp"
namespace waybar::modules {
class Wireplumber : public ALabel {
public:
Wireplumber(const std::string&, const Json::Value&);
virtual ~Wireplumber();
auto update() -> void override;
private:
void loadRequiredApiModules();
void prepare();
void activatePlugins();
static void updateVolume(waybar::modules::Wireplumber* self, uint32_t id);
static void updateNodeName(waybar::modules::Wireplumber* self, uint32_t id);
static void onPluginActivated(WpObject* p, GAsyncResult* res, waybar::modules::Wireplumber* self);
static void onObjectManagerInstalled(waybar::modules::Wireplumber* self);
static void onMixerChanged(waybar::modules::Wireplumber* self, uint32_t id);
static void onDefaultNodesApiChanged(waybar::modules::Wireplumber* self);
bool handleScroll(GdkEventScroll* e) override;
WpCore* wp_core_;
GPtrArray* apis_;
WpObjectManager* om_;
WpPlugin* mixer_api_;
WpPlugin* def_nodes_api_;
gchar* default_node_name_;
uint32_t pending_plugins_;
bool muted_;
double volume_;
double min_step_;
uint32_t node_id_{0};
std::string node_name_;
};
} // namespace waybar::modules

View File

@ -1,179 +1,164 @@
#pragma once #pragma once
#include <gdk/gdk.h>
#include <glibmm/refptr.h>
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/icontheme.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>
#include <wayland-client.h>
#include <map>
#include <memory>
#include <string>
#include <unordered_set>
#include <vector>
#include "AModule.hpp" #include "AModule.hpp"
#include "bar.hpp" #include "bar.hpp"
#include "client.hpp" #include "client.hpp"
#include "giomm/desktopappinfo.h"
#include "util/json.hpp" #include "util/json.hpp"
#include <memory>
#include <string>
#include <vector>
#include <unordered_set>
#include <gdk/gdk.h>
#include <glibmm/refptr.h>
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>
#include <gtkmm/icontheme.h>
#include <wayland-client.h>
#include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h" #include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
namespace waybar::modules::wlr { namespace waybar::modules::wlr {
class Taskbar; class Taskbar;
class Task { class Task
public: {
Task(const waybar::Bar &, const Json::Value &, Taskbar *, public:
struct zwlr_foreign_toplevel_handle_v1 *, struct wl_seat *); Task(const waybar::Bar&, const Json::Value&, Taskbar*,
~Task(); struct zwlr_foreign_toplevel_handle_v1 *, struct wl_seat*);
~Task();
public: public:
enum State { enum State {
MAXIMIZED = (1 << 0), MAXIMIZED = (1 << 0),
MINIMIZED = (1 << 1), MINIMIZED = (1 << 1),
ACTIVE = (1 << 2), ACTIVE = (1 << 2),
FULLSCREEN = (1 << 3), FULLSCREEN = (1 << 3),
INVALID = (1 << 4) INVALID = (1 << 4)
}; };
// made public so TaskBar can reorder based on configuration.
Gtk::Button button;
private: private:
static uint32_t global_id; static uint32_t global_id;
private: private:
const waybar::Bar &bar_; const waybar::Bar &bar_;
const Json::Value &config_; const Json::Value &config_;
Taskbar *tbar_; Taskbar *tbar_;
struct zwlr_foreign_toplevel_handle_v1 *handle_; struct zwlr_foreign_toplevel_handle_v1 *handle_;
struct wl_seat *seat_; struct wl_seat *seat_;
uint32_t id_; uint32_t id_;
Gtk::Box content_; Gtk::Button button_;
Gtk::Image icon_; Gtk::Box content_;
Gtk::Label text_before_; Gtk::Image icon_;
Gtk::Label text_after_; Gtk::Label text_before_;
Glib::RefPtr<Gio::DesktopAppInfo> app_info_; Gtk::Label text_after_;
bool button_visible_ = false; bool button_visible_;
bool ignored_ = false; bool ignored_;
bool with_icon_ = false; bool with_icon_;
bool with_name_ = false; std::string format_before_;
std::string format_before_; std::string format_after_;
std::string format_after_;
std::string format_tooltip_; std::string format_tooltip_;
std::string name_; std::string title_;
std::string title_; std::string app_id_;
std::string app_id_; uint32_t state_ = 0;
uint32_t state_ = 0;
int32_t drag_start_x; private:
int32_t drag_start_y; std::string repr() const;
int32_t drag_start_button = -1; std::string state_string(bool = false) const;
private: public:
std::string repr() const; /* Getter functions */
std::string state_string(bool = false) const; uint32_t id() const { return id_; }
void set_app_info_from_app_id_list(const std::string &app_id_list); std::string title() const { return title_; }
bool image_load_icon(Gtk::Image &image, const Glib::RefPtr<Gtk::IconTheme> &icon_theme, std::string app_id() const { return app_id_; }
Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size); uint32_t state() const { return state_; }
void hide_if_ignored(); bool maximized() const { return state_ & MAXIMIZED; }
bool minimized() const { return state_ & MINIMIZED; }
bool active() const { return state_ & ACTIVE; }
bool fullscreen() const { return state_ & FULLSCREEN; }
public: public:
/* Getter functions */ /* Callbacks for the wlr protocol */
uint32_t id() const { return id_; } void handle_title(const char *);
std::string title() const { return title_; } void handle_app_id(const char *);
std::string app_id() const { return app_id_; } void handle_output_enter(struct wl_output *);
uint32_t state() const { return state_; } void handle_output_leave(struct wl_output *);
bool maximized() const { return state_ & MAXIMIZED; } void handle_state(struct wl_array *);
bool minimized() const { return state_ & MINIMIZED; } void handle_done();
bool active() const { return state_ & ACTIVE; } void handle_closed();
bool fullscreen() const { return state_ & FULLSCREEN; }
public: /* Callbacks for Gtk events */
/* Callbacks for the wlr protocol */ bool handle_clicked(GdkEventButton *);
void handle_title(const char *);
void handle_app_id(const char *);
void handle_output_enter(struct wl_output *);
void handle_output_leave(struct wl_output *);
void handle_state(struct wl_array *);
void handle_done();
void handle_closed();
/* Callbacks for Gtk events */ public:
bool handle_clicked(GdkEventButton *); bool operator==(const Task&) const;
bool handle_button_release(GdkEventButton *); bool operator!=(const Task&) const;
bool handle_motion_notify(GdkEventMotion *);
void handle_drag_data_get(const Glib::RefPtr<Gdk::DragContext> &context,
Gtk::SelectionData &selection_data, guint info, guint time);
void handle_drag_data_received(const Glib::RefPtr<Gdk::DragContext> &context, int x, int y,
Gtk::SelectionData selection_data, guint info, guint time);
public: public:
bool operator==(const Task &) const; void update();
bool operator!=(const Task &) const;
public: public:
void update(); /* Interaction with the tasks */
void maximize(bool);
public: void minimize(bool);
/* Interaction with the tasks */ void activate();
void maximize(bool); void fullscreen(bool);
void minimize(bool); void close();
void activate();
void fullscreen(bool);
void close();
}; };
using TaskPtr = std::unique_ptr<Task>; using TaskPtr = std::unique_ptr<Task>;
class Taskbar : public waybar::AModule {
public:
Taskbar(const std::string &, const waybar::Bar &, const Json::Value &);
~Taskbar();
void update();
private: class Taskbar : public waybar::AModule
const waybar::Bar &bar_; {
Gtk::Box box_; public:
std::vector<TaskPtr> tasks_; Taskbar(const std::string&, const waybar::Bar&, const Json::Value&);
~Taskbar();
void update();
std::vector<Glib::RefPtr<Gtk::IconTheme>> icon_themes_; private:
std::unordered_set<std::string> ignore_list_; const waybar::Bar &bar_;
std::map<std::string, std::string> app_ids_replace_map_; Gtk::Box box_;
std::vector<TaskPtr> tasks_;
struct zwlr_foreign_toplevel_manager_v1 *manager_; std::vector<Glib::RefPtr<Gtk::IconTheme>> icon_themes_;
struct wl_seat *seat_; std::unordered_set<std::string> ignore_list_;
public: struct zwlr_foreign_toplevel_manager_v1 *manager_;
/* Callbacks for global registration */ struct wl_seat *seat_;
void register_manager(struct wl_registry *, uint32_t name, uint32_t version);
void register_seat(struct wl_registry *, uint32_t name, uint32_t version);
/* Callbacks for the wlr protocol */ public:
void handle_toplevel_create(struct zwlr_foreign_toplevel_handle_v1 *); /* Callbacks for global registration */
void handle_finished(); void register_manager(struct wl_registry*, uint32_t name, uint32_t version);
void register_seat(struct wl_registry*, uint32_t name, uint32_t version);
public: /* Callbacks for the wlr protocol */
void add_button(Gtk::Button &); void handle_toplevel_create(struct zwlr_foreign_toplevel_handle_v1 *);
void move_button(Gtk::Button &, int); void handle_finished();
void remove_button(Gtk::Button &);
void remove_task(uint32_t);
bool show_output(struct wl_output *) const; public:
bool all_outputs() const; void add_button(Gtk::Button &);
void move_button(Gtk::Button &, int);
void remove_button(Gtk::Button &);
void remove_task(uint32_t);
const std::vector<Glib::RefPtr<Gtk::IconTheme>> &icon_themes() const; bool show_output(struct wl_output *) const;
const std::unordered_set<std::string> &ignore_list() const; bool all_outputs() const;
const std::map<std::string, std::string> &app_ids_replace_map() const;
std::vector<Glib::RefPtr<Gtk::IconTheme>> icon_themes() const;
const std::unordered_set<std::string>& ignore_list() const;
}; };
} /* namespace waybar::modules::wlr */ } /* namespace waybar::modules::wlr */

View File

@ -1,172 +0,0 @@
#pragma once
#include <fmt/format.h>
#include <gtkmm/button.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>
#include <functional>
#include <map>
#include <memory>
#include <vector>
#include "AModule.hpp"
#include "bar.hpp"
#include "ext-workspace-unstable-v1-client-protocol.h"
namespace waybar::modules::wlr {
class WorkspaceManager;
class WorkspaceGroup;
class Workspace {
public:
Workspace(const waybar::Bar &bar, const Json::Value &config, WorkspaceGroup &workspace_group,
zext_workspace_handle_v1 *workspace, uint32_t id, std::string name);
~Workspace();
auto update() -> void;
auto id() const -> uint32_t { return id_; }
auto is_active() const -> bool { return state_ & static_cast<uint32_t>(State::ACTIVE); }
auto is_urgent() const -> bool { return state_ & static_cast<uint32_t>(State::URGENT); }
auto is_hidden() const -> bool { return state_ & static_cast<uint32_t>(State::HIDDEN); }
auto is_empty() const -> bool { return state_ & static_cast<uint32_t>(State::EMPTY); }
auto is_persistent() const -> bool { return persistent_; }
// wlr stuff
auto handle_name(const std::string &name) -> void;
auto handle_coordinates(const std::vector<uint32_t> &coordinates) -> void;
auto handle_state(const std::vector<uint32_t> &state) -> void;
auto handle_remove() -> void;
auto make_persistent() -> void;
auto handle_duplicate() -> void;
auto handle_done() -> void;
auto handle_clicked(GdkEventButton *bt) -> bool;
auto show() -> void;
auto hide() -> void;
auto get_button_ref() -> Gtk::Button & { return button_; }
auto get_name() -> std::string & { return name_; }
auto get_coords() -> std::vector<uint32_t> & { return coordinates_; }
enum class State {
ACTIVE = (1 << 0),
URGENT = (1 << 1),
HIDDEN = (1 << 2),
EMPTY = (1 << 3),
};
private:
auto get_icon() -> std::string;
const Bar &bar_;
const Json::Value &config_;
WorkspaceGroup &workspace_group_;
// wlr stuff
zext_workspace_handle_v1 *workspace_handle_;
uint32_t state_ = 0;
uint32_t id_;
std::string name_;
std::vector<uint32_t> coordinates_;
static std::map<std::string, std::string> icons_map_;
std::string format_;
bool with_icon_ = false;
bool persistent_ = false;
Gtk::Button button_;
Gtk::Box content_;
Gtk::Label label_;
};
class WorkspaceGroup {
public:
WorkspaceGroup(const waybar::Bar &bar, Gtk::Box &box, const Json::Value &config,
WorkspaceManager &manager, zext_workspace_group_handle_v1 *workspace_group_handle,
uint32_t id);
~WorkspaceGroup();
auto update() -> void;
auto id() const -> uint32_t { return id_; }
auto is_visible() const -> bool;
auto remove_workspace(uint32_t id_) -> void;
auto active_only() const -> bool;
auto creation_delayed() const -> bool;
auto workspaces() -> std::vector<std::unique_ptr<Workspace>> & { return workspaces_; }
auto persistent_workspaces() -> std::vector<std::string> & { return persistent_workspaces_; }
auto sort_workspaces() -> void;
auto set_need_to_sort() -> void { need_to_sort = true; }
auto add_button(Gtk::Button &button) -> void;
auto remove_button(Gtk::Button &button) -> void;
auto fill_persistent_workspaces() -> void;
auto create_persistent_workspaces() -> void;
// wlr stuff
auto handle_workspace_create(zext_workspace_handle_v1 *workspace_handle) -> void;
auto handle_remove() -> void;
auto handle_output_enter(wl_output *output) -> void;
auto handle_output_leave() -> void;
auto handle_done() -> void;
auto commit() -> void;
private:
static uint32_t workspace_global_id;
const waybar::Bar &bar_;
Gtk::Box &box_;
const Json::Value &config_;
WorkspaceManager &workspace_manager_;
// wlr stuff
zext_workspace_group_handle_v1 *workspace_group_handle_;
wl_output *output_ = nullptr;
uint32_t id_;
std::vector<std::unique_ptr<Workspace>> workspaces_;
bool need_to_sort = false;
std::vector<std::string> persistent_workspaces_;
bool persistent_created_ = false;
};
class WorkspaceManager : public AModule {
public:
WorkspaceManager(const std::string &id, const waybar::Bar &bar, const Json::Value &config);
~WorkspaceManager() override;
auto update() -> void override;
auto all_outputs() const -> bool { return all_outputs_; }
auto active_only() const -> bool { return active_only_; }
auto workspace_comparator() const
-> std::function<bool(std::unique_ptr<Workspace> &, std::unique_ptr<Workspace> &)>;
auto creation_delayed() const -> bool { return creation_delayed_; }
auto sort_workspaces() -> void;
auto remove_workspace_group(uint32_t id_) -> void;
// wlr stuff
auto register_manager(wl_registry *registry, uint32_t name, uint32_t version) -> void;
auto handle_workspace_group_create(zext_workspace_group_handle_v1 *workspace_group_handle)
-> void;
auto handle_done() -> void;
auto handle_finished() -> void;
auto commit() -> void;
private:
const waybar::Bar &bar_;
Gtk::Box box_;
std::vector<std::unique_ptr<WorkspaceGroup>> groups_;
// wlr stuff
zext_workspace_manager_v1 *workspace_manager_ = nullptr;
static uint32_t group_global_id;
bool sort_by_name_ = true;
bool sort_by_coordinates_ = true;
bool sort_by_number_ = false;
bool all_outputs_ = false;
bool active_only_ = false;
bool creation_delayed_ = false;
};
} // namespace waybar::modules::wlr

View File

@ -1,10 +0,0 @@
#include "ext-workspace-unstable-v1-client-protocol.h"
namespace waybar::modules::wlr {
void add_registry_listener(void *data);
void add_workspace_listener(zext_workspace_handle_v1 *workspace_handle, void *data);
void add_workspace_group_listener(zext_workspace_group_handle_v1 *workspace_group_handle,
void *data);
zext_workspace_manager_v1 *workspace_manager_bind(wl_registry *registry, uint32_t name,
uint32_t version, void *data);
} // namespace waybar::modules::wlr

View File

@ -1,75 +0,0 @@
#pragma once
#include <glibmm/dispatcher.h>
#include <sigc++/signal.h>
#include <functional>
#include <mutex>
#include <queue>
#include <thread>
#include <tuple>
#include <type_traits>
#include <utility>
namespace waybar {
/**
* Thread-safe signal wrapper.
* Uses Glib::Dispatcher to pass events to another thread and locked queue to pass the arguments.
*/
template <typename... Args>
struct SafeSignal : sigc::signal<void(std::decay_t<Args>...)> {
public:
SafeSignal() { dp_.connect(sigc::mem_fun(*this, &SafeSignal::handle_event)); }
template <typename... EmitArgs>
void emit(EmitArgs&&... args) {
if (main_tid_ == std::this_thread::get_id()) {
/*
* Bypass the queue if the method is called the main thread.
* Ensures that events emitted from the main thread are processed synchronously and saves a
* few CPU cycles on locking/queuing.
* As a downside, this makes main thread events prioritized over the other threads and
* disrupts chronological order.
*/
signal_t::emit(std::forward<EmitArgs>(args)...);
} else {
{
std::unique_lock lock(mutex_);
queue_.emplace(std::forward<EmitArgs>(args)...);
}
dp_.emit();
}
}
template <typename... EmitArgs>
inline void operator()(EmitArgs&&... args) {
emit(std::forward<EmitArgs>(args)...);
}
protected:
using signal_t = sigc::signal<void(std::decay_t<Args>...)>;
using slot_t = decltype(std::declval<signal_t>().make_slot());
using arg_tuple_t = std::tuple<std::decay_t<Args>...>;
// ensure that unwrapped methods are not accessible
using signal_t::emit_reverse;
using signal_t::make_slot;
void handle_event() {
for (std::unique_lock lock(mutex_); !queue_.empty(); lock.lock()) {
auto args = queue_.front();
queue_.pop();
lock.unlock();
std::apply(cached_fn_, args);
}
}
Glib::Dispatcher dp_;
std::mutex mutex_;
std::queue<arg_tuple_t> queue_;
const std::thread::id main_tid_ = std::this_thread::get_id();
// cache functor for signal emission to avoid recreating it on each event
const slot_t cached_fn_ = make_slot();
};
} // namespace waybar

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <fcntl.h>
#include <giomm.h> #include <giomm.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -21,13 +20,13 @@ extern std::list<pid_t> reap;
namespace waybar::util::command { namespace waybar::util::command {
struct res { struct res {
int exit_code; int exit_code;
std::string out; std::string out;
}; };
inline std::string read(FILE* fp) { inline std::string read(FILE* fp) {
std::array<char, 128> buffer = {0}; std::array<char, 128> buffer = {0};
std::string output; std::string output;
while (feof(fp) == 0) { while (feof(fp) == 0) {
if (fgets(buffer.data(), 128, fp) != nullptr) { if (fgets(buffer.data(), 128, fp) != nullptr) {
output += buffer.data(); output += buffer.data();
@ -69,21 +68,12 @@ inline int close(FILE* fp, pid_t pid) {
inline FILE* open(const std::string& cmd, int& pid) { inline FILE* open(const std::string& cmd, int& pid) {
if (cmd == "") return nullptr; if (cmd == "") return nullptr;
int fd[2]; int fd[2];
// Open the pipe with the close-on-exec flag set, so it will not be inherited pipe(fd);
// by any other subprocesses launched by other threads (which could result in
// the pipe staying open after this child dies, causing us to hang when trying
// to read from it)
if (pipe2(fd, O_CLOEXEC) != 0) {
spdlog::error("Unable to pipe fd");
return nullptr;
}
pid_t child_pid = fork(); pid_t child_pid = fork();
if (child_pid < 0) { if (child_pid < 0) {
spdlog::error("Unable to exec cmd {}, error {}", cmd.c_str(), strerror(errno)); spdlog::error("Unable to exec cmd {}, error {}", cmd.c_str(), strerror(errno));
::close(fd[0]);
::close(fd[1]);
return nullptr; return nullptr;
} }
@ -119,7 +109,7 @@ inline FILE* open(const std::string& cmd, int& pid) {
} }
inline struct res exec(const std::string& cmd) { inline struct res exec(const std::string& cmd) {
int pid; int pid;
auto fp = command::open(cmd, pid); auto fp = command::open(cmd, pid);
if (!fp) return {-1, ""}; if (!fp) return {-1, ""};
auto output = command::read(fp); auto output = command::read(fp);
@ -128,7 +118,7 @@ inline struct res exec(const std::string& cmd) {
} }
inline struct res execNoRead(const std::string& cmd) { inline struct res execNoRead(const std::string& cmd) {
int pid; int pid;
auto fp = command::open(cmd, pid); auto fp = command::open(cmd, pid);
if (!fp) return {-1, ""}; if (!fp) return {-1, ""};
auto stat = command::close(fp, pid); auto stat = command::close(fp, pid);

View File

@ -1,60 +0,0 @@
#pragma once
#include <fmt/format.h>
#if HAVE_CHRONO_TIMEZONES
#include <chrono>
#include <format>
/* Compatibility layer for <date/tz.h> on top of C++20 <chrono> */
namespace date {
using namespace std::chrono;
namespace literals {
using std::chrono::last;
}
inline auto format(const std::string& spec, const auto& ztime) {
return spec.empty() ? "" : std::vformat("{:L" + spec + "}", std::make_format_args(ztime));
}
inline auto format(const std::locale& loc, const std::string& spec, const auto& ztime) {
return spec.empty() ? "" : std::vformat(loc, "{:L" + spec + "}", std::make_format_args(ztime));
}
} // namespace date
#else
#include <date/tz.h>
#endif
template <typename Duration, typename TimeZonePtr>
struct fmt::formatter<date::zoned_time<Duration, TimeZonePtr>> {
std::string_view specs;
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin();
if (it != ctx.end() && *it == ':') {
++it;
}
auto end = it;
while (end != ctx.end() && *end != '}') {
++end;
}
if (end != it) {
specs = {it, std::string_view::size_type(end - it)};
}
return end;
}
template <typename FormatContext>
auto format(const date::zoned_time<Duration, TimeZonePtr>& ztime, FormatContext& ctx) {
if (ctx.locale()) {
const auto loc = ctx.locale().template get<std::locale>();
return fmt::format_to(ctx.out(), "{}", date::format(loc, fmt::to_string(specs), ztime));
}
return fmt::format_to(ctx.out(), "{}", date::format(fmt::to_string(specs), ztime));
}
};

View File

@ -1,99 +1,88 @@
#pragma once #pragma once
#include <fmt/format.h> #include <fmt/format.h>
#include <glibmm/ustring.h>
class pow_format { class pow_format {
public: public:
pow_format(long long val, std::string&& unit, bool binary = false) pow_format(long long val, std::string&& unit, bool binary = false):
: val_(val), unit_(unit), binary_(binary){}; val_(val), unit_(unit), binary_(binary) { };
long long val_; long long val_;
std::string unit_; std::string unit_;
bool binary_; bool binary_;
}; };
namespace fmt { namespace fmt {
template <> template <>
struct formatter<pow_format> { struct formatter<pow_format> {
char spec = 0; char spec = 0;
int width = 0; int width = 0;
template <typename ParseContext> template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { constexpr auto parse(ParseContext& ctx) -> decltype (ctx.begin()) {
auto it = ctx.begin(), end = ctx.end(); auto it = ctx.begin(), end = ctx.end();
if (it != end && *it == ':') ++it; if (it != end && *it == ':') ++it;
if (it && (*it == '>' || *it == '<' || *it == '=')) { if (it && (*it == '>' || *it == '<' || *it == '=')) {
spec = *it; spec = *it;
++it; ++it;
} }
if (it == end || *it == '}') return it; if (it == end || *it == '}') return it;
if ('0' <= *it && *it <= '9') { if ('0' <= *it && *it <= '9') {
// We ignore it for now, but keep it for compatibility with // We ignore it for now, but keep it for compatibility with
// existing configs where the format for pow_format'ed numbers was // existing configs where the format for pow_format'ed numbers was
// 'string' and specifications such as {:>9} were valid. // 'string' and specifications such as {:>9} were valid.
// The rationale for ignoring it is that the only reason to specify // The rationale for ignoring it is that the only reason to specify
// an alignment and a with is to get a fixed width bar, and ">" is // an alignment and a with is to get a fixed width bar, and ">" is
// sufficient in this implementation. // sufficient in this implementation.
#if FMT_VERSION < 80000 #if FMT_VERSION < 80000
width = parse_nonnegative_int(it, end, ctx); width = parse_nonnegative_int(it, end, ctx);
#else #else
width = detail::parse_nonnegative_int(it, end, -1); width = detail::parse_nonnegative_int(it, end, -1);
#endif #endif
} }
return it; return it;
} }
template <class FormatContext> template<class FormatContext>
auto format(const pow_format& s, FormatContext& ctx) -> decltype(ctx.out()) { auto format(const pow_format& s, FormatContext &ctx) -> decltype (ctx.out()) {
const char* units[] = {"", "k", "M", "G", "T", "P", nullptr}; const char* units[] = { "", "k", "M", "G", "T", "P", nullptr};
auto base = s.binary_ ? 1024ull : 1000ll; auto base = s.binary_ ? 1024ull : 1000ll;
auto fraction = (double)s.val_; auto fraction = (double) s.val_;
int pow; int pow;
for (pow = 0; units[pow + 1] != nullptr && fraction / base >= 1; ++pow) { for (pow = 0; units[pow+1] != nullptr && fraction / base >= 1; ++pow) {
fraction /= base; fraction /= base;
} }
auto number_width = 5 // coeff in {:.1f} format auto max_width = 4 // coeff in {:.3g} format
+ s.binary_; // potential 4th digit before the decimal point + 1 // prefix from units array
auto max_width = number_width + 1 // prefix from units array + s.binary_ // for the 'i' in GiB.
+ s.binary_ // for the 'i' in GiB. + s.unit_.length();
+ s.unit_.length();
const char* format; const char * format;
std::string string; std::string string;
switch (spec) { switch (spec) {
case '>': case '>':
return fmt::format_to(ctx.out(), "{:>{}}", fmt::format("{}", s), max_width); return format_to(ctx.out(), "{:>{}}", fmt::format("{}", s), max_width);
case '<': case '<':
return fmt::format_to(ctx.out(), "{:<{}}", fmt::format("{}", s), max_width); return format_to(ctx.out(), "{:<{}}", fmt::format("{}", s), max_width);
case '=': case '=':
format = "{coefficient:<{number_width}.1f}{padding}{prefix}{unit}"; format = "{coefficient:<4.3g}{padding}{prefix}{unit}";
break; break;
case 0: case 0:
default: default:
format = "{coefficient:.1f}{prefix}{unit}"; format = "{coefficient:.3g}{prefix}{unit}";
break; break;
} }
return fmt::format_to( return format_to(ctx.out(), format
ctx.out(), fmt::runtime(format), fmt::arg("coefficient", fraction), , fmt::arg("coefficient", fraction)
fmt::arg("number_width", number_width), , fmt::arg("prefix", std::string() + units[pow] + ((s.binary_ && pow) ? "i" : ""))
fmt::arg("prefix", std::string() + units[pow] + ((s.binary_ && pow) ? "i" : "")), , fmt::arg("unit", s.unit_)
fmt::arg("unit", s.unit_), , fmt::arg("padding", pow ? "" : s.binary_ ? " " : " ")
fmt::arg("padding", pow ? "" );
: s.binary_ ? " " }
: " ")); };
} }
};
// Glib ustirng support
template <>
struct formatter<Glib::ustring> : formatter<std::string> {
template <typename FormatContext>
auto format(const Glib::ustring& value, FormatContext& ctx) {
return formatter<std::string>::format(static_cast<std::string>(value), ctx);
}
};
} // namespace fmt

View File

@ -1,14 +0,0 @@
#pragma once
#include <gtkmm/icontheme.h>
#include <mutex>
#include <string>
class DefaultGtkIconThemeWrapper {
private:
static std::mutex default_theme_mutex;
public:
static bool has_icon(const std::string&);
static Glib::RefPtr<Gdk::Pixbuf> load_icon(const char*, int, Gtk::IconLookupFlags);
};

View File

@ -1,15 +1,7 @@
#pragma once #pragma once
#include <fmt/ostream.h>
#include <json/json.h> #include <json/json.h>
#if (FMT_VERSION >= 90000)
template <>
struct fmt::formatter<Json::Value> : ostream_formatter {};
#endif
namespace waybar::util { namespace waybar::util {
struct JsonParser { struct JsonParser {
@ -21,7 +13,7 @@ struct JsonParser {
return root; return root;
} }
std::unique_ptr<Json::CharReader> const reader(builder_.newCharReader()); std::unique_ptr<Json::CharReader> const reader(builder_.newCharReader());
std::string err; std::string err;
bool res = reader->parse(data.c_str(), data.c_str() + data.size(), &root, &err); bool res = reader->parse(data.c_str(), data.c_str() + data.size(), &root, &err);
if (!res) throw std::runtime_error(err); if (!res) throw std::runtime_error(err);
return root; return root;

View File

@ -1,9 +0,0 @@
#pragma once
#include "SafeSignal.hpp"
namespace waybar::util {
// Get a signal emited with value true when entering sleep, and false when exiting
SafeSignal<bool>& prepare_for_sleep();
} // namespace waybar::util

View File

@ -1,8 +0,0 @@
#pragma once
#include <json/json.h>
#include <string>
namespace waybar::util {
std::string rewriteString(const std::string&, const Json::Value&);
}

View File

@ -17,8 +17,8 @@ class Rfkill : public sigc::trackable {
private: private:
enum rfkill_type rfkill_type_; enum rfkill_type rfkill_type_;
bool state_ = false; bool state_ = false;
int fd_ = -1; int fd_ = -1;
bool on_event(Glib::IOCondition cond); bool on_event(Glib::IOCondition cond);
}; };

View File

@ -1,6 +0,0 @@
#pragma once
#include <string>
namespace waybar::util {
std::string sanitize_string(std::string str);
} // namespace waybar::util

View File

@ -6,8 +6,6 @@
#include <functional> #include <functional>
#include <thread> #include <thread>
#include "prepare_for_sleep.h"
namespace waybar::util { namespace waybar::util {
/** /**
@ -19,8 +17,7 @@ namespace waybar::util {
*/ */
class CancellationGuard { class CancellationGuard {
int oldstate; int oldstate;
public:
public:
CancellationGuard() { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); } CancellationGuard() { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); }
~CancellationGuard() { pthread_setcancelstate(oldstate, &oldstate); } ~CancellationGuard() { pthread_setcancelstate(oldstate, &oldstate); }
}; };
@ -35,11 +32,7 @@ class SleeperThread {
signal_ = false; signal_ = false;
func(); func();
} }
}} { }} {}
connection_ = prepare_for_sleep().connect([this](bool sleep) {
if (not sleep) wake_up();
});
}
SleeperThread& operator=(std::function<void()> func) { SleeperThread& operator=(std::function<void()> func) {
thread_ = std::thread([this, func] { thread_ = std::thread([this, func] {
@ -48,18 +41,13 @@ class SleeperThread {
func(); func();
} }
}); });
if (connection_.empty()) {
connection_ = prepare_for_sleep().connect([this](bool sleep) {
if (not sleep) wake_up();
});
}
return *this; return *this;
} }
bool isRunning() const { return do_run_; } bool isRunning() const { return do_run_; }
auto sleep_for(std::chrono::system_clock::duration dur) { auto sleep_for(std::chrono::system_clock::duration dur) {
std::unique_lock lk(mutex_); std::unique_lock lk(mutex_);
CancellationGuard cancel_lock; CancellationGuard cancel_lock;
return condvar_.wait_for(lk, dur, [this] { return signal_ || !do_run_; }); return condvar_.wait_for(lk, dur, [this] { return signal_ || !do_run_; });
} }
@ -67,12 +55,12 @@ class SleeperThread {
auto sleep_until( auto sleep_until(
std::chrono::time_point<std::chrono::system_clock, std::chrono::system_clock::duration> std::chrono::time_point<std::chrono::system_clock, std::chrono::system_clock::duration>
time_point) { time_point) {
std::unique_lock lk(mutex_); std::unique_lock lk(mutex_);
CancellationGuard cancel_lock; CancellationGuard cancel_lock;
return condvar_.wait_until(lk, time_point, [this] { return signal_ || !do_run_; }); return condvar_.wait_until(lk, time_point, [this] { return signal_ || !do_run_; });
} }
void wake_up() { auto wake_up() {
{ {
std::lock_guard<std::mutex> lck(mutex_); std::lock_guard<std::mutex> lck(mutex_);
signal_ = true; signal_ = true;
@ -95,7 +83,6 @@ class SleeperThread {
} }
~SleeperThread() { ~SleeperThread() {
connection_.disconnect();
stop(); stop();
if (thread_.joinable()) { if (thread_.joinable()) {
thread_.join(); thread_.join();
@ -103,12 +90,11 @@ class SleeperThread {
} }
private: private:
std::thread thread_; std::thread thread_;
std::condition_variable condvar_; std::condition_variable condvar_;
std::mutex mutex_; std::mutex mutex_;
bool do_run_ = true; bool do_run_ = true;
bool signal_ = false; bool signal_ = false;
sigc::connection connection_;
}; };
} // namespace waybar::util } // namespace waybar::util

View File

@ -1,17 +1,15 @@
#pragma once
#include <string> #include <string>
const std::string WHITESPACE = " \n\r\t\f\v"; const std::string WHITESPACE = " \n\r\t\f\v";
inline std::string ltrim(const std::string& s) { std::string ltrim(const std::string s) {
size_t begin = s.find_first_not_of(WHITESPACE); size_t begin = s.find_first_not_of(WHITESPACE);
return (begin == std::string::npos) ? "" : s.substr(begin); return (begin == std::string::npos) ? "" : s.substr(begin);
} }
inline std::string rtrim(const std::string& s) { std::string rtrim(const std::string s) {
size_t end = s.find_last_not_of(WHITESPACE); size_t end = s.find_last_not_of(WHITESPACE);
return (end == std::string::npos) ? "" : s.substr(0, end + 1); return (end == std::string::npos) ? "" : s.substr(0, end + 1);
} }
inline std::string trim(const std::string& s) { return rtrim(ltrim(s)); } std::string trim(const std::string& s) { return rtrim(ltrim(s)); }

View File

@ -25,20 +25,20 @@ The *backlight* module displays the current backlight level.
The maximum length in characters the module should display. The maximum length in characters the module should display.
*min-length*: ++ *min-length*: ++
typeof: integer ++ typeof: integer ++
The minimum length in characters the module should take up. The minimum length in characters the module should take up.
*align*: ++ *align*: ++
typeof: float ++ typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*rotate*: ++ *rotate*: ++
typeof: integer ++ typeof: integer ++
Positive value to rotate the text label. Positive value to rotate the text label.
*states*: ++ *states*: ++
typeof: object ++ typeof: array ++
A number of backlight states which get activated on certain brightness levels. See *waybar-states(5)*. A number of backlight states which get activated on certain brightness levels.
*on-click*: ++ *on-click*: ++
typeof: string ++ typeof: string ++
@ -58,32 +58,23 @@ The *backlight* module displays the current backlight level.
*on-scroll-up*: ++ *on-scroll-up*: ++
typeof: string ++ typeof: string ++
Command to execute when performing a scroll up on the module. This replaces the default behaviour of brightness control. Command to execute when performing a scroll up on the module.
*on-scroll-down*: ++ *on-scroll-down*: ++
typeof: string typeof: string
Command to execute when performing a scroll down on the module. This replaces the default behaviour of brightness control. Command to execute when performing a scroll down on the module.
*smooth-scrolling-threshold*: ++ *smooth-scrolling-threshold*: ++
typeof: double typeof: double
Threshold to be used when scrolling. Threshold to be used when scrolling.
*reverse-scrolling*: ++
typeof: bool ++
Option to reverse the scroll direction.
*scroll-step*: ++
typeof: float ++
default: 1.0 ++
The speed in which to change the brightness when scrolling.
# EXAMPLE: # EXAMPLE:
``` ```
"backlight": { "backlight": {
"device": "intel_backlight", "device": "intel_backlight",
"format": "{percent}% {icon}", "format": "{percent}% {icon}",
"format-icons": ["", ""] "format-icons": ["", ""]
} }
``` ```

View File

@ -23,9 +23,9 @@ The *battery* module displays the current capacity and state (eg. charging) of y
Define the max percentage of the battery, for when you've set the battery to stop charging at a lower level to save it. For example, if you've set the battery to stop at 80% that will become the new 100%. Define the max percentage of the battery, for when you've set the battery to stop charging at a lower level to save it. For example, if you've set the battery to stop at 80% that will become the new 100%.
*design-capacity*: ++ *design-capacity*: ++
typeof: bool ++ typeof: bool ++
default: false ++ default: false ++
Option to use the battery design capacity instead of it's current maximal capacity. Option to use the battery design capacity instead of it's current maximal capacity.
*interval*: ++ *interval*: ++
typeof: integer ++ typeof: integer ++
@ -33,13 +33,13 @@ The *battery* module displays the current capacity and state (eg. charging) of y
The interval in which the information gets polled. The interval in which the information gets polled.
*states*: ++ *states*: ++
typeof: object ++ typeof: array ++
A number of battery states which get activated on certain capacity levels. See *waybar-states(5)*. A number of battery states which get activated on certain capacity levels. See *waybar-states(5)*.
*format*: ++ *format*: ++
typeof: string ++ typeof: string ++
default: {capacity}% ++ default: {capacity}% ++
The format, how information should be displayed. The format, how the time should be displayed.
*format-time*: ++ *format-time*: ++
typeof: string ++ typeof: string ++
@ -56,12 +56,12 @@ The *battery* module displays the current capacity and state (eg. charging) of y
The maximum length in character the module should display. The maximum length in character the module should display.
*min-length*: ++ *min-length*: ++
typeof: integer ++ typeof: integer ++
The minimum length in characters the module should take up. The minimum length in characters the module should take up.
*align*: ++ *align*: ++
typeof: float ++ typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*rotate*: ++ *rotate*: ++
typeof: integer++ typeof: integer++
@ -114,14 +114,13 @@ The *battery* module displays the current capacity and state (eg. charging) of y
The *battery* module allows you to define how time should be formatted via *format-time*. The *battery* module allows you to define how time should be formatted via *format-time*.
The three arguments are: The two arguments are:
*{H}*: Hours *{H}*: Hours
*{M}*: Minutes *{M}*: Minutes
*{m}*: Zero-padded minutes
# CUSTOM FORMATS # CUSTOM FORMATS
The *battery* module allows one to define custom formats based on up to two factors. The best fitting format will be selected. The *battery* module allows to define custom formats based on up to two factors. The best fitting format will be selected.
*format-<state>*: With *states*, a custom format can be set depending on the capacity of your battery. *format-<state>*: With *states*, a custom format can be set depending on the capacity of your battery.
@ -132,8 +131,8 @@ The *battery* module allows one to define custom formats based on up to two fact
# STATES # STATES
- Every entry (*state*) consists of a *<name>* (typeof: *string*) and a *<value>* (typeof: *integer*). - Every entry (*state*) consists of a *<name>* (typeof: *string*) and a *<value>* (typeof: *integer*).
- The state can be addressed as a CSS class in the *style.css*. The name of the CSS class is the *<name>* of the state. Each class gets activated when the current capacity is equal or below the configured *<value>*. - The state can be addressed as a CSS class in the *style.css*. The name of the CSS class is the *<name>* of the state. Each class gets activated when the current capacity is equal or below the configured *<value>*.
- Also each state can have its own *format*. Those con be configured via *format-<name>*. Or if you want to differentiate a bit more even as *format-<status>-<state>*. For more information see *custom-formats*. - Also each state can have its own *format*. Those con be configured via *format-<name>*. Or if you want to differentiate a bit more even as *format-<status>-<state>*. For more information see *custom-formats*.
@ -141,15 +140,15 @@ The *battery* module allows one to define custom formats based on up to two fact
``` ```
"battery": { "battery": {
"bat": "BAT2", "bat": "BAT2",
"interval": 60, "interval": 60,
"states": { "states": {
"warning": 30, "warning": 30,
"critical": 15 "critical": 15
}, },
"format": "{capacity}% {icon}", "format": "{capacity}% {icon}",
"format-icons": ["", "", "", "", ""], "format-icons": ["", "", "", "", ""],
"max-length": 25 "max-length": 25
} }
``` ```

View File

@ -6,51 +6,21 @@ waybar - bluetooth module
# DESCRIPTION # DESCRIPTION
The *bluetooth* module displays information about a bluetooth controller and its connections. The *bluetooth* module displays information about the status of the device's bluetooth device.
# CONFIGURATION # CONFIGURATION
Addressed by *bluetooth* Addressed by *bluetooth*
*controller*: ++
typeof: string ++
Use the controller with the defined alias. Otherwise a random controller is used. Recommended to define when there is more than 1 controller available to the system.
*format-device-preference*: ++
typeof: array ++
A ranking of bluetooth devices, addressed by their alias. The order is from *first displayed* to *last displayed*. ++
If this config option is not defined or none of the devices in the list are connected, it will fall back to showing the last connected device.
*format*: ++ *format*: ++
typeof: string ++ typeof: string ++
default: * {status}* ++ default: *{icon}* ++
The format, how information should be displayed. This format is used when other formats aren't specified. The format, how information should be displayed. This format is used when other formats aren't specified.
*format-disabled*: ++
typeof: string ++
This format is used when the displayed controller is disabled.
*format-off*: ++
typeof: string ++
This format is used when the displayed controller is turned off.
*format-on*: ++
typeof: string ++
This format is used when the displayed controller is turned on with no devices connected.
*format-connected*: ++
typeof: string ++
This format is used when the displayed controller is connected to at least 1 device.
*format-no-controller*: ++
typeof: string ++
This format is used when no bluetooth controller could be found
*format-icons*: ++ *format-icons*: ++
typeof: array/object ++ typeof: array/object ++
Based on the current battery percentage (see section *EXPERIMENTAL BATTERY PERCENTAGE FEATURE*), the corresponding icon gets selected. ++ Based on the device status, the corresponding icon gets selected. ++
The order is *low* to *high*. Will only show the current battery percentage icon in the *\*-connected-battery* config options. ++ The order is *low* to *high*. Or by the state if it is an object.
Or by the state if it is an object. It will fall back to the enabled state if its derivatives are not defined (on, off, connected).
*rotate*: ++ *rotate*: ++
typeof: integer ++ typeof: integer ++
@ -61,12 +31,12 @@ Addressed by *bluetooth*
The maximum length in character the module should display. The maximum length in character the module should display.
*min-length*: ++ *min-length*: ++
typeof: integer ++ typeof: integer ++
The minimum length in characters the module should take up. The minimum length in characters the module should take up.
*align*: ++ *align*: ++
typeof: float ++ typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*on-click*: ++ *on-click*: ++
typeof: string ++ typeof: string ++
@ -101,110 +71,26 @@ Addressed by *bluetooth*
typeof: string ++ typeof: string ++
The format, how information should be displayed in the tooltip. This format is used when other formats aren't specified. The format, how information should be displayed in the tooltip. This format is used when other formats aren't specified.
*tooltip-format-disabled*: ++
typeof: string ++
This format is used when the displayed controller is disabled.
*tooltip-format-off*: ++
typeof: string ++
This format is used when the displayed controller is turned off.
*tooltip-format-on*: ++
typeof: string ++
This format is used when the displayed controller is turned on with no devices connected.
*tooltip-format-connected*: ++
typeof: string ++
This format is used when the displayed controller is connected to at least 1 device.
*tooltip-format-no-controller*: ++
typeof: string ++
This format is used when no bluetooth controller could be found
*tooltip-format-enumerate-connected*: ++
typeof: string ++
This format is used to define how each connected device should be displayed within the *device_enumerate* format replacement in the tooltip menu.
# FORMAT REPLACEMENTS # FORMAT REPLACEMENTS
*{status}*: Status of the bluetooth device. *{status}*: Status of the bluetooth device.
*{icon}*: Icon, as defined in *format-icons*. *{icon}*: Icon, as defined in *format-icons*.
*{num_connections}*: Number of connections the displayed controller has.
*{controller_address}*: Address of the displayed controller.
*{controller_address_type}*: Address type of the displayed controller.
*{controller_alias}*: Alias of the displayed controller.
*{device_address}*: Address of the displayed device.
*{device_address_type}*: Address type of the displayed device.
*{device_alias}*: Alias of the displayed device.
*{device_enumerate}*: Show a list of all connected devices, each on a separate line. Define the format of each device with the *tooltip-format-enumerate-connected* ++
and/or *tooltip-format-enumerate-connected-battery* config options. Can only be used in the tooltip related format options.
# EXPERIMENTAL BATTERY PERCENTAGE FEATURE
At the time of writing, the experimental features of BlueZ need to be turned on, for the battery percentage options listed below to work.
## FORMAT REPLACEMENT
*{device_battery_percentage}*: Battery percentage of the displayed device if available. Use only in the config options defined below.
## CONFIGURATION
*format-connected-battery*: ++
typeof: string ++
This format is used when the displayed device provides its battery percentage.
*tooltip-format-connected-battery*: ++
typeof: string ++
This format is used when the displayed device provides its battery percentage.
*tooltip-format-enumerate-connected-battery*: ++
typeof: string ++
This format is used to define how each connected device with a battery should be displayed within the *device_enumerate* format replacement option. ++
When this config option is not defined, it will fall back on the *tooltip-format-enumerate-connected* config option.
# EXAMPLES # EXAMPLES
``` ```
"bluetooth": { "bluetooth": {
// "controller": "controller1", // specify the alias of the controller if there are more than 1 on the system "format": "{icon}",
"format": " {status}", "format-alt": "bluetooth: {status}",
"format-disabled": "", // an empty format will hide the module "format-icons": {
"format-connected": " {num_connections} connected", "enabled": "",
"tooltip-format": "{controller_alias}\\t{controller_address}", "disabled": ""
"tooltip-format-connected": "{controller_alias}\\t{controller_address}\\n\\n{device_enumerate}", },
"tooltip-format-enumerate-connected": "{device_alias}\\t{device_address}" "tooltip-format": "{}"
}
```
```
"bluetooth": {
"format": " {status}",
"format-connected": " {device_alias}",
"format-connected-battery": " {device_alias} {device_battery_percentage}%",
// "format-device-preference": [ "device1", "device2" ], // preference list deciding the displayed device
"tooltip-format": "{controller_alias}\\t{controller_address}\\n\\n{num_connections} connected",
"tooltip-format-connected": "{controller_alias}\\t{controller_address}\\n\\n{num_connections} connected\\n\\n{device_enumerate}",
"tooltip-format-enumerate-connected": "{device_alias}\\t{device_address}",
"tooltip-format-enumerate-connected-battery": "{device_alias}\\t{device_address}\\t{device_battery_percentage}%"
} }
``` ```
# STYLE # STYLE
- *#bluetooth* - *#bluetooth*
- *#bluetooth.disabled*
- *#bluetooth.off*
- *#bluetooth.on*
- *#bluetooth.connected*
- *#bluetooth.discoverable*
- *#bluetooth.discovering*
- *#bluetooth.pairable*

View File

@ -1,182 +0,0 @@
waybar-cava(5) "waybar-cava" "User Manual"
# NAME
waybar - cava module
# DESCRIPTION
*cava* module for karlstav/cava project. See it on github: https://github.com/karlstav/cava.
# FILES
$XDG_CONFIG_HOME/waybar/config ++
Per user configuration file
# ADDITIONAL FILES
libcava lives in:
. /usr/lib/libcava.so or /usr/lib64/libcava.so
. /usr/lib/pkgconfig/cava.pc or /usr/lib64/pkgconfig/cava.pc
. /usr/include/cava
# CONFIGURATION
[- *Option*
:- *Typeof*
:- *Default*
:- *Description*
|[ *cava_config*
:[ string
:[
:< Path where cava configuration file is placed to
|[ *framerate*
:[ integer
:[ 30
:[ rames per second. Is used as a replacement for *interval*
|[ *autosens*
:[ integer
:[ 1
:[ Will attempt to decrease sensitivity if the bars peak
|[ *sensitivity*
:[ integer
:[ 100
:[ Manual sensitivity in %. It's recommended to be omitted when *autosens* = 1
|[ *bars*
:[ integer
:[ 12
:[ The number of bars
|[ *lower_cutoff_freq*
:[ long integer
:[ 50
:[ Lower cutoff frequencies for lowest bars the bandwidth of the visualizer
|[ *higher_cutoff_freq*
:[ long integer
:[ 10000
:[ Higher cutoff frequencies for highest bars the bandwidth of the visualizer
|[ *sleep_timer*
:[ integer
:[ 5
:[ Seconds with no input before cava main thread goes to sleep mode
|[ *method*
:[ string
:[ pulse
:[ Audio capturing method. Possible methods are: pipewire, pulse, alsa, fifo, sndio or shmem
|[ *source*
:[ string
:[ auto
:[ See cava configuration
|[ *sample_rate*
:[ long integer
:[ 44100
:[ See cava configuration
|[ *sample_bits*
:[ integer
:[ 16
:[ See cava configuration
|[ *stereo*
:[ bool
:[ true
:[ Visual channels
|[ *reverse*
:[ bool
:[ false
:[ Displays frequencies the other way around
|[ *bar_delimiter*
:[ integer
:[ 0
:[ Each bar is separated by a delimiter. Use decimal value in ascii table(i.e. 59 = ";"). 0 means no delimiter
|[ *monstercat*
:[ bool
:[ false
:[ Disables or enables the so-called "Monstercat smoothing" with of without "waves"
|[ *waves*
:[ bool
:[ false
:[ Disables or enables the so-called "Monstercat smoothing" with of without "waves"
|[ *noise_reduction*
:[ double
:[ 0.77
:[ Range between 0 - 1. The raw visualization is very noisy, this factor adjust the integral and gravity filters to keep the signal smooth. 1 - will be very slow and smooth, 0 - will be fast but noisy
|[ *input_delay*
:[ integer
:[ 2
:[ Sets the delay before fetching audio source thread start working. On author machine Waybar starts much faster then pipewire audio server, and without a little delay cava module fails due to pipewire is not ready
|[ *ascii_max_range*
:[ integer
:[ 7
:[ It's impossible to set it directly. The value is dictated by the number of icons in the array *format-icons*
|[ *data_format*
:[ string
:[ asci
:[ It's impossible to set it. Waybar sets it to = asci for internal needs
|[ *raw_target*
:[ string
:[ /dev/stdout
:[ It's impossible to set it. Waybar sets it to = /dev/stdout for internal needs
Configuration can be provided as:
- The only cava configuration file which is provided through *cava_config*. The rest configuration can be skipped
- Without cava configuration file. In such case cava should be configured through provided list of the configuration option
- Mix. When provided both And cava configuration file And configuration options. In such case waybar applies configuration file first then overrides particular options by the provided list of configuration options
# ACTIONS
[- *String*
:- *Action*
|[ *mode*
:< Switch main cava thread and fetching audio source thread from/to pause/resume
# DEPENDENCIES
- iniparser
- fftw3
# SOLVING ISSUES
. On start Waybar throws an exception "error while loading shared libraries: libcava.so: cannot open shared object file: No such file or directory".
It might happen when libcava for some reason hasn't been registered in the system. sudo ldconfig should help
. Waybar is starting but cava module doesn't react on the music
1. In such case for at first need to make sure usual cava application is working as well
2. If so, need to comment all configuration options. Uncomment cava_config and provide the path to the working cava config
3. You might set too huge or too small input_delay. Try to setup to 4 seconds, restart waybar and check again 4 seconds past. Usual even on weak machines it should be enough
4. You might accidentally switched action mode to pause mode
# RISING ISSUES
For clear understanding: this module is a cava API's consumer. So for any bugs related to cava engine you should contact to Cava upstream(https://github.com/karlstav/cava) ++
with the one Exception. Cava upstream doesn't provide cava as a shared library. For that this module author made a fork libcava(https://github.com/LukashonakV/cava). ++
So the order is:
. cava upstream
. libcava upstream.
In case when cava releases new version and you're wanna get it, it should be raised an issue to libcava(https://github.com/LukashonakV/cava) with title ++
\[Bump\]x.x.x where x.x.x is cava release version.
# EXAMPLES
```
"cava": {
//"cava_config": "$XDG_CONFIG_HOME/cava/cava.conf",
"framerate": 30,
"autosens": 1,
//"sensitivity": 100,
"bars": 14,
"lower_cutoff_freq": 50,
"higher_cutoff_freq": 10000,
"method": "pulse",
"source": "auto",
"stereo": true,
"reverse": false,
"bar_delimiter": 0,
"monstercat": false,
"waves": false,
"noise_reduction": 0.77,
"input_delay": 2,
"format-icons" : ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" ],
"actions": {
"on-click-right": "mode"
}
},
```

View File

@ -1,4 +1,4 @@
waybar-clock(5) "waybar-clock" "User Manual" waybar-clock(5)
# NAME # NAME
@ -6,265 +6,101 @@ waybar - clock module
# DESCRIPTION # DESCRIPTION
*clock* module displays current date and time The *clock* module displays the current date and time.
# FILES
$XDG_CONFIG_HOME/waybar/config ++
Per user configuration file
# CONFIGURATION # CONFIGURATION
1. Addressed by *clock* *interval*: ++
[- *Option* typeof: integer ++
:- *Typeof* default: 60 ++
:- *Default* The interval in which the information gets polled.
:- *Description*
|[ *interval*
:[ integer
:[ 60
:[ The interval in which the information gets polled
|[ *format*
:[ string
:[ *{:%H:%M}*
:[ The format, how the date and time should be displayed. See format options below
|[ *timezone*
:[ string
:[
:[ The timezone to display the time in, e.g. America/New_York. "" represents
the system's local timezone. See Wikipedia's unofficial list of timezones <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>
|[ *timezones*
:[ list of strings
:[
:[ A list of timezones (as in *timezone*) to use for time display, changed using
the scroll wheel. Do not specify *timezone* option when *timezones* is specified.
"" represents the system's local timezone
|[ *locale*
:[ string
:[
:[ A locale to be used to display the time. Intended to render times in custom
timezones with the proper language and format
|[ *max-length*
:[ integer
:[
:[ The maximum length in character the module should display
|[ *rotate*
:[ integer
:[
:[ Positive value to rotate the text label
|[ *on-click*
:[ string
:[
:[ Command to execute when clicked on the module
|[ *on-click-middle*
:[ string
:[
:[ Command to execute when you middle clicked on the module using mousewheel
|[ *on-click-right*
:[ string
:[
:[ Command to execute when you right clicked on the module
|[ *on-scroll-up*
:[ string
:[
:[ Command to execute when scrolling up on the module
|[ *on-scroll-down*
:[ string
:[
:[ Command to execute when scrolling down on the module
|[ *smooth-scrolling-threshold*
:[ double
:[
:[ Threshold to be used when scrolling
|[ *tooltip*
:[ bool
:[ true
:[ Option to enable tooltip on hover
|[ *tooltip-format*
:[ string
:[ same as format
:[ Tooltip on hover
View all valid format options in *strftime(3)* or have a look <https://fmt.dev/latest/syntax.html#chrono-specs> *format*: ++
typeof: string ++
default: {:%H:%M} ++
The format, how the date and time should be displayed. ++
It uses the format of the date library. See https://howardhinnant.github.io/date/date.html#to_stream_formatting for details.
2. Addressed by *clock: calendar* *timezone*: ++
[- *Option* typeof: string ++
:- *Typeof* default: inferred local timezone ++
:- *Default* The timezone to display the time in, e.g. America/New_York.
:- *Description*
|[ *mode*
:[ string
:[ month
:[ Calendar view mode. Possible values: year|month
|[ *mode-mon-col*
:[ integer
:[ 3
:[ Relevant for *mode=year*. Count of months per row
|[ *weeks-pos*
:[ integer
:[
:[ The position where week numbers should be displayed. Disabled when is empty.
Possible values: left|right
|[ *on-scroll*
:[ integer
:[ 1
:[ Value to scroll months/years forward/backward. Can be negative. Is
configured under *on-scroll* option
3. Addressed by *clock: calendar: format* *timezones*: ++
[- *Option* typeof: list of strings ++
:- *Typeof* A list of timezones to use for time display, changed using the scroll wheel. ++
:- *Default* Use "" to represent the system's local timezone. Using %Z in the format or tooltip format is useful to track which time zone is currently displayed.
:- *Description*
|[ *months*
:[ string
:[
:[ Format is applied to months header(January, February,...etc.)
|[ *days*
:[ string
:[
:[ Format is applied to days
|[ *weeks*
:[ string
:[ *{:%U}*
:[ Format is applied to week numbers. When weekday format is not provided then
is used default format: '{:%W}' when week starts with Monday, '{:%U}' otherwise
|[ *weekdays*
:[ string
:[
:[ Format is applied to weeks header(Su,Mo,...etc.)
|[ *today*
:[ string
:[ *<b><u>{}</u></b>*
:[ Format is applied to Today
## Actions *locale*: ++
typeof: string ++
default: inferred from current locale ++
A locale to be used to display the time. Intended to render times in custom timezones with the proper language and format.
[- *String* *today-format*: ++
:- *Action* typeof: string ++
|[ *mode* default: <b><u>{}</u></b> ++
:[ Switch calendar mode between year/month The format of today's date in the calendar.
|[ *tz_up*
:[ Switch to the next provided time zone *max-length*: ++
|[ *tz_down* typeof: integer ++
:[ Switch to the previous provided time zone The maximum length in character the module should display.
|[ *shift_up*
:[ Switch to the next calendar month/year *min-length*: ++
|[ *shift_down* typeof: integer ++
:[ Switch to the previous calendar month/year The minimum length in characters the module should take up.
*align*: ++
typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*rotate*: ++
typeof: integer ++
Positive value to rotate the text label.
*on-click*: ++
typeof: string ++
Command to execute when clicked on the module.
*on-click-middle*: ++
typeof: string ++
Command to execute when middle-clicked on the module using mousewheel.
*on-click-right*: ++
typeof: string ++
Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++
typeof: string ++
Command to execute when scrolling up on the module.
*on-scroll-down*: ++
typeof: string ++
Command to execute when scrolling down on the module.
*smooth-scrolling-threshold*: ++
typeof: double ++
Threshold to be used when scrolling.
View all valid format options in *strftime(3)*.
# FORMAT REPLACEMENTS # FORMAT REPLACEMENTS
- *{calendar}*: Current month calendar *{calendar}*: Current month calendar
- *{timezoned_time_list}*: List of time in the rest timezones, if more than one timezone is set in the config
# EXAMPLES # EXAMPLES
1. General
``` ```
"clock": { "clock": {
"interval": 60, "interval": 60,
"format": "{:%H:%M}", "format": "{:%H:%M}",
"max-length": 25 "max-length": 25
}
```
2. Calendar
```
"clock": {
"format": "{:%H:%M}  ",
"format-alt": "{:%A, %B %d, %Y (%R)}  ",
"tooltip-format": "<tt><small>{calendar}</small></tt>",
"calendar": {
"mode" : "year",
"mode-mon-col" : 3,
"weeks-pos" : "right",
"on-scroll" : 1,
"on-click-right": "mode",
"format": {
"months": "<span color='#ffead3'><b>{}</b></span>",
"days": "<span color='#ecc6d9'><b>{}</b></span>",
"weeks": "<span color='#99ffdd'><b>W{}</b></span>",
"weekdays": "<span color='#ffcc66'><b>{}</b></span>",
"today": "<span color='#ff6699'><b><u>{}</u></b></span>"
}
},
"actions": {
"on-click-right": "mode",
"on-click-forward": "tz_up",
"on-click-backward": "tz_down",
"on-scroll-up": "shift_up",
"on-scroll-down": "shift_down"
}
},
```
3. Full date on hover
```
"clock": {
"interval": 60,
"tooltip": true,
"format": "{:%H.%M}",
"tooltip-format": "{:%Y-%m-%d}",
} }
``` ```
# STYLE # STYLE
- *#clock* - *#clock*
# Troubleshooting
If clock module is disabled at startup with locale::facet::\_S\_create\_c\_locale ++
name not valid error message try one of the followings:
- check if LC_TIME is set properly (glibc)
- set locale to C in the config file (musl)
The locale option must be set for {calendar} to use the correct start-of-week, regardless of system locale.
## Calendar in Chinese. Alignment
In order to have aligned Chinese calendar there are some useful recommendations:
. Use "WenQuanYi Zen Hei Mono" which is provided in most Linux distributions
. Try different font sizes and find best for you. size = 9pt should be fine
. In case when "WenQuanYi Zen Hei Mono" font is used disable monospace font pango tag
Example of working config
```
"clock": {
"format": "{:%H:%M}  ",
"format-alt": "{:%A, %B %d, %Y (%R)}  ",
"tooltip-format": "\n<span size='9pt' font='WenQuanYi Zen Hei Mono'>{calendar}</span>",
"calendar": {
"mode" : "year",
"mode-mon-col" : 3,
"weeks-pos" : "right",
"on-scroll" : 1,
"on-click-right": "mode",
"format": {
"months": "<span color='#ffead3'><b>{}</b></span>",
"days": "<span color='#ecc6d9'><b>{}</b></span>",
"weeks": "<span color='#99ffdd'><b>W{}</b></span>",
"weekdays": "<span color='#ffcc66'><b>{}</b></span>",
"today": "<span color='#ff6699'><b><u>{}</u></b></span>"
}
},
"actions": {
"on-click-right": "mode",
"on-click-forward": "tz_up",
"on-click-backward": "tz_down",
"on-scroll-up": "shift_up",
"on-scroll-down": "shift_down"
}
},
```
# AUTHOR
Alexis Rouillard <contact@arouillard.fr>

View File

@ -20,29 +20,24 @@ The *cpu* module displays the current cpu utilization.
default: {usage}% ++ default: {usage}% ++
The format, how information should be displayed. On {} data gets inserted. The format, how information should be displayed. On {} data gets inserted.
*format-icons*: ++
typeof: array/object ++
Based on the current usage, the corresponding icon gets selected. ++
The order is *low* to *high*. Or by the state if it is an object.
*max-length*: ++ *max-length*: ++
typeof: integer ++ typeof: integer ++
The maximum length in character the module should display. The maximum length in character the module should display.
*min-length*: ++ *min-length*: ++
typeof: integer ++ typeof: integer ++
The minimum length in characters the module should take up. The minimum length in characters the module should take up.
*align*: ++ *align*: ++
typeof: float ++ typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*rotate*: ++ *rotate*: ++
typeof: integer ++ typeof: integer ++
Positive value to rotate the text label. Positive value to rotate the text label.
*states*: ++ *states*: ++
typeof: object ++ typeof: array ++
A number of cpu usage states which get activated on certain usage levels. See *waybar-states(5)*. A number of cpu usage states which get activated on certain usage levels. See *waybar-states(5)*.
*on-click*: ++ *on-click*: ++
@ -82,9 +77,7 @@ The *cpu* module displays the current cpu utilization.
*{load}*: Current cpu load. *{load}*: Current cpu load.
*{usage}*: Current overall cpu usage. *{usage}*: Current cpu usage.
*{usage*{n}*}*: Current cpu core n usage. Cores are numbered from zero, so first core will be {usage0} and 4th will be {usage3}.
*{avg_frequency}*: Current cpu average frequency (based on all cores) in GHz. *{avg_frequency}*: Current cpu average frequency (based on all cores) in GHz.
@ -92,13 +85,7 @@ The *cpu* module displays the current cpu utilization.
*{min_frequency}*: Current cpu min frequency (based on the core with the lowest frequency) in GHz. *{min_frequency}*: Current cpu min frequency (based on the core with the lowest frequency) in GHz.
*{icon}*: Icon for overall cpu usage. # EXAMPLE
*{icon*{n}*}*: Icon for cpu core n usage. Use like {icon0}.
# EXAMPLES
Basic configuration:
``` ```
"cpu": { "cpu": {
@ -108,16 +95,6 @@ Basic configuration:
} }
``` ```
Cpu usage per core rendered as icons:
```
"cpu": {
"interval": 1,
"format": "{icon0}{icon1}{icon2}{icon3} {usage:>2}% ",
"format-icons": ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"],
},
```
# STYLE # STYLE
- *#cpu* - *#cpu*

View File

@ -1,4 +1,5 @@
waybar-custom(5) waybar-custom(5)
# NAME # NAME
waybar - custom module waybar - custom module
@ -18,13 +19,14 @@ Addressed by *custom/<name>*
*exec-if*: ++ *exec-if*: ++
typeof: string ++ typeof: string ++
The path to a script, which determines if the script in *exec* should be executed. ++ The path to a script, which determines if the script in *exec* should be executed.
*exec* will be executed if the exit code of *exec-if* equals 0. *exec* will be executed if the exit code of *exec-if* equals 0.
*exec-on-event*: ++ *exec-on-event*: ++
typeof: bool ++ typeof: bool ++
default: true ++ default: true ++
If an event command is set (e.g. *on-click* or *on-scroll-up*) then re-execute the script after executing the event command. If an event command is set (e.g. *on-click* or *on-scroll-up*) then re-execute the script after
executing the event command.
*return-type*: ++ *return-type*: ++
typeof: string ++ typeof: string ++
@ -32,19 +34,20 @@ Addressed by *custom/<name>*
*interval*: ++ *interval*: ++
typeof: integer ++ typeof: integer ++
The interval (in seconds) in which the information gets polled. ++ The interval (in seconds) in which the information gets polled.
Use *once* if you want to execute the module only on startup. ++ Use *once* if you want to execute the module only on startup.
You can update it manually with a signal. If no *interval* is defined, it is assumed that the out script loops it self. You can update it manually with a signal. If no *interval* is defined,
it is assumed that the out script loops it self.
*restart-interval*: ++ *restart-interval*: ++
typeof: integer ++ typeof: integer ++
The restart interval (in seconds). ++ The restart interval (in seconds).
Can't be used with the *interval* option, so only with continuous scripts. ++ Can't be used with the *interval* option, so only with continuous scripts.
Once the script exit, it'll be re-executed after the *restart-interval*. Once the script exit, it'll be re-executed after the *restart-interval*.
*signal*: ++ *signal*: ++
typeof: integer ++ typeof: integer ++
The signal number used to update the module. ++ The signal number used to update the module.
The number is valid between 1 and N, where *SIGRTMIN+N* = *SIGRTMAX*. The number is valid between 1 and N, where *SIGRTMIN+N* = *SIGRTMAX*.
*format*: ++ *format*: ++
@ -65,12 +68,12 @@ Addressed by *custom/<name>*
The maximum length in character the module should display. The maximum length in character the module should display.
*min-length*: ++ *min-length*: ++
typeof: integer ++ typeof: integer ++
The minimum length in characters the module should take up. The minimum length in characters the module should take up.
*align*: ++ *align*: ++
typeof: float ++ typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text. The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*on-click*: ++ *on-click*: ++
typeof: string ++ typeof: string ++
@ -148,8 +151,7 @@ $text\\n$tooltip\\n$class*
"max-length": 40, "max-length": 40,
"interval": 30, // Remove this if your script is endless and write in loop "interval": 30, // Remove this if your script is endless and write in loop
"exec": "$HOME/.config/waybar/mediaplayer.sh 2> /dev/null", // Script in resources folder "exec": "$HOME/.config/waybar/mediaplayer.sh 2> /dev/null", // Script in resources folder
"exec-if": "pgrep spotify", "exec-if": "pgrep spotify"
"return-type": "json"
} }
``` ```

Some files were not shown because too many files have changed in this diff Show More