Compare commits
248 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d56dd6ee7f | ||
|
|
1142979581 | ||
|
|
8a89706d03 | ||
|
|
a4d31ab10d | ||
|
|
34bfefcd2e | ||
|
|
fef0bb995c | ||
|
|
46e7ed35de | ||
|
|
d623a89cd1 | ||
|
|
1210bcd2b5 | ||
|
|
30f6ed05ec | ||
|
|
3ade275d10 | ||
|
|
4354da2849 | ||
|
|
6417782af6 | ||
|
|
64d99a5884 | ||
|
|
627e4a4a50 | ||
|
|
c2f1a7894b | ||
|
|
6560e32bc1 | ||
|
|
70f3c1d9e9 | ||
|
|
7a6960842a | ||
|
|
9b5c2dc7ed | ||
|
|
0ee519753c | ||
|
|
5d184f74d8 | ||
|
|
4d89c64bed | ||
|
|
f665d1da52 | ||
|
|
26329b660a | ||
|
|
0fb1957dae | ||
|
|
c5a4266329 | ||
|
|
fd478bf2ab | ||
|
|
1f23b30b56 | ||
|
|
21906f07b3 | ||
|
|
c468119f52 | ||
|
|
79d3a1a296 | ||
|
|
4ae144a724 | ||
|
|
fdc8431709 | ||
|
|
9d15c666b2 | ||
|
|
2131678f6b | ||
|
|
17f07b2452 | ||
|
|
05d69ae822 | ||
|
|
3ae81d62bc | ||
|
|
4efa123183 | ||
|
|
24a9886952 | ||
|
|
7ec1343ad5 | ||
|
|
7e1fffc455 | ||
|
|
003dd3a9a2 | ||
|
|
cece04e02f | ||
|
|
58e21e876e | ||
|
|
cb8fc1c10d | ||
|
|
a544f4b2cd | ||
|
|
ee0912a254 | ||
|
|
15e1547661 | ||
|
|
dcbcf90aef | ||
|
|
ed0ed398b7 | ||
|
|
152053e069 | ||
|
|
496dd05e14 | ||
|
|
3ff8fc8a10 | ||
|
|
d061d2259e | ||
|
|
90ac7d5d2c | ||
|
|
4295faa7c4 | ||
|
|
9c40137d05 | ||
|
|
17132b250d | ||
|
|
3f61df4e66 | ||
|
|
2d9cc623c2 | ||
|
|
f6ff6492ef | ||
|
|
b65ca334a8 | ||
|
|
b71dfce1f7 | ||
|
|
5f3a9d9423 | ||
|
|
895c870d02 | ||
|
|
47d7324a19 | ||
|
|
b19890c0b1 | ||
|
|
b41fcdedff | ||
|
|
0a78da0315 | ||
|
|
3d0fd14f3f | ||
|
|
e117bd7cb6 | ||
|
|
2655660509 | ||
|
|
0dd6af5a7e | ||
|
|
e2e5d4d447 | ||
|
|
44f39ca0ce | ||
|
|
7725f6ed5a | ||
|
|
b26ab1f982 | ||
|
|
21d42baa8e | ||
|
|
23274a9d57 | ||
|
|
f78f29ee66 | ||
|
|
7e2d8ab2a3 | ||
|
|
6f994c849d | ||
|
|
702e10649e | ||
|
|
ca3877d0b8 | ||
|
|
18e67afe09 | ||
|
|
d66685a3aa | ||
|
|
14c3235c12 | ||
|
|
034760e8b6 | ||
|
|
8f64caceb5 | ||
|
|
9997155617 | ||
|
|
ff0f408ab8 | ||
|
|
3262b375c9 | ||
|
|
494cedb3bc | ||
|
|
93000e3fca | ||
|
|
abfb654f90 | ||
|
|
9c7a275cd6 | ||
|
|
f609042ece | ||
|
|
8eee568731 | ||
|
|
fb24e8cb1f | ||
|
|
64a3133083 | ||
|
|
64f54e1fce | ||
|
|
c08660d837 | ||
|
|
f6482c36dc | ||
|
|
ccc3c13212 | ||
|
|
1003c220be | ||
|
|
d68bcbd292 | ||
|
|
4126502fe8 | ||
|
|
136b207a12 | ||
|
|
c4d769a586 | ||
|
|
1c1089bade | ||
|
|
b114b1155c | ||
|
|
f9e693b2a2 | ||
|
|
bac4d03813 | ||
|
|
9ba5825009 | ||
|
|
0df3c84c0f | ||
|
|
3f49725834 | ||
|
|
ab91d0bac3 | ||
|
|
79a6229522 | ||
|
|
01438f71a4 | ||
|
|
0bc43c1aa7 | ||
|
|
e8a2882796 | ||
|
|
b955e92276 | ||
|
|
562e1e59b1 | ||
|
|
892042eb92 | ||
|
|
0251e25f23 | ||
|
|
9bd09aa1b3 | ||
|
|
1cd013a09b | ||
|
|
7721dcdae8 | ||
|
|
e8d91eb14b | ||
|
|
0773786766 | ||
|
|
71bb2b64bf | ||
|
|
06fa931de9 | ||
|
|
16ff5ee99b | ||
|
|
08c5df3633 | ||
|
|
b365831839 | ||
|
|
959422f143 | ||
|
|
fa2e21dfd5 | ||
|
|
58e7abba2c | ||
|
|
87eaa75b8a | ||
|
|
749f46f86f | ||
|
|
0055ee6910 | ||
|
|
1b3b45779a | ||
|
|
e1a6d513cc | ||
|
|
f4da203915 | ||
|
|
637b220f82 | ||
|
|
365e77af58 | ||
|
|
1b1442e3ba | ||
|
|
d0a8c1d90d | ||
|
|
76c2f3166e | ||
|
|
02eaa8b46e | ||
|
|
4fbd4f212a | ||
|
|
1474cc626d | ||
|
|
7163752aa0 | ||
|
|
e9350cf25f | ||
|
|
1a1a61e917 | ||
|
|
532a90259b | ||
|
|
cf66604f85 | ||
|
|
9332697ec1 | ||
|
|
ab735f723c | ||
|
|
c5b5b64dfa | ||
|
|
381fe83008 | ||
|
|
8adb0a5644 | ||
|
|
885290d907 | ||
|
|
8220dbb513 | ||
|
|
d9f2e0f7d2 | ||
|
|
161c8c4c47 | ||
|
|
f3ed5ca5af | ||
|
|
0d518cb5a3 | ||
|
|
24e8766aaa | ||
|
|
29e3d8c371 | ||
|
|
c3581fb66b | ||
|
|
57f2a57dac | ||
|
|
b6ca3ea4d9 | ||
|
|
1a9952d0c0 | ||
|
|
a4a4be3381 | ||
|
|
b7ce0b05b1 | ||
|
|
af87388eb4 | ||
|
|
2aa8008ae2 | ||
|
|
d4413f5fa6 | ||
|
|
af7945197e | ||
|
|
ac2fa9870f | ||
|
|
a3ac6cb099 | ||
|
|
dc203b8439 | ||
|
|
f5bb086460 | ||
|
|
9ba9d57c8c | ||
|
|
82ae474002 | ||
|
|
56319a4705 | ||
|
|
07c91c200a | ||
|
|
d73051e980 | ||
|
|
9fe51af6b0 | ||
|
|
e4353e548a | ||
|
|
63bb338343 | ||
|
|
d012124c03 | ||
|
|
10664922c9 | ||
|
|
60a613ae51 | ||
|
|
35a9ca476d | ||
|
|
b8e68b0e63 | ||
|
|
b61ea62732 | ||
|
|
8ad7c75d79 | ||
|
|
5a1454ab31 | ||
|
|
b288fdf8c1 | ||
|
|
d2a719d67c | ||
|
|
28ef5b7db2 | ||
|
|
6413f25b8d | ||
|
|
912d0e83f3 | ||
|
|
3c075bcc53 | ||
|
|
ba8a88acfb | ||
|
|
e27488b48c | ||
|
|
1828a94b6c | ||
|
|
49afcdf715 | ||
|
|
ff84c6dbaf | ||
|
|
cb2d54a237 | ||
|
|
5fe99ea0e1 | ||
|
|
21751b2faa | ||
|
|
3b87b83076 | ||
|
|
884b909e7d | ||
|
|
b980dab6df | ||
|
|
e298bf922f | ||
|
|
2ead1bbf84 | ||
|
|
29917fb073 | ||
|
|
e627879b16 | ||
|
|
0572e02d7e | ||
|
|
df1a9c5509 | ||
|
|
e7779b5458 | ||
|
|
fc6d708fb6 | ||
|
|
a453ea3c70 | ||
|
|
8e8ce0c6bc | ||
|
|
c4e0c569aa | ||
|
|
231d6972d7 | ||
|
|
50476edc98 | ||
|
|
0b6476da32 | ||
|
|
79ae530bd2 | ||
|
|
f41458ea24 | ||
|
|
2481f7a292 | ||
|
|
61ac7e4e10 | ||
|
|
9a3044a54f | ||
|
|
a597a994d2 | ||
|
|
a2c5a8215b | ||
|
|
57197b8e01 | ||
|
|
5c4e368819 | ||
|
|
8d962430dd | ||
|
|
54a85ea15f | ||
|
|
efa7dc7ba4 | ||
|
|
a04016e0b6 | ||
|
|
08b0ed1b79 | ||
|
|
5b7d0a2810 |
24
.clang-tidy
24
.clang-tidy
@@ -15,15 +15,15 @@ Checks: >
|
||||
-readability-redundant-member-init,
|
||||
-readability-redundant-string-init,
|
||||
-readability-identifier-length
|
||||
CheckOptions:
|
||||
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.StructCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.FunctionCase, value: camelBack }
|
||||
- { key: readability-identifier-naming.VariableCase, value: camelBack }
|
||||
- { key: readability-identifier-naming.PrivateMemberCase, value: camelBack }
|
||||
- { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
|
||||
- { key: readability-identifier-naming.EnumCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
|
||||
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
|
||||
- { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }
|
||||
# CheckOptions:
|
||||
# - { key: readability-identifier-naming.NamespaceCase, value: lower_case }
|
||||
# - { key: readability-identifier-naming.ClassCase, value: CamelCase }
|
||||
# - { key: readability-identifier-naming.StructCase, value: CamelCase }
|
||||
# - { key: readability-identifier-naming.FunctionCase, value: camelBack }
|
||||
# - { key: readability-identifier-naming.VariableCase, value: camelBack }
|
||||
# - { key: readability-identifier-naming.PrivateMemberCase, value: camelBack }
|
||||
# - { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
|
||||
# - { key: readability-identifier-naming.EnumCase, value: CamelCase }
|
||||
# - { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
|
||||
# - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
|
||||
# - { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }
|
||||
|
||||
3
.github/workflows/clang-format.yml
vendored
3
.github/workflows/clang-format.yml
vendored
@@ -16,4 +16,5 @@ jobs:
|
||||
with:
|
||||
source: "."
|
||||
extensions: "hpp,h,cpp,c"
|
||||
clangFormatVersion: 16
|
||||
style: "file:.clang-format"
|
||||
clangFormatVersion: 18
|
||||
|
||||
32
.github/workflows/docker.yml
vendored
Normal file
32
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# run every night at midnight
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false # don't fail the other jobs if one of the images fails to build
|
||||
matrix:
|
||||
os: [ 'alpine', 'archlinux', 'debian', 'fedora', 'gentoo', 'opensuse' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfiles/${{ matrix.os }}
|
||||
push: true
|
||||
tags: alexays/waybar:${{ matrix.os }}
|
||||
9
.github/workflows/freebsd.yml
vendored
9
.github/workflows/freebsd.yml
vendored
@@ -14,23 +14,22 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Test in FreeBSD VM
|
||||
uses: cross-platform-actions/action@v0.23.0
|
||||
uses: cross-platform-actions/action@v0.25.0
|
||||
timeout-minutes: 180
|
||||
env:
|
||||
CPPFLAGS: '-isystem/usr/local/include'
|
||||
LDFLAGS: '-L/usr/local/lib'
|
||||
with:
|
||||
operating_system: freebsd
|
||||
version: "13.2"
|
||||
version: "14.1"
|
||||
environment_variables: CPPFLAGS LDFLAGS
|
||||
sync_files: runner-to-vm
|
||||
run: |
|
||||
sudo sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
|
||||
sudo pkg install -y git # subprojects/date
|
||||
sudo pkg install -y catch evdev-proto gtk-layer-shell gtkmm30 jsoncpp \
|
||||
libdbusmenu libevdev libfmt libmpdclient libudev-devd meson \
|
||||
pkgconf pulseaudio scdoc sndio spdlog wayland-protocols upower \
|
||||
pkgconf pipewire pulseaudio scdoc sndio spdlog wayland-protocols upower \
|
||||
libinotify
|
||||
meson build -Dman-pages=enabled
|
||||
meson setup build -Dman-pages=enabled
|
||||
ninja -C build
|
||||
meson test -C build --no-rebuild --print-errorlogs --suite waybar
|
||||
|
||||
3
.github/workflows/linux.yml
vendored
3
.github/workflows/linux.yml
vendored
@@ -9,6 +9,7 @@ concurrency:
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
distro:
|
||||
- alpine
|
||||
@@ -26,7 +27,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: configure
|
||||
run: meson -Dman-pages=enabled -Dcpp_std=${{matrix.cpp_std}} build
|
||||
run: meson setup -Dman-pages=enabled -Dcpp_std=${{matrix.cpp_std}} build
|
||||
- name: build
|
||||
run: ninja -C build
|
||||
- name: test
|
||||
|
||||
17
.github/workflows/nix-tests.yml
vendored
Normal file
17
.github/workflows/nix-tests.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: "Nix-Tests"
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
jobs:
|
||||
nix-flake-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: cachix/install-nix-action@v27
|
||||
with:
|
||||
extra_nix_config: |
|
||||
experimental-features = nix-command flakes
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
- run: nix flake show
|
||||
- run: nix flake check --print-build-logs
|
||||
- run: nix build --print-build-logs
|
||||
21
.github/workflows/nix-update-flake-lock.yml
vendored
Normal file
21
.github/workflows/nix-update-flake-lock.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: update-flake-lock
|
||||
on:
|
||||
workflow_dispatch: # allows manual triggering
|
||||
schedule:
|
||||
- cron: '0 0 1 * *' # Run monthly
|
||||
push:
|
||||
paths:
|
||||
- 'flake.nix'
|
||||
jobs:
|
||||
lockfile:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v27
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Update flake.lock
|
||||
uses: DeterminateSystems/update-flake-lock@v21
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -48,3 +48,5 @@ packagecache
|
||||
# Nix
|
||||
result
|
||||
result-*
|
||||
|
||||
.ccls-cache
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
FROM archlinux:base-devel
|
||||
|
||||
RUN pacman -Syu --noconfirm && \
|
||||
pacman -S --noconfirm git meson base-devel libinput wayland wayland-protocols pixman libxkbcommon mesa gtkmm3 jsoncpp pugixml scdoc libpulse libdbusmenu-gtk3 libmpdclient gobject-introspection libxkbcommon playerctl iniparser fftw && \
|
||||
pacman -S --noconfirm git meson base-devel libinput wayland wayland-protocols glib2-devel pixman libxkbcommon mesa gtkmm3 jsoncpp pugixml scdoc libpulse libdbusmenu-gtk3 libmpdclient gobject-introspection libxkbcommon playerctl iniparser fftw && \
|
||||
sed -Ei 's/#(en_(US|GB)\.UTF)/\1/' /etc/locale.gen && locale-gen
|
||||
|
||||
@@ -34,7 +34,7 @@ RUN apt update && \
|
||||
libudev-dev \
|
||||
libupower-glib-dev \
|
||||
libwayland-dev \
|
||||
libwireplumber-0.4-dev \
|
||||
libwireplumber-0.5-dev \
|
||||
libxkbcommon-dev \
|
||||
libxkbregistry-dev \
|
||||
locales \
|
||||
|
||||
@@ -29,6 +29,6 @@ RUN dnf install -y @c-development \
|
||||
'pkgconfig(wayland-client)' \
|
||||
'pkgconfig(wayland-cursor)' \
|
||||
'pkgconfig(wayland-protocols)' \
|
||||
'pkgconfig(wireplumber-0.4)' \
|
||||
'pkgconfig(wireplumber-0.5)' \
|
||||
'pkgconfig(xkbregistry)' && \
|
||||
dnf clean all -y
|
||||
|
||||
@@ -6,4 +6,4 @@ RUN zypper -n up && \
|
||||
zypper addrepo https://download.opensuse.org/repositories/X11:Wayland/openSUSE_Tumbleweed/X11:Wayland.repo | echo 'a' && \
|
||||
zypper -n refresh && \
|
||||
zypper -n install -t pattern devel_C_C++ && \
|
||||
zypper -n install git meson clang libinput10 libinput-devel pugixml-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel libxkbregistry-devel scdoc playerctl-devel
|
||||
zypper -n install git meson clang libinput10 libinput-devel pugixml-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel libxkbregistry-devel scdoc playerctl-devel python3-packaging
|
||||
|
||||
4
Makefile
4
Makefile
@@ -3,11 +3,11 @@
|
||||
default: build
|
||||
|
||||
build:
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
|
||||
build-debug:
|
||||
meson build --buildtype=debug
|
||||
meson setup build --buildtype=debug
|
||||
ninja -C build
|
||||
|
||||
install: build
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
- Sway (Workspaces, Binding mode, Focused window name)
|
||||
- River (Mapping mode, Tags, Focused window name)
|
||||
- Hyprland (Window Icons, Workspaces, Focused window name)
|
||||
- Niri (Workspaces, Focused window name, Language)
|
||||
- DWL (Tags, Focused window name) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
|
||||
- Tray [#21](https://github.com/Alexays/Waybar/issues/21)
|
||||
- Local time
|
||||
@@ -48,7 +49,7 @@ An Ubuntu PPA with more recent versions is available
|
||||
```bash
|
||||
$ git clone https://github.com/Alexays/Waybar
|
||||
$ cd Waybar
|
||||
$ meson build
|
||||
$ meson setup build
|
||||
$ ninja -C build
|
||||
$ ./build/waybar
|
||||
# If you want to install it
|
||||
|
||||
6
flake.lock
generated
6
flake.lock
generated
@@ -18,11 +18,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1711163522,
|
||||
"narHash": "sha256-YN/Ciidm+A0fmJPWlHBGvVkcarYWSC+s3NTPk/P+q3c=",
|
||||
"lastModified": 1724819573,
|
||||
"narHash": "sha256-GnR7/ibgIH1vhoy8cYdmXE6iyZqKqFxQSVkFgosBh6w=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "44d0940ea560dee511026a53f0e2e2cde489b4d4",
|
||||
"rev": "71e91c409d1e654808b2621f28a327acfdad8dc2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
38
flake.nix
38
flake.nix
@@ -16,7 +16,12 @@
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
]
|
||||
(system: func (import nixpkgs { inherit system; }));
|
||||
(system: func (import nixpkgs {
|
||||
inherit system;
|
||||
overlays = with self.overlays; [
|
||||
waybar
|
||||
];
|
||||
}));
|
||||
|
||||
mkDate = longDate: (lib.concatStringsSep "-" [
|
||||
(builtins.substring 0 4 longDate)
|
||||
@@ -46,22 +51,25 @@
|
||||
};
|
||||
});
|
||||
|
||||
overlays.default = final: prev: {
|
||||
waybar = final.callPackage ./nix/default.nix {
|
||||
# take the first "version: '...'" from meson.build
|
||||
version =
|
||||
(builtins.head (builtins.split "'"
|
||||
(builtins.elemAt
|
||||
(builtins.split " version: '" (builtins.readFile ./meson.build))
|
||||
2)))
|
||||
+ "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
overlays = {
|
||||
default = self.overlays.waybar;
|
||||
waybar = final: prev: {
|
||||
waybar = final.callPackage ./nix/default.nix {
|
||||
waybar = prev.waybar;
|
||||
# take the first "version: '...'" from meson.build
|
||||
version =
|
||||
(builtins.head (builtins.split "'"
|
||||
(builtins.elemAt
|
||||
(builtins.split " version: '" (builtins.readFile ./meson.build))
|
||||
2)))
|
||||
+ "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
packages = genSystems (pkgs:
|
||||
let packages = self.overlays.default pkgs pkgs;
|
||||
in packages // {
|
||||
default = packages.waybar;
|
||||
});
|
||||
packages = genSystems (pkgs: {
|
||||
default = self.packages.${pkgs.stdenv.hostPlatform.system}.waybar;
|
||||
inherit (pkgs) waybar;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ class ALabel : public AModule {
|
||||
|
||||
bool handleToggle(GdkEventButton *const &e) override;
|
||||
virtual std::string getState(uint8_t value, bool lesser = false);
|
||||
|
||||
std::map<std::string, GtkMenuItem *> submenus_;
|
||||
std::map<std::string, std::string> menuActionsMap_;
|
||||
static void handleGtkMenuEvent(GtkMenuItem *menuitem, gpointer data);
|
||||
};
|
||||
|
||||
} // namespace waybar
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <glibmm/dispatcher.h>
|
||||
#include <glibmm/markup.h>
|
||||
#include <gtkmm.h>
|
||||
#include <gtkmm/eventbox.h>
|
||||
#include <json/json.h>
|
||||
|
||||
@@ -13,9 +14,9 @@ class AModule : public IModule {
|
||||
public:
|
||||
static constexpr const char *MODULE_CLASS = "module";
|
||||
|
||||
virtual ~AModule();
|
||||
~AModule() override;
|
||||
auto update() -> void override;
|
||||
virtual auto refresh(int) -> void{};
|
||||
virtual auto refresh(int shouldRefresh) -> void {};
|
||||
operator Gtk::Widget &() override;
|
||||
auto doAction(const std::string &name) -> void override;
|
||||
|
||||
@@ -31,21 +32,25 @@ class AModule : public IModule {
|
||||
enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT };
|
||||
|
||||
SCROLL_DIR getScrollDir(GdkEventScroll *e);
|
||||
bool tooltipEnabled();
|
||||
bool tooltipEnabled() const;
|
||||
|
||||
const std::string name_;
|
||||
const Json::Value &config_;
|
||||
Gtk::EventBox event_box_;
|
||||
|
||||
virtual void setCursor(Gdk::CursorType const &c);
|
||||
|
||||
virtual bool handleToggle(GdkEventButton *const &ev);
|
||||
virtual bool handleMouseEnter(GdkEventCrossing *const &ev);
|
||||
virtual bool handleMouseLeave(GdkEventCrossing *const &ev);
|
||||
virtual bool handleScroll(GdkEventScroll *);
|
||||
virtual bool handleRelease(GdkEventButton *const &ev);
|
||||
GObject *menu_;
|
||||
|
||||
private:
|
||||
bool handleUserEvent(GdkEventButton *const &ev);
|
||||
const bool isTooltip;
|
||||
bool hasUserEvents_;
|
||||
std::vector<int> pid_;
|
||||
gdouble distance_scrolled_y_;
|
||||
gdouble distance_scrolled_x_;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <json/json.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "AModule.hpp"
|
||||
@@ -41,7 +42,7 @@ struct bar_margins {
|
||||
};
|
||||
|
||||
struct bar_mode {
|
||||
bar_layer layer;
|
||||
std::optional<bar_layer> layer;
|
||||
bool exclusive;
|
||||
bool passthrough;
|
||||
bool visible;
|
||||
@@ -53,7 +54,7 @@ class BarIpcClient;
|
||||
}
|
||||
#endif // HAVE_SWAY
|
||||
|
||||
class Bar {
|
||||
class Bar : public sigc::trackable {
|
||||
public:
|
||||
using bar_mode_map = std::map<std::string, struct bar_mode>;
|
||||
static const bar_mode_map PRESET_MODES;
|
||||
@@ -65,7 +66,7 @@ class Bar {
|
||||
~Bar();
|
||||
|
||||
void setMode(const std::string &mode);
|
||||
void setVisible(bool visible);
|
||||
void setVisible(bool value);
|
||||
void toggle();
|
||||
void handleSignal(int);
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@ class Config {
|
||||
static std::optional<std::string> findConfigPath(
|
||||
const std::vector<std::string> &names, const std::vector<std::string> &dirs = CONFIG_DIRS);
|
||||
|
||||
static std::optional<std::string> tryExpandPath(const std::string &base,
|
||||
const std::string &filename);
|
||||
|
||||
Config() = default;
|
||||
|
||||
void load(const std::string &config);
|
||||
|
||||
@@ -11,15 +11,13 @@ namespace waybar {
|
||||
|
||||
class Group : public AModule {
|
||||
public:
|
||||
Group(const std::string&, const std::string&, const Json::Value&, bool);
|
||||
virtual ~Group() = default;
|
||||
Group(const std::string &, const std::string &, const Json::Value &, bool);
|
||||
~Group() override = default;
|
||||
auto update() -> void override;
|
||||
operator Gtk::Widget&() override;
|
||||
operator Gtk::Widget &() override;
|
||||
|
||||
virtual Gtk::Box& getBox();
|
||||
void addWidget(Gtk::Widget& widget);
|
||||
|
||||
bool handleMouseHover(GdkEventCrossing* const& e);
|
||||
virtual Gtk::Box &getBox();
|
||||
void addWidget(Gtk::Widget &widget);
|
||||
|
||||
protected:
|
||||
Gtk::Box box;
|
||||
@@ -27,9 +25,13 @@ class Group : public AModule {
|
||||
Gtk::Revealer revealer;
|
||||
bool is_first_widget = true;
|
||||
bool is_drawer = false;
|
||||
bool click_to_reveal = false;
|
||||
std::string add_class_to_drawer_children;
|
||||
|
||||
void addHoverHandlerTo(Gtk::Widget& widget);
|
||||
bool handleMouseEnter(GdkEventCrossing *const &ev) override;
|
||||
bool handleMouseLeave(GdkEventCrossing *const &ev) override;
|
||||
bool handleToggle(GdkEventButton *const &ev) override;
|
||||
void show_group();
|
||||
void hide_group();
|
||||
};
|
||||
|
||||
} // namespace waybar
|
||||
|
||||
@@ -49,6 +49,9 @@ class Bluetooth : public ALabel {
|
||||
auto update() -> void override;
|
||||
|
||||
private:
|
||||
static auto onObjectAdded(GDBusObjectManager*, GDBusObject*, gpointer) -> void;
|
||||
static auto onObjectRemoved(GDBusObjectManager*, GDBusObject*, gpointer) -> void;
|
||||
|
||||
static auto onInterfaceAddedOrRemoved(GDBusObjectManager*, GDBusObject*, GDBusInterface*,
|
||||
gpointer) -> void;
|
||||
static auto onInterfaceProxyPropertiesChanged(GDBusObjectManagerClient*, GDBusObjectProxy*,
|
||||
|
||||
@@ -21,10 +21,12 @@ class Clock final : public ALabel {
|
||||
auto doAction(const std::string&) -> void override;
|
||||
|
||||
private:
|
||||
const std::locale locale_;
|
||||
const std::locale m_locale_;
|
||||
// tooltip
|
||||
const std::string tlpFmt_;
|
||||
std::string tlpText_{""}; // tooltip text to print
|
||||
const std::string m_tlpFmt_;
|
||||
std::string m_tlpText_{""}; // tooltip text to print
|
||||
const Glib::RefPtr<Gtk::Label> m_tooltip_; // tooltip as a separate Gtk::Label
|
||||
bool query_tlp_cb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
|
||||
// Calendar
|
||||
const bool cldInTooltip_; // calendar in tooltip
|
||||
/*
|
||||
@@ -49,8 +51,8 @@ class Clock final : public ALabel {
|
||||
day cldBaseDay_{0}; // calendar Cached day. Is used when today is changing(midnight)
|
||||
std::string cldText_{""}; // calendar text to print
|
||||
CldMode cldMode_{CldMode::MONTH};
|
||||
auto get_calendar(const year_month_day& today, const year_month_day& ymd, const time_zone* tz)
|
||||
-> const std::string;
|
||||
auto get_calendar(const year_month_day& today, const year_month_day& ymd,
|
||||
const time_zone* tz) -> const std::string;
|
||||
|
||||
// get local time zone
|
||||
auto local_zone() -> const time_zone*;
|
||||
|
||||
@@ -35,6 +35,7 @@ class Custom : public ALabel {
|
||||
std::string id_;
|
||||
std::string alt_;
|
||||
std::string tooltip_;
|
||||
const bool tooltip_format_enabled_;
|
||||
std::vector<std::string> class_;
|
||||
int percentage_;
|
||||
FILE* fp_;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace waybar::modules::dwl {
|
||||
class Window : public AAppIconLabel, public sigc::trackable {
|
||||
public:
|
||||
Window(const std::string &, const waybar::Bar &, const Json::Value &);
|
||||
virtual ~Window() = default;
|
||||
~Window();
|
||||
|
||||
void handle_layout(const uint32_t layout);
|
||||
void handle_title(const char *title);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
@@ -25,6 +26,10 @@ class IPC {
|
||||
|
||||
static std::string getSocket1Reply(const std::string& rq);
|
||||
Json::Value getSocket1JsonReply(const std::string& rq);
|
||||
static std::filesystem::path getSocketFolder(const char* instanceSig);
|
||||
|
||||
protected:
|
||||
static std::filesystem::path socketFolder_;
|
||||
|
||||
private:
|
||||
void startIPC();
|
||||
|
||||
61
include/modules/hyprland/windowcreationpayload.hpp
Normal file
61
include/modules/hyprland/windowcreationpayload.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtkmm/button.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <json/value.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "AModule.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/hyprland/backend.hpp"
|
||||
#include "util/enum.hpp"
|
||||
#include "util/regex_collection.hpp"
|
||||
|
||||
using WindowAddress = std::string;
|
||||
|
||||
namespace waybar::modules::hyprland {
|
||||
|
||||
class Workspaces;
|
||||
|
||||
class WindowCreationPayload {
|
||||
public:
|
||||
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
||||
std::string window_repr);
|
||||
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
||||
std::string window_class, std::string window_title);
|
||||
WindowCreationPayload(Json::Value const& client_data);
|
||||
|
||||
int incrementTimeSpentUncreated();
|
||||
bool isEmpty(Workspaces& workspace_manager);
|
||||
bool reprIsReady() const { return std::holds_alternative<Repr>(m_window); }
|
||||
std::string repr(Workspaces& workspace_manager);
|
||||
|
||||
std::string getWorkspaceName() const { return m_workspaceName; }
|
||||
WindowAddress getAddress() const { return m_windowAddress; }
|
||||
|
||||
void moveToWorksace(std::string& new_workspace_name);
|
||||
|
||||
private:
|
||||
void clearAddr();
|
||||
void clearWorkspaceName();
|
||||
|
||||
using Repr = std::string;
|
||||
using ClassAndTitle = std::pair<std::string, std::string>;
|
||||
std::variant<Repr, ClassAndTitle> m_window;
|
||||
|
||||
WindowAddress m_windowAddress;
|
||||
std::string m_workspaceName;
|
||||
|
||||
int m_timeSpentUncreated = 0;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
88
include/modules/hyprland/workspace.hpp
Normal file
88
include/modules/hyprland/workspace.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtkmm/button.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <json/value.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "AModule.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/hyprland/backend.hpp"
|
||||
#include "modules/hyprland/windowcreationpayload.hpp"
|
||||
#include "util/enum.hpp"
|
||||
#include "util/regex_collection.hpp"
|
||||
|
||||
using WindowAddress = std::string;
|
||||
|
||||
namespace waybar::modules::hyprland {
|
||||
|
||||
class Workspaces;
|
||||
class Workspace {
|
||||
public:
|
||||
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
|
||||
const Json::Value& clients_data = Json::Value::nullRef);
|
||||
std::string& selectIcon(std::map<std::string, std::string>& icons_map);
|
||||
Gtk::Button& button() { return m_button; };
|
||||
|
||||
int id() const { return m_id; };
|
||||
std::string name() const { return m_name; };
|
||||
std::string output() const { return m_output; };
|
||||
bool isActive() const { return m_isActive; };
|
||||
bool isSpecial() const { return m_isSpecial; };
|
||||
bool isPersistent() const { return m_isPersistentRule || m_isPersistentConfig; };
|
||||
bool isPersistentConfig() const { return m_isPersistentConfig; };
|
||||
bool isPersistentRule() const { return m_isPersistentRule; };
|
||||
bool isVisible() const { return m_isVisible; };
|
||||
bool isEmpty() const { return m_windows == 0; };
|
||||
bool isUrgent() const { return m_isUrgent; };
|
||||
|
||||
bool handleClicked(GdkEventButton* bt) const;
|
||||
void setActive(bool value = true) { m_isActive = value; };
|
||||
void setPersistentRule(bool value = true) { m_isPersistentRule = value; };
|
||||
void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; };
|
||||
void setUrgent(bool value = true) { m_isUrgent = value; };
|
||||
void setVisible(bool value = true) { m_isVisible = value; };
|
||||
void setWindows(uint value) { m_windows = value; };
|
||||
void setName(std::string const& value) { m_name = value; };
|
||||
void setOutput(std::string const& value) { m_output = value; };
|
||||
bool containsWindow(WindowAddress const& addr) const { return m_windowMap.contains(addr); }
|
||||
void insertWindow(WindowCreationPayload create_window_paylod);
|
||||
std::string removeWindow(WindowAddress const& addr);
|
||||
void initializeWindowMap(const Json::Value& clients_data);
|
||||
|
||||
bool onWindowOpened(WindowCreationPayload const& create_window_paylod);
|
||||
std::optional<std::string> closeWindow(WindowAddress const& addr);
|
||||
|
||||
void update(const std::string& format, const std::string& icon);
|
||||
|
||||
private:
|
||||
Workspaces& m_workspaceManager;
|
||||
|
||||
int m_id;
|
||||
std::string m_name;
|
||||
std::string m_output;
|
||||
uint m_windows;
|
||||
bool m_isActive = false;
|
||||
bool m_isSpecial = false;
|
||||
bool m_isPersistentRule = false; // represents the persistent state in hyprland
|
||||
bool m_isPersistentConfig = false; // represents the persistent state in the Waybar config
|
||||
bool m_isUrgent = false;
|
||||
bool m_isVisible = false;
|
||||
|
||||
std::map<WindowAddress, std::string> m_windowMap;
|
||||
|
||||
Gtk::Button m_button;
|
||||
Gtk::Box m_content;
|
||||
Gtk::Label m_label;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
@@ -4,19 +4,18 @@
|
||||
#include <gtkmm/label.h>
|
||||
#include <json/value.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "AModule.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "modules/hyprland/backend.hpp"
|
||||
#include "modules/hyprland/windowcreationpayload.hpp"
|
||||
#include "modules/hyprland/workspace.hpp"
|
||||
#include "util/enum.hpp"
|
||||
#include "util/regex_collection.hpp"
|
||||
|
||||
@@ -26,97 +25,6 @@ namespace waybar::modules::hyprland {
|
||||
|
||||
class Workspaces;
|
||||
|
||||
class WindowCreationPayload {
|
||||
public:
|
||||
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
||||
std::string window_repr);
|
||||
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
|
||||
std::string window_class, std::string window_title);
|
||||
WindowCreationPayload(Json::Value const& client_data);
|
||||
|
||||
int incrementTimeSpentUncreated();
|
||||
bool isEmpty(Workspaces& workspace_manager);
|
||||
bool reprIsReady() const { return std::holds_alternative<Repr>(m_window); }
|
||||
std::string repr(Workspaces& workspace_manager);
|
||||
|
||||
std::string getWorkspaceName() const { return m_workspaceName; }
|
||||
WindowAddress getAddress() const { return m_windowAddress; }
|
||||
|
||||
void moveToWorksace(std::string& new_workspace_name);
|
||||
|
||||
private:
|
||||
void clearAddr();
|
||||
void clearWorkspaceName();
|
||||
|
||||
using Repr = std::string;
|
||||
using ClassAndTitle = std::pair<std::string, std::string>;
|
||||
std::variant<Repr, ClassAndTitle> m_window;
|
||||
|
||||
WindowAddress m_windowAddress;
|
||||
std::string m_workspaceName;
|
||||
|
||||
int m_timeSpentUncreated = 0;
|
||||
};
|
||||
|
||||
class Workspace {
|
||||
public:
|
||||
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
|
||||
const Json::Value& clients_data = Json::Value::nullRef);
|
||||
std::string& selectIcon(std::map<std::string, std::string>& icons_map);
|
||||
Gtk::Button& button() { return m_button; };
|
||||
|
||||
int id() const { return m_id; };
|
||||
std::string name() const { return m_name; };
|
||||
std::string output() const { return m_output; };
|
||||
bool isActive() const { return m_isActive; };
|
||||
bool isSpecial() const { return m_isSpecial; };
|
||||
bool isPersistent() const { return m_isPersistentRule || m_isPersistentConfig; };
|
||||
bool isPersistentConfig() const { return m_isPersistentConfig; };
|
||||
bool isPersistentRule() const { return m_isPersistentRule; };
|
||||
bool isVisible() const { return m_isVisible; };
|
||||
bool isEmpty() const { return m_windows == 0; };
|
||||
bool isUrgent() const { return m_isUrgent; };
|
||||
|
||||
bool handleClicked(GdkEventButton* bt) const;
|
||||
void setActive(bool value = true) { m_isActive = value; };
|
||||
void setPersistentRule(bool value = true) { m_isPersistentRule = value; };
|
||||
void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; };
|
||||
void setUrgent(bool value = true) { m_isUrgent = value; };
|
||||
void setVisible(bool value = true) { m_isVisible = value; };
|
||||
void setWindows(uint value) { m_windows = value; };
|
||||
void setName(std::string const& value) { m_name = value; };
|
||||
void setOutput(std::string const& value) { m_output = value; };
|
||||
bool containsWindow(WindowAddress const& addr) const { return m_windowMap.contains(addr); }
|
||||
void insertWindow(WindowCreationPayload create_window_paylod);
|
||||
std::string removeWindow(WindowAddress const& addr);
|
||||
void initializeWindowMap(const Json::Value& clients_data);
|
||||
|
||||
bool onWindowOpened(WindowCreationPayload const& create_window_paylod);
|
||||
std::optional<std::string> closeWindow(WindowAddress const& addr);
|
||||
|
||||
void update(const std::string& format, const std::string& icon);
|
||||
|
||||
private:
|
||||
Workspaces& m_workspaceManager;
|
||||
|
||||
int m_id;
|
||||
std::string m_name;
|
||||
std::string m_output;
|
||||
uint m_windows;
|
||||
bool m_isActive = false;
|
||||
bool m_isSpecial = false;
|
||||
bool m_isPersistentRule = false; // represents the persistent state in hyprland
|
||||
bool m_isPersistentConfig = false; // represents the persistent state in the Waybar config
|
||||
bool m_isUrgent = false;
|
||||
bool m_isVisible = false;
|
||||
|
||||
std::map<WindowAddress, std::string> m_windowMap;
|
||||
|
||||
Gtk::Button m_button;
|
||||
Gtk::Box m_content;
|
||||
Gtk::Label m_label;
|
||||
};
|
||||
|
||||
class Workspaces : public AModule, public EventHandler {
|
||||
public:
|
||||
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||
@@ -127,6 +35,7 @@ class Workspaces : public AModule, public EventHandler {
|
||||
auto allOutputs() const -> bool { return m_allOutputs; }
|
||||
auto showSpecial() const -> bool { return m_showSpecial; }
|
||||
auto activeOnly() const -> bool { return m_activeOnly; }
|
||||
auto specialVisibleOnly() const -> bool { return m_specialVisibleOnly; }
|
||||
auto moveToMonitor() const -> bool { return m_moveToMonitor; }
|
||||
|
||||
auto getBarOutput() const -> std::string { return m_bar.output->name; }
|
||||
@@ -141,11 +50,24 @@ class Workspaces : public AModule, public EventHandler {
|
||||
void onEvent(const std::string& e) override;
|
||||
void updateWindowCount();
|
||||
void sortWorkspaces();
|
||||
void createWorkspace(Json::Value const& workspaceData,
|
||||
Json::Value const& clientsData = Json::Value::nullRef);
|
||||
void createWorkspace(Json::Value const& workspace_data,
|
||||
Json::Value const& clients_data = Json::Value::nullRef);
|
||||
|
||||
static Json::Value createMonitorWorkspaceData(std::string const& name,
|
||||
std::string const& monitor);
|
||||
void removeWorkspace(std::string const& name);
|
||||
void setUrgentWorkspace(std::string const& windowaddress);
|
||||
|
||||
// Config
|
||||
void parseConfig(const Json::Value& config);
|
||||
auto populateIconsMap(const Json::Value& formatIcons) -> void;
|
||||
static auto populateBoolConfig(const Json::Value& config, const std::string& key,
|
||||
bool& member) -> void;
|
||||
auto populateSortByConfig(const Json::Value& config) -> void;
|
||||
auto populateIgnoreWorkspacesConfig(const Json::Value& config) -> void;
|
||||
auto populateFormatWindowSeparatorConfig(const Json::Value& config) -> void;
|
||||
auto populateWindowRewriteConfig(const Json::Value& config) -> void;
|
||||
|
||||
void registerIpc();
|
||||
|
||||
// workspace events
|
||||
@@ -171,7 +93,13 @@ class Workspaces : public AModule, public EventHandler {
|
||||
|
||||
int windowRewritePriorityFunction(std::string const& window_rule);
|
||||
|
||||
// Update methods
|
||||
void doUpdate();
|
||||
void removeWorkspacesToRemove();
|
||||
void createWorkspacesToCreate();
|
||||
static std::vector<std::string> getVisibleWorkspaces();
|
||||
void updateWorkspaceStates();
|
||||
bool updateWindowsToCreate();
|
||||
|
||||
void extendOrphans(int workspaceId, Json::Value const& clientsJson);
|
||||
void registerOrphanWindow(WindowCreationPayload create_window_payload);
|
||||
@@ -184,6 +112,7 @@ class Workspaces : public AModule, public EventHandler {
|
||||
bool m_allOutputs = false;
|
||||
bool m_showSpecial = false;
|
||||
bool m_activeOnly = false;
|
||||
bool m_specialVisibleOnly = false;
|
||||
bool m_moveToMonitor = false;
|
||||
Json::Value m_persistentWorkspaceConfig;
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ class Network : public ALabel {
|
||||
void parseEssid(struct nlattr**);
|
||||
void parseSignal(struct nlattr**);
|
||||
void parseFreq(struct nlattr**);
|
||||
void parseBssid(struct nlattr**);
|
||||
bool associatedOrJoined(struct nlattr**);
|
||||
bool checkInterface(std::string name);
|
||||
auto getInfo() -> void;
|
||||
@@ -69,6 +70,7 @@ class Network : public ALabel {
|
||||
|
||||
std::string state_;
|
||||
std::string essid_;
|
||||
std::string bssid_;
|
||||
bool carrier_;
|
||||
std::string ifname_;
|
||||
std::string ipaddr_;
|
||||
|
||||
52
include/modules/niri/backend.hpp
Normal file
52
include/modules/niri/backend.hpp
Normal file
@@ -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() { startIPC(); }
|
||||
|
||||
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
|
||||
38
include/modules/niri/language.hpp
Normal file
38
include/modules/niri/language.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#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_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::niri
|
||||
28
include/modules/niri/window.hpp
Normal file
28
include/modules/niri/window.hpp
Normal file
@@ -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
|
||||
30
include/modules/niri/workspaces.hpp
Normal file
30
include/modules/niri/workspaces.hpp
Normal file
@@ -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
|
||||
@@ -10,6 +10,8 @@ namespace waybar::modules {
|
||||
struct Profile {
|
||||
std::string name;
|
||||
std::string driver;
|
||||
|
||||
Profile(std::string n, std::string d) : name(std::move(n)), driver(std::move(d)) {}
|
||||
};
|
||||
|
||||
class PowerProfilesDaemon : public ALabel {
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "ALabel.hpp"
|
||||
#include "gtkmm/box.h"
|
||||
#include "modules/privacy/privacy_item.hpp"
|
||||
#include "util/pipewire/pipewire_backend.hpp"
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
#include <json/value.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "gtkmm/box.h"
|
||||
|
||||
@@ -76,6 +76,8 @@ class Item : public sigc::trackable {
|
||||
void makeMenu();
|
||||
bool handleClick(GdkEventButton* const& /*ev*/);
|
||||
bool handleScroll(GdkEventScroll* const&);
|
||||
bool handleMouseEnter(GdkEventCrossing* const&);
|
||||
bool handleMouseLeave(GdkEventCrossing* const&);
|
||||
|
||||
// smooth scrolling threshold
|
||||
gdouble scroll_threshold_ = 0;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace waybar::modules::sway {
|
||||
class Workspaces : public AModule, public sigc::trackable {
|
||||
public:
|
||||
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||
virtual ~Workspaces() = default;
|
||||
~Workspaces() override = default;
|
||||
auto update() -> void override;
|
||||
|
||||
private:
|
||||
@@ -38,10 +38,10 @@ class Workspaces : public AModule, public sigc::trackable {
|
||||
Gtk::Button& addButton(const Json::Value&);
|
||||
void onButtonReady(const Json::Value&, Gtk::Button&);
|
||||
std::string getIcon(const std::string&, const Json::Value&);
|
||||
const 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;
|
||||
std::string trimWorkspaceName(std::string);
|
||||
bool handleScroll(GdkEventScroll*) override;
|
||||
static std::string trimWorkspaceName(std::string);
|
||||
bool handleScroll(GdkEventScroll* /*unused*/) override;
|
||||
|
||||
const Bar& bar_;
|
||||
std::vector<Json::Value> workspaces_;
|
||||
|
||||
94
include/modules/upower.hpp
Normal file
94
include/modules/upower.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
|
||||
#include <giomm/dbusconnection.h>
|
||||
#include <gtkmm/icontheme.h>
|
||||
#include <libupower-glib/upower.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "AIconLabel.hpp"
|
||||
|
||||
namespace waybar::modules {
|
||||
|
||||
class UPower final : public AIconLabel {
|
||||
public:
|
||||
UPower(const std::string &, const Json::Value &);
|
||||
virtual ~UPower();
|
||||
auto update() -> void override;
|
||||
|
||||
private:
|
||||
const std::string NO_BATTERY{"battery-missing-symbolic"};
|
||||
|
||||
// Config
|
||||
bool showIcon_{true};
|
||||
bool hideIfEmpty_{true};
|
||||
int iconSize_{20};
|
||||
int tooltip_spacing_{4};
|
||||
int tooltip_padding_{4};
|
||||
Gtk::Box contentBox_; // tooltip box
|
||||
std::string tooltipFormat_;
|
||||
|
||||
// UPower device info
|
||||
struct upDevice_output {
|
||||
UpDevice *upDevice{NULL};
|
||||
double percentage{0.0};
|
||||
double temperature{0.0};
|
||||
guint64 time_full{0u};
|
||||
guint64 time_empty{0u};
|
||||
gchar *icon_name{(char *)'\0'};
|
||||
bool upDeviceValid{false};
|
||||
UpDeviceState state;
|
||||
UpDeviceKind kind;
|
||||
char *nativePath{(char *)'\0'};
|
||||
char *model{(char *)'\0'};
|
||||
};
|
||||
|
||||
// Technical variables
|
||||
std::string nativePath_;
|
||||
std::string model_;
|
||||
std::string lastStatus_;
|
||||
Glib::ustring label_markup_;
|
||||
std::mutex mutex_;
|
||||
Glib::RefPtr<Gtk::IconTheme> gtkTheme_;
|
||||
bool sleeping_;
|
||||
|
||||
// Technical functions
|
||||
void addDevice(UpDevice *);
|
||||
void removeDevice(const gchar *);
|
||||
void removeDevices();
|
||||
void resetDevices();
|
||||
void setDisplayDevice();
|
||||
const Glib::ustring getText(const upDevice_output &upDevice_, const std::string &format);
|
||||
bool queryTooltipCb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &);
|
||||
|
||||
// DBUS variables
|
||||
guint watcherID_;
|
||||
Glib::RefPtr<Gio::DBus::Connection> conn_;
|
||||
guint subscrID_{0u};
|
||||
|
||||
// UPower variables
|
||||
UpClient *upClient_;
|
||||
upDevice_output upDevice_; // Device to display
|
||||
typedef std::unordered_map<std::string, upDevice_output> Devices;
|
||||
Devices devices_;
|
||||
bool upRunning_{true};
|
||||
|
||||
// DBus callbacks
|
||||
void getConn_cb(Glib::RefPtr<Gio::AsyncResult> &result);
|
||||
void onAppear(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &,
|
||||
const Glib::ustring &);
|
||||
void onVanished(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &);
|
||||
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
|
||||
const Glib::ustring &sender_name, const Glib::ustring &object_path,
|
||||
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
|
||||
const Glib::VariantContainerBase ¶meters);
|
||||
|
||||
// UPower callbacks
|
||||
static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data);
|
||||
static void deviceRemoved_cb(UpClient *client, const gchar *objectPath, gpointer data);
|
||||
static void deviceNotify_cb(UpDevice *device, GParamSpec *pspec, gpointer user_data);
|
||||
// UPower secondary functions
|
||||
void getUpDeviceInfo(upDevice_output &upDevice_);
|
||||
};
|
||||
|
||||
} // namespace waybar::modules
|
||||
@@ -1,82 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <libupower-glib/upower.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "ALabel.hpp"
|
||||
#include "glibconfig.h"
|
||||
#include "gtkmm/box.h"
|
||||
#include "gtkmm/image.h"
|
||||
#include "gtkmm/label.h"
|
||||
#include "modules/upower/upower_tooltip.hpp"
|
||||
|
||||
namespace waybar::modules::upower {
|
||||
|
||||
class UPower : public AModule {
|
||||
public:
|
||||
UPower(const std::string &, const Json::Value &);
|
||||
virtual ~UPower();
|
||||
auto update() -> void override;
|
||||
|
||||
private:
|
||||
typedef std::unordered_map<std::string, UpDevice *> Devices;
|
||||
|
||||
const std::string DEFAULT_FORMAT = "{percentage}";
|
||||
const std::string DEFAULT_FORMAT_ALT = "{percentage} {time}";
|
||||
|
||||
static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data);
|
||||
static void deviceRemoved_cb(UpClient *client, const gchar *objectPath, gpointer data);
|
||||
static void deviceNotify_cb(UpDevice *device, GParamSpec *pspec, gpointer user_data);
|
||||
static void prepareForSleep_cb(GDBusConnection *system_bus, const gchar *sender_name,
|
||||
const gchar *object_path, const gchar *interface_name,
|
||||
const gchar *signal_name, GVariant *parameters,
|
||||
gpointer user_data);
|
||||
static void upowerAppear(GDBusConnection *conn, const gchar *name, const gchar *name_owner,
|
||||
gpointer data);
|
||||
static void upowerDisappear(GDBusConnection *connection, const gchar *name, gpointer user_data);
|
||||
|
||||
void removeDevice(const gchar *objectPath);
|
||||
void addDevice(UpDevice *device);
|
||||
void setDisplayDevice();
|
||||
void resetDevices();
|
||||
void removeDevices();
|
||||
bool show_tooltip_callback(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &tooltip);
|
||||
bool handleToggle(GdkEventButton *const &) override;
|
||||
std::string timeToString(gint64 time);
|
||||
|
||||
const std::string getDeviceStatus(UpDeviceState &state);
|
||||
|
||||
Gtk::Box box_;
|
||||
Gtk::Image icon_;
|
||||
Gtk::Label label_;
|
||||
|
||||
// Config
|
||||
bool hideIfEmpty = true;
|
||||
bool tooltip_enabled = true;
|
||||
uint tooltip_spacing = 4;
|
||||
uint tooltip_padding = 4;
|
||||
uint iconSize = 20;
|
||||
std::string format = DEFAULT_FORMAT;
|
||||
std::string format_alt = DEFAULT_FORMAT_ALT;
|
||||
|
||||
Devices devices;
|
||||
std::mutex m_Mutex;
|
||||
UpClient *client;
|
||||
UpDevice *displayDevice = nullptr;
|
||||
guint login1_id;
|
||||
GDBusConnection *login1_connection;
|
||||
std::unique_ptr<UPowerTooltip> upower_tooltip;
|
||||
std::string lastStatus;
|
||||
const char *lastWarningLevel;
|
||||
bool showAltText;
|
||||
bool showIcon = true;
|
||||
bool upowerRunning;
|
||||
guint upowerWatcher_id;
|
||||
std::string nativePath_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::upower
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <libupower-glib/upower.h>
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "gtkmm/box.h"
|
||||
#include "gtkmm/label.h"
|
||||
#include "gtkmm/window.h"
|
||||
|
||||
namespace waybar::modules::upower {
|
||||
|
||||
class UPowerTooltip : public Gtk::Window {
|
||||
private:
|
||||
typedef std::unordered_map<std::string, UpDevice*> Devices;
|
||||
|
||||
const std::string getDeviceIcon(UpDeviceKind& kind);
|
||||
|
||||
std::unique_ptr<Gtk::Box> contentBox;
|
||||
|
||||
uint iconSize;
|
||||
uint tooltipSpacing;
|
||||
uint tooltipPadding;
|
||||
|
||||
public:
|
||||
UPowerTooltip(uint iconSize, uint tooltipSpacing, uint tooltipPadding);
|
||||
virtual ~UPowerTooltip();
|
||||
|
||||
uint updateTooltip(Devices& devices);
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::upower
|
||||
@@ -24,6 +24,10 @@
|
||||
|
||||
namespace waybar::modules::wlr {
|
||||
|
||||
struct widget_geometry {
|
||||
int x, y, w, h;
|
||||
};
|
||||
|
||||
class Taskbar;
|
||||
|
||||
class Task {
|
||||
@@ -42,6 +46,7 @@ class Task {
|
||||
};
|
||||
// made public so TaskBar can reorder based on configuration.
|
||||
Gtk::Button button;
|
||||
struct widget_geometry minimize_hint;
|
||||
|
||||
private:
|
||||
static uint32_t global_id;
|
||||
@@ -82,6 +87,8 @@ class Task {
|
||||
private:
|
||||
std::string repr() const;
|
||||
std::string state_string(bool = false) const;
|
||||
void set_minimize_hint();
|
||||
void on_button_size_allocated(Gtk::Allocation &alloc);
|
||||
void set_app_info_from_app_id_list(const std::string &app_id_list);
|
||||
bool image_load_icon(Gtk::Image &image, const Glib::RefPtr<Gtk::IconTheme> &icon_theme,
|
||||
Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size);
|
||||
|
||||
@@ -56,10 +56,10 @@ class BacklightBackend {
|
||||
|
||||
void set_previous_best_device(const BacklightDevice *device);
|
||||
|
||||
void set_brightness(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(std::string preferred_device, int brightness);
|
||||
int get_scaled_brightness(std::string preferred_device);
|
||||
void set_scaled_brightness(const std::string &preferred_device, int brightness);
|
||||
int get_scaled_brightness(const std::string &preferred_device);
|
||||
|
||||
bool is_login_proxy_initialized() const { return static_cast<bool>(login_proxy_); }
|
||||
|
||||
@@ -70,7 +70,7 @@ class BacklightBackend {
|
||||
std::mutex udev_thread_mutex_;
|
||||
|
||||
private:
|
||||
void set_brightness_internal(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::chrono::milliseconds polling_interval_;
|
||||
|
||||
@@ -622,8 +622,8 @@ inline auto convertInto(std::string const &source, bool &target) -> ParserResult
|
||||
}
|
||||
#ifdef CLARA_CONFIG_OPTIONAL_TYPE
|
||||
template <typename T>
|
||||
inline auto convertInto(std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T> &target)
|
||||
-> ParserResult {
|
||||
inline auto convertInto(std::string const &source,
|
||||
CLARA_CONFIG_OPTIONAL_TYPE<T> &target) -> ParserResult {
|
||||
T temp;
|
||||
auto result = convertInto(source, temp);
|
||||
if (result) target = std::move(temp);
|
||||
@@ -751,8 +751,8 @@ class ParserBase {
|
||||
public:
|
||||
virtual ~ParserBase() = default;
|
||||
virtual auto validate() const -> Result { return Result::ok(); }
|
||||
virtual auto parse(std::string const &exeName, TokenStream const &tokens) const
|
||||
-> InternalParseResult = 0;
|
||||
virtual auto parse(std::string const &exeName,
|
||||
TokenStream const &tokens) const -> InternalParseResult = 0;
|
||||
virtual auto cardinality() const -> size_t { return 1; }
|
||||
|
||||
auto parse(Args const &args) const -> InternalParseResult {
|
||||
@@ -1098,8 +1098,8 @@ struct Parser : ParserBase {
|
||||
|
||||
using ParserBase::parse;
|
||||
|
||||
auto parse(std::string const &exeName, TokenStream const &tokens) const
|
||||
-> InternalParseResult override {
|
||||
auto parse(std::string const &exeName,
|
||||
TokenStream const &tokens) const -> InternalParseResult override {
|
||||
struct ParserInfo {
|
||||
ParserBase const *parser = nullptr;
|
||||
size_t count = 0;
|
||||
|
||||
@@ -64,7 +64,7 @@ struct fmt::formatter<date::zoned_time<Duration, TimeZonePtr>> {
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(const date::zoned_time<Duration, TimeZonePtr>& ztime, FormatContext& ctx) {
|
||||
auto format(const date::zoned_time<Duration, TimeZonePtr>& ztime, FormatContext& ctx) const {
|
||||
if (ctx.locale()) {
|
||||
const auto loc = ctx.locale().template get<std::locale>();
|
||||
return fmt::format_to(ctx.out(), "{}", date::format(loc, fmt::to_string(specs), ztime));
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class pow_format {
|
||||
public:
|
||||
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_;
|
||||
std::string unit_;
|
||||
@@ -45,7 +45,7 @@ struct formatter<pow_format> {
|
||||
}
|
||||
|
||||
template <class FormatContext>
|
||||
auto format(const pow_format& s, FormatContext& ctx) -> decltype(ctx.out()) {
|
||||
auto format(const pow_format& s, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||
const char* units[] = {"", "k", "M", "G", "T", "P", nullptr};
|
||||
|
||||
auto base = s.binary_ ? 1024ull : 1000ll;
|
||||
@@ -92,7 +92,7 @@ struct formatter<pow_format> {
|
||||
template <>
|
||||
struct formatter<Glib::ustring> : formatter<std::string> {
|
||||
template <typename FormatContext>
|
||||
auto format(const Glib::ustring& value, FormatContext& ctx) {
|
||||
auto format(const Glib::ustring& value, FormatContext& ctx) const {
|
||||
return formatter<std::string>::format(static_cast<std::string>(value), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "util/backend_common.hpp"
|
||||
#include "util/pipewire/privacy_node_info.hpp"
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <functional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace waybar::util {
|
||||
|
||||
@@ -17,7 +18,7 @@ struct Rule {
|
||||
// See https://en.cppreference.com/w/cpp/compiler_support/20 "Parenthesized initialization of
|
||||
// aggregates"
|
||||
Rule(std::regex rule, std::string repr, int priority)
|
||||
: rule(rule), repr(repr), priority(priority) {}
|
||||
: rule(std::move(rule)), repr(std::move(repr)), priority(priority) {}
|
||||
};
|
||||
|
||||
int default_priority_function(std::string& key);
|
||||
@@ -36,16 +37,17 @@ class RegexCollection {
|
||||
std::map<std::string, std::string> regex_cache;
|
||||
std::string default_repr;
|
||||
|
||||
std::string& find_match(std::string& value, bool& matched_any);
|
||||
std::string find_match(std::string& value, bool& matched_any);
|
||||
|
||||
public:
|
||||
RegexCollection() = default;
|
||||
RegexCollection(const Json::Value& map, std::string default_repr = "",
|
||||
std::function<int(std::string&)> priority_function = default_priority_function);
|
||||
RegexCollection(
|
||||
const Json::Value& map, std::string default_repr = "",
|
||||
const std::function<int(std::string&)>& priority_function = default_priority_function);
|
||||
~RegexCollection() = default;
|
||||
|
||||
std::string& get(std::string& value, bool& matched_any);
|
||||
std::string& get(std::string& value);
|
||||
};
|
||||
|
||||
} // namespace waybar::util
|
||||
} // namespace waybar::util
|
||||
|
||||
@@ -81,6 +81,19 @@ The *backlight* module displays the current backlight level.
|
||||
default: 1.0 ++
|
||||
The speed at which to change the brightness when scrolling.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLE:
|
||||
|
||||
```
|
||||
|
||||
@@ -109,6 +109,19 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
||||
default: false ++
|
||||
Option to enable battery compatibility if not detected.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{capacity}*: Capacity in percentage
|
||||
|
||||
@@ -129,6 +129,19 @@ Addressed by *bluetooth*
|
||||
typeof: string ++
|
||||
This format is used to define how each connected device should be displayed within the *device_enumerate* format replacement in the tooltip menu.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{status}*: Status of the bluetooth device.
|
||||
|
||||
@@ -120,6 +120,18 @@ libcava lives in:
|
||||
:[ string
|
||||
:[ /dev/stdout
|
||||
:[ It's impossible to set it. Waybar sets it to = /dev/stdout for internal needs
|
||||
|[ *menu*
|
||||
:[ string
|
||||
:[
|
||||
:[ Action that popups the menu.
|
||||
|[ *menu-file*
|
||||
:[ string
|
||||
:[
|
||||
:[ Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
|
||||
|[ *menu-actions*
|
||||
:[ array
|
||||
:[
|
||||
:[ The actions corresponding to the buttons of the menu.
|
||||
|
||||
Configuration can be provided as:
|
||||
- The only cava configuration file which is provided through *cava_config*. The rest configuration can be skipped
|
||||
|
||||
@@ -84,6 +84,18 @@ $XDG_CONFIG_HOME/waybar/config ++
|
||||
:[ string
|
||||
:[ same as format
|
||||
:[ Tooltip on hover
|
||||
|[ *menu*
|
||||
:[ string
|
||||
:[
|
||||
:[ Action that popups the menu.
|
||||
|[ *menu-file*
|
||||
:[ string
|
||||
:[
|
||||
:[ Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
|
||||
|[ *menu-actions*
|
||||
:[ array
|
||||
:[
|
||||
:[ The actions corresponding to the buttons of the menu.
|
||||
|
||||
View all valid format options in *strftime(3)* or have a look https://en.cppreference.com/w/cpp/chrono/duration/formatter
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ Addressed by *custom/<name>*
|
||||
The path to a script, which determines if the script in *exec* should be executed. ++
|
||||
*exec* will be executed if the exit code of *exec-if* equals 0.
|
||||
|
||||
*hide-empty-text*: ++
|
||||
typeof: bool ++
|
||||
Disables the module when output is empty, but format might contain additional static content.
|
||||
|
||||
*exec-on-event*: ++
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
@@ -121,6 +125,19 @@ Addressed by *custom/<name>*
|
||||
default: false ++
|
||||
Option to enable escaping of script output.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# RETURN-TYPE
|
||||
|
||||
When *return-type* is set to *json*, Waybar expects the *exec*-script to output its data in JSON format.
|
||||
|
||||
@@ -93,6 +93,19 @@ Addressed by *disk*
|
||||
typeof: string ++
|
||||
Use with specific_free, specific_used, and specific_total to force calculation to always be in a certain unit. Accepts kB, kiB, MB, Mib, GB, GiB, TB, TiB.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{percentage_used}*: Percentage of disk in use.
|
||||
|
||||
@@ -25,6 +25,19 @@ Addressed by *hyprland/language*
|
||||
typeof: string ++
|
||||
Specifies which keyboard to use from hyprctl devices output. Using the option that begins with "at-translated-set..." is recommended.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
|
||||
@@ -80,6 +80,19 @@ Addressed by *hyprland/submap*
|
||||
default: Default ++
|
||||
Option to set the submap name to display when not in an active submap.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ Addressed by *hyprland/workspaces*
|
||||
Regex rules to map window class to an icon or preferred method of representation for a workspace's window.
|
||||
Keys are the rules, while the values are the methods of representation. Values may use the placeholders {class} and {title} to use the window's original class and/or title respectively.
|
||||
Rules may specify `class<...>`, `title<...>`, or both in order to fine-tune the matching.
|
||||
You may assign an empty value to a rule to have it ignored from generating any representation in workspaces.
|
||||
|
||||
*window-rewrite-default*:
|
||||
typeof: string ++
|
||||
@@ -42,6 +43,11 @@ Addressed by *hyprland/workspaces*
|
||||
default: false ++
|
||||
If set to true, special workspaces will be shown.
|
||||
|
||||
*special-visible-only*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If this and show-special are to true, special workspaces will be shown only if visible.
|
||||
|
||||
*all-outputs*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
@@ -142,6 +148,7 @@ Additional to workspace name matching, the following *format-icons* can be set.
|
||||
"class<firefox> title<.*github.*>": "", // Windows whose class is "firefox" and title contains "github". Note that "class" always comes first.
|
||||
"foot": "", // Windows that contain "foot" in either class or title. For optimization reasons, it will only match against a title if at least one other window explicitly matches against a title.
|
||||
"code": "",
|
||||
"title<.* - (.*) - VSCodium>": "codium $1" // captures part of the window title and formats it into output
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -89,6 +89,19 @@ screensaver, also known as "presentation mode".
|
||||
typeof: string ++
|
||||
This format is used when the inhibit is deactivated.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu. Cannot be "on-click".
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{status}*: status (*activated* or *deactivated*)
|
||||
|
||||
@@ -76,6 +76,19 @@ See *systemd-inhibit*(1) for more information.
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu. Cannot be "on-click".
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{status}*: status (*activated* or *deactivated*)
|
||||
|
||||
@@ -85,6 +85,19 @@ Addressed by *jack*
|
||||
typeof: string ++
|
||||
Command to execute when the module is updated.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{load}*: The current CPU load estimated by JACK.
|
||||
|
||||
@@ -84,6 +84,19 @@ Addressed by *memory*
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{percentage}*: Percentage of memory in use.
|
||||
|
||||
153
man/waybar-menu.5.scd
Normal file
153
man/waybar-menu.5.scd
Normal file
@@ -0,0 +1,153 @@
|
||||
waybar-menu(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - menu property
|
||||
|
||||
# OVERVIEW
|
||||
|
||||
|
||||
Some modules support a 'menu', which allows to have a popup menu whan a defined
|
||||
click is done over the module.
|
||||
|
||||
# PROPERTIES
|
||||
|
||||
A module that implements a 'menu' needs 3 properties defined in its config :
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu. The possibles actions are :
|
||||
|
||||
[- *Option*
|
||||
:- *Description*
|
||||
|[ *on-click*
|
||||
:< When you left-click on the module
|
||||
|[ *on-click-release*
|
||||
:< When you release left button on the module
|
||||
|[ *on-double-click*
|
||||
:< When you double left click on the module
|
||||
|[ *on-triple-click*
|
||||
:< When you triple left click on the module
|
||||
|[ *on-click-middle*
|
||||
:< When you middle click on the module using mousewheel
|
||||
|[ *on-click-middle-release*
|
||||
:< When you release mousewheel button on the module
|
||||
|[ *on-double-click-middle*
|
||||
:< When you double middle click on the module
|
||||
|[ *on-triple-click-middle*
|
||||
:< When you triple middle click on the module
|
||||
|[ *on-click-right*
|
||||
:< When you right click on the module using
|
||||
|[ *on-click-right-release*
|
||||
:< When you release right button on the module
|
||||
|[ *on-double-click-right*
|
||||
:< When you double right click on the module
|
||||
|[ *on-triple-click-right*
|
||||
:< When you triple middle click on the module
|
||||
|[ *on-click-backward*
|
||||
:< When you click on the module using mouse backward button
|
||||
|[ *on-click-backward-release*
|
||||
:< When you release mouse backward button on the module
|
||||
|[ *on-double-click-backward*
|
||||
:< When you double click on the module using mouse backward button
|
||||
|[ *on-triple-click-backward*
|
||||
:< When you triple click on the module using mouse backawrd button
|
||||
|[ *on-click-forward*
|
||||
:< When you click on the module using mouse forward button
|
||||
|[ *on-click-forward-release*
|
||||
:< When you release mouse forward button on the module
|
||||
|[ *on-double-click-forward*
|
||||
:< When you double click on the module using mouse forward button
|
||||
|[ *on-triple-click-forward*
|
||||
:< When you triple click on the module using mouse forward button
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*.
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu. The identifiers of
|
||||
each actions needs to exists as an id in the 'menu-file' for it to be linked
|
||||
properly.
|
||||
|
||||
# MENU-FILE
|
||||
|
||||
The menu-file is an `.xml` file representing a GtkBuilder. Documentation for it
|
||||
can be found here : https://docs.gtk.org/gtk4/class.Builder.html
|
||||
|
||||
Here, it needs to have an element of type GtkMenu with id "menu". Eeach actions
|
||||
in *menu-actions* are linked to elements in the *menu-file* file by the id of
|
||||
the elements.
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
Module config :
|
||||
```
|
||||
"custom/power": {
|
||||
"format" : "⏻ ",
|
||||
"tooltip": false,
|
||||
"menu": "on-click",
|
||||
"menu-file": "~/.config/waybar/power_menu.xml",
|
||||
"menu-actions": {
|
||||
"shutdown": "shutdown",
|
||||
"reboot": "reboot",
|
||||
"suspend": "systemctl suspend",
|
||||
"hibernate": "systemctl hibernate",
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
~/.config/waybar/power_menu.xml :
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkMenu" id="menu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="suspend">
|
||||
<property name="label">Suspend</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="hibernat">
|
||||
<property name="label">Hibernate</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="shutdown">
|
||||
<property name="label">Shutdown</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="delimiter1"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="reboot">
|
||||
<property name="label">Reboot</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
```
|
||||
|
||||
# STYLING MENUS
|
||||
|
||||
- *menu*
|
||||
Style for the menu
|
||||
|
||||
- *menuitem*
|
||||
Style for items in the menu
|
||||
|
||||
# EXAMPLE:
|
||||
|
||||
```
|
||||
menu {
|
||||
border-radius: 15px;
|
||||
background: #161320;
|
||||
color: #B5E8E0;
|
||||
}
|
||||
menuitem {
|
||||
border-radius: 15px;
|
||||
}
|
||||
```
|
||||
@@ -162,6 +162,19 @@ Addressed by *mpd*
|
||||
default: {} ++
|
||||
Icon to show depending on the "single" option (*{ "on": "...", "off": "..." }*)
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
## WHEN PLAYING/PAUSED
|
||||
|
||||
@@ -142,11 +142,11 @@ The *mpris* module displays currently playing media via libplayerctl.
|
||||
|
||||
*player-icons*: ++
|
||||
typeof: map[string]string ++
|
||||
Allows setting _{player-icon}_ based on player-name property.
|
||||
Allows setting _{player_icon}_ based on player-name property.
|
||||
|
||||
*status-icons*: ++
|
||||
typeof: map[string]string ++
|
||||
Allows setting _{status-icon}_ based on player status (playing, paused, stopped).
|
||||
Allows setting _{status_icon}_ based on player status (playing, paused, stopped).
|
||||
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
@@ -129,6 +129,19 @@ Addressed by *network*
|
||||
typeof: string ++
|
||||
This format is used when the displayed interface is disabled.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{ifname}*: Name of the network interface.
|
||||
@@ -143,6 +156,8 @@ Addressed by *network*
|
||||
|
||||
*{essid}*: Name (SSID) of the wireless network.
|
||||
|
||||
*{bssid}*: MAC address (BSSID) of the wireless access point.
|
||||
|
||||
*{signalStrength}*: Signal strength of the wireless network.
|
||||
|
||||
*{signaldBm}*: Signal strength of the wireless network in dBm.
|
||||
|
||||
58
man/waybar-niri-language.5.scd
Normal file
58
man/waybar-niri-language.5.scd
Normal file
@@ -0,0 +1,58 @@
|
||||
waybar-niri-language(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - niri language module
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
The *language* module displays the currently selected language in niri.
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
Addressed by *niri/language*
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {} ++
|
||||
The format, how information should be displayed.
|
||||
|
||||
*format-<lang>* ++
|
||||
typeof: string++
|
||||
Provide an alternative name to display per language where <lang> is the language of your choosing. Can be passed multiple times with multiple languages as shown by the example below.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{short}*: Short name of layout (e.g. "us"). Equals to {}.
|
||||
|
||||
*{shortDescription}*: Short description of layout (e.g. "en").
|
||||
|
||||
*{long}*: Long name of layout (e.g. "English (Dvorak)").
|
||||
|
||||
*{variant}*: Variant of layout (e.g. "dvorak").
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
"niri/language": {
|
||||
"format": "Lang: {long}"
|
||||
"format-en": "AMERICA, HELL YEAH!"
|
||||
"format-tr": "As bayrakları"
|
||||
}
|
||||
```
|
||||
|
||||
# STYLE
|
||||
|
||||
- *#language*
|
||||
81
man/waybar-niri-window.5.scd
Normal file
81
man/waybar-niri-window.5.scd
Normal file
@@ -0,0 +1,81 @@
|
||||
waybar-niri-window(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - niri window module
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
The *window* module displays the title of the currently focused window in niri.
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
Addressed by *niri/window*
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {title} ++
|
||||
The format, how information should be displayed. On {} the current window title is displayed.
|
||||
|
||||
*rewrite*: ++
|
||||
typeof: object ++
|
||||
Rules to rewrite window title. See *rewrite rules*.
|
||||
|
||||
*separate-outputs*: ++
|
||||
typeof: bool ++
|
||||
Show the active window of the monitor the bar belongs to, instead of the focused window.
|
||||
|
||||
*icon*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Option to hide the application icon.
|
||||
|
||||
*icon-size*: ++
|
||||
typeof: integer ++
|
||||
default: 24 ++
|
||||
Option to change the size of the application icon.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
See the output of "niri msg windows" for examples
|
||||
|
||||
*{title}*: The current title of the focused window.
|
||||
|
||||
*{app_id}*: The current app ID of the focused window.
|
||||
|
||||
# REWRITE RULES
|
||||
|
||||
*rewrite* is an object where keys are regular expressions and values are
|
||||
rewrite rules if the expression matches. Rules may contain references to
|
||||
captures of the expression.
|
||||
|
||||
Regular expression and replacement follow ECMA-script rules.
|
||||
|
||||
If no expression matches, the title is left unchanged.
|
||||
|
||||
Invalid expressions (e.g., mismatched parentheses) are skipped.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
"niri/window": {
|
||||
"format": "{}",
|
||||
"rewrite": {
|
||||
"(.*) - Mozilla Firefox": "🌎 $1",
|
||||
"(.*) - zsh": "> [$1]"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# STYLE
|
||||
|
||||
- *#window*
|
||||
- *window#waybar.empty #window* When no windows are on the workspace
|
||||
|
||||
The following classes are applied to the entire Waybar rather than just the
|
||||
window widget:
|
||||
|
||||
- *window#waybar.empty* When no windows are in the workspace
|
||||
- *window#waybar.solo* When only one window is on the workspace
|
||||
- *window#waybar.<app-id>* Where *app-id* is the app ID of the only window on
|
||||
the workspace
|
||||
97
man/waybar-niri-workspaces.5.scd
Normal file
97
man/waybar-niri-workspaces.5.scd
Normal file
@@ -0,0 +1,97 @@
|
||||
waybar-niri-workspaces(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - niri workspaces module
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
The *workspaces* module displays the currently used workspaces in niri.
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
Addressed by *niri/workspaces*
|
||||
|
||||
*all-outputs*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If set to false, workspaces will only be shown on the output they are on. If set to true all workspaces will be shown on every output.
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {value} ++
|
||||
The format, how information should be displayed.
|
||||
|
||||
*format-icons*: ++
|
||||
typeof: array ++
|
||||
Based on the workspace name, index and state, the corresponding icon gets selected. See *icons*.
|
||||
|
||||
*disable-click*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If set to false, you can click to change workspace. If set to true this behaviour is disabled.
|
||||
|
||||
*disable-markup*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If set to true, button label will escape pango markup.
|
||||
|
||||
*current-only*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If set to true, only the active or focused workspace will be shown.
|
||||
|
||||
*on-update*: ++
|
||||
typeof: string ++
|
||||
Command to execute when the module is updated.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{value}*: Name of the workspace, or index for unnamed workspaces,
|
||||
as defined by niri.
|
||||
|
||||
*{name}*: Name of the workspace for named workspaces.
|
||||
|
||||
*{icon}*: Icon, as defined in *format-icons*.
|
||||
|
||||
*{index}*: Index of the workspace on its output.
|
||||
|
||||
*{output}*: Output where the workspace is located.
|
||||
|
||||
# ICONS
|
||||
|
||||
Additional to workspace name matching, the following *format-icons* can be set.
|
||||
|
||||
- *default*: Will be shown, when no string matches are found.
|
||||
- *focused*: Will be shown, when workspace is focused.
|
||||
- *active*: Will be shown, when workspace is active on its output.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
"niri/workspaces": {
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
// Named workspaces
|
||||
// (you need to configure them in niri)
|
||||
"browser": "",
|
||||
"discord": "",
|
||||
"chat": "<b></b>",
|
||||
|
||||
// Icons by state
|
||||
"active": "",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Style
|
||||
|
||||
- *#workspaces button*
|
||||
- *#workspaces button.focused*: The single focused workspace.
|
||||
- *#workspaces button.active*: The workspace is active (visible) on its output.
|
||||
- *#workspaces button.empty*: The workspace is empty.
|
||||
- *#workspaces button.current_output*: The workspace is from the same output as
|
||||
the bar that it is displayed on.
|
||||
- *#workspaces button#niri-workspace-<name>*: Workspaces named this, or index
|
||||
for unnamed workspaces.
|
||||
@@ -31,7 +31,7 @@ The volume can be controlled by dragging the slider across the bar or clicking o
|
||||
|
||||
```
|
||||
"modules-right": [
|
||||
"pulseaudio-slider",
|
||||
"pulseaudio/slider",
|
||||
],
|
||||
"pulseaudio/slider": {
|
||||
"min": 0,
|
||||
|
||||
@@ -113,6 +113,19 @@ Additionally, you can control the volume by scrolling *up* or *down* while the c
|
||||
typeof: array ++
|
||||
Sinks in this list will not be shown as active sink by Waybar. Entries should be the sink's description field.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{desc}*: Pulseaudio port's description, for bluetooth it'll be the device name.
|
||||
@@ -142,6 +155,8 @@ If they are found in the current PulseAudio port name, the corresponding icons w
|
||||
- *hifi*
|
||||
- *phone*
|
||||
|
||||
Additionally, suffixing a device name or port with *-muted* will cause the icon
|
||||
to be selected when the corresponding audio device is muted. This applies to *default* as well.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
@@ -152,10 +167,12 @@ If they are found in the current PulseAudio port name, the corresponding icons w
|
||||
"format-muted": "",
|
||||
"format-icons": {
|
||||
"alsa_output.pci-0000_00_1f.3.analog-stereo": "",
|
||||
"alsa_output.pci-0000_00_1f.3.analog-stereo-muted": "",
|
||||
"headphones": "",
|
||||
"handsfree": "",
|
||||
"headset": "",
|
||||
"phone": "",
|
||||
"phone-muted": "",
|
||||
"portable": "",
|
||||
"car": "",
|
||||
"default": ["", ""]
|
||||
|
||||
@@ -51,6 +51,19 @@ Addressed by *river/layout*
|
||||
typeof: string ++
|
||||
Command to execute when you right-click on the module.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
```
|
||||
|
||||
@@ -65,6 +65,19 @@ Addressed by *river/mode*
|
||||
typeof: double ++
|
||||
Threshold to be used when scrolling.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
||||
@@ -49,6 +49,19 @@ Addressed by *river/window*
|
||||
typeof: string ++
|
||||
Command to execute when you right-click on the module.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
||||
@@ -74,6 +74,19 @@ cursor is over the module, and clicking on the module toggles mute.
|
||||
typeof: double ++
|
||||
Threshold to be used when scrolling.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{volume}*: Volume in percentage.
|
||||
|
||||
@@ -39,6 +39,40 @@ You can apply special styling to any module for when the cursor hovers it.
|
||||
}
|
||||
```
|
||||
|
||||
## Setting cursor style
|
||||
|
||||
Most, if not all, module types support setting the `cursor` option. This is
|
||||
configured in your `config.jsonc`. If set to `false`, when hovering the module a
|
||||
"pointer"(as commonly known from web CSS styling `cursor: pointer`) style cursor
|
||||
will not be shown. Default behavior is to indicate an interaction event is
|
||||
available.
|
||||
|
||||
There are more cursor types to choose from by setting the `cursor` option to
|
||||
a number, see Gdk3 official docs for all possible cursor types:
|
||||
https://docs.gtk.org/gdk3/enum.CursorType.html.
|
||||
However, note that not all cursor options listed may be available on
|
||||
your system. If you attempt to use a cursor which is not available, the
|
||||
application will crash.
|
||||
|
||||
Example of disabling pointer(`Gdk::Hand2`) cursor type on a custom module:
|
||||
|
||||
```
|
||||
"custom/my-custom-module": {
|
||||
...
|
||||
"cursor": false,
|
||||
}
|
||||
```
|
||||
|
||||
Example of setting cursor type to `Gdk::Boat`(according to
|
||||
https://docs.gtk.org/gdk3/enum.CursorType.html#boat):
|
||||
|
||||
```
|
||||
"custom/my-custom-module": {
|
||||
...
|
||||
"cursor": 8,
|
||||
}
|
||||
```
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
- *waybar(5)*
|
||||
|
||||
@@ -32,6 +32,19 @@ Addressed by *sway/language*
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{short}*: Short name of layout (e.g. "us"). Equals to {}.
|
||||
|
||||
@@ -70,6 +70,19 @@ Addressed by *sway/mode*
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
|
||||
@@ -36,6 +36,19 @@ Addressed by *sway/scratchpad*
|
||||
default: {app}: {title} ++
|
||||
The format, how information in the tooltip should be displayed.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{icon}*: Icon, as defined in *format-icons*.
|
||||
|
||||
@@ -87,6 +87,7 @@ warp-on-scroll: ++
|
||||
Regex rules to map window class to an icon or preferred method of representation for a workspace's window.
|
||||
Keys are the rules, while the values are the methods of representation.
|
||||
Rules may specify `class<...>`, `title<...>`, or both in order to fine-tune the matching.
|
||||
You may assign an empty value to a rule to have it ignored from generating any representation in workspaces.
|
||||
|
||||
*window-rewrite-default*:
|
||||
typeof: string ++
|
||||
@@ -171,6 +172,7 @@ n.b.: the list of outputs can be obtained from command line using *swaymsg -t ge
|
||||
"window-rewrite": {
|
||||
"class<firefox>": "",
|
||||
"class<kitty>": "k",
|
||||
"title<.* - (.*) - VSCodium>": "codium $1" // captures part of the window title and formats it into output
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -36,6 +36,19 @@ Addressed by *systemd-failed-units*
|
||||
default: *true* ++
|
||||
Option to hide this module when there is no failing units.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{nr_failed_system}*: Number of failed units from systemwide (PID=1) systemd.
|
||||
|
||||
@@ -25,6 +25,7 @@ Addressed by *temperature*
|
||||
*hwmon-path-abs*: ++
|
||||
typeof: string ++
|
||||
The path of the hwmon-directory of the device, e.g. */sys/devices/pci0000:00/0000:00:18.3/hwmon*. (Note that the subdirectory *hwmon/hwmon#*, where *#* is a number is not part of the path!) Has to be used together with *input-filename*.
|
||||
This can also be an array of strings, for which, it just works like *hwmon-path*.
|
||||
|
||||
*input-filename*: ++
|
||||
typeof: string ++
|
||||
@@ -110,6 +111,19 @@ Addressed by *temperature*
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{temperatureC}*: Temperature in Celsius.
|
||||
|
||||
@@ -17,6 +17,12 @@ compatible devices in the tooltip.
|
||||
The battery to monitor. Refer to the https://upower.freedesktop.org/docs/UpDevice.html#UpDevice--native-path ++
|
||||
Can be obtained using `upower --dump`
|
||||
|
||||
*model*: ++
|
||||
typeof: string ++
|
||||
default: ++
|
||||
The battery to monitor, based on the model. (this option is ignored if *native-path* is given). ++
|
||||
Can be obtained using `upower --dump`
|
||||
|
||||
*icon-size*: ++
|
||||
typeof: integer ++
|
||||
default: 20 ++
|
||||
@@ -62,6 +68,19 @@ compatible devices in the tooltip.
|
||||
default: true ++
|
||||
Option to disable battery icon.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{percentage}*: The battery capacity in percentage
|
||||
|
||||
@@ -87,6 +87,19 @@ The *wireplumber* module displays the current volume reported by WirePlumber.
|
||||
default: 100 ++
|
||||
The maximum volume that can be set, in percentage.
|
||||
|
||||
*menu*: ++
|
||||
typeof: string ++
|
||||
Action that popups the menu.
|
||||
|
||||
*menu-file*: ++
|
||||
typeof: string ++
|
||||
Location of the menu descriptor file. There need to be an element of type
|
||||
GtkMenu with id *menu*
|
||||
|
||||
*menu-actions*: ++
|
||||
typeof: array ++
|
||||
The actions corresponding to the buttons of the menu.
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{volume}*: Volume in percentage.
|
||||
|
||||
@@ -278,6 +278,11 @@ A group may hide all but one element, showing them only on mouse hover. In order
|
||||
default: "hidden" ++
|
||||
Defines the CSS class to be applied to the hidden elements.
|
||||
|
||||
*click-to-reveal*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Whether left click should reveal the content rather than mouse over. Note that grouped modules may still process their own on-click events.
|
||||
|
||||
*transition-left-to-right*: ++
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
@@ -318,6 +323,9 @@ A group may hide all but one element, showing them only on mouse hover. In order
|
||||
- *waybar-hyprland-submap(5)*
|
||||
- *waybar-hyprland-window(5)*
|
||||
- *waybar-hyprland-workspaces(5)*
|
||||
- *waybar-niri-language(5)*
|
||||
- *waybar-niri-window(5)*
|
||||
- *waybar-niri-workspaces(5)*
|
||||
- *waybar-idle-inhibitor(5)*
|
||||
- *waybar-image(5)*
|
||||
- *waybar-inhibitor(5)*
|
||||
|
||||
29
meson.build
29
meson.build
@@ -1,6 +1,6 @@
|
||||
project(
|
||||
'waybar', 'cpp', 'c',
|
||||
version: '0.10.1',
|
||||
version: '0.11.0',
|
||||
license: 'MIT',
|
||||
meson_version: '>= 0.59.0',
|
||||
default_options : [
|
||||
@@ -69,7 +69,7 @@ is_openbsd = host_machine.system() == 'openbsd'
|
||||
|
||||
thread_dep = dependency('threads')
|
||||
fmt = dependency('fmt', version : ['>=8.1.1'], fallback : ['fmt', 'fmt_dep'])
|
||||
spdlog = dependency('spdlog', version : ['>=1.10.0'], fallback : ['spdlog', 'spdlog_dep'], default_options : ['external_fmt=enabled'])
|
||||
spdlog = dependency('spdlog', version : ['>=1.10.0'], fallback : ['spdlog', 'spdlog_dep'], default_options : ['external_fmt=enabled', 'std_format=disabled', 'tests=disabled'])
|
||||
wayland_client = dependency('wayland-client')
|
||||
wayland_cursor = dependency('wayland-cursor')
|
||||
wayland_protos = dependency('wayland-protocols')
|
||||
@@ -192,6 +192,7 @@ man_files = files(
|
||||
'man/waybar-idle-inhibitor.5.scd',
|
||||
'man/waybar-image.5.scd',
|
||||
'man/waybar-states.5.scd',
|
||||
'man/waybar-menu.5.scd',
|
||||
'man/waybar-temperature.5.scd',
|
||||
)
|
||||
|
||||
@@ -305,7 +306,9 @@ if true
|
||||
'src/modules/hyprland/language.cpp',
|
||||
'src/modules/hyprland/submap.cpp',
|
||||
'src/modules/hyprland/window.cpp',
|
||||
'src/modules/hyprland/workspace.cpp',
|
||||
'src/modules/hyprland/workspaces.cpp',
|
||||
'src/modules/hyprland/windowcreationpayload.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-hyprland-language.5.scd',
|
||||
@@ -315,6 +318,21 @@ if true
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('niri')
|
||||
add_project_arguments('-DHAVE_NIRI', language: 'cpp')
|
||||
src_files += files(
|
||||
'src/modules/niri/backend.cpp',
|
||||
'src/modules/niri/language.cpp',
|
||||
'src/modules/niri/window.cpp',
|
||||
'src/modules/niri/workspaces.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-niri-language.5.scd',
|
||||
'man/waybar-niri-window.5.scd',
|
||||
'man/waybar-niri-workspaces.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if libnl.found() and libnlgen.found()
|
||||
add_project_arguments('-DHAVE_LIBNL', language: 'cpp')
|
||||
src_files += files('src/modules/network.cpp')
|
||||
@@ -335,10 +353,7 @@ endif
|
||||
|
||||
if (upower_glib.found() and not get_option('logind').disabled())
|
||||
add_project_arguments('-DHAVE_UPOWER', language: 'cpp')
|
||||
src_files += files(
|
||||
'src/modules/upower/upower.cpp',
|
||||
'src/modules/upower/upower_tooltip.cpp',
|
||||
)
|
||||
src_files += files('src/modules/upower.cpp')
|
||||
man_files += files('man/waybar-upower.5.scd')
|
||||
endif
|
||||
|
||||
@@ -467,7 +482,7 @@ if get_option('experimental')
|
||||
endif
|
||||
|
||||
cava = dependency('cava',
|
||||
version : '>=0.10.1',
|
||||
version : '>=0.10.2',
|
||||
required: get_option('cava'),
|
||||
fallback : ['cava', 'cava_dep'],
|
||||
not_found_message: 'cava is not found. Building waybar without cava')
|
||||
|
||||
@@ -19,3 +19,4 @@ option('experimental', type : 'boolean', value : false, description: 'Enable exp
|
||||
option('jack', type: 'feature', value: 'auto', description: 'Enable support for JACK')
|
||||
option('wireplumber', type: 'feature', value: 'auto', description: 'Enable support for WirePlumber')
|
||||
option('cava', type: 'feature', value: 'auto', description: 'Enable support for Cava')
|
||||
option('niri', type: 'boolean', description: 'Enable support for niri')
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
}:
|
||||
let
|
||||
libcava = rec {
|
||||
version = "0.10.1";
|
||||
version = "0.10.2";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "LukashonakV";
|
||||
repo = "cava";
|
||||
rev = version;
|
||||
hash = "sha256-iIYKvpOWafPJB5XhDOSIW9Mb4I3A4pcgIIPQdQYEqUw=";
|
||||
hash = "sha256-jU7RQV2txruu/nUUl0TzjK4nai7G38J1rcTjO7UXumY=";
|
||||
};
|
||||
};
|
||||
in
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
"battery",
|
||||
"battery#bat2",
|
||||
"clock",
|
||||
"tray"
|
||||
"tray",
|
||||
"custom/power"
|
||||
],
|
||||
// Modules configuration
|
||||
// "sway/workspaces": {
|
||||
@@ -198,5 +199,17 @@
|
||||
"escape": true,
|
||||
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
|
||||
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
|
||||
},
|
||||
"custom/power": {
|
||||
"format" : "⏻ ",
|
||||
"tooltip": false,
|
||||
"menu": "on-click",
|
||||
"menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder
|
||||
"menu-actions": {
|
||||
"shutdown": "shutdown",
|
||||
"reboot": "reboot",
|
||||
"suspend": "systemctl suspend",
|
||||
"hibernate": "systemctl hibernate"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ class PlayerManager:
|
||||
player_name = player.props.player_name
|
||||
artist = player.get_artist()
|
||||
title = player.get_title()
|
||||
title = title.replace("&", "&")
|
||||
|
||||
track_info = ""
|
||||
if player_name == "spotify" and "mpris:trackid" in metadata.keys() and ":ad:" in player.props.metadata["mpris:trackid"]:
|
||||
@@ -136,6 +137,10 @@ class PlayerManager:
|
||||
|
||||
def on_player_appeared(self, _, player):
|
||||
logger.info(f"Player has appeared: {player.name}")
|
||||
if player.name in self.excluded_player:
|
||||
logger.debug(
|
||||
"New player appeared, but it's in exclude player list, skipping")
|
||||
return
|
||||
if player is not None and (self.selected_player is None or player.name == self.selected_player):
|
||||
self.init_player(player)
|
||||
else:
|
||||
|
||||
28
resources/custom_modules/power_menu.xml
Normal file
28
resources/custom_modules/power_menu.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkMenu" id="menu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="suspend">
|
||||
<property name="label">Suspend</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="hibernate">
|
||||
<property name="label">Hibernate</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="shutdown">
|
||||
<property name="label">Shutdown</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="delimiter1"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="reboot">
|
||||
<property name="label">Reboot</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -96,14 +96,14 @@ std::optional<Glib::ustring> getIconName(const std::string& app_identifier,
|
||||
return app_identifier;
|
||||
}
|
||||
|
||||
const auto app_identifier_desktop = app_identifier + "-desktop";
|
||||
auto app_identifier_desktop = app_identifier + "-desktop";
|
||||
if (DefaultGtkIconThemeWrapper::has_icon(app_identifier_desktop)) {
|
||||
return app_identifier_desktop;
|
||||
}
|
||||
|
||||
const auto first_space = app_identifier.find_first_of(' ');
|
||||
auto first_space = app_identifier.find_first_of(' ');
|
||||
if (first_space != std::string::npos) {
|
||||
const auto first_word = toLowerCase(app_identifier.substr(0, first_space));
|
||||
auto first_word = toLowerCase(app_identifier.substr(0, first_space));
|
||||
if (DefaultGtkIconThemeWrapper::has_icon(first_word)) {
|
||||
return first_word;
|
||||
}
|
||||
@@ -111,7 +111,7 @@ std::optional<Glib::ustring> getIconName(const std::string& app_identifier,
|
||||
|
||||
const auto first_dash = app_identifier.find_first_of('-');
|
||||
if (first_dash != std::string::npos) {
|
||||
const auto first_word = toLowerCase(app_identifier.substr(0, first_dash));
|
||||
auto first_word = toLowerCase(app_identifier.substr(0, first_dash));
|
||||
if (DefaultGtkIconThemeWrapper::has_icon(first_word)) {
|
||||
return first_word;
|
||||
}
|
||||
|
||||
@@ -2,14 +2,20 @@
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <util/command.hpp>
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
namespace waybar {
|
||||
|
||||
ALabel::ALabel(const Json::Value& config, const std::string& name, const std::string& id,
|
||||
const std::string& format, uint16_t interval, bool ellipsize, bool enable_click,
|
||||
bool enable_scroll)
|
||||
: AModule(config, name, id, config["format-alt"].isString() || enable_click, enable_scroll),
|
||||
: AModule(config, name, id,
|
||||
config["format-alt"].isString() || config["menu"].isString() || enable_click,
|
||||
enable_scroll),
|
||||
format_(config_["format"].isString() ? config_["format"].asString() : format),
|
||||
interval_(config_["interval"] == "once"
|
||||
? std::chrono::seconds::max()
|
||||
@@ -51,6 +57,55 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
|
||||
}
|
||||
}
|
||||
|
||||
// If a GTKMenu is requested in the config
|
||||
if (config_["menu"].isString()) {
|
||||
// Create the GTKMenu widget
|
||||
try {
|
||||
// Check that the file exists
|
||||
std::string menuFile = config_["menu-file"].asString();
|
||||
|
||||
// there might be "~" or "$HOME" in original path, try to expand it.
|
||||
auto result = Config::tryExpandPath(menuFile, "");
|
||||
if (!result.has_value()) {
|
||||
throw std::runtime_error("Failed to expand file: " + menuFile);
|
||||
}
|
||||
|
||||
menuFile = result.value();
|
||||
// Read the menu descriptor file
|
||||
std::ifstream file(menuFile);
|
||||
if (!file.is_open()) {
|
||||
throw std::runtime_error("Failed to open file: " + menuFile);
|
||||
}
|
||||
std::stringstream fileContent;
|
||||
fileContent << file.rdbuf();
|
||||
GtkBuilder* builder = gtk_builder_new();
|
||||
|
||||
// Make the GtkBuilder and check for errors in his parsing
|
||||
if (gtk_builder_add_from_string(builder, fileContent.str().c_str(), -1, nullptr) == 0U) {
|
||||
throw std::runtime_error("Error found in the file " + menuFile);
|
||||
}
|
||||
|
||||
menu_ = gtk_builder_get_object(builder, "menu");
|
||||
if (menu_ == nullptr) {
|
||||
throw std::runtime_error("Failed to get 'menu' object from GtkBuilder");
|
||||
}
|
||||
submenus_ = std::map<std::string, GtkMenuItem*>();
|
||||
menuActionsMap_ = std::map<std::string, std::string>();
|
||||
|
||||
// Linking actions to the GTKMenu based on
|
||||
for (Json::Value::const_iterator it = config_["menu-actions"].begin();
|
||||
it != config_["menu-actions"].end(); ++it) {
|
||||
std::string key = it.key().asString();
|
||||
submenus_[key] = GTK_MENU_ITEM(gtk_builder_get_object(builder, key.c_str()));
|
||||
menuActionsMap_[key] = it->asString();
|
||||
g_signal_connect(submenus_[key], "activate", G_CALLBACK(handleGtkMenuEvent),
|
||||
(gpointer)menuActionsMap_[key].c_str());
|
||||
}
|
||||
} catch (std::runtime_error& e) {
|
||||
spdlog::warn("Error while creating the menu : {}. Menu popup not activated.", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
if (config_["justify"].isString()) {
|
||||
auto justify_str = config_["justify"].asString();
|
||||
if (justify_str == "left") {
|
||||
@@ -76,7 +131,7 @@ std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_
|
||||
}
|
||||
if (format_icons.isArray()) {
|
||||
auto size = format_icons.size();
|
||||
if (size) {
|
||||
if (size != 0U) {
|
||||
auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1);
|
||||
format_icons = format_icons[idx];
|
||||
}
|
||||
@@ -102,7 +157,7 @@ std::string ALabel::getIcon(uint16_t percentage, const std::vector<std::string>&
|
||||
}
|
||||
if (format_icons.isArray()) {
|
||||
auto size = format_icons.size();
|
||||
if (size) {
|
||||
if (size != 0U) {
|
||||
auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1);
|
||||
format_icons = format_icons[idx];
|
||||
}
|
||||
@@ -125,6 +180,10 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
|
||||
return AModule::handleToggle(e);
|
||||
}
|
||||
|
||||
void ALabel::handleGtkMenuEvent(GtkMenuItem* /*menuitem*/, gpointer data) {
|
||||
waybar::util::command::res res = waybar::util::command::exec((char*)data, "GtkMenu");
|
||||
}
|
||||
|
||||
std::string ALabel::getState(uint8_t value, bool lesser) {
|
||||
if (!config_["states"].isObject()) {
|
||||
return "";
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
#include "AModule.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <util/command.hpp>
|
||||
|
||||
#include "gdk/gdk.h"
|
||||
#include "gdkmm/cursor.h"
|
||||
|
||||
namespace waybar {
|
||||
|
||||
AModule::AModule(const Json::Value& config, const std::string& name, const std::string& id,
|
||||
bool enable_click, bool enable_scroll)
|
||||
: name_(std::move(name)),
|
||||
config_(std::move(config)),
|
||||
: name_(name),
|
||||
config_(config),
|
||||
isTooltip{config_["tooltip"].isBool() ? config_["tooltip"].asBool() : true},
|
||||
distance_scrolled_y_(0.0),
|
||||
distance_scrolled_x_(0.0) {
|
||||
// Configure module action Map
|
||||
const Json::Value actions{config_["actions"]};
|
||||
|
||||
for (Json::Value::const_iterator it = actions.begin(); it != actions.end(); ++it) {
|
||||
if (it.key().isString() && it->isString())
|
||||
if (eventActionMap_.count(it.key().asString()) == 0) {
|
||||
if (!eventActionMap_.contains(it.key().asString())) {
|
||||
eventActionMap_.insert({it.key().asString(), it->asString()});
|
||||
enable_click = true;
|
||||
enable_scroll = true;
|
||||
} else
|
||||
spdlog::warn("Dublicate action is ignored: {0}", it.key().asString());
|
||||
spdlog::warn("Duplicate action is ignored: {0}", it.key().asString());
|
||||
else
|
||||
spdlog::warn("Wrong actions section configuration. See config by index: {}", it.index());
|
||||
}
|
||||
@@ -31,17 +36,20 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
|
||||
event_box_.signal_leave_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseLeave));
|
||||
|
||||
// configure events' user commands
|
||||
// hasUserEvent is true if any element from eventMap_ is satisfying the condition in the lambda
|
||||
bool hasUserEvent =
|
||||
// hasUserEvents is true if any element from eventMap_ is satisfying the condition in the lambda
|
||||
bool hasUserEvents =
|
||||
std::find_if(eventMap_.cbegin(), eventMap_.cend(), [&config](const auto& eventEntry) {
|
||||
// True if there is any non-release type event
|
||||
return eventEntry.first.second != GdkEventType::GDK_BUTTON_RELEASE &&
|
||||
config[eventEntry.second].isString();
|
||||
}) != eventMap_.cend();
|
||||
|
||||
if (enable_click || hasUserEvent) {
|
||||
if (enable_click || hasUserEvents) {
|
||||
hasUserEvents_ = true;
|
||||
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
|
||||
event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &AModule::handleToggle));
|
||||
} else {
|
||||
hasUserEvents_ = false;
|
||||
}
|
||||
|
||||
bool hasReleaseEvent =
|
||||
@@ -60,6 +68,17 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
|
||||
event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
||||
event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &AModule::handleScroll));
|
||||
}
|
||||
|
||||
// Respect user configuration of cursor
|
||||
if (config_.isMember("cursor")) {
|
||||
if (config_["cursor"].isBool() && config_["cursor"].asBool()) {
|
||||
setCursor(Gdk::HAND2);
|
||||
} else if (config_["cursor"].isInt()) {
|
||||
setCursor(Gdk::CursorType(config_["cursor"].asInt()));
|
||||
} else {
|
||||
spdlog::warn("unknown cursor option configured on module {}", name_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AModule::~AModule() {
|
||||
@@ -86,18 +105,47 @@ auto AModule::doAction(const std::string& name) -> void {
|
||||
}
|
||||
}
|
||||
|
||||
void AModule::setCursor(Gdk::CursorType const& c) {
|
||||
auto gdk_window = event_box_.get_window();
|
||||
if (gdk_window) {
|
||||
auto cursor = Gdk::Cursor::create(c);
|
||||
gdk_window->set_cursor(cursor);
|
||||
} else {
|
||||
// window may not be accessible yet, in this case,
|
||||
// schedule another call for setting the cursor in 1 sec
|
||||
Glib::signal_timeout().connect_seconds(
|
||||
[this, c]() {
|
||||
setCursor(c);
|
||||
return false;
|
||||
},
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
bool AModule::handleMouseEnter(GdkEventCrossing* const& e) {
|
||||
if (auto* module = event_box_.get_child(); module != nullptr) {
|
||||
module->set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
|
||||
}
|
||||
return true;
|
||||
|
||||
// Default behavior indicating event availability
|
||||
if (hasUserEvents_ && !config_.isMember("cursor")) {
|
||||
setCursor(Gdk::HAND2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AModule::handleMouseLeave(GdkEventCrossing* const& e) {
|
||||
if (auto* module = event_box_.get_child(); module != nullptr) {
|
||||
module->unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
|
||||
}
|
||||
return true;
|
||||
|
||||
// Default behavior indicating event availability
|
||||
if (hasUserEvents_ && !config_.isMember("cursor")) {
|
||||
setCursor(Gdk::ARROW);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AModule::handleToggle(GdkEventButton* const& e) { return handleUserEvent(e); }
|
||||
@@ -108,12 +156,23 @@ bool AModule::handleUserEvent(GdkEventButton* const& e) {
|
||||
std::string format{};
|
||||
const std::map<std::pair<uint, GdkEventType>, std::string>::const_iterator& rec{
|
||||
eventMap_.find(std::pair(e->button, e->type))};
|
||||
|
||||
if (rec != eventMap_.cend()) {
|
||||
// First call module actions
|
||||
this->AModule::doAction(rec->second);
|
||||
|
||||
format = rec->second;
|
||||
}
|
||||
|
||||
// Check that a menu has been configured
|
||||
if (config_["menu"].isString()) {
|
||||
// Check if the event is the one specified for the "menu" option
|
||||
if (rec->second == config_["menu"].asString()) {
|
||||
// Popup the menu
|
||||
gtk_widget_show_all(GTK_WIDGET(menu_));
|
||||
gtk_menu_popup_at_pointer(GTK_MENU(menu_), reinterpret_cast<GdkEvent*>(e));
|
||||
}
|
||||
}
|
||||
// Second call user scripts
|
||||
if (!format.empty()) {
|
||||
if (config_[format].isString())
|
||||
@@ -135,7 +194,7 @@ AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) {
|
||||
|
||||
// ignore reverse-scrolling if event comes from a mouse wheel
|
||||
GdkDevice* device = gdk_event_get_source_device((GdkEvent*)e);
|
||||
if (device != NULL && gdk_device_get_source(device) == GDK_SOURCE_MOUSE) {
|
||||
if (device != nullptr && gdk_device_get_source(device) == GDK_SOURCE_MOUSE) {
|
||||
reverse = reverse_mouse;
|
||||
}
|
||||
|
||||
@@ -213,7 +272,7 @@ bool AModule::handleScroll(GdkEventScroll* e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AModule::tooltipEnabled() { return isTooltip; }
|
||||
bool AModule::tooltipEnabled() const { return isTooltip; }
|
||||
|
||||
AModule::operator Gtk::Widget&() { return event_box_; }
|
||||
|
||||
|
||||
38
src/bar.cpp
38
src/bar.cpp
@@ -43,7 +43,7 @@ const Bar::bar_mode_map Bar::PRESET_MODES = { //
|
||||
.visible = true}},
|
||||
{"invisible",
|
||||
{//
|
||||
.layer = bar_layer::BOTTOM,
|
||||
.layer = std::nullopt,
|
||||
.exclusive = false,
|
||||
.passthrough = true,
|
||||
.visible = false}},
|
||||
@@ -59,7 +59,7 @@ const std::string Bar::MODE_INVISIBLE = "invisible";
|
||||
const std::string_view DEFAULT_BAR_ID = "bar-0";
|
||||
|
||||
/* Deserializer for enum bar_layer */
|
||||
void from_json(const Json::Value& j, bar_layer& l) {
|
||||
void from_json(const Json::Value& j, std::optional<bar_layer>& l) {
|
||||
if (j == "bottom") {
|
||||
l = bar_layer::BOTTOM;
|
||||
} else if (j == "top") {
|
||||
@@ -72,16 +72,16 @@ void from_json(const Json::Value& j, bar_layer& l) {
|
||||
/* Deserializer for struct bar_mode */
|
||||
void from_json(const Json::Value& j, bar_mode& m) {
|
||||
if (j.isObject()) {
|
||||
if (auto v = j["layer"]; v.isString()) {
|
||||
if (const auto& v = j["layer"]; v.isString()) {
|
||||
from_json(v, m.layer);
|
||||
}
|
||||
if (auto v = j["exclusive"]; v.isBool()) {
|
||||
if (const auto& v = j["exclusive"]; v.isBool()) {
|
||||
m.exclusive = v.asBool();
|
||||
}
|
||||
if (auto v = j["passthrough"]; v.isBool()) {
|
||||
if (const auto& v = j["passthrough"]; v.isBool()) {
|
||||
m.passthrough = v.asBool();
|
||||
}
|
||||
if (auto v = j["visible"]; v.isBool()) {
|
||||
if (const auto& v = j["visible"]; v.isBool()) {
|
||||
m.visible = v.asBool();
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ Glib::ustring to_string(Gtk::PositionType pos) {
|
||||
* Assumes that all the values in the object are deserializable to the same type.
|
||||
*/
|
||||
template <typename Key, typename Value,
|
||||
typename = std::enable_if_t<std::is_convertible<std::string, Key>::value>>
|
||||
typename = std::enable_if_t<std::is_convertible_v<std::string, Key>>>
|
||||
void from_json(const Json::Value& j, std::map<Key, Value>& m) {
|
||||
if (j.isObject()) {
|
||||
for (auto it = j.begin(); it != j.end(); ++it) {
|
||||
@@ -316,13 +316,13 @@ void waybar::Bar::setMode(const std::string& mode) {
|
||||
void waybar::Bar::setMode(const struct bar_mode& mode) {
|
||||
auto* gtk_window = window.gobj();
|
||||
|
||||
auto layer = GTK_LAYER_SHELL_LAYER_BOTTOM;
|
||||
if (mode.layer == bar_layer::TOP) {
|
||||
layer = GTK_LAYER_SHELL_LAYER_TOP;
|
||||
if (mode.layer == bar_layer::BOTTOM) {
|
||||
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_BOTTOM);
|
||||
} else if (mode.layer == bar_layer::TOP) {
|
||||
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_TOP);
|
||||
} else if (mode.layer == bar_layer::OVERLAY) {
|
||||
layer = GTK_LAYER_SHELL_LAYER_OVERLAY;
|
||||
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_OVERLAY);
|
||||
}
|
||||
gtk_layer_set_layer(gtk_window, layer);
|
||||
|
||||
if (mode.exclusive) {
|
||||
gtk_layer_auto_exclusive_zone_enable(gtk_window);
|
||||
@@ -393,11 +393,11 @@ void waybar::Bar::setPosition(Gtk::PositionType position) {
|
||||
}
|
||||
}
|
||||
|
||||
void waybar::Bar::onMap(GdkEventAny*) {
|
||||
void waybar::Bar::onMap(GdkEventAny* /*unused*/) {
|
||||
/*
|
||||
* Obtain a pointer to the custom layer surface for modules that require it (idle_inhibitor).
|
||||
*/
|
||||
auto gdk_window = window.get_window()->gobj();
|
||||
auto* gdk_window = window.get_window()->gobj();
|
||||
surface = gdk_wayland_window_get_wl_surface(gdk_window);
|
||||
configureGlobalOffset(gdk_window_get_width(gdk_window), gdk_window_get_height(gdk_window));
|
||||
|
||||
@@ -473,7 +473,7 @@ void waybar::Bar::handleSignal(int signal) {
|
||||
|
||||
void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
|
||||
waybar::Group* group = nullptr) {
|
||||
auto module_list = group ? config[pos]["modules"] : config[pos];
|
||||
auto module_list = group != nullptr ? config[pos]["modules"] : config[pos];
|
||||
if (module_list.isArray()) {
|
||||
for (const auto& name : module_list) {
|
||||
try {
|
||||
@@ -485,10 +485,10 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
|
||||
auto id_name = ref.substr(6, hash_pos - 6);
|
||||
auto class_name = hash_pos != std::string::npos ? ref.substr(hash_pos + 1) : "";
|
||||
|
||||
auto vertical = (group ? group->getBox().get_orientation() : box_.get_orientation()) ==
|
||||
Gtk::ORIENTATION_VERTICAL;
|
||||
auto vertical = (group != nullptr ? group->getBox().get_orientation()
|
||||
: box_.get_orientation()) == Gtk::ORIENTATION_VERTICAL;
|
||||
|
||||
auto group_module = new waybar::Group(id_name, class_name, config[ref], vertical);
|
||||
auto* group_module = new waybar::Group(id_name, class_name, config[ref], vertical);
|
||||
getModules(factory, ref, group_module);
|
||||
module = group_module;
|
||||
} else {
|
||||
@@ -497,7 +497,7 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
|
||||
|
||||
std::shared_ptr<AModule> module_sp(module);
|
||||
modules_all_.emplace_back(module_sp);
|
||||
if (group) {
|
||||
if (group != nullptr) {
|
||||
group->addWidget(*module);
|
||||
} else {
|
||||
if (pos == "modules-left") {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#include "gtkmm/icontheme.h"
|
||||
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||
@@ -11,13 +12,13 @@
|
||||
#include "util/format.hpp"
|
||||
|
||||
waybar::Client *waybar::Client::inst() {
|
||||
static auto c = new Client();
|
||||
static auto *c = new Client();
|
||||
return c;
|
||||
}
|
||||
|
||||
void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
|
||||
const char *interface, uint32_t version) {
|
||||
auto client = static_cast<Client *>(data);
|
||||
auto *client = static_cast<Client *>(data);
|
||||
if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 &&
|
||||
version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
|
||||
client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(wl_registry_bind(
|
||||
@@ -42,7 +43,7 @@ void waybar::Client::handleOutput(struct waybar_output &output) {
|
||||
.description = &handleOutputDescription,
|
||||
};
|
||||
// owned by output->monitor; no need to destroy
|
||||
auto wl_output = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
|
||||
auto *wl_output = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
|
||||
output.xdg_output.reset(zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, wl_output));
|
||||
zxdg_output_v1_add_listener(output.xdg_output.get(), &xdgOutputListener, &output);
|
||||
}
|
||||
@@ -61,7 +62,7 @@ std::vector<Json::Value> waybar::Client::getOutputConfigs(struct waybar_output &
|
||||
}
|
||||
|
||||
void waybar::Client::handleOutputDone(void *data, struct zxdg_output_v1 * /*xdg_output*/) {
|
||||
auto client = waybar::Client::inst();
|
||||
auto *client = waybar::Client::inst();
|
||||
try {
|
||||
auto &output = client->getOutput(data);
|
||||
/**
|
||||
@@ -85,24 +86,24 @@ void waybar::Client::handleOutputDone(void *data, struct zxdg_output_v1 * /*xdg_
|
||||
}
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void waybar::Client::handleOutputName(void *data, struct zxdg_output_v1 * /*xdg_output*/,
|
||||
const char *name) {
|
||||
auto client = waybar::Client::inst();
|
||||
auto *client = waybar::Client::inst();
|
||||
try {
|
||||
auto &output = client->getOutput(data);
|
||||
output.name = name;
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void waybar::Client::handleOutputDescription(void *data, struct zxdg_output_v1 * /*xdg_output*/,
|
||||
const char *description) {
|
||||
auto client = waybar::Client::inst();
|
||||
auto *client = waybar::Client::inst();
|
||||
try {
|
||||
auto &output = client->getOutput(data);
|
||||
const char *open_paren = strrchr(description, '(');
|
||||
@@ -111,18 +112,19 @@ void waybar::Client::handleOutputDescription(void *data, struct zxdg_output_v1 *
|
||||
size_t identifier_length = open_paren - description;
|
||||
output.identifier = std::string(description, identifier_length - 1);
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) {
|
||||
auto &output = outputs_.emplace_back();
|
||||
output.monitor = monitor;
|
||||
output.monitor = std::move(monitor);
|
||||
handleOutput(output);
|
||||
}
|
||||
|
||||
void waybar::Client::handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor) {
|
||||
spdlog::debug("Output removed: {} {}", monitor->get_manufacturer(), monitor->get_model());
|
||||
spdlog::debug("Output removed: {} {}", monitor->get_manufacturer().c_str(),
|
||||
monitor->get_model().c_str());
|
||||
/* This event can be triggered from wl_display_roundtrip called by GTK or our code.
|
||||
* Defer destruction of bars for the output to the next iteration of the event loop to avoid
|
||||
* deleting objects referenced by currently executed code.
|
||||
@@ -154,15 +156,15 @@ const std::string waybar::Client::getStyle(const std::string &style,
|
||||
std::vector<std::string> search_files;
|
||||
switch (appearance.value_or(portal->getAppearance())) {
|
||||
case waybar::Appearance::LIGHT:
|
||||
search_files.push_back("style-light.css");
|
||||
search_files.emplace_back("style-light.css");
|
||||
break;
|
||||
case waybar::Appearance::DARK:
|
||||
search_files.push_back("style-dark.css");
|
||||
search_files.emplace_back("style-dark.css");
|
||||
break;
|
||||
case waybar::Appearance::UNKNOWN:
|
||||
break;
|
||||
}
|
||||
search_files.push_back("style.css");
|
||||
search_files.emplace_back("style.css");
|
||||
css_file = Config::findConfigPath(search_files);
|
||||
} else {
|
||||
css_file = style;
|
||||
@@ -196,7 +198,7 @@ void waybar::Client::bindInterfaces() {
|
||||
wl_registry_add_listener(registry, ®istry_listener, this);
|
||||
wl_display_roundtrip(wl_display);
|
||||
|
||||
if (!gtk_layer_is_supported()) {
|
||||
if (gtk_layer_is_supported() == 0) {
|
||||
throw std::runtime_error("The Wayland compositor does not support wlr-layer-shell protocol");
|
||||
}
|
||||
|
||||
@@ -233,11 +235,11 @@ int waybar::Client::main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
if (show_help) {
|
||||
std::cout << cli << std::endl;
|
||||
std::cout << cli << '\n';
|
||||
return 0;
|
||||
}
|
||||
if (show_version) {
|
||||
std::cout << "Waybar v" << VERSION << std::endl;
|
||||
std::cout << "Waybar v" << VERSION << '\n';
|
||||
return 0;
|
||||
}
|
||||
if (!log_level.empty()) {
|
||||
|
||||
@@ -21,10 +21,11 @@ const std::vector<std::string> Config::CONFIG_DIRS = {
|
||||
|
||||
const char *Config::CONFIG_PATH_ENV = "WAYBAR_CONFIG_DIR";
|
||||
|
||||
std::optional<std::string> tryExpandPath(const std::string base, const std::string filename) {
|
||||
std::optional<std::string> Config::tryExpandPath(const std::string &base,
|
||||
const std::string &filename) {
|
||||
fs::path path;
|
||||
|
||||
if (filename != "") {
|
||||
if (!filename.empty()) {
|
||||
path = fs::path(base) / fs::path(filename);
|
||||
} else {
|
||||
path = fs::path(base);
|
||||
@@ -129,9 +130,9 @@ bool isValidOutput(const Json::Value &config, const std::string &name,
|
||||
if (config_output.substr(0, 1) == "!") {
|
||||
if (config_output.substr(1) == name || config_output.substr(1) == identifier) {
|
||||
return false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if (config_output == name || config_output == identifier) {
|
||||
return true;
|
||||
@@ -142,7 +143,9 @@ bool isValidOutput(const Json::Value &config, const std::string &name,
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (config["output"].isString()) {
|
||||
}
|
||||
|
||||
if (config["output"].isString()) {
|
||||
auto config_output = config["output"].asString();
|
||||
if (!config_output.empty()) {
|
||||
if (config_output.substr(0, 1) == "!") {
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
#include "modules/hyprland/window.hpp"
|
||||
#include "modules/hyprland/workspaces.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_NIRI
|
||||
#include "modules/niri/language.hpp"
|
||||
#include "modules/niri/window.hpp"
|
||||
#include "modules/niri/workspaces.hpp"
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__linux__)
|
||||
#include "modules/battery.hpp"
|
||||
#endif
|
||||
@@ -70,7 +75,7 @@
|
||||
#include "modules/gamemode.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_UPOWER
|
||||
#include "modules/upower/upower.hpp"
|
||||
#include "modules/upower.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_PIPEWIRE
|
||||
#include "modules/privacy/privacy.hpp"
|
||||
@@ -130,7 +135,7 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name,
|
||||
#endif
|
||||
#ifdef HAVE_UPOWER
|
||||
if (ref == "upower") {
|
||||
return new waybar::modules::upower::UPower(id, config_[name]);
|
||||
return new waybar::modules::UPower(id, config_[name]);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_PIPEWIRE
|
||||
@@ -205,6 +210,17 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name,
|
||||
if (ref == "hyprland/workspaces") {
|
||||
return new waybar::modules::hyprland::Workspaces(id, bar_, config_[name]);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_NIRI
|
||||
if (ref == "niri/language") {
|
||||
return new waybar::modules::niri::Language(id, bar_, config_[name]);
|
||||
}
|
||||
if (ref == "niri/window") {
|
||||
return new waybar::modules::niri::Window(id, bar_, config_[name]);
|
||||
}
|
||||
if (ref == "niri/workspaces") {
|
||||
return new waybar::modules::niri::Workspaces(id, bar_, config_[name]);
|
||||
}
|
||||
#endif
|
||||
if (ref == "idle_inhibitor") {
|
||||
return new waybar::modules::IdleInhibitor(id, bar_, config_[name]);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user