Merge remote-tracking branch 'origin/master' into pr-2157
# Conflicts: # resources/custom_modules/mediaplayer.py
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
|||||||
|
Checks: >
|
||||||
|
-*,
|
||||||
|
bugprone-*
|
||||||
|
misc-*,
|
||||||
|
modernize-*,
|
||||||
|
performance-*,
|
||||||
|
portability-*,
|
||||||
|
readability-*,
|
||||||
|
-fuchsia-trailing-return,
|
||||||
|
-readability-magic-numbers,
|
||||||
|
-modernize-use-nodiscard,
|
||||||
|
-modernize-use-trailing-return-type,
|
||||||
|
-readability-braces-around-statements,
|
||||||
|
-readability-redundant-access-specifiers,
|
||||||
|
-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 }
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
bug:
|
||||||
|
- "(crash|bug|error|coredump|freeze|segfault|issue|problem)"
|
||||||
|
|
||||||
|
enhancement:
|
||||||
|
- "(feature|enhancement|improvement|request|suggestion)"
|
||||||
|
|
||||||
|
hyprland:
|
||||||
|
- "(hyprland)"
|
||||||
|
|
||||||
|
network:
|
||||||
|
- "(network|wifi|ethernet)"
|
||||||
|
|
||||||
|
bluetooth:
|
||||||
|
- "(bluetooth|bluez)"
|
||||||
|
|
||||||
|
sway:
|
||||||
|
- "(sway)"
|
||||||
|
|
||||||
|
cpu:
|
||||||
|
- "(cpu)"
|
||||||
|
|
||||||
|
memory:
|
||||||
|
- "(memory|ram)"
|
||||||
|
|
||||||
|
disk:
|
||||||
|
- "(disk|storage)"
|
||||||
|
|
||||||
|
battery:
|
||||||
|
- "(upower|battery)"
|
||||||
|
|
||||||
|
sni:
|
||||||
|
- "(sni|tray)"
|
||||||
|
|
||||||
|
dwl:
|
||||||
|
- "(dwl)"
|
||||||
|
|
||||||
|
custom:
|
||||||
|
- "(custom|module|extension|plugin|script)"
|
||||||
|
|
||||||
|
mpd:
|
||||||
|
- "(mpd|music)"
|
||||||
|
|
||||||
|
audio:
|
||||||
|
- "(pulseaudio|alsa|jack|audio|pirewire|wireplumber)"
|
||||||
|
|
||||||
|
temperature:
|
||||||
|
- "(temperature|thermal|hwmon)"
|
||||||
|
|
||||||
|
clock:
|
||||||
|
- "(clock|time|date)"
|
||||||
|
|
||||||
|
gamemode:
|
||||||
|
- "(gamemode|game|gaming)"
|
||||||
|
|
||||||
|
inhibitor:
|
||||||
|
- "(inhibitor|idle|lock|suspend|hibernate|logout)"
|
||||||
|
|
||||||
|
cava:
|
||||||
|
- "(cava|audio-visualizer)"
|
||||||
|
|
||||||
|
backlight:
|
||||||
|
- "(backlight|brightness)"
|
||||||
|
|
||||||
|
keyboard:
|
||||||
|
- "(keyboard|keymap|layout|shortcut)"
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
name: clang-format
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-format-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
- uses: RafikFarhad/clang-format-github-action@v6
|
||||||
|
name: clang-format
|
||||||
|
with:
|
||||||
|
sources: "src/**/*.hpp,src/**/*.cpp"
|
||||||
|
style: "file"
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
name: clang-tidy
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-tidy-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: alexays/waybar:debian
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
- name: configure
|
||||||
|
run: |
|
||||||
|
meson -Dcpp_std=c++20 build # necessary to generate compile_commands.json
|
||||||
|
ninja -C build # necessary to find certain .h files (xdg, wayland, etc.)
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.10' # to be kept in sync with cpp-linter-action
|
||||||
|
update-environment: true # the python dist installed by the action needs LD_LIBRARY_PATH to work
|
||||||
|
- uses: cpp-linter/cpp-linter-action@v2.9.1
|
||||||
|
name: clang-tidy
|
||||||
|
id: clang-tidy-check
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
PIP_NO_CACHE_DIR: false
|
||||||
|
with:
|
||||||
|
style: "" # empty string => don't do clang-format checks here, we do them in clang-format.yml
|
||||||
|
files-changed-only: true # only check files that have changed
|
||||||
|
lines-changed-only: true # only check lines that have changed
|
||||||
|
tidy-checks: "" # empty string => use the .clang-tidy file
|
||||||
|
version: "17" # clang-tools version
|
||||||
|
database: "build" # path to the compile_commands.json file
|
||||||
|
- name: Check if clang-tidy failed on any files
|
||||||
|
if: steps.clang-tidy-check.outputs.checks-failed > 0
|
||||||
|
run: echo "Some files failed the linting checks!" && exit 1
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
name: Build and Push Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
# run monthly
|
||||||
|
- cron: '0 0 1 * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name != 'schedule' || github.repository == 'Alexays/Waybar'
|
||||||
|
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@v6
|
||||||
|
|
||||||
|
- 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 }}
|
||||||
@@ -2,28 +2,34 @@ name: freebsd
|
|||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-freebsd-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
clang:
|
build:
|
||||||
# Run actions in a FreeBSD VM on the macos-12 runner
|
# Run actions in a FreeBSD VM on the ubuntu runner
|
||||||
# https://github.com/actions/runner/issues/385 - for FreeBSD runner support
|
# https://github.com/actions/runner/issues/385 - for FreeBSD runner support
|
||||||
# https://github.com/actions/virtual-environments/issues/4060 - for lack of VirtualBox on MacOS 11 runners
|
runs-on: ubuntu-latest
|
||||||
runs-on: macos-12
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v6
|
||||||
- name: Test in FreeBSD VM
|
- name: Test in FreeBSD VM
|
||||||
uses: vmactions/freebsd-vm@v0
|
uses: cross-platform-actions/action@v0.28.0
|
||||||
|
timeout-minutes: 180
|
||||||
|
env:
|
||||||
|
CPPFLAGS: '-isystem/usr/local/include'
|
||||||
|
LDFLAGS: '-L/usr/local/lib'
|
||||||
with:
|
with:
|
||||||
mem: 2048
|
operating_system: freebsd
|
||||||
usesh: true
|
version: "14.2"
|
||||||
prepare: |
|
environment_variables: CPPFLAGS LDFLAGS
|
||||||
export CPPFLAGS=-isystem/usr/local/include LDFLAGS=-L/usr/local/lib # sndio
|
sync_files: runner-to-vm
|
||||||
sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
|
|
||||||
pkg install -y git # subprojects/date
|
|
||||||
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 \
|
|
||||||
libinotify
|
|
||||||
run: |
|
run: |
|
||||||
meson build -Dman-pages=enabled
|
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 pipewire pulseaudio scdoc sndio spdlog wayland-protocols upower \
|
||||||
|
libinotify
|
||||||
|
meson setup build -Dman-pages=enabled
|
||||||
ninja -C build
|
ninja -C build
|
||||||
meson test -C build --no-rebuild --print-errorlogs --suite waybar
|
meson test -C build --no-rebuild --print-errorlogs --suite waybar
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
name: "Issue Labeler"
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened, edited]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
triage:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: github/issue-labeler@v3.4
|
||||||
|
with:
|
||||||
|
configuration-path: .github/labeler.yml
|
||||||
|
enable-versioned-regex: 0
|
||||||
|
include-title: 1
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
name: Linter
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: DoozyX/clang-format-lint-action@v0.13
|
|
||||||
with:
|
|
||||||
source: '.'
|
|
||||||
extensions: 'h,cpp,c'
|
|
||||||
clangFormatVersion: 12
|
|
||||||
@@ -2,9 +2,14 @@ name: linux
|
|||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-linux-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
distro:
|
distro:
|
||||||
- alpine
|
- alpine
|
||||||
@@ -13,19 +18,16 @@ jobs:
|
|||||||
- fedora
|
- fedora
|
||||||
- opensuse
|
- opensuse
|
||||||
- gentoo
|
- gentoo
|
||||||
cpp_std: [c++17]
|
cpp_std: [c++20]
|
||||||
include:
|
|
||||||
- distro: fedora
|
|
||||||
cpp_std: c++20
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: alexays/waybar:${{ matrix.distro }}
|
image: alexays/waybar:${{ matrix.distro }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v6
|
||||||
- name: configure
|
- 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
|
- name: build
|
||||||
run: ninja -C build
|
run: ninja -C build
|
||||||
- name: test
|
- name: test
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
name: "Nix-Tests"
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-nix-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
jobs:
|
||||||
|
nix-flake-check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
- uses: cachix/install-nix-action@v31
|
||||||
|
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
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
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
|
||||||
|
if: github.event_name != 'schedule' || github.repository == 'Alexays/Waybar'
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
- name: Install Nix
|
||||||
|
uses: cachix/install-nix-action@v31
|
||||||
|
with:
|
||||||
|
extra_nix_config: |
|
||||||
|
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Update flake.lock
|
||||||
|
uses: DeterminateSystems/update-flake-lock@v28
|
||||||
@@ -7,6 +7,7 @@ vgcore.*
|
|||||||
*.swp
|
*.swp
|
||||||
packagecache
|
packagecache
|
||||||
/subprojects/**/
|
/subprojects/**/
|
||||||
|
/subprojects/.wraplock
|
||||||
/build*
|
/build*
|
||||||
/dist
|
/dist
|
||||||
/meson.egg-info
|
/meson.egg-info
|
||||||
@@ -44,3 +45,11 @@ packagecache
|
|||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
/.direnv/
|
/.direnv/
|
||||||
|
|
||||||
|
# Nix
|
||||||
|
result
|
||||||
|
result-*
|
||||||
|
|
||||||
|
.ccls-cache
|
||||||
|
_codeql_detected_source_root
|
||||||
|
heaptrack*
|
||||||
|
|||||||
@@ -3,5 +3,5 @@
|
|||||||
FROM archlinux:base-devel
|
FROM archlinux:base-devel
|
||||||
|
|
||||||
RUN pacman -Syu --noconfirm && \
|
RUN pacman -Syu --noconfirm && \
|
||||||
pacman -S --noconfirm git meson base-devel libinput wayland wayland-protocols pixman libxkbcommon mesa gtkmm3 jsoncpp pugixml scdoc libpulse libdbusmenu-gtk3 libmpdclient gobject-introspection libxkbcommon playerctl && \
|
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
|
sed -Ei 's/#(en_(US|GB)\.UTF)/\1/' /etc/locale.gen && locale-gen
|
||||||
|
|||||||
+46
-4
@@ -1,7 +1,49 @@
|
|||||||
# vim: ft=Dockerfile
|
# vim: ft=Dockerfile
|
||||||
|
|
||||||
FROM debian:sid
|
FROM debian:sid-slim
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt update && \
|
||||||
apt-get install -y build-essential meson ninja-build git pkg-config libinput10 libpugixml-dev libinput-dev wayland-protocols libwayland-client0 libwayland-cursor0 libwayland-dev libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libxkbcommon-dev libudev-dev libpixman-1-dev libgtkmm-3.0-dev libjsoncpp-dev scdoc libdbusmenu-gtk3-dev libnl-3-dev libnl-genl-3-dev libpulse-dev libmpdclient-dev gobject-introspection libgirepository1.0-dev libxkbcommon-dev libxkbregistry-dev libxkbregistry0 libplayerctl-dev && \
|
apt install --no-install-recommends --no-install-suggests -y \
|
||||||
apt-get clean
|
build-essential \
|
||||||
|
catch2 \
|
||||||
|
cmake \
|
||||||
|
git \
|
||||||
|
gobject-introspection \
|
||||||
|
libdbusmenu-gtk3-dev \
|
||||||
|
libegl1-mesa-dev \
|
||||||
|
libfmt-dev \
|
||||||
|
libgbm-dev \
|
||||||
|
libgirepository1.0-dev \
|
||||||
|
libgles2-mesa-dev \
|
||||||
|
libgtk-layer-shell-dev \
|
||||||
|
libgtkmm-3.0-dev \
|
||||||
|
libhowardhinnant-date-dev \
|
||||||
|
libiniparser-dev \
|
||||||
|
libinput-dev \
|
||||||
|
libjack-jackd2-dev \
|
||||||
|
libjsoncpp-dev \
|
||||||
|
libmpdclient-dev \
|
||||||
|
libnl-3-dev \
|
||||||
|
libnl-genl-3-dev \
|
||||||
|
libpixman-1-dev \
|
||||||
|
libplayerctl-dev \
|
||||||
|
libpugixml-dev \
|
||||||
|
libpulse-dev \
|
||||||
|
libsndio-dev \
|
||||||
|
libspdlog-dev \
|
||||||
|
libudev-dev \
|
||||||
|
libupower-glib-dev \
|
||||||
|
libwayland-dev \
|
||||||
|
libwireplumber-0.5-dev \
|
||||||
|
libxkbcommon-dev \
|
||||||
|
libxkbregistry-dev \
|
||||||
|
locales \
|
||||||
|
meson \
|
||||||
|
ninja-build \
|
||||||
|
pkg-config \
|
||||||
|
python3-pip \
|
||||||
|
python3-venv \
|
||||||
|
scdoc \
|
||||||
|
sudo \
|
||||||
|
wayland-protocols \
|
||||||
|
&& apt clean
|
||||||
|
|||||||
+1
-1
@@ -29,6 +29,6 @@ RUN dnf install -y @c-development \
|
|||||||
'pkgconfig(wayland-client)' \
|
'pkgconfig(wayland-client)' \
|
||||||
'pkgconfig(wayland-cursor)' \
|
'pkgconfig(wayland-cursor)' \
|
||||||
'pkgconfig(wayland-protocols)' \
|
'pkgconfig(wayland-protocols)' \
|
||||||
'pkgconfig(wireplumber-0.4)' \
|
'pkgconfig(wireplumber-0.5)' \
|
||||||
'pkgconfig(xkbregistry)' && \
|
'pkgconfig(xkbregistry)' && \
|
||||||
dnf clean all -y
|
dnf clean all -y
|
||||||
|
|||||||
+2
-2
@@ -6,6 +6,6 @@ RUN export FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox -sandbox -usersa
|
|||||||
emerge --sync && \
|
emerge --sync && \
|
||||||
eselect news read --quiet new 1>/dev/null 2>&1 && \
|
eselect news read --quiet new 1>/dev/null 2>&1 && \
|
||||||
emerge --verbose --update --deep --with-bdeps=y --backtrack=30 --newuse @world && \
|
emerge --verbose --update --deep --with-bdeps=y --backtrack=30 --newuse @world && \
|
||||||
USE="wayland gtk3 gtk -doc X" emerge dev-vcs/git dev-libs/wayland dev-libs/wayland-protocols =dev-cpp/gtkmm-3.24.6 x11-libs/libxkbcommon \
|
USE="wayland gtk3 gtk -doc X pulseaudio minimal" emerge dev-vcs/git dev-libs/wayland dev-libs/wayland-protocols dev-cpp/gtkmm:3.0 x11-libs/libxkbcommon \
|
||||||
x11-libs/gtk+:3 dev-libs/libdbusmenu dev-libs/libnl sys-power/upower media-libs/libpulse dev-libs/libevdev media-libs/libmpdclient \
|
x11-libs/gtk+:3 dev-libs/libdbusmenu dev-libs/libnl sys-power/upower media-libs/libpulse dev-libs/libevdev media-libs/libmpdclient \
|
||||||
media-sound/sndio gui-libs/gtk-layer-shell app-text/scdoc media-sound/playerctl dev-libs/iniparser
|
media-sound/sndio gui-libs/gtk-layer-shell app-text/scdoc media-sound/playerctl dev-libs/iniparser sci-libs/fftw
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ RUN zypper -n up && \
|
|||||||
zypper addrepo https://download.opensuse.org/repositories/X11:Wayland/openSUSE_Tumbleweed/X11:Wayland.repo | echo 'a' && \
|
zypper addrepo https://download.opensuse.org/repositories/X11:Wayland/openSUSE_Tumbleweed/X11:Wayland.repo | echo 'a' && \
|
||||||
zypper -n refresh && \
|
zypper -n refresh && \
|
||||||
zypper -n install -t pattern devel_C_C++ && \
|
zypper -n install -t pattern devel_C_C++ && \
|
||||||
zypper -n install git meson clang libinput10 libinput-devel pugixml-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel libxkbregistry-devel scdoc playerctl-devel
|
zypper -n install git meson clang libinput10 libinput-devel pugixml-devel libwayland-client0 libwayland-cursor0 wayland-protocols-devel wayland-devel Mesa-libEGL-devel Mesa-libGLESv2-devel libgbm-devel libxkbcommon-devel libudev-devel libpixman-1-0-devel gtkmm3-devel jsoncpp-devel libxkbregistry-devel scdoc playerctl-devel python3-packaging
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018 Alex
|
Copyright (c) 2025 Alex
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
default: build
|
default: build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
meson build
|
meson setup build
|
||||||
ninja -C build
|
ninja -C build
|
||||||
|
|
||||||
build-debug:
|
build-debug:
|
||||||
meson build --buildtype=debug
|
meson setup build --buildtype=debug
|
||||||
ninja -C build
|
ninja -C build
|
||||||
|
|
||||||
install: build
|
install: build
|
||||||
@@ -20,8 +20,12 @@ debug-run: build-debug
|
|||||||
./build/waybar --log-level debug
|
./build/waybar --log-level debug
|
||||||
|
|
||||||
test:
|
test:
|
||||||
meson test -C build --no-rebuild --verbose --suite waybar
|
meson test -C build --verbose --suite waybar
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|
||||||
|
test-detailed:
|
||||||
|
meson test -C build --verbose --print-errorlogs --test-args='--reporter console -s'
|
||||||
|
.PHONY: test-detailed
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build
|
rm -rf build
|
||||||
|
|||||||
@@ -1,22 +1,25 @@
|
|||||||
# Waybar [](LICENSE) [](https://paypal.me/ARouillard)<br>
|
# Waybar [](LICENSE) [](https://paypal.me/ARouillard)<br>
|
||||||
|
|
||||||
> Highly customizable Wayland bar for Sway and Wlroots based compositors.<br>
|
> Highly customizable Wayland bar for Sway and Wlroots based compositors.<br>
|
||||||
> Available in Arch [community](https://www.archlinux.org/packages/community/x86_64/waybar/) or
|
> Available in [all major distributions](https://github.com/Alexays/Waybar/wiki/Installation)<br>
|
||||||
[AUR](https://aur.archlinux.org/packages/waybar-git/), [Gentoo](https://packages.gentoo.org/packages/gui-apps/waybar), [openSUSE](https://build.opensuse.org/package/show/X11:Wayland/waybar), and [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=waybar).<br>
|
|
||||||
> *Waybar [examples](https://github.com/Alexays/Waybar/wiki/Examples)*
|
> *Waybar [examples](https://github.com/Alexays/Waybar/wiki/Examples)*
|
||||||
|
|
||||||
#### Current features
|
#### Current features
|
||||||
- Sway (Workspaces, Binding mode, Focused window name)
|
- Sway (Workspaces, Binding mode, Focused window name)
|
||||||
- River (Mapping mode, Tags, Focused window name)
|
- River (Mapping mode, Tags, Focused window name)
|
||||||
- Hyprland (Focused window name)
|
- Hyprland (Window Icons, Workspaces, Focused window name)
|
||||||
- DWL (Tags) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
|
- Niri (Workspaces, Focused window name, Language)
|
||||||
|
- Mango (Workspaces, Focused window name, Language, Keymode)
|
||||||
|
- DWL (Tags, Focused window name) [requires dwl ipc patch](https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/ipc)
|
||||||
- Tray [#21](https://github.com/Alexays/Waybar/issues/21)
|
- Tray [#21](https://github.com/Alexays/Waybar/issues/21)
|
||||||
- Local time
|
- Local time
|
||||||
- Battery
|
- Battery
|
||||||
- UPower
|
- UPower
|
||||||
|
- Power profiles daemon
|
||||||
- Network
|
- Network
|
||||||
- Bluetooth
|
- Bluetooth
|
||||||
- Pulseaudio
|
- Pulseaudio
|
||||||
|
- Privacy Info
|
||||||
- Wireplumber
|
- Wireplumber
|
||||||
- Disk
|
- Disk
|
||||||
- Memory
|
- Memory
|
||||||
@@ -36,7 +39,7 @@
|
|||||||
|
|
||||||
Waybar is available from a number of Linux distributions:
|
Waybar is available from a number of Linux distributions:
|
||||||
|
|
||||||
[](https://repology.org/project/waybar/versions)
|
[](https://repology.org/project/waybar/versions)
|
||||||
|
|
||||||
An Ubuntu PPA with more recent versions is available
|
An Ubuntu PPA with more recent versions is available
|
||||||
[here](https://launchpad.net/~nschloe/+archive/ubuntu/waybar).
|
[here](https://launchpad.net/~nschloe/+archive/ubuntu/waybar).
|
||||||
@@ -47,7 +50,7 @@ An Ubuntu PPA with more recent versions is available
|
|||||||
```bash
|
```bash
|
||||||
$ git clone https://github.com/Alexays/Waybar
|
$ git clone https://github.com/Alexays/Waybar
|
||||||
$ cd Waybar
|
$ cd Waybar
|
||||||
$ meson build
|
$ meson setup build
|
||||||
$ ninja -C build
|
$ ninja -C build
|
||||||
$ ./build/waybar
|
$ ./build/waybar
|
||||||
# If you want to install it
|
# If you want to install it
|
||||||
@@ -114,11 +117,45 @@ sudo apt install \
|
|||||||
libxkbregistry-dev
|
libxkbregistry-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On Arch, you can use this command:
|
||||||
|
|
||||||
|
```
|
||||||
|
pacman -S --asdeps \
|
||||||
|
gtkmm3 \
|
||||||
|
jsoncpp \
|
||||||
|
libsigc++ \
|
||||||
|
fmt \
|
||||||
|
wayland \
|
||||||
|
chrono-date \
|
||||||
|
spdlog \
|
||||||
|
gtk3 \
|
||||||
|
gobject-introspection \
|
||||||
|
libgirepository \
|
||||||
|
libpulse \
|
||||||
|
libnl \
|
||||||
|
libappindicator-gtk3 \
|
||||||
|
libdbusmenu-gtk3 \
|
||||||
|
libmpdclient \
|
||||||
|
sndio \
|
||||||
|
libevdev \
|
||||||
|
libxkbcommon \
|
||||||
|
upower \
|
||||||
|
meson \
|
||||||
|
cmake \
|
||||||
|
scdoc \
|
||||||
|
wayland-protocols \
|
||||||
|
glib2-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Contributions welcome!<br>
|
Contributions welcome!<br>
|
||||||
Have fun :)<br>
|
Have fun :)<br>
|
||||||
The style guidelines are [Google's](https://google.github.io/styleguide/cppguide.html)
|
The style guidelines are [Google's](https://google.github.io/styleguide/cppguide.html)
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> Distributions of Waybar are only released on the [official GitHub page](https://github.com/Alexays/Waybar).<br/>
|
||||||
|
> Waybar does **not** have an official website. Do not trust any sites that claim to be official.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Waybar is licensed under the MIT license. [See LICENSE for more information](https://github.com/Alexays/Waybar/blob/master/LICENSE).
|
Waybar is licensed under the MIT license. [See LICENSE for more information](https://github.com/Alexays/Waybar/blob/master/LICENSE).
|
||||||
|
|||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Suppress common address sanitizer issues in dependencies, these are often non-fixable or not an issue.
|
||||||
|
# Use it like this (when in repo root): ASAN_OPTIONS="suppressions=./asan.supp" ./build/waybar
|
||||||
|
leak:libpangoft2-1.0.so.0
|
||||||
|
leak:libgtk-3.so.0
|
||||||
|
leak:libfontconfig.so.1
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
(import (
|
||||||
|
let
|
||||||
|
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
|
||||||
|
in
|
||||||
|
fetchTarball {
|
||||||
|
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||||
|
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||||
|
}
|
||||||
|
) { src = ./.; }).defaultNix
|
||||||
Generated
+14
-64
@@ -1,77 +1,28 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"devshell": {
|
"flake-compat": {
|
||||||
"inputs": {
|
"flake": false,
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs"
|
|
||||||
},
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1667210711,
|
"lastModified": 1767039857,
|
||||||
"narHash": "sha256-IoErjXZAkzYWHEpQqwu/DeRNJGFdR7X2OGbkhMqMrpw=",
|
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||||
"owner": "numtide",
|
"owner": "edolstra",
|
||||||
"repo": "devshell",
|
"repo": "flake-compat",
|
||||||
"rev": "96a9dd12b8a447840cc246e17a47b81a4268bba7",
|
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "numtide",
|
"owner": "edolstra",
|
||||||
"repo": "devshell",
|
"repo": "flake-compat",
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1642700792,
|
|
||||||
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1667395993,
|
|
||||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1643381941,
|
"lastModified": 1769461804,
|
||||||
"narHash": "sha256-pHTwvnN4tTsEKkWlXQ8JMY423epos8wUOhthpwJjtpc=",
|
"narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "5efc8ca954272c4376ac929f4c5ffefcc20551d5",
|
"rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixpkgs-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1670152712,
|
|
||||||
"narHash": "sha256-LJttwIvJqsZIj8u1LxVRv82vwUtkzVqQVi7Wb8gxPS4=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "14ddeaebcbe9a25748221d1d7ecdf98e20e2325e",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -83,9 +34,8 @@
|
|||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"devshell": "devshell",
|
"flake-compat": "flake-compat",
|
||||||
"flake-utils": "flake-utils_2",
|
"nixpkgs": "nixpkgs"
|
||||||
"nixpkgs": "nixpkgs_2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,65 +1,126 @@
|
|||||||
{
|
{
|
||||||
description = "Highly customizable Wayland bar for Sway and Wlroots based compositors.";
|
description = "Highly customizable Wayland bar for Sway and Wlroots based compositors";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
devshell.url = "github:numtide/devshell";
|
flake-compat = {
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
url = "github:edolstra/flake-compat";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, flake-utils, devshell, nixpkgs }:
|
outputs =
|
||||||
|
{ self, nixpkgs, ... }:
|
||||||
let
|
let
|
||||||
inherit (nixpkgs) lib;
|
inherit (nixpkgs) lib;
|
||||||
genSystems = lib.genAttrs [
|
genSystems =
|
||||||
|
func:
|
||||||
|
lib.genAttrs
|
||||||
|
[
|
||||||
"x86_64-linux"
|
"x86_64-linux"
|
||||||
];
|
"aarch64-linux"
|
||||||
|
]
|
||||||
pkgsFor = genSystems (system:
|
(
|
||||||
|
system:
|
||||||
|
func (
|
||||||
import nixpkgs {
|
import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
});
|
overlays = with self.overlays; [
|
||||||
|
waybar
|
||||||
|
];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
mkDate = longDate: (lib.concatStringsSep "-" [
|
mkDate =
|
||||||
|
longDate:
|
||||||
|
(lib.concatStringsSep "-" [
|
||||||
(builtins.substring 0 4 longDate)
|
(builtins.substring 0 4 longDate)
|
||||||
(builtins.substring 4 2 longDate)
|
(builtins.substring 4 2 longDate)
|
||||||
(builtins.substring 6 2 longDate)
|
(builtins.substring 6 2 longDate)
|
||||||
]);
|
]);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
overlays.default = _: prev: rec {
|
devShells = genSystems (pkgs: {
|
||||||
waybar = prev.callPackage ./nix/default.nix {
|
default = pkgs.mkShell {
|
||||||
version = "0.9.16" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
name = "waybar-shell";
|
||||||
};
|
|
||||||
};
|
|
||||||
packages = genSystems
|
|
||||||
(system:
|
|
||||||
(self.overlays.default null pkgsFor.${system})
|
|
||||||
// {
|
|
||||||
default = self.packages.${system}.waybar;
|
|
||||||
});
|
|
||||||
} //
|
|
||||||
flake-utils.lib.eachDefaultSystem (system: {
|
|
||||||
devShell =
|
|
||||||
let pkgs = import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
|
|
||||||
overlays = [ devshell.overlay ];
|
# inherit attributes from upstream nixpkgs derivation
|
||||||
};
|
inherit (pkgs.waybar)
|
||||||
in
|
buildInputs
|
||||||
pkgs.devshell.mkShell {
|
depsBuildBuild
|
||||||
imports = [ "${pkgs.devshell.extraModulesDir}/language/c.nix" ];
|
depsBuildBuildPropagated
|
||||||
commands = [
|
depsBuildTarget
|
||||||
{
|
depsBuildTargetPropagated
|
||||||
package = pkgs.devshell.cli;
|
depsHostHost
|
||||||
help = "Per project developer environments";
|
depsHostHostPropagated
|
||||||
}
|
depsTargetTarget
|
||||||
];
|
depsTargetTargetPropagated
|
||||||
devshell.packages = with pkgs; [
|
propagatedBuildInputs
|
||||||
|
propagatedNativeBuildInputs
|
||||||
|
strictDeps
|
||||||
|
;
|
||||||
|
|
||||||
|
# overrides for local development
|
||||||
|
nativeBuildInputs =
|
||||||
|
pkgs.waybar.nativeBuildInputs
|
||||||
|
++ (with pkgs; [
|
||||||
|
nixfmt
|
||||||
clang-tools
|
clang-tools
|
||||||
gdb
|
gdb
|
||||||
];
|
]);
|
||||||
language.c.libraries = with pkgs; [
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
formatter = genSystems (
|
||||||
|
pkgs:
|
||||||
|
pkgs.treefmt.withConfig {
|
||||||
|
settings = {
|
||||||
|
formatter = {
|
||||||
|
clang-format = {
|
||||||
|
options = [ "-i" ];
|
||||||
|
command = lib.getExe' pkgs.clang-tools "clang-format";
|
||||||
|
excludes = [ ];
|
||||||
|
includes = [
|
||||||
|
"*.c"
|
||||||
|
"*.cpp"
|
||||||
|
"*.h"
|
||||||
|
"*.hpp"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
nixfmt = {
|
||||||
|
command = lib.getExe pkgs.nixfmt;
|
||||||
|
includes = [ "*.nix" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
tree-root-file = ".git/index";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
overlays = {
|
||||||
|
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: {
|
||||||
|
default = self.packages.${pkgs.stdenv.hostPlatform.system}.waybar;
|
||||||
|
inherit (pkgs) waybar;
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/box.h>
|
||||||
|
#include <gtkmm/image.h>
|
||||||
|
|
||||||
|
#include "AIconLabel.hpp"
|
||||||
|
|
||||||
|
namespace waybar {
|
||||||
|
|
||||||
|
class AAppIconLabel : public AIconLabel {
|
||||||
|
public:
|
||||||
|
AAppIconLabel(const Json::Value& config, const std::string& name, const std::string& id,
|
||||||
|
const std::string& format, uint16_t interval = 0, bool ellipsize = false,
|
||||||
|
bool enable_click = false, bool enable_scroll = false);
|
||||||
|
virtual ~AAppIconLabel() = default;
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateAppIconName(const std::string& app_identifier,
|
||||||
|
const std::string& alternative_app_identifier);
|
||||||
|
void updateAppIcon();
|
||||||
|
unsigned app_icon_size_{24};
|
||||||
|
bool update_app_icon_{true};
|
||||||
|
std::string app_icon_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glibmm/markup.h>
|
||||||
|
#include <gtkmm/label.h>
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
|
||||||
|
namespace waybar {
|
||||||
|
|
||||||
|
enum class GraphType { LINE, BAR, GAUGE };
|
||||||
|
|
||||||
|
class AGraph : public AModule {
|
||||||
|
public:
|
||||||
|
AGraph(const Json::Value&, const std::string&, const std::string&, uint16_t interval = 0,
|
||||||
|
bool enable_click = false, bool enable_scroll = false);
|
||||||
|
virtual ~AGraph() = default;
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Gtk::DrawingArea graph_;
|
||||||
|
std::deque<int> values_;
|
||||||
|
uint16_t datapoints_ = 20;
|
||||||
|
GraphType graph_type_ = GraphType::LINE;
|
||||||
|
|
||||||
|
void addValue(const int n);
|
||||||
|
|
||||||
|
const std::chrono::seconds interval_;
|
||||||
|
|
||||||
|
bool onDraw(const Cairo::RefPtr<Cairo::Context>& cr);
|
||||||
|
|
||||||
|
std::map<std::string, GtkMenuItem*> submenus_;
|
||||||
|
std::map<std::string, std::string> menuActionsMap_;
|
||||||
|
static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void drawFilledArea(const Cairo::RefPtr<Cairo::Context>& cr,
|
||||||
|
const std::vector<std::pair<double, double>>& points, double height,
|
||||||
|
const Gdk::RGBA& bg_color);
|
||||||
|
|
||||||
|
void drawLine(const Cairo::RefPtr<Cairo::Context>& cr,
|
||||||
|
const std::vector<std::pair<double, double>>& points, const Gdk::RGBA& fg_color);
|
||||||
|
|
||||||
|
void drawPath(const Cairo::RefPtr<Cairo::Context>& cr,
|
||||||
|
const std::vector<std::pair<double, double>>& points);
|
||||||
|
|
||||||
|
void drawBars(const Cairo::RefPtr<Cairo::Context>& cr, double width, double height,
|
||||||
|
int current_value, const Gdk::RGBA& fg_color);
|
||||||
|
|
||||||
|
void drawGauge(const Cairo::RefPtr<Cairo::Context>& cr, double width, double height,
|
||||||
|
int current_value, const Gdk::RGBA& fg_color);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar
|
||||||
@@ -14,10 +14,14 @@ class AIconLabel : public ALabel {
|
|||||||
bool enable_click = false, bool enable_scroll = false);
|
bool enable_click = false, bool enable_scroll = false);
|
||||||
virtual ~AIconLabel() = default;
|
virtual ~AIconLabel() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
static std::tuple<std::string, std::string> extractIcon(const std::string& input);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Gtk::Image image_;
|
Gtk::Image image_;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
|
unsigned app_icon_size_{24};
|
||||||
|
|
||||||
|
bool label_contains_icon{false};
|
||||||
|
|
||||||
bool iconEnabled() const;
|
bool iconEnabled() const;
|
||||||
};
|
};
|
||||||
|
|||||||
+63
-1
@@ -1,9 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/args.h>
|
||||||
|
#include <fmt/format.h>
|
||||||
#include <glibmm/markup.h>
|
#include <glibmm/markup.h>
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
@@ -21,12 +27,68 @@ class ALabel : public AModule {
|
|||||||
protected:
|
protected:
|
||||||
Gtk::Label label_;
|
Gtk::Label label_;
|
||||||
std::string format_;
|
std::string format_;
|
||||||
const std::chrono::seconds interval_;
|
const std::chrono::milliseconds interval_;
|
||||||
bool alt_ = false;
|
bool alt_ = false;
|
||||||
std::string default_format_;
|
std::string default_format_;
|
||||||
|
|
||||||
|
bool setLabelMarkup(const Glib::ustring& markup);
|
||||||
|
bool setTooltipMarkup(const Glib::ustring& markup);
|
||||||
|
|
||||||
|
// resolveTooltipFormat() / resolveFormat() are inherited from AModule.
|
||||||
|
|
||||||
|
// Combined label + tooltip helper. Builds a single fmt argument store from
|
||||||
|
// `args`, renders `labelFormat` into the label and the resolved tooltip format
|
||||||
|
// into the tooltip, both through the dedup-aware setters. Honors the `tooltip`
|
||||||
|
// toggle. This replaces the label/tooltip formatting boilerplate that modules
|
||||||
|
// used to duplicate. `state` selects `tooltip-format-<state>` when non-empty.
|
||||||
|
template <typename... Args>
|
||||||
|
void updateLabelAndTooltipForState(const std::string& state, const std::string& labelFormat,
|
||||||
|
const std::string& tooltipDefault, Args&&... args) {
|
||||||
|
fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||||
|
(store.push_back(std::forward<Args>(args)), ...);
|
||||||
|
setLabelMarkup(fmt::vformat(labelFormat, store));
|
||||||
|
if (tooltipEnabled()) {
|
||||||
|
setTooltipMarkup(fmt::vformat(resolveTooltipFormat(tooltipDefault, state), store));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void updateLabelAndTooltip(const std::string& labelFormat, const std::string& tooltipDefault,
|
||||||
|
Args&&... args) {
|
||||||
|
updateLabelAndTooltipForState("", labelFormat, tooltipDefault, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overloads accepting a pre-built argument store, for modules that must
|
||||||
|
// assemble a dynamic set of format arguments (e.g. per-core CPU stats) that
|
||||||
|
// cannot be expressed through a fixed variadic call.
|
||||||
|
// A non-const reference is used so this overload is preferred over the
|
||||||
|
// variadic template above (which would otherwise bind the store as a single
|
||||||
|
// forwarded argument).
|
||||||
|
void updateLabelAndTooltipForState(const std::string& state, const std::string& labelFormat,
|
||||||
|
const std::string& tooltipDefault,
|
||||||
|
fmt::dynamic_format_arg_store<fmt::format_context>& store) {
|
||||||
|
setLabelMarkup(fmt::vformat(labelFormat, store));
|
||||||
|
if (tooltipEnabled()) {
|
||||||
|
setTooltipMarkup(fmt::vformat(resolveTooltipFormat(tooltipDefault, state), store));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateLabelAndTooltip(const std::string& labelFormat, const std::string& tooltipDefault,
|
||||||
|
fmt::dynamic_format_arg_store<fmt::format_context>& store) {
|
||||||
|
updateLabelAndTooltipForState("", labelFormat, tooltipDefault, store);
|
||||||
|
}
|
||||||
|
|
||||||
bool handleToggle(GdkEventButton* const& e) override;
|
bool handleToggle(GdkEventButton* const& e) override;
|
||||||
|
void copyToClipboard(const std::string&);
|
||||||
virtual std::string getState(uint8_t value, bool lesser = false);
|
virtual std::string getState(uint8_t value, bool lesser = false);
|
||||||
|
|
||||||
|
std::map<std::string, GtkMenuItem*> submenus_;
|
||||||
|
std::map<std::string, std::string> menuActionsMap_;
|
||||||
|
static void handleGtkMenuEvent(GtkMenuItem* menuitem, gpointer data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<Glib::ustring> last_label_markup_;
|
||||||
|
std::optional<Glib::ustring> last_tooltip_markup_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
+73
-5
@@ -1,24 +1,39 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/args.h>
|
||||||
|
#include <fmt/format.h>
|
||||||
#include <glibmm/dispatcher.h>
|
#include <glibmm/dispatcher.h>
|
||||||
#include <glibmm/markup.h>
|
#include <glibmm/markup.h>
|
||||||
|
#include <gtkmm.h>
|
||||||
#include <gtkmm/eventbox.h>
|
#include <gtkmm/eventbox.h>
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "IModule.hpp"
|
#include "IModule.hpp"
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
|
|
||||||
class AModule : public IModule {
|
class AModule : public IModule {
|
||||||
public:
|
public:
|
||||||
virtual ~AModule();
|
static constexpr const char* MODULE_CLASS = "module";
|
||||||
|
|
||||||
|
~AModule() override;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
virtual auto refresh(int) -> void{};
|
virtual auto refresh(int shouldRefresh) -> void {};
|
||||||
operator Gtk::Widget&() override;
|
operator Gtk::Widget&() override;
|
||||||
auto doAction(const std::string& name) -> void override;
|
auto doAction(const std::string& name) -> void override;
|
||||||
|
|
||||||
|
/// Emitting on this dispatcher triggers a update() call
|
||||||
Glib::Dispatcher dp;
|
Glib::Dispatcher dp;
|
||||||
|
|
||||||
|
bool expandEnabled() const;
|
||||||
|
|
||||||
|
virtual void suspend() {};
|
||||||
|
virtual void resume() {};
|
||||||
|
bool shouldSuspend() const { return disable_on_sleep_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Don't need to make an object directly
|
// Don't need to make an object directly
|
||||||
// Derived classes are able to use it
|
// Derived classes are able to use it
|
||||||
@@ -28,36 +43,89 @@ class AModule : public IModule {
|
|||||||
enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT };
|
enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT };
|
||||||
|
|
||||||
SCROLL_DIR getScrollDir(GdkEventScroll* e);
|
SCROLL_DIR getScrollDir(GdkEventScroll* e);
|
||||||
bool tooltipEnabled();
|
bool tooltipEnabled() const;
|
||||||
|
|
||||||
|
// --- Generic format/tooltip resolution (config-only, usable by any module,
|
||||||
|
// ALabel-derived or not). Prefers `<key>-<state>`, then `<key>`, then default.
|
||||||
|
std::string resolveFormat(const std::string& defaultFormat, const std::string& state = "") const {
|
||||||
|
if (!state.empty() && config_["format-" + state].isString()) {
|
||||||
|
return config_["format-" + state].asString();
|
||||||
|
}
|
||||||
|
if (config_["format"].isString()) {
|
||||||
|
return config_["format"].asString();
|
||||||
|
}
|
||||||
|
return defaultFormat;
|
||||||
|
}
|
||||||
|
std::string resolveTooltipFormat(const std::string& defaultFormat,
|
||||||
|
const std::string& state = "") const {
|
||||||
|
if (!state.empty() && config_["tooltip-format-" + state].isString()) {
|
||||||
|
return config_["tooltip-format-" + state].asString();
|
||||||
|
}
|
||||||
|
if (config_["tooltip-format"].isString()) {
|
||||||
|
return config_["tooltip-format"].asString();
|
||||||
|
}
|
||||||
|
return defaultFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic tooltip for any widget: honors the `tooltip` toggle and
|
||||||
|
// `tooltip-format`, formats with the given args and applies it. Lets modules
|
||||||
|
// that are not ALabel-derived (e.g. gamemode) reuse the shared logic.
|
||||||
|
template <typename... Args>
|
||||||
|
void updateTooltip(Gtk::Widget& widget, const std::string& defaultFormat, Args&&... args) {
|
||||||
|
if (!tooltipEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
widget.set_tooltip_markup(
|
||||||
|
fmt::format(fmt::runtime(resolveTooltipFormat(defaultFormat)), std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> pid_children_;
|
||||||
const std::string name_;
|
const std::string name_;
|
||||||
const Json::Value& config_;
|
const Json::Value& config_;
|
||||||
Gtk::EventBox event_box_;
|
Gtk::EventBox event_box_;
|
||||||
|
|
||||||
|
virtual void setCursor(std::string const& c);
|
||||||
|
|
||||||
virtual bool handleToggle(GdkEventButton* const& ev);
|
virtual bool handleToggle(GdkEventButton* const& ev);
|
||||||
|
virtual bool handleMouseEnter(GdkEventCrossing* const& ev);
|
||||||
|
virtual bool handleMouseLeave(GdkEventCrossing* const& ev);
|
||||||
virtual bool handleScroll(GdkEventScroll*);
|
virtual bool handleScroll(GdkEventScroll*);
|
||||||
|
virtual bool handleRelease(GdkEventButton* const& ev);
|
||||||
|
|
||||||
|
bool disable_on_sleep_{false};
|
||||||
|
GObject* menu_ = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<int> pid_;
|
bool handleUserEvent(GdkEventButton* const& ev);
|
||||||
|
const bool isTooltip;
|
||||||
|
const bool isExpand;
|
||||||
|
bool hasUserEvents_;
|
||||||
gdouble distance_scrolled_y_;
|
gdouble distance_scrolled_y_;
|
||||||
gdouble distance_scrolled_x_;
|
gdouble distance_scrolled_x_;
|
||||||
|
sigc::connection cursor_timeout_conn_;
|
||||||
std::map<std::string, std::string> eventActionMap_;
|
std::map<std::string, std::string> eventActionMap_;
|
||||||
static const inline std::map<std::pair<uint, GdkEventType>, std::string> eventMap_{
|
static const inline std::map<std::pair<uint, GdkEventType>, std::string> eventMap_{
|
||||||
{std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), "on-click"},
|
{std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), "on-click"},
|
||||||
|
{std::make_pair(1, GdkEventType::GDK_BUTTON_RELEASE), "on-click-release"},
|
||||||
{std::make_pair(1, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click"},
|
{std::make_pair(1, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click"},
|
||||||
{std::make_pair(1, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click"},
|
{std::make_pair(1, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click"},
|
||||||
{std::make_pair(2, GdkEventType::GDK_BUTTON_PRESS), "on-click-middle"},
|
{std::make_pair(2, GdkEventType::GDK_BUTTON_PRESS), "on-click-middle"},
|
||||||
|
{std::make_pair(2, GdkEventType::GDK_BUTTON_RELEASE), "on-click-middle-release"},
|
||||||
{std::make_pair(2, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-middle"},
|
{std::make_pair(2, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-middle"},
|
||||||
{std::make_pair(2, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-middle"},
|
{std::make_pair(2, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-middle"},
|
||||||
{std::make_pair(3, GdkEventType::GDK_BUTTON_PRESS), "on-click-right"},
|
{std::make_pair(3, GdkEventType::GDK_BUTTON_PRESS), "on-click-right"},
|
||||||
|
{std::make_pair(3, GdkEventType::GDK_BUTTON_RELEASE), "on-click-right-release"},
|
||||||
{std::make_pair(3, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-right"},
|
{std::make_pair(3, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-right"},
|
||||||
{std::make_pair(3, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-right"},
|
{std::make_pair(3, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-right"},
|
||||||
{std::make_pair(8, GdkEventType::GDK_BUTTON_PRESS), "on-click-backward"},
|
{std::make_pair(8, GdkEventType::GDK_BUTTON_PRESS), "on-click-backward"},
|
||||||
|
{std::make_pair(8, GdkEventType::GDK_BUTTON_RELEASE), "on-click-backward-release"},
|
||||||
{std::make_pair(8, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-backward"},
|
{std::make_pair(8, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-backward"},
|
||||||
{std::make_pair(8, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-backward"},
|
{std::make_pair(8, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-backward"},
|
||||||
{std::make_pair(9, GdkEventType::GDK_BUTTON_PRESS), "on-click-forward"},
|
{std::make_pair(9, GdkEventType::GDK_BUTTON_PRESS), "on-click-forward"},
|
||||||
|
{std::make_pair(9, GdkEventType::GDK_BUTTON_RELEASE), "on-click-forward-release"},
|
||||||
{std::make_pair(9, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-forward"},
|
{std::make_pair(9, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-forward"},
|
||||||
{std::make_pair(9, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-forward"}};
|
{std::make_pair(9, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-forward"},
|
||||||
|
{std::make_pair(10, GdkEventType::GDK_BUTTON_PRESS), "on-click-copy"}};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "gtkmm/scale.h"
|
||||||
|
|
||||||
|
namespace waybar {
|
||||||
|
|
||||||
|
class ASlider : public AModule {
|
||||||
|
public:
|
||||||
|
ASlider(const Json::Value& config, const std::string& name, const std::string& id);
|
||||||
|
virtual void onValueChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool vertical_ = false;
|
||||||
|
int min_ = 0, max_ = 100, curr_ = 50;
|
||||||
|
Gtk::Scale scale_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar
|
||||||
+34
-25
@@ -9,9 +9,12 @@
|
|||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
|
#include "group.hpp"
|
||||||
|
#include "util/kill_signal.hpp"
|
||||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
@@ -52,44 +55,38 @@ class BarIpcClient;
|
|||||||
}
|
}
|
||||||
#endif // HAVE_SWAY
|
#endif // HAVE_SWAY
|
||||||
|
|
||||||
class BarSurface {
|
class Bar : public sigc::trackable {
|
||||||
protected:
|
|
||||||
BarSurface() = default;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void setExclusiveZone(bool enable) = 0;
|
using bar_mode_map = std::map<std::string, struct bar_mode>;
|
||||||
virtual void setLayer(bar_layer layer) = 0;
|
|
||||||
virtual void setMargins(const struct bar_margins &margins) = 0;
|
|
||||||
virtual void setPassThrough(bool enable) = 0;
|
|
||||||
virtual void setPosition(const std::string_view &position) = 0;
|
|
||||||
virtual void setSize(uint32_t width, uint32_t height) = 0;
|
|
||||||
virtual void commit(){};
|
|
||||||
|
|
||||||
virtual ~BarSurface() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Bar {
|
|
||||||
public:
|
|
||||||
using bar_mode_map = std::map<std::string_view, struct bar_mode>;
|
|
||||||
static const bar_mode_map PRESET_MODES;
|
static const bar_mode_map PRESET_MODES;
|
||||||
static const std::string_view MODE_DEFAULT;
|
static const std::string MODE_DEFAULT;
|
||||||
static const std::string_view MODE_INVISIBLE;
|
static const std::string MODE_INVISIBLE;
|
||||||
|
|
||||||
Bar(struct waybar_output* w_output, const Json::Value&);
|
Bar(struct waybar_output* w_output, const Json::Value&);
|
||||||
Bar(const Bar&) = delete;
|
Bar(const Bar&) = delete;
|
||||||
~Bar();
|
~Bar();
|
||||||
|
|
||||||
void setMode(const std::string_view &);
|
void setMode(const std::string& mode);
|
||||||
void setVisible(bool visible);
|
void setVisible(bool value);
|
||||||
void toggle();
|
void toggle();
|
||||||
|
void show();
|
||||||
|
void hide();
|
||||||
void handleSignal(int);
|
void handleSignal(int);
|
||||||
|
util::KillSignalAction getOnSigusr1Action();
|
||||||
|
util::KillSignalAction getOnSigusr2Action();
|
||||||
|
|
||||||
|
void toggleSuspend(bool suspend);
|
||||||
|
|
||||||
struct waybar_output* output;
|
struct waybar_output* output;
|
||||||
Json::Value config;
|
Json::Value config;
|
||||||
struct wl_surface* surface;
|
struct wl_surface* surface;
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
bool vertical = false;
|
|
||||||
Gtk::Window window;
|
Gtk::Window window;
|
||||||
|
Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL;
|
||||||
|
Gtk::PositionType position = Gtk::POS_TOP;
|
||||||
|
|
||||||
|
int x_global;
|
||||||
|
int y_global;
|
||||||
|
|
||||||
#ifdef HAVE_SWAY
|
#ifdef HAVE_SWAY
|
||||||
std::string bar_id;
|
std::string bar_id;
|
||||||
@@ -98,16 +95,25 @@ class Bar {
|
|||||||
private:
|
private:
|
||||||
void onMap(GdkEventAny*);
|
void onMap(GdkEventAny*);
|
||||||
auto setupWidgets() -> void;
|
auto setupWidgets() -> void;
|
||||||
void getModules(const Factory &, const std::string &, Gtk::Box *);
|
void getModules(const Factory&, const std::string&, waybar::Group*);
|
||||||
void setupAltFormatKeyForModule(const std::string& module_name);
|
void setupAltFormatKeyForModule(const std::string& module_name);
|
||||||
void setupAltFormatKeyForModuleList(const char* module_list_name);
|
void setupAltFormatKeyForModuleList(const char* module_list_name);
|
||||||
void setMode(const bar_mode&);
|
void setMode(const bar_mode&);
|
||||||
|
void setPassThrough(bool passthrough);
|
||||||
|
void setPosition(Gtk::PositionType position);
|
||||||
|
void forceLayerCommit();
|
||||||
|
void onConfigure(GdkEventConfigure* ev);
|
||||||
|
void configureGlobalOffset(int width, int height);
|
||||||
|
void onOutputGeometryChanged();
|
||||||
|
|
||||||
/* Copy initial set of modes to allow customization */
|
/* Copy initial set of modes to allow customization */
|
||||||
bar_mode_map configured_modes = PRESET_MODES;
|
bar_mode_map configured_modes = PRESET_MODES;
|
||||||
std::string last_mode_{MODE_DEFAULT};
|
std::string last_mode_{MODE_DEFAULT};
|
||||||
|
|
||||||
std::unique_ptr<BarSurface> surface_impl_;
|
struct bar_margins margins_;
|
||||||
|
uint32_t width_, height_;
|
||||||
|
bool passthrough_;
|
||||||
|
|
||||||
Gtk::Box left_;
|
Gtk::Box left_;
|
||||||
Gtk::Box center_;
|
Gtk::Box center_;
|
||||||
Gtk::Box right_;
|
Gtk::Box right_;
|
||||||
@@ -120,6 +126,9 @@ class Bar {
|
|||||||
std::unique_ptr<BarIpcClient> _ipc_client;
|
std::unique_ptr<BarIpcClient> _ipc_client;
|
||||||
#endif
|
#endif
|
||||||
std::vector<std::shared_ptr<waybar::AModule>> modules_all_;
|
std::vector<std::shared_ptr<waybar::AModule>> modules_all_;
|
||||||
|
|
||||||
|
waybar::util::KillSignalAction onSigusr1 = util::SIGNALACTION_DEFAULT_SIGUSR1;
|
||||||
|
waybar::util::KillSignalAction onSigusr2 = util::SIGNALACTION_DEFAULT_SIGUSR2;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
+13
-3
@@ -7,10 +7,12 @@
|
|||||||
|
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
|
#include "util/css_reload_helper.hpp"
|
||||||
|
#include "util/portal.hpp"
|
||||||
|
|
||||||
struct zwlr_layer_shell_v1;
|
|
||||||
struct zwp_idle_inhibitor_v1;
|
struct zwp_idle_inhibitor_v1;
|
||||||
struct zwp_idle_inhibit_manager_v1;
|
struct zwp_idle_inhibit_manager_v1;
|
||||||
|
struct ext_idle_notifier_v1;
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
|
|
||||||
@@ -24,16 +26,16 @@ class Client {
|
|||||||
Glib::RefPtr<Gdk::Display> gdk_display;
|
Glib::RefPtr<Gdk::Display> gdk_display;
|
||||||
struct wl_display* wl_display = nullptr;
|
struct wl_display* wl_display = nullptr;
|
||||||
struct wl_registry* registry = nullptr;
|
struct wl_registry* registry = nullptr;
|
||||||
struct zwlr_layer_shell_v1 *layer_shell = nullptr;
|
|
||||||
struct zxdg_output_manager_v1* xdg_output_manager = nullptr;
|
struct zxdg_output_manager_v1* xdg_output_manager = nullptr;
|
||||||
struct zwp_idle_inhibit_manager_v1* idle_inhibit_manager = nullptr;
|
struct zwp_idle_inhibit_manager_v1* idle_inhibit_manager = nullptr;
|
||||||
|
struct ext_idle_notifier_v1* idle_notifier = nullptr;
|
||||||
std::vector<std::unique_ptr<Bar>> bars;
|
std::vector<std::unique_ptr<Bar>> bars;
|
||||||
Config config;
|
Config config;
|
||||||
std::string bar_id;
|
std::string bar_id;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Client() = default;
|
Client() = default;
|
||||||
const std::string getStyle(const std::string &style);
|
const std::string getStyle(const std::string& style, std::optional<Appearance> appearance);
|
||||||
void bindInterfaces();
|
void bindInterfaces();
|
||||||
void handleOutput(struct waybar_output& output);
|
void handleOutput(struct waybar_output& output);
|
||||||
auto setupCss(const std::string& css_file) -> void;
|
auto setupCss(const std::string& css_file) -> void;
|
||||||
@@ -44,6 +46,7 @@ class Client {
|
|||||||
const char* interface, uint32_t version);
|
const char* interface, uint32_t version);
|
||||||
static void handleGlobalRemove(void* data, struct wl_registry* registry, uint32_t name);
|
static void handleGlobalRemove(void* data, struct wl_registry* registry, uint32_t name);
|
||||||
static void handleOutputDone(void*, struct zxdg_output_v1*);
|
static void handleOutputDone(void*, struct zxdg_output_v1*);
|
||||||
|
void createBarsBatch();
|
||||||
static void handleOutputName(void*, struct zxdg_output_v1*, const char*);
|
static void handleOutputName(void*, struct zxdg_output_v1*, const char*);
|
||||||
static void handleOutputDescription(void*, struct zxdg_output_v1*, const char*);
|
static void handleOutputDescription(void*, struct zxdg_output_v1*, const char*);
|
||||||
void handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor);
|
void handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor);
|
||||||
@@ -52,7 +55,14 @@ class Client {
|
|||||||
|
|
||||||
Glib::RefPtr<Gtk::StyleContext> style_context_;
|
Glib::RefPtr<Gtk::StyleContext> style_context_;
|
||||||
Glib::RefPtr<Gtk::CssProvider> css_provider_;
|
Glib::RefPtr<Gtk::CssProvider> css_provider_;
|
||||||
|
std::unique_ptr<Portal> portal;
|
||||||
std::list<struct waybar_output> outputs_;
|
std::list<struct waybar_output> outputs_;
|
||||||
|
std::unique_ptr<CssReloadHelper> m_cssReloadHelper;
|
||||||
|
std::string m_cssFile;
|
||||||
|
sigc::connection monitor_added_connection_;
|
||||||
|
sigc::connection monitor_removed_connection_;
|
||||||
|
std::list<waybar_output*> pending_outputs_;
|
||||||
|
bool bars_scheduled_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ class Config {
|
|||||||
static std::optional<std::string> findConfigPath(
|
static std::optional<std::string> findConfigPath(
|
||||||
const std::vector<std::string>& names, const std::vector<std::string>& dirs = CONFIG_DIRS);
|
const std::vector<std::string>& names, const std::vector<std::string>& dirs = CONFIG_DIRS);
|
||||||
|
|
||||||
|
static std::vector<std::string> tryExpandPath(const std::string& base,
|
||||||
|
const std::string& filename);
|
||||||
|
|
||||||
Config() = default;
|
Config() = default;
|
||||||
|
|
||||||
void load(const std::string& config);
|
void load(const std::string& config);
|
||||||
@@ -32,6 +35,8 @@ class Config {
|
|||||||
void setupConfig(Json::Value& dst, const std::string& config_file, int depth);
|
void setupConfig(Json::Value& dst, const std::string& config_file, int depth);
|
||||||
void resolveConfigIncludes(Json::Value& config, int depth);
|
void resolveConfigIncludes(Json::Value& config, int depth);
|
||||||
void mergeConfig(Json::Value& a_config_, Json::Value& b_config_);
|
void mergeConfig(Json::Value& a_config_, Json::Value& b_config_);
|
||||||
|
static std::vector<std::string> findIncludePath(
|
||||||
|
const std::string& name, const std::vector<std::string>& dirs = CONFIG_DIRS);
|
||||||
|
|
||||||
std::string config_file_;
|
std::string config_file_;
|
||||||
|
|
||||||
|
|||||||
+5
-91
@@ -1,103 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
#if defined(HAVE_CHRONO_TIMEZONES) || defined(HAVE_LIBDATE)
|
|
||||||
#include "modules/clock.hpp"
|
#include <AModule.hpp>
|
||||||
#else
|
|
||||||
#include "modules/simpleclock.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SWAY
|
|
||||||
#include "modules/sway/language.hpp"
|
|
||||||
#include "modules/sway/mode.hpp"
|
|
||||||
#include "modules/sway/scratchpad.hpp"
|
|
||||||
#include "modules/sway/window.hpp"
|
|
||||||
#include "modules/sway/workspaces.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WLR
|
|
||||||
#include "modules/wlr/taskbar.hpp"
|
|
||||||
#include "modules/wlr/workspace_manager.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_RIVER
|
|
||||||
#include "modules/river/layout.hpp"
|
|
||||||
#include "modules/river/mode.hpp"
|
|
||||||
#include "modules/river/tags.hpp"
|
|
||||||
#include "modules/river/window.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_DWL
|
|
||||||
#include "modules/dwl/tags.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_HYPRLAND
|
|
||||||
#include "modules/hyprland/backend.hpp"
|
|
||||||
#include "modules/hyprland/language.hpp"
|
|
||||||
#include "modules/hyprland/submap.hpp"
|
|
||||||
#include "modules/hyprland/window.hpp"
|
|
||||||
#endif
|
|
||||||
#if defined(__FreeBSD__) || (defined(__linux__) && !defined(NO_FILESYSTEM))
|
|
||||||
#include "modules/battery.hpp"
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_CPU_LINUX) || defined(HAVE_CPU_BSD)
|
|
||||||
#include "modules/cpu.hpp"
|
|
||||||
#endif
|
|
||||||
#include "modules/idle_inhibitor.hpp"
|
|
||||||
#if defined(HAVE_MEMORY_LINUX) || defined(HAVE_MEMORY_BSD)
|
|
||||||
#include "modules/memory.hpp"
|
|
||||||
#endif
|
|
||||||
#include "modules/disk.hpp"
|
|
||||||
#ifdef HAVE_DBUSMENU
|
|
||||||
#include "modules/sni/tray.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_MPRIS
|
|
||||||
#include "modules/mpris/mpris.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBNL
|
|
||||||
#include "modules/network.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBUDEV
|
|
||||||
#include "modules/backlight.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBEVDEV
|
|
||||||
#include "modules/keyboard_state.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GAMEMODE
|
|
||||||
#include "modules/gamemode.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UPOWER
|
|
||||||
#include "modules/upower/upower.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBPULSE
|
|
||||||
#include "modules/pulseaudio.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBMPDCLIENT
|
|
||||||
#include "modules/mpd/mpd.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBSNDIO
|
|
||||||
#include "modules/sndio.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GIO_UNIX
|
|
||||||
#include "modules/bluetooth.hpp"
|
|
||||||
#include "modules/inhibitor.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBJACK
|
|
||||||
#include "modules/jack.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBWIREPLUMBER
|
|
||||||
#include "modules/wireplumber.hpp"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBCAVA
|
|
||||||
#include "modules/cava.hpp"
|
|
||||||
#endif
|
|
||||||
#include "bar.hpp"
|
|
||||||
#include "modules/custom.hpp"
|
|
||||||
#include "modules/image.hpp"
|
|
||||||
#include "modules/temperature.hpp"
|
|
||||||
#include "modules/user.hpp"
|
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
|
|
||||||
|
class Bar;
|
||||||
|
|
||||||
class Factory {
|
class Factory {
|
||||||
public:
|
public:
|
||||||
Factory(const Bar& bar, const Json::Value& config);
|
Factory(const Bar& bar, const Json::Value& config);
|
||||||
AModule* makeModule(const std::string& name) const;
|
AModule* makeModule(const std::string& name, const std::string& pos) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
|
|||||||
+23
-3
@@ -5,18 +5,38 @@
|
|||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
#include "bar.hpp"
|
#include "gtkmm/revealer.h"
|
||||||
#include "factory.hpp"
|
|
||||||
|
|
||||||
namespace waybar {
|
namespace waybar {
|
||||||
|
|
||||||
class Group : public AModule {
|
class Group : public AModule {
|
||||||
|
sigc::connection reveal_timeout_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Group(const std::string&, const std::string&, const Json::Value&, bool);
|
Group(const std::string&, const std::string&, const Json::Value&, bool);
|
||||||
~Group() = default;
|
~Group() override = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
operator Gtk::Widget&() override;
|
operator Gtk::Widget&() override;
|
||||||
|
|
||||||
|
virtual Gtk::Box& getBox();
|
||||||
|
void addWidget(Gtk::Widget& widget);
|
||||||
|
|
||||||
|
protected:
|
||||||
Gtk::Box box;
|
Gtk::Box box;
|
||||||
|
Gtk::Box revealer_box;
|
||||||
|
Gtk::Revealer revealer;
|
||||||
|
bool is_first_widget = true;
|
||||||
|
bool is_drawer = false;
|
||||||
|
bool click_to_reveal = false;
|
||||||
|
bool empty_if_drawer_empty = false;
|
||||||
|
int reveal_delay = 0;
|
||||||
|
std::string add_class_to_drawer_children;
|
||||||
|
bool handleMouseEnter(GdkEventCrossing* const& ev) override;
|
||||||
|
bool handleMouseLeave(GdkEventCrossing* const& ev) override;
|
||||||
|
bool handleToggle(GdkEventButton* const& ev) override;
|
||||||
|
bool handleScroll(GdkEventScroll* e) override;
|
||||||
|
void show_group();
|
||||||
|
void hide_group();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "giomm/dbusproxy.h"
|
#include "util/backlight_backend.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
|
||||||
|
|
||||||
struct udev;
|
struct udev;
|
||||||
struct udev_device;
|
struct udev_device;
|
||||||
@@ -16,54 +16,17 @@ struct udev_device;
|
|||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Backlight : public ALabel {
|
class Backlight : public ALabel {
|
||||||
class BacklightDev {
|
|
||||||
public:
|
|
||||||
BacklightDev() = default;
|
|
||||||
BacklightDev(std::string name, int actual, int max, bool powered);
|
|
||||||
std::string_view name() const;
|
|
||||||
int get_actual() const;
|
|
||||||
void set_actual(int actual);
|
|
||||||
int get_max() const;
|
|
||||||
void set_max(int max);
|
|
||||||
bool get_powered() const;
|
|
||||||
void set_powered(bool powered);
|
|
||||||
friend inline bool operator==(const BacklightDev &lhs, const BacklightDev &rhs) {
|
|
||||||
return lhs.name_ == rhs.name_ && lhs.actual_ == rhs.actual_ && lhs.max_ == rhs.max_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string name_;
|
|
||||||
int actual_ = 1;
|
|
||||||
int max_ = 1;
|
|
||||||
bool powered_ = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Backlight(const std::string&, const Json::Value&);
|
Backlight(const std::string&, const Json::Value&);
|
||||||
virtual ~Backlight();
|
virtual ~Backlight() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
|
||||||
template <class ForwardIt>
|
|
||||||
static const BacklightDev *best_device(ForwardIt first, ForwardIt last, std::string_view);
|
|
||||||
template <class ForwardIt, class Inserter>
|
|
||||||
static void upsert_device(ForwardIt first, ForwardIt last, Inserter inserter, udev_device *dev);
|
|
||||||
template <class ForwardIt, class Inserter>
|
|
||||||
static void enumerate_devices(ForwardIt first, ForwardIt last, Inserter inserter, udev *udev);
|
|
||||||
|
|
||||||
bool handleScroll(GdkEventScroll* e) override;
|
bool handleScroll(GdkEventScroll* e) override;
|
||||||
|
|
||||||
const std::string preferred_device_;
|
const std::string preferred_device_;
|
||||||
static constexpr int EPOLL_MAX_EVENTS = 16;
|
|
||||||
|
|
||||||
std::optional<BacklightDev> previous_best_;
|
|
||||||
std::string previous_format_;
|
std::string previous_format_;
|
||||||
|
|
||||||
std::mutex udev_thread_mutex_;
|
util::BacklightBackend backend;
|
||||||
std::vector<BacklightDev> devices_;
|
|
||||||
// thread must destruct before shared data
|
|
||||||
util::SleeperThread udev_thread_;
|
|
||||||
|
|
||||||
Glib::RefPtr<Gio::DBus::Proxy> login_proxy_;
|
|
||||||
};
|
};
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#include "ASlider.hpp"
|
||||||
|
#include "util/backlight_backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class BacklightSlider : public ASlider {
|
||||||
|
public:
|
||||||
|
BacklightSlider(const std::string&, const Json::Value&);
|
||||||
|
virtual ~BacklightSlider() = default;
|
||||||
|
|
||||||
|
void update() override;
|
||||||
|
void onValueChanged() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::chrono::milliseconds interval_;
|
||||||
|
std::string preferred_device_;
|
||||||
|
util::BacklightBackend backend;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
+21
-13
@@ -1,34 +1,31 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef FILESYSTEM_EXPERIMENTAL
|
|
||||||
#include <experimental/filesystem>
|
|
||||||
#else
|
|
||||||
#include <filesystem>
|
|
||||||
#endif
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
#include "util/udev_deleter.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
#ifdef FILESYSTEM_EXPERIMENTAL
|
|
||||||
namespace fs = std::experimental::filesystem;
|
|
||||||
#else
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
#endif
|
|
||||||
|
|
||||||
class Battery : public ALabel {
|
class Battery : public ALabel {
|
||||||
public:
|
public:
|
||||||
Battery(const std::string&, const Json::Value&);
|
Battery(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
virtual ~Battery();
|
virtual ~Battery();
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
@@ -38,17 +35,28 @@ class Battery : public ALabel {
|
|||||||
void refreshBatteries();
|
void refreshBatteries();
|
||||||
void worker();
|
void worker();
|
||||||
const std::string getAdapterStatus(uint8_t capacity) const;
|
const std::string getAdapterStatus(uint8_t capacity) const;
|
||||||
const std::tuple<uint8_t, float, std::string, float> getInfos();
|
std::tuple<uint8_t, float, std::string, float, uint16_t, float> getInfos();
|
||||||
const std::string formatTimeRemaining(float hoursRemaining);
|
const std::string formatTimeRemaining(float hoursRemaining);
|
||||||
|
void setBarClass(std::string&);
|
||||||
|
void processEvents(std::string& state, std::string& status, uint8_t capacity);
|
||||||
|
|
||||||
int global_watch;
|
|
||||||
std::map<fs::path, int> batteries_;
|
std::map<fs::path, int> batteries_;
|
||||||
|
std::unique_ptr<udev, util::UdevDeleter> udev_;
|
||||||
|
std::array<pollfd, 1> poll_fds_;
|
||||||
|
std::unique_ptr<udev_monitor, util::UdevMonitorDeleter> mon_;
|
||||||
fs::path adapter_;
|
fs::path adapter_;
|
||||||
int battery_watch_fd_;
|
int battery_watch_fd_;
|
||||||
int global_watch_fd_;
|
|
||||||
std::mutex battery_list_mutex_;
|
std::mutex battery_list_mutex_;
|
||||||
std::string old_status_;
|
std::string old_status_;
|
||||||
|
std::string last_event_;
|
||||||
bool warnFirstTime_{true};
|
bool warnFirstTime_{true};
|
||||||
|
bool weightedAverage_{true};
|
||||||
|
const Bar& bar_;
|
||||||
|
bool smoothPowerEnable_{false};
|
||||||
|
double time_constant_s_{260.0};
|
||||||
|
double smooth_power_{0.0}; // µW
|
||||||
|
std::chrono::steady_clock::time_point last_t_{std::chrono::steady_clock::now()};
|
||||||
|
std::string old_status_raw_{""};
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
util::SleeperThread thread_battery_update_;
|
util::SleeperThread thread_battery_update_;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class Bluetooth : public ALabel {
|
|||||||
bool services_resolved;
|
bool services_resolved;
|
||||||
// NOTE: experimental feature in bluez
|
// NOTE: experimental feature in bluez
|
||||||
std::optional<unsigned char> battery_percentage;
|
std::optional<unsigned char> battery_percentage;
|
||||||
|
std::optional<unsigned char> battery_percentage_peripheral;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -49,6 +50,9 @@ class Bluetooth : public ALabel {
|
|||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static auto onObjectAdded(GDBusObjectManager*, GDBusObject*, gpointer) -> void;
|
||||||
|
static auto onObjectRemoved(GDBusObjectManager*, GDBusObject*, gpointer) -> void;
|
||||||
|
|
||||||
static auto onInterfaceAddedOrRemoved(GDBusObjectManager*, GDBusObject*, GDBusInterface*,
|
static auto onInterfaceAddedOrRemoved(GDBusObjectManager*, GDBusObject*, GDBusInterface*,
|
||||||
gpointer) -> void;
|
gpointer) -> void;
|
||||||
static auto onInterfaceProxyPropertiesChanged(GDBusObjectManagerClient*, GDBusObjectProxy*,
|
static auto onInterfaceProxyPropertiesChanged(GDBusObjectManagerClient*, GDBusObjectProxy*,
|
||||||
@@ -56,10 +60,17 @@ class Bluetooth : public ALabel {
|
|||||||
gpointer) -> void;
|
gpointer) -> void;
|
||||||
|
|
||||||
auto getDeviceBatteryPercentage(GDBusObject*) -> std::optional<unsigned char>;
|
auto getDeviceBatteryPercentage(GDBusObject*) -> std::optional<unsigned char>;
|
||||||
|
auto getDeviceGattBatteryLevels(GDBusObject*, std::optional<unsigned char>&,
|
||||||
|
std::optional<unsigned char>&) -> void;
|
||||||
|
static auto processBatteryServiceCharacteristics(GList*, const std::string&, const std::string&,
|
||||||
|
const std::string&,
|
||||||
|
std::optional<unsigned char>&,
|
||||||
|
std::optional<unsigned char>&) -> void;
|
||||||
auto getDeviceProperties(GDBusObject*, DeviceInfo&) -> bool;
|
auto getDeviceProperties(GDBusObject*, DeviceInfo&) -> bool;
|
||||||
auto getControllerProperties(GDBusObject*, ControllerInfo&) -> bool;
|
auto getControllerProperties(GDBusObject*, ControllerInfo&) -> bool;
|
||||||
|
|
||||||
auto findCurController(ControllerInfo&) -> bool;
|
// Returns std::nullopt if no controller could be found
|
||||||
|
auto findCurController() -> std::optional<ControllerInfo>;
|
||||||
auto findConnectedDevices(const std::string&, std::vector<DeviceInfo>&) -> void;
|
auto findConnectedDevices(const std::string&, std::vector<DeviceInfo>&) -> void;
|
||||||
|
|
||||||
#ifdef WANT_RFKILL
|
#ifdef WANT_RFKILL
|
||||||
@@ -68,7 +79,7 @@ class Bluetooth : public ALabel {
|
|||||||
const std::unique_ptr<GDBusObjectManager, void (*)(GDBusObjectManager*)> manager_;
|
const std::unique_ptr<GDBusObjectManager, void (*)(GDBusObjectManager*)> manager_;
|
||||||
|
|
||||||
std::string state_;
|
std::string state_;
|
||||||
ControllerInfo cur_controller_;
|
std::optional<ControllerInfo> cur_controller_;
|
||||||
std::vector<DeviceInfo> connected_devices_;
|
std::vector<DeviceInfo> connected_devices_;
|
||||||
DeviceInfo cur_focussed_device_;
|
DeviceInfo cur_focussed_device_;
|
||||||
std::string device_enumerate_;
|
std::string device_enumerate_;
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
|
||||||
#include "util/sleeper_thread.hpp"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <cava/common.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace waybar::modules {
|
|
||||||
using namespace std::literals::chrono_literals;
|
|
||||||
|
|
||||||
class Cava final : public ALabel {
|
|
||||||
public:
|
|
||||||
Cava(const std::string&, const Json::Value&);
|
|
||||||
virtual ~Cava();
|
|
||||||
auto update() -> void override;
|
|
||||||
auto doAction(const std::string& name) -> void override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
util::SleeperThread thread_;
|
|
||||||
util::SleeperThread thread_fetch_input_;
|
|
||||||
|
|
||||||
struct error_s error_ {}; // cava errors
|
|
||||||
struct config_params prm_ {}; // cava parameters
|
|
||||||
struct audio_raw audio_raw_ {}; // cava handled raw audio data(is based on audio_data)
|
|
||||||
struct audio_data audio_data_ {}; // cava audio data
|
|
||||||
struct cava_plan* plan_; //{new cava_plan{}};
|
|
||||||
// Cava API to read audio source
|
|
||||||
ptr input_source_;
|
|
||||||
// Delay to handle audio source
|
|
||||||
std::chrono::milliseconds frame_time_milsec_{1s};
|
|
||||||
// Text to display
|
|
||||||
std::string text_{""};
|
|
||||||
int rePaint_{1};
|
|
||||||
std::chrono::seconds fetch_input_delay_{4};
|
|
||||||
std::chrono::seconds suspend_silence_delay_{0};
|
|
||||||
bool silence_{false};
|
|
||||||
int sleep_counter_{0};
|
|
||||||
// Cava method
|
|
||||||
void pause_resume();
|
|
||||||
// ModuleActionMap
|
|
||||||
static inline std::map<const std::string, void (waybar::modules::Cava::*const)()> actionMap_{
|
|
||||||
{"mode", &waybar::modules::Cava::pause_resume}};
|
|
||||||
};
|
|
||||||
} // namespace waybar::modules
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <epoxy/gl.h>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "cava_backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
|
||||||
|
class CavaGLSL final : public AModule, public Gtk::GLArea {
|
||||||
|
public:
|
||||||
|
CavaGLSL(const std::string&, const Json::Value&);
|
||||||
|
~CavaGLSL() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<CavaBackend> backend_;
|
||||||
|
struct ::cava::config_params prm_;
|
||||||
|
int frame_counter{0};
|
||||||
|
bool silence_{false};
|
||||||
|
bool hide_on_silence_{false};
|
||||||
|
// Cava method
|
||||||
|
auto onUpdate(const ::cava::audio_raw& input) -> void;
|
||||||
|
auto onSilence() -> void;
|
||||||
|
// Member variable to store the shared pointer
|
||||||
|
std::shared_ptr<::cava::audio_raw> m_data_;
|
||||||
|
GLuint shaderProgram_;
|
||||||
|
// OpenGL variables
|
||||||
|
GLuint fbo_;
|
||||||
|
GLuint texture_;
|
||||||
|
GLint uniform_bars_;
|
||||||
|
GLint uniform_previous_bars_;
|
||||||
|
GLint uniform_bars_count_;
|
||||||
|
GLint uniform_time_;
|
||||||
|
// Methods
|
||||||
|
void onRealize();
|
||||||
|
bool onRender(const Glib::RefPtr<Gdk::GLContext>& context);
|
||||||
|
|
||||||
|
void initShaders();
|
||||||
|
void initSurface();
|
||||||
|
void initGLSL();
|
||||||
|
GLuint loadShader(const std::string& fileName, GLenum type);
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "cava_backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
|
||||||
|
class Cava final : public ALabel, public sigc::trackable {
|
||||||
|
public:
|
||||||
|
Cava(const std::string&, const Json::Value&);
|
||||||
|
~Cava() = default;
|
||||||
|
auto doAction(const std::string& name) -> void override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<CavaBackend> backend_;
|
||||||
|
// Text to display
|
||||||
|
Glib::ustring label_text_{""};
|
||||||
|
bool silence_{false};
|
||||||
|
bool hide_on_silence_{false};
|
||||||
|
std::string format_silent_{""};
|
||||||
|
int ascii_range_{0};
|
||||||
|
// Cava method
|
||||||
|
void pause_resume();
|
||||||
|
auto onUpdate(const std::string& input) -> void;
|
||||||
|
auto onSilence() -> void;
|
||||||
|
// ModuleActionMap
|
||||||
|
static inline std::map<const std::string, void (waybar::modules::cava::Cava::* const)()>
|
||||||
|
actionMap_{{"mode", &waybar::modules::cava::Cava::pause_resume}};
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <sigc++/sigc++.h>
|
||||||
|
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace cava {
|
||||||
|
extern "C" {
|
||||||
|
// Need sdl_glsl output feature to be enabled on libcava
|
||||||
|
#ifndef SDL_GLSL
|
||||||
|
#define SDL_GLSL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cava/common.h>
|
||||||
|
|
||||||
|
#ifdef SDL_GLSL
|
||||||
|
#undef SDL_GLSL
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} // namespace cava
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
|
class CavaBackend final {
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<CavaBackend> inst(const Json::Value& config);
|
||||||
|
|
||||||
|
virtual ~CavaBackend();
|
||||||
|
// Methods
|
||||||
|
int getAsciiRange();
|
||||||
|
void doPauseResume();
|
||||||
|
void Update();
|
||||||
|
const struct ::cava::config_params* getPrm();
|
||||||
|
std::chrono::milliseconds getFrameTimeMilsec();
|
||||||
|
|
||||||
|
// Signal accessor
|
||||||
|
using type_signal_update = sigc::signal<void(const std::string&)>;
|
||||||
|
type_signal_update signal_update();
|
||||||
|
using type_signal_audio_raw_update = sigc::signal<void(const ::cava::audio_raw&)>;
|
||||||
|
type_signal_audio_raw_update signal_audio_raw_update();
|
||||||
|
using type_signal_silence = sigc::signal<void()>;
|
||||||
|
type_signal_silence signal_silence();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CavaBackend(const Json::Value& config);
|
||||||
|
util::SleeperThread read_thread_;
|
||||||
|
util::SleeperThread out_thread_;
|
||||||
|
|
||||||
|
// Cava API to read audio source
|
||||||
|
::cava::ptr input_source_{NULL};
|
||||||
|
|
||||||
|
struct ::cava::error_s error_{}; // cava errors
|
||||||
|
struct ::cava::config_params prm_{}; // cava parameters
|
||||||
|
struct ::cava::audio_raw audio_raw_{}; // cava handled raw audio data(is based on audio_data)
|
||||||
|
struct ::cava::audio_data audio_data_{}; // cava audio data
|
||||||
|
struct ::cava::cava_plan* plan_{NULL}; //{new cava_plan{}};
|
||||||
|
|
||||||
|
std::chrono::seconds fetch_input_delay_{4};
|
||||||
|
// Delay to handle audio source
|
||||||
|
std::chrono::milliseconds frame_time_milsec_{1s};
|
||||||
|
|
||||||
|
const Json::Value& config_;
|
||||||
|
int re_paint_{0};
|
||||||
|
bool silence_{false};
|
||||||
|
bool silence_prev_{false};
|
||||||
|
std::chrono::seconds suspend_silence_delay_{0};
|
||||||
|
int sleep_counter_{0};
|
||||||
|
std::string output_{};
|
||||||
|
// Methods
|
||||||
|
void invoke();
|
||||||
|
void execute();
|
||||||
|
bool isSilence();
|
||||||
|
void doUpdate(bool force = false);
|
||||||
|
void loadConfig();
|
||||||
|
void freeBackend();
|
||||||
|
|
||||||
|
// Signal
|
||||||
|
type_signal_update m_signal_update_;
|
||||||
|
type_signal_audio_raw_update m_signal_audio_raw_;
|
||||||
|
type_signal_silence m_signal_silence_;
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBCAVA
|
||||||
|
#include "cavaRaw.hpp"
|
||||||
|
#include "cava_backend.hpp"
|
||||||
|
#ifdef HAVE_LIBCAVAGLSL
|
||||||
|
#include "cavaGLSL.hpp"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace waybar::modules::cava {
|
||||||
|
AModule* getModule(const std::string& id, const Json::Value& config) {
|
||||||
|
#ifdef HAVE_LIBCAVA
|
||||||
|
const std::shared_ptr<CavaBackend> backend_{waybar::modules::cava::CavaBackend::inst(config)};
|
||||||
|
switch (backend_->getPrm()->output) {
|
||||||
|
#ifdef HAVE_LIBCAVAGLSL
|
||||||
|
case ::cava::output_method::OUTPUT_SDL_GLSL:
|
||||||
|
return new waybar::modules::cava::CavaGLSL(id, config);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return new waybar::modules::cava::Cava(id, config);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
throw std::runtime_error("Unknown module");
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::cava
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "util/command.hpp"
|
||||||
|
#include "util/json.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
namespace ffi {
|
||||||
|
extern "C" {
|
||||||
|
typedef struct wbcffi_module wbcffi_module;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
wbcffi_module* obj;
|
||||||
|
const char* waybar_version;
|
||||||
|
GtkContainer* (*get_root_widget)(wbcffi_module*);
|
||||||
|
void (*queue_update)(wbcffi_module*);
|
||||||
|
} wbcffi_init_info;
|
||||||
|
|
||||||
|
struct wbcffi_config_entry {
|
||||||
|
const char* key;
|
||||||
|
const char* value;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} // namespace ffi
|
||||||
|
|
||||||
|
class CFFI : public AModule {
|
||||||
|
public:
|
||||||
|
CFFI(const std::string&, const std::string&, const Json::Value&);
|
||||||
|
virtual ~CFFI();
|
||||||
|
|
||||||
|
virtual auto refresh(int signal) -> void override;
|
||||||
|
virtual auto doAction(const std::string& name) -> void override;
|
||||||
|
virtual auto update() -> void override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
///
|
||||||
|
void* cffi_instance_ = nullptr;
|
||||||
|
|
||||||
|
typedef void*(InitFn)(const ffi::wbcffi_init_info* init_info,
|
||||||
|
const ffi::wbcffi_config_entry* config_entries, size_t config_entries_len);
|
||||||
|
typedef void(DenitFn)(void* instance);
|
||||||
|
typedef void(RefreshFn)(void* instance, int signal);
|
||||||
|
typedef void(DoActionFn)(void* instance, const char* name);
|
||||||
|
typedef void(UpdateFn)(void* instance);
|
||||||
|
|
||||||
|
// FFI hooks
|
||||||
|
struct {
|
||||||
|
std::function<InitFn> init = nullptr;
|
||||||
|
std::function<DenitFn> deinit = nullptr;
|
||||||
|
std::function<RefreshFn> refresh = [](void*, int) {};
|
||||||
|
std::function<DoActionFn> doAction = [](void*, const char*) {};
|
||||||
|
std::function<UpdateFn> update = [](void*) {};
|
||||||
|
} hooks_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
+63
-38
@@ -6,67 +6,92 @@
|
|||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
const std::string kCalendarPlaceholder = "calendar";
|
const std::string kCldPlaceholder{"calendar"};
|
||||||
const std::string KTimezonedTimeListPlaceholder = "timezoned_time_list";
|
const std::string kTZPlaceholder{"tz_list"};
|
||||||
|
const std::string kOrdPlaceholder{"ordinal_date"};
|
||||||
enum class WeeksSide {
|
|
||||||
LEFT,
|
|
||||||
RIGHT,
|
|
||||||
HIDDEN,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class CldMode { MONTH, YEAR };
|
enum class CldMode { MONTH, YEAR };
|
||||||
|
enum class WS { LEFT, RIGHT, HIDDEN };
|
||||||
|
|
||||||
class Clock final : public ALabel {
|
class Clock final : public ALabel {
|
||||||
public:
|
public:
|
||||||
Clock(const std::string&, const Json::Value&);
|
Clock(const std::string&, const Json::Value&);
|
||||||
virtual ~Clock() = default;
|
virtual ~Clock() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
auto doAction(const std::string& name) -> void override;
|
auto doAction(const std::string&) -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
util::SleeperThread thread_;
|
const std::locale m_locale_;
|
||||||
std::locale locale_;
|
// tooltip
|
||||||
std::vector<const date::time_zone*> time_zones_;
|
const std::string m_tlpFmt_;
|
||||||
int current_time_zone_idx_;
|
std::string m_tlpText_{""}; // tooltip text to print
|
||||||
bool is_calendar_in_tooltip_;
|
const Glib::RefPtr<Gtk::Label> m_tooltip_; // tooltip as a separate Gtk::Label
|
||||||
bool is_timezoned_list_in_tooltip_;
|
bool query_tlp_cb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
|
||||||
|
// Calendar
|
||||||
auto first_day_of_week() -> date::weekday;
|
const bool cldInTooltip_; // calendar in tooltip
|
||||||
const date::time_zone* current_timezone();
|
/*
|
||||||
bool is_timezone_fixed();
|
0 - calendar.format.months
|
||||||
auto timezones_text(std::chrono::system_clock::time_point* now) -> std::string;
|
1 - calendar.format.weekdays
|
||||||
|
2 - calendar.format.days
|
||||||
/*Calendar properties*/
|
3 - calendar.format.today
|
||||||
WeeksSide cldWPos_{WeeksSide::HIDDEN};
|
4 - calendar.format.weeks
|
||||||
|
5 - tooltip-format
|
||||||
|
*/
|
||||||
std::map<int, std::string const> fmtMap_;
|
std::map<int, std::string const> fmtMap_;
|
||||||
|
uint cldMonCols_{3}; // calendar count month columns
|
||||||
|
int cldWnLen_{3}; // calendar week number length
|
||||||
|
const int cldMonColLen_{20}; // calendar month column length
|
||||||
|
WS cldWPos_{WS::HIDDEN}; // calendar week side to print
|
||||||
|
date::months cldCurrShift_{0}; // calendar months shift
|
||||||
|
int cldShift_{1}; // calendar months shift factor
|
||||||
|
date::year_month_day cldYearShift_; // calendar Year mode. Cached ymd
|
||||||
|
std::string cldYearCached_; // calendar Year mode. Cached calendar
|
||||||
|
date::year_month cldMonShift_; // calendar Month mode. Cached ym
|
||||||
|
std::string cldMonCached_; // calendar Month mode. Cached calendar
|
||||||
|
date::day cldBaseDay_{0}; // calendar Cached day. Is used when today is changing(midnight)
|
||||||
|
std::string cldText_{""}; // calendar text to print
|
||||||
|
bool iso8601Calendar_{false}; // whether the calendar is in ISO8601
|
||||||
CldMode cldMode_{CldMode::MONTH};
|
CldMode cldMode_{CldMode::MONTH};
|
||||||
uint cldMonCols_{3}; // Count of the month in the row
|
auto get_calendar(const date::year_month_day& today, const date::year_month_day& ymd,
|
||||||
int cldMonColLen_{20}; // Length of the month column
|
const date::time_zone* tz) -> const std::string;
|
||||||
int cldWnLen_{3}; // Length of the week number
|
|
||||||
date::year_month_day cldYearShift_;
|
// get local time zone
|
||||||
date::year_month cldMonShift_;
|
auto local_zone() -> const date::time_zone*;
|
||||||
date::months cldCurrShift_{0};
|
|
||||||
date::months cldShift_{0};
|
// time zoned time in tooltip
|
||||||
std::string cldYearCached_{};
|
const bool tzInTooltip_; // if need to print time zones text
|
||||||
std::string cldMonCached_{};
|
std::vector<const date::time_zone*> tzList_; // time zones list
|
||||||
date::day cldBaseDay_{0};
|
int tzCurrIdx_; // current time zone index for tzList_
|
||||||
/*Calendar functions*/
|
std::string tzText_{""}; // time zones text to print
|
||||||
auto get_calendar(const date::zoned_seconds& now, const date::zoned_seconds& wtime)
|
std::string tzTooltipFormat_{""}; // optional timezone tooltip format
|
||||||
-> std::string;
|
util::SleeperThread thread_;
|
||||||
/*Clock actions*/
|
|
||||||
|
// ordinal date in tooltip
|
||||||
|
const bool ordInTooltip_;
|
||||||
|
std::string ordText_{""};
|
||||||
|
auto get_ordinal_date(const date::year_month_day& today) -> std::string;
|
||||||
|
|
||||||
|
auto getTZtext(date::sys_seconds now) -> std::string;
|
||||||
|
auto first_day_of_week() -> date::weekday;
|
||||||
|
// Module actions
|
||||||
void cldModeSwitch();
|
void cldModeSwitch();
|
||||||
void cldShift_up();
|
void cldShift_up();
|
||||||
void cldShift_down();
|
void cldShift_down();
|
||||||
|
void cldShift_reset();
|
||||||
void tz_up();
|
void tz_up();
|
||||||
void tz_down();
|
void tz_down();
|
||||||
|
void action_exec(const std::string& action);
|
||||||
// Module Action Map
|
// Module Action Map
|
||||||
static inline std::map<const std::string, void (waybar::modules::Clock::* const)()> actionMap_{
|
static inline std::map<const std::string, void (waybar::modules::Clock::* const)()> actionMap_{
|
||||||
{"mode", &waybar::modules::Clock::cldModeSwitch},
|
{"mode", &waybar::modules::Clock::cldModeSwitch},
|
||||||
{"shift_up", &waybar::modules::Clock::cldShift_up},
|
{"shift_up", &waybar::modules::Clock::cldShift_up},
|
||||||
{"shift_down", &waybar::modules::Clock::cldShift_down},
|
{"shift_down", &waybar::modules::Clock::cldShift_down},
|
||||||
|
{"shift_reset", &waybar::modules::Clock::cldShift_reset},
|
||||||
{"tz_up", &waybar::modules::Clock::tz_up},
|
{"tz_up", &waybar::modules::Clock::tz_up},
|
||||||
{"tz_down", &waybar::modules::Clock::tz_down}};
|
{"tz_down", &waybar::modules::Clock::tz_down}};
|
||||||
|
static inline std::map<const std::string,
|
||||||
|
void (waybar::modules::Clock::* const)(const std::string& action)>
|
||||||
|
actionWithArgsMap_{{"exec", &waybar::modules::Clock::action_exec}};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -21,12 +21,6 @@ class Cpu : public ALabel {
|
|||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double getCpuLoad();
|
|
||||||
std::tuple<std::vector<uint16_t>, std::string> getCpuUsage();
|
|
||||||
std::tuple<float, float, float> getCpuFrequency();
|
|
||||||
std::vector<std::tuple<size_t, size_t>> parseCpuinfo();
|
|
||||||
std::vector<float> parseCpuFrequencies();
|
|
||||||
|
|
||||||
std::vector<std::tuple<size_t, size_t>> prev_times_;
|
std::vector<std::tuple<size_t, size_t>> prev_times_;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fstream>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class CpuFrequency : public ALabel {
|
||||||
|
public:
|
||||||
|
CpuFrequency(const std::string&, const Json::Value&);
|
||||||
|
virtual ~CpuFrequency() = default;
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
// This is a static member because it is also used by the cpu module.
|
||||||
|
static std::tuple<float, float, float> getCpuFrequency();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::vector<float> parseCpuFrequencies();
|
||||||
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fstream>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "AGraph.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class CpuGraph : public AGraph {
|
||||||
|
public:
|
||||||
|
CpuGraph(const std::string&, const Json::Value&);
|
||||||
|
virtual ~CpuGraph() = default;
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr const char* MODERATE_CLASS = "cpu-moderate";
|
||||||
|
static constexpr const char* HIGH_CLASS = "cpu-high";
|
||||||
|
static constexpr const char* INTENSIVE_CLASS = "cpu-intensive";
|
||||||
|
|
||||||
|
std::vector<std::tuple<size_t, size_t>> prev_times_;
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fstream>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class CpuUsage : public ALabel {
|
||||||
|
public:
|
||||||
|
CpuUsage(const std::string&, const Json::Value&);
|
||||||
|
virtual ~CpuUsage() = default;
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
// This is a static member because it is also used by the cpu module.
|
||||||
|
static std::tuple<std::vector<uint16_t>, std::string> getCpuUsage(
|
||||||
|
std::vector<std::tuple<size_t, size_t>>&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::vector<std::tuple<size_t, size_t>> parseCpuinfo();
|
||||||
|
|
||||||
|
std::vector<std::tuple<size_t, size_t>> prev_times_;
|
||||||
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
@@ -5,16 +5,16 @@
|
|||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AIconLabel.hpp"
|
||||||
#include "util/command.hpp"
|
#include "util/command.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Custom : public ALabel {
|
class Custom : public AIconLabel {
|
||||||
public:
|
public:
|
||||||
Custom(const std::string&, const std::string&, const Json::Value&);
|
Custom(const std::string&, const std::string&, const Json::Value&, const std::string&);
|
||||||
virtual ~Custom();
|
virtual ~Custom();
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
void refresh(int /*signal*/) override;
|
void refresh(int /*signal*/) override;
|
||||||
@@ -22,6 +22,7 @@ class Custom : public ALabel {
|
|||||||
private:
|
private:
|
||||||
void delayWorker();
|
void delayWorker();
|
||||||
void continuousWorker();
|
void continuousWorker();
|
||||||
|
void waitingWorker();
|
||||||
void parseOutputRaw();
|
void parseOutputRaw();
|
||||||
void parseOutputJson();
|
void parseOutputJson();
|
||||||
void handleEvent();
|
void handleEvent();
|
||||||
@@ -29,10 +30,16 @@ class Custom : public ALabel {
|
|||||||
bool handleToggle(GdkEventButton* const& e) override;
|
bool handleToggle(GdkEventButton* const& e) override;
|
||||||
|
|
||||||
const std::string name_;
|
const std::string name_;
|
||||||
|
const std::string output_name_;
|
||||||
std::string text_;
|
std::string text_;
|
||||||
std::string id_;
|
std::string id_;
|
||||||
std::string alt_;
|
std::string alt_;
|
||||||
std::string tooltip_;
|
std::string tooltip_;
|
||||||
|
std::string last_tooltip_markup_;
|
||||||
|
std::string image_path_;
|
||||||
|
std::string image_name_;
|
||||||
|
unsigned app_icon_size_{24};
|
||||||
|
const bool tooltip_format_enabled_;
|
||||||
std::vector<std::string> class_;
|
std::vector<std::string> class_;
|
||||||
int percentage_;
|
int percentage_;
|
||||||
FILE* fp_;
|
FILE* fp_;
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <csignal>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "AGraph.hpp"
|
||||||
|
#include "util/command.hpp"
|
||||||
|
#include "util/json.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class CustomGraph : public AGraph {
|
||||||
|
public:
|
||||||
|
CustomGraph(const std::string&, const std::string&, const Json::Value&, const std::string&);
|
||||||
|
virtual ~CustomGraph();
|
||||||
|
auto update() -> void override;
|
||||||
|
void refresh(int /*signal*/) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void delayWorker();
|
||||||
|
void continuousWorker();
|
||||||
|
void waitingWorker();
|
||||||
|
void parseOutputRaw();
|
||||||
|
void parseOutputJson();
|
||||||
|
void handleEvent();
|
||||||
|
bool handleScroll(GdkEventScroll* e) override;
|
||||||
|
bool handleToggle(GdkEventButton* const& e) override;
|
||||||
|
|
||||||
|
const std::string name_;
|
||||||
|
const std::string output_name_;
|
||||||
|
std::string text_;
|
||||||
|
std::string id_;
|
||||||
|
std::string alt_;
|
||||||
|
std::string tooltip_;
|
||||||
|
const bool tooltip_format_enabled_;
|
||||||
|
std::vector<std::string> class_;
|
||||||
|
int percentage_;
|
||||||
|
FILE* fp_;
|
||||||
|
int pid_;
|
||||||
|
util::command::res output_;
|
||||||
|
util::JsonParser parser_;
|
||||||
|
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "util/format.hpp"
|
#include "util/format.hpp"
|
||||||
@@ -19,7 +20,12 @@ class Disk : public ALabel {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
std::string path_;
|
std::string header_;
|
||||||
|
std::vector<std::string> paths_;
|
||||||
|
std::string separator_;
|
||||||
|
std::string unit_;
|
||||||
|
|
||||||
|
float calc_specific_divisor(const std::string& divisor);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "dwl-bar-ipc-unstable-v1-client-protocol.h"
|
#include "dwl-ipc-unstable-v2-client-protocol.h"
|
||||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
namespace waybar::modules::dwl {
|
namespace waybar::modules::dwl {
|
||||||
@@ -21,14 +21,17 @@ class Tags : public waybar::AModule {
|
|||||||
void handle_primary_clicked(uint32_t tag);
|
void handle_primary_clicked(uint32_t tag);
|
||||||
bool handle_button_press(GdkEventButton* event_button, uint32_t tag);
|
bool handle_button_press(GdkEventButton* event_button, uint32_t tag);
|
||||||
|
|
||||||
struct zdwl_manager_v1 *status_manager_;
|
void handle_active_output(zdwl_ipc_output_v2* zdwl_output_v2, uint32_t active);
|
||||||
|
|
||||||
|
struct zdwl_ipc_manager_v2* status_manager_;
|
||||||
struct wl_seat* seat_;
|
struct wl_seat* seat_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const waybar::Bar& bar_;
|
const waybar::Bar& bar_;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
std::vector<Gtk::Button> buttons_;
|
std::vector<Gtk::Button> buttons_;
|
||||||
struct zdwl_output_v1 *output_status_;
|
bool hide_vacant_;
|
||||||
|
struct zdwl_ipc_output_v2* output_status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace waybar::modules::dwl */
|
} /* namespace waybar::modules::dwl */
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "AAppIconLabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "dwl-ipc-unstable-v2-client-protocol.h"
|
||||||
|
#include "util/json.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::dwl {
|
||||||
|
|
||||||
|
class Window : public AAppIconLabel, public sigc::trackable {
|
||||||
|
public:
|
||||||
|
Window(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
|
~Window();
|
||||||
|
|
||||||
|
void handle_layout(const uint32_t layout);
|
||||||
|
void handle_title(const char* title);
|
||||||
|
void handle_appid(const char* ppid);
|
||||||
|
void handle_active(const uint32_t active);
|
||||||
|
void handle_layout_symbol(const char* layout_symbol);
|
||||||
|
void handle_frame();
|
||||||
|
|
||||||
|
struct zdwl_ipc_manager_v2* status_manager_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Bar& bar_;
|
||||||
|
|
||||||
|
std::string title_;
|
||||||
|
std::string appid_;
|
||||||
|
std::string layout_symbol_;
|
||||||
|
bool active_;
|
||||||
|
bool hide_inactive_;
|
||||||
|
bool hide_empty_;
|
||||||
|
uint32_t layout_;
|
||||||
|
|
||||||
|
struct zdwl_ipc_output_v2* output_status_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::dwl
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <gtkmm/image.h>
|
||||||
|
#include <gtkmm/label.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "ext-workspace-v1-client-protocol.h"
|
||||||
|
|
||||||
|
namespace waybar::modules::ext {
|
||||||
|
|
||||||
|
class WorkspaceGroup;
|
||||||
|
class Workspace;
|
||||||
|
|
||||||
|
class WorkspaceManager final : public AModule {
|
||||||
|
public:
|
||||||
|
WorkspaceManager(const std::string& id, const waybar::Bar& bar, const Json::Value& config);
|
||||||
|
~WorkspaceManager() override;
|
||||||
|
void register_manager(wl_registry* registry, uint32_t name, uint32_t version);
|
||||||
|
void remove_workspace_group(uint32_t id);
|
||||||
|
void remove_workspace(uint32_t id);
|
||||||
|
void set_needs_sorting() { needs_sorting_ = true; }
|
||||||
|
|
||||||
|
// wl events
|
||||||
|
void handle_workspace_group(ext_workspace_group_handle_v1* handle);
|
||||||
|
void handle_workspace(ext_workspace_handle_v1* handle);
|
||||||
|
void handle_done();
|
||||||
|
void handle_finished();
|
||||||
|
|
||||||
|
// wl requests
|
||||||
|
void commit() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void update() override;
|
||||||
|
bool has_button(const Gtk::Button* button);
|
||||||
|
void sort_workspaces();
|
||||||
|
void clear_buttons();
|
||||||
|
void update_buttons();
|
||||||
|
|
||||||
|
static uint32_t group_global_id;
|
||||||
|
static uint32_t workspace_global_id;
|
||||||
|
uint32_t workspace_name = 0;
|
||||||
|
|
||||||
|
bool sort_by_id_ = false;
|
||||||
|
bool sort_by_name_ = true;
|
||||||
|
bool sort_by_coordinates_ = false;
|
||||||
|
bool all_outputs_ = false;
|
||||||
|
|
||||||
|
const waybar::Bar& bar_;
|
||||||
|
Gtk::Box box_;
|
||||||
|
|
||||||
|
ext_workspace_manager_v1* ext_manager_ = nullptr;
|
||||||
|
std::vector<std::unique_ptr<WorkspaceGroup>> groups_;
|
||||||
|
std::vector<std::unique_ptr<Workspace>> workspaces_;
|
||||||
|
|
||||||
|
bool needs_sorting_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorkspaceGroup {
|
||||||
|
public:
|
||||||
|
WorkspaceGroup(WorkspaceManager& manager, ext_workspace_group_handle_v1* handle, uint32_t id);
|
||||||
|
~WorkspaceGroup();
|
||||||
|
|
||||||
|
u_int32_t id() const { return id_; }
|
||||||
|
bool has_output(const wl_output* output);
|
||||||
|
bool has_workspace(const ext_workspace_handle_v1* workspace);
|
||||||
|
|
||||||
|
// wl events
|
||||||
|
void handle_capabilities(uint32_t capabilities);
|
||||||
|
void handle_output_enter(wl_output* output);
|
||||||
|
void handle_output_leave(wl_output* output);
|
||||||
|
void handle_workspace_enter(ext_workspace_handle_v1* handle);
|
||||||
|
void handle_workspace_leave(ext_workspace_handle_v1* handle);
|
||||||
|
void handle_removed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
WorkspaceManager& workspaces_manager_;
|
||||||
|
ext_workspace_group_handle_v1* ext_handle_;
|
||||||
|
uint32_t id_;
|
||||||
|
std::vector<wl_output*> outputs_;
|
||||||
|
std::vector<ext_workspace_handle_v1*> workspaces_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Workspace {
|
||||||
|
public:
|
||||||
|
Workspace(const Json::Value& config, WorkspaceManager& manager, ext_workspace_handle_v1* handle,
|
||||||
|
uint32_t id, const std::string& name);
|
||||||
|
~Workspace();
|
||||||
|
|
||||||
|
ext_workspace_handle_v1* handle() const { return ext_handle_; }
|
||||||
|
u_int32_t id() const { return id_; }
|
||||||
|
std::string& workspace_id() { return workspace_id_; }
|
||||||
|
std::string& name() { return name_; }
|
||||||
|
std::vector<u_int32_t>& coordinates() { return coordinates_; }
|
||||||
|
Gtk::Button& button() { return button_; }
|
||||||
|
void update();
|
||||||
|
|
||||||
|
// wl events
|
||||||
|
void handle_id(const std::string& id);
|
||||||
|
void handle_name(const std::string& name);
|
||||||
|
void handle_coordinates(const std::vector<uint32_t>& coordinates);
|
||||||
|
void handle_state(uint32_t state);
|
||||||
|
void handle_capabilities(uint32_t capabilities);
|
||||||
|
void handle_removed();
|
||||||
|
|
||||||
|
// gdk events
|
||||||
|
bool handle_clicked(const GdkEventButton* button) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool has_state(uint32_t state) const { return (state_ & state) == state; }
|
||||||
|
std::string icon();
|
||||||
|
|
||||||
|
WorkspaceManager& workspace_manager_;
|
||||||
|
ext_workspace_handle_v1* ext_handle_ = nullptr;
|
||||||
|
uint32_t id_;
|
||||||
|
uint32_t state_ = 0;
|
||||||
|
std::string workspace_id_;
|
||||||
|
std::string name_;
|
||||||
|
std::vector<uint32_t> coordinates_;
|
||||||
|
|
||||||
|
bool active_only_ = false;
|
||||||
|
bool ignore_hidden_ = true;
|
||||||
|
std::string format_;
|
||||||
|
bool with_icon_ = false;
|
||||||
|
static std::map<std::string, std::string> icon_map_;
|
||||||
|
std::string on_click_action_;
|
||||||
|
std::string on_click_middle_action_;
|
||||||
|
std::string on_click_right_action_;
|
||||||
|
|
||||||
|
Gtk::Button button_;
|
||||||
|
Gtk::Box content_;
|
||||||
|
Gtk::Label label_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::ext
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#include "ext-workspace-v1-client-protocol.h"
|
||||||
|
|
||||||
|
namespace waybar::modules::ext {
|
||||||
|
void add_registry_listener(void* data);
|
||||||
|
void add_workspace_listener(ext_workspace_handle_v1* workspace_handle, void* data);
|
||||||
|
void add_workspace_group_listener(ext_workspace_group_handle_v1* workspace_group_handle,
|
||||||
|
void* data);
|
||||||
|
ext_workspace_manager_v1* workspace_manager_bind(wl_registry* registry, uint32_t name,
|
||||||
|
uint32_t version, void* data);
|
||||||
|
} // namespace waybar::modules::ext
|
||||||
@@ -26,7 +26,7 @@ class Gamemode : public AModule {
|
|||||||
const std::string DEFAULT_FORMAT = "{glyph}";
|
const std::string DEFAULT_FORMAT = "{glyph}";
|
||||||
const std::string DEFAULT_FORMAT_ALT = "{glyph} {count}";
|
const std::string DEFAULT_FORMAT_ALT = "{glyph} {count}";
|
||||||
const std::string DEFAULT_TOOLTIP_FORMAT = "Games running: {count}";
|
const std::string DEFAULT_TOOLTIP_FORMAT = "Games running: {count}";
|
||||||
const std::string DEFAULT_GLYPH = "";
|
const std::string DEFAULT_GLYPH = "";
|
||||||
|
|
||||||
void appear(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name,
|
void appear(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& name,
|
||||||
const Glib::ustring& name_owner);
|
const Glib::ustring& name_owner);
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
#ifdef WANT_RFKILL
|
||||||
|
#include "util/rfkill.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gps.h>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class Gps : public ALabel {
|
||||||
|
public:
|
||||||
|
Gps(const std::string&, const Json::Value&);
|
||||||
|
virtual ~Gps();
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef WANT_RFKILL
|
||||||
|
util::Rfkill rfkill_;
|
||||||
|
#endif
|
||||||
|
const std::string getFixModeName() const;
|
||||||
|
const std::string getFixModeString() const;
|
||||||
|
|
||||||
|
const std::string getFixStatusString() const;
|
||||||
|
|
||||||
|
util::SleeperThread thread_, gps_thread_;
|
||||||
|
gps_data_t gps_data_;
|
||||||
|
std::string state_;
|
||||||
|
|
||||||
|
bool hideDisconnected = true;
|
||||||
|
bool hideNoFix = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <functional>
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <filesystem>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "util/json.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
@@ -14,23 +19,50 @@ class EventHandler {
|
|||||||
virtual ~EventHandler() = default;
|
virtual ~EventHandler() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// If you want to use the Hyprland IPC, simply use IPC::inst() to get the singleton instance.
|
||||||
|
/// Do not create multiple instances.
|
||||||
class IPC {
|
class IPC {
|
||||||
|
protected:
|
||||||
|
IPC(); // use IPC::inst() instead.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IPC() { startIPC(); }
|
~IPC();
|
||||||
|
static IPC& inst();
|
||||||
|
|
||||||
void registerForIPC(const std::string&, EventHandler*);
|
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
|
||||||
void unregisterForIPC(EventHandler*);
|
void unregisterForIPC(EventHandler* handler);
|
||||||
|
|
||||||
std::string getSocket1Reply(const std::string& rq);
|
static std::string getSocket1Reply(const std::string& rq);
|
||||||
|
Json::Value getSocket1JsonReply(const std::string& rq);
|
||||||
|
static std::filesystem::path getSocketFolder(const char* instanceSig);
|
||||||
|
|
||||||
|
/// Dispatch a Hyprland command. Automatically uses the correct protocol
|
||||||
|
/// (legacy text or Lua-based) depending on the running Hyprland version.
|
||||||
|
static std::string dispatch(const std::string& dispatcher, const std::string& arg);
|
||||||
|
|
||||||
|
/// Build a Lua-format dispatch command string.
|
||||||
|
static std::string buildLuaDispatch(const std::string& dispatcher, const std::string& arg);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static std::filesystem::path socketFolder_;
|
||||||
|
|
||||||
|
/// Detect whether the running Hyprland uses the Lua-based IPC protocol.
|
||||||
|
/// Returns true for Hyprland >= 0.54 (Lua config), false for older versions.
|
||||||
|
static bool isLuaProtocol();
|
||||||
|
|
||||||
|
static std::optional<bool> s_luaProtocolDetected_; // cached detection result
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startIPC();
|
void socketListener();
|
||||||
void parseIPC(const std::string&);
|
void parseIPC(const std::string&);
|
||||||
|
|
||||||
std::mutex callbackMutex;
|
std::thread ipcThread_;
|
||||||
std::list<std::pair<std::string, EventHandler*>> callbacks;
|
std::mutex callbackMutex_;
|
||||||
|
std::mutex socketMutex_;
|
||||||
|
util::JsonParser parser_;
|
||||||
|
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
||||||
|
int socketfd_ = -1; // the hyprland socket file descriptor
|
||||||
|
pid_t socketOwnerPid_ = -1;
|
||||||
|
std::atomic<bool> running_ = true; // the ipcThread will stop running when this is false
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<IPC> gIPC;
|
|
||||||
inline bool modulesReady = false;
|
|
||||||
}; // namespace waybar::modules::hyprland
|
}; // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "modules/hyprland/backend.hpp"
|
#include "modules/hyprland/backend.hpp"
|
||||||
@@ -26,13 +30,17 @@ class Language : public waybar::ALabel, public EventHandler {
|
|||||||
std::string short_description;
|
std::string short_description;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto getLayout(const std::string&) -> Layout;
|
auto removeXkbLayoutCssClass() -> void;
|
||||||
|
auto addXkbLayoutCssClass() -> void;
|
||||||
|
static auto getLayout(const std::string&) -> Layout;
|
||||||
|
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
|
|
||||||
Layout layout_;
|
Layout layout_;
|
||||||
|
|
||||||
|
IPC& m_ipc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "modules/hyprland/backend.hpp"
|
#include "modules/hyprland/backend.hpp"
|
||||||
@@ -10,17 +14,25 @@ namespace waybar::modules::hyprland {
|
|||||||
class Submap : public waybar::ALabel, public EventHandler {
|
class Submap : public waybar::ALabel, public EventHandler {
|
||||||
public:
|
public:
|
||||||
Submap(const std::string&, const waybar::Bar&, const Json::Value&);
|
Submap(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
virtual ~Submap();
|
~Submap() override;
|
||||||
|
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onEvent(const std::string&) override;
|
auto parseConfig(const Json::Value&) -> void;
|
||||||
|
void onEvent(const std::string& ev) override;
|
||||||
|
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::string submap_;
|
std::string submap_;
|
||||||
|
std::string icon_;
|
||||||
|
std::string prev_submap_;
|
||||||
|
bool always_on_ = false;
|
||||||
|
std::string default_submap_ = "Default";
|
||||||
|
std::unordered_map<std::string, std::string> icons_;
|
||||||
|
|
||||||
|
IPC& m_ipc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -1,31 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include <tuple>
|
#include <string>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "AAppIconLabel.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "modules/hyprland/backend.hpp"
|
#include "modules/hyprland/backend.hpp"
|
||||||
#include "util/json.hpp"
|
#include "util/json.hpp"
|
||||||
|
|
||||||
namespace waybar::modules::hyprland {
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
class Window : public waybar::ALabel, public EventHandler {
|
class Window : public waybar::AAppIconLabel, public EventHandler {
|
||||||
public:
|
public:
|
||||||
Window(const std::string&, const waybar::Bar&, const Json::Value&);
|
Window(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
virtual ~Window();
|
~Window() override;
|
||||||
|
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int getActiveWorkspaceID(std::string);
|
struct Workspace {
|
||||||
std::string getLastWindowTitle(int);
|
int id = 0;
|
||||||
void onEvent(const std::string&) override;
|
int windows = 0;
|
||||||
|
std::string last_window;
|
||||||
|
std::string last_window_title;
|
||||||
|
|
||||||
bool separate_outputs;
|
static auto parse(const Json::Value& value) -> Workspace;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WindowData {
|
||||||
|
bool floating = false;
|
||||||
|
int monitor = -1;
|
||||||
|
std::string class_name;
|
||||||
|
std::string initial_class_name;
|
||||||
|
std::string title;
|
||||||
|
std::string initial_title;
|
||||||
|
bool fullscreen = false;
|
||||||
|
bool grouped = false;
|
||||||
|
|
||||||
|
static auto parse(const Json::Value&) -> WindowData;
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto getActiveWorkspace(const std::string&) -> Workspace;
|
||||||
|
static auto getActiveWorkspace() -> Workspace;
|
||||||
|
void onEvent(const std::string& ev) override;
|
||||||
|
void queryActiveWorkspace();
|
||||||
|
void setClass(const std::string&, bool enable);
|
||||||
|
|
||||||
|
bool separateOutputs_ = false;
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
util::JsonParser parser_;
|
util::JsonParser parser_;
|
||||||
std::string lastView;
|
WindowData windowData_;
|
||||||
|
Workspace workspace_;
|
||||||
|
std::string soloClass_;
|
||||||
|
std::string lastSoloClass_;
|
||||||
|
bool solo_ = false;
|
||||||
|
bool allFloating_ = false;
|
||||||
|
bool swallowing_ = false;
|
||||||
|
bool fullscreen_ = false;
|
||||||
|
bool focused_ = false;
|
||||||
|
|
||||||
|
IPC& m_ipc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::hyprland
|
} // namespace waybar::modules::hyprland
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "AAppIconLabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/hyprland/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
|
class WindowCount : public waybar::AAppIconLabel, public EventHandler {
|
||||||
|
public:
|
||||||
|
WindowCount(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
|
~WindowCount() override;
|
||||||
|
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Workspace {
|
||||||
|
int id;
|
||||||
|
int windows;
|
||||||
|
bool hasfullscreen;
|
||||||
|
static auto parse(const Json::Value& value) -> Workspace;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto getActiveWorkspace(const std::string&) -> Workspace;
|
||||||
|
auto getActiveWorkspace() -> Workspace;
|
||||||
|
void onEvent(const std::string& ev) override;
|
||||||
|
void queryActiveWorkspace();
|
||||||
|
void setClass(const std::string&, bool enable);
|
||||||
|
|
||||||
|
bool separateOutputs_;
|
||||||
|
std::mutex mutex_;
|
||||||
|
const Bar& bar_;
|
||||||
|
Workspace workspace_;
|
||||||
|
IPC& m_ipc;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::hyprland
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#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;
|
||||||
|
|
||||||
|
struct WindowRepr {
|
||||||
|
std::string address;
|
||||||
|
std::string window_class;
|
||||||
|
std::string window_title;
|
||||||
|
std::string repr_rewrite;
|
||||||
|
bool isActive = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool empty() const { return address.empty(); }
|
||||||
|
void setActive(bool value) { isActive = value; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class WindowCreationPayload {
|
||||||
|
public:
|
||||||
|
WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
|
||||||
|
WindowRepr window_repr);
|
||||||
|
WindowCreationPayload(const std::string& workspace_name, WindowAddress window_address,
|
||||||
|
const std::string& window_class, const std::string& window_title,
|
||||||
|
bool is_active);
|
||||||
|
WindowCreationPayload(Json::Value const& client_data);
|
||||||
|
|
||||||
|
int incrementTimeSpentUncreated();
|
||||||
|
bool isEmpty(Workspaces& workspace_manager);
|
||||||
|
bool reprIsReady() const { return std::holds_alternative<Repr>(m_window); }
|
||||||
|
WindowRepr repr(Workspaces& workspace_manager);
|
||||||
|
void setActive(bool value) { m_isActive = value; }
|
||||||
|
|
||||||
|
std::string getWorkspaceName() const { return m_workspaceName; }
|
||||||
|
WindowAddress getAddress() const { return m_windowAddress; }
|
||||||
|
|
||||||
|
void moveToWorkspace(std::string& new_workspace_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void clearAddr();
|
||||||
|
void clearWorkspaceName();
|
||||||
|
|
||||||
|
using Repr = WindowRepr;
|
||||||
|
using ClassAndTitle = std::pair<std::string, std::string>;
|
||||||
|
std::variant<Repr, ClassAndTitle> m_window;
|
||||||
|
|
||||||
|
WindowAddress m_windowAddress;
|
||||||
|
std::string m_workspaceName;
|
||||||
|
bool m_isActive = false;
|
||||||
|
|
||||||
|
int m_timeSpentUncreated = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::hyprland
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
#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);
|
||||||
|
~Workspace();
|
||||||
|
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 isUrgent() const { return m_isUrgent; };
|
||||||
|
|
||||||
|
bool handleClicked(GdkEventButton* bt) const;
|
||||||
|
|
||||||
|
bool handleEnter(GdkEventCrossing* event);
|
||||||
|
bool handleLeave(GdkEventCrossing* event);
|
||||||
|
|
||||||
|
void startHoverCheck();
|
||||||
|
void stopHoverCheck();
|
||||||
|
bool syncHoverClass();
|
||||||
|
bool pointerInsideButton();
|
||||||
|
|
||||||
|
void setActive(bool value = true) { m_isActive = value; };
|
||||||
|
void 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 std::ranges::any_of(m_windowMap,
|
||||||
|
[&addr](const auto& window) { return window.address == addr; });
|
||||||
|
};
|
||||||
|
void insertWindow(WindowCreationPayload create_window_payload);
|
||||||
|
void initializeWindowMap(const Json::Value& clients_data);
|
||||||
|
void setActiveWindow(WindowAddress const& addr);
|
||||||
|
|
||||||
|
bool onWindowOpened(WindowCreationPayload const& create_window_payload);
|
||||||
|
std::optional<WindowRepr> closeWindow(WindowAddress const& addr);
|
||||||
|
|
||||||
|
void update(const std::string& workspace_icon);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Workspaces& m_workspaceManager;
|
||||||
|
|
||||||
|
int m_id;
|
||||||
|
std::string m_name;
|
||||||
|
std::string m_prevNameClass;
|
||||||
|
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;
|
||||||
|
|
||||||
|
sigc::connection m_hoverCheckConnection;
|
||||||
|
|
||||||
|
std::vector<WindowRepr> m_windowMap;
|
||||||
|
|
||||||
|
Gtk::Button m_button;
|
||||||
|
Gtk::Box m_content;
|
||||||
|
Gtk::Label m_labelBefore;
|
||||||
|
Gtk::Label m_labelAfter;
|
||||||
|
|
||||||
|
bool isEmpty() const;
|
||||||
|
void updateTaskbar(const std::string& workspace_icon);
|
||||||
|
bool handleClick(const GdkEventButton* event_button, WindowAddress const& addr) const;
|
||||||
|
bool shouldSkipWindow(const WindowRepr& window_repr) const;
|
||||||
|
IPC& m_ipc;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::hyprland
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <gtkmm/enums.h>
|
||||||
|
#include <gtkmm/label.h>
|
||||||
|
#include <json/value.h>
|
||||||
|
#include <sigc++/connection.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
#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/icon_loader.hpp"
|
||||||
|
#include "util/regex_collection.hpp"
|
||||||
|
|
||||||
|
using WindowAddress = std::string;
|
||||||
|
|
||||||
|
namespace waybar::modules::hyprland {
|
||||||
|
|
||||||
|
class Workspaces;
|
||||||
|
|
||||||
|
class Workspaces : public AModule, public EventHandler {
|
||||||
|
public:
|
||||||
|
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
|
~Workspaces() override;
|
||||||
|
void update() override;
|
||||||
|
void init();
|
||||||
|
|
||||||
|
auto allOutputs() const -> bool { return m_allOutputs; }
|
||||||
|
auto showSpecial() const -> bool { return m_showSpecial; }
|
||||||
|
auto activeOnly() const -> bool { return m_activeOnly; }
|
||||||
|
auto hideActive() const -> bool { return m_hideActive; }
|
||||||
|
auto specialVisibleOnly() const -> bool { return m_specialVisibleOnly; }
|
||||||
|
auto persistentOnly() const -> bool { return m_persistentOnly; }
|
||||||
|
auto moveToMonitor() const -> bool { return m_moveToMonitor; }
|
||||||
|
auto enableTaskbar() const -> bool { return m_enableTaskbar; }
|
||||||
|
auto taskbarWithIcon() const -> bool { return m_taskbarWithIcon; }
|
||||||
|
auto barScroll() const -> bool { return m_barScroll; }
|
||||||
|
|
||||||
|
auto getBarOutput() const -> std::string { return m_bar.output->name; }
|
||||||
|
auto formatBefore() const -> std::string { return m_formatBefore; }
|
||||||
|
auto formatAfter() const -> std::string { return m_formatAfter; }
|
||||||
|
auto taskbarFormatBefore() const -> std::string { return m_taskbarFormatBefore; }
|
||||||
|
auto taskbarFormatAfter() const -> std::string { return m_taskbarFormatAfter; }
|
||||||
|
auto taskbarIconSize() const -> int { return m_taskbarIconSize; }
|
||||||
|
auto taskbarOrientation() const -> Gtk::Orientation { return m_taskbarOrientation; }
|
||||||
|
auto taskbarReverseDirection() const -> bool { return m_taskbarReverseDirection; }
|
||||||
|
auto onClickWindow() const -> std::string { return m_onClickWindow; }
|
||||||
|
auto getIgnoredWindows() const -> std::vector<std::regex> { return m_ignoreWindows; }
|
||||||
|
auto maxWindows() const -> int { return m_maxWindows; }
|
||||||
|
|
||||||
|
enum class ActiveWindowPosition { NONE, FIRST, LAST };
|
||||||
|
auto activeWindowPosition() const -> ActiveWindowPosition { return m_activeWindowPosition; }
|
||||||
|
|
||||||
|
std::string getRewrite(const std::string& window_class, const std::string& window_title);
|
||||||
|
std::string& getWindowSeparator() { return m_formatWindowSeparator; }
|
||||||
|
auto windowRewriteGroupThreshold() const -> int { return m_windowRewriteGroupThreshold; }
|
||||||
|
auto const& getWindowRewriteGroupFormat() const { return m_windowRewriteGroupFormat; }
|
||||||
|
bool isWorkspaceIgnored(std::string const& workspace_name);
|
||||||
|
|
||||||
|
bool windowRewriteConfigUsesTitle() const { return m_anyWindowRewriteRuleUsesTitle; }
|
||||||
|
const IconLoader& iconLoader() const { return m_iconLoader; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onEvent(const std::string& e) override;
|
||||||
|
void updateWindowCount();
|
||||||
|
void sortSpecialCentered();
|
||||||
|
void sortWorkspaces();
|
||||||
|
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& workspaceString);
|
||||||
|
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;
|
||||||
|
auto populateMaxWindowsConfig(const Json::Value& config) -> void;
|
||||||
|
auto populateWorkspaceTaskbarConfig(const Json::Value& config) -> void;
|
||||||
|
|
||||||
|
void registerIpc();
|
||||||
|
|
||||||
|
// workspace events
|
||||||
|
void onWorkspaceActivated(std::string const& payload);
|
||||||
|
void onSpecialWorkspaceActivated(std::string const& payload);
|
||||||
|
void onWorkspaceDestroyed(std::string const& payload);
|
||||||
|
void onWorkspaceCreated(std::string const& payload,
|
||||||
|
Json::Value const& clientsData = Json::Value::nullRef);
|
||||||
|
void onWorkspaceMoved(std::string const& payload);
|
||||||
|
void onWorkspaceRenamed(std::string const& payload);
|
||||||
|
static std::optional<int> parseWorkspaceId(std::string const& workspaceIdStr);
|
||||||
|
|
||||||
|
// monitor events
|
||||||
|
void onMonitorFocused(std::string const& payload);
|
||||||
|
|
||||||
|
// window events
|
||||||
|
void onWindowOpened(std::string const& payload);
|
||||||
|
void onWindowClosed(std::string const& addr);
|
||||||
|
void onWindowMoved(std::string const& payload);
|
||||||
|
|
||||||
|
void onWindowTitleEvent(std::string const& payload);
|
||||||
|
void onActiveWindowChanged(WindowAddress const& payload);
|
||||||
|
|
||||||
|
void onConfigReloaded();
|
||||||
|
|
||||||
|
int windowRewritePriorityFunction(std::string const& window_rule);
|
||||||
|
|
||||||
|
// event payload management
|
||||||
|
template <typename... Args>
|
||||||
|
static std::string makePayload(Args const&... args);
|
||||||
|
static std::pair<std::string, std::string> splitDoublePayload(std::string const& payload);
|
||||||
|
static std::tuple<std::string, std::string, std::string> splitTriplePayload(
|
||||||
|
std::string const& payload);
|
||||||
|
// scroll events
|
||||||
|
bool handleScroll(GdkEventScroll* e) override;
|
||||||
|
|
||||||
|
// Update methods
|
||||||
|
void doUpdate();
|
||||||
|
void removeWorkspacesToRemove();
|
||||||
|
void createWorkspacesToCreate();
|
||||||
|
static std::vector<int> getVisibleWorkspaces();
|
||||||
|
void updateWorkspaceStates();
|
||||||
|
bool updateWindowsToCreate();
|
||||||
|
|
||||||
|
void extendOrphans(int workspaceId, Json::Value const& clientsJson);
|
||||||
|
void registerOrphanWindow(WindowCreationPayload create_window_payload);
|
||||||
|
|
||||||
|
void initializeWorkspaces();
|
||||||
|
void setCurrentMonitorId();
|
||||||
|
void loadPersistentWorkspacesFromConfig(Json::Value const& clientsJson);
|
||||||
|
void loadPersistentWorkspacesFromWorkspaceRules(const Json::Value& clientsJson);
|
||||||
|
|
||||||
|
bool m_allOutputs = false;
|
||||||
|
bool m_showSpecial = false;
|
||||||
|
bool m_activeOnly = false;
|
||||||
|
bool m_hideActive = false;
|
||||||
|
bool m_specialVisibleOnly = false;
|
||||||
|
bool m_persistentOnly = false;
|
||||||
|
bool m_moveToMonitor = false;
|
||||||
|
bool m_barScroll = false;
|
||||||
|
Json::Value m_persistentWorkspaceConfig;
|
||||||
|
|
||||||
|
// Map for windows stored in workspaces not present in the current bar.
|
||||||
|
// This happens when the user has multiple monitors (hence, multiple bars)
|
||||||
|
// and doesn't share windows across bars (a.k.a `all-outputs` = false)
|
||||||
|
std::map<WindowAddress, WindowRepr, std::less<>> m_orphanWindowMap;
|
||||||
|
|
||||||
|
enum class SortMethod { ID, NAME, NUMBER, SPECIAL_CENTERED, DEFAULT };
|
||||||
|
util::EnumParser<SortMethod> m_enumParser;
|
||||||
|
SortMethod m_sortBy = SortMethod::DEFAULT;
|
||||||
|
std::map<std::string, SortMethod> m_sortMap = {{"ID", SortMethod::ID},
|
||||||
|
{"NAME", SortMethod::NAME},
|
||||||
|
{"NUMBER", SortMethod::NUMBER},
|
||||||
|
{"SPECIAL-CENTERED", SortMethod::SPECIAL_CENTERED},
|
||||||
|
{"DEFAULT", SortMethod::DEFAULT}};
|
||||||
|
|
||||||
|
std::string m_formatBefore;
|
||||||
|
std::string m_formatAfter;
|
||||||
|
|
||||||
|
std::map<std::string, std::string> m_iconsMap;
|
||||||
|
util::RegexCollection m_windowRewriteRules;
|
||||||
|
bool m_anyWindowRewriteRuleUsesTitle = false;
|
||||||
|
std::string m_formatWindowSeparator;
|
||||||
|
int m_windowRewriteGroupThreshold = 0;
|
||||||
|
std::string m_windowRewriteGroupFormat = "{icon}×{count}";
|
||||||
|
|
||||||
|
bool m_withIcon;
|
||||||
|
uint64_t m_monitorId;
|
||||||
|
int m_activeWorkspaceId;
|
||||||
|
std::string m_activeSpecialWorkspaceName;
|
||||||
|
std::vector<std::unique_ptr<Workspace>> m_workspaces;
|
||||||
|
std::vector<std::pair<Json::Value, Json::Value>> m_workspacesToCreate;
|
||||||
|
std::vector<std::string> m_workspacesToRemove;
|
||||||
|
std::vector<WindowCreationPayload> m_windowsToCreate;
|
||||||
|
|
||||||
|
IconLoader m_iconLoader;
|
||||||
|
bool m_enableTaskbar = false;
|
||||||
|
bool m_updateActiveWindow = false;
|
||||||
|
bool m_taskbarWithIcon = false;
|
||||||
|
bool m_taskbarWithTitle = false;
|
||||||
|
std::string m_taskbarFormatBefore;
|
||||||
|
std::string m_taskbarFormatAfter;
|
||||||
|
int m_taskbarIconSize = 16;
|
||||||
|
Gtk::Orientation m_taskbarOrientation = Gtk::ORIENTATION_HORIZONTAL;
|
||||||
|
bool m_taskbarReverseDirection = false;
|
||||||
|
util::EnumParser<ActiveWindowPosition> m_activeWindowEnumParser;
|
||||||
|
ActiveWindowPosition m_activeWindowPosition = ActiveWindowPosition::NONE;
|
||||||
|
std::map<std::string, ActiveWindowPosition> m_activeWindowPositionMap = {
|
||||||
|
{"NONE", ActiveWindowPosition::NONE},
|
||||||
|
{"FIRST", ActiveWindowPosition::FIRST},
|
||||||
|
{"LAST", ActiveWindowPosition::LAST},
|
||||||
|
};
|
||||||
|
std::string m_onClickWindow;
|
||||||
|
std::string m_currentActiveWindowAddress;
|
||||||
|
int m_maxWindows = 0;
|
||||||
|
|
||||||
|
std::vector<std::regex> m_ignoreWorkspaces;
|
||||||
|
std::vector<std::regex> m_ignoreWindows;
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
const Bar& m_bar;
|
||||||
|
Gtk::Box m_box;
|
||||||
|
sigc::connection m_scrollEventConnection_;
|
||||||
|
IPC& m_ipc;
|
||||||
|
|
||||||
|
sigc::connection m_debounceTimer;
|
||||||
|
bool m_updatePending = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::hyprland
|
||||||
@@ -6,25 +6,35 @@
|
|||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
|
|
||||||
|
struct ext_idle_notification_v1;
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class IdleInhibitor : public ALabel {
|
class IdleInhibitor : public ALabel {
|
||||||
sigc::connection timeout_;
|
sigc::connection timeout_;
|
||||||
|
ext_idle_notification_v1* idle_notification_;
|
||||||
|
uint32_t idle_timeout_ms_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
|
IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||||
virtual ~IdleInhibitor();
|
virtual ~IdleInhibitor();
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
auto refresh(int) -> void override;
|
||||||
static std::list<waybar::AModule*> modules;
|
static std::list<waybar::AModule*> modules;
|
||||||
static bool status;
|
static bool status;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool handleToggle(GdkEventButton* const& e) override;
|
bool handleToggle(GdkEventButton* const& e) override;
|
||||||
void toggleStatus();
|
void toggleStatus();
|
||||||
|
void setupIdleNotification();
|
||||||
|
void teardownIdleNotification();
|
||||||
|
static void handleIdled(void* data, ext_idle_notification_v1* notification);
|
||||||
|
static void handleResumed(void* data, ext_idle_notification_v1* notification);
|
||||||
|
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
struct zwp_idle_inhibitor_v1* idle_inhibitor_;
|
struct zwp_idle_inhibitor_v1* idle_inhibitor_;
|
||||||
int pid_;
|
int pid_;
|
||||||
|
bool wait_for_activity_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -24,12 +24,15 @@ class Image : public AModule {
|
|||||||
private:
|
private:
|
||||||
void delayWorker();
|
void delayWorker();
|
||||||
void handleEvent();
|
void handleEvent();
|
||||||
|
void parseOutputRaw();
|
||||||
|
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
Gtk::Image image_;
|
Gtk::Image image_;
|
||||||
std::string path_;
|
std::string path_;
|
||||||
|
std::string tooltip_;
|
||||||
int size_;
|
int size_;
|
||||||
int interval_;
|
std::chrono::milliseconds interval_;
|
||||||
|
util::command::res output_;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <fmt/chrono.h>
|
#include <fmt/chrono.h>
|
||||||
#include <gtkmm/label.h>
|
#include <gtkmm/label.h>
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "AModule.hpp"
|
#include "AModule.hpp"
|
||||||
@@ -34,12 +36,13 @@ class KeyboardState : public AModule {
|
|||||||
std::string capslock_format_;
|
std::string capslock_format_;
|
||||||
std::string scrolllock_format_;
|
std::string scrolllock_format_;
|
||||||
const std::chrono::seconds interval_;
|
const std::chrono::seconds interval_;
|
||||||
std::string icon_locked_;
|
std::unordered_map<std::string, std::vector<std::string>> key_icon_states_;
|
||||||
std::string icon_unlocked_;
|
|
||||||
std::string devices_path_;
|
std::string devices_path_;
|
||||||
|
|
||||||
struct libinput* libinput_;
|
struct libinput* libinput_;
|
||||||
std::unordered_map<std::string, struct libinput_device*> libinput_devices_;
|
std::unordered_map<std::string, struct libinput_device*> libinput_devices_;
|
||||||
|
std::mutex devices_mutex_; // protects libinput_devices_
|
||||||
|
std::set<int> binding_keys;
|
||||||
|
|
||||||
util::SleeperThread libinput_thread_, hotplug_thread_;
|
util::SleeperThread libinput_thread_, hotplug_thread_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fstream>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class Load : public ALabel {
|
||||||
|
public:
|
||||||
|
Load(const std::string&, const Json::Value&);
|
||||||
|
virtual ~Load() = default;
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
// This is a static member because it is also used by the cpu module.
|
||||||
|
static std::tuple<double, double, double> getLoad();
|
||||||
|
|
||||||
|
private:
|
||||||
|
util::SleeperThread thread_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
// include/modules/mango/backend.hpp
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "util/json.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::mango {
|
||||||
|
|
||||||
|
class EventHandler {
|
||||||
|
public:
|
||||||
|
virtual void onEvent(const Json::Value& ev) = 0;
|
||||||
|
virtual ~EventHandler() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IPC {
|
||||||
|
public:
|
||||||
|
static IPC& getInstance();
|
||||||
|
IPC(const IPC&) = delete;
|
||||||
|
IPC& operator=(const IPC&) = delete;
|
||||||
|
|
||||||
|
void registerForIPC(const std::string& ev, EventHandler* handler);
|
||||||
|
void unregisterForIPC(EventHandler* handler);
|
||||||
|
|
||||||
|
static Json::Value send(const Json::Value& request);
|
||||||
|
static void sendAsync(const Json::Value& request);
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lockData() { return std::unique_lock<std::mutex>(data_mutex_); }
|
||||||
|
|
||||||
|
std::unordered_map<std::string, Json::Value> getMonitors() const;
|
||||||
|
Json::Value getMonitor(const std::string& name);
|
||||||
|
Json::Value getActiveClientForMonitor(const std::string& name) const;
|
||||||
|
std::string getKeyboardLayout() const;
|
||||||
|
std::string getKeymode() const;
|
||||||
|
std::string getLayoutSymbolForMonitor(const std::string& name) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IPC();
|
||||||
|
~IPC();
|
||||||
|
void startIPC();
|
||||||
|
static int connectToSocket();
|
||||||
|
void parseIPC(const std::string& line);
|
||||||
|
|
||||||
|
void handleMonitorUpdate(const Json::Value& mon);
|
||||||
|
void updateFocusingClient(const Json::Value& client);
|
||||||
|
void updateKeyboardLayout(const std::string& layout);
|
||||||
|
|
||||||
|
static Json::Value sendCommand(const std::string& cmd);
|
||||||
|
|
||||||
|
int sockfd_ = -1;
|
||||||
|
std::thread ipc_thread_;
|
||||||
|
mutable std::mutex data_mutex_;
|
||||||
|
std::unordered_map<std::string, Json::Value> monitors_;
|
||||||
|
std::unordered_map<uint64_t, Json::Value> clients_;
|
||||||
|
uint64_t focusing_client_id_ = 0;
|
||||||
|
std::string keyboard_layout_;
|
||||||
|
std::string keymode_;
|
||||||
|
Json::Value active_client_;
|
||||||
|
std::mutex callback_mutex_;
|
||||||
|
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
||||||
|
};
|
||||||
|
} // namespace waybar::modules::mango
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/mango/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::mango {
|
||||||
|
|
||||||
|
class Keymode : public ALabel, public EventHandler {
|
||||||
|
public:
|
||||||
|
Keymode(const std::string&, const Bar&, const Json::Value&);
|
||||||
|
~Keymode() override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onEvent(const Json::Value& ev) override;
|
||||||
|
void doUpdate();
|
||||||
|
|
||||||
|
std::mutex mutex_;
|
||||||
|
const Bar& bar_;
|
||||||
|
std::string last_keymode_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::mango
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <xkbcommon/xkbregistry.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/mango/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::mango {
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
Layout getLayout(const std::string& fullName);
|
||||||
|
|
||||||
|
std::mutex mutex_;
|
||||||
|
const Bar& bar_;
|
||||||
|
|
||||||
|
std::vector<Layout> layouts_;
|
||||||
|
unsigned current_idx_;
|
||||||
|
std::string last_short_name_;
|
||||||
|
|
||||||
|
struct rxkb_context* rxkb_ctx_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::mango
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/mango/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::mango {
|
||||||
|
|
||||||
|
class Layout : public ALabel, public EventHandler {
|
||||||
|
public:
|
||||||
|
Layout(const std::string&, const Bar&, const Json::Value&);
|
||||||
|
~Layout() override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onEvent(const Json::Value& ev) override;
|
||||||
|
void doUpdate();
|
||||||
|
|
||||||
|
std::mutex mutex_;
|
||||||
|
const Bar& bar_;
|
||||||
|
std::string last_symbol_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::mango
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <json/value.h>
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "AAppIconLabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/mango/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::mango {
|
||||||
|
|
||||||
|
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_;
|
||||||
|
std::mutex mutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::mango
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <json/value.h>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/mango/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::mango {
|
||||||
|
|
||||||
|
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(uint64_t idx);
|
||||||
|
void updateButtonState(Gtk::Button& button, const Json::Value& tag, const Json::Value& monitor);
|
||||||
|
std::string getIcon(const std::string& value, const Json::Value& tag);
|
||||||
|
bool handleButtonClick(GdkEventButton* event, uint64_t idx, bool isOverview);
|
||||||
|
|
||||||
|
const Bar& bar_;
|
||||||
|
Gtk::Box box_;
|
||||||
|
|
||||||
|
std::unordered_map<uint64_t, Gtk::Button> buttons_;
|
||||||
|
Gtk::Button* overview_button_ = nullptr;
|
||||||
|
|
||||||
|
std::string on_click_left_;
|
||||||
|
std::string on_click_middle_;
|
||||||
|
std::string on_click_right_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::mango
|
||||||
@@ -22,6 +22,8 @@ class Memory : public ALabel {
|
|||||||
std::unordered_map<std::string, unsigned long> meminfo_;
|
std::unordered_map<std::string, unsigned long> meminfo_;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
|
|
||||||
|
std::string unit_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -28,11 +28,14 @@ class MPD : public ALabel {
|
|||||||
|
|
||||||
unsigned timeout_;
|
unsigned timeout_;
|
||||||
|
|
||||||
|
unsigned playing_interval_;
|
||||||
|
|
||||||
detail::unique_connection connection_;
|
detail::unique_connection connection_;
|
||||||
|
|
||||||
detail::unique_status status_;
|
detail::unique_status status_;
|
||||||
mpd_state state_;
|
mpd_state state_;
|
||||||
detail::unique_song song_;
|
detail::unique_song song_;
|
||||||
|
std::string ellipsis_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MPD(const std::string&, const Json::Value&);
|
MPD(const std::string&, const Json::Value&);
|
||||||
@@ -44,7 +47,11 @@ class MPD : public ALabel {
|
|||||||
std::string getFilename() const;
|
std::string getFilename() const;
|
||||||
void setLabel();
|
void setLabel();
|
||||||
std::string getStateIcon() const;
|
std::string getStateIcon() const;
|
||||||
std::string getOptionIcon(std::string optionName, bool activated) const;
|
std::string getOptionIcon(const std::string& optionName, bool activated) const;
|
||||||
|
std::string getArtistStr(bool truncated) const;
|
||||||
|
std::string getAlbumArtistStr(bool truncated) const;
|
||||||
|
std::string getAlbumStr(bool truncated) const;
|
||||||
|
std::string getTitleStr(bool truncated) const;
|
||||||
|
|
||||||
// GUI-side methods
|
// GUI-side methods
|
||||||
bool handlePlayPause(GdkEventButton* const&);
|
bool handlePlayPause(GdkEventButton* const&);
|
||||||
@@ -54,11 +61,11 @@ class MPD : public ALabel {
|
|||||||
void tryConnect();
|
void tryConnect();
|
||||||
void checkErrors(mpd_connection* conn);
|
void checkErrors(mpd_connection* conn);
|
||||||
void fetchState();
|
void fetchState();
|
||||||
void queryMPD();
|
|
||||||
|
|
||||||
inline bool stopped() const { return connection_ && state_ == MPD_STATE_STOP; }
|
inline bool stopped() const { return connection_ && state_ == MPD_STATE_STOP; }
|
||||||
inline bool playing() const { return connection_ && state_ == MPD_STATE_PLAY; }
|
inline bool playing() const { return connection_ && state_ == MPD_STATE_PLAY; }
|
||||||
inline bool paused() const { return connection_ && state_ == MPD_STATE_PAUSE; }
|
inline bool paused() const { return connection_ && state_ == MPD_STATE_PAUSE; }
|
||||||
|
inline unsigned playing_interval() const { return playing_interval_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !defined(MPD_NOINLINE)
|
#if !defined(MPD_NOINLINE)
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ class Idle : public State {
|
|||||||
class Playing : public State {
|
class Playing : public State {
|
||||||
Context* const ctx_;
|
Context* const ctx_;
|
||||||
sigc::connection timer_connection_;
|
sigc::connection timer_connection_;
|
||||||
|
sigc::connection idle_connection_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Playing(Context* const ctx) : ctx_{ctx} {}
|
Playing(Context* const ctx) : ctx_{ctx} {}
|
||||||
@@ -98,7 +99,10 @@ class Playing : public State {
|
|||||||
Playing(Playing const&) = delete;
|
Playing(Playing const&) = delete;
|
||||||
Playing& operator=(Playing const&) = delete;
|
Playing& operator=(Playing const&) = delete;
|
||||||
|
|
||||||
|
void timer() noexcept;
|
||||||
|
void idle() noexcept;
|
||||||
bool on_timer();
|
bool on_timer();
|
||||||
|
bool on_io(Glib::IOCondition const&);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Paused : public State {
|
class Paused : public State {
|
||||||
@@ -148,6 +152,7 @@ class Stopped : public State {
|
|||||||
class Disconnected : public State {
|
class Disconnected : public State {
|
||||||
Context* const ctx_;
|
Context* const ctx_;
|
||||||
sigc::connection timer_connection_;
|
sigc::connection timer_connection_;
|
||||||
|
int last_interval_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Disconnected(Context* const ctx) : ctx_{ctx} {}
|
Disconnected(Context* const ctx) : ctx_{ctx} {}
|
||||||
@@ -162,7 +167,7 @@ class Disconnected : public State {
|
|||||||
Disconnected(Disconnected const&) = delete;
|
Disconnected(Disconnected const&) = delete;
|
||||||
Disconnected& operator=(Disconnected const&) = delete;
|
Disconnected& operator=(Disconnected const&) = delete;
|
||||||
|
|
||||||
void arm_timer(int interval) noexcept;
|
bool arm_timer(int interval) noexcept;
|
||||||
void disarm_timer() noexcept;
|
void disarm_timer() noexcept;
|
||||||
|
|
||||||
bool on_timer();
|
bool on_timer();
|
||||||
@@ -193,10 +198,10 @@ class Context {
|
|||||||
bool is_paused() const;
|
bool is_paused() const;
|
||||||
bool is_stopped() const;
|
bool is_stopped() const;
|
||||||
constexpr std::size_t interval() const;
|
constexpr std::size_t interval() const;
|
||||||
|
unsigned playing_interval() const;
|
||||||
void tryConnect() const;
|
void tryConnect() const;
|
||||||
void checkErrors(mpd_connection*) const;
|
void checkErrors(mpd_connection*) const;
|
||||||
void do_update();
|
void do_update();
|
||||||
void queryMPD() const;
|
|
||||||
void fetchState() const;
|
void fetchState() const;
|
||||||
constexpr mpd_state state() const;
|
constexpr mpd_state state() const;
|
||||||
void emit() const;
|
void emit() const;
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
inline bool Context::is_connected() const { return mpd_module_->connection_ != nullptr; }
|
inline bool Context::is_connected() const { return mpd_module_->connection_ != nullptr; }
|
||||||
inline bool Context::is_playing() const { return mpd_module_->playing(); }
|
inline bool Context::is_playing() const { return mpd_module_->playing(); }
|
||||||
inline bool Context::is_paused() const { return mpd_module_->paused(); }
|
inline bool Context::is_paused() const { return mpd_module_->paused(); }
|
||||||
inline bool Context::is_stopped() const { return mpd_module_->stopped(); }
|
inline bool Context::is_stopped() const { return mpd_module_->stopped(); }
|
||||||
|
|
||||||
constexpr inline std::size_t Context::interval() const { return mpd_module_->interval_.count(); }
|
constexpr inline std::size_t Context::interval() const { return mpd_module_->interval_ / 1s; }
|
||||||
|
inline unsigned Context::playing_interval() const { return mpd_module_->playing_interval(); }
|
||||||
inline void Context::tryConnect() const { mpd_module_->tryConnect(); }
|
inline void Context::tryConnect() const { mpd_module_->tryConnect(); }
|
||||||
inline unique_connection& Context::connection() { return mpd_module_->connection_; }
|
inline unique_connection& Context::connection() { return mpd_module_->connection_; }
|
||||||
constexpr inline mpd_state Context::state() const { return mpd_module_->state_; }
|
constexpr inline mpd_state Context::state() const { return mpd_module_->state_; }
|
||||||
@@ -15,7 +17,6 @@ constexpr inline mpd_state Context::state() const { return mpd_module_->state_;
|
|||||||
inline void Context::do_update() { mpd_module_->setLabel(); }
|
inline void Context::do_update() { mpd_module_->setLabel(); }
|
||||||
|
|
||||||
inline void Context::checkErrors(mpd_connection* conn) const { mpd_module_->checkErrors(conn); }
|
inline void Context::checkErrors(mpd_connection* conn) const { mpd_module_->checkErrors(conn); }
|
||||||
inline void Context::queryMPD() const { mpd_module_->queryMPD(); }
|
|
||||||
inline void Context::fetchState() const { mpd_module_->fetchState(); }
|
inline void Context::fetchState() const { mpd_module_->fetchState(); }
|
||||||
inline void Context::emit() const { mpd_module_->emit(); }
|
inline void Context::emit() const { mpd_module_->emit(); }
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class Mpris : public ALabel {
|
|||||||
|
|
||||||
std::optional<std::string> artist;
|
std::optional<std::string> artist;
|
||||||
std::optional<std::string> album;
|
std::optional<std::string> album;
|
||||||
|
std::optional<std::string> album_artist;
|
||||||
std::optional<std::string> title;
|
std::optional<std::string> title;
|
||||||
std::optional<std::string> length; // as HH:MM:SS
|
std::optional<std::string> length; // as HH:MM:SS
|
||||||
std::optional<std::string> position; // same format
|
std::optional<std::string> position; // same format
|
||||||
@@ -67,6 +68,8 @@ class Mpris : public ALabel {
|
|||||||
int title_len_;
|
int title_len_;
|
||||||
int dynamic_len_;
|
int dynamic_len_;
|
||||||
std::vector<std::string> dynamic_prio_;
|
std::vector<std::string> dynamic_prio_;
|
||||||
|
std::vector<std::string> dynamic_order_;
|
||||||
|
std::string dynamic_separator_;
|
||||||
bool truncate_hours_;
|
bool truncate_hours_;
|
||||||
bool tooltip_len_limits_;
|
bool tooltip_len_limits_;
|
||||||
std::string ellipsis_;
|
std::string ellipsis_;
|
||||||
@@ -74,12 +77,16 @@ class Mpris : public ALabel {
|
|||||||
std::string player_;
|
std::string player_;
|
||||||
std::vector<std::string> ignored_players_;
|
std::vector<std::string> ignored_players_;
|
||||||
|
|
||||||
|
bool prefer_album_artist_;
|
||||||
|
|
||||||
PlayerctlPlayerManager* manager;
|
PlayerctlPlayerManager* manager;
|
||||||
PlayerctlPlayer* player;
|
PlayerctlPlayer* player;
|
||||||
|
PlayerctlPlayer* last_active_player_ = nullptr;
|
||||||
std::string lastStatus;
|
std::string lastStatus;
|
||||||
std::string lastPlayer;
|
std::string lastPlayer;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
|
std::chrono::time_point<std::chrono::system_clock> last_update_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::mpris
|
} // namespace waybar::modules::mpris
|
||||||
|
|||||||
+34
-23
@@ -9,6 +9,7 @@
|
|||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
#include "util/sleeper_thread.hpp"
|
#include "util/sleeper_thread.hpp"
|
||||||
@@ -16,6 +17,8 @@
|
|||||||
#include "util/rfkill.hpp"
|
#include "util/rfkill.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum ip_addr_pref : uint8_t { IPV4, IPV6, IPV4_6 };
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Network : public ALabel {
|
class Network : public ALabel {
|
||||||
@@ -25,8 +28,8 @@ class Network : public ALabel {
|
|||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t MAX_RETRY = 5;
|
static const uint8_t MAX_RETRY{5};
|
||||||
static const uint8_t EPOLL_MAX = 200;
|
static const uint8_t EPOLL_MAX{200};
|
||||||
|
|
||||||
static int handleEvents(struct nl_msg*, void*);
|
static int handleEvents(struct nl_msg*, void*);
|
||||||
static int handleEventsDone(struct nl_msg*, void*);
|
static int handleEventsDone(struct nl_msg*, void*);
|
||||||
@@ -40,52 +43,60 @@ class Network : public ALabel {
|
|||||||
void parseEssid(struct nlattr**);
|
void parseEssid(struct nlattr**);
|
||||||
void parseSignal(struct nlattr**);
|
void parseSignal(struct nlattr**);
|
||||||
void parseFreq(struct nlattr**);
|
void parseFreq(struct nlattr**);
|
||||||
|
void parseBssid(struct nlattr**);
|
||||||
bool associatedOrJoined(struct nlattr**);
|
bool associatedOrJoined(struct nlattr**);
|
||||||
bool checkInterface(std::string name);
|
bool matchInterface(const std::string& ifname, const std::vector<std::string>& altnames,
|
||||||
|
std::string& matched) const;
|
||||||
auto getInfo() -> void;
|
auto getInfo() -> void;
|
||||||
const std::string getNetworkState() const;
|
const std::string getNetworkState() const;
|
||||||
void clearIface();
|
void clearIface();
|
||||||
bool wildcardMatch(const std::string& pattern, const std::string& text) const;
|
|
||||||
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
|
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
|
||||||
|
|
||||||
int ifid_;
|
int ifid_{-1};
|
||||||
sa_family_t family_;
|
ip_addr_pref addr_pref_{ip_addr_pref::IPV4};
|
||||||
struct sockaddr_nl nladdr_ = {0};
|
struct sockaddr_nl nladdr_{0};
|
||||||
struct nl_sock* sock_ = nullptr;
|
struct nl_sock* sock_{nullptr};
|
||||||
struct nl_sock* ev_sock_ = nullptr;
|
struct nl_sock* ev_sock_{nullptr};
|
||||||
int efd_;
|
int efd_{-1};
|
||||||
int ev_fd_;
|
int ev_fd_{-1};
|
||||||
int nl80211_id_;
|
int nl80211_id_{-1};
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
|
|
||||||
bool want_route_dump_;
|
bool want_route_dump_{false};
|
||||||
bool want_link_dump_;
|
bool want_link_dump_{false};
|
||||||
bool want_addr_dump_;
|
bool want_addr_dump_{false};
|
||||||
bool dump_in_progress_;
|
bool dump_in_progress_{false};
|
||||||
bool is_p2p_;
|
bool is_p2p_{false};
|
||||||
|
|
||||||
unsigned long long bandwidth_down_total_;
|
unsigned long long bandwidth_down_total_{0};
|
||||||
unsigned long long bandwidth_up_total_;
|
unsigned long long bandwidth_up_total_{0};
|
||||||
|
unsigned long long bandwidth_down_prev_{0};
|
||||||
|
unsigned long long bandwidth_up_prev_{0};
|
||||||
|
std::chrono::steady_clock::time_point bandwidth_last_sample_time_;
|
||||||
|
|
||||||
std::string state_;
|
std::string state_;
|
||||||
std::string essid_;
|
std::string essid_;
|
||||||
bool carrier_;
|
std::string bssid_;
|
||||||
|
bool carrier_{false};
|
||||||
std::string ifname_;
|
std::string ifname_;
|
||||||
std::string ipaddr_;
|
std::string ipaddr_;
|
||||||
|
std::string ipaddr6_;
|
||||||
std::string gwaddr_;
|
std::string gwaddr_;
|
||||||
std::string netmask_;
|
std::string netmask_;
|
||||||
int cidr_;
|
std::string netmask6_;
|
||||||
|
int cidr_{0};
|
||||||
|
int cidr6_{0};
|
||||||
int32_t signal_strength_dbm_;
|
int32_t signal_strength_dbm_;
|
||||||
uint8_t signal_strength_;
|
uint8_t signal_strength_;
|
||||||
std::string signal_strength_app_;
|
std::string signal_strength_app_;
|
||||||
float frequency_;
|
|
||||||
uint32_t route_priority;
|
uint32_t route_priority;
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
util::SleeperThread thread_timer_;
|
util::SleeperThread thread_timer_;
|
||||||
#ifdef WANT_RFKILL
|
#ifdef WANT_RFKILL
|
||||||
util::Rfkill rfkill_;
|
util::Rfkill rfkill_{RFKILL_TYPE_WLAN};
|
||||||
#endif
|
#endif
|
||||||
|
float frequency_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "util/json.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::niri {
|
||||||
|
|
||||||
|
class EventHandler {
|
||||||
|
public:
|
||||||
|
virtual void onEvent(const Json::Value& ev) = 0;
|
||||||
|
virtual ~EventHandler() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IPC {
|
||||||
|
public:
|
||||||
|
IPC();
|
||||||
|
|
||||||
|
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
|
||||||
|
void unregisterForIPC(EventHandler* handler);
|
||||||
|
|
||||||
|
static Json::Value send(const Json::Value& request);
|
||||||
|
|
||||||
|
// The data members are only safe to access while dataMutex_ is locked.
|
||||||
|
std::lock_guard<std::mutex> lockData() { return std::lock_guard(dataMutex_); }
|
||||||
|
const std::vector<Json::Value>& workspaces() const { return workspaces_; }
|
||||||
|
const std::vector<Json::Value>& windows() const { return windows_; }
|
||||||
|
const std::vector<std::string>& keyboardLayoutNames() const { return keyboardLayoutNames_; }
|
||||||
|
unsigned keyboardLayoutCurrent() const { return keyboardLayoutCurrent_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void startIPC();
|
||||||
|
static int connectToSocket();
|
||||||
|
void parseIPC(const std::string&);
|
||||||
|
|
||||||
|
std::mutex dataMutex_;
|
||||||
|
std::vector<Json::Value> workspaces_;
|
||||||
|
std::vector<Json::Value> windows_;
|
||||||
|
std::vector<std::string> keyboardLayoutNames_;
|
||||||
|
unsigned keyboardLayoutCurrent_;
|
||||||
|
|
||||||
|
util::JsonParser parser_;
|
||||||
|
std::mutex callbackMutex_;
|
||||||
|
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::unique_ptr<IPC> gIPC;
|
||||||
|
|
||||||
|
}; // namespace waybar::modules::niri
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/niri/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::niri {
|
||||||
|
|
||||||
|
class Language : public ALabel, public EventHandler {
|
||||||
|
public:
|
||||||
|
Language(const std::string&, const Bar&, const Json::Value&);
|
||||||
|
~Language() override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateFromIPC();
|
||||||
|
void onEvent(const Json::Value& ev) override;
|
||||||
|
void doUpdate();
|
||||||
|
|
||||||
|
struct Layout {
|
||||||
|
std::string full_name;
|
||||||
|
std::string short_name;
|
||||||
|
std::string variant;
|
||||||
|
std::string short_description;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Layout getLayout(const std::string& fullName);
|
||||||
|
|
||||||
|
std::mutex mutex_;
|
||||||
|
const Bar& bar_;
|
||||||
|
|
||||||
|
std::vector<Layout> layouts_;
|
||||||
|
unsigned current_idx_;
|
||||||
|
std::string last_short_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::niri
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <json/value.h>
|
||||||
|
|
||||||
|
#include "AAppIconLabel.hpp"
|
||||||
|
#include "bar.hpp"
|
||||||
|
#include "modules/niri/backend.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules::niri {
|
||||||
|
|
||||||
|
class Window : public AAppIconLabel, public EventHandler {
|
||||||
|
public:
|
||||||
|
Window(const std::string&, const Bar&, const Json::Value&);
|
||||||
|
~Window() override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onEvent(const Json::Value& ev) override;
|
||||||
|
void doUpdate();
|
||||||
|
void setClass(const std::string& className, bool enable);
|
||||||
|
|
||||||
|
const Bar& bar_;
|
||||||
|
|
||||||
|
std::string oldAppId_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::niri
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtkmm/button.h>
|
||||||
|
#include <json/value.h>
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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();
|
||||||
|
void sortWorkspaces(std::vector<Json::Value>& workspaces) const;
|
||||||
|
Gtk::Button& addButton(const Json::Value& ws);
|
||||||
|
std::string getIcon(const std::string& value, const Json::Value& ws);
|
||||||
|
bool isWorkspaceIgnored(const std::string& name);
|
||||||
|
bool handleScroll(GdkEventScroll* /*unused*/) override;
|
||||||
|
|
||||||
|
const Bar& bar_;
|
||||||
|
Gtk::Box box_;
|
||||||
|
// Map from niri workspace id to button.
|
||||||
|
std::unordered_map<uint64_t, Gtk::Button> buttons_;
|
||||||
|
// Vec of regex rules to ignore workspaces.
|
||||||
|
std::vector<std::regex> ignoreWorkspaces_;
|
||||||
|
|
||||||
|
bool sort_by_id_ = false;
|
||||||
|
bool sort_by_name_ = false;
|
||||||
|
bool sort_by_coordinates_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::niri
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include "ALabel.hpp"
|
||||||
|
#include "giomm/dbusproxy.h"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
struct Profile {
|
||||||
|
std::string name;
|
||||||
|
// Legacy driver field, kept for backward compatibility with the
|
||||||
|
// `{driver}` format placeholder and with older power-profiles-daemon
|
||||||
|
// versions that only expose a single `Driver` DBus property.
|
||||||
|
std::string driver;
|
||||||
|
std::string cpuDriver;
|
||||||
|
std::string platformDriver;
|
||||||
|
|
||||||
|
Profile(std::string n, std::string d, std::string cd, std::string pd)
|
||||||
|
: name(std::move(n)),
|
||||||
|
driver(std::move(d)),
|
||||||
|
cpuDriver(std::move(cd)),
|
||||||
|
platformDriver(std::move(pd)) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PowerProfilesDaemon : public ALabel {
|
||||||
|
public:
|
||||||
|
PowerProfilesDaemon(const std::string&, const Json::Value&);
|
||||||
|
auto update() -> void override;
|
||||||
|
void profileChangedCb(const Gio::DBus::Proxy::MapChangedProperties&,
|
||||||
|
const std::vector<Glib::ustring>&);
|
||||||
|
void busConnectedCb(Glib::RefPtr<Gio::AsyncResult>& r);
|
||||||
|
void getAllPropsCb(Glib::RefPtr<Gio::AsyncResult>& r);
|
||||||
|
void setPropCb(Glib::RefPtr<Gio::AsyncResult>& r);
|
||||||
|
void populateInitState();
|
||||||
|
bool handleToggle(GdkEventButton* const& e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// True if we're connected to the dbug interface. False if we're
|
||||||
|
// not.
|
||||||
|
bool connected_;
|
||||||
|
// Look for a profile name in the list of available profiles and
|
||||||
|
// switch activeProfile_ to it.
|
||||||
|
void switchToProfile(std::string const&);
|
||||||
|
// Used to toggle/display the profiles
|
||||||
|
std::vector<Profile> availableProfiles_;
|
||||||
|
// Points to the active profile in the profiles list
|
||||||
|
std::vector<Profile>::iterator activeProfile_;
|
||||||
|
// Current CSS class applied to the label
|
||||||
|
std::string currentStyle_;
|
||||||
|
// Format string
|
||||||
|
std::string tooltipFormat_;
|
||||||
|
// DBus Proxy used to track the current active profile
|
||||||
|
Glib::RefPtr<Gio::DBus::Proxy> powerProfilesProxy_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "gtkmm/box.h"
|
||||||
|
#include "modules/privacy/privacy_item.hpp"
|
||||||
|
#include "util/pipewire/pipewire_backend.hpp"
|
||||||
|
#include "util/pipewire/privacy_node_info.hpp"
|
||||||
|
|
||||||
|
using waybar::util::PipewireBackend::PrivacyNodeInfo;
|
||||||
|
|
||||||
|
namespace waybar::modules::privacy {
|
||||||
|
|
||||||
|
class Privacy : public AModule {
|
||||||
|
public:
|
||||||
|
Privacy(const std::string&, const Json::Value&, Gtk::Orientation, const std::string& pos);
|
||||||
|
auto update() -> void override;
|
||||||
|
|
||||||
|
void onPrivacyNodesChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::list<PrivacyNodeInfo*> nodes_screenshare; // Screen is being shared
|
||||||
|
std::list<PrivacyNodeInfo*> nodes_audio_in; // Application is using the microphone
|
||||||
|
std::list<PrivacyNodeInfo*> nodes_audio_out; // Application is outputting audio
|
||||||
|
|
||||||
|
std::mutex mutex_;
|
||||||
|
sigc::connection visibility_conn;
|
||||||
|
|
||||||
|
// Config
|
||||||
|
Gtk::Box box_;
|
||||||
|
std::vector<PrivacyItem*> modules_;
|
||||||
|
uint iconSpacing = 4;
|
||||||
|
uint iconSize = 20;
|
||||||
|
uint transition_duration = 250;
|
||||||
|
std::set<std::pair<PrivacyNodeType, std::string>> ignore;
|
||||||
|
bool ignore_monitor = true;
|
||||||
|
|
||||||
|
std::shared_ptr<util::PipewireBackend::PipewireBackend> backend = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::privacy
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <json/value.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "gtkmm/box.h"
|
||||||
|
#include "gtkmm/image.h"
|
||||||
|
#include "gtkmm/revealer.h"
|
||||||
|
#include "util/pipewire/privacy_node_info.hpp"
|
||||||
|
|
||||||
|
using waybar::util::PipewireBackend::PrivacyNodeInfo;
|
||||||
|
using waybar::util::PipewireBackend::PrivacyNodeType;
|
||||||
|
|
||||||
|
namespace waybar::modules::privacy {
|
||||||
|
|
||||||
|
class PrivacyItem : public Gtk::Revealer {
|
||||||
|
public:
|
||||||
|
PrivacyItem(const Json::Value& config_, enum PrivacyNodeType privacy_type_,
|
||||||
|
std::list<PrivacyNodeInfo*>* nodes, Gtk::Orientation orientation,
|
||||||
|
const std::string& pos, const uint icon_size, const uint transition_duration);
|
||||||
|
|
||||||
|
enum PrivacyNodeType privacy_type;
|
||||||
|
|
||||||
|
void set_in_use(bool in_use);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::list<PrivacyNodeInfo*>* nodes;
|
||||||
|
|
||||||
|
sigc::connection signal_conn;
|
||||||
|
|
||||||
|
Gtk::Box tooltip_window;
|
||||||
|
|
||||||
|
bool init = false;
|
||||||
|
bool in_use = false;
|
||||||
|
|
||||||
|
// Config
|
||||||
|
std::string iconName = "image-missing-symbolic";
|
||||||
|
bool tooltip = true;
|
||||||
|
uint tooltipIconSize = 24;
|
||||||
|
|
||||||
|
Gtk::Box box_;
|
||||||
|
Gtk::Image icon_;
|
||||||
|
|
||||||
|
void update_tooltip();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules::privacy
|
||||||
@@ -1,54 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <pulse/pulseaudio.h>
|
|
||||||
#include <pulse/volume.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "ALabel.hpp"
|
#include "ALabel.hpp"
|
||||||
|
#include "util/audio_backend.hpp"
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
class Pulseaudio : public ALabel {
|
class Pulseaudio : public ALabel {
|
||||||
public:
|
public:
|
||||||
Pulseaudio(const std::string&, const Json::Value&);
|
Pulseaudio(const std::string&, const Json::Value&);
|
||||||
virtual ~Pulseaudio();
|
virtual ~Pulseaudio() = default;
|
||||||
auto update() -> void override;
|
auto update() -> void override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void subscribeCb(pa_context*, pa_subscription_event_type_t, uint32_t, void*);
|
|
||||||
static void contextStateCb(pa_context*, void*);
|
|
||||||
static void sinkInfoCb(pa_context*, const pa_sink_info*, int, void*);
|
|
||||||
static void sourceInfoCb(pa_context*, const pa_source_info* i, int, void* data);
|
|
||||||
static void serverInfoCb(pa_context*, const pa_server_info*, void*);
|
|
||||||
static void volumeModifyCb(pa_context*, int, void*);
|
|
||||||
|
|
||||||
bool handleScroll(GdkEventScroll* e) override;
|
bool handleScroll(GdkEventScroll* e) override;
|
||||||
const std::vector<std::string> getPulseIcon() const;
|
const std::vector<std::string> getPulseIcon() const;
|
||||||
|
|
||||||
pa_threaded_mainloop* mainloop_;
|
std::shared_ptr<util::AudioBackend> backend = nullptr;
|
||||||
pa_mainloop_api* mainloop_api_;
|
util::PulseaudioTarget target = util::PulseaudioTarget::Sink;
|
||||||
pa_context* context_;
|
|
||||||
// SINK
|
|
||||||
uint32_t sink_idx_{0};
|
|
||||||
uint16_t volume_;
|
|
||||||
pa_cvolume pa_volume_;
|
|
||||||
bool muted_;
|
|
||||||
std::string port_name_;
|
|
||||||
std::string form_factor_;
|
|
||||||
std::string desc_;
|
|
||||||
std::string monitor_;
|
|
||||||
std::string current_sink_name_;
|
|
||||||
bool current_sink_running_;
|
|
||||||
// SOURCE
|
|
||||||
uint32_t source_idx_{0};
|
|
||||||
uint16_t source_volume_;
|
|
||||||
bool source_muted_;
|
|
||||||
std::string source_port_name_;
|
|
||||||
std::string source_desc_;
|
|
||||||
std::string default_source_name_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules
|
} // namespace waybar::modules
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "ASlider.hpp"
|
||||||
|
#include "util/audio_backend.hpp"
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class PulseaudioSlider : public ASlider {
|
||||||
|
public:
|
||||||
|
PulseaudioSlider(const std::string&, const Json::Value&);
|
||||||
|
virtual ~PulseaudioSlider() = default;
|
||||||
|
|
||||||
|
void update() override;
|
||||||
|
void onValueChanged() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<util::AudioBackend> backend = nullptr;
|
||||||
|
util::PulseaudioTarget target = util::PulseaudioTarget::Sink;
|
||||||
|
|
||||||
|
bool zero_on_mute = true;
|
||||||
|
bool unmute_on_volume_change = true;
|
||||||
|
// zero_on_mute and unmute_on_volume_change default to true
|
||||||
|
// in order to maintain previous behaviour when using a
|
||||||
|
// config in which these values are undefined
|
||||||
|
|
||||||
|
bool previously_muted = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
||||||
@@ -24,6 +24,7 @@ class Layout : public waybar::ALabel {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const waybar::Bar& bar_;
|
const waybar::Bar& bar_;
|
||||||
|
std::string name_;
|
||||||
struct wl_output* output_; // stores the output this module belongs to
|
struct wl_output* output_; // stores the output this module belongs to
|
||||||
struct wl_output* focused_output_; // stores the currently focused output
|
struct wl_output* focused_output_; // stores the currently focused output
|
||||||
struct zriver_output_status_v1* output_status_;
|
struct zriver_output_status_v1* output_status_;
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ class Tags : public waybar::AModule {
|
|||||||
void handle_focused_tags(uint32_t tags);
|
void handle_focused_tags(uint32_t tags);
|
||||||
void handle_view_tags(struct wl_array* tags);
|
void handle_view_tags(struct wl_array* tags);
|
||||||
void handle_urgent_tags(uint32_t tags);
|
void handle_urgent_tags(uint32_t tags);
|
||||||
|
void handle_focused_output(struct wl_output* output);
|
||||||
|
void handle_unfocused_output(struct wl_output* output);
|
||||||
|
|
||||||
|
void handle_show();
|
||||||
void handle_primary_clicked(uint32_t tag);
|
void handle_primary_clicked(uint32_t tag);
|
||||||
bool handle_button_press(GdkEventButton* event_button, uint32_t tag);
|
bool handle_button_press(GdkEventButton* event_button, uint32_t tag);
|
||||||
|
|
||||||
@@ -30,9 +33,11 @@ class Tags : public waybar::AModule {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const waybar::Bar& bar_;
|
const waybar::Bar& bar_;
|
||||||
|
struct wl_output* output_; // stores the output this module belongs to
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
std::vector<Gtk::Button> buttons_;
|
std::vector<Gtk::Button> buttons_;
|
||||||
struct zriver_output_status_v1* output_status_;
|
struct zriver_output_status_v1* output_status_;
|
||||||
|
struct zriver_seat_status_v1* seat_status_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace waybar::modules::river */
|
} /* namespace waybar::modules::river */
|
||||||
|
|||||||
@@ -14,11 +14,14 @@ namespace waybar::modules::SNI {
|
|||||||
|
|
||||||
class Host {
|
class Host {
|
||||||
public:
|
public:
|
||||||
Host(const std::size_t id, const Json::Value&, const Bar&,
|
Host(const std::size_t id, const Json::Value&, const Bar&, const std::vector<std::string>&,
|
||||||
const std::function<void(std::unique_ptr<Item>&)>&,
|
const std::function<void(std::unique_ptr<Item>&)>&,
|
||||||
const std::function<void(std::unique_ptr<Item>&)>&);
|
const std::function<void(std::unique_ptr<Item>&)>&, const std::function<void()>&);
|
||||||
~Host();
|
~Host();
|
||||||
|
|
||||||
|
void checkIgnoreList(const std::vector<std::string>& ignore_list,
|
||||||
|
const std::function<void(std::unique_ptr<Item>&)>& on_remove);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void busAcquired(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring);
|
void busAcquired(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring);
|
||||||
void nameAppeared(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring,
|
void nameAppeared(const Glib::RefPtr<Gio::DBus::Connection>&, Glib::ustring,
|
||||||
@@ -28,9 +31,13 @@ class Host {
|
|||||||
static void registerHost(GObject*, GAsyncResult*, gpointer);
|
static void registerHost(GObject*, GAsyncResult*, gpointer);
|
||||||
static void itemRegistered(SnWatcher*, const gchar*, gpointer);
|
static void itemRegistered(SnWatcher*, const gchar*, gpointer);
|
||||||
static void itemUnregistered(SnWatcher*, const gchar*, gpointer);
|
static void itemUnregistered(SnWatcher*, const gchar*, gpointer);
|
||||||
|
void itemReady(Item&);
|
||||||
|
void itemInvalidated(Item&);
|
||||||
|
void removeItem(std::vector<std::unique_ptr<Item>>::iterator);
|
||||||
|
void clearItems();
|
||||||
|
|
||||||
std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string);
|
std::tuple<std::string, std::string> getBusNameAndObjectPath(const std::string);
|
||||||
void addRegisteredItem(std::string service);
|
void addRegisteredItem(const std::string& service);
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Item>> items_;
|
std::vector<std::unique_ptr<Item>> items_;
|
||||||
const std::string bus_name_;
|
const std::string bus_name_;
|
||||||
@@ -39,10 +46,14 @@ class Host {
|
|||||||
std::size_t watcher_id_;
|
std::size_t watcher_id_;
|
||||||
GCancellable* cancellable_ = nullptr;
|
GCancellable* cancellable_ = nullptr;
|
||||||
SnWatcher* watcher_ = nullptr;
|
SnWatcher* watcher_ = nullptr;
|
||||||
|
sigc::connection retry_connection_;
|
||||||
|
unsigned retry_count_ = 0;
|
||||||
const Json::Value& config_;
|
const Json::Value& config_;
|
||||||
const Bar& bar_;
|
const Bar& bar_;
|
||||||
|
const std::vector<std::string> ignore_list_;
|
||||||
const std::function<void(std::unique_ptr<Item>&)> on_add_;
|
const std::function<void(std::unique_ptr<Item>&)> on_add_;
|
||||||
const std::function<void(std::unique_ptr<Item>&)> on_remove_;
|
const std::function<void(std::unique_ptr<Item>&)> on_remove_;
|
||||||
|
const std::function<void()> on_update_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar::modules::SNI
|
} // namespace waybar::modules::SNI
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
class IconManager {
|
||||||
|
public:
|
||||||
|
static IconManager& instance() {
|
||||||
|
static IconManager instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIconsConfig(const Json::Value& icons_config) {
|
||||||
|
if (icons_config.isObject()) {
|
||||||
|
for (const auto& key : icons_config.getMemberNames()) {
|
||||||
|
std::string app_name = key;
|
||||||
|
const Json::Value& icon_value = icons_config[key];
|
||||||
|
|
||||||
|
if (icon_value.isBool() && !icon_value.asBool()) {
|
||||||
|
// false value means hide this app
|
||||||
|
hidden_apps_.insert(app_name);
|
||||||
|
} else if (icon_value.isString()) {
|
||||||
|
std::string icon_path = icon_value.asString();
|
||||||
|
icons_map_[app_name] = icon_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
spdlog::warn("Invalid icon config format.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getIconForApp(const std::string& app_name) const {
|
||||||
|
auto it = icons_map_.find(app_name);
|
||||||
|
if (it != icons_map_.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isHidden(const std::string& app_name) const {
|
||||||
|
return hidden_apps_.find(app_name) != hidden_apps_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IconManager() = default;
|
||||||
|
std::unordered_map<std::string, std::string> icons_map_;
|
||||||
|
std::unordered_set<std::string> hidden_apps_;
|
||||||
|
};
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <libdbusmenu-gtk/dbusmenu-gtk.h>
|
#include <libdbusmenu-gtk/dbusmenu-gtk.h>
|
||||||
#include <sigc++/trackable.h>
|
#include <sigc++/trackable.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
@@ -25,8 +26,12 @@ struct ToolTip {
|
|||||||
|
|
||||||
class Item : public sigc::trackable {
|
class Item : public sigc::trackable {
|
||||||
public:
|
public:
|
||||||
Item(const std::string&, const std::string&, const Json::Value&, const Bar&);
|
Item(const std::string&, const std::string&, const Json::Value&, const Bar&,
|
||||||
~Item() = default;
|
const std::function<void(Item&)>&, const std::function<void(Item&)>&,
|
||||||
|
const std::function<void()>&);
|
||||||
|
~Item();
|
||||||
|
|
||||||
|
bool isReady() const;
|
||||||
|
|
||||||
std::string bus_name;
|
std::string bus_name;
|
||||||
std::string object_path;
|
std::string object_path;
|
||||||
@@ -41,9 +46,12 @@ class Item : public sigc::trackable {
|
|||||||
std::string title;
|
std::string title;
|
||||||
std::string icon_name;
|
std::string icon_name;
|
||||||
Glib::RefPtr<Gdk::Pixbuf> icon_pixmap;
|
Glib::RefPtr<Gdk::Pixbuf> icon_pixmap;
|
||||||
|
bool has_custom_icon_ = false;
|
||||||
Glib::RefPtr<Gtk::IconTheme> icon_theme;
|
Glib::RefPtr<Gtk::IconTheme> icon_theme;
|
||||||
std::string overlay_icon_name;
|
std::string overlay_icon_name;
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> overlay_icon_pixmap;
|
||||||
std::string attention_icon_name;
|
std::string attention_icon_name;
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> attention_icon_pixmap;
|
||||||
std::string attention_movie_name;
|
std::string attention_movie_name;
|
||||||
std::string icon_theme_path;
|
std::string icon_theme_path;
|
||||||
std::string menu;
|
std::string menu;
|
||||||
@@ -62,20 +70,30 @@ class Item : public sigc::trackable {
|
|||||||
void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result);
|
void proxyReady(Glib::RefPtr<Gio::AsyncResult>& result);
|
||||||
void setProperty(const Glib::ustring& name, Glib::VariantBase& value);
|
void setProperty(const Glib::ustring& name, Glib::VariantBase& value);
|
||||||
void setStatus(const Glib::ustring& value);
|
void setStatus(const Glib::ustring& value);
|
||||||
|
void setReady();
|
||||||
|
void invalidate();
|
||||||
|
void setCustomIcon(const std::string& id);
|
||||||
void getUpdatedProperties();
|
void getUpdatedProperties();
|
||||||
void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result);
|
void processUpdatedProperties(Glib::RefPtr<Gio::AsyncResult>& result);
|
||||||
void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
|
void onSignal(const Glib::ustring& sender_name, const Glib::ustring& signal_name,
|
||||||
const Glib::VariantContainerBase& arguments);
|
const Glib::VariantContainerBase& arguments);
|
||||||
|
|
||||||
void updateImage();
|
void updateImage();
|
||||||
Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant);
|
static Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant* variant);
|
||||||
Glib::RefPtr<Gdk::Pixbuf> getIconPixbuf();
|
Glib::RefPtr<Gdk::Pixbuf> getIconPixbuf();
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> getAttentionIconPixbuf();
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> getOverlayIconPixbuf();
|
||||||
|
Glib::RefPtr<Gdk::Pixbuf> loadIconFromNameOrFile(const std::string& name, bool log_failure);
|
||||||
|
static Glib::RefPtr<Gdk::Pixbuf> overlayPixbufs(const Glib::RefPtr<Gdk::Pixbuf>&,
|
||||||
|
const Glib::RefPtr<Gdk::Pixbuf>&);
|
||||||
Glib::RefPtr<Gdk::Pixbuf> getIconByName(const std::string& name, int size);
|
Glib::RefPtr<Gdk::Pixbuf> getIconByName(const std::string& name, int size);
|
||||||
double getScaledIconSize();
|
double getScaledIconSize();
|
||||||
static void onMenuDestroyed(Item* self, GObject* old_menu_pointer);
|
static void onMenuDestroyed(Item* self, GObject* old_menu_pointer);
|
||||||
void makeMenu();
|
void makeMenu();
|
||||||
bool handleClick(GdkEventButton* const& /*ev*/);
|
bool handleClick(GdkEventButton* const& /*ev*/);
|
||||||
bool handleScroll(GdkEventScroll* const&);
|
bool handleScroll(GdkEventScroll* const&);
|
||||||
|
bool handleMouseEnter(GdkEventCrossing* const&);
|
||||||
|
bool handleMouseLeave(GdkEventCrossing* const&);
|
||||||
|
|
||||||
// smooth scrolling threshold
|
// smooth scrolling threshold
|
||||||
gdouble scroll_threshold_ = 0;
|
gdouble scroll_threshold_ = 0;
|
||||||
@@ -83,6 +101,15 @@ class Item : public sigc::trackable {
|
|||||||
gdouble distance_scrolled_y_ = 0;
|
gdouble distance_scrolled_y_ = 0;
|
||||||
// visibility of items with Status == Passive
|
// visibility of items with Status == Passive
|
||||||
bool show_passive_ = false;
|
bool show_passive_ = false;
|
||||||
|
// hidden via config
|
||||||
|
bool is_hidden_ = false;
|
||||||
|
bool ready_ = false;
|
||||||
|
Glib::ustring status_ = "active";
|
||||||
|
|
||||||
|
const Bar& bar_;
|
||||||
|
const std::function<void(Item&)> on_ready_;
|
||||||
|
const std::function<void(Item&)> on_invalidate_;
|
||||||
|
const std::function<void()> on_updated_;
|
||||||
|
|
||||||
Glib::RefPtr<Gio::DBus::Proxy> proxy_;
|
Glib::RefPtr<Gio::DBus::Proxy> proxy_;
|
||||||
Glib::RefPtr<Gio::Cancellable> cancellable_;
|
Glib::RefPtr<Gio::Cancellable> cancellable_;
|
||||||
|
|||||||
@@ -19,10 +19,14 @@ class Tray : public AModule {
|
|||||||
private:
|
private:
|
||||||
void onAdd(std::unique_ptr<Item>& item);
|
void onAdd(std::unique_ptr<Item>& item);
|
||||||
void onRemove(std::unique_ptr<Item>& item);
|
void onRemove(std::unique_ptr<Item>& item);
|
||||||
|
void checkIgnoreList(std::unique_ptr<Item>* item);
|
||||||
|
std::vector<std::string> parseIgnoreList(const Json::Value& config);
|
||||||
|
void queueUpdate();
|
||||||
|
|
||||||
static inline std::size_t nb_hosts_ = 0;
|
static inline std::size_t nb_hosts_ = 0;
|
||||||
Gtk::Box box_;
|
Gtk::Box box_;
|
||||||
SNI::Watcher::singleton watcher_;
|
SNI::Watcher::singleton watcher_;
|
||||||
|
std::vector<std::string> ignore_list_;
|
||||||
SNI::Host host_;
|
SNI::Host host_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user