Merge remote-tracking branch 'origin/master' into pr/pulseaudio_mapping
# Conflicts: # src/util/audio_backend.cpp
This commit is contained in:
@@ -7,13 +7,12 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v6
|
||||||
- uses: DoozyX/clang-format-lint-action@v0.16.2
|
- uses: RafikFarhad/clang-format-github-action@v6
|
||||||
name: clang-format
|
name: clang-format
|
||||||
with:
|
with:
|
||||||
source: "."
|
sources: "src/**/*.hpp,src/**/*.cpp"
|
||||||
extensions: "hpp,h,cpp,c"
|
style: "file"
|
||||||
clangFormatVersion: 16
|
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: alexays/waybar:debian
|
image: alexays/waybar:debian
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v6
|
||||||
- name: configure
|
- name: configure
|
||||||
run: |
|
run: |
|
||||||
meson -Dcpp_std=c++20 build # necessary to generate compile_commands.json
|
meson -Dcpp_std=c++20 build # necessary to generate compile_commands.json
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
name: Build and Push Docker Image
|
name: Build and Push Docker Image
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
# run every night at midnight
|
# run monthly
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 0 1 * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-push:
|
build-and-push:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name != 'schedule' || github.repository == 'Alexays/Waybar'
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false # don't fail the other jobs if one of the images fails to build
|
fail-fast: false # don't fail the other jobs if one of the images fails to build
|
||||||
matrix:
|
matrix:
|
||||||
@@ -15,7 +17,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
|
|||||||
@@ -7,21 +7,21 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
clang:
|
build:
|
||||||
# Run actions in a FreeBSD VM on the ubuntu runner
|
# Run actions in a FreeBSD VM on the ubuntu runner
|
||||||
# https://github.com/actions/runner/issues/385 - for FreeBSD runner support
|
# https://github.com/actions/runner/issues/385 - for FreeBSD runner support
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v6
|
||||||
- name: Test in FreeBSD VM
|
- name: Test in FreeBSD VM
|
||||||
uses: cross-platform-actions/action@v0.25.0
|
uses: cross-platform-actions/action@v0.28.0
|
||||||
timeout-minutes: 180
|
timeout-minutes: 180
|
||||||
env:
|
env:
|
||||||
CPPFLAGS: '-isystem/usr/local/include'
|
CPPFLAGS: '-isystem/usr/local/include'
|
||||||
LDFLAGS: '-L/usr/local/lib'
|
LDFLAGS: '-L/usr/local/lib'
|
||||||
with:
|
with:
|
||||||
operating_system: freebsd
|
operating_system: freebsd
|
||||||
version: "14.1"
|
version: "14.2"
|
||||||
environment_variables: CPPFLAGS LDFLAGS
|
environment_variables: CPPFLAGS LDFLAGS
|
||||||
sync_files: runner-to-vm
|
sync_files: runner-to-vm
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ jobs:
|
|||||||
image: alexays/waybar:${{ matrix.distro }}
|
image: alexays/waybar:${{ matrix.distro }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v6
|
||||||
- name: configure
|
- name: configure
|
||||||
run: meson setup -Dman-pages=enabled -Dcpp_std=${{matrix.cpp_std}} build
|
run: meson setup -Dman-pages=enabled -Dcpp_std=${{matrix.cpp_std}} build
|
||||||
- name: build
|
- name: build
|
||||||
|
|||||||
@@ -2,16 +2,19 @@ name: "Nix-Tests"
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-nix-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
jobs:
|
jobs:
|
||||||
nix-flake-check:
|
nix-flake-check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- uses: cachix/install-nix-action@v27
|
- uses: cachix/install-nix-action@v31
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
- run: nix flake show
|
- run: nix flake show
|
||||||
- run: nix flake check --print-build-logs
|
- run: nix flake check --print-build-logs
|
||||||
- run: nix build --print-build-logs
|
- run: nix build --print-build-logs
|
||||||
|
|||||||
@@ -4,18 +4,19 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 1 * *' # Run monthly
|
- cron: '0 0 1 * *' # Run monthly
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- 'flake.nix'
|
- 'flake.nix'
|
||||||
jobs:
|
jobs:
|
||||||
lockfile:
|
lockfile:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name != 'schedule' || github.repository == 'Alexays/Waybar'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: cachix/install-nix-action@v27
|
uses: cachix/install-nix-action@v31
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Update flake.lock
|
- name: Update flake.lock
|
||||||
uses: DeterminateSystems/update-flake-lock@v21
|
uses: DeterminateSystems/update-flake-lock@v28
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ vgcore.*
|
|||||||
*.swp
|
*.swp
|
||||||
packagecache
|
packagecache
|
||||||
/subprojects/**/
|
/subprojects/**/
|
||||||
|
/subprojects/.wraplock
|
||||||
/build*
|
/build*
|
||||||
/dist
|
/dist
|
||||||
/meson.egg-info
|
/meson.egg-info
|
||||||
@@ -50,3 +51,5 @@ result
|
|||||||
result-*
|
result-*
|
||||||
|
|
||||||
.ccls-cache
|
.ccls-cache
|
||||||
|
_codeql_detected_source_root
|
||||||
|
heaptrack*
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# vim: ft=Dockerfile
|
# vim: ft=Dockerfile
|
||||||
|
|
||||||
FROM debian:sid
|
FROM debian:sid-slim
|
||||||
|
|
||||||
RUN apt update && \
|
RUN apt update && \
|
||||||
apt install --no-install-recommends --no-install-suggests -y \
|
apt install --no-install-recommends --no-install-suggests -y \
|
||||||
|
|||||||
+1
-1
@@ -6,6 +6,6 @@ RUN export FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox -sandbox -usersa
|
|||||||
emerge --sync && \
|
emerge --sync && \
|
||||||
eselect news read --quiet new 1>/dev/null 2>&1 && \
|
eselect news read --quiet new 1>/dev/null 2>&1 && \
|
||||||
emerge --verbose --update --deep --with-bdeps=y --backtrack=30 --newuse @world && \
|
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 \
|
USE="wayland gtk3 gtk -doc X pulseaudio minimal" emerge dev-vcs/git dev-libs/wayland dev-libs/wayland-protocols dev-cpp/gtkmm:3.0 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 \
|
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
|
media-sound/sndio gui-libs/gtk-layer-shell app-text/scdoc media-sound/playerctl dev-libs/iniparser sci-libs/fftw
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018 Alex
|
Copyright (c) 2025 Alex
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -20,8 +20,12 @@ debug-run: build-debug
|
|||||||
./build/waybar --log-level debug
|
./build/waybar --log-level debug
|
||||||
|
|
||||||
test:
|
test:
|
||||||
meson test -C build --no-rebuild --verbose --suite waybar
|
meson test -C build --verbose --suite waybar
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|
||||||
|
test-detailed:
|
||||||
|
meson test -C build --verbose --print-errorlogs --test-args='--reporter console -s'
|
||||||
|
.PHONY: test-detailed
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build
|
rm -rf build
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
- Sway (Workspaces, Binding mode, Focused window name)
|
- Sway (Workspaces, Binding mode, Focused window name)
|
||||||
- River (Mapping mode, Tags, Focused window name)
|
- River (Mapping mode, Tags, Focused window name)
|
||||||
- Hyprland (Window Icons, Workspaces, Focused window name)
|
- Hyprland (Window Icons, Workspaces, Focused window name)
|
||||||
- DWL (Tags, Focused window name) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
|
- Niri (Workspaces, Focused window name, Language)
|
||||||
|
- DWL (Tags, Focused window name) [requires dwl ipc patch](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/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
|
||||||
@@ -115,11 +116,45 @@ sudo apt install \
|
|||||||
libxkbregistry-dev
|
libxkbregistry-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On Arch, you can use this command:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -S --asdeps \
|
||||||
|
gtkmm3 \
|
||||||
|
jsoncpp \
|
||||||
|
libsigc++ \
|
||||||
|
fmt \
|
||||||
|
wayland \
|
||||||
|
chrono-date \
|
||||||
|
spdlog \
|
||||||
|
gtk3 \
|
||||||
|
gobject-introspection \
|
||||||
|
libgirepository \
|
||||||
|
libpulse \
|
||||||
|
libnl \
|
||||||
|
libappindicator-gtk3 \
|
||||||
|
libdbusmenu-gtk3 \
|
||||||
|
libmpdclient \
|
||||||
|
sndio \
|
||||||
|
libevdev \
|
||||||
|
libxkbcommon \
|
||||||
|
upower \
|
||||||
|
meson \
|
||||||
|
cmake \
|
||||||
|
scdoc \
|
||||||
|
wayland-protocols \
|
||||||
|
glib2-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Contributions welcome!<br>
|
Contributions welcome!<br>
|
||||||
Have fun :)<br>
|
Have fun :)<br>
|
||||||
The style guidelines are [Google's](https://google.github.io/styleguide/cppguide.html)
|
The style guidelines are [Google's](https://google.github.io/styleguide/cppguide.html)
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> Distributions of Waybar are only released on the [official GitHub page](https://github.com/Alexays/Waybar).<br/>
|
||||||
|
> Waybar does **not** have an official website. Do not trust any sites that claim to be official.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Waybar is licensed under the MIT license. [See LICENSE for more information](https://github.com/Alexays/Waybar/blob/master/LICENSE).
|
Waybar is licensed under the MIT license. [See LICENSE for more information](https://github.com/Alexays/Waybar/blob/master/LICENSE).
|
||||||
|
|||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Suppress common address sanitizer issues in dependencies, these are often non-fixable or not an issue.
|
||||||
|
# Use it like this (when in repo root): ASAN_OPTIONS="suppressions=./asan.supp" ./build/waybar
|
||||||
|
leak:libpangoft2-1.0.so.0
|
||||||
|
leak:libgtk-3.so.0
|
||||||
|
leak:libfontconfig.so.1
|
||||||
+9
-10
@@ -1,10 +1,9 @@
|
|||||||
(import
|
(import (
|
||||||
(
|
let
|
||||||
let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
|
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
|
||||||
fetchTarball {
|
in
|
||||||
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
fetchTarball {
|
||||||
sha256 = lock.nodes.flake-compat.locked.narHash;
|
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||||
}
|
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||||
)
|
}
|
||||||
{ src = ./.; }
|
) { src = ./.; }).defaultNix
|
||||||
).defaultNix
|
|
||||||
|
|||||||
Generated
+6
-6
@@ -3,11 +3,11 @@
|
|||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1696426674,
|
"lastModified": 1767039857,
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||||
"owner": "edolstra",
|
"owner": "edolstra",
|
||||||
"repo": "flake-compat",
|
"repo": "flake-compat",
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -18,11 +18,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1722185531,
|
"lastModified": 1769461804,
|
||||||
"narHash": "sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k=",
|
"narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "52ec9ac3b12395ad677e8b62106f0b98c1f8569d",
|
"rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -9,47 +9,94 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, ... }:
|
outputs =
|
||||||
|
{ self, nixpkgs, ... }:
|
||||||
let
|
let
|
||||||
inherit (nixpkgs) lib;
|
inherit (nixpkgs) lib;
|
||||||
genSystems = func: lib.genAttrs [
|
genSystems =
|
||||||
"x86_64-linux"
|
func:
|
||||||
"aarch64-linux"
|
lib.genAttrs
|
||||||
]
|
[
|
||||||
(system: func (import nixpkgs {
|
"x86_64-linux"
|
||||||
inherit system;
|
"aarch64-linux"
|
||||||
overlays = with self.overlays; [
|
]
|
||||||
waybar
|
(
|
||||||
];
|
system:
|
||||||
}));
|
func (
|
||||||
|
import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = with self.overlays; [
|
||||||
|
waybar
|
||||||
|
];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
mkDate = longDate: (lib.concatStringsSep "-" [
|
mkDate =
|
||||||
(builtins.substring 0 4 longDate)
|
longDate:
|
||||||
(builtins.substring 4 2 longDate)
|
(lib.concatStringsSep "-" [
|
||||||
(builtins.substring 6 2 longDate)
|
(builtins.substring 0 4 longDate)
|
||||||
]);
|
(builtins.substring 4 2 longDate)
|
||||||
|
(builtins.substring 6 2 longDate)
|
||||||
|
]);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
devShells = genSystems
|
devShells = genSystems (pkgs: {
|
||||||
(pkgs:
|
default = pkgs.mkShell {
|
||||||
{
|
name = "waybar-shell";
|
||||||
default =
|
|
||||||
pkgs.mkShell
|
|
||||||
{
|
|
||||||
name = "waybar-shell";
|
|
||||||
|
|
||||||
# inherit attributes from upstream nixpkgs derivation
|
# inherit attributes from upstream nixpkgs derivation
|
||||||
inherit (pkgs.waybar) buildInputs depsBuildBuild depsBuildBuildPropagated depsBuildTarget
|
inherit (pkgs.waybar)
|
||||||
depsBuildTargetPropagated depsHostHost depsHostHostPropagated depsTargetTarget
|
buildInputs
|
||||||
depsTargetTargetPropagated propagatedBuildInputs propagatedNativeBuildInputs strictDeps;
|
depsBuildBuild
|
||||||
|
depsBuildBuildPropagated
|
||||||
|
depsBuildTarget
|
||||||
|
depsBuildTargetPropagated
|
||||||
|
depsHostHost
|
||||||
|
depsHostHostPropagated
|
||||||
|
depsTargetTarget
|
||||||
|
depsTargetTargetPropagated
|
||||||
|
propagatedBuildInputs
|
||||||
|
propagatedNativeBuildInputs
|
||||||
|
strictDeps
|
||||||
|
;
|
||||||
|
|
||||||
# overrides for local development
|
# overrides for local development
|
||||||
nativeBuildInputs = pkgs.waybar.nativeBuildInputs ++ (with pkgs; [
|
nativeBuildInputs =
|
||||||
clang-tools
|
pkgs.waybar.nativeBuildInputs
|
||||||
gdb
|
++ (with pkgs; [
|
||||||
]);
|
nixfmt
|
||||||
};
|
clang-tools
|
||||||
});
|
gdb
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
formatter = genSystems (
|
||||||
|
pkgs:
|
||||||
|
pkgs.treefmt.withConfig {
|
||||||
|
settings = {
|
||||||
|
formatter = {
|
||||||
|
clang-format = {
|
||||||
|
options = [ "-i" ];
|
||||||
|
command = lib.getExe' pkgs.clang-tools "clang-format";
|
||||||
|
excludes = [ ];
|
||||||
|
includes = [
|
||||||
|
"*.c"
|
||||||
|
"*.cpp"
|
||||||
|
"*.h"
|
||||||
|
"*.hpp"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
nixfmt = {
|
||||||
|
command = lib.getExe pkgs.nixfmt;
|
||||||
|
includes = [ "*.nix" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
tree-root-file = ".git/index";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
overlays = {
|
overlays = {
|
||||||
default = self.overlays.waybar;
|
default = self.overlays.waybar;
|
||||||
@@ -58,11 +105,15 @@
|
|||||||
waybar = prev.waybar;
|
waybar = prev.waybar;
|
||||||
# take the first "version: '...'" from meson.build
|
# take the first "version: '...'" from meson.build
|
||||||
version =
|
version =
|
||||||
(builtins.head (builtins.split "'"
|
(builtins.head (
|
||||||
(builtins.elemAt
|
builtins.split "'" (
|
||||||
(builtins.split " version: '" (builtins.readFile ./meson.build))
|
builtins.elemAt (builtins.split " version: '" (builtins.readFile ./meson.build)) 2
|
||||||
2)))
|
)
|
||||||
+ "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
))
|
||||||
|
+ "+date="
|
||||||
|
+ (mkDate (self.lastModifiedDate or "19700101"))
|
||||||
|
+ "_"
|
||||||
|
+ (self.shortRev or "dirty");
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ namespace waybar {
|
|||||||
|
|
||||||
class AAppIconLabel : public AIconLabel {
|
class AAppIconLabel : public AIconLabel {
|
||||||
public:
|
public:
|
||||||
AAppIconLabel(const Json::Value &config, const std::string &name, const std::string &id,
|
AAppIconLabel(const Json::Value& config, const std::string& name, const std::string& id,
|
||||||
const std::string &format, uint16_t interval = 0, bool ellipsize = false,
|
const std::string& format, uint16_t interval = 0, bool ellipsize = false,
|
||||||
bool enable_click = false, bool enable_scroll = false);
|
bool enable_click = false, bool enable_scroll = false);
|
||||||
virtual ~AAppIconLabel() = default;
|
virtual ~AAppIconLabel() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateAppIconName(const std::string &app_identifier,
|
void updateAppIconName(const std::string& app_identifier,
|
||||||
const std::string &alternative_app_identifier);
|
const std::string& alternative_app_identifier);
|
||||||
void updateAppIcon();
|
void updateAppIcon();
|
||||||
unsigned app_icon_size_{24};
|
unsigned app_icon_size_{24};
|
||||||
bool update_app_icon_{true};
|
bool update_app_icon_{true};
|
||||||
|
|||||||
@@ -9,15 +9,19 @@ namespace waybar {
|
|||||||
|
|
||||||
class AIconLabel : public ALabel {
|
class AIconLabel : public ALabel {
|
||||||
public:
|
public:
|
||||||
AIconLabel(const Json::Value &config, const std::string &name, const std::string &id,
|
AIconLabel(const Json::Value& config, const std::string& name, const std::string& id,
|
||||||
const std::string &format, uint16_t interval = 0, bool ellipsize = false,
|
const std::string& format, uint16_t interval = 0, bool ellipsize = false,
|
||||||
bool enable_click = false, bool enable_scroll = false);
|
bool enable_click = false, bool enable_scroll = false);
|
||||||
virtual ~AIconLabel() = default;
|
virtual ~AIconLabel() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
static std::tuple<std::string, std::string> extractIcon(const std::string& input);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Gtk::Image image_;
|
Gtk::Image image_;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
|
unsigned app_icon_size_{24};
|
||||||
|
|
||||||
|
bool label_contains_icon{false};
|
||||||
|
|
||||||
bool iconEnabled() const;
|
bool iconEnabled() const;
|
||||||
};
|
};
|
||||||
|
|||||||
+16
-7
@@ -4,33 +4,42 @@
|
|||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
|
|
||||||
namespace waybar {
|
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;
|
auto update() -> void override;
|
||||||
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::milliseconds interval_;
|
||||||
bool alt_ = false;
|
bool alt_ = false;
|
||||||
std::string default_format_;
|
std::string default_format_;
|
||||||
|
|
||||||
bool handleToggle(GdkEventButton *const &e) override;
|
bool setLabelMarkup(const Glib::ustring& markup);
|
||||||
|
bool setTooltipMarkup(const Glib::ustring& markup);
|
||||||
|
|
||||||
|
bool handleToggle(GdkEventButton* const& e) override;
|
||||||
virtual std::string getState(uint8_t value, bool lesser = false);
|
virtual std::string getState(uint8_t value, bool lesser = false);
|
||||||
|
|
||||||
std::map<std::string, GtkMenuItem *> submenus_;
|
std::map<std::string, GtkMenuItem*> submenus_;
|
||||||
std::map<std::string, std::string> menuActionsMap_;
|
std::map<std::string, std::string> menuActionsMap_;
|
||||||
static void handleGtkMenuEvent(GtkMenuItem *menuitem, gpointer data);
|
static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<Glib::ustring> last_label_markup_;
|
||||||
|
std::optional<Glib::ustring> last_tooltip_markup_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
+26
-16
@@ -12,48 +12,58 @@ namespace waybar {
|
|||||||
|
|
||||||
class AModule : public IModule {
|
class AModule : public IModule {
|
||||||
public:
|
public:
|
||||||
static constexpr const char *MODULE_CLASS = "module";
|
static constexpr const char* MODULE_CLASS = "module";
|
||||||
|
|
||||||
~AModule() override;
|
~AModule() override;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
virtual auto refresh(int shouldRefresh) -> void{};
|
virtual auto refresh(int shouldRefresh) -> void {};
|
||||||
operator Gtk::Widget &() override;
|
operator Gtk::Widget&() override;
|
||||||
auto doAction(const std::string &name) -> void override;
|
auto doAction(const std::string& name) -> void override;
|
||||||
|
|
||||||
/// Emitting on this dispatcher triggers a update() call
|
/// Emitting on this dispatcher triggers a update() call
|
||||||
Glib::Dispatcher dp;
|
Glib::Dispatcher dp;
|
||||||
|
|
||||||
|
bool expandEnabled() const;
|
||||||
|
|
||||||
|
virtual void suspend() {};
|
||||||
|
virtual void resume() {};
|
||||||
|
bool shouldSuspend() const { return disable_on_sleep_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Don't need to make an object directly
|
// Don't need to make an object directly
|
||||||
// Derived classes are able to use it
|
// Derived classes are able to use it
|
||||||
AModule(const Json::Value &, const std::string &, const std::string &, bool enable_click = false,
|
AModule(const Json::Value&, const std::string&, const std::string&, bool enable_click = false,
|
||||||
bool enable_scroll = 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() const;
|
bool tooltipEnabled() const;
|
||||||
|
|
||||||
|
std::vector<int> pid_children_;
|
||||||
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 void setCursor(Gdk::CursorType const &c);
|
virtual void setCursor(Gdk::CursorType const& c);
|
||||||
|
|
||||||
virtual bool handleToggle(GdkEventButton *const &ev);
|
virtual bool handleToggle(GdkEventButton* const& ev);
|
||||||
virtual bool handleMouseEnter(GdkEventCrossing *const &ev);
|
virtual bool handleMouseEnter(GdkEventCrossing* const& ev);
|
||||||
virtual bool handleMouseLeave(GdkEventCrossing *const &ev);
|
virtual bool handleMouseLeave(GdkEventCrossing* const& ev);
|
||||||
virtual bool handleScroll(GdkEventScroll *);
|
virtual bool handleScroll(GdkEventScroll*);
|
||||||
virtual bool handleRelease(GdkEventButton *const &ev);
|
virtual bool handleRelease(GdkEventButton* const& ev);
|
||||||
GObject *menu_;
|
|
||||||
|
bool disable_on_sleep_{false};
|
||||||
|
GObject* menu_ = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool handleUserEvent(GdkEventButton *const &ev);
|
bool handleUserEvent(GdkEventButton* const& ev);
|
||||||
const bool isTooltip;
|
const bool isTooltip;
|
||||||
|
const bool isExpand;
|
||||||
bool hasUserEvents_;
|
bool hasUserEvents_;
|
||||||
std::vector<int> pid_;
|
|
||||||
gdouble distance_scrolled_y_;
|
gdouble distance_scrolled_y_;
|
||||||
gdouble distance_scrolled_x_;
|
gdouble distance_scrolled_x_;
|
||||||
|
sigc::connection cursor_timeout_conn_;
|
||||||
std::map<std::string, std::string> eventActionMap_;
|
std::map<std::string, std::string> eventActionMap_;
|
||||||
static const inline std::map<std::pair<uint, GdkEventType>, std::string> eventMap_{
|
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_BUTTON_PRESS), "on-click"},
|
||||||
|
|||||||
+23
-12
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
#include "group.hpp"
|
#include "group.hpp"
|
||||||
|
#include "util/kill_signal.hpp"
|
||||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
@@ -42,7 +43,7 @@ struct bar_margins {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct bar_mode {
|
struct bar_mode {
|
||||||
std::optional<bar_layer> layer;
|
bar_layer layer;
|
||||||
bool exclusive;
|
bool exclusive;
|
||||||
bool passthrough;
|
bool passthrough;
|
||||||
bool visible;
|
bool visible;
|
||||||
@@ -61,18 +62,24 @@ class Bar : public sigc::trackable {
|
|||||||
static const std::string MODE_DEFAULT;
|
static const std::string MODE_DEFAULT;
|
||||||
static const std::string MODE_INVISIBLE;
|
static const std::string 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();
|
||||||
|
|
||||||
void setMode(const std::string &mode);
|
void setMode(const std::string& mode);
|
||||||
void setVisible(bool value);
|
void setVisible(bool value);
|
||||||
void toggle();
|
void toggle();
|
||||||
|
void show();
|
||||||
|
void hide();
|
||||||
void handleSignal(int);
|
void handleSignal(int);
|
||||||
|
util::KillSignalAction getOnSigusr1Action();
|
||||||
|
util::KillSignalAction getOnSigusr2Action();
|
||||||
|
|
||||||
struct waybar_output *output;
|
void toggleSuspend(bool suspend);
|
||||||
|
|
||||||
|
struct waybar_output* output;
|
||||||
Json::Value config;
|
Json::Value config;
|
||||||
struct wl_surface *surface;
|
struct wl_surface* surface;
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
Gtk::Window window;
|
Gtk::Window window;
|
||||||
Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL;
|
Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL;
|
||||||
@@ -86,15 +93,16 @@ class Bar : public sigc::trackable {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onMap(GdkEventAny *);
|
void onMap(GdkEventAny*);
|
||||||
auto setupWidgets() -> void;
|
auto setupWidgets() -> void;
|
||||||
void getModules(const Factory &, const std::string &, waybar::Group *);
|
void getModules(const Factory&, const std::string&, waybar::Group*);
|
||||||
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 &);
|
void setMode(const bar_mode&);
|
||||||
void setPassThrough(bool passthrough);
|
void setPassThrough(bool passthrough);
|
||||||
void setPosition(Gtk::PositionType position);
|
void setPosition(Gtk::PositionType position);
|
||||||
void onConfigure(GdkEventConfigure *ev);
|
void forceLayerCommit();
|
||||||
|
void onConfigure(GdkEventConfigure* ev);
|
||||||
void configureGlobalOffset(int width, int height);
|
void configureGlobalOffset(int width, int height);
|
||||||
void onOutputGeometryChanged();
|
void onOutputGeometryChanged();
|
||||||
|
|
||||||
@@ -118,6 +126,9 @@ class Bar : public sigc::trackable {
|
|||||||
std::unique_ptr<BarIpcClient> _ipc_client;
|
std::unique_ptr<BarIpcClient> _ipc_client;
|
||||||
#endif
|
#endif
|
||||||
std::vector<std::shared_ptr<waybar::AModule>> modules_all_;
|
std::vector<std::shared_ptr<waybar::AModule>> modules_all_;
|
||||||
|
|
||||||
|
waybar::util::KillSignalAction onSigusr1 = util::SIGNALACTION_DEFAULT_SIGUSR1;
|
||||||
|
waybar::util::KillSignalAction onSigusr2 = util::SIGNALACTION_DEFAULT_SIGUSR2;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
+22
-17
@@ -17,35 +17,36 @@ 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 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;
|
Config config;
|
||||||
std::string bar_id;
|
std::string bar_id;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Client() = default;
|
Client() = default;
|
||||||
const std::string getStyle(const std::string &style, std::optional<Appearance> appearance);
|
const std::string getStyle(const std::string& style, std::optional<Appearance> appearance);
|
||||||
void bindInterfaces();
|
void bindInterfaces();
|
||||||
void handleOutput(struct waybar_output &output);
|
void handleOutput(struct waybar_output& output);
|
||||||
auto setupCss(const std::string &css_file) -> void;
|
auto setupCss(const std::string& css_file) -> void;
|
||||||
struct waybar_output &getOutput(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,
|
||||||
const char *interface, uint32_t version);
|
const char* interface, uint32_t version);
|
||||||
static void handleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name);
|
static void handleGlobalRemove(void* data, struct wl_registry* registry, uint32_t name);
|
||||||
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 *);
|
void createBarsBatch();
|
||||||
static void handleOutputDescription(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*);
|
||||||
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);
|
||||||
@@ -56,6 +57,10 @@ class Client {
|
|||||||
std::list<struct waybar_output> outputs_;
|
std::list<struct waybar_output> outputs_;
|
||||||
std::unique_ptr<CssReloadHelper> m_cssReloadHelper;
|
std::unique_ptr<CssReloadHelper> m_cssReloadHelper;
|
||||||
std::string m_cssFile;
|
std::string m_cssFile;
|
||||||
|
sigc::connection monitor_added_connection_;
|
||||||
|
sigc::connection monitor_removed_connection_;
|
||||||
|
std::list<waybar_output*> pending_outputs_;
|
||||||
|
bool bars_scheduled_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
+12
-10
@@ -14,27 +14,29 @@ namespace waybar {
|
|||||||
class Config {
|
class Config {
|
||||||
public:
|
public:
|
||||||
static const std::vector<std::string> CONFIG_DIRS;
|
static const std::vector<std::string> CONFIG_DIRS;
|
||||||
static const char *CONFIG_PATH_ENV;
|
static const char* CONFIG_PATH_ENV;
|
||||||
|
|
||||||
/* Try to find any of provided names in the supported set of config directories */
|
/* Try to find any of provided names in the supported set of config directories */
|
||||||
static std::optional<std::string> findConfigPath(
|
static std::optional<std::string> findConfigPath(
|
||||||
const std::vector<std::string> &names, const std::vector<std::string> &dirs = CONFIG_DIRS);
|
const std::vector<std::string>& names, const std::vector<std::string>& dirs = CONFIG_DIRS);
|
||||||
|
|
||||||
static std::optional<std::string> tryExpandPath(const std::string &base,
|
static std::vector<std::string> tryExpandPath(const std::string& base,
|
||||||
const std::string &filename);
|
const std::string& filename);
|
||||||
|
|
||||||
Config() = default;
|
Config() = default;
|
||||||
|
|
||||||
void load(const std::string &config);
|
void load(const std::string& config);
|
||||||
|
|
||||||
Json::Value &getConfig() { return config_; }
|
Json::Value& getConfig() { return config_; }
|
||||||
|
|
||||||
std::vector<Json::Value> getOutputConfigs(const std::string &name, const std::string &identifier);
|
std::vector<Json::Value> getOutputConfigs(const std::string& name, const std::string& identifier);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupConfig(Json::Value &dst, const std::string &config_file, int depth);
|
void setupConfig(Json::Value& dst, const std::string& config_file, int depth);
|
||||||
void resolveConfigIncludes(Json::Value &config, int depth);
|
void resolveConfigIncludes(Json::Value& config, int depth);
|
||||||
void mergeConfig(Json::Value &a_config_, Json::Value &b_config_);
|
void mergeConfig(Json::Value& a_config_, Json::Value& b_config_);
|
||||||
|
static std::vector<std::string> findIncludePath(
|
||||||
|
const std::string& name, const std::vector<std::string>& dirs = CONFIG_DIRS);
|
||||||
|
|
||||||
std::string config_file_;
|
std::string config_file_;
|
||||||
|
|
||||||
|
|||||||
+11
-7
@@ -10,14 +10,16 @@
|
|||||||
namespace waybar {
|
namespace waybar {
|
||||||
|
|
||||||
class Group : public AModule {
|
class Group : public AModule {
|
||||||
|
sigc::connection reveal_timeout_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Group(const std::string &, const std::string &, const Json::Value &, bool);
|
Group(const std::string&, const std::string&, const Json::Value&, bool);
|
||||||
~Group() override = default;
|
~Group() override = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
operator Gtk::Widget &() override;
|
operator Gtk::Widget&() override;
|
||||||
|
|
||||||
virtual Gtk::Box &getBox();
|
virtual Gtk::Box& getBox();
|
||||||
void addWidget(Gtk::Widget &widget);
|
void addWidget(Gtk::Widget& widget);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Gtk::Box box;
|
Gtk::Box box;
|
||||||
@@ -26,10 +28,12 @@ class Group : public AModule {
|
|||||||
bool is_first_widget = true;
|
bool is_first_widget = true;
|
||||||
bool is_drawer = false;
|
bool is_drawer = false;
|
||||||
bool click_to_reveal = false;
|
bool click_to_reveal = false;
|
||||||
|
int reveal_delay = 0;
|
||||||
std::string add_class_to_drawer_children;
|
std::string add_class_to_drawer_children;
|
||||||
bool handleMouseEnter(GdkEventCrossing *const &ev) override;
|
bool handleMouseEnter(GdkEventCrossing* const& ev) override;
|
||||||
bool handleMouseLeave(GdkEventCrossing *const &ev) override;
|
bool handleMouseLeave(GdkEventCrossing* const& ev) override;
|
||||||
bool handleToggle(GdkEventButton *const &ev) override;
|
bool handleToggle(GdkEventButton* const& ev) override;
|
||||||
|
bool handleScroll(GdkEventScroll* e) override;
|
||||||
void show_group();
|
void show_group();
|
||||||
void hide_group();
|
void hide_group();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ namespace waybar::modules {
|
|||||||
|
|
||||||
class Backlight : public ALabel {
|
class Backlight : public ALabel {
|
||||||
public:
|
public:
|
||||||
Backlight(const std::string &, const Json::Value &);
|
Backlight(const std::string&, const Json::Value&);
|
||||||
virtual ~Backlight() = default;
|
virtual ~Backlight() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
bool handleScroll(GdkEventScroll *e) override;
|
bool handleScroll(GdkEventScroll* e) override;
|
||||||
|
|
||||||
const std::string preferred_device_;
|
const std::string preferred_device_;
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,10 @@
|
|||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -15,6 +17,7 @@
|
|||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
#include "util/udev_deleter.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
@@ -35,16 +38,25 @@ class Battery : public ALabel {
|
|||||||
std::tuple<uint8_t, float, std::string, float, uint16_t, float> getInfos();
|
std::tuple<uint8_t, float, std::string, float, uint16_t, float> getInfos();
|
||||||
const std::string formatTimeRemaining(float hoursRemaining);
|
const std::string formatTimeRemaining(float hoursRemaining);
|
||||||
void setBarClass(std::string&);
|
void setBarClass(std::string&);
|
||||||
|
void processEvents(std::string& state, std::string& status, uint8_t capacity);
|
||||||
|
|
||||||
int global_watch;
|
|
||||||
std::map<fs::path, int> batteries_;
|
std::map<fs::path, int> batteries_;
|
||||||
|
std::unique_ptr<udev, util::UdevDeleter> udev_;
|
||||||
|
std::array<pollfd, 1> poll_fds_;
|
||||||
|
std::unique_ptr<udev_monitor, util::UdevMonitorDeleter> mon_;
|
||||||
fs::path adapter_;
|
fs::path adapter_;
|
||||||
int battery_watch_fd_;
|
int battery_watch_fd_;
|
||||||
int global_watch_fd_;
|
|
||||||
std::mutex battery_list_mutex_;
|
std::mutex battery_list_mutex_;
|
||||||
std::string old_status_;
|
std::string old_status_;
|
||||||
|
std::string last_event_;
|
||||||
bool warnFirstTime_{true};
|
bool warnFirstTime_{true};
|
||||||
|
bool weightedAverage_{true};
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
|
bool smoothPowerEnable_{false};
|
||||||
|
double time_constant_s_{260.0};
|
||||||
|
double smooth_power_{0.0}; // µW
|
||||||
|
std::chrono::steady_clock::time_point last_t_{std::chrono::steady_clock::now()};
|
||||||
|
std::string old_status_raw_{""};
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
util::SleeperThread thread_battery_update_;
|
util::SleeperThread thread_battery_update_;
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
|
||||||
#include "util/sleeper_thread.hpp"
|
|
||||||
|
|
||||||
namespace cava {
|
|
||||||
extern "C" {
|
|
||||||
#include <cava/common.h>
|
|
||||||
}
|
|
||||||
} // namespace cava
|
|
||||||
|
|
||||||
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 cava::error_s error_ {}; // cava errors
|
|
||||||
struct cava::config_params prm_ {}; // cava parameters
|
|
||||||
struct cava::audio_raw audio_raw_ {}; // cava handled raw audio data(is based on audio_data)
|
|
||||||
struct cava::audio_data audio_data_ {}; // cava audio data
|
|
||||||
struct cava::cava_plan* plan_; //{new cava_plan{}};
|
|
||||||
// Cava API to read audio source
|
|
||||||
cava::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};
|
|
||||||
bool hide_on_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
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <epoxy/gl.h>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "cava_backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
|
||||||
|
class CavaGLSL final : public AModule, public Gtk::GLArea {
|
||||||
|
public:
|
||||||
|
CavaGLSL(const std::string&, const Json::Value&);
|
||||||
|
~CavaGLSL() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<CavaBackend> backend_;
|
||||||
|
struct ::cava::config_params prm_;
|
||||||
|
int frame_counter{0};
|
||||||
|
bool silence_{false};
|
||||||
|
bool hide_on_silence_{false};
|
||||||
|
// Cava method
|
||||||
|
auto onUpdate(const ::cava::audio_raw& input) -> void;
|
||||||
|
auto onSilence() -> void;
|
||||||
|
// Member variable to store the shared pointer
|
||||||
|
std::shared_ptr<::cava::audio_raw> m_data_;
|
||||||
|
GLuint shaderProgram_;
|
||||||
|
// OpenGL variables
|
||||||
|
GLuint fbo_;
|
||||||
|
GLuint texture_;
|
||||||
|
GLint uniform_bars_;
|
||||||
|
GLint uniform_previous_bars_;
|
||||||
|
GLint uniform_bars_count_;
|
||||||
|
GLint uniform_time_;
|
||||||
|
// Methods
|
||||||
|
void onRealize();
|
||||||
|
bool onRender(const Glib::RefPtr<Gdk::GLContext>& context);
|
||||||
|
|
||||||
|
void initShaders();
|
||||||
|
void initSurface();
|
||||||
|
void initGLSL();
|
||||||
|
GLuint loadShader(const std::string& fileName, GLenum type);
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "cava_backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
|
||||||
|
class Cava final : public ALabel, public sigc::trackable {
|
||||||
|
public:
|
||||||
|
Cava(const std::string&, const Json::Value&);
|
||||||
|
~Cava() = default;
|
||||||
|
auto doAction(const std::string& name) -> void override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<CavaBackend> backend_;
|
||||||
|
// Text to display
|
||||||
|
Glib::ustring label_text_{""};
|
||||||
|
bool silence_{false};
|
||||||
|
bool hide_on_silence_{false};
|
||||||
|
std::string format_silent_{""};
|
||||||
|
int ascii_range_{0};
|
||||||
|
// Cava method
|
||||||
|
void pause_resume();
|
||||||
|
auto onUpdate(const std::string& input) -> void;
|
||||||
|
auto onSilence() -> void;
|
||||||
|
// ModuleActionMap
|
||||||
|
static inline std::map<const std::string, void (waybar::modules::cava::Cava::* const)()>
|
||||||
|
actionMap_{{"mode", &waybar::modules::cava::Cava::pause_resume}};
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <sigc++/sigc++.h>
|
||||||
|
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace cava {
|
||||||
|
extern "C" {
|
||||||
|
// Need sdl_glsl output feature to be enabled on libcava
|
||||||
|
#ifndef SDL_GLSL
|
||||||
|
#define SDL_GLSL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cava/common.h>
|
||||||
|
|
||||||
|
#ifdef SDL_GLSL
|
||||||
|
#undef SDL_GLSL
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} // namespace cava
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
|
class CavaBackend final {
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<CavaBackend> inst(const Json::Value& config);
|
||||||
|
|
||||||
|
virtual ~CavaBackend();
|
||||||
|
// Methods
|
||||||
|
int getAsciiRange();
|
||||||
|
void doPauseResume();
|
||||||
|
void Update();
|
||||||
|
const struct ::cava::config_params* getPrm();
|
||||||
|
std::chrono::milliseconds getFrameTimeMilsec();
|
||||||
|
|
||||||
|
// Signal accessor
|
||||||
|
using type_signal_update = sigc::signal<void(const std::string&)>;
|
||||||
|
type_signal_update signal_update();
|
||||||
|
using type_signal_audio_raw_update = sigc::signal<void(const ::cava::audio_raw&)>;
|
||||||
|
type_signal_audio_raw_update signal_audio_raw_update();
|
||||||
|
using type_signal_silence = sigc::signal<void()>;
|
||||||
|
type_signal_silence signal_silence();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CavaBackend(const Json::Value& config);
|
||||||
|
util::SleeperThread read_thread_;
|
||||||
|
util::SleeperThread out_thread_;
|
||||||
|
|
||||||
|
// Cava API to read audio source
|
||||||
|
::cava::ptr input_source_{NULL};
|
||||||
|
|
||||||
|
struct ::cava::error_s error_{}; // cava errors
|
||||||
|
struct ::cava::config_params prm_{}; // cava parameters
|
||||||
|
struct ::cava::audio_raw audio_raw_{}; // cava handled raw audio data(is based on audio_data)
|
||||||
|
struct ::cava::audio_data audio_data_{}; // cava audio data
|
||||||
|
struct ::cava::cava_plan* plan_{NULL}; //{new cava_plan{}};
|
||||||
|
|
||||||
|
std::chrono::seconds fetch_input_delay_{4};
|
||||||
|
// Delay to handle audio source
|
||||||
|
std::chrono::milliseconds frame_time_milsec_{1s};
|
||||||
|
|
||||||
|
const Json::Value& config_;
|
||||||
|
int re_paint_{0};
|
||||||
|
bool silence_{false};
|
||||||
|
bool silence_prev_{false};
|
||||||
|
std::chrono::seconds suspend_silence_delay_{0};
|
||||||
|
int sleep_counter_{0};
|
||||||
|
std::string output_{};
|
||||||
|
// Methods
|
||||||
|
void invoke();
|
||||||
|
void execute();
|
||||||
|
bool isSilence();
|
||||||
|
void doUpdate(bool force = false);
|
||||||
|
void loadConfig();
|
||||||
|
void freeBackend();
|
||||||
|
|
||||||
|
// Signal
|
||||||
|
type_signal_update m_signal_update_;
|
||||||
|
type_signal_audio_raw_update m_signal_audio_raw_;
|
||||||
|
type_signal_silence m_signal_silence_;
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBCAVA
|
||||||
|
#include "cavaRaw.hpp"
|
||||||
|
#include "cava_backend.hpp"
|
||||||
|
#ifdef HAVE_LIBCAVAGLSL
|
||||||
|
#include "cavaGLSL.hpp"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
AModule* getModule(const std::string& id, const Json::Value& config) {
|
||||||
|
#ifdef HAVE_LIBCAVA
|
||||||
|
const std::shared_ptr<CavaBackend> backend_{waybar::modules::cava::CavaBackend::inst(config)};
|
||||||
|
switch (backend_->getPrm()->output) {
|
||||||
|
#ifdef HAVE_LIBCAVAGLSL
|
||||||
|
case ::cava::output_method::OUTPUT_SDL_GLSL:
|
||||||
|
return new waybar::modules::cava::CavaGLSL(id, config);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return new waybar::modules::cava::Cava(id, config);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
throw std::runtime_error("Unknown module");
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
+24
-22
@@ -38,39 +38,41 @@ class Clock final : public ALabel {
|
|||||||
5 - tooltip-format
|
5 - tooltip-format
|
||||||
*/
|
*/
|
||||||
std::map<int, std::string const> fmtMap_;
|
std::map<int, std::string const> fmtMap_;
|
||||||
uint cldMonCols_{3}; // calendar count month columns
|
uint cldMonCols_{3}; // calendar count month columns
|
||||||
int cldWnLen_{3}; // calendar week number length
|
int cldWnLen_{3}; // calendar week number length
|
||||||
const int cldMonColLen_{20}; // calendar month column length
|
const int cldMonColLen_{20}; // calendar month column length
|
||||||
WS cldWPos_{WS::HIDDEN}; // calendar week side to print
|
WS cldWPos_{WS::HIDDEN}; // calendar week side to print
|
||||||
months cldCurrShift_{0}; // calendar months shift
|
date::months cldCurrShift_{0}; // calendar months shift
|
||||||
int cldShift_{1}; // calendar months shift factor
|
int cldShift_{1}; // calendar months shift factor
|
||||||
year_month_day cldYearShift_; // calendar Year mode. Cached ymd
|
date::year_month_day cldYearShift_; // calendar Year mode. Cached ymd
|
||||||
std::string cldYearCached_; // calendar Year mode. Cached calendar
|
std::string cldYearCached_; // calendar Year mode. Cached calendar
|
||||||
year_month cldMonShift_; // calendar Month mode. Cached ym
|
date::year_month cldMonShift_; // calendar Month mode. Cached ym
|
||||||
std::string cldMonCached_; // calendar Month mode. Cached calendar
|
std::string cldMonCached_; // calendar Month mode. Cached calendar
|
||||||
day cldBaseDay_{0}; // calendar Cached day. Is used when today is changing(midnight)
|
date::day cldBaseDay_{0}; // calendar Cached day. Is used when today is changing(midnight)
|
||||||
std::string cldText_{""}; // calendar text to print
|
std::string cldText_{""}; // calendar text to print
|
||||||
|
bool iso8601Calendar_{false}; // whether the calendar is in ISO8601
|
||||||
CldMode cldMode_{CldMode::MONTH};
|
CldMode cldMode_{CldMode::MONTH};
|
||||||
auto get_calendar(const year_month_day& today, const year_month_day& ymd, const time_zone* tz)
|
auto get_calendar(const date::year_month_day& today, const date::year_month_day& ymd,
|
||||||
-> const std::string;
|
const date::time_zone* tz) -> const std::string;
|
||||||
|
|
||||||
// get local time zone
|
// get local time zone
|
||||||
auto local_zone() -> const time_zone*;
|
auto local_zone() -> const date::time_zone*;
|
||||||
|
|
||||||
// time zoned time in tooltip
|
// time zoned time in tooltip
|
||||||
const bool tzInTooltip_; // if need to print time zones text
|
const bool tzInTooltip_; // if need to print time zones text
|
||||||
std::vector<const time_zone*> tzList_; // time zones list
|
std::vector<const date::time_zone*> tzList_; // time zones list
|
||||||
int tzCurrIdx_; // current time zone index for tzList_
|
int tzCurrIdx_; // current time zone index for tzList_
|
||||||
std::string tzText_{""}; // time zones text to print
|
std::string tzText_{""}; // time zones text to print
|
||||||
|
std::string tzTooltipFormat_{""}; // optional timezone tooltip format
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
|
|
||||||
// ordinal date in tooltip
|
// ordinal date in tooltip
|
||||||
const bool ordInTooltip_;
|
const bool ordInTooltip_;
|
||||||
std::string ordText_{""};
|
std::string ordText_{""};
|
||||||
auto get_ordinal_date(const year_month_day& today) -> std::string;
|
auto get_ordinal_date(const date::year_month_day& today) -> std::string;
|
||||||
|
|
||||||
auto getTZtext(sys_seconds now) -> std::string;
|
auto getTZtext(date::sys_seconds now) -> std::string;
|
||||||
auto first_day_of_week() -> weekday;
|
auto first_day_of_week() -> date::weekday;
|
||||||
// Module actions
|
// Module actions
|
||||||
void cldModeSwitch();
|
void cldModeSwitch();
|
||||||
void cldShift_up();
|
void cldShift_up();
|
||||||
@@ -79,7 +81,7 @@ class Clock final : public ALabel {
|
|||||||
void tz_up();
|
void tz_up();
|
||||||
void tz_down();
|
void tz_down();
|
||||||
// Module Action Map
|
// Module Action Map
|
||||||
static inline std::map<const std::string, void (waybar::modules::Clock::*const)()> actionMap_{
|
static inline std::map<const std::string, void (waybar::modules::Clock::* const)()> actionMap_{
|
||||||
{"mode", &waybar::modules::Clock::cldModeSwitch},
|
{"mode", &waybar::modules::Clock::cldModeSwitch},
|
||||||
{"shift_up", &waybar::modules::Clock::cldShift_up},
|
{"shift_up", &waybar::modules::Clock::cldShift_up},
|
||||||
{"shift_down", &waybar::modules::Clock::cldShift_down},
|
{"shift_down", &waybar::modules::Clock::cldShift_down},
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ class Custom : public ALabel {
|
|||||||
std::string id_;
|
std::string id_;
|
||||||
std::string alt_;
|
std::string alt_;
|
||||||
std::string tooltip_;
|
std::string tooltip_;
|
||||||
|
std::string last_tooltip_markup_;
|
||||||
const bool tooltip_format_enabled_;
|
const bool tooltip_format_enabled_;
|
||||||
std::vector<std::string> class_;
|
std::vector<std::string> class_;
|
||||||
int percentage_;
|
int percentage_;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class Disk : public ALabel {
|
|||||||
std::string path_;
|
std::string path_;
|
||||||
std::string unit_;
|
std::string unit_;
|
||||||
|
|
||||||
float calc_specific_divisor(const std::string divisor);
|
float calc_specific_divisor(const std::string& divisor);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -12,23 +12,23 @@ namespace waybar::modules::dwl {
|
|||||||
|
|
||||||
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();
|
virtual ~Tags();
|
||||||
|
|
||||||
// Handlers for wayland events
|
// Handlers for wayland events
|
||||||
void handle_view_tags(uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused);
|
void handle_view_tags(uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused);
|
||||||
|
|
||||||
void handle_primary_clicked(uint32_t tag);
|
void handle_primary_clicked(uint32_t tag);
|
||||||
bool handle_button_press(GdkEventButton *event_button, uint32_t tag);
|
bool handle_button_press(GdkEventButton* event_button, uint32_t tag);
|
||||||
|
|
||||||
struct zdwl_ipc_manager_v2 *status_manager_;
|
struct zdwl_ipc_manager_v2* status_manager_;
|
||||||
struct wl_seat *seat_;
|
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 zdwl_ipc_output_v2 *output_status_;
|
struct zdwl_ipc_output_v2* output_status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace waybar::modules::dwl */
|
} /* namespace waybar::modules::dwl */
|
||||||
|
|||||||
@@ -13,26 +13,26 @@ namespace waybar::modules::dwl {
|
|||||||
|
|
||||||
class Window : public AAppIconLabel, public sigc::trackable {
|
class Window : public AAppIconLabel, 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&);
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
void handle_layout(const uint32_t layout);
|
void handle_layout(const uint32_t layout);
|
||||||
void handle_title(const char *title);
|
void handle_title(const char* title);
|
||||||
void handle_appid(const char *ppid);
|
void handle_appid(const char* ppid);
|
||||||
void handle_layout_symbol(const char *layout_symbol);
|
void handle_layout_symbol(const char* layout_symbol);
|
||||||
void handle_frame();
|
void handle_frame();
|
||||||
|
|
||||||
struct zdwl_ipc_manager_v2 *status_manager_;
|
struct zdwl_ipc_manager_v2* status_manager_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Bar &bar_;
|
const Bar& bar_;
|
||||||
|
|
||||||
std::string title_;
|
std::string title_;
|
||||||
std::string appid_;
|
std::string appid_;
|
||||||
std::string layout_symbol_;
|
std::string layout_symbol_;
|
||||||
uint32_t layout_;
|
uint32_t layout_;
|
||||||
|
|
||||||
struct zdwl_ipc_output_v2 *output_status_;
|
struct zdwl_ipc_output_v2* output_status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::dwl
|
} // namespace waybar::modules::dwl
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <gtkmm/image.h>
|
||||||
|
#include <gtkmm/label.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "ext-workspace-v1-client-protocol.h"
|
||||||
|
|
||||||
|
namespace waybar::modules::ext {
|
||||||
|
|
||||||
|
class WorkspaceGroup;
|
||||||
|
class Workspace;
|
||||||
|
|
||||||
|
class WorkspaceManager final : public AModule {
|
||||||
|
public:
|
||||||
|
WorkspaceManager(const std::string& id, const waybar::Bar& bar, const Json::Value& config);
|
||||||
|
~WorkspaceManager() override;
|
||||||
|
void register_manager(wl_registry* registry, uint32_t name, uint32_t version);
|
||||||
|
void remove_workspace_group(uint32_t id);
|
||||||
|
void remove_workspace(uint32_t id);
|
||||||
|
void set_needs_sorting() { needs_sorting_ = true; }
|
||||||
|
|
||||||
|
// wl events
|
||||||
|
void handle_workspace_group(ext_workspace_group_handle_v1* handle);
|
||||||
|
void handle_workspace(ext_workspace_handle_v1* handle);
|
||||||
|
void handle_done();
|
||||||
|
void handle_finished();
|
||||||
|
|
||||||
|
// wl requests
|
||||||
|
void commit() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void update() override;
|
||||||
|
bool has_button(const Gtk::Button* button);
|
||||||
|
void sort_workspaces();
|
||||||
|
void clear_buttons();
|
||||||
|
void update_buttons();
|
||||||
|
|
||||||
|
static uint32_t group_global_id;
|
||||||
|
static uint32_t workspace_global_id;
|
||||||
|
uint32_t workspace_name = 0;
|
||||||
|
|
||||||
|
bool sort_by_id_ = false;
|
||||||
|
bool sort_by_name_ = true;
|
||||||
|
bool sort_by_coordinates_ = false;
|
||||||
|
bool all_outputs_ = false;
|
||||||
|
|
||||||
|
const waybar::Bar& bar_;
|
||||||
|
Gtk::Box box_;
|
||||||
|
|
||||||
|
ext_workspace_manager_v1* ext_manager_ = nullptr;
|
||||||
|
std::vector<std::unique_ptr<WorkspaceGroup>> groups_;
|
||||||
|
std::vector<std::unique_ptr<Workspace>> workspaces_;
|
||||||
|
|
||||||
|
bool needs_sorting_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorkspaceGroup {
|
||||||
|
public:
|
||||||
|
WorkspaceGroup(WorkspaceManager& manager, ext_workspace_group_handle_v1* handle, uint32_t id);
|
||||||
|
~WorkspaceGroup();
|
||||||
|
|
||||||
|
u_int32_t id() const { return id_; }
|
||||||
|
bool has_output(const wl_output* output);
|
||||||
|
bool has_workspace(const ext_workspace_handle_v1* workspace);
|
||||||
|
|
||||||
|
// wl events
|
||||||
|
void handle_capabilities(uint32_t capabilities);
|
||||||
|
void handle_output_enter(wl_output* output);
|
||||||
|
void handle_output_leave(wl_output* output);
|
||||||
|
void handle_workspace_enter(ext_workspace_handle_v1* handle);
|
||||||
|
void handle_workspace_leave(ext_workspace_handle_v1* handle);
|
||||||
|
void handle_removed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
WorkspaceManager& workspaces_manager_;
|
||||||
|
ext_workspace_group_handle_v1* ext_handle_;
|
||||||
|
uint32_t id_;
|
||||||
|
std::vector<wl_output*> outputs_;
|
||||||
|
std::vector<ext_workspace_handle_v1*> workspaces_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Workspace {
|
||||||
|
public:
|
||||||
|
Workspace(const Json::Value& config, WorkspaceManager& manager, ext_workspace_handle_v1* handle,
|
||||||
|
uint32_t id, const std::string& name);
|
||||||
|
~Workspace();
|
||||||
|
|
||||||
|
ext_workspace_handle_v1* handle() const { return ext_handle_; }
|
||||||
|
u_int32_t id() const { return id_; }
|
||||||
|
std::string& workspace_id() { return workspace_id_; }
|
||||||
|
std::string& name() { return name_; }
|
||||||
|
std::vector<u_int32_t>& coordinates() { return coordinates_; }
|
||||||
|
Gtk::Button& button() { return button_; }
|
||||||
|
void update();
|
||||||
|
|
||||||
|
// wl events
|
||||||
|
void handle_id(const std::string& id);
|
||||||
|
void handle_name(const std::string& name);
|
||||||
|
void handle_coordinates(const std::vector<uint32_t>& coordinates);
|
||||||
|
void handle_state(uint32_t state);
|
||||||
|
void handle_capabilities(uint32_t capabilities);
|
||||||
|
void handle_removed();
|
||||||
|
|
||||||
|
// gdk events
|
||||||
|
bool handle_clicked(const GdkEventButton* button) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool has_state(uint32_t state) const { return (state_ & state) == state; }
|
||||||
|
std::string icon();
|
||||||
|
|
||||||
|
WorkspaceManager& workspace_manager_;
|
||||||
|
ext_workspace_handle_v1* ext_handle_ = nullptr;
|
||||||
|
uint32_t id_;
|
||||||
|
uint32_t state_ = 0;
|
||||||
|
std::string workspace_id_;
|
||||||
|
std::string name_;
|
||||||
|
std::vector<uint32_t> coordinates_;
|
||||||
|
|
||||||
|
bool active_only_ = false;
|
||||||
|
bool ignore_hidden_ = true;
|
||||||
|
std::string format_;
|
||||||
|
bool with_icon_ = false;
|
||||||
|
static std::map<std::string, std::string> icon_map_;
|
||||||
|
std::string on_click_action_;
|
||||||
|
std::string on_click_middle_action_;
|
||||||
|
std::string on_click_right_action_;
|
||||||
|
|
||||||
|
Gtk::Button button_;
|
||||||
|
Gtk::Box content_;
|
||||||
|
Gtk::Label label_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::ext
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#include "ext-workspace-v1-client-protocol.h"
|
||||||
|
|
||||||
|
namespace waybar::modules::ext {
|
||||||
|
void add_registry_listener(void* data);
|
||||||
|
void add_workspace_listener(ext_workspace_handle_v1* workspace_handle, void* data);
|
||||||
|
void add_workspace_group_listener(ext_workspace_group_handle_v1* workspace_group_handle,
|
||||||
|
void* data);
|
||||||
|
ext_workspace_manager_v1* workspace_manager_bind(wl_registry* registry, uint32_t name,
|
||||||
|
uint32_t version, void* data);
|
||||||
|
} // namespace waybar::modules::ext
|
||||||
@@ -17,7 +17,7 @@ namespace waybar::modules {
|
|||||||
|
|
||||||
class Gamemode : public AModule {
|
class Gamemode : public AModule {
|
||||||
public:
|
public:
|
||||||
Gamemode(const std::string &, const Json::Value &);
|
Gamemode(const std::string&, const Json::Value&);
|
||||||
virtual ~Gamemode();
|
virtual ~Gamemode();
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
@@ -26,20 +26,20 @@ class Gamemode : public AModule {
|
|||||||
const std::string DEFAULT_FORMAT = "{glyph}";
|
const std::string DEFAULT_FORMAT = "{glyph}";
|
||||||
const std::string DEFAULT_FORMAT_ALT = "{glyph} {count}";
|
const std::string DEFAULT_FORMAT_ALT = "{glyph} {count}";
|
||||||
const std::string DEFAULT_TOOLTIP_FORMAT = "Games running: {count}";
|
const std::string DEFAULT_TOOLTIP_FORMAT = "Games running: {count}";
|
||||||
const std::string DEFAULT_GLYPH = "";
|
const std::string DEFAULT_GLYPH = "";
|
||||||
|
|
||||||
void appear(const Glib::RefPtr<Gio::DBus::Connection> &connection, const Glib::ustring &name,
|
void appear(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name,
|
||||||
const Glib::ustring &name_owner);
|
const Glib::ustring& name_owner);
|
||||||
void disappear(const Glib::RefPtr<Gio::DBus::Connection> &connection, const Glib::ustring &name);
|
void disappear(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name);
|
||||||
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
|
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection>& connection,
|
||||||
const Glib::ustring &sender_name, const Glib::ustring &object_path,
|
const Glib::ustring& sender_name, const Glib::ustring& object_path,
|
||||||
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
|
const Glib::ustring& interface_name, const Glib::ustring& signal_name,
|
||||||
const Glib::VariantContainerBase ¶meters);
|
const Glib::VariantContainerBase& parameters);
|
||||||
void notify_cb(const Glib::ustring &sender_name, const Glib::ustring &signal_name,
|
void notify_cb(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
|
||||||
const Glib::VariantContainerBase &arguments);
|
const Glib::VariantContainerBase& arguments);
|
||||||
|
|
||||||
void getData();
|
void getData();
|
||||||
bool handleToggle(GdkEventButton *const &) override;
|
bool handleToggle(GdkEventButton* const&) override;
|
||||||
|
|
||||||
// Config
|
// Config
|
||||||
std::string format = DEFAULT_FORMAT;
|
std::string format = DEFAULT_FORMAT;
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
#ifdef WANT_RFKILL
|
||||||
|
#include "util/rfkill.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gps.h>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class Gps : public ALabel {
|
||||||
|
public:
|
||||||
|
Gps(const std::string&, const Json::Value&);
|
||||||
|
virtual ~Gps();
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef WANT_RFKILL
|
||||||
|
util::Rfkill rfkill_;
|
||||||
|
#endif
|
||||||
|
const std::string getFixModeName() const;
|
||||||
|
const std::string getFixModeString() const;
|
||||||
|
|
||||||
|
const std::string getFixStatusString() const;
|
||||||
|
|
||||||
|
util::SleeperThread thread_, gps_thread_;
|
||||||
|
gps_data_t gps_data_;
|
||||||
|
std::string state_;
|
||||||
|
|
||||||
|
bool hideDisconnected = true;
|
||||||
|
bool hideNoFix = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
@@ -17,9 +19,15 @@ class EventHandler {
|
|||||||
virtual ~EventHandler() = default;
|
virtual ~EventHandler() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// If you want to use the Hyprland IPC, simply use IPC::inst() to get the singleton instance.
|
||||||
|
/// Do not create multiple instances.
|
||||||
class IPC {
|
class IPC {
|
||||||
|
protected:
|
||||||
|
IPC(); // use IPC::inst() instead.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IPC() { startIPC(); }
|
~IPC();
|
||||||
|
static IPC& inst();
|
||||||
|
|
||||||
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
|
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
|
||||||
void unregisterForIPC(EventHandler* handler);
|
void unregisterForIPC(EventHandler* handler);
|
||||||
@@ -28,18 +36,33 @@ class IPC {
|
|||||||
Json::Value getSocket1JsonReply(const std::string& rq);
|
Json::Value getSocket1JsonReply(const std::string& rq);
|
||||||
static std::filesystem::path getSocketFolder(const char* instanceSig);
|
static std::filesystem::path getSocketFolder(const char* instanceSig);
|
||||||
|
|
||||||
|
/// Dispatch a Hyprland command. Automatically uses the correct protocol
|
||||||
|
/// (legacy text or Lua-based) depending on the running Hyprland version.
|
||||||
|
static std::string dispatch(const std::string& dispatcher, const std::string& arg);
|
||||||
|
|
||||||
|
/// Build a Lua-format dispatch command string.
|
||||||
|
static std::string buildLuaDispatch(const std::string& dispatcher, const std::string& arg);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static std::filesystem::path socketFolder_;
|
static std::filesystem::path socketFolder_;
|
||||||
|
|
||||||
|
/// Detect whether the running Hyprland uses the Lua-based IPC protocol.
|
||||||
|
/// Returns true for Hyprland >= 0.54 (Lua config), false for older versions.
|
||||||
|
static bool isLuaProtocol();
|
||||||
|
|
||||||
|
static std::optional<bool> s_luaProtocolDetected_; // cached detection result
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startIPC();
|
void socketListener();
|
||||||
void parseIPC(const std::string&);
|
void parseIPC(const std::string&);
|
||||||
|
|
||||||
|
std::thread ipcThread_;
|
||||||
std::mutex callbackMutex_;
|
std::mutex callbackMutex_;
|
||||||
|
std::mutex socketMutex_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
||||||
|
int socketfd_ = -1; // the hyprland socket file descriptor
|
||||||
|
pid_t socketOwnerPid_ = -1;
|
||||||
|
std::atomic<bool> running_ = true; // the ipcThread will stop running when this is false
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<IPC> gIPC;
|
|
||||||
inline bool modulesReady = false;
|
|
||||||
}; // namespace waybar::modules::hyprland
|
}; // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ class Language : public waybar::ALabel, public EventHandler {
|
|||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
|
|
||||||
Layout layout_;
|
Layout layout_;
|
||||||
|
|
||||||
|
IPC& m_ipc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -26,8 +26,11 @@ class Submap : public waybar::ALabel, public EventHandler {
|
|||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::string submap_;
|
std::string submap_;
|
||||||
|
std::string prev_submap_;
|
||||||
bool always_on_ = false;
|
bool always_on_ = false;
|
||||||
std::string default_submap_ = "Default";
|
std::string default_submap_ = "Default";
|
||||||
|
|
||||||
|
IPC& m_ipc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct Workspace {
|
struct Workspace {
|
||||||
int id;
|
int id = 0;
|
||||||
int windows;
|
int windows = 0;
|
||||||
std::string last_window;
|
std::string last_window;
|
||||||
std::string last_window_title;
|
std::string last_window_title;
|
||||||
|
|
||||||
@@ -29,14 +29,14 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct WindowData {
|
struct WindowData {
|
||||||
bool floating;
|
bool floating = false;
|
||||||
int monitor = -1;
|
int monitor = -1;
|
||||||
std::string class_name;
|
std::string class_name;
|
||||||
std::string initial_class_name;
|
std::string initial_class_name;
|
||||||
std::string title;
|
std::string title;
|
||||||
std::string initial_title;
|
std::string initial_title;
|
||||||
bool fullscreen;
|
bool fullscreen = false;
|
||||||
bool grouped;
|
bool grouped = false;
|
||||||
|
|
||||||
static auto parse(const Json::Value&) -> WindowData;
|
static auto parse(const Json::Value&) -> WindowData;
|
||||||
};
|
};
|
||||||
@@ -47,7 +47,7 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
|||||||
void queryActiveWorkspace();
|
void queryActiveWorkspace();
|
||||||
void setClass(const std::string&, bool enable);
|
void setClass(const std::string&, bool enable);
|
||||||
|
|
||||||
bool separateOutputs_;
|
bool separateOutputs_ = false;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
@@ -55,11 +55,13 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
|||||||
Workspace workspace_;
|
Workspace workspace_;
|
||||||
std::string soloClass_;
|
std::string soloClass_;
|
||||||
std::string lastSoloClass_;
|
std::string lastSoloClass_;
|
||||||
bool solo_;
|
bool solo_ = false;
|
||||||
bool allFloating_;
|
bool allFloating_ = false;
|
||||||
bool swallowing_;
|
bool swallowing_ = false;
|
||||||
bool fullscreen_;
|
bool fullscreen_ = false;
|
||||||
bool focused_;
|
bool focused_ = false;
|
||||||
|
|
||||||
|
IPC& m_ipc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "AAppIconLabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/hyprland/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
|
class WindowCount : public waybar::AAppIconLabel, public EventHandler {
|
||||||
|
public:
|
||||||
|
WindowCount(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
|
~WindowCount() override;
|
||||||
|
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Workspace {
|
||||||
|
int id;
|
||||||
|
int windows;
|
||||||
|
bool hasfullscreen;
|
||||||
|
static auto parse(const Json::Value& value) -> Workspace;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getActiveWorkspace(const std::string&) -> Workspace;
|
||||||
|
auto getActiveWorkspace() -> Workspace;
|
||||||
|
void onEvent(const std::string& ev) override;
|
||||||
|
void queryActiveWorkspace();
|
||||||
|
void setClass(const std::string&, bool enable);
|
||||||
|
|
||||||
|
bool separateOutputs_;
|
||||||
|
std::mutex mutex_;
|
||||||
|
const Bar& bar_;
|
||||||
|
Workspace workspace_;
|
||||||
|
IPC& m_ipc;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::hyprland
|
||||||
@@ -26,34 +26,49 @@ namespace waybar::modules::hyprland {
|
|||||||
|
|
||||||
class Workspaces;
|
class Workspaces;
|
||||||
|
|
||||||
|
struct WindowRepr {
|
||||||
|
std::string address;
|
||||||
|
std::string window_class;
|
||||||
|
std::string window_title;
|
||||||
|
std::string repr_rewrite;
|
||||||
|
bool isActive = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool empty() const { return address.empty(); }
|
||||||
|
void setActive(bool value) { isActive = value; }
|
||||||
|
};
|
||||||
|
|
||||||
class WindowCreationPayload {
|
class WindowCreationPayload {
|
||||||
public:
|
public:
|
||||||
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
|
||||||
std::string window_repr);
|
WindowRepr window_repr);
|
||||||
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
|
||||||
std::string window_class, std::string window_title);
|
const std::string& window_class, const std::string& window_title,
|
||||||
|
bool is_active);
|
||||||
WindowCreationPayload(Json::Value const& client_data);
|
WindowCreationPayload(Json::Value const& client_data);
|
||||||
|
|
||||||
int incrementTimeSpentUncreated();
|
int incrementTimeSpentUncreated();
|
||||||
bool isEmpty(Workspaces& workspace_manager);
|
bool isEmpty(Workspaces& workspace_manager);
|
||||||
bool reprIsReady() const { return std::holds_alternative<Repr>(m_window); }
|
bool reprIsReady() const { return std::holds_alternative<Repr>(m_window); }
|
||||||
std::string repr(Workspaces& workspace_manager);
|
WindowRepr repr(Workspaces& workspace_manager);
|
||||||
|
void setActive(bool value) { m_isActive = value; }
|
||||||
|
|
||||||
std::string getWorkspaceName() const { return m_workspaceName; }
|
std::string getWorkspaceName() const { return m_workspaceName; }
|
||||||
WindowAddress getAddress() const { return m_windowAddress; }
|
WindowAddress getAddress() const { return m_windowAddress; }
|
||||||
|
|
||||||
void moveToWorksace(std::string& new_workspace_name);
|
void moveToWorkspace(std::string& new_workspace_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void clearAddr();
|
void clearAddr();
|
||||||
void clearWorkspaceName();
|
void clearWorkspaceName();
|
||||||
|
|
||||||
using Repr = std::string;
|
using Repr = WindowRepr;
|
||||||
using ClassAndTitle = std::pair<std::string, std::string>;
|
using ClassAndTitle = std::pair<std::string, std::string>;
|
||||||
std::variant<Repr, ClassAndTitle> m_window;
|
std::variant<Repr, ClassAndTitle> m_window;
|
||||||
|
|
||||||
WindowAddress m_windowAddress;
|
WindowAddress m_windowAddress;
|
||||||
std::string m_workspaceName;
|
std::string m_workspaceName;
|
||||||
|
bool m_isActive = false;
|
||||||
|
|
||||||
int m_timeSpentUncreated = 0;
|
int m_timeSpentUncreated = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class Workspace {
|
|||||||
public:
|
public:
|
||||||
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
|
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
|
||||||
const Json::Value& clients_data = Json::Value::nullRef);
|
const Json::Value& clients_data = Json::Value::nullRef);
|
||||||
|
~Workspace();
|
||||||
std::string& selectIcon(std::map<std::string, std::string>& icons_map);
|
std::string& selectIcon(std::map<std::string, std::string>& icons_map);
|
||||||
Gtk::Button& button() { return m_button; };
|
Gtk::Button& button() { return m_button; };
|
||||||
|
|
||||||
@@ -42,10 +43,18 @@ class Workspace {
|
|||||||
bool isPersistentConfig() const { return m_isPersistentConfig; };
|
bool isPersistentConfig() const { return m_isPersistentConfig; };
|
||||||
bool isPersistentRule() const { return m_isPersistentRule; };
|
bool isPersistentRule() const { return m_isPersistentRule; };
|
||||||
bool isVisible() const { return m_isVisible; };
|
bool isVisible() const { return m_isVisible; };
|
||||||
bool isEmpty() const { return m_windows == 0; };
|
|
||||||
bool isUrgent() const { return m_isUrgent; };
|
bool isUrgent() const { return m_isUrgent; };
|
||||||
|
|
||||||
bool handleClicked(GdkEventButton* bt) const;
|
bool handleClicked(GdkEventButton* bt) const;
|
||||||
|
|
||||||
|
bool handleEnter(GdkEventCrossing* event);
|
||||||
|
bool handleLeave(GdkEventCrossing* event);
|
||||||
|
|
||||||
|
void startHoverCheck();
|
||||||
|
void stopHoverCheck();
|
||||||
|
bool syncHoverClass();
|
||||||
|
bool pointerInsideButton();
|
||||||
|
|
||||||
void setActive(bool value = true) { m_isActive = value; };
|
void setActive(bool value = true) { m_isActive = value; };
|
||||||
void setPersistentRule(bool value = true) { m_isPersistentRule = value; };
|
void setPersistentRule(bool value = true) { m_isPersistentRule = value; };
|
||||||
void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; };
|
void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; };
|
||||||
@@ -54,15 +63,18 @@ class Workspace {
|
|||||||
void setWindows(uint value) { m_windows = value; };
|
void setWindows(uint value) { m_windows = value; };
|
||||||
void setName(std::string const& value) { m_name = value; };
|
void setName(std::string const& value) { m_name = value; };
|
||||||
void setOutput(std::string const& value) { m_output = value; };
|
void setOutput(std::string const& value) { m_output = value; };
|
||||||
bool containsWindow(WindowAddress const& addr) const { return m_windowMap.contains(addr); }
|
bool containsWindow(WindowAddress const& addr) const {
|
||||||
void insertWindow(WindowCreationPayload create_window_paylod);
|
return std::ranges::any_of(m_windowMap,
|
||||||
std::string removeWindow(WindowAddress const& addr);
|
[&addr](const auto& window) { return window.address == addr; });
|
||||||
|
};
|
||||||
|
void insertWindow(WindowCreationPayload create_window_payload);
|
||||||
void initializeWindowMap(const Json::Value& clients_data);
|
void initializeWindowMap(const Json::Value& clients_data);
|
||||||
|
void setActiveWindow(WindowAddress const& addr);
|
||||||
|
|
||||||
bool onWindowOpened(WindowCreationPayload const& create_window_paylod);
|
bool onWindowOpened(WindowCreationPayload const& create_window_payload);
|
||||||
std::optional<std::string> closeWindow(WindowAddress const& addr);
|
std::optional<WindowRepr> closeWindow(WindowAddress const& addr);
|
||||||
|
|
||||||
void update(const std::string& format, const std::string& icon);
|
void update(const std::string& workspace_icon);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Workspaces& m_workspaceManager;
|
Workspaces& m_workspaceManager;
|
||||||
@@ -78,11 +90,20 @@ class Workspace {
|
|||||||
bool m_isUrgent = false;
|
bool m_isUrgent = false;
|
||||||
bool m_isVisible = false;
|
bool m_isVisible = false;
|
||||||
|
|
||||||
std::map<WindowAddress, std::string> m_windowMap;
|
sigc::connection m_hoverCheckConnection;
|
||||||
|
|
||||||
|
std::vector<WindowRepr> m_windowMap;
|
||||||
|
|
||||||
Gtk::Button m_button;
|
Gtk::Button m_button;
|
||||||
Gtk::Box m_content;
|
Gtk::Box m_content;
|
||||||
Gtk::Label m_label;
|
Gtk::Label m_labelBefore;
|
||||||
|
Gtk::Label m_labelAfter;
|
||||||
|
|
||||||
|
bool isEmpty() const;
|
||||||
|
void updateTaskbar(const std::string& workspace_icon);
|
||||||
|
bool handleClick(const GdkEventButton* event_button, WindowAddress const& addr) const;
|
||||||
|
bool shouldSkipWindow(const WindowRepr& window_repr) const;
|
||||||
|
IPC& m_ipc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtkmm/button.h>
|
#include <gtkmm/button.h>
|
||||||
|
#include <gtkmm/enums.h>
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
#include <json/value.h>
|
#include <json/value.h>
|
||||||
|
#include <sigc++/connection.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -17,6 +20,7 @@
|
|||||||
#include "modules/hyprland/windowcreationpayload.hpp"
|
#include "modules/hyprland/windowcreationpayload.hpp"
|
||||||
#include "modules/hyprland/workspace.hpp"
|
#include "modules/hyprland/workspace.hpp"
|
||||||
#include "util/enum.hpp"
|
#include "util/enum.hpp"
|
||||||
|
#include "util/icon_loader.hpp"
|
||||||
#include "util/regex_collection.hpp"
|
#include "util/regex_collection.hpp"
|
||||||
|
|
||||||
using WindowAddress = std::string;
|
using WindowAddress = std::string;
|
||||||
@@ -36,26 +40,44 @@ class Workspaces : public AModule, public EventHandler {
|
|||||||
auto showSpecial() const -> bool { return m_showSpecial; }
|
auto showSpecial() const -> bool { return m_showSpecial; }
|
||||||
auto activeOnly() const -> bool { return m_activeOnly; }
|
auto activeOnly() const -> bool { return m_activeOnly; }
|
||||||
auto specialVisibleOnly() const -> bool { return m_specialVisibleOnly; }
|
auto specialVisibleOnly() const -> bool { return m_specialVisibleOnly; }
|
||||||
|
auto persistentOnly() const -> bool { return m_persistentOnly; }
|
||||||
auto moveToMonitor() const -> bool { return m_moveToMonitor; }
|
auto moveToMonitor() const -> bool { return m_moveToMonitor; }
|
||||||
|
auto enableTaskbar() const -> bool { return m_enableTaskbar; }
|
||||||
|
auto taskbarWithIcon() const -> bool { return m_taskbarWithIcon; }
|
||||||
|
auto barScroll() const -> bool { return m_barScroll; }
|
||||||
|
|
||||||
auto getBarOutput() const -> std::string { return m_bar.output->name; }
|
auto getBarOutput() const -> std::string { return m_bar.output->name; }
|
||||||
|
auto formatBefore() const -> std::string { return m_formatBefore; }
|
||||||
|
auto formatAfter() const -> std::string { return m_formatAfter; }
|
||||||
|
auto taskbarFormatBefore() const -> std::string { return m_taskbarFormatBefore; }
|
||||||
|
auto taskbarFormatAfter() const -> std::string { return m_taskbarFormatAfter; }
|
||||||
|
auto taskbarIconSize() const -> int { return m_taskbarIconSize; }
|
||||||
|
auto taskbarOrientation() const -> Gtk::Orientation { return m_taskbarOrientation; }
|
||||||
|
auto taskbarReverseDirection() const -> bool { return m_taskbarReverseDirection; }
|
||||||
|
auto onClickWindow() const -> std::string { return m_onClickWindow; }
|
||||||
|
auto getIgnoredWindows() const -> std::vector<std::regex> { return m_ignoreWindows; }
|
||||||
|
|
||||||
std::string getRewrite(std::string window_class, std::string window_title);
|
enum class ActiveWindowPosition { NONE, FIRST, LAST };
|
||||||
|
auto activeWindowPosition() const -> ActiveWindowPosition { return m_activeWindowPosition; }
|
||||||
|
|
||||||
|
std::string getRewrite(const std::string& window_class, const std::string& window_title);
|
||||||
std::string& getWindowSeparator() { return m_formatWindowSeparator; }
|
std::string& getWindowSeparator() { return m_formatWindowSeparator; }
|
||||||
bool isWorkspaceIgnored(std::string const& workspace_name);
|
bool isWorkspaceIgnored(std::string const& workspace_name);
|
||||||
|
|
||||||
bool windowRewriteConfigUsesTitle() const { return m_anyWindowRewriteRuleUsesTitle; }
|
bool windowRewriteConfigUsesTitle() const { return m_anyWindowRewriteRuleUsesTitle; }
|
||||||
|
const IconLoader& iconLoader() const { return m_iconLoader; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onEvent(const std::string& e) override;
|
void onEvent(const std::string& e) override;
|
||||||
void updateWindowCount();
|
void updateWindowCount();
|
||||||
|
void sortSpecialCentered();
|
||||||
void sortWorkspaces();
|
void sortWorkspaces();
|
||||||
void createWorkspace(Json::Value const& workspace_data,
|
void createWorkspace(Json::Value const& workspace_data,
|
||||||
Json::Value const& clients_data = Json::Value::nullRef);
|
Json::Value const& clients_data = Json::Value::nullRef);
|
||||||
|
|
||||||
static Json::Value createMonitorWorkspaceData(std::string const& name,
|
static Json::Value createMonitorWorkspaceData(std::string const& name,
|
||||||
std::string const& monitor);
|
std::string const& monitor);
|
||||||
void removeWorkspace(std::string const& name);
|
void removeWorkspace(std::string const& workspaceString);
|
||||||
void setUrgentWorkspace(std::string const& windowaddress);
|
void setUrgentWorkspace(std::string const& windowaddress);
|
||||||
|
|
||||||
// Config
|
// Config
|
||||||
@@ -67,6 +89,7 @@ class Workspaces : public AModule, public EventHandler {
|
|||||||
auto populateIgnoreWorkspacesConfig(const Json::Value& config) -> void;
|
auto populateIgnoreWorkspacesConfig(const Json::Value& config) -> void;
|
||||||
auto populateFormatWindowSeparatorConfig(const Json::Value& config) -> void;
|
auto populateFormatWindowSeparatorConfig(const Json::Value& config) -> void;
|
||||||
auto populateWindowRewriteConfig(const Json::Value& config) -> void;
|
auto populateWindowRewriteConfig(const Json::Value& config) -> void;
|
||||||
|
auto populateWorkspaceTaskbarConfig(const Json::Value& config) -> void;
|
||||||
|
|
||||||
void registerIpc();
|
void registerIpc();
|
||||||
|
|
||||||
@@ -74,10 +97,11 @@ class Workspaces : public AModule, public EventHandler {
|
|||||||
void onWorkspaceActivated(std::string const& payload);
|
void onWorkspaceActivated(std::string const& payload);
|
||||||
void onSpecialWorkspaceActivated(std::string const& payload);
|
void onSpecialWorkspaceActivated(std::string const& payload);
|
||||||
void onWorkspaceDestroyed(std::string const& payload);
|
void onWorkspaceDestroyed(std::string const& payload);
|
||||||
void onWorkspaceCreated(std::string const& workspaceName,
|
void onWorkspaceCreated(std::string const& payload,
|
||||||
Json::Value const& clientsData = Json::Value::nullRef);
|
Json::Value const& clientsData = Json::Value::nullRef);
|
||||||
void onWorkspaceMoved(std::string const& payload);
|
void onWorkspaceMoved(std::string const& payload);
|
||||||
void onWorkspaceRenamed(std::string const& payload);
|
void onWorkspaceRenamed(std::string const& payload);
|
||||||
|
static std::optional<int> parseWorkspaceId(std::string const& workspaceIdStr);
|
||||||
|
|
||||||
// monitor events
|
// monitor events
|
||||||
void onMonitorFocused(std::string const& payload);
|
void onMonitorFocused(std::string const& payload);
|
||||||
@@ -88,16 +112,26 @@ class Workspaces : public AModule, public EventHandler {
|
|||||||
void onWindowMoved(std::string const& payload);
|
void onWindowMoved(std::string const& payload);
|
||||||
|
|
||||||
void onWindowTitleEvent(std::string const& payload);
|
void onWindowTitleEvent(std::string const& payload);
|
||||||
|
void onActiveWindowChanged(WindowAddress const& payload);
|
||||||
|
|
||||||
void onConfigReloaded();
|
void onConfigReloaded();
|
||||||
|
|
||||||
int windowRewritePriorityFunction(std::string const& window_rule);
|
int windowRewritePriorityFunction(std::string const& window_rule);
|
||||||
|
|
||||||
|
// event payload management
|
||||||
|
template <typename... Args>
|
||||||
|
static std::string makePayload(Args const&... args);
|
||||||
|
static std::pair<std::string, std::string> splitDoublePayload(std::string const& payload);
|
||||||
|
static std::tuple<std::string, std::string, std::string> splitTriplePayload(
|
||||||
|
std::string const& payload);
|
||||||
|
// scroll events
|
||||||
|
bool handleScroll(GdkEventScroll* e) override;
|
||||||
|
|
||||||
// Update methods
|
// Update methods
|
||||||
void doUpdate();
|
void doUpdate();
|
||||||
void removeWorkspacesToRemove();
|
void removeWorkspacesToRemove();
|
||||||
void createWorkspacesToCreate();
|
void createWorkspacesToCreate();
|
||||||
static std::vector<std::string> getVisibleWorkspaces();
|
static std::vector<int> getVisibleWorkspaces();
|
||||||
void updateWorkspaceStates();
|
void updateWorkspaceStates();
|
||||||
bool updateWindowsToCreate();
|
bool updateWindowsToCreate();
|
||||||
|
|
||||||
@@ -113,23 +147,27 @@ class Workspaces : public AModule, public EventHandler {
|
|||||||
bool m_showSpecial = false;
|
bool m_showSpecial = false;
|
||||||
bool m_activeOnly = false;
|
bool m_activeOnly = false;
|
||||||
bool m_specialVisibleOnly = false;
|
bool m_specialVisibleOnly = false;
|
||||||
|
bool m_persistentOnly = false;
|
||||||
bool m_moveToMonitor = false;
|
bool m_moveToMonitor = false;
|
||||||
|
bool m_barScroll = false;
|
||||||
Json::Value m_persistentWorkspaceConfig;
|
Json::Value m_persistentWorkspaceConfig;
|
||||||
|
|
||||||
// Map for windows stored in workspaces not present in the current bar.
|
// Map for windows stored in workspaces not present in the current bar.
|
||||||
// This happens when the user has multiple monitors (hence, multiple bars)
|
// This happens when the user has multiple monitors (hence, multiple bars)
|
||||||
// and doesn't share windows accross bars (a.k.a `all-outputs` = false)
|
// and doesn't share windows across bars (a.k.a `all-outputs` = false)
|
||||||
std::map<WindowAddress, std::string> m_orphanWindowMap;
|
std::map<WindowAddress, WindowRepr, std::less<>> m_orphanWindowMap;
|
||||||
|
|
||||||
enum class SortMethod { ID, NAME, NUMBER, DEFAULT };
|
enum class SortMethod { ID, NAME, NUMBER, SPECIAL_CENTERED, DEFAULT };
|
||||||
util::EnumParser<SortMethod> m_enumParser;
|
util::EnumParser<SortMethod> m_enumParser;
|
||||||
SortMethod m_sortBy = SortMethod::DEFAULT;
|
SortMethod m_sortBy = SortMethod::DEFAULT;
|
||||||
std::map<std::string, SortMethod> m_sortMap = {{"ID", SortMethod::ID},
|
std::map<std::string, SortMethod> m_sortMap = {{"ID", SortMethod::ID},
|
||||||
{"NAME", SortMethod::NAME},
|
{"NAME", SortMethod::NAME},
|
||||||
{"NUMBER", SortMethod::NUMBER},
|
{"NUMBER", SortMethod::NUMBER},
|
||||||
|
{"SPECIAL-CENTERED", SortMethod::SPECIAL_CENTERED},
|
||||||
{"DEFAULT", SortMethod::DEFAULT}};
|
{"DEFAULT", SortMethod::DEFAULT}};
|
||||||
|
|
||||||
std::string m_format;
|
std::string m_formatBefore;
|
||||||
|
std::string m_formatAfter;
|
||||||
|
|
||||||
std::map<std::string, std::string> m_iconsMap;
|
std::map<std::string, std::string> m_iconsMap;
|
||||||
util::RegexCollection m_windowRewriteRules;
|
util::RegexCollection m_windowRewriteRules;
|
||||||
@@ -138,18 +176,41 @@ class Workspaces : public AModule, public EventHandler {
|
|||||||
|
|
||||||
bool m_withIcon;
|
bool m_withIcon;
|
||||||
uint64_t m_monitorId;
|
uint64_t m_monitorId;
|
||||||
std::string m_activeWorkspaceName;
|
int m_activeWorkspaceId;
|
||||||
std::string m_activeSpecialWorkspaceName;
|
std::string m_activeSpecialWorkspaceName;
|
||||||
std::vector<std::unique_ptr<Workspace>> m_workspaces;
|
std::vector<std::unique_ptr<Workspace>> m_workspaces;
|
||||||
std::vector<std::pair<Json::Value, Json::Value>> m_workspacesToCreate;
|
std::vector<std::pair<Json::Value, Json::Value>> m_workspacesToCreate;
|
||||||
std::vector<std::string> m_workspacesToRemove;
|
std::vector<std::string> m_workspacesToRemove;
|
||||||
std::vector<WindowCreationPayload> m_windowsToCreate;
|
std::vector<WindowCreationPayload> m_windowsToCreate;
|
||||||
|
|
||||||
|
IconLoader m_iconLoader;
|
||||||
|
bool m_enableTaskbar = false;
|
||||||
|
bool m_updateActiveWindow = false;
|
||||||
|
bool m_taskbarWithIcon = false;
|
||||||
|
bool m_taskbarWithTitle = false;
|
||||||
|
std::string m_taskbarFormatBefore;
|
||||||
|
std::string m_taskbarFormatAfter;
|
||||||
|
int m_taskbarIconSize = 16;
|
||||||
|
Gtk::Orientation m_taskbarOrientation = Gtk::ORIENTATION_HORIZONTAL;
|
||||||
|
bool m_taskbarReverseDirection = false;
|
||||||
|
util::EnumParser<ActiveWindowPosition> m_activeWindowEnumParser;
|
||||||
|
ActiveWindowPosition m_activeWindowPosition = ActiveWindowPosition::NONE;
|
||||||
|
std::map<std::string, ActiveWindowPosition> m_activeWindowPositionMap = {
|
||||||
|
{"NONE", ActiveWindowPosition::NONE},
|
||||||
|
{"FIRST", ActiveWindowPosition::FIRST},
|
||||||
|
{"LAST", ActiveWindowPosition::LAST},
|
||||||
|
};
|
||||||
|
std::string m_onClickWindow;
|
||||||
|
std::string m_currentActiveWindowAddress;
|
||||||
|
|
||||||
std::vector<std::regex> m_ignoreWorkspaces;
|
std::vector<std::regex> m_ignoreWorkspaces;
|
||||||
|
std::vector<std::regex> m_ignoreWindows;
|
||||||
|
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
const Bar& m_bar;
|
const Bar& m_bar;
|
||||||
Gtk::Box m_box;
|
Gtk::Box m_box;
|
||||||
|
sigc::connection m_scrollEventConnection_;
|
||||||
|
IPC& m_ipc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class Image : public AModule {
|
|||||||
std::string path_;
|
std::string path_;
|
||||||
std::string tooltip_;
|
std::string tooltip_;
|
||||||
int size_;
|
int size_;
|
||||||
int interval_;
|
std::chrono::milliseconds interval_;
|
||||||
util::command::res output_;
|
util::command::res output_;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace waybar::modules {
|
|||||||
|
|
||||||
class JACK : public ALabel {
|
class JACK : public ALabel {
|
||||||
public:
|
public:
|
||||||
JACK(const std::string &, const Json::Value &);
|
JACK(const std::string&, const Json::Value&);
|
||||||
virtual ~JACK() = default;
|
virtual ~JACK() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ class JACK : public ALabel {
|
|||||||
private:
|
private:
|
||||||
std::string JACKState();
|
std::string JACKState();
|
||||||
|
|
||||||
jack_client_t *client_;
|
jack_client_t* client_;
|
||||||
jack_nframes_t bufsize_;
|
jack_nframes_t bufsize_;
|
||||||
jack_nframes_t samplerate_;
|
jack_nframes_t samplerate_;
|
||||||
unsigned int xruns_;
|
unsigned int xruns_;
|
||||||
@@ -38,7 +38,7 @@ class JACK : public ALabel {
|
|||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|
||||||
int bufSizeCallback(jack_nframes_t size, void *obj);
|
int bufSizeCallback(jack_nframes_t size, void* obj);
|
||||||
int sampleRateCallback(jack_nframes_t rate, void *obj);
|
int sampleRateCallback(jack_nframes_t rate, void* obj);
|
||||||
int xrunCallback(void *obj);
|
int xrunCallback(void* obj);
|
||||||
void shutdownCallback(void *obj);
|
void shutdownCallback(void* obj);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <fmt/chrono.h>
|
#include <fmt/chrono.h>
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@@ -35,12 +36,12 @@ class KeyboardState : public AModule {
|
|||||||
std::string capslock_format_;
|
std::string capslock_format_;
|
||||||
std::string scrolllock_format_;
|
std::string scrolllock_format_;
|
||||||
const std::chrono::seconds interval_;
|
const std::chrono::seconds interval_;
|
||||||
std::string icon_locked_;
|
std::unordered_map<std::string, std::vector<std::string>> key_icon_states_;
|
||||||
std::string icon_unlocked_;
|
|
||||||
std::string devices_path_;
|
std::string devices_path_;
|
||||||
|
|
||||||
struct libinput* libinput_;
|
struct libinput* libinput_;
|
||||||
std::unordered_map<std::string, struct libinput_device*> libinput_devices_;
|
std::unordered_map<std::string, struct libinput_device*> libinput_devices_;
|
||||||
|
std::mutex devices_mutex_; // protects libinput_devices_
|
||||||
std::set<int> binding_keys;
|
std::set<int> binding_keys;
|
||||||
|
|
||||||
util::SleeperThread libinput_thread_, hotplug_thread_;
|
util::SleeperThread libinput_thread_, hotplug_thread_;
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ class Memory : public ALabel {
|
|||||||
std::unordered_map<std::string, unsigned long> meminfo_;
|
std::unordered_map<std::string, unsigned long> meminfo_;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
|
|
||||||
|
std::string unit_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class MPD : public ALabel {
|
|||||||
detail::unique_status status_;
|
detail::unique_status status_;
|
||||||
mpd_state state_;
|
mpd_state state_;
|
||||||
detail::unique_song song_;
|
detail::unique_song song_;
|
||||||
|
std::string ellipsis_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MPD(const std::string&, const Json::Value&);
|
MPD(const std::string&, const Json::Value&);
|
||||||
@@ -44,7 +45,11 @@ class MPD : public ALabel {
|
|||||||
std::string getFilename() 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(const std::string& optionName, bool activated) const;
|
||||||
|
std::string getArtistStr(bool truncated) const;
|
||||||
|
std::string getAlbumArtistStr(bool truncated) const;
|
||||||
|
std::string getAlbumStr(bool truncated) const;
|
||||||
|
std::string getTitleStr(bool truncated) const;
|
||||||
|
|
||||||
// GUI-side methods
|
// GUI-side methods
|
||||||
bool handlePlayPause(GdkEventButton* const&);
|
bool handlePlayPause(GdkEventButton* const&);
|
||||||
@@ -54,7 +59,6 @@ class MPD : public ALabel {
|
|||||||
void tryConnect();
|
void tryConnect();
|
||||||
void checkErrors(mpd_connection* conn);
|
void checkErrors(mpd_connection* conn);
|
||||||
void fetchState();
|
void fetchState();
|
||||||
void queryMPD();
|
|
||||||
|
|
||||||
inline bool stopped() const { return connection_ && state_ == MPD_STATE_STOP; }
|
inline bool stopped() const { return connection_ && state_ == MPD_STATE_STOP; }
|
||||||
inline bool playing() const { return connection_ && state_ == MPD_STATE_PLAY; }
|
inline bool playing() const { return connection_ && state_ == MPD_STATE_PLAY; }
|
||||||
|
|||||||
@@ -197,7 +197,6 @@ class Context {
|
|||||||
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 fetchState() const;
|
void fetchState() const;
|
||||||
constexpr mpd_state state() const;
|
constexpr mpd_state state() const;
|
||||||
void emit() const;
|
void emit() const;
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
inline bool Context::is_connected() const { return mpd_module_->connection_ != nullptr; }
|
inline bool Context::is_connected() const { return mpd_module_->connection_ != nullptr; }
|
||||||
inline bool Context::is_playing() const { return mpd_module_->playing(); }
|
inline bool Context::is_playing() const { return mpd_module_->playing(); }
|
||||||
inline bool Context::is_paused() const { return mpd_module_->paused(); }
|
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_ / 1s; }
|
||||||
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_; }
|
||||||
@@ -15,7 +16,6 @@ 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::fetchState() const { mpd_module_->fetchState(); }
|
inline void Context::fetchState() const { mpd_module_->fetchState(); }
|
||||||
inline void Context::emit() const { mpd_module_->emit(); }
|
inline void Context::emit() const { mpd_module_->emit(); }
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ class Mpris : public ALabel {
|
|||||||
|
|
||||||
PlayerctlPlayerManager* manager;
|
PlayerctlPlayerManager* manager;
|
||||||
PlayerctlPlayer* player;
|
PlayerctlPlayer* player;
|
||||||
|
PlayerctlPlayer* last_active_player_ = nullptr;
|
||||||
std::string lastStatus;
|
std::string lastStatus;
|
||||||
std::string lastPlayer;
|
std::string lastPlayer;
|
||||||
|
|
||||||
|
|||||||
+32
-23
@@ -9,6 +9,7 @@
|
|||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
@@ -16,6 +17,8 @@
|
|||||||
#include "util/rfkill.hpp"
|
#include "util/rfkill.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum ip_addr_pref : uint8_t { IPV4, IPV6, IPV4_6 };
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Network : public ALabel {
|
class Network : public ALabel {
|
||||||
@@ -25,8 +28,8 @@ class Network : public ALabel {
|
|||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t MAX_RETRY = 5;
|
static const uint8_t MAX_RETRY{5};
|
||||||
static const uint8_t EPOLL_MAX = 200;
|
static const uint8_t EPOLL_MAX{200};
|
||||||
|
|
||||||
static int handleEvents(struct nl_msg*, void*);
|
static int handleEvents(struct nl_msg*, void*);
|
||||||
static int handleEventsDone(struct nl_msg*, void*);
|
static int handleEventsDone(struct nl_msg*, void*);
|
||||||
@@ -42,41 +45,47 @@ class Network : public ALabel {
|
|||||||
void parseFreq(struct nlattr**);
|
void parseFreq(struct nlattr**);
|
||||||
void parseBssid(struct nlattr**);
|
void parseBssid(struct nlattr**);
|
||||||
bool associatedOrJoined(struct nlattr**);
|
bool associatedOrJoined(struct nlattr**);
|
||||||
bool checkInterface(std::string name);
|
bool matchInterface(const std::string& ifname, const std::vector<std::string>& altnames,
|
||||||
|
std::string& matched) const;
|
||||||
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;
|
|
||||||
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
|
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
|
||||||
|
|
||||||
int ifid_;
|
int ifid_{-1};
|
||||||
sa_family_t family_;
|
ip_addr_pref addr_pref_{ip_addr_pref::IPV4};
|
||||||
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_{-1};
|
||||||
int ev_fd_;
|
int ev_fd_{-1};
|
||||||
int nl80211_id_;
|
int nl80211_id_{-1};
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
|
|
||||||
bool want_route_dump_;
|
bool want_route_dump_{false};
|
||||||
bool want_link_dump_;
|
bool want_link_dump_{false};
|
||||||
bool want_addr_dump_;
|
bool want_addr_dump_{false};
|
||||||
bool dump_in_progress_;
|
bool dump_in_progress_{false};
|
||||||
bool is_p2p_;
|
bool is_p2p_{false};
|
||||||
|
|
||||||
unsigned long long bandwidth_down_total_;
|
unsigned long long bandwidth_down_total_{0};
|
||||||
unsigned long long bandwidth_up_total_;
|
unsigned long long bandwidth_up_total_{0};
|
||||||
|
unsigned long long bandwidth_down_prev_{0};
|
||||||
|
unsigned long long bandwidth_up_prev_{0};
|
||||||
|
std::chrono::steady_clock::time_point bandwidth_last_sample_time_;
|
||||||
|
|
||||||
std::string state_;
|
std::string state_;
|
||||||
std::string essid_;
|
std::string essid_;
|
||||||
std::string bssid_;
|
std::string bssid_;
|
||||||
bool carrier_;
|
bool carrier_{false};
|
||||||
std::string ifname_;
|
std::string ifname_;
|
||||||
std::string ipaddr_;
|
std::string ipaddr_;
|
||||||
|
std::string ipaddr6_;
|
||||||
std::string gwaddr_;
|
std::string gwaddr_;
|
||||||
std::string netmask_;
|
std::string netmask_;
|
||||||
int cidr_;
|
std::string netmask6_;
|
||||||
|
int cidr_{0};
|
||||||
|
int cidr6_{0};
|
||||||
int32_t signal_strength_dbm_;
|
int32_t signal_strength_dbm_;
|
||||||
uint8_t signal_strength_;
|
uint8_t signal_strength_;
|
||||||
std::string signal_strength_app_;
|
std::string signal_strength_app_;
|
||||||
@@ -85,9 +94,9 @@ class Network : public ALabel {
|
|||||||
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_{RFKILL_TYPE_WLAN};
|
||||||
#endif
|
#endif
|
||||||
float frequency_;
|
float frequency_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "util/json.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::niri {
|
||||||
|
|
||||||
|
class EventHandler {
|
||||||
|
public:
|
||||||
|
virtual void onEvent(const Json::Value& ev) = 0;
|
||||||
|
virtual ~EventHandler() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IPC {
|
||||||
|
public:
|
||||||
|
IPC();
|
||||||
|
|
||||||
|
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
|
||||||
|
void unregisterForIPC(EventHandler* handler);
|
||||||
|
|
||||||
|
static Json::Value send(const Json::Value& request);
|
||||||
|
|
||||||
|
// The data members are only safe to access while dataMutex_ is locked.
|
||||||
|
std::lock_guard<std::mutex> lockData() { return std::lock_guard(dataMutex_); }
|
||||||
|
const std::vector<Json::Value>& workspaces() const { return workspaces_; }
|
||||||
|
const std::vector<Json::Value>& windows() const { return windows_; }
|
||||||
|
const std::vector<std::string>& keyboardLayoutNames() const { return keyboardLayoutNames_; }
|
||||||
|
unsigned keyboardLayoutCurrent() const { return keyboardLayoutCurrent_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void startIPC();
|
||||||
|
static int connectToSocket();
|
||||||
|
void parseIPC(const std::string&);
|
||||||
|
|
||||||
|
std::mutex dataMutex_;
|
||||||
|
std::vector<Json::Value> workspaces_;
|
||||||
|
std::vector<Json::Value> windows_;
|
||||||
|
std::vector<std::string> keyboardLayoutNames_;
|
||||||
|
unsigned keyboardLayoutCurrent_;
|
||||||
|
|
||||||
|
util::JsonParser parser_;
|
||||||
|
std::mutex callbackMutex_;
|
||||||
|
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::unique_ptr<IPC> gIPC;
|
||||||
|
|
||||||
|
}; // namespace waybar::modules::niri
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/niri/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::niri {
|
||||||
|
|
||||||
|
class Language : public ALabel, public EventHandler {
|
||||||
|
public:
|
||||||
|
Language(const std::string&, const Bar&, const Json::Value&);
|
||||||
|
~Language() override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateFromIPC();
|
||||||
|
void onEvent(const Json::Value& ev) override;
|
||||||
|
void doUpdate();
|
||||||
|
|
||||||
|
struct Layout {
|
||||||
|
std::string full_name;
|
||||||
|
std::string short_name;
|
||||||
|
std::string variant;
|
||||||
|
std::string short_description;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Layout getLayout(const std::string& fullName);
|
||||||
|
|
||||||
|
std::mutex mutex_;
|
||||||
|
const Bar& bar_;
|
||||||
|
|
||||||
|
std::vector<Layout> layouts_;
|
||||||
|
unsigned current_idx_;
|
||||||
|
std::string last_short_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::niri
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <json/value.h>
|
||||||
|
|
||||||
|
#include "AAppIconLabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/niri/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::niri {
|
||||||
|
|
||||||
|
class Window : public AAppIconLabel, public EventHandler {
|
||||||
|
public:
|
||||||
|
Window(const std::string&, const Bar&, const Json::Value&);
|
||||||
|
~Window() override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onEvent(const Json::Value& ev) override;
|
||||||
|
void doUpdate();
|
||||||
|
void setClass(const std::string& className, bool enable);
|
||||||
|
|
||||||
|
const Bar& bar_;
|
||||||
|
|
||||||
|
std::string oldAppId_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::niri
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <json/value.h>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/niri/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::niri {
|
||||||
|
|
||||||
|
class Workspaces : public AModule, public EventHandler {
|
||||||
|
public:
|
||||||
|
Workspaces(const std::string&, const Bar&, const Json::Value&);
|
||||||
|
~Workspaces() override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onEvent(const Json::Value& ev) override;
|
||||||
|
void doUpdate();
|
||||||
|
Gtk::Button& addButton(const Json::Value& ws);
|
||||||
|
std::string getIcon(const std::string& value, const Json::Value& ws);
|
||||||
|
|
||||||
|
const Bar& bar_;
|
||||||
|
Gtk::Box box_;
|
||||||
|
// Map from niri workspace id to button.
|
||||||
|
std::unordered_map<uint64_t, Gtk::Button> buttons_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::niri
|
||||||
@@ -9,22 +9,31 @@ namespace waybar::modules {
|
|||||||
|
|
||||||
struct Profile {
|
struct Profile {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
// Legacy driver field, kept for backward compatibility with the
|
||||||
|
// `{driver}` format placeholder and with older power-profiles-daemon
|
||||||
|
// versions that only expose a single `Driver` DBus property.
|
||||||
std::string driver;
|
std::string driver;
|
||||||
|
std::string cpuDriver;
|
||||||
|
std::string platformDriver;
|
||||||
|
|
||||||
Profile(std::string n, std::string d) : name(std::move(n)), driver(std::move(d)) {}
|
Profile(std::string n, std::string d, std::string cd, std::string pd)
|
||||||
|
: name(std::move(n)),
|
||||||
|
driver(std::move(d)),
|
||||||
|
cpuDriver(std::move(cd)),
|
||||||
|
platformDriver(std::move(pd)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PowerProfilesDaemon : public ALabel {
|
class PowerProfilesDaemon : public ALabel {
|
||||||
public:
|
public:
|
||||||
PowerProfilesDaemon(const std::string &, const Json::Value &);
|
PowerProfilesDaemon(const std::string&, const Json::Value&);
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
void profileChangedCb(const Gio::DBus::Proxy::MapChangedProperties &,
|
void profileChangedCb(const Gio::DBus::Proxy::MapChangedProperties&,
|
||||||
const std::vector<Glib::ustring> &);
|
const std::vector<Glib::ustring>&);
|
||||||
void busConnectedCb(Glib::RefPtr<Gio::AsyncResult> &r);
|
void busConnectedCb(Glib::RefPtr<Gio::AsyncResult>& r);
|
||||||
void getAllPropsCb(Glib::RefPtr<Gio::AsyncResult> &r);
|
void getAllPropsCb(Glib::RefPtr<Gio::AsyncResult>& r);
|
||||||
void setPropCb(Glib::RefPtr<Gio::AsyncResult> &r);
|
void setPropCb(Glib::RefPtr<Gio::AsyncResult>& r);
|
||||||
void populateInitState();
|
void populateInitState();
|
||||||
bool handleToggle(GdkEventButton *const &e) override;
|
bool handleToggle(GdkEventButton* const& e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// True if we're connected to the dbug interface. False if we're
|
// True if we're connected to the dbug interface. False if we're
|
||||||
@@ -32,7 +41,7 @@ class PowerProfilesDaemon : public ALabel {
|
|||||||
bool connected_;
|
bool connected_;
|
||||||
// Look for a profile name in the list of available profiles and
|
// Look for a profile name in the list of available profiles and
|
||||||
// switch activeProfile_ to it.
|
// switch activeProfile_ to it.
|
||||||
void switchToProfile(std::string const &);
|
void switchToProfile(std::string const&);
|
||||||
// Used to toggle/display the profiles
|
// Used to toggle/display the profiles
|
||||||
std::vector<Profile> availableProfiles_;
|
std::vector<Profile> availableProfiles_;
|
||||||
// Points to the active profile in the profiles list
|
// Points to the active profile in the profiles list
|
||||||
|
|||||||
@@ -13,24 +13,27 @@ namespace waybar::modules::privacy {
|
|||||||
|
|
||||||
class Privacy : public AModule {
|
class Privacy : public AModule {
|
||||||
public:
|
public:
|
||||||
Privacy(const std::string &, const Json::Value &, const std::string &pos);
|
Privacy(const std::string&, const Json::Value&, Gtk::Orientation, const std::string& pos);
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
void onPrivacyNodesChanged();
|
void onPrivacyNodesChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<PrivacyNodeInfo *> nodes_screenshare; // Screen is being shared
|
std::list<PrivacyNodeInfo*> nodes_screenshare; // Screen is being shared
|
||||||
std::list<PrivacyNodeInfo *> nodes_audio_in; // Application is using the microphone
|
std::list<PrivacyNodeInfo*> nodes_audio_in; // Application is using the microphone
|
||||||
std::list<PrivacyNodeInfo *> nodes_audio_out; // Application is outputting audio
|
std::list<PrivacyNodeInfo*> nodes_audio_out; // Application is outputting audio
|
||||||
|
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
sigc::connection visibility_conn;
|
sigc::connection visibility_conn;
|
||||||
|
|
||||||
// Config
|
// Config
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
|
std::vector<PrivacyItem*> modules_;
|
||||||
uint iconSpacing = 4;
|
uint iconSpacing = 4;
|
||||||
uint iconSize = 20;
|
uint iconSize = 20;
|
||||||
uint transition_duration = 250;
|
uint transition_duration = 250;
|
||||||
|
std::set<std::pair<PrivacyNodeType, std::string>> ignore;
|
||||||
|
bool ignore_monitor = true;
|
||||||
|
|
||||||
std::shared_ptr<util::PipewireBackend::PipewireBackend> backend = nullptr;
|
std::shared_ptr<util::PipewireBackend::PipewireBackend> backend = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,16 +16,16 @@ namespace waybar::modules::privacy {
|
|||||||
|
|
||||||
class PrivacyItem : public Gtk::Revealer {
|
class PrivacyItem : public Gtk::Revealer {
|
||||||
public:
|
public:
|
||||||
PrivacyItem(const Json::Value &config_, enum PrivacyNodeType privacy_type_,
|
PrivacyItem(const Json::Value& config_, enum PrivacyNodeType privacy_type_,
|
||||||
std::list<PrivacyNodeInfo *> *nodes, const std::string &pos, const uint icon_size,
|
std::list<PrivacyNodeInfo*>* nodes, Gtk::Orientation orientation,
|
||||||
const uint transition_duration);
|
const std::string& pos, const uint icon_size, const uint transition_duration);
|
||||||
|
|
||||||
enum PrivacyNodeType privacy_type;
|
enum PrivacyNodeType privacy_type;
|
||||||
|
|
||||||
void set_in_use(bool in_use);
|
void set_in_use(bool in_use);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<PrivacyNodeInfo *> *nodes;
|
std::list<PrivacyNodeInfo*>* nodes;
|
||||||
|
|
||||||
sigc::connection signal_conn;
|
sigc::connection signal_conn;
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,6 @@
|
|||||||
#include "util/audio_backend.hpp"
|
#include "util/audio_backend.hpp"
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
enum class PulseaudioSliderTarget {
|
|
||||||
Sink,
|
|
||||||
Source,
|
|
||||||
};
|
|
||||||
|
|
||||||
class PulseaudioSlider : public ASlider {
|
class PulseaudioSlider : public ASlider {
|
||||||
public:
|
public:
|
||||||
PulseaudioSlider(const std::string&, const Json::Value&);
|
PulseaudioSlider(const std::string&, const Json::Value&);
|
||||||
@@ -21,7 +16,15 @@ class PulseaudioSlider : public ASlider {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<util::AudioBackend> backend = nullptr;
|
std::shared_ptr<util::AudioBackend> backend = nullptr;
|
||||||
PulseaudioSliderTarget target = PulseaudioSliderTarget::Sink;
|
util::PulseaudioTarget target = util::PulseaudioTarget::Sink;
|
||||||
|
|
||||||
|
bool zero_on_mute = true;
|
||||||
|
bool unmute_on_volume_change = true;
|
||||||
|
// zero_on_mute and unmute_on_volume_change default to true
|
||||||
|
// in order to maintain previous behaviour when using a
|
||||||
|
// config in which these values are undefined
|
||||||
|
|
||||||
|
bool previously_muted = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
@@ -10,24 +10,25 @@ namespace waybar::modules::river {
|
|||||||
|
|
||||||
class Layout : public waybar::ALabel {
|
class Layout : public waybar::ALabel {
|
||||||
public:
|
public:
|
||||||
Layout(const std::string &, const waybar::Bar &, const Json::Value &);
|
Layout(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
virtual ~Layout();
|
virtual ~Layout();
|
||||||
|
|
||||||
// Handlers for wayland events
|
// Handlers for wayland events
|
||||||
void handle_name(const char *name);
|
void handle_name(const char* name);
|
||||||
void handle_clear();
|
void handle_clear();
|
||||||
void handle_focused_output(struct wl_output *output);
|
void handle_focused_output(struct wl_output* output);
|
||||||
void handle_unfocused_output(struct wl_output *output);
|
void handle_unfocused_output(struct wl_output* output);
|
||||||
|
|
||||||
struct zriver_status_manager_v1 *status_manager_;
|
struct zriver_status_manager_v1* status_manager_;
|
||||||
struct wl_seat *seat_;
|
struct wl_seat* seat_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const waybar::Bar &bar_;
|
const waybar::Bar& bar_;
|
||||||
struct wl_output *output_; // stores the output this module belongs to
|
std::string name_;
|
||||||
struct wl_output *focused_output_; // stores the currently focused output
|
struct wl_output* output_; // stores the output this module belongs to
|
||||||
struct zriver_output_status_v1 *output_status_;
|
struct wl_output* focused_output_; // stores the currently focused output
|
||||||
struct zriver_seat_status_v1 *seat_status_;
|
struct zriver_output_status_v1* output_status_;
|
||||||
|
struct zriver_seat_status_v1* seat_status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace waybar::modules::river */
|
} /* namespace waybar::modules::river */
|
||||||
|
|||||||
@@ -10,19 +10,19 @@ namespace waybar::modules::river {
|
|||||||
|
|
||||||
class Mode : public waybar::ALabel {
|
class Mode : public waybar::ALabel {
|
||||||
public:
|
public:
|
||||||
Mode(const std::string &, const waybar::Bar &, const Json::Value &);
|
Mode(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
virtual ~Mode();
|
virtual ~Mode();
|
||||||
|
|
||||||
// Handlers for wayland events
|
// Handlers for wayland events
|
||||||
void handle_mode(const char *mode);
|
void handle_mode(const char* mode);
|
||||||
|
|
||||||
struct zriver_status_manager_v1 *status_manager_;
|
struct zriver_status_manager_v1* status_manager_;
|
||||||
struct wl_seat *seat_;
|
struct wl_seat* seat_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const waybar::Bar &bar_;
|
const waybar::Bar& bar_;
|
||||||
std::string mode_;
|
std::string mode_;
|
||||||
struct zriver_seat_status_v1 *seat_status_;
|
struct zriver_seat_status_v1* seat_status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace waybar::modules::river */
|
} /* namespace waybar::modules::river */
|
||||||
|
|||||||
@@ -13,26 +13,27 @@ 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();
|
virtual ~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_urgent_tags(uint32_t tags);
|
||||||
|
|
||||||
|
void handle_show();
|
||||||
void handle_primary_clicked(uint32_t tag);
|
void handle_primary_clicked(uint32_t tag);
|
||||||
bool handle_button_press(GdkEventButton *event_button, 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 zriver_control_v1* control_;
|
||||||
struct wl_seat *seat_;
|
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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace waybar::modules::river */
|
} /* namespace waybar::modules::river */
|
||||||
|
|||||||
@@ -12,22 +12,22 @@ namespace waybar::modules::river {
|
|||||||
|
|
||||||
class Window : public waybar::ALabel {
|
class Window : public waybar::ALabel {
|
||||||
public:
|
public:
|
||||||
Window(const std::string &, const waybar::Bar &, const Json::Value &);
|
Window(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
virtual ~Window();
|
virtual ~Window();
|
||||||
|
|
||||||
// Handlers for wayland events
|
// Handlers for wayland events
|
||||||
void handle_focused_view(const char *title);
|
void handle_focused_view(const char* title);
|
||||||
void handle_focused_output(struct wl_output *output);
|
void handle_focused_output(struct wl_output* output);
|
||||||
void handle_unfocused_output(struct wl_output *output);
|
void handle_unfocused_output(struct wl_output* output);
|
||||||
|
|
||||||
struct zriver_status_manager_v1 *status_manager_;
|
struct zriver_status_manager_v1* status_manager_;
|
||||||
struct wl_seat *seat_;
|
struct wl_seat* seat_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const waybar::Bar &bar_;
|
const waybar::Bar& bar_;
|
||||||
struct wl_output *output_; // stores the output this module belongs to
|
struct wl_output* output_; // stores the output this module belongs to
|
||||||
struct wl_output *focused_output_; // stores the currently focused output
|
struct wl_output* focused_output_; // stores the currently focused output
|
||||||
struct zriver_seat_status_v1 *seat_status_;
|
struct zriver_seat_status_v1* seat_status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace waybar::modules::river */
|
} /* namespace waybar::modules::river */
|
||||||
|
|||||||
@@ -11,18 +11,18 @@ 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();
|
virtual ~Sndio();
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
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*) override;
|
||||||
bool handleToggle(GdkEventButton *const &) override;
|
bool handleToggle(GdkEventButton* const&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto connect_to_sndio() -> void;
|
auto connect_to_sndio() -> void;
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
struct sioctl_hdl *hdl_;
|
struct sioctl_hdl* hdl_;
|
||||||
std::vector<struct pollfd> pfds_;
|
std::vector<struct pollfd> pfds_;
|
||||||
unsigned int addr_;
|
unsigned int addr_;
|
||||||
unsigned int volume_, old_volume_, maxval_;
|
unsigned int volume_, old_volume_, maxval_;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ 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 Bar&,
|
||||||
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>&)>&, const std::function<void()>&);
|
||||||
~Host();
|
~Host();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -28,9 +28,13 @@ class Host {
|
|||||||
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);
|
||||||
|
void itemReady(Item&);
|
||||||
|
void itemInvalidated(Item&);
|
||||||
|
void removeItem(std::vector<std::unique_ptr<Item>>::iterator);
|
||||||
|
void clearItems();
|
||||||
|
|
||||||
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(const 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_;
|
||||||
@@ -39,10 +43,13 @@ class Host {
|
|||||||
std::size_t watcher_id_;
|
std::size_t watcher_id_;
|
||||||
GCancellable* cancellable_ = nullptr;
|
GCancellable* cancellable_ = nullptr;
|
||||||
SnWatcher* watcher_ = nullptr;
|
SnWatcher* watcher_ = nullptr;
|
||||||
|
sigc::connection retry_connection_;
|
||||||
|
unsigned retry_count_ = 0;
|
||||||
const Json::Value& config_;
|
const Json::Value& config_;
|
||||||
const Bar& bar_;
|
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_;
|
||||||
|
const std::function<void()> on_update_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::SNI
|
} // namespace waybar::modules::SNI
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
class IconManager {
|
||||||
|
public:
|
||||||
|
static IconManager& instance() {
|
||||||
|
static IconManager instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIconsConfig(const Json::Value& icons_config) {
|
||||||
|
if (icons_config.isObject()) {
|
||||||
|
for (const auto& key : icons_config.getMemberNames()) {
|
||||||
|
std::string app_name = key;
|
||||||
|
const Json::Value& icon_value = icons_config[key];
|
||||||
|
|
||||||
|
if (icon_value.isString()) {
|
||||||
|
std::string icon_path = icon_value.asString();
|
||||||
|
icons_map_[app_name] = icon_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
spdlog::warn("Invalid icon config format.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getIconForApp(const std::string& app_name) const {
|
||||||
|
auto it = icons_map_.find(app_name);
|
||||||
|
if (it != icons_map_.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IconManager() = default;
|
||||||
|
std::unordered_map<std::string, std::string> icons_map_;
|
||||||
|
};
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <libdbusmenu-gtk/dbusmenu-gtk.h>
|
#include <libdbusmenu-gtk/dbusmenu-gtk.h>
|
||||||
#include <sigc++/trackable.h>
|
#include <sigc++/trackable.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
@@ -25,8 +26,12 @@ 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&, const Bar&,
|
||||||
~Item() = default;
|
const std::function<void(Item&)>&, const std::function<void(Item&)>&,
|
||||||
|
const std::function<void()>&);
|
||||||
|
~Item();
|
||||||
|
|
||||||
|
bool isReady() const;
|
||||||
|
|
||||||
std::string bus_name;
|
std::string bus_name;
|
||||||
std::string object_path;
|
std::string object_path;
|
||||||
@@ -41,9 +46,12 @@ class Item : public sigc::trackable {
|
|||||||
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;
|
||||||
|
bool has_custom_icon_ = false;
|
||||||
Glib::RefPtr<Gtk::IconTheme> icon_theme;
|
Glib::RefPtr<Gtk::IconTheme> icon_theme;
|
||||||
std::string overlay_icon_name;
|
std::string overlay_icon_name;
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> overlay_icon_pixmap;
|
||||||
std::string attention_icon_name;
|
std::string attention_icon_name;
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> attention_icon_pixmap;
|
||||||
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;
|
||||||
@@ -62,14 +70,22 @@ class Item : public sigc::trackable {
|
|||||||
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);
|
||||||
|
void setReady();
|
||||||
|
void invalidate();
|
||||||
|
void setCustomIcon(const std::string& id);
|
||||||
void getUpdatedProperties();
|
void getUpdatedProperties();
|
||||||
void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result);
|
void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result);
|
||||||
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);
|
static Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant);
|
||||||
Glib::RefPtr<Gdk::Pixbuf> getIconPixbuf();
|
Glib::RefPtr<Gdk::Pixbuf> getIconPixbuf();
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> getAttentionIconPixbuf();
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> getOverlayIconPixbuf();
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> loadIconFromNameOrFile(const std::string& name, bool log_failure);
|
||||||
|
static Glib::RefPtr<Gdk::Pixbuf> overlayPixbufs(const Glib::RefPtr<Gdk::Pixbuf>&,
|
||||||
|
const Glib::RefPtr<Gdk::Pixbuf>&);
|
||||||
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);
|
||||||
@@ -85,8 +101,13 @@ class Item : public sigc::trackable {
|
|||||||
gdouble distance_scrolled_y_ = 0;
|
gdouble distance_scrolled_y_ = 0;
|
||||||
// visibility of items with Status == Passive
|
// visibility of items with Status == Passive
|
||||||
bool show_passive_ = false;
|
bool show_passive_ = false;
|
||||||
|
bool ready_ = false;
|
||||||
|
Glib::ustring status_ = "active";
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
|
const std::function<void(Item&)> on_ready_;
|
||||||
|
const std::function<void(Item&)> on_invalidate_;
|
||||||
|
const std::function<void()> on_updated_;
|
||||||
|
|
||||||
Glib::RefPtr<Gio::DBus::Proxy> proxy_;
|
Glib::RefPtr<Gio::DBus::Proxy> proxy_;
|
||||||
Glib::RefPtr<Gio::Cancellable> cancellable_;
|
Glib::RefPtr<Gio::Cancellable> cancellable_;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class Tray : public AModule {
|
|||||||
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);
|
||||||
|
void queueUpdate();
|
||||||
|
|
||||||
static inline std::size_t nb_hosts_ = 0;
|
static inline std::size_t nb_hosts_ = 0;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
|
|||||||
@@ -30,27 +30,27 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::SNI
|
} // namespace waybar::modules::SNI
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class BarIpcClient {
|
|||||||
void onModeUpdate(bool visible_by_modifier);
|
void onModeUpdate(bool visible_by_modifier);
|
||||||
void onUrgencyUpdate(bool visible_by_urgency);
|
void onUrgencyUpdate(bool visible_by_urgency);
|
||||||
void update();
|
void update();
|
||||||
bool isModuleEnabled(std::string name);
|
bool isModuleEnabled(const std::string& name);
|
||||||
|
|
||||||
Bar& bar_;
|
Bar& bar_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ipc.hpp"
|
#include "ipc.hpp"
|
||||||
|
#include "util/SafeSignal.hpp"
|
||||||
|
#include "util/scoped_fd.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::sway {
|
namespace waybar::modules::sway {
|
||||||
@@ -27,25 +29,25 @@ class Ipc {
|
|||||||
std::string payload;
|
std::string payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
sigc::signal<void, const struct ipc_response &> signal_event;
|
::waybar::SafeSignal<const struct ipc_response&> signal_event;
|
||||||
sigc::signal<void, const struct ipc_response &> signal_cmd;
|
::waybar::SafeSignal<const struct ipc_response&> signal_cmd;
|
||||||
|
|
||||||
void sendCmd(uint32_t type, const std::string &payload = "");
|
void sendCmd(uint32_t type, const std::string& payload = "");
|
||||||
void subscribe(const std::string &payload);
|
void subscribe(const std::string& payload);
|
||||||
void handleEvent();
|
void handleEvent();
|
||||||
void setWorker(std::function<void()> &&func);
|
void setWorker(std::function<void()>&& func);
|
||||||
|
|
||||||
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_;
|
util::ScopedFd fd_;
|
||||||
int fd_event_;
|
util::ScopedFd fd_event_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Language : public ALabel, public sigc::trackable {
|
|||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class DispayedShortFlag { None = 0, ShortName = 1, ShortDescription = 1 << 1 };
|
enum class DisplayedShortFlag { None = 0, ShortName = 1, ShortDescription = 1 << 1 };
|
||||||
|
|
||||||
struct Layout {
|
struct Layout {
|
||||||
std::string full_name;
|
std::string full_name;
|
||||||
@@ -47,7 +47,7 @@ class Language : public ALabel, public sigc::trackable {
|
|||||||
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&);
|
||||||
|
|
||||||
auto set_current_layout(std::string current_layout) -> void;
|
auto set_current_layout(const std::string& current_layout) -> void;
|
||||||
auto init_layouts_map(const std::vector<std::string>& used_layouts) -> void;
|
auto init_layouts_map(const std::vector<std::string>& used_layouts) -> void;
|
||||||
|
|
||||||
const static std::string XKB_LAYOUT_NAMES_KEY;
|
const static std::string XKB_LAYOUT_NAMES_KEY;
|
||||||
@@ -58,7 +58,7 @@ class Language : public ALabel, public sigc::trackable {
|
|||||||
std::map<std::string, Layout> layouts_map_;
|
std::map<std::string, Layout> layouts_map_;
|
||||||
bool hide_single_;
|
bool hide_single_;
|
||||||
bool is_variant_displayed;
|
bool is_variant_displayed;
|
||||||
std::byte displayed_short_flag = static_cast<std::byte>(DispayedShortFlag::None);
|
std::byte displayed_short_flag = static_cast<std::byte>(DisplayedShortFlag::None);
|
||||||
|
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
|
|||||||
@@ -19,10 +19,11 @@ class Window : public AAppIconLabel, public sigc::trackable {
|
|||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setClass(std::string classname, bool enable);
|
void setClass(const 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, int, std::string, std::string, std::string, std::string, std::string>
|
std::tuple<std::size_t, int, int, std::string, std::string, std::string, std::string, std::string,
|
||||||
|
std::string>
|
||||||
getFocusedNode(const Json::Value& nodes, std::string& output);
|
getFocusedNode(const Json::Value& nodes, std::string& output);
|
||||||
void getTree();
|
void getTree();
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ class Window : public AAppIconLabel, public sigc::trackable {
|
|||||||
std::string old_app_id_;
|
std::string old_app_id_;
|
||||||
std::size_t app_nb_;
|
std::size_t app_nb_;
|
||||||
std::string shell_;
|
std::string shell_;
|
||||||
|
std::string marks_;
|
||||||
int floating_count_;
|
int floating_count_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
|
|||||||
@@ -24,10 +24,11 @@ class Workspaces : public AModule, public sigc::trackable {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr std::string_view workspace_switch_cmd_ = "workspace {} \"{}\"";
|
static constexpr std::string_view workspace_switch_cmd_ = "workspace {} \"{}\"";
|
||||||
|
static constexpr std::string_view workspace_switch_number_cmd_ = "workspace {} number {}";
|
||||||
static constexpr std::string_view persistent_workspace_switch_cmd_ =
|
static constexpr std::string_view persistent_workspace_switch_cmd_ =
|
||||||
R"(workspace {} "{}"; move workspace to output "{}"; workspace {} "{}")";
|
R"(workspace {} "{}"; move workspace to output "{}"; workspace {} "{}")";
|
||||||
|
|
||||||
static int convertWorkspaceNameToNum(std::string name);
|
static int convertWorkspaceNameToNum(const std::string& name);
|
||||||
static int windowRewritePriorityFunction(std::string const& window_rule);
|
static int windowRewritePriorityFunction(std::string const& window_rule);
|
||||||
|
|
||||||
void onCmd(const struct Ipc::ipc_response&);
|
void onCmd(const struct Ipc::ipc_response&);
|
||||||
@@ -40,7 +41,7 @@ class Workspaces : public AModule, public sigc::trackable {
|
|||||||
std::string getIcon(const std::string&, const Json::Value&);
|
std::string getIcon(const std::string&, const Json::Value&);
|
||||||
std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) 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;
|
||||||
static std::string trimWorkspaceName(std::string);
|
static std::string trimWorkspaceName(const std::string&);
|
||||||
bool handleScroll(GdkEventScroll* /*unused*/) override;
|
bool handleScroll(GdkEventScroll* /*unused*/) override;
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
@@ -48,8 +49,7 @@ class Workspaces : public AModule, public sigc::trackable {
|
|||||||
std::vector<std::string> high_priority_named_;
|
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_;
|
||||||
std::string m_formatWindowSeperator;
|
std::string m_formatWindowSeparator;
|
||||||
std::string m_windowRewriteDefault;
|
|
||||||
util::RegexCollection m_windowRewriteRules;
|
util::RegexCollection m_windowRewriteRules;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::unordered_map<std::string, Gtk::Button> buttons_;
|
std::unordered_map<std::string, Gtk::Button> buttons_;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <giomm/dbusproxy.h>
|
#include <giomm/dbusproxy.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
|
|
||||||
@@ -10,21 +11,43 @@ namespace waybar::modules {
|
|||||||
|
|
||||||
class SystemdFailedUnits : public ALabel {
|
class SystemdFailedUnits : public ALabel {
|
||||||
public:
|
public:
|
||||||
SystemdFailedUnits(const std::string &, const Json::Value &);
|
SystemdFailedUnits(const std::string&, const Json::Value&);
|
||||||
virtual ~SystemdFailedUnits();
|
virtual ~SystemdFailedUnits() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool hide_on_ok;
|
struct FailedUnit {
|
||||||
std::string format_ok;
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
std::string load_state;
|
||||||
|
std::string active_state;
|
||||||
|
std::string sub_state;
|
||||||
|
std::string scope;
|
||||||
|
};
|
||||||
|
|
||||||
bool update_pending;
|
bool hide_on_ok_;
|
||||||
uint32_t nr_failed_system, nr_failed_user;
|
std::string format_ok_;
|
||||||
std::string last_status;
|
std::string tooltip_format_;
|
||||||
Glib::RefPtr<Gio::DBus::Proxy> system_proxy, user_proxy;
|
std::string tooltip_format_ok_;
|
||||||
|
std::string tooltip_unit_format_;
|
||||||
|
|
||||||
void notify_cb(const Glib::ustring &sender_name, const Glib::ustring &signal_name,
|
bool update_pending_;
|
||||||
const Glib::VariantContainerBase &arguments);
|
std::string system_state_, user_state_, overall_state_;
|
||||||
|
uint32_t nr_failed_system_, nr_failed_user_, nr_failed_;
|
||||||
|
std::string last_status_;
|
||||||
|
Glib::RefPtr<Gio::DBus::Proxy> system_props_proxy_, user_props_proxy_;
|
||||||
|
Glib::RefPtr<Gio::DBus::Proxy> system_manager_proxy_, user_manager_proxy_;
|
||||||
|
std::vector<FailedUnit> failed_units_;
|
||||||
|
|
||||||
|
void notify_cb(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
|
||||||
|
const Glib::VariantContainerBase& arguments);
|
||||||
|
void RequestFailedUnits();
|
||||||
|
void RequestFailedUnitsList();
|
||||||
|
void RequestSystemState();
|
||||||
|
std::vector<FailedUnit> LoadFailedUnitsList(const char* kind,
|
||||||
|
Glib::RefPtr<Gio::DBus::Proxy>& proxy,
|
||||||
|
const std::string& scope);
|
||||||
|
std::string BuildTooltipFailedList() const;
|
||||||
void updateData();
|
void updateData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,13 @@ class Temperature : public ALabel {
|
|||||||
Temperature(const std::string&, const Json::Value&);
|
Temperature(const std::string&, const Json::Value&);
|
||||||
virtual ~Temperature() = default;
|
virtual ~Temperature() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
void suspend() override;
|
||||||
|
void resume() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float getTemperature();
|
float getTemperature();
|
||||||
bool isCritical(uint16_t);
|
bool isCritical(uint16_t);
|
||||||
|
bool isWarning(uint16_t);
|
||||||
|
|
||||||
std::string file_path_;
|
std::string file_path_;
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
|
|||||||
+22
-22
@@ -12,7 +12,7 @@ namespace waybar::modules {
|
|||||||
|
|
||||||
class UPower final : public AIconLabel {
|
class UPower final : public AIconLabel {
|
||||||
public:
|
public:
|
||||||
UPower(const std::string &, const Json::Value &);
|
UPower(const std::string&, const Json::Value&);
|
||||||
virtual ~UPower();
|
virtual ~UPower();
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
@@ -30,17 +30,17 @@ class UPower final : public AIconLabel {
|
|||||||
|
|
||||||
// UPower device info
|
// UPower device info
|
||||||
struct upDevice_output {
|
struct upDevice_output {
|
||||||
UpDevice *upDevice{NULL};
|
UpDevice* upDevice{NULL};
|
||||||
double percentage{0.0};
|
double percentage{0.0};
|
||||||
double temperature{0.0};
|
double temperature{0.0};
|
||||||
guint64 time_full{0u};
|
guint64 time_full{0u};
|
||||||
guint64 time_empty{0u};
|
guint64 time_empty{0u};
|
||||||
gchar *icon_name{(char *)'\0'};
|
gchar* icon_name{(char*)'\0'};
|
||||||
bool upDeviceValid{false};
|
bool upDeviceValid{false};
|
||||||
UpDeviceState state;
|
UpDeviceState state;
|
||||||
UpDeviceKind kind;
|
UpDeviceKind kind;
|
||||||
char *nativePath{(char *)'\0'};
|
char* nativePath{(char*)'\0'};
|
||||||
char *model{(char *)'\0'};
|
char* model{(char*)'\0'};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Technical variables
|
// Technical variables
|
||||||
@@ -53,13 +53,13 @@ class UPower final : public AIconLabel {
|
|||||||
bool sleeping_;
|
bool sleeping_;
|
||||||
|
|
||||||
// Technical functions
|
// Technical functions
|
||||||
void addDevice(UpDevice *);
|
void addDevice(UpDevice*);
|
||||||
void removeDevice(const gchar *);
|
void removeDevice(const gchar*);
|
||||||
void removeDevices();
|
void removeDevices();
|
||||||
void resetDevices();
|
void resetDevices();
|
||||||
void setDisplayDevice();
|
void setDisplayDevice();
|
||||||
const Glib::ustring getText(const upDevice_output &upDevice_, const std::string &format);
|
const Glib::ustring getText(const upDevice_output& upDevice_, const std::string& format);
|
||||||
bool queryTooltipCb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &);
|
bool queryTooltipCb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip>&);
|
||||||
|
|
||||||
// DBUS variables
|
// DBUS variables
|
||||||
guint watcherID_;
|
guint watcherID_;
|
||||||
@@ -67,28 +67,28 @@ class UPower final : public AIconLabel {
|
|||||||
guint subscrID_{0u};
|
guint subscrID_{0u};
|
||||||
|
|
||||||
// UPower variables
|
// UPower variables
|
||||||
UpClient *upClient_;
|
UpClient* upClient_;
|
||||||
upDevice_output upDevice_; // Device to display
|
upDevice_output upDevice_; // Device to display
|
||||||
typedef std::unordered_map<std::string, upDevice_output> Devices;
|
typedef std::unordered_map<std::string, upDevice_output> Devices;
|
||||||
Devices devices_;
|
Devices devices_;
|
||||||
bool upRunning_{true};
|
bool upRunning_{true};
|
||||||
|
|
||||||
// DBus callbacks
|
// DBus callbacks
|
||||||
void getConn_cb(Glib::RefPtr<Gio::AsyncResult> &result);
|
void getConn_cb(Glib::RefPtr<Gio::AsyncResult>& result);
|
||||||
void onAppear(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &,
|
void onAppear(const Glib::RefPtr<Gio::DBus::Connection>&, const Glib::ustring&,
|
||||||
const Glib::ustring &);
|
const Glib::ustring&);
|
||||||
void onVanished(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &);
|
void onVanished(const Glib::RefPtr<Gio::DBus::Connection>&, const Glib::ustring&);
|
||||||
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
|
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection>& connection,
|
||||||
const Glib::ustring &sender_name, const Glib::ustring &object_path,
|
const Glib::ustring& sender_name, const Glib::ustring& object_path,
|
||||||
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
|
const Glib::ustring& interface_name, const Glib::ustring& signal_name,
|
||||||
const Glib::VariantContainerBase ¶meters);
|
const Glib::VariantContainerBase& parameters);
|
||||||
|
|
||||||
// UPower callbacks
|
// UPower callbacks
|
||||||
static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data);
|
static void deviceAdded_cb(UpClient* client, UpDevice* device, gpointer data);
|
||||||
static void deviceRemoved_cb(UpClient *client, const gchar *objectPath, 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 deviceNotify_cb(UpDevice* device, GParamSpec* pspec, gpointer user_data);
|
||||||
// UPower secondary functions
|
// UPower secondary functions
|
||||||
void getUpDeviceInfo(upDevice_output &upDevice_);
|
void getUpDeviceInfo(upDevice_output& upDevice_);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "util/scoped_fd.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::wayfire {
|
||||||
|
|
||||||
|
using EventHandler = std::function<void(const std::string& event)>;
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
/*
|
||||||
|
┌───────────┐ ┌───────────┐
|
||||||
|
│ output #1 │ │ output #2 │
|
||||||
|
└─────┬─────┘ └─────┬─────┘
|
||||||
|
└─┐ └─────┐─ ─ ─ ─ ─ ─ ─ ─ ┐
|
||||||
|
┌───────┴───────┐ ┌───────┴──────┐ ┌───────┴───────┐
|
||||||
|
│ wset #1 │ │ wset #2 │ │ wset #3 │
|
||||||
|
│┌────────────┐ │ │┌────────────┐│ │┌────────────┐ │
|
||||||
|
││ workspaces │ │ ││ workspaces ││ ││ workspaces │ │
|
||||||
|
│└─┬──────────┘ │ │└────────────┘│ │└─┬──────────┘ │
|
||||||
|
│ │ ┌─────────┐│ └──────────────┘ │ │ ┌─────────┐│
|
||||||
|
│ ├─┤ view #1 ││ │ └─┤ view #3 ││
|
||||||
|
│ │ └─────────┘│ │ └─────────┘│
|
||||||
|
│ │ ┌─────────┐│ └───────────────┘
|
||||||
|
│ └─┤ view #2 ││
|
||||||
|
│ └─────────┘│
|
||||||
|
└───────────────┘
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Output {
|
||||||
|
size_t id;
|
||||||
|
size_t w, h;
|
||||||
|
size_t wset_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Workspace {
|
||||||
|
size_t num_views;
|
||||||
|
size_t num_sticky_views;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Wset {
|
||||||
|
std::optional<std::reference_wrapper<Output>> output;
|
||||||
|
std::vector<Workspace> wss;
|
||||||
|
size_t ws_w, ws_h, ws_x, ws_y;
|
||||||
|
size_t focused_view_id;
|
||||||
|
|
||||||
|
auto ws_idx() const { return ws_w * ws_y + ws_x; }
|
||||||
|
auto count_ws(const Json::Value& pos) -> Workspace&;
|
||||||
|
auto locate_ws(const Json::Value& geo) -> Workspace&;
|
||||||
|
auto locate_ws(const Json::Value& geo) const -> const Workspace&;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<std::string, Output> outputs;
|
||||||
|
std::unordered_map<size_t, Wset> wsets;
|
||||||
|
std::unordered_map<size_t, Json::Value> views;
|
||||||
|
std::string focused_output_name;
|
||||||
|
size_t maybe_empty_focus_wset_idx = {};
|
||||||
|
size_t vswitch_sticky_view_id = {};
|
||||||
|
bool new_output_detected = {};
|
||||||
|
bool vswitching = {};
|
||||||
|
|
||||||
|
auto update_view(const Json::Value& view) -> void;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Sock = util::ScopedFd;
|
||||||
|
|
||||||
|
class IPC : public std::enable_shared_from_this<IPC> {
|
||||||
|
static std::weak_ptr<IPC> instance;
|
||||||
|
Json::CharReaderBuilder reader_builder;
|
||||||
|
Json::StreamWriterBuilder writer_builder;
|
||||||
|
std::list<std::pair<std::string, std::reference_wrapper<const EventHandler>>> handlers;
|
||||||
|
std::mutex handlers_mutex;
|
||||||
|
State state;
|
||||||
|
std::mutex state_mutex;
|
||||||
|
|
||||||
|
IPC() = default;
|
||||||
|
|
||||||
|
static auto connect() -> Sock;
|
||||||
|
auto receive(Sock& sock) -> Json::Value;
|
||||||
|
auto start() -> void;
|
||||||
|
auto root_event_handler(const std::string& event, const Json::Value& data) -> void;
|
||||||
|
auto update_state_handler(const std::string& event, const Json::Value& data) -> void;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static auto get_instance() -> std::shared_ptr<IPC>;
|
||||||
|
auto send(const std::string& method, Json::Value&& data) -> Json::Value;
|
||||||
|
auto register_handler(const std::string& event, const EventHandler& handler) -> void;
|
||||||
|
auto unregister_handler(EventHandler& handler) -> void;
|
||||||
|
|
||||||
|
auto lock_state() -> std::lock_guard<std::mutex> { return std::lock_guard{state_mutex}; }
|
||||||
|
auto& get_outputs() const { return state.outputs; }
|
||||||
|
auto& get_wsets() const { return state.wsets; }
|
||||||
|
auto& get_views() const { return state.views; }
|
||||||
|
auto& get_focused_output_name() const { return state.focused_output_name; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::wayfire
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AAppIconLabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/wayfire/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::wayfire {
|
||||||
|
|
||||||
|
class Window : public AAppIconLabel {
|
||||||
|
std::shared_ptr<IPC> ipc;
|
||||||
|
EventHandler handler;
|
||||||
|
|
||||||
|
const Bar& bar_;
|
||||||
|
std::string old_app_id_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Window(const std::string& id, const Bar& bar, const Json::Value& config);
|
||||||
|
~Window() override;
|
||||||
|
|
||||||
|
auto update() -> void override;
|
||||||
|
auto update_icon_label() -> void;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::wayfire
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/wayfire/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::wayfire {
|
||||||
|
|
||||||
|
class Workspaces : public AModule {
|
||||||
|
std::shared_ptr<IPC> ipc;
|
||||||
|
EventHandler handler;
|
||||||
|
|
||||||
|
const Bar& bar_;
|
||||||
|
Gtk::Box box_;
|
||||||
|
std::vector<Gtk::Button> buttons_;
|
||||||
|
|
||||||
|
auto handleScroll(GdkEventScroll* e) -> bool override;
|
||||||
|
auto update() -> void override;
|
||||||
|
auto update_box() -> void;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Workspaces(const std::string& id, const Bar& bar, const Json::Value& config);
|
||||||
|
~Workspaces() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::wayfire
|
||||||
@@ -18,10 +18,12 @@ class Wireplumber : public ALabel {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void asyncLoadRequiredApiModules();
|
void asyncLoadRequiredApiModules();
|
||||||
void prepare();
|
void prepare(waybar::modules::Wireplumber* self);
|
||||||
void activatePlugins();
|
void activatePlugins();
|
||||||
static void updateVolume(waybar::modules::Wireplumber* self, uint32_t id);
|
static void updateVolume(waybar::modules::Wireplumber* self, uint32_t id);
|
||||||
static void updateNodeName(waybar::modules::Wireplumber* self, uint32_t id);
|
static void updateNodeName(waybar::modules::Wireplumber* self, uint32_t id);
|
||||||
|
static void updateSourceVolume(waybar::modules::Wireplumber* self, uint32_t id);
|
||||||
|
static void updateSourceName(waybar::modules::Wireplumber* self, uint32_t id); // NEW
|
||||||
static void onPluginActivated(WpObject* p, GAsyncResult* res, waybar::modules::Wireplumber* self);
|
static void onPluginActivated(WpObject* p, GAsyncResult* res, waybar::modules::Wireplumber* self);
|
||||||
static void onDefaultNodesApiLoaded(WpObject* p, GAsyncResult* res,
|
static void onDefaultNodesApiLoaded(WpObject* p, GAsyncResult* res,
|
||||||
waybar::modules::Wireplumber* self);
|
waybar::modules::Wireplumber* self);
|
||||||
@@ -32,6 +34,8 @@ class Wireplumber : public ALabel {
|
|||||||
|
|
||||||
bool handleScroll(GdkEventScroll* e) override;
|
bool handleScroll(GdkEventScroll* e) override;
|
||||||
|
|
||||||
|
static std::list<waybar::modules::Wireplumber*> modules;
|
||||||
|
|
||||||
WpCore* wp_core_;
|
WpCore* wp_core_;
|
||||||
GPtrArray* apis_;
|
GPtrArray* apis_;
|
||||||
WpObjectManager* om_;
|
WpObjectManager* om_;
|
||||||
@@ -44,6 +48,12 @@ class Wireplumber : public ALabel {
|
|||||||
double min_step_;
|
double min_step_;
|
||||||
uint32_t node_id_{0};
|
uint32_t node_id_{0};
|
||||||
std::string node_name_;
|
std::string node_name_;
|
||||||
|
std::string source_name_;
|
||||||
|
gchar* type_;
|
||||||
|
uint32_t source_node_id_;
|
||||||
|
bool source_muted_;
|
||||||
|
double source_volume_;
|
||||||
|
gchar* default_source_name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -18,18 +18,24 @@
|
|||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
|
#include "ext-workspace-v1-client-protocol.h"
|
||||||
#include "giomm/desktopappinfo.h"
|
#include "giomm/desktopappinfo.h"
|
||||||
|
#include "util/icon_loader.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#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 {
|
||||||
|
|
||||||
|
struct widget_geometry {
|
||||||
|
int x, y, w, h;
|
||||||
|
};
|
||||||
|
|
||||||
class Taskbar;
|
class Taskbar;
|
||||||
|
|
||||||
class Task {
|
class Task {
|
||||||
public:
|
public:
|
||||||
Task(const waybar::Bar &, const Json::Value &, Taskbar *,
|
Task(const waybar::Bar&, const Json::Value&, Taskbar*, struct zwlr_foreign_toplevel_handle_v1*,
|
||||||
struct zwlr_foreign_toplevel_handle_v1 *, struct wl_seat *);
|
struct wl_seat*);
|
||||||
~Task();
|
~Task();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -42,16 +48,17 @@ class Task {
|
|||||||
};
|
};
|
||||||
// made public so TaskBar can reorder based on configuration.
|
// made public so TaskBar can reorder based on configuration.
|
||||||
Gtk::Button button;
|
Gtk::Button button;
|
||||||
|
struct widget_geometry minimize_hint;
|
||||||
|
|
||||||
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_;
|
||||||
|
|
||||||
@@ -74,6 +81,7 @@ class Task {
|
|||||||
std::string title_;
|
std::string title_;
|
||||||
std::string app_id_;
|
std::string app_id_;
|
||||||
uint32_t state_ = 0;
|
uint32_t state_ = 0;
|
||||||
|
struct ext_workspace_handle_v1* workspace_ = nullptr;
|
||||||
|
|
||||||
int32_t drag_start_x;
|
int32_t drag_start_x;
|
||||||
int32_t drag_start_y;
|
int32_t drag_start_y;
|
||||||
@@ -82,9 +90,8 @@ class Task {
|
|||||||
private:
|
private:
|
||||||
std::string repr() const;
|
std::string repr() const;
|
||||||
std::string state_string(bool = false) const;
|
std::string state_string(bool = false) const;
|
||||||
void set_app_info_from_app_id_list(const std::string &app_id_list);
|
void set_minimize_hint();
|
||||||
bool image_load_icon(Gtk::Image &image, const Glib::RefPtr<Gtk::IconTheme> &icon_theme,
|
void on_button_size_allocated(Gtk::Allocation& alloc);
|
||||||
Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size);
|
|
||||||
void hide_if_ignored();
|
void hide_if_ignored();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -97,29 +104,32 @@ class Task {
|
|||||||
bool minimized() const { return state_ & MINIMIZED; }
|
bool minimized() const { return state_ & MINIMIZED; }
|
||||||
bool active() const { return state_ & ACTIVE; }
|
bool active() const { return state_ & ACTIVE; }
|
||||||
bool fullscreen() const { return state_ & FULLSCREEN; }
|
bool fullscreen() const { return state_ & FULLSCREEN; }
|
||||||
|
bool visible() const { return button_visible_; }
|
||||||
|
struct ext_workspace_handle_v1* workspace() const { return workspace_; }
|
||||||
|
void set_workspace(struct ext_workspace_handle_v1* workspace) { workspace_ = workspace; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Callbacks for the wlr protocol */
|
/* Callbacks for the wlr protocol */
|
||||||
void handle_title(const char *);
|
void handle_title(const char*);
|
||||||
void handle_app_id(const char *);
|
void handle_app_id(const char*);
|
||||||
void handle_output_enter(struct wl_output *);
|
void handle_output_enter(struct wl_output*);
|
||||||
void handle_output_leave(struct wl_output *);
|
void handle_output_leave(struct wl_output*);
|
||||||
void handle_state(struct wl_array *);
|
void handle_state(struct wl_array*);
|
||||||
void handle_done();
|
void handle_done();
|
||||||
void handle_closed();
|
void handle_closed();
|
||||||
|
|
||||||
/* Callbacks for Gtk events */
|
/* Callbacks for Gtk events */
|
||||||
bool handle_clicked(GdkEventButton *);
|
bool handle_clicked(GdkEventButton*);
|
||||||
bool handle_button_release(GdkEventButton *);
|
bool handle_button_release(GdkEventButton*);
|
||||||
bool handle_motion_notify(GdkEventMotion *);
|
bool handle_motion_notify(GdkEventMotion*);
|
||||||
void handle_drag_data_get(const Glib::RefPtr<Gdk::DragContext> &context,
|
void handle_drag_data_get(const Glib::RefPtr<Gdk::DragContext>& context,
|
||||||
Gtk::SelectionData &selection_data, guint info, guint time);
|
Gtk::SelectionData& selection_data, guint info, guint time);
|
||||||
void handle_drag_data_received(const Glib::RefPtr<Gdk::DragContext> &context, int x, int y,
|
void handle_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y,
|
||||||
Gtk::SelectionData selection_data, guint info, guint time);
|
Gtk::SelectionData selection_data, guint info, guint time);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool operator==(const Task &) const;
|
bool operator==(const Task&) const;
|
||||||
bool operator!=(const Task &) const;
|
bool operator!=(const Task&) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void update();
|
void update();
|
||||||
@@ -137,43 +147,65 @@ using TaskPtr = std::unique_ptr<Task>;
|
|||||||
|
|
||||||
class Taskbar : public waybar::AModule {
|
class Taskbar : public waybar::AModule {
|
||||||
public:
|
public:
|
||||||
Taskbar(const std::string &, const waybar::Bar &, const Json::Value &);
|
struct WorkspaceState {
|
||||||
|
Taskbar* taskbar;
|
||||||
|
struct ext_workspace_handle_v1* handle;
|
||||||
|
uint32_t state = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Taskbar(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
~Taskbar();
|
~Taskbar();
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const waybar::Bar &bar_;
|
const waybar::Bar& bar_;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
std::vector<TaskPtr> tasks_;
|
std::vector<TaskPtr> tasks_;
|
||||||
|
|
||||||
std::vector<Glib::RefPtr<Gtk::IconTheme>> icon_themes_;
|
IconLoader icon_loader_;
|
||||||
std::unordered_set<std::string> ignore_list_;
|
std::unordered_set<std::string> ignore_list_;
|
||||||
std::map<std::string, std::string> app_ids_replace_map_;
|
std::map<std::string, std::string> app_ids_replace_map_;
|
||||||
|
|
||||||
struct zwlr_foreign_toplevel_manager_v1 *manager_;
|
struct zwlr_foreign_toplevel_manager_v1* manager_;
|
||||||
struct wl_seat *seat_;
|
struct ext_workspace_manager_v1* workspace_manager_;
|
||||||
|
struct wl_seat* seat_;
|
||||||
|
std::vector<struct ext_workspace_group_handle_v1*> workspace_groups_;
|
||||||
|
std::vector<std::unique_ptr<WorkspaceState>> workspaces_;
|
||||||
|
struct ext_workspace_handle_v1* current_workspace_ = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Callbacks for global registration */
|
/* Callbacks for global registration */
|
||||||
void register_manager(struct wl_registry *, uint32_t name, uint32_t version);
|
void register_manager(struct wl_registry*, uint32_t name, uint32_t version);
|
||||||
void register_seat(struct wl_registry *, uint32_t name, uint32_t version);
|
void register_workspace_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 */
|
/* Callbacks for the wlr protocol */
|
||||||
void handle_toplevel_create(struct zwlr_foreign_toplevel_handle_v1 *);
|
void handle_toplevel_create(struct zwlr_foreign_toplevel_handle_v1*);
|
||||||
void handle_finished();
|
void handle_finished();
|
||||||
|
void handle_workspace_group_create(struct ext_workspace_group_handle_v1*);
|
||||||
|
void handle_workspace_group_removed(struct ext_workspace_group_handle_v1*);
|
||||||
|
void handle_workspace_create(struct ext_workspace_handle_v1*);
|
||||||
|
void handle_workspace_done();
|
||||||
|
void handle_workspace_finished();
|
||||||
|
void handle_workspace_removed(struct ext_workspace_handle_v1*);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void add_button(Gtk::Button &);
|
void add_button(Gtk::Button&);
|
||||||
void move_button(Gtk::Button &, int);
|
void move_button(Gtk::Button&, int);
|
||||||
void remove_button(Gtk::Button &);
|
void remove_button(Gtk::Button&);
|
||||||
void remove_task(uint32_t);
|
void remove_task(uint32_t);
|
||||||
|
void assign_current_workspace(Task&);
|
||||||
|
void update_bar_css_classes();
|
||||||
|
|
||||||
bool show_output(struct wl_output *) const;
|
bool show_output(struct wl_output*) const;
|
||||||
bool all_outputs() const;
|
bool all_outputs() const;
|
||||||
|
|
||||||
const std::vector<Glib::RefPtr<Gtk::IconTheme>> &icon_themes() const;
|
const IconLoader& icon_loader() const;
|
||||||
const std::unordered_set<std::string> &ignore_list() const;
|
const std::unordered_set<std::string>& ignore_list() const;
|
||||||
const std::map<std::string, std::string> &app_ids_replace_map() const;
|
const std::map<std::string, std::string>& app_ids_replace_map() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void set_bar_css_class(const std::string&, bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace waybar::modules::wlr */
|
} /* namespace waybar::modules::wlr */
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <glibmm/dispatcher.h>
|
#include <glibmm/dispatcher.h>
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@@ -22,6 +23,12 @@ struct SafeSignal : sigc::signal<void(std::decay_t<Args>...)> {
|
|||||||
public:
|
public:
|
||||||
SafeSignal() { dp_.connect(sigc::mem_fun(*this, &SafeSignal::handle_event)); }
|
SafeSignal() { dp_.connect(sigc::mem_fun(*this, &SafeSignal::handle_event)); }
|
||||||
|
|
||||||
|
void set_max_queued_events(std::size_t max_queued_events) {
|
||||||
|
std::unique_lock lock(mutex_);
|
||||||
|
max_queued_events_ = max_queued_events;
|
||||||
|
trim_queue_locked();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... EmitArgs>
|
template <typename... EmitArgs>
|
||||||
void emit(EmitArgs&&... args) {
|
void emit(EmitArgs&&... args) {
|
||||||
if (main_tid_ == std::this_thread::get_id()) {
|
if (main_tid_ == std::this_thread::get_id()) {
|
||||||
@@ -36,6 +43,9 @@ struct SafeSignal : sigc::signal<void(std::decay_t<Args>...)> {
|
|||||||
} else {
|
} else {
|
||||||
{
|
{
|
||||||
std::unique_lock lock(mutex_);
|
std::unique_lock lock(mutex_);
|
||||||
|
if (max_queued_events_ != 0 && queue_.size() >= max_queued_events_) {
|
||||||
|
queue_.pop();
|
||||||
|
}
|
||||||
queue_.emplace(std::forward<EmitArgs>(args)...);
|
queue_.emplace(std::forward<EmitArgs>(args)...);
|
||||||
}
|
}
|
||||||
dp_.emit();
|
dp_.emit();
|
||||||
@@ -55,6 +65,15 @@ struct SafeSignal : sigc::signal<void(std::decay_t<Args>...)> {
|
|||||||
using signal_t::emit_reverse;
|
using signal_t::emit_reverse;
|
||||||
using signal_t::make_slot;
|
using signal_t::make_slot;
|
||||||
|
|
||||||
|
void trim_queue_locked() {
|
||||||
|
if (max_queued_events_ == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (queue_.size() > max_queued_events_) {
|
||||||
|
queue_.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handle_event() {
|
void handle_event() {
|
||||||
for (std::unique_lock lock(mutex_); !queue_.empty(); lock.lock()) {
|
for (std::unique_lock lock(mutex_); !queue_.empty(); lock.lock()) {
|
||||||
auto args = queue_.front();
|
auto args = queue_.front();
|
||||||
@@ -67,6 +86,7 @@ struct SafeSignal : sigc::signal<void(std::decay_t<Args>...)> {
|
|||||||
Glib::Dispatcher dp_;
|
Glib::Dispatcher dp_;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
std::queue<arg_tuple_t> queue_;
|
std::queue<arg_tuple_t> queue_;
|
||||||
|
std::size_t max_queued_events_ = 4096;
|
||||||
const std::thread::id main_tid_ = std::this_thread::get_id();
|
const std::thread::id main_tid_ = std::this_thread::get_id();
|
||||||
// cache functor for signal emission to avoid recreating it on each event
|
// cache functor for signal emission to avoid recreating it on each event
|
||||||
const slot_t cached_fn_ = make_slot();
|
const slot_t cached_fn_ = make_slot();
|
||||||
|
|||||||
@@ -14,6 +14,11 @@
|
|||||||
|
|
||||||
namespace waybar::util {
|
namespace waybar::util {
|
||||||
|
|
||||||
|
enum class PulseaudioTarget {
|
||||||
|
Sink,
|
||||||
|
Source,
|
||||||
|
};
|
||||||
|
|
||||||
class AudioBackend {
|
class AudioBackend {
|
||||||
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*);
|
||||||
@@ -38,6 +43,8 @@ class AudioBackend {
|
|||||||
std::string desc_;
|
std::string desc_;
|
||||||
std::string monitor_;
|
std::string monitor_;
|
||||||
std::string current_sink_name_;
|
std::string current_sink_name_;
|
||||||
|
std::string default_sink_name;
|
||||||
|
bool default_sink_running_;
|
||||||
bool current_sink_running_;
|
bool current_sink_running_;
|
||||||
// SOURCE
|
// SOURCE
|
||||||
uint32_t source_idx_{0};
|
uint32_t source_idx_{0};
|
||||||
@@ -92,6 +99,10 @@ class AudioBackend {
|
|||||||
void toggleSourceMute();
|
void toggleSourceMute();
|
||||||
void toggleSourceMute(bool);
|
void toggleSourceMute(bool);
|
||||||
|
|
||||||
|
uint16_t getVolume(PulseaudioTarget) const;
|
||||||
|
bool getMuted(PulseaudioTarget) const;
|
||||||
|
void unmute(PulseaudioTarget);
|
||||||
|
|
||||||
bool isBluetooth();
|
bool isBluetooth();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class BacklightDevice {
|
|||||||
void set_max(int max);
|
void set_max(int max);
|
||||||
bool get_powered() const;
|
bool get_powered() const;
|
||||||
void set_powered(bool powered);
|
void set_powered(bool powered);
|
||||||
friend inline bool operator==(const BacklightDevice &lhs, const BacklightDevice &rhs) {
|
friend inline bool operator==(const BacklightDevice& lhs, const BacklightDevice& 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_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,25 +52,25 @@ class BacklightBackend {
|
|||||||
BacklightBackend(std::chrono::milliseconds interval, std::function<void()> on_updated_cb = NOOP);
|
BacklightBackend(std::chrono::milliseconds interval, std::function<void()> on_updated_cb = NOOP);
|
||||||
|
|
||||||
// const inline BacklightDevice *get_best_device(std::string_view preferred_device);
|
// const inline BacklightDevice *get_best_device(std::string_view preferred_device);
|
||||||
const BacklightDevice *get_previous_best_device();
|
const BacklightDevice* get_previous_best_device();
|
||||||
|
|
||||||
void set_previous_best_device(const BacklightDevice *device);
|
void set_previous_best_device(const BacklightDevice* device);
|
||||||
|
|
||||||
void set_brightness(const std::string &preferred_device, ChangeType change_type, double step);
|
void set_brightness(const std::string& preferred_device, ChangeType change_type, double step);
|
||||||
|
|
||||||
void set_scaled_brightness(const std::string &preferred_device, int brightness);
|
void set_scaled_brightness(const std::string& preferred_device, int brightness);
|
||||||
int get_scaled_brightness(const std::string &preferred_device);
|
int get_scaled_brightness(const std::string& preferred_device);
|
||||||
|
|
||||||
bool is_login_proxy_initialized() const { return static_cast<bool>(login_proxy_); }
|
bool is_login_proxy_initialized() const { return static_cast<bool>(login_proxy_); }
|
||||||
|
|
||||||
static const BacklightDevice *best_device(const std::vector<BacklightDevice> &devices,
|
static const BacklightDevice* best_device(const std::vector<BacklightDevice>& devices,
|
||||||
std::string_view);
|
std::string_view);
|
||||||
|
|
||||||
std::vector<BacklightDevice> devices_;
|
std::vector<BacklightDevice> devices_;
|
||||||
std::mutex udev_thread_mutex_;
|
std::mutex udev_thread_mutex_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_brightness_internal(const std::string &device_name, int brightness, int max_brightness);
|
void set_brightness_internal(const std::string& device_name, int brightness, int max_brightness);
|
||||||
|
|
||||||
std::function<void()> on_updated_cb_;
|
std::function<void()> on_updated_cb_;
|
||||||
std::chrono::milliseconds polling_interval_;
|
std::chrono::milliseconds polling_interval_;
|
||||||
|
|||||||
+128
-128
@@ -78,7 +78,7 @@ class Column {
|
|||||||
class iterator {
|
class iterator {
|
||||||
friend Column;
|
friend Column;
|
||||||
|
|
||||||
Column const &m_column;
|
Column const& m_column;
|
||||||
size_t m_stringIndex = 0;
|
size_t m_stringIndex = 0;
|
||||||
size_t m_pos = 0;
|
size_t m_pos = 0;
|
||||||
|
|
||||||
@@ -86,10 +86,10 @@ class Column {
|
|||||||
size_t m_end = 0;
|
size_t m_end = 0;
|
||||||
bool m_suffix = false;
|
bool m_suffix = false;
|
||||||
|
|
||||||
iterator(Column const &column, size_t stringIndex)
|
iterator(Column const& column, size_t stringIndex)
|
||||||
: m_column(column), m_stringIndex(stringIndex) {}
|
: m_column(column), m_stringIndex(stringIndex) {}
|
||||||
|
|
||||||
auto line() const -> std::string const & { return m_column.m_strings[m_stringIndex]; }
|
auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }
|
||||||
|
|
||||||
auto isBoundary(size_t at) const -> bool {
|
auto isBoundary(size_t at) const -> bool {
|
||||||
assert(at > 0);
|
assert(at > 0);
|
||||||
@@ -129,18 +129,18 @@ class Column {
|
|||||||
return initial == std::string::npos ? m_column.m_indent : initial;
|
return initial == std::string::npos ? m_column.m_indent : initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto addIndentAndSuffix(std::string const &plain) const -> std::string {
|
auto addIndentAndSuffix(std::string const& plain) const -> std::string {
|
||||||
return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
|
return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using value_type = std::string;
|
using value_type = std::string;
|
||||||
using pointer = value_type *;
|
using pointer = value_type*;
|
||||||
using reference = value_type &;
|
using reference = value_type&;
|
||||||
using iterator_category = std::forward_iterator_tag;
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
|
||||||
explicit iterator(Column const &column) : m_column(column) {
|
explicit iterator(Column const& column) : m_column(column) {
|
||||||
assert(m_column.m_width > m_column.m_indent);
|
assert(m_column.m_width > m_column.m_indent);
|
||||||
assert(m_column.m_initialIndent == std::string::npos ||
|
assert(m_column.m_initialIndent == std::string::npos ||
|
||||||
m_column.m_width > m_column.m_initialIndent);
|
m_column.m_width > m_column.m_initialIndent);
|
||||||
@@ -154,7 +154,7 @@ class Column {
|
|||||||
return addIndentAndSuffix(line().substr(m_pos, m_len));
|
return addIndentAndSuffix(line().substr(m_pos, m_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator++() -> iterator & {
|
auto operator++() -> iterator& {
|
||||||
m_pos += m_len;
|
m_pos += m_len;
|
||||||
if (m_pos < line().size() && line()[m_pos] == '\n')
|
if (m_pos < line().size() && line()[m_pos] == '\n')
|
||||||
m_pos += 1;
|
m_pos += 1;
|
||||||
@@ -174,26 +174,26 @@ class Column {
|
|||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator==(iterator const &other) const -> bool {
|
auto operator==(iterator const& other) const -> bool {
|
||||||
return m_pos == other.m_pos && m_stringIndex == other.m_stringIndex &&
|
return m_pos == other.m_pos && m_stringIndex == other.m_stringIndex &&
|
||||||
&m_column == &other.m_column;
|
&m_column == &other.m_column;
|
||||||
}
|
}
|
||||||
auto operator!=(iterator const &other) const -> bool { return !operator==(other); }
|
auto operator!=(iterator const& other) const -> bool { return !operator==(other); }
|
||||||
};
|
};
|
||||||
using const_iterator = iterator;
|
using const_iterator = iterator;
|
||||||
|
|
||||||
explicit Column(std::string const &text) { m_strings.push_back(text); }
|
explicit Column(std::string const& text) { m_strings.push_back(text); }
|
||||||
|
|
||||||
auto width(size_t newWidth) -> Column & {
|
auto width(size_t newWidth) -> Column& {
|
||||||
assert(newWidth > 0);
|
assert(newWidth > 0);
|
||||||
m_width = newWidth;
|
m_width = newWidth;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
auto indent(size_t newIndent) -> Column & {
|
auto indent(size_t newIndent) -> Column& {
|
||||||
m_indent = newIndent;
|
m_indent = newIndent;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
auto initialIndent(size_t newIndent) -> Column & {
|
auto initialIndent(size_t newIndent) -> Column& {
|
||||||
m_initialIndent = newIndent;
|
m_initialIndent = newIndent;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,7 @@ class Column {
|
|||||||
auto begin() const -> iterator { return iterator(*this); }
|
auto begin() const -> iterator { return iterator(*this); }
|
||||||
auto end() const -> iterator { return {*this, m_strings.size()}; }
|
auto end() const -> iterator { return {*this, m_strings.size()}; }
|
||||||
|
|
||||||
inline friend std::ostream &operator<<(std::ostream &os, Column const &col) {
|
inline friend std::ostream& operator<<(std::ostream& os, Column const& col) {
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto line : col) {
|
for (auto line : col) {
|
||||||
if (first)
|
if (first)
|
||||||
@@ -214,7 +214,7 @@ class Column {
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator+(Column const &other) -> Columns;
|
auto operator+(Column const& other) -> Columns;
|
||||||
|
|
||||||
auto toString() const -> std::string {
|
auto toString() const -> std::string {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
@@ -236,34 +236,34 @@ class Columns {
|
|||||||
friend Columns;
|
friend Columns;
|
||||||
struct EndTag {};
|
struct EndTag {};
|
||||||
|
|
||||||
std::vector<Column> const &m_columns;
|
std::vector<Column> const& m_columns;
|
||||||
std::vector<Column::iterator> m_iterators;
|
std::vector<Column::iterator> m_iterators;
|
||||||
size_t m_activeIterators;
|
size_t m_activeIterators;
|
||||||
|
|
||||||
iterator(Columns const &columns, EndTag) : m_columns(columns.m_columns), m_activeIterators(0) {
|
iterator(Columns const& columns, EndTag) : m_columns(columns.m_columns), m_activeIterators(0) {
|
||||||
m_iterators.reserve(m_columns.size());
|
m_iterators.reserve(m_columns.size());
|
||||||
|
|
||||||
for (auto const &col : m_columns) m_iterators.push_back(col.end());
|
for (auto const& col : m_columns) m_iterators.push_back(col.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using value_type = std::string;
|
using value_type = std::string;
|
||||||
using pointer = value_type *;
|
using pointer = value_type*;
|
||||||
using reference = value_type &;
|
using reference = value_type&;
|
||||||
using iterator_category = std::forward_iterator_tag;
|
using iterator_category = std::forward_iterator_tag;
|
||||||
|
|
||||||
explicit iterator(Columns const &columns)
|
explicit iterator(Columns const& columns)
|
||||||
: m_columns(columns.m_columns), m_activeIterators(m_columns.size()) {
|
: m_columns(columns.m_columns), m_activeIterators(m_columns.size()) {
|
||||||
m_iterators.reserve(m_columns.size());
|
m_iterators.reserve(m_columns.size());
|
||||||
|
|
||||||
for (auto const &col : m_columns) m_iterators.push_back(col.begin());
|
for (auto const& col : m_columns) m_iterators.push_back(col.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator==(iterator const &other) const -> bool {
|
auto operator==(iterator const& other) const -> bool {
|
||||||
return m_iterators == other.m_iterators;
|
return m_iterators == other.m_iterators;
|
||||||
}
|
}
|
||||||
auto operator!=(iterator const &other) const -> bool {
|
auto operator!=(iterator const& other) const -> bool {
|
||||||
return m_iterators != other.m_iterators;
|
return m_iterators != other.m_iterators;
|
||||||
}
|
}
|
||||||
auto operator*() const -> std::string {
|
auto operator*() const -> std::string {
|
||||||
@@ -284,7 +284,7 @@ class Columns {
|
|||||||
}
|
}
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
auto operator++() -> iterator & {
|
auto operator++() -> iterator& {
|
||||||
for (size_t i = 0; i < m_columns.size(); ++i) {
|
for (size_t i = 0; i < m_columns.size(); ++i) {
|
||||||
if (m_iterators[i] != m_columns[i].end()) ++m_iterators[i];
|
if (m_iterators[i] != m_columns[i].end()) ++m_iterators[i];
|
||||||
}
|
}
|
||||||
@@ -301,17 +301,17 @@ class Columns {
|
|||||||
auto begin() const -> iterator { return iterator(*this); }
|
auto begin() const -> iterator { return iterator(*this); }
|
||||||
auto end() const -> iterator { return {*this, iterator::EndTag()}; }
|
auto end() const -> iterator { return {*this, iterator::EndTag()}; }
|
||||||
|
|
||||||
auto operator+=(Column const &col) -> Columns & {
|
auto operator+=(Column const& col) -> Columns& {
|
||||||
m_columns.push_back(col);
|
m_columns.push_back(col);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
auto operator+(Column const &col) -> Columns {
|
auto operator+(Column const& col) -> Columns {
|
||||||
Columns combined = *this;
|
Columns combined = *this;
|
||||||
combined += col;
|
combined += col;
|
||||||
return combined;
|
return combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline friend std::ostream &operator<<(std::ostream &os, Columns const &cols) {
|
inline friend std::ostream& operator<<(std::ostream& os, Columns const& cols) {
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto line : cols) {
|
for (auto line : cols) {
|
||||||
if (first)
|
if (first)
|
||||||
@@ -330,7 +330,7 @@ class Columns {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto Column::operator+(Column const &other) -> Columns {
|
inline auto Column::operator+(Column const& other) -> Columns {
|
||||||
Columns cols;
|
Columns cols;
|
||||||
cols += *this;
|
cols += *this;
|
||||||
cols += other;
|
cols += other;
|
||||||
@@ -381,7 +381,7 @@ class Args {
|
|||||||
std::vector<std::string> m_args;
|
std::vector<std::string> m_args;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Args(int argc, char const *const *argv) : m_exeName(argv[0]), m_args(argv + 1, argv + argc) {}
|
Args(int argc, char const* const* argv) : m_exeName(argv[0]), m_args(argv + 1, argv + argc) {}
|
||||||
|
|
||||||
Args(std::initializer_list<std::string> args)
|
Args(std::initializer_list<std::string> args)
|
||||||
: m_exeName(*args.begin()), m_args(args.begin() + 1, args.end()) {}
|
: m_exeName(*args.begin()), m_args(args.begin() + 1, args.end()) {}
|
||||||
@@ -419,7 +419,7 @@ class TokenStream {
|
|||||||
while (it != itEnd && it->empty()) ++it;
|
while (it != itEnd && it->empty()) ++it;
|
||||||
|
|
||||||
if (it != itEnd) {
|
if (it != itEnd) {
|
||||||
auto const &next = *it;
|
auto const& next = *it;
|
||||||
if (isOptPrefix(next[0])) {
|
if (isOptPrefix(next[0])) {
|
||||||
auto delimiterPos = next.find_first_of(" :=");
|
auto delimiterPos = next.find_first_of(" :=");
|
||||||
if (delimiterPos != std::string::npos) {
|
if (delimiterPos != std::string::npos) {
|
||||||
@@ -443,7 +443,7 @@ class TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TokenStream(Args const &args) : TokenStream(args.m_args.begin(), args.m_args.end()) {}
|
explicit TokenStream(Args const& args) : TokenStream(args.m_args.begin(), args.m_args.end()) {}
|
||||||
|
|
||||||
TokenStream(Iterator it, Iterator itEnd) : it(it), itEnd(itEnd) { loadBuffer(); }
|
TokenStream(Iterator it, Iterator itEnd) : it(it), itEnd(itEnd) { loadBuffer(); }
|
||||||
|
|
||||||
@@ -456,12 +456,12 @@ class TokenStream {
|
|||||||
return m_tokenBuffer.front();
|
return m_tokenBuffer.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator->() const -> Token const * {
|
auto operator->() const -> Token const* {
|
||||||
assert(!m_tokenBuffer.empty());
|
assert(!m_tokenBuffer.empty());
|
||||||
return &m_tokenBuffer.front();
|
return &m_tokenBuffer.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator++() -> TokenStream & {
|
auto operator++() -> TokenStream& {
|
||||||
if (m_tokenBuffer.size() >= 2) {
|
if (m_tokenBuffer.size() >= 2) {
|
||||||
m_tokenBuffer.erase(m_tokenBuffer.begin());
|
m_tokenBuffer.erase(m_tokenBuffer.begin());
|
||||||
} else {
|
} else {
|
||||||
@@ -488,7 +488,7 @@ class ResultBase {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class ResultValueBase : public ResultBase {
|
class ResultValueBase : public ResultBase {
|
||||||
public:
|
public:
|
||||||
auto value() const -> T const & {
|
auto value() const -> T const& {
|
||||||
enforceOk();
|
enforceOk();
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
@@ -496,13 +496,13 @@ class ResultValueBase : public ResultBase {
|
|||||||
protected:
|
protected:
|
||||||
ResultValueBase(Type type) : ResultBase(type) {}
|
ResultValueBase(Type type) : ResultBase(type) {}
|
||||||
|
|
||||||
ResultValueBase(ResultValueBase const &other) : ResultBase(other) {
|
ResultValueBase(ResultValueBase const& other) : ResultBase(other) {
|
||||||
if (m_type == ResultBase::Ok) new (&m_value) T(other.m_value);
|
if (m_type == ResultBase::Ok) new (&m_value) T(other.m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultValueBase(Type, T const &value) : ResultBase(Ok) { new (&m_value) T(value); }
|
ResultValueBase(Type, T const& value) : ResultBase(Ok) { new (&m_value) T(value); }
|
||||||
|
|
||||||
auto operator=(ResultValueBase const &other) -> ResultValueBase & {
|
auto operator=(ResultValueBase const& other) -> ResultValueBase& {
|
||||||
if (m_type == ResultBase::Ok) m_value.~T();
|
if (m_type == ResultBase::Ok) m_value.~T();
|
||||||
ResultBase::operator=(other);
|
ResultBase::operator=(other);
|
||||||
if (m_type == ResultBase::Ok) new (&m_value) T(other.m_value);
|
if (m_type == ResultBase::Ok) new (&m_value) T(other.m_value);
|
||||||
@@ -528,20 +528,20 @@ template <typename T = void>
|
|||||||
class BasicResult : public ResultValueBase<T> {
|
class BasicResult : public ResultValueBase<T> {
|
||||||
public:
|
public:
|
||||||
template <typename U>
|
template <typename U>
|
||||||
explicit BasicResult(BasicResult<U> const &other)
|
explicit BasicResult(BasicResult<U> const& other)
|
||||||
: ResultValueBase<T>(other.type()), m_errorMessage(other.errorMessage()) {
|
: ResultValueBase<T>(other.type()), m_errorMessage(other.errorMessage()) {
|
||||||
assert(type() != ResultBase::Ok);
|
assert(type() != ResultBase::Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
static auto ok(U const &value) -> BasicResult {
|
static auto ok(U const& value) -> BasicResult {
|
||||||
return {ResultBase::Ok, value};
|
return {ResultBase::Ok, value};
|
||||||
}
|
}
|
||||||
static auto ok() -> BasicResult { return {ResultBase::Ok}; }
|
static auto ok() -> BasicResult { return {ResultBase::Ok}; }
|
||||||
static auto logicError(std::string const &message) -> BasicResult {
|
static auto logicError(std::string const& message) -> BasicResult {
|
||||||
return {ResultBase::LogicError, message};
|
return {ResultBase::LogicError, message};
|
||||||
}
|
}
|
||||||
static auto runtimeError(std::string const &message) -> BasicResult {
|
static auto runtimeError(std::string const& message) -> BasicResult {
|
||||||
return {ResultBase::RuntimeError, message};
|
return {ResultBase::RuntimeError, message};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,7 +560,7 @@ class BasicResult : public ResultValueBase<T> {
|
|||||||
|
|
||||||
std::string m_errorMessage; // Only populated if resultType is an error
|
std::string m_errorMessage; // Only populated if resultType is an error
|
||||||
|
|
||||||
BasicResult(ResultBase::Type type, std::string const &message)
|
BasicResult(ResultBase::Type type, std::string const& message)
|
||||||
: ResultValueBase<T>(type), m_errorMessage(message) {
|
: ResultValueBase<T>(type), m_errorMessage(message) {
|
||||||
assert(m_type != ResultBase::Ok);
|
assert(m_type != ResultBase::Ok);
|
||||||
}
|
}
|
||||||
@@ -573,7 +573,7 @@ enum class ParseResultType { Matched, NoMatch, ShortCircuitAll, ShortCircuitSame
|
|||||||
|
|
||||||
class ParseState {
|
class ParseState {
|
||||||
public:
|
public:
|
||||||
ParseState(ParseResultType type, TokenStream const &remainingTokens)
|
ParseState(ParseResultType type, TokenStream const& remainingTokens)
|
||||||
: m_type(type), m_remainingTokens(remainingTokens) {}
|
: m_type(type), m_remainingTokens(remainingTokens) {}
|
||||||
|
|
||||||
auto type() const -> ParseResultType { return m_type; }
|
auto type() const -> ParseResultType { return m_type; }
|
||||||
@@ -594,7 +594,7 @@ struct HelpColumns {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline auto convertInto(std::string const &source, T &target) -> ParserResult {
|
inline auto convertInto(std::string const& source, T& target) -> ParserResult {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << source;
|
ss << source;
|
||||||
ss >> target;
|
ss >> target;
|
||||||
@@ -603,11 +603,11 @@ inline auto convertInto(std::string const &source, T &target) -> ParserResult {
|
|||||||
else
|
else
|
||||||
return ParserResult::ok(ParseResultType::Matched);
|
return ParserResult::ok(ParseResultType::Matched);
|
||||||
}
|
}
|
||||||
inline auto convertInto(std::string const &source, std::string &target) -> ParserResult {
|
inline auto convertInto(std::string const& source, std::string& target) -> ParserResult {
|
||||||
target = source;
|
target = source;
|
||||||
return ParserResult::ok(ParseResultType::Matched);
|
return ParserResult::ok(ParseResultType::Matched);
|
||||||
}
|
}
|
||||||
inline auto convertInto(std::string const &source, bool &target) -> ParserResult {
|
inline auto convertInto(std::string const& source, bool& target) -> ParserResult {
|
||||||
std::string srcLC = source;
|
std::string srcLC = source;
|
||||||
std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(),
|
std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(),
|
||||||
[](char c) { return static_cast<char>(::tolower(c)); });
|
[](char c) { return static_cast<char>(::tolower(c)); });
|
||||||
@@ -622,7 +622,7 @@ inline auto convertInto(std::string const &source, bool &target) -> ParserResult
|
|||||||
}
|
}
|
||||||
#ifdef CLARA_CONFIG_OPTIONAL_TYPE
|
#ifdef CLARA_CONFIG_OPTIONAL_TYPE
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline auto convertInto(std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T> &target)
|
inline auto convertInto(std::string const& source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target)
|
||||||
-> ParserResult {
|
-> ParserResult {
|
||||||
T temp;
|
T temp;
|
||||||
auto result = convertInto(source, temp);
|
auto result = convertInto(source, temp);
|
||||||
@@ -633,10 +633,10 @@ inline auto convertInto(std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>
|
|||||||
|
|
||||||
struct NonCopyable {
|
struct NonCopyable {
|
||||||
NonCopyable() = default;
|
NonCopyable() = default;
|
||||||
NonCopyable(NonCopyable const &) = delete;
|
NonCopyable(NonCopyable const&) = delete;
|
||||||
NonCopyable(NonCopyable &&) = delete;
|
NonCopyable(NonCopyable&&) = delete;
|
||||||
NonCopyable &operator=(NonCopyable const &) = delete;
|
NonCopyable& operator=(NonCopyable const&) = delete;
|
||||||
NonCopyable &operator=(NonCopyable &&) = delete;
|
NonCopyable& operator=(NonCopyable&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BoundRef : NonCopyable {
|
struct BoundRef : NonCopyable {
|
||||||
@@ -645,7 +645,7 @@ struct BoundRef : NonCopyable {
|
|||||||
virtual auto isFlag() const -> bool { return false; }
|
virtual auto isFlag() const -> bool { return false; }
|
||||||
};
|
};
|
||||||
struct BoundValueRefBase : BoundRef {
|
struct BoundValueRefBase : BoundRef {
|
||||||
virtual auto setValue(std::string const &arg) -> ParserResult = 0;
|
virtual auto setValue(std::string const& arg) -> ParserResult = 0;
|
||||||
};
|
};
|
||||||
struct BoundFlagRefBase : BoundRef {
|
struct BoundFlagRefBase : BoundRef {
|
||||||
virtual auto setFlag(bool flag) -> ParserResult = 0;
|
virtual auto setFlag(bool flag) -> ParserResult = 0;
|
||||||
@@ -654,22 +654,22 @@ struct BoundFlagRefBase : BoundRef {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct BoundValueRef : BoundValueRefBase {
|
struct BoundValueRef : BoundValueRefBase {
|
||||||
T &m_ref;
|
T& m_ref;
|
||||||
|
|
||||||
explicit BoundValueRef(T &ref) : m_ref(ref) {}
|
explicit BoundValueRef(T& ref) : m_ref(ref) {}
|
||||||
|
|
||||||
auto setValue(std::string const &arg) -> ParserResult override { return convertInto(arg, m_ref); }
|
auto setValue(std::string const& arg) -> ParserResult override { return convertInto(arg, m_ref); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
|
struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
|
||||||
std::vector<T> &m_ref;
|
std::vector<T>& m_ref;
|
||||||
|
|
||||||
explicit BoundValueRef(std::vector<T> &ref) : m_ref(ref) {}
|
explicit BoundValueRef(std::vector<T>& ref) : m_ref(ref) {}
|
||||||
|
|
||||||
auto isContainer() const -> bool override { return true; }
|
auto isContainer() const -> bool override { return true; }
|
||||||
|
|
||||||
auto setValue(std::string const &arg) -> ParserResult override {
|
auto setValue(std::string const& arg) -> ParserResult override {
|
||||||
T temp;
|
T temp;
|
||||||
auto result = convertInto(arg, temp);
|
auto result = convertInto(arg, temp);
|
||||||
if (result) m_ref.push_back(temp);
|
if (result) m_ref.push_back(temp);
|
||||||
@@ -678,9 +678,9 @@ struct BoundValueRef<std::vector<T>> : BoundValueRefBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BoundFlagRef : BoundFlagRefBase {
|
struct BoundFlagRef : BoundFlagRefBase {
|
||||||
bool &m_ref;
|
bool& m_ref;
|
||||||
|
|
||||||
explicit BoundFlagRef(bool &ref) : m_ref(ref) {}
|
explicit BoundFlagRef(bool& ref) : m_ref(ref) {}
|
||||||
|
|
||||||
auto setFlag(bool flag) -> ParserResult override {
|
auto setFlag(bool flag) -> ParserResult override {
|
||||||
m_ref = flag;
|
m_ref = flag;
|
||||||
@@ -694,7 +694,7 @@ struct LambdaInvoker {
|
|||||||
"Lambda must return void or clara::ParserResult");
|
"Lambda must return void or clara::ParserResult");
|
||||||
|
|
||||||
template <typename L, typename ArgType>
|
template <typename L, typename ArgType>
|
||||||
static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
|
static auto invoke(L const& lambda, ArgType const& arg) -> ParserResult {
|
||||||
return lambda(arg);
|
return lambda(arg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -702,14 +702,14 @@ struct LambdaInvoker {
|
|||||||
template <>
|
template <>
|
||||||
struct LambdaInvoker<void> {
|
struct LambdaInvoker<void> {
|
||||||
template <typename L, typename ArgType>
|
template <typename L, typename ArgType>
|
||||||
static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult {
|
static auto invoke(L const& lambda, ArgType const& arg) -> ParserResult {
|
||||||
lambda(arg);
|
lambda(arg);
|
||||||
return ParserResult::ok(ParseResultType::Matched);
|
return ParserResult::ok(ParseResultType::Matched);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ArgType, typename L>
|
template <typename ArgType, typename L>
|
||||||
inline auto invokeLambda(L const &lambda, std::string const &arg) -> ParserResult {
|
inline auto invokeLambda(L const& lambda, std::string const& arg) -> ParserResult {
|
||||||
ArgType temp{};
|
ArgType temp{};
|
||||||
auto result = convertInto(arg, temp);
|
auto result = convertInto(arg, temp);
|
||||||
return !result ? result
|
return !result ? result
|
||||||
@@ -721,9 +721,9 @@ struct BoundLambda : BoundValueRefBase {
|
|||||||
L m_lambda;
|
L m_lambda;
|
||||||
|
|
||||||
static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
|
static_assert(UnaryLambdaTraits<L>::isValid, "Supplied lambda must take exactly one argument");
|
||||||
explicit BoundLambda(L const &lambda) : m_lambda(lambda) {}
|
explicit BoundLambda(L const& lambda) : m_lambda(lambda) {}
|
||||||
|
|
||||||
auto setValue(std::string const &arg) -> ParserResult override {
|
auto setValue(std::string const& arg) -> ParserResult override {
|
||||||
return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(m_lambda, arg);
|
return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>(m_lambda, arg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -736,7 +736,7 @@ struct BoundFlagLambda : BoundFlagRefBase {
|
|||||||
static_assert(std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value,
|
static_assert(std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value,
|
||||||
"flags must be boolean");
|
"flags must be boolean");
|
||||||
|
|
||||||
explicit BoundFlagLambda(L const &lambda) : m_lambda(lambda) {}
|
explicit BoundFlagLambda(L const& lambda) : m_lambda(lambda) {}
|
||||||
|
|
||||||
auto setFlag(bool flag) -> ParserResult override {
|
auto setFlag(bool flag) -> ParserResult override {
|
||||||
return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(m_lambda, flag);
|
return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke(m_lambda, flag);
|
||||||
@@ -751,11 +751,11 @@ class ParserBase {
|
|||||||
public:
|
public:
|
||||||
virtual ~ParserBase() = default;
|
virtual ~ParserBase() = default;
|
||||||
virtual auto validate() const -> Result { return Result::ok(); }
|
virtual auto validate() const -> Result { return Result::ok(); }
|
||||||
virtual auto parse(std::string const &exeName, TokenStream const &tokens) const
|
virtual auto parse(std::string const& exeName, TokenStream const& tokens) const
|
||||||
-> InternalParseResult = 0;
|
-> InternalParseResult = 0;
|
||||||
virtual auto cardinality() const -> size_t { return 1; }
|
virtual auto cardinality() const -> size_t { return 1; }
|
||||||
|
|
||||||
auto parse(Args const &args) const -> InternalParseResult {
|
auto parse(Args const& args) const -> InternalParseResult {
|
||||||
return parse(args.exeName(), TokenStream(args));
|
return parse(args.exeName(), TokenStream(args));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -764,10 +764,10 @@ template <typename DerivedT>
|
|||||||
class ComposableParserImpl : public ParserBase {
|
class ComposableParserImpl : public ParserBase {
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto operator|(T const &other) const -> Parser;
|
auto operator|(T const& other) const -> Parser;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto operator+(T const &other) const -> Parser;
|
auto operator+(T const& other) const -> Parser;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Common code and state for Args and Opts
|
// Common code and state for Args and Opts
|
||||||
@@ -779,30 +779,30 @@ class ParserRefImpl : public ComposableParserImpl<DerivedT> {
|
|||||||
std::string m_hint;
|
std::string m_hint;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
|
|
||||||
explicit ParserRefImpl(std::shared_ptr<BoundRef> const &ref) : m_ref(ref) {}
|
explicit ParserRefImpl(std::shared_ptr<BoundRef> const& ref) : m_ref(ref) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
ParserRefImpl(T &ref, std::string const &hint)
|
ParserRefImpl(T& ref, std::string const& hint)
|
||||||
: m_ref(std::make_shared<BoundValueRef<T>>(ref)), m_hint(hint) {}
|
: m_ref(std::make_shared<BoundValueRef<T>>(ref)), m_hint(hint) {}
|
||||||
|
|
||||||
template <typename LambdaT>
|
template <typename LambdaT>
|
||||||
ParserRefImpl(LambdaT const &ref, std::string const &hint)
|
ParserRefImpl(LambdaT const& ref, std::string const& hint)
|
||||||
: m_ref(std::make_shared<BoundLambda<LambdaT>>(ref)), m_hint(hint) {}
|
: m_ref(std::make_shared<BoundLambda<LambdaT>>(ref)), m_hint(hint) {}
|
||||||
|
|
||||||
auto operator()(std::string const &description) -> DerivedT & {
|
auto operator()(std::string const& description) -> DerivedT& {
|
||||||
m_description = description;
|
m_description = description;
|
||||||
return static_cast<DerivedT &>(*this);
|
return static_cast<DerivedT&>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto optional() -> DerivedT & {
|
auto optional() -> DerivedT& {
|
||||||
m_optionality = Optionality::Optional;
|
m_optionality = Optionality::Optional;
|
||||||
return static_cast<DerivedT &>(*this);
|
return static_cast<DerivedT&>(*this);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto required() -> DerivedT & {
|
auto required() -> DerivedT& {
|
||||||
m_optionality = Optionality::Required;
|
m_optionality = Optionality::Required;
|
||||||
return static_cast<DerivedT &>(*this);
|
return static_cast<DerivedT&>(*this);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto isOptional() const -> bool { return m_optionality == Optionality::Optional; }
|
auto isOptional() const -> bool { return m_optionality == Optionality::Optional; }
|
||||||
@@ -822,29 +822,29 @@ class ExeName : public ComposableParserImpl<ExeName> {
|
|||||||
std::shared_ptr<BoundValueRefBase> m_ref;
|
std::shared_ptr<BoundValueRefBase> m_ref;
|
||||||
|
|
||||||
template <typename LambdaT>
|
template <typename LambdaT>
|
||||||
static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {
|
static auto makeRef(LambdaT const& lambda) -> std::shared_ptr<BoundValueRefBase> {
|
||||||
return std::make_shared<BoundLambda<LambdaT>>(lambda);
|
return std::make_shared<BoundLambda<LambdaT>>(lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExeName() : m_name(std::make_shared<std::string>("<executable>")) {}
|
ExeName() : m_name(std::make_shared<std::string>("<executable>")) {}
|
||||||
|
|
||||||
explicit ExeName(std::string &ref) : ExeName() {
|
explicit ExeName(std::string& ref) : ExeName() {
|
||||||
m_ref = std::make_shared<BoundValueRef<std::string>>(ref);
|
m_ref = std::make_shared<BoundValueRef<std::string>>(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename LambdaT>
|
template <typename LambdaT>
|
||||||
explicit ExeName(LambdaT const &lambda) : ExeName() {
|
explicit ExeName(LambdaT const& lambda) : ExeName() {
|
||||||
m_ref = std::make_shared<BoundLambda<LambdaT>>(lambda);
|
m_ref = std::make_shared<BoundLambda<LambdaT>>(lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The exe name is not parsed out of the normal tokens, but is handled specially
|
// The exe name is not parsed out of the normal tokens, but is handled specially
|
||||||
auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
|
auto parse(std::string const&, TokenStream const& tokens) const -> InternalParseResult override {
|
||||||
return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
|
return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name() const -> std::string { return *m_name; }
|
auto name() const -> std::string { return *m_name; }
|
||||||
auto set(std::string const &newName) -> ParserResult {
|
auto set(std::string const& newName) -> ParserResult {
|
||||||
auto lastSlash = newName.find_last_of("\\/");
|
auto lastSlash = newName.find_last_of("\\/");
|
||||||
auto filename = (lastSlash == std::string::npos) ? newName : newName.substr(lastSlash + 1);
|
auto filename = (lastSlash == std::string::npos) ? newName : newName.substr(lastSlash + 1);
|
||||||
|
|
||||||
@@ -860,17 +860,17 @@ class Arg : public ParserRefImpl<Arg> {
|
|||||||
public:
|
public:
|
||||||
using ParserRefImpl::ParserRefImpl;
|
using ParserRefImpl::ParserRefImpl;
|
||||||
|
|
||||||
auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
|
auto parse(std::string const&, TokenStream const& tokens) const -> InternalParseResult override {
|
||||||
auto validationResult = validate();
|
auto validationResult = validate();
|
||||||
if (!validationResult) return InternalParseResult(validationResult);
|
if (!validationResult) return InternalParseResult(validationResult);
|
||||||
|
|
||||||
auto remainingTokens = tokens;
|
auto remainingTokens = tokens;
|
||||||
auto const &token = *remainingTokens;
|
auto const& token = *remainingTokens;
|
||||||
if (token.type != TokenType::Argument)
|
if (token.type != TokenType::Argument)
|
||||||
return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
|
return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens));
|
||||||
|
|
||||||
assert(!m_ref->isFlag());
|
assert(!m_ref->isFlag());
|
||||||
auto valueRef = static_cast<detail::BoundValueRefBase *>(m_ref.get());
|
auto valueRef = static_cast<detail::BoundValueRefBase*>(m_ref.get());
|
||||||
|
|
||||||
auto result = valueRef->setValue(remainingTokens->token);
|
auto result = valueRef->setValue(remainingTokens->token);
|
||||||
if (!result)
|
if (!result)
|
||||||
@@ -880,7 +880,7 @@ class Arg : public ParserRefImpl<Arg> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto normaliseOpt(std::string const &optName) -> std::string {
|
inline auto normaliseOpt(std::string const& optName) -> std::string {
|
||||||
#ifdef CLARA_PLATFORM_WINDOWS
|
#ifdef CLARA_PLATFORM_WINDOWS
|
||||||
if (optName[0] == '/')
|
if (optName[0] == '/')
|
||||||
return "-" + optName.substr(1);
|
return "-" + optName.substr(1);
|
||||||
@@ -895,18 +895,18 @@ class Opt : public ParserRefImpl<Opt> {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename LambdaT>
|
template <typename LambdaT>
|
||||||
explicit Opt(LambdaT const &ref)
|
explicit Opt(LambdaT const& ref)
|
||||||
: ParserRefImpl(std::make_shared<BoundFlagLambda<LambdaT>>(ref)) {}
|
: ParserRefImpl(std::make_shared<BoundFlagLambda<LambdaT>>(ref)) {}
|
||||||
|
|
||||||
explicit Opt(bool &ref) : ParserRefImpl(std::make_shared<BoundFlagRef>(ref)) {}
|
explicit Opt(bool& ref) : ParserRefImpl(std::make_shared<BoundFlagRef>(ref)) {}
|
||||||
|
|
||||||
template <typename LambdaT>
|
template <typename LambdaT>
|
||||||
Opt(LambdaT const &ref, std::string const &hint) : ParserRefImpl(ref, hint) {}
|
Opt(LambdaT const& ref, std::string const& hint) : ParserRefImpl(ref, hint) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Opt(T &ref, std::string const &hint) : ParserRefImpl(ref, hint) {}
|
Opt(T& ref, std::string const& hint) : ParserRefImpl(ref, hint) {}
|
||||||
|
|
||||||
auto operator[](std::string const &optName) -> Opt & {
|
auto operator[](std::string const& optName) -> Opt& {
|
||||||
m_optNames.push_back(optName);
|
m_optNames.push_back(optName);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -914,7 +914,7 @@ class Opt : public ParserRefImpl<Opt> {
|
|||||||
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto const &opt : m_optNames) {
|
for (auto const& opt : m_optNames) {
|
||||||
if (first)
|
if (first)
|
||||||
first = false;
|
first = false;
|
||||||
else
|
else
|
||||||
@@ -925,9 +925,9 @@ class Opt : public ParserRefImpl<Opt> {
|
|||||||
return {{oss.str(), m_description}};
|
return {{oss.str(), m_description}};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto isMatch(std::string const &optToken) const -> bool {
|
auto isMatch(std::string const& optToken) const -> bool {
|
||||||
auto normalisedToken = normaliseOpt(optToken);
|
auto normalisedToken = normaliseOpt(optToken);
|
||||||
for (auto const &name : m_optNames) {
|
for (auto const& name : m_optNames) {
|
||||||
if (normaliseOpt(name) == normalisedToken) return true;
|
if (normaliseOpt(name) == normalisedToken) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -935,26 +935,26 @@ class Opt : public ParserRefImpl<Opt> {
|
|||||||
|
|
||||||
using ParserBase::parse;
|
using ParserBase::parse;
|
||||||
|
|
||||||
auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override {
|
auto parse(std::string const&, TokenStream const& tokens) const -> InternalParseResult override {
|
||||||
auto validationResult = validate();
|
auto validationResult = validate();
|
||||||
if (!validationResult) return InternalParseResult(validationResult);
|
if (!validationResult) return InternalParseResult(validationResult);
|
||||||
|
|
||||||
auto remainingTokens = tokens;
|
auto remainingTokens = tokens;
|
||||||
if (remainingTokens && remainingTokens->type == TokenType::Option) {
|
if (remainingTokens && remainingTokens->type == TokenType::Option) {
|
||||||
auto const &token = *remainingTokens;
|
auto const& token = *remainingTokens;
|
||||||
if (isMatch(token.token)) {
|
if (isMatch(token.token)) {
|
||||||
if (m_ref->isFlag()) {
|
if (m_ref->isFlag()) {
|
||||||
auto flagRef = static_cast<detail::BoundFlagRefBase *>(m_ref.get());
|
auto flagRef = static_cast<detail::BoundFlagRefBase*>(m_ref.get());
|
||||||
auto result = flagRef->setFlag(true);
|
auto result = flagRef->setFlag(true);
|
||||||
if (!result) return InternalParseResult(result);
|
if (!result) return InternalParseResult(result);
|
||||||
if (result.value() == ParseResultType::ShortCircuitAll)
|
if (result.value() == ParseResultType::ShortCircuitAll)
|
||||||
return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
|
return InternalParseResult::ok(ParseState(result.value(), remainingTokens));
|
||||||
} else {
|
} else {
|
||||||
auto valueRef = static_cast<detail::BoundValueRefBase *>(m_ref.get());
|
auto valueRef = static_cast<detail::BoundValueRefBase*>(m_ref.get());
|
||||||
++remainingTokens;
|
++remainingTokens;
|
||||||
if (!remainingTokens)
|
if (!remainingTokens)
|
||||||
return InternalParseResult::runtimeError("Expected argument following " + token.token);
|
return InternalParseResult::runtimeError("Expected argument following " + token.token);
|
||||||
auto const &argToken = *remainingTokens;
|
auto const& argToken = *remainingTokens;
|
||||||
if (argToken.type != TokenType::Argument)
|
if (argToken.type != TokenType::Argument)
|
||||||
return InternalParseResult::runtimeError("Expected argument following " + token.token);
|
return InternalParseResult::runtimeError("Expected argument following " + token.token);
|
||||||
auto result = valueRef->setValue(argToken.token);
|
auto result = valueRef->setValue(argToken.token);
|
||||||
@@ -970,7 +970,7 @@ class Opt : public ParserRefImpl<Opt> {
|
|||||||
|
|
||||||
auto validate() const -> Result override {
|
auto validate() const -> Result override {
|
||||||
if (m_optNames.empty()) return Result::logicError("No options supplied to Opt");
|
if (m_optNames.empty()) return Result::logicError("No options supplied to Opt");
|
||||||
for (auto const &name : m_optNames) {
|
for (auto const& name : m_optNames) {
|
||||||
if (name.empty()) return Result::logicError("Option name cannot be empty");
|
if (name.empty()) return Result::logicError("Option name cannot be empty");
|
||||||
#ifdef CLARA_PLATFORM_WINDOWS
|
#ifdef CLARA_PLATFORM_WINDOWS
|
||||||
if (name[0] != '-' && name[0] != '/')
|
if (name[0] != '-' && name[0] != '/')
|
||||||
@@ -984,12 +984,12 @@ class Opt : public ParserRefImpl<Opt> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Help : Opt {
|
struct Help : Opt {
|
||||||
Help(bool &showHelpFlag)
|
Help(bool& showHelpFlag)
|
||||||
: Opt([&](bool flag) {
|
: Opt([&](bool flag) {
|
||||||
showHelpFlag = flag;
|
showHelpFlag = flag;
|
||||||
return ParserResult::ok(ParseResultType::ShortCircuitAll);
|
return ParserResult::ok(ParseResultType::ShortCircuitAll);
|
||||||
}) {
|
}) {
|
||||||
static_cast<Opt &>(*this)("display usage information")["-?"]["-h"]["--help"].optional();
|
static_cast<Opt&>(*this)("display usage information")["-?"]["-h"]["--help"].optional();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -998,57 +998,57 @@ struct Parser : ParserBase {
|
|||||||
std::vector<Opt> m_options;
|
std::vector<Opt> m_options;
|
||||||
std::vector<Arg> m_args;
|
std::vector<Arg> m_args;
|
||||||
|
|
||||||
auto operator|=(ExeName const &exeName) -> Parser & {
|
auto operator|=(ExeName const& exeName) -> Parser& {
|
||||||
m_exeName = exeName;
|
m_exeName = exeName;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator|=(Arg const &arg) -> Parser & {
|
auto operator|=(Arg const& arg) -> Parser& {
|
||||||
m_args.push_back(arg);
|
m_args.push_back(arg);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator|=(Opt const &opt) -> Parser & {
|
auto operator|=(Opt const& opt) -> Parser& {
|
||||||
m_options.push_back(opt);
|
m_options.push_back(opt);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator|=(Parser const &other) -> Parser & {
|
auto operator|=(Parser const& other) -> Parser& {
|
||||||
m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
|
m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());
|
||||||
m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
|
m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto operator|(T const &other) const -> Parser {
|
auto operator|(T const& other) const -> Parser {
|
||||||
return Parser(*this) |= other;
|
return Parser(*this) |= other;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward deprecated interface with '+' instead of '|'
|
// Forward deprecated interface with '+' instead of '|'
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto operator+=(T const &other) -> Parser & {
|
auto operator+=(T const& other) -> Parser& {
|
||||||
return operator|=(other);
|
return operator|=(other);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto operator+(T const &other) const -> Parser {
|
auto operator+(T const& other) const -> Parser {
|
||||||
return operator|(other);
|
return operator|(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
auto getHelpColumns() const -> std::vector<HelpColumns> {
|
||||||
std::vector<HelpColumns> cols;
|
std::vector<HelpColumns> cols;
|
||||||
for (auto const &o : m_options) {
|
for (auto const& o : m_options) {
|
||||||
auto childCols = o.getHelpColumns();
|
auto childCols = o.getHelpColumns();
|
||||||
cols.insert(cols.end(), childCols.begin(), childCols.end());
|
cols.insert(cols.end(), childCols.begin(), childCols.end());
|
||||||
}
|
}
|
||||||
return cols;
|
return cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeToStream(std::ostream &os) const {
|
void writeToStream(std::ostream& os) const {
|
||||||
if (!m_exeName.name().empty()) {
|
if (!m_exeName.name().empty()) {
|
||||||
os << "usage:\n"
|
os << "usage:\n"
|
||||||
<< " " << m_exeName.name() << " ";
|
<< " " << m_exeName.name() << " ";
|
||||||
bool required = true, first = true;
|
bool required = true, first = true;
|
||||||
for (auto const &arg : m_args) {
|
for (auto const& arg : m_args) {
|
||||||
if (first)
|
if (first)
|
||||||
first = false;
|
first = false;
|
||||||
else
|
else
|
||||||
@@ -1068,28 +1068,28 @@ struct Parser : ParserBase {
|
|||||||
auto rows = getHelpColumns();
|
auto rows = getHelpColumns();
|
||||||
size_t consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
|
size_t consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
|
||||||
size_t optWidth = 0;
|
size_t optWidth = 0;
|
||||||
for (auto const &cols : rows) optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
for (auto const& cols : rows) optWidth = (std::max)(optWidth, cols.left.size() + 2);
|
||||||
|
|
||||||
optWidth = (std::min)(optWidth, consoleWidth / 2);
|
optWidth = (std::min)(optWidth, consoleWidth / 2);
|
||||||
|
|
||||||
for (auto const &cols : rows) {
|
for (auto const& cols : rows) {
|
||||||
auto row = TextFlow::Column(cols.left).width(optWidth).indent(2) + TextFlow::Spacer(4) +
|
auto row = TextFlow::Column(cols.left).width(optWidth).indent(2) + TextFlow::Spacer(4) +
|
||||||
TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth);
|
TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth);
|
||||||
os << row << std::endl;
|
os << row << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
friend auto operator<<(std::ostream &os, Parser const &parser) -> std::ostream & {
|
friend auto operator<<(std::ostream& os, Parser const& parser) -> std::ostream& {
|
||||||
parser.writeToStream(os);
|
parser.writeToStream(os);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto validate() const -> Result override {
|
auto validate() const -> Result override {
|
||||||
for (auto const &opt : m_options) {
|
for (auto const& opt : m_options) {
|
||||||
auto result = opt.validate();
|
auto result = opt.validate();
|
||||||
if (!result) return result;
|
if (!result) return result;
|
||||||
}
|
}
|
||||||
for (auto const &arg : m_args) {
|
for (auto const& arg : m_args) {
|
||||||
auto result = arg.validate();
|
auto result = arg.validate();
|
||||||
if (!result) return result;
|
if (!result) return result;
|
||||||
}
|
}
|
||||||
@@ -1098,10 +1098,10 @@ struct Parser : ParserBase {
|
|||||||
|
|
||||||
using ParserBase::parse;
|
using ParserBase::parse;
|
||||||
|
|
||||||
auto parse(std::string const &exeName, TokenStream const &tokens) const
|
auto parse(std::string const& exeName, TokenStream const& tokens) const
|
||||||
-> InternalParseResult override {
|
-> InternalParseResult override {
|
||||||
struct ParserInfo {
|
struct ParserInfo {
|
||||||
ParserBase const *parser = nullptr;
|
ParserBase const* parser = nullptr;
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
};
|
};
|
||||||
const size_t totalParsers = m_options.size() + m_args.size();
|
const size_t totalParsers = m_options.size() + m_args.size();
|
||||||
@@ -1111,8 +1111,8 @@ struct Parser : ParserBase {
|
|||||||
|
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
|
for (auto const& opt : m_options) parseInfos[i++].parser = &opt;
|
||||||
for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
|
for (auto const& arg : m_args) parseInfos[i++].parser = &arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_exeName.set(exeName);
|
m_exeName.set(exeName);
|
||||||
@@ -1122,7 +1122,7 @@ struct Parser : ParserBase {
|
|||||||
bool tokenParsed = false;
|
bool tokenParsed = false;
|
||||||
|
|
||||||
for (size_t i = 0; i < totalParsers; ++i) {
|
for (size_t i = 0; i < totalParsers; ++i) {
|
||||||
auto &parseInfo = parseInfos[i];
|
auto& parseInfo = parseInfos[i];
|
||||||
if (parseInfo.parser->cardinality() == 0 ||
|
if (parseInfo.parser->cardinality() == 0 ||
|
||||||
parseInfo.count < parseInfo.parser->cardinality()) {
|
parseInfo.count < parseInfo.parser->cardinality()) {
|
||||||
result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
|
result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
|
||||||
@@ -1147,8 +1147,8 @@ struct Parser : ParserBase {
|
|||||||
|
|
||||||
template <typename DerivedT>
|
template <typename DerivedT>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto ComposableParserImpl<DerivedT>::operator|(T const &other) const -> Parser {
|
auto ComposableParserImpl<DerivedT>::operator|(T const& other) const -> Parser {
|
||||||
return Parser() | static_cast<DerivedT const &>(*this) | other;
|
return Parser() | static_cast<DerivedT const&>(*this) | other;
|
||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ extern std::list<pid_t> reap;
|
|||||||
|
|
||||||
namespace waybar::util::command {
|
namespace waybar::util::command {
|
||||||
|
|
||||||
|
constexpr int kExecFailureExitCode = 127;
|
||||||
|
|
||||||
struct res {
|
struct res {
|
||||||
int exit_code;
|
int exit_code;
|
||||||
std::string out;
|
std::string out;
|
||||||
@@ -59,6 +61,7 @@ inline int close(FILE* fp, pid_t pid) {
|
|||||||
spdlog::debug("Cmd continued");
|
spdlog::debug("Cmd continued");
|
||||||
} else if (ret == -1) {
|
} else if (ret == -1) {
|
||||||
spdlog::debug("waitpid failed: {}", strerror(errno));
|
spdlog::debug("waitpid failed: {}", strerror(errno));
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -109,11 +112,13 @@ inline FILE* open(const std::string& cmd, int& pid, const std::string& output_na
|
|||||||
::close(fd[0]);
|
::close(fd[0]);
|
||||||
dup2(fd[1], 1);
|
dup2(fd[1], 1);
|
||||||
setpgid(child_pid, child_pid);
|
setpgid(child_pid, child_pid);
|
||||||
if (output_name != "") {
|
if (!output_name.empty()) {
|
||||||
setenv("WAYBAR_OUTPUT_NAME", output_name.c_str(), 1);
|
setenv("WAYBAR_OUTPUT_NAME", output_name.c_str(), 1);
|
||||||
}
|
}
|
||||||
execlp("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
|
execlp("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
|
||||||
exit(0);
|
const int saved_errno = errno;
|
||||||
|
spdlog::error("execlp(/bin/sh) failed in open: {}", strerror(saved_errno));
|
||||||
|
_exit(kExecFailureExitCode);
|
||||||
} else {
|
} else {
|
||||||
::close(fd[1]);
|
::close(fd[1]);
|
||||||
}
|
}
|
||||||
@@ -138,7 +143,7 @@ inline struct res execNoRead(const std::string& cmd) {
|
|||||||
return {WEXITSTATUS(stat), ""};
|
return {WEXITSTATUS(stat), ""};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int32_t forkExec(const std::string& cmd) {
|
inline int32_t forkExec(const std::string& cmd, const std::string& output_name) {
|
||||||
if (cmd == "") return -1;
|
if (cmd == "") return -1;
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
@@ -157,8 +162,13 @@ inline int32_t forkExec(const std::string& cmd) {
|
|||||||
err = pthread_sigmask(SIG_UNBLOCK, &mask, nullptr);
|
err = pthread_sigmask(SIG_UNBLOCK, &mask, nullptr);
|
||||||
if (err != 0) spdlog::error("pthread_sigmask in forkExec failed: {}", strerror(err));
|
if (err != 0) spdlog::error("pthread_sigmask in forkExec failed: {}", strerror(err));
|
||||||
setpgid(pid, pid);
|
setpgid(pid, pid);
|
||||||
|
if (!output_name.empty()) {
|
||||||
|
setenv("WAYBAR_OUTPUT_NAME", output_name.c_str(), 1);
|
||||||
|
}
|
||||||
execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
|
execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
|
||||||
exit(0);
|
const int saved_errno = errno;
|
||||||
|
spdlog::error("execl(/bin/sh) failed in forkExec: {}", strerror(saved_errno));
|
||||||
|
_exit(kExecFailureExitCode);
|
||||||
} else {
|
} else {
|
||||||
reap_mtx.lock();
|
reap_mtx.lock();
|
||||||
reap.push_back(pid);
|
reap.push_back(pid);
|
||||||
@@ -169,4 +179,6 @@ inline int32_t forkExec(const std::string& cmd) {
|
|||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int32_t forkExec(const std::string& cmd) { return forkExec(cmd, ""); }
|
||||||
|
|
||||||
} // namespace waybar::util::command
|
} // namespace waybar::util::command
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ struct pollfd;
|
|||||||
namespace waybar {
|
namespace waybar {
|
||||||
class CssReloadHelper {
|
class CssReloadHelper {
|
||||||
public:
|
public:
|
||||||
CssReloadHelper(std::string cssFile, std::function<void()> callback);
|
CssReloadHelper(std::string cssFile, std::function<void(const std::string&)> callback);
|
||||||
|
|
||||||
virtual ~CssReloadHelper() = default;
|
virtual ~CssReloadHelper() = default;
|
||||||
|
|
||||||
virtual void monitorChanges();
|
virtual void monitorChanges();
|
||||||
|
|
||||||
|
virtual void changeCssFile(const std::string& newCssFile);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<std::string> parseImports(const std::string& cssFile);
|
std::vector<std::string> parseImports(const std::string& cssFile);
|
||||||
|
|
||||||
@@ -42,7 +44,7 @@ class CssReloadHelper {
|
|||||||
private:
|
private:
|
||||||
std::string m_cssFile;
|
std::string m_cssFile;
|
||||||
|
|
||||||
std::function<void()> m_callback;
|
std::function<void(const std::string&)> m_callback;
|
||||||
|
|
||||||
std::vector<std::tuple<Glib::RefPtr<Gio::FileMonitor>>> m_fileMonitors;
|
std::vector<std::tuple<Glib::RefPtr<Gio::FileMonitor>>> m_fileMonitors;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
namespace date {
|
namespace date {
|
||||||
#if HAVE_CHRONO_TIMEZONES
|
#if HAVE_CHRONO_TIMEZONES
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
using namespace std;
|
using std::format;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
using system_clock = std::chrono::system_clock;
|
using system_clock = std::chrono::system_clock;
|
||||||
@@ -73,5 +73,3 @@ struct fmt::formatter<date::zoned_time<Duration, TimeZonePtr>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace date;
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
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_;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user