Compare commits

...

302 Commits

Author SHA1 Message Date
d8a808f76c chore: 0.9.19 2023-07-04 23:03:50 +02:00
5ef6636237 Merge pull request #2265 from tengyifei/master
Partially revert 3af1853260 to fix use-after-free
2023-07-04 22:59:45 +02:00
fc632f50ec fix: lint 2023-07-04 22:52:24 +02:00
31e4c9023e Merge pull request #1872 from HarHarLinks/patch-1
Add output parameter format to manpage
2023-07-04 22:46:06 +02:00
3e1c341933 Merge branch 'master' into patch-1 2023-07-04 22:45:15 +02:00
0d1016d4d2 Merge pull request #2203 from rodrgz/mprisImprovement
mpris: dynamic tag ordering and separator customization
2023-07-04 22:44:21 +02:00
12725f4418 Merge pull request #2220 from sigboe/warp-on-scroll-toggle
sway/workspaces: setting to not warp to window when scrolling
2023-07-04 22:42:53 +02:00
5c64d034a2 Merge pull request #2010 from chayleaf/improve-flake
improve nix dev shell; override the nixpkgs waybar
2023-07-04 22:40:52 +02:00
14fa9cf7b7 Merge pull request #2128 from Alan-Kuan/image-tooltip
Image tooltip
2023-07-04 22:40:04 +02:00
6c196b8f8d fix: lint 2023-07-04 22:35:27 +02:00
18d6dfea88 feat(man): start_hidden 2023-07-04 22:35:15 +02:00
d2eb8eb9fc Merge pull request #2175 from maqrrr/start_hidden
Add a new start_hidden flag
2023-07-04 22:33:33 +02:00
65f73d3e95 Merge pull request #2269 from Arcus92/master
wlr/taskbar: add support for rewrite rules
2023-07-04 22:31:37 +02:00
265b4edb2e Merge pull request #2276 from skligys/fix_mpris_ui_spamming
Stop MPRIS module from updating every ~20ms
2023-07-04 22:29:48 +02:00
18f5af835f Merge pull request #2280 from zjeffer/fix/hyprland/workspaces 2023-07-04 19:58:07 +02:00
7ef80d563b Formatting fixes 2023-07-04 19:48:04 +02:00
d3be9a7363 Fix rare segfault when destroying workspace 2023-07-04 19:40:43 +02:00
5f29e5a5e8 Merge pull request #2279 from LukashonakV/Catch_bump 2023-07-04 18:37:30 +02:00
cf4d58f30a Catch2 bump 2023-07-04 11:30:44 -04:00
bb61461aad Merge pull request #2278 from Anakael/pr/anakael/hyprland-workspaces 2023-07-04 08:02:45 +02:00
c91c8bbc45 Merge pull request #2277 from Aparicio99/fix_icon_theme_segfault 2023-07-04 08:01:45 +02:00
f26a125d15 format 2023-07-04 01:26:16 +03:00
de626dcbbc format 2023-07-04 01:24:34 +03:00
c9b963e82b fix segfault 2023-07-04 01:17:26 +03:00
a1cd0acac5 Fix random segfault on GTK icon functions
The segfaults were happening on GTK icon theme functions, which are
called via the C++ interface functions such as Gtk::IconTheme::has_icon.

There are multiple modules and threads using this functions on the default
icon theme by calling Gtk::IconTheme::get_default(), which returns the same
object for all callers, and was causing concurrent access to the same internal
data structures on the GTK lib. Even a seemingly read-only function such as
has_icon can cause writes due to the internal icon cache being updated.

To avoid this issues, a program wide global mutex must be used to ensure
a single thread is accessing the default icon theme instance.

This commit implements wrappers for the existing IconTheme function calls,
ensuring the global lock is held while calling the underling GTK functions.
2023-07-03 22:32:24 +01:00
c2f9d889f4 Stop MPRIS module from updating every ~20ms as onPlayerMetadata(), onPlayerPlay()
callbacks get triggered without regard for update interval.
2023-07-03 13:52:57 -07:00
58bdc6a41c fix spaces in waybar-wlr-taskbar.5.scd 2023-07-02 12:51:54 +02:00
c55cd82b39 wlr/taskbar: add support for rewrite rules 2023-07-02 12:23:36 +02:00
91588fb8bb Merge pull request #2212 from evyatark2/wpscroll
wireplumber: Support for scrolling
2023-07-02 11:46:56 +02:00
6b9600fecd Merge pull request #2267 from korylprince/reverse-scrolling
Don't apply reverse scrolling to mice wheels
2023-07-02 11:45:44 +02:00
0bfb29789c Merge pull request #2268 from zjeffer/hyprland/workspaces
Fixes for hyprland/workspaces
2023-07-02 11:45:09 +02:00
f6a62e258e fixes for hyprland/workspaces 2023-07-01 18:53:17 +02:00
1ba05d1ffa add reverse-mouse-scrolling to configure mouse wheel reverse scrolling 2023-07-01 10:35:37 -05:00
7a01143359 ignore reverse-scrolling from mouse wheel 2023-07-01 10:33:55 -05:00
35496f461f fix regression from #2232: reverse-scrolling was not applied to
GTK_SCROLL_SMOOTH events
2023-07-01 10:33:55 -05:00
b9cd0287f4 fix: typo 2023-07-01 11:12:46 +02:00
9d741f89e2 fix: lint 2023-07-01 11:12:14 +02:00
cc4370f1b2 fix: build 2023-07-01 11:08:31 +02:00
85854c71d6 Merge pull request #2219 from xytovl/wake_threads_on_resume
Wake all sleeping threads when leaving suspend
2023-07-01 11:02:13 +02:00
6ed550117c Merge pull request #2237 from LukashonakV/Gentoo_CI
Refresh Gentoo docker
2023-07-01 10:57:33 +02:00
15fe85d18d Merge pull request #2264 from Anakael/pr/anakael/hyprland-workspaces
feat: hyprland/workspaces
2023-07-01 10:55:24 +02:00
b62e5eb822 Merge pull request #2266 from zjeffer/master
Fixed some build warnings
2023-07-01 10:53:24 +02:00
25c2aaabcb Fixed build warnings 2023-07-01 10:12:24 +02:00
cd49eef229 Partially revert 3af1853260 to fix use-after-free
After upgrading to the latest release of Waybar the bar will crash
whenever I close the laptop lid. After some debugging I believe it is
because the watching added by watch_name is not being correctly canceled
using unwatch_name. After the Tray object and Host object are destroyed,
additional callbacks will become use-after-free.

Looks like commit 3af1853260 removed the
unwatch_name. I'm not sure why it did that, but it seemed dangerous.

Additionally, bus_name_id_ is created by own_name. According to that
function's documentation, the correct inverse operation is unown_name.
2023-06-30 23:25:24 -07:00
4f9fbbfa54 fix format 2023-07-01 02:25:15 +03:00
0b602632f2 return catch2 2023-07-01 02:23:37 +03:00
dbc7471f83 add docs 2023-07-01 02:13:36 +03:00
887c44bf68 finish MVP 2023-07-01 00:18:57 +03:00
33236c222f save 2023-06-28 02:52:01 +03:00
4116490535 Merge pull request #2256 from luttermann/master
Add output port (display) of workspace to template function of sway/workspace
2023-06-27 13:50:54 +02:00
08e18387c9 Add output port of workspace to template 2023-06-27 13:41:42 +02:00
0fff38c751 Merge pull request #2258 from Anakael/pr/anakael/hide-empty-taskbar
[wrl/taskbare] fix: use empty class for empty taskbar
2023-06-27 08:58:54 +02:00
afc489869a fix format 2023-06-27 00:18:49 +03:00
ce4da59f34 finish 2023-06-27 00:07:40 +03:00
43434254e0 Add output port of workspace to template 2023-06-26 11:01:50 +02:00
66ce74d29b mpris: Rename dynamic-priority to dynamic-importance-order keeping backward compatibility 2023-06-22 02:13:44 -03:00
77a8420aaf mpris: Add dynamic-order and dynamic-separator
This commit allows better handling of ordering and exclusion of the tags in Dynamics tags.
It also becomes possible to choose the separator between the tags.
2023-06-22 02:13:34 -03:00
b0f89f2bc1 Merge pull request #2241 from yangyingchao/master
support multiple items in hwmon-path of temperature module
2023-06-20 13:22:36 +02:00
7cda2dfd1a Merge pull request #2245 from gardenappl/main
hyprland/window: Add CSS customization similar to sway/window
2023-06-20 13:22:12 +02:00
238cfa9547 Merge pull request #2247 from gardenappl/hypr-backend
More robust Hyprland backend
2023-06-20 13:21:34 +02:00
b163b21ace More robust Hyprland backend 2023-06-20 13:36:48 +03:00
30c4f08773 hyprland/window: Correct application of .solo class 2023-06-20 03:54:02 +03:00
fd7c2a2012 hyprland/language: Show language on startup 2023-06-20 00:43:33 +03:00
4f14ce3285 hyprland/window: add .floating and .fullscreen CSS classes 2023-06-20 00:42:19 +03:00
e233022d1a hyprland/window: Rework, add .empty, .solo and .<app_id> CSS classes 2023-06-19 23:44:20 +03:00
e403c3b71b support multiple items in hwmon-path of temperature module
So user can share configuration file among different machines with different hardware
configurations.
2023-06-17 11:33:14 +08:00
d367b7e1d6 Merge pull request #2229 from LukashonakV/Upower_nativePath
Upower native-path filter
2023-06-16 15:38:58 +02:00
038644f8d9 Merge pull request #2238 from LukashonakV/ISSUE#2204
Issue#2204
2023-06-16 15:38:20 +02:00
d650c597f9 Renew clock man page
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-06-15 16:36:33 +03:00
5196009656 Refresh Gentoo docker
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-06-15 13:58:33 +03:00
4d8515930f Use local TZ, when user sets blank TZ in config
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-06-13 23:32:28 +03:00
192cea97f2 Upower man
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-06-13 18:44:29 +03:00
83f3c2321e Merge pull request #2231 from RobertMueller2/appid-fix
sway/window: fix appid style not cleared
2023-06-12 15:40:56 +02:00
dff0583c12 Merge pull request #2232 from robertgzr/reverse-scroll
Lift reverse-scrolling option into AModule
2023-06-12 08:54:38 +02:00
73c7e54535 pulseaudio: document reverse-scrolling option
Signed-off-by: Robert Günzler <r@gnzler.io>
2023-06-12 14:08:22 +09:00
0f8c156f24 Lift reverse-scrolling option into AModule
The option is generally useful when scrolling is used, when configuring
input devices to use "natural scroll direction".
Both backlight and pulseaudio were using different implementations, this
unifies and documents them.

Signed-off-by: Robert Günzler <r@gnzler.io>
2023-06-12 14:08:18 +09:00
fff4509723 sway/window: fix appid style not cleared (#2227)
Probably a rebase error during development of #1419. The code block now
removed was not supposed to be there anymore.
2023-06-11 08:41:20 +02:00
17af49d421 Upower native-path filter
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-06-09 18:22:24 +03:00
9f38631c7f Merge pull request #2223 from Anakael/pr/shchemel/fix-class-priority 2023-06-09 08:36:34 +02:00
62f4125927 change order 2023-06-08 23:31:14 +03:00
a67e692d4a sway: warp-on-scroll toggle 2023-06-07 15:49:11 +02:00
3c9cbc99d7 Wake all sleeping threads when leaving suspend
std::condition_variable::wait_for does not count time spent in sleep
mode, resulting in longer than expected waits.
2023-06-07 10:17:42 +02:00
c5379fa52d Merge pull request #2218 from LukashonakV/Wdeprecated
deprecated: implicit capture of 'this' via '[=]'
2023-06-06 22:56:27 +02:00
070110af0c Merge pull request #2217 from LukashonakV/g_bus_unwatch_name
Tray module causes: Invalid id passed to g_bus_unwatch_name()
2023-06-06 22:37:46 +02:00
6bf5b15c13 deprecated: implicit capture of 'this' via '[=]'
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-06-06 23:31:12 +03:00
a9779c2aa2 Happy Linter
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-06-06 23:06:11 +03:00
3af1853260 Tray module cause error g_bus_unwatch_name()
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-06-06 23:02:36 +03:00
d638610db1 Merge pull request #2216 from LukashonakV/small_fixies
Small performance fixies
2023-06-06 13:03:52 +02:00
87023c39f8 Small performance fixies
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-06-06 13:58:05 +03:00
e96610e31a Use consistent tabbing 2023-06-06 12:01:25 +03:00
d61b1d54de Document new wireplumber module functionality 2023-06-06 11:44:17 +03:00
e397f568b7 Round volume instead of truncating it 2023-06-06 11:42:31 +03:00
d22fd3bbd1 Use a minimum step as provided by wireplubmer; Default step to 1 2023-06-06 11:42:02 +03:00
75990c2867 Fix linting 2023-06-05 22:23:46 +03:00
88a1a702b4 wireplumber: Support for scrolling 2023-06-05 22:03:46 +03:00
24407dbf4a Merge pull request #2196 from calvinchd/hyprland-window-empty-css
[hyprland/window] Add css class for empty window name
2023-06-05 16:48:59 +02:00
108285e9ac Merge pull request #2210 from D3vil0p3r/patch-1
Fixing 'incomplete type error' during building
2023-06-05 16:30:00 +02:00
b728a37b6d Fixing 'incomplete type error' during building
Fixing errors during the building due to missing library after latest GCC updates.
2023-06-05 16:28:32 +02:00
938a93a0d7 Merge pull request #2209 from Matias-Hall/river_window_tooltip 2023-06-05 12:39:38 +02:00
ff6f727631 river/window: Add tooltip. 2023-06-05 18:29:19 +08:00
84077e0253 Merge pull request #2207 from dejor/dwl-module 2023-06-04 18:39:03 +02:00
d2787cc2d8 fix: typo to avoid null pointer 2023-06-04 12:45:33 +02:00
17a56aa4f7 hyprland/window: use empty() for empty window name check 2023-06-03 12:29:36 +10:00
ca52892ab9 Merge pull request #2200 from Visne/patch-1 2023-06-01 22:52:54 +02:00
655bc8f215 Fix broken link 2023-06-01 22:08:54 +02:00
a3912436be hyprland/window: add css class for empty label 2023-06-01 21:38:27 +10:00
47193a3d2f chore: v0.9.18 2023-05-29 09:25:01 +02:00
097cbc0c53 fix: lint 2023-05-29 09:24:33 +02:00
13a9c4a08b Merge pull request #2185 from xdavidel/dwl-module
Update to new ipc version
2023-05-29 09:16:22 +02:00
ebba529682 Apply clang-format 2023-05-25 01:29:28 +03:00
b97b0ae605 Fix linter complains 2023-05-25 01:25:55 +03:00
7e9bfc504c Update to new ipc version 2023-05-25 00:27:50 +03:00
7b0d2e8043 Merge pull request #2184 from lfos/fix-battery-segfault
Fix SEGFAULT in battery module
2023-05-22 16:19:13 +02:00
75eacb95ef Fix SEGFAULT in battery module
In waybar::modules::Battery::~Battery(), store a copy of the batteries_
iterator before calling erase(), as erase() invalidates the iterator.

Prior to this change, disconnecting outputs resulted in a SEGFAULT when
using the battery module; e.g.,

    [debug] Received SIGCHLD in signalThread
    [debug] Cmd exited with code 0
    [debug] Received SIGCHLD in signalThread
    [debug] Cmd exited with code 0
    [debug] Received SIGCHLD in signalThread
    [debug] Cmd exited with code 0
    [debug] Output removed: AU Optronics 0x2336
    [info] Bar configured (width: 1280, height: 25) for output: eDP-1
    [info] Bar configured (width: 1280, height: 25) for output: eDP-1
    zsh: segmentation fault (core dumped)  ./build/waybar -l trace

Signed-off-by: Lukas Fleischer <lfleischer@lfos.de>
2023-05-22 10:16:30 -04:00
2b24b16023 Merge pull request #2182 from cptpcrd/fd-closing 2023-05-22 07:40:14 +02:00
5cbbfd5c8a Close pipe if fork() fails when spawning processes
Prevents potential file descriptor leakage, albeit in a bit of an edge
case.
2023-05-21 12:15:49 -04:00
6163be687d Open network module eventfd as close-on-exec
Ensures that it is not leaked to child processes.
2023-05-21 12:13:17 -04:00
df65cab17a Open command pipes as close-on-exec
Avoids a race where the pipe could be inherited by another process
spawning at about the same time. If the other process didn't exit
quickly (e.g. if it was a custom script that did its own looping), it
would keep the write end of the pipe open, and so reading from the pipe
to try to get the command's output would block.

This bug manifested as some custom modules randomly not appearing in the
bar, requiring a reload to fix. The custom script had run and exited,
but the pipe had been inherited by another process, and the thread that
updated the module's output was blocked trying to read from it.
2023-05-21 12:10:44 -04:00
339bea1213 Add a new start_hidden bool 2023-05-15 07:01:00 -04:00
7b704071ff Merge pull request #2171 from FintasticMan/fix_mpris_man
mpris: Fix incorrect format replacement names
2023-05-13 23:25:30 +02:00
5748e56aeb mpris: Fix incorrect format replacement names 2023-05-13 21:45:29 +02:00
5b29119dab Merge pull request #2170 from FintasticMan/hide_mpris_if_empty
mpris: Hide label if empty
2023-05-13 18:26:12 +02:00
4bc30e040f mpris: Hide label if empty 2023-05-10 13:43:43 +02:00
919ad0a8bb Merge pull request #2156 from theRealCarneiro/master
Add persistent format-icon to wlr/workspaces
2023-05-05 14:05:32 +02:00
5df43be11f add persistent format-icon 2023-05-05 08:52:37 -03:00
56fa6b6afc Merge pull request #2153 from MonstrousOgre/master 2023-05-04 22:21:13 +02:00
c04485a5d0 separate css class for empty workspaces 2023-05-05 00:09:32 +05:30
b06953757e Merge pull request #2144 from LukashonakV/cava_bump 2023-04-29 00:13:25 +02:00
f5ef13c7f1 Gentoo docker. Add iniparser
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-04-28 15:46:51 +03:00
8c83af75a1 happy linter
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-04-28 15:38:34 +03:00
e253c34cd4 cava bump
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-04-28 13:38:35 +03:00
e4faf252b2 Merge pull request #2140 from 257/master 2023-04-26 21:35:46 +02:00
3da3732cc9 network: detect if link is p2p and use local addr
without this we endup with peer's addr

Signed-off-by: Paymon MARANDI <darwinskernel@gmail.com>
2023-04-26 13:52:17 -04:00
757f20fc04 Merge pull request #2135 from eneshecan/master 2023-04-23 13:47:28 +02:00
f00602058c Fix misinterpreting return value of getaddrinfo call which caused an early return for Hyprland language 2023-04-23 13:31:02 +02:00
9389c8d854 chore: update manual of the image modle 2023-04-21 16:51:04 +08:00
6a17139423 feat: tooltip for image module 2023-04-21 16:38:21 +08:00
a9a2223469 fix: lint 2023-04-17 09:09:13 +02:00
33d1ee413f fix: typo 2023-04-17 09:07:59 +02:00
0b4c1cb877 Merge pull request #1950 from tleydxdy/shironeko 2023-04-17 09:06:43 +02:00
5e5569bb10 Merge pull request #1858 from uncomfyhalomacro/replace-gethostbyname-getaddrinfo 2023-04-17 09:05:35 +02:00
272d672953 fix: add missing man 2023-04-17 09:03:01 +02:00
ede1d25440 fix: lint 2023-04-17 09:01:14 +02:00
8be889c5aa Merge pull request #2103 from xdavidel/dwl-module
Add DWL tags module
2023-04-17 09:01:00 +02:00
b1e3347fca Merge pull request #2089 from MonstrousOgre/master 2023-04-17 08:59:22 +02:00
da2163ae41 Merge pull request #2092 from chayleaf/mpris-fix-non-dynamic-tag-escapes 2023-04-17 08:58:40 +02:00
1d7d1a8fe8 Merge pull request #2108 from yeheng282/backlight-fix 2023-04-17 08:58:03 +02:00
7d20034067 Merge pull request #2095 from alex-courtis/2094-pulseaudio-states 2023-04-17 08:56:26 +02:00
8aafe817bf Merge pull request #2102 from LukashonakV/Cava 2023-04-16 18:06:53 +02:00
a5607b66ca Cava module
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-04-15 02:36:15 +03:00
61648c55d9 Merge pull request #2113 from LukashonakV/ISSUE#2073 2023-04-13 16:29:34 +02:00
4dff1b91fe Merge branch 'Alexays:master' into dwl-module 2023-04-13 17:18:27 +03:00
1368ba64b5 Fix segfault in destructor 2023-04-13 17:16:37 +03:00
6de3b58d6a ISSUE#2073
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-04-13 17:16:03 +03:00
731eaeb0be Addapt to DWL new tag system
- tagscount is being used instead of tag array
2023-04-13 03:58:57 +03:00
022c9abad4 backlight: support tooltip 2023-04-11 21:01:02 +08:00
a46b8a0109 Merge pull request #2105 from skylar779/master
Made use of node_id_
2023-04-11 11:12:38 +02:00
3b2dfeec01 Made use of node_id_
Checking against names for volume changes seems a bit weird to me and
also didn't really work, so I've made use of node_id_ to check against
this instead and also fixed an issue, where the volume update would
refuse to do its thing despite it being the same id that was used on launch.
2023-04-11 10:51:25 +02:00
e62d339b57 Merge pull request #2104 from numas13/master 2023-04-11 07:44:52 +02:00
18a2b90fc0 fix: generate wireplumber module man page 2023-04-11 08:17:45 +03:00
60cdf10e64 Add DWL tags module 2023-04-11 04:50:21 +03:00
51f0fc6b72 #2094 pulseaudio apply states 2023-04-07 14:19:45 +10:00
6f3a27905d preventing persistent_workspaces and all-outputs from being used together 2023-04-06 12:14:44 +05:30
659fea07ee mpris: fix non-dynamic tags not being html escaped 2023-04-06 13:24:28 +07:00
bd908f6d97 Merge pull request #2090 from chayleaf/mpris-css-fix 2023-04-06 07:26:34 +02:00
cb82326b22 mpris: fix css class application
apply styles to label rather than event_box (fixes play/pause state and
per-player selectors)
2023-04-06 04:50:32 +07:00
33c4964187 replacing spdlog::info with spdlog::debug 2023-04-06 00:34:52 +05:30
3d980f92a3 fix: build 2023-04-03 10:59:29 +02:00
626a1f58be fix: build 2023-04-03 10:51:36 +02:00
1445dc4151 fix: lint 2023-04-03 10:06:01 +02:00
a6084ea7e6 Merge pull request #2068 from TheRealLorenz/master 2023-04-03 09:44:04 +02:00
60467ad7f2 Merge pull request #2064 from en3wton/hyprland-language-format-replacements 2023-04-03 09:43:28 +02:00
ef99b0226c Merge pull request #1932 from ldelossa/wlr-taskbar-sort-app-id 2023-04-03 09:42:19 +02:00
60e0584d16 fix: lint 2023-04-03 09:41:24 +02:00
ba6faa7859 Merge pull request #2011 from chayleaf/improve-mpris 2023-04-03 09:40:01 +02:00
02b3c125a1 fix: init optional to null 2023-04-03 09:38:12 +02:00
20a8039a25 Merge pull request #2080 from cdump/master 2023-03-31 19:17:56 +02:00
ffeef7f40f modules/clock: fix calendar shift in months with 31 days 2023-03-31 20:07:59 +03:00
0cfd1c7094 mpris: don't put ellipsis after whitespace 2023-03-31 19:54:44 +07:00
e5524d5059 mpris: switch base class from AModule to ALabel 2023-03-31 19:54:39 +07:00
774d8880cd mpris: fix potentially invalid seconds count on >1h media 2023-03-31 19:54:39 +07:00
a301b8c4cd mpris: update docs 2023-03-31 19:54:27 +07:00
5383f7bd56 mpris: add unicode support; add position tag 2023-03-31 19:54:20 +07:00
a53c97f7f6 mpris: add tooltip and length limits 2023-03-31 19:53:53 +07:00
9fd2703cb9 Merge pull request #2077 from lilydjwg/master 2023-03-30 20:45:17 +02:00
918de59988 custom module: free memory returned by libc's getline 2023-03-29 21:18:13 +08:00
4b27385da2 Update manpage for sway/window module 2023-03-25 17:41:09 +01:00
f557697e92 Rewrite entire label in sway/window module
Closes #1742
2023-03-25 17:37:49 +01:00
63525ec956 Rename function name 2023-03-25 17:33:01 +01:00
5791a6abc6 Reading persistent workspaces 2023-03-24 23:11:47 +05:30
bbcfb5e138 remove use of new on Layout 2023-03-21 19:30:35 +00:00
4ab4ff790e add more format replacements for hyprland/language 2023-03-19 15:12:11 +00:00
473eb0982b Merge pull request #2053 from paul-ri/exlude-in-array 2023-03-13 11:04:25 +01:00
fa9f3a6dc5 make:Add phony 'test' rule 2023-03-13 00:50:19 +00:00
c26849217e test:Add test for output config with multiple exclusion/wildcard 2023-03-13 00:49:18 +00:00
90206f55be config:output:Allow multiple exclusions & wildcard
Covers the use case where needing to exclude more than 1 output but
still include all other displays.

e.g. I have 3 monitors: laptop + HD + 4K; and 3 bar types:
- The main bar is on the laptop. `output: "laptop-monitor-id"`
- The 4K has a specific waybar bar-1 configuration. `output: "4K-monitor-id"`
- I want all other displays (3rd HD monitor / any HDMI output when presenting)
  to have a plain bar: `output: ["!laptop-monitor-id", "!4k-monitor-id", "*"]`
2023-03-13 00:44:07 +00:00
9a0dbd555d Merge pull request #2049 from 2e0byo/lint 2023-03-08 15:46:41 +01:00
a9015c7c98 refactor: make linter happy. 2023-03-08 14:35:07 +00:00
5b6e9d4e34 Merge pull request #2048 from LDAP/patch-1 2023-03-08 15:29:17 +01:00
8ccf00f0fe Wireplumber: Free the default node name
The `default_node_name_` is reassigned without calling `g_free` on the old string.
2023-03-08 15:21:52 +01:00
823c13a8c0 Merge pull request #2046 from 2e0byo/fix/mpd 2023-03-07 18:12:40 +01:00
3c96881a59 fix: mpd bug paused with no song. 2023-03-07 16:48:05 +00:00
b34d325a71 Merge pull request #2037 from LukashonakV/Happy_clang
Happy clang
2023-03-02 19:42:38 +01:00
3bda22da72 Merge pull request #1589 from qubidt/module-group-orientation
group module: configurable orientation
2023-03-02 19:42:22 +01:00
61a6c00c02 Happy clang 2023-03-02 16:57:32 +03:00
39bc54e3ad Merge pull request #2036 from LukashonakV/Clock_TZ_try_catch 2023-03-02 08:48:56 +01:00
4cb7e55a91 ISSUE #878. Try catch Clock timezones
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-03-02 10:10:34 +03:00
43862ceb34 ISSUE #878. Try catch Clock timezones 2023-03-02 10:07:10 +03:00
f29a400c97 Merge pull request #2035 from LukashonakV/AModule_forceEvents 2023-03-01 23:24:18 +01:00
ce16e029ed Issue #2030. AModule enable_click & enable_scroll
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-03-01 23:39:36 +03:00
79eb2f5bc1 wlr-taskbar: allow sorting by app_id
some users (maybe only myself) may want to sort the task bar by app_id
which then places occurrences of the same task next to each other.

Signed-off-by: Louis DeLosSantos <louis.delos@gmail.com>
2023-03-01 12:16:28 +00:00
b7e6a2dc25 Merge pull request #2034 from pascal-huber/master 2023-03-01 11:06:27 +01:00
23f39938fb Revert "feat(sway): add workspace css class"
This reverts commit a10464d9bb.
2023-03-01 10:55:15 +01:00
8cc8820369 Merge pull request #2017 from pascal-huber/master 2023-03-01 09:43:44 +01:00
c9c8b09e3f Merge pull request #1991 from alex-courtis/add-river-layout 2023-03-01 09:42:39 +01:00
fb1f550c1a Merge pull request #2019 from LukashonakV/ISSUE#1977 2023-03-01 09:38:28 +01:00
e25a7c9719 ISSUE#1977. AModule implements module actions call
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-02-28 15:32:28 +03:00
09142fa322 Merge pull request #2025 from ElyesH/master 2023-02-25 10:49:59 +01:00
1af25094b7 Fix some typos
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
2023-02-25 09:55:04 +01:00
0d99d38089 modules/network.cpp: Remove repeated "the"
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
2023-02-25 09:51:40 +01:00
a10464d9bb feat(sway): add workspace css class 2023-02-18 20:31:12 +01:00
3f23792df0 use the recommended way of using flake-compat 2023-02-16 20:31:02 +07:00
529031f44f fix typo 2023-02-16 20:26:57 +07:00
f51894614d after updating nix.lock all this soup isn't needed 2023-02-16 20:25:07 +07:00
a7dbab79e5 add default.nix for compatibility; update flake.lock 2023-02-16 20:02:39 +07:00
4dcce810d2 improve nix dev shell; override the nixpkgs waybar
for example, the update from 0.9.16 to 0.9.17 broke this flake, after
this change the derivation will be the same as the nixpkgs one. This is
the better option since the flake is unmaintained in this repo (although
it may still break inbetween releases)
2023-02-16 19:45:58 +07:00
43958ef560 fix: compilation errors with cpp_std=c++20 2023-02-11 13:26:03 +11:00
5e4a47c0a8 Merge branch 'master' into add-river-layout 2023-02-11 13:22:46 +11:00
ea38eec2af fix: lint 2023-02-09 13:25:39 +01:00
286a3c70f4 Merge pull request #1978 from kpanuragh/master 2023-02-09 13:25:15 +01:00
9049de583e Merge pull request #1996 from Kuruyia/feat/brightness-control
Closes https://github.com/Alexays/Waybar/issues/1411
2023-02-09 13:24:35 +01:00
a6eaaad97f Merge pull request #1998 from LukashonakV/Clock_revision 2023-02-09 09:32:57 +01:00
d25930793c Merge pull request #2004 from bwaite/fix-memory-leak-upower 2023-02-08 09:02:06 +01:00
67ab269706 Fixing memory leak on update UPower tooltip 2023-02-08 17:19:51 +11:00
48312f4c91 Merge pull request #2001 from LukashonakV/ISSUE#1988 2023-02-04 23:30:12 +01:00
677cbb3384 When no one timezone is provided use system's TZ
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-02-04 23:48:25 +03:00
973aa09f8b refactor(backlight): fix linter 2023-02-03 18:18:44 +01:00
e8c4b85328 feat(backlight): use dbus to set the brightness 2023-02-03 12:58:52 +01:00
b5ad77ea8c Avoid of unnecessary string transformation
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-02-02 13:26:05 +03:00
74a8464c09 updating man page 2023-02-01 21:22:10 +05:30
a78f0124d2 feat(backlight): add brightness control 2023-02-01 14:46:55 +01:00
8da5425189 Merge pull request #1994 from smoak/fix_wireplumber_invalid_pointer 2023-02-01 08:25:05 +01:00
a9c9f1d705 fix(wireplumber): free(): invalid pointer
When freeing the `default_node_name_` pointer using `free`, the `&`
operator was used to try to free the reference rather than the pointer.
This caused a core dump. In order to fix this, the pointer is freed
instead (ie the `&` operator is no longer used).
2023-01-31 17:56:58 -08:00
301b106c48 add river/layout clang-format 2023-01-31 16:41:36 +11:00
757a450324 add river/layout 2023-01-31 16:34:38 +11:00
7b3a6fbaa7 created local variable for _output 2023-01-30 18:35:06 +05:30
c93811b158 Merge pull request #1987 from adamant-pwn/patch-2 2023-01-30 08:57:28 +01:00
7554d7f071 Fixing build issue in image module 2023-01-29 19:13:01 +05:30
220b859948 Fix kbName initialization
Second argument of substr is the length of the substring, _not_ the position. With positions, it's better to do like this.

Example:
```sh
[2023-01-29 13:08:00.927] [debug] hyprland IPC received activelayout>>ITE Tech. Inc. ITE Device(8910) Keyboard,Russian (with Ukrainian-Belorussian layout)
[2023-01-29 13:08:00.927] [debug] kbName is ITE Tech. Inc. ITE Device(8910) Keyboard,Russian (with
```

After the fix it's correct:
```sh
[2023-01-29 13:11:11.408] [debug] hyprland IPC received activelayout>>ITE Tech. Inc. ITE Device(8910) Keyboard,Russian (with Ukrainian-Belorussian layout)
[2023-01-29 13:11:11.408] [debug] kbName is ITE Tech. Inc. ITE Device(8910) Keyboard
```
2023-01-29 13:14:05 +01:00
012baadaca added exec condition check on image module 2023-01-29 10:41:24 +05:30
0ecfce9c61 Merge pull request #1975 from bd-g/fix-image 2023-01-27 14:38:26 +01:00
d2116acb62 Merge pull request #1982 from LukashonakV/ClockSimplify 2023-01-27 14:33:28 +01:00
5d8f9a8273 Clock. Formating simplify
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-01-27 15:57:18 +03:00
9068b7548f for image module get path from executable file 2023-01-25 22:29:33 +05:30
1495b957f1 for image module get path from executable file 2023-01-25 22:28:07 +05:30
47cdd6f988 Merge pull request #1976 from LukashonakV/ClockAltMode 2023-01-25 15:10:08 +01:00
f3f0b008c6 Clock. Proper handletoggle propagation
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-01-25 16:56:45 +03:00
c1ceb7ac42 fix linting issues 2023-01-24 14:53:49 -05:00
e128c48573 image module CSS fix 2023-01-24 14:34:02 -05:00
dd9e3d0172 Merge pull request #1871 from Narice/feat/nix-flake-support 2023-01-24 09:34:03 +01:00
a9613892bb Rename .envrc to .envrc.sample 2023-01-24 09:33:38 +01:00
e7af29ac1e Merge pull request #1971 from LukashonakV/YearCalendar 2023-01-23 17:07:21 +01:00
3b28af8b51 Merge remote-tracking branch 'origin/master' into YearCalendar
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-01-23 18:49:45 +03:00
ed31b20c26 Merge branch 'master' into YearCalendar
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2023-01-23 18:42:32 +03:00
fea7ec9133 Merge pull request #1941 from eneshecan/master
Fixes https://github.com/Alexays/Waybar/issues/1940
2023-01-23 10:24:44 +01:00
3c8ca009ff Sanitize hyprland language string only instead of the whole format. Fixes #1940 2023-01-23 09:50:40 +01:00
f4cfafd238 fix: lint 2023-01-23 09:25:02 +01:00
5182fadede Merge pull request #1944 from PolpOnline/master 2023-01-23 09:22:27 +01:00
18e0e0c7c1 Merge pull request #1964 from tactikauan/master 2023-01-23 09:20:46 +01:00
69b95e6d71 Merge pull request #1959 from alebastr/gcc-13 2023-01-23 09:18:13 +01:00
5e2895ccb3 Merge pull request #1966 from asas1asas200/zeng-doc-image 2023-01-22 13:39:39 +01:00
0ca1c3957a docs(image): add image doc in meson and fix title 2023-01-22 20:16:46 +08:00
de77787b60 Allow any module to implement signal handling 2023-01-21 21:57:28 -03:00
51b6c22cab ci: add glibc locales for date formatting tests.
Add some missing dependencies for Fedora.
2023-01-21 02:18:46 -08:00
01cee153a4 ci: try to build with cpp_std=c++20
Add an extra job to build with `-std=c++20` on Fedora.
Update actions/checkout to v3.
2023-01-21 02:18:45 -08:00
93e340a081 feat(clock): support chrono Time Zone extensions.
Use chrono Calendars and Time Zones (P0355R7, P1466R3) when available
instead of the `date` library.
Verified with a patched build of a recent GCC 13 snapshot.
2023-01-21 02:18:44 -08:00
6225db0a48 test: refactor date formatter tests.
- Add tests for global locale.
- Warn about missing locales.
- Downgrade REQUIRE to CHECK.
- Skip tests if localized formatting does not work as expected.
2023-01-21 02:18:43 -08:00
ea17a66dfc fix: compilation errors with cpp_std=c++20
There were two main issues with fmtlib and C++20 mode:

 - `fmt::format` defaults to compile-time argument checking and requires
   using `fmt::runtime(format_string)` to bypass that.
 - `std::format` implementation introduces conflicting declarations and
   we have to specify the namespace for all `format`/`format_to` calls.
2023-01-20 22:50:02 -08:00
67efe1af89 refactor(clock): remove struct waybar_time
The structure was used to pass the locale instance to the date
formatter. All the supported versions of `fmt` are passing the locale
parameter via `FormatContext.locale()` so we can remove the struct and
simplify the code.

While we at it, drop `date::make_zoned` in favor of CTAD on a
`date::zoned_time` constructor.
2023-01-20 22:50:01 -08:00
ba498869c5 fix(clock): delete outdated warning 2023-01-20 22:50:00 -08:00
43d52c59d9 test: fix build with Catch2 v2.x
Use smaller includes for Catch2 v3.
2023-01-20 22:49:59 -08:00
ca9d237b00 fix(sway): add missing includes for GCC 13
See also: https://gcc.gnu.org/gcc-13/porting_to.html
2023-01-20 22:49:58 -08:00
bc07a82579 Merge pull request #1962 from maximbaz/hyprland-submap-init 2023-01-20 23:46:08 +01:00
6e9f21fc6b hyprland/submap: run initial render on startup 2023-01-20 23:40:08 +01:00
eb9d2d9c5d Merge pull request #1935 from multun/master 2023-01-17 09:40:45 +01:00
be3df41ae0 Merge pull request #1942 from smoak/fix-wireplumber-crashes
Fixes https://github.com/Alexays/Waybar/issues/1907
2023-01-17 09:36:05 +01:00
4e8ccf36b5 fix(wireplumber): waybar crashes when default node changes
In order to fix the issue, the default node name is cached rather than
the default node id. This is due to ids being unstable. So now when the
object manager is installed (ie ready), the default node name is
retrieved and stored for later.

Now when the mixer changed signal is emitted, the id of the changed node
is used to get the node from the object manager. The nodes name is
grabbed off that node and compared against the default node name, if
they match the volume is updated. Some safeguarding has been added such
that if the node cannot be found off the object manager, it's ignored.

Additionally, the "changed" signal on the default nodes api is now
utilized to update the default node name if it has changed. This way if
the default node changes, the module will be updated with the correct
volume and node.nick.

This adds additional debug logging for helping diagnose wireplumber
issues.

This also adds the wireplumber man page entry to the main waybar
supported section.
2023-01-16 10:29:35 -08:00
5649c3f552 river/tags: refactor to support special purpose tags
adds the set-tags and toggle-tags setting so it's possible to have
different tags set vs toggled. This enables the use of e.g. sticky tags

Also clean-up the code a bit.
2023-01-15 12:16:30 -05:00
a4b1b0a211 modules/custom: Added percentage rounding 2023-01-13 22:39:59 +01:00
6c8e186586 Merge pull request #1939 from RobertMueller2/master 2023-01-13 15:31:50 +01:00
544c6deb88 sway/window: fix manpage 2023-01-13 15:08:59 +01:00
e59b4e4c93 Merge pull request #1419 from RobertMueller2/sway-window-newstyles 2023-01-13 13:58:43 +01:00
d71a4569fe Merge pull request #1937 from cyrinux/fix/battery-time-remaining
fix https://github.com/Alexays/Waybar/pull/1867#pullrequestreview-1246756355
2023-01-13 09:51:40 +01:00
120cba0f5e fix: battery time remaining
time is reported in second and should be divided by 3600 and not 1000.
2023-01-13 09:44:39 +01:00
328573332f sway-window, Issue 1399: new style classes
Provides CSS classes empty, floating, tabbed, tiled, solo, stacked and
app_id.

Adds offscreen-css bool option (default false), only effective when
"all-outputs" is true. This adds styles on outputs without focused
node, according to its focused workspaces window situation.

Adds an "offscreen-css-text" string option (default empty), only
effective when "all-outputs" and "offscreen-style" are set. This
is shown as a text on outputs without a focused node.

Adds a "show-focused-workspace" bool option (default false) to indicate
the workspace name if the whole workspace is focused when nodes are
also present. If not set, empty text is shown, but css classes
according to nodes in the workspace are still applied.

Limitation:
When the top level layout changes, there is no sway event so the
module cannot react. Perhaps in the future recurring polling can
be added to go around this limitation.
2023-01-12 05:53:59 +01:00
df0fdce92b get_desktop_app_info: fix crash on failed DesktopAppInfo::create
Even though it makes little sense for this call to fail,
it sometimes randomly does, and takes down waybar with it.
2023-01-11 23:02:12 +01:00
1130e8c8ec Add output parameter format to manpage 2022-12-06 19:05:08 +01:00
d5a86526bc dev: Added Nix Flake support
- Enables Nix users to get the git version of waybar
- Enables Nix users to develop waybar easily
- Adds a fully reproducible development environment
  - The user only has to install Nix, no other depencencies
  - Automatic dev env on directory entry through .envrc
2022-12-06 18:44:26 +01:00
55d7868f86 fix(2): use getaddrinfo() instead of gethostbyname() 2022-12-02 22:18:32 +08:00
0540977e45 format: remove some newlines 2022-12-02 21:42:58 +08:00
385726e701 fix: use getaddrinfo() instead of gethostbyname() 2022-12-02 21:36:14 +08:00
f5a24d12e5 group module: configurable orientation
currently, the orientation of group modules is always the opposite of
the bar. Change it so that:

* the default orientation of the group module is always the opposite of
  its parent, even for nested groups
* the orientation can be overridden in the config
* css ID and class are set for the group element
2022-09-03 18:37:35 -05:00
163 changed files with 4859 additions and 1278 deletions

1
.envrc.sample Normal file
View File

@ -0,0 +1 @@
use flake

View File

@ -9,7 +9,7 @@ jobs:
# https://github.com/actions/virtual-environments/issues/4060 - for lack of VirtualBox on MacOS 11 runners
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Test in FreeBSD VM
uses: vmactions/freebsd-vm@v0
with:

View File

@ -6,7 +6,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: DoozyX/clang-format-lint-action@v0.13
with:
source: '.'

View File

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

1
.gitignore vendored
View File

@ -43,3 +43,4 @@ packagecache
*.exe
*.out
*.app
/.direnv/

View File

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

View File

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

View File

@ -6,6 +6,6 @@ RUN export FEATURES="-ipc-sandbox -network-sandbox -pid-sandbox -sandbox -usersa
emerge --sync && \
eselect news read --quiet new 1>/dev/null 2>&1 && \
emerge --verbose --update --deep --with-bdeps=y --backtrack=30 --newuse @world && \
USE="wayland gtk3 gtk -doc X" 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.24.6 x11-libs/libxkbcommon \
x11-libs/gtk+:3 dev-libs/libdbusmenu dev-libs/libnl sys-power/upower media-libs/libpulse dev-libs/libevdev media-libs/libmpdclient \
media-sound/sndio gui-libs/gtk-layer-shell app-text/scdoc media-sound/playerctl
media-sound/sndio gui-libs/gtk-layer-shell app-text/scdoc media-sound/playerctl dev-libs/iniparser sci-libs/fftw

View File

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

View File

@ -1,7 +1,7 @@
# Waybar [![Licence](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Paypal Donate](https://img.shields.io/badge/Donate-Paypal-2244dd.svg)](https://paypal.me/ARouillard)<br>![Waybar](https://raw.githubusercontent.com/alexays/waybar/master/preview-2.png)
> Highly customizable Wayland bar for Sway and Wlroots based compositors.<br>
> Available in Arch [community](https://www.archlinux.org/packages/community/x86_64/waybar/) or
> Available in Arch [community](https://www.archlinux.org/packages/extra/x86_64/waybar/) or
[AUR](https://aur.archlinux.org/packages/waybar-git/), [Gentoo](https://packages.gentoo.org/packages/gui-apps/waybar), [openSUSE](https://build.opensuse.org/package/show/X11:Wayland/waybar), and [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=waybar).<br>
> *Waybar [examples](https://github.com/Alexays/Waybar/wiki/Examples)*
@ -9,6 +9,7 @@
- Sway (Workspaces, Binding mode, Focused window name)
- River (Mapping mode, Tags, Focused window name)
- Hyprland (Focused window name)
- DWL (Tags) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
- Tray [#21](https://github.com/Alexays/Waybar/issues/21)
- Local time
- Battery

10
default.nix Normal file
View File

@ -0,0 +1,10 @@
(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

111
flake.lock generated Normal file
View File

@ -0,0 +1,111 @@
{
"nodes": {
"devshell": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1676293499,
"narHash": "sha256-uIOTlTxvrXxpKeTvwBI1JGDGtCxMXE3BI0LFwoQMhiQ=",
"owner": "numtide",
"repo": "devshell",
"rev": "71e3022e3ab20bbf1342640547ef5bc14fb43bf4",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"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": 1676283394,
"narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1643381941,
"narHash": "sha256-pHTwvnN4tTsEKkWlXQ8JMY423epos8wUOhthpwJjtpc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5efc8ca954272c4376ac929f4c5ffefcc20551d5",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1676300157,
"narHash": "sha256-1HjRzfp6LOLfcj/HJHdVKWAkX9QRAouoh6AjzJiIerU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "545c7a31e5dedea4a6d372712a18e00ce097d462",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"devshell": "devshell",
"flake-compat": "flake-compat",
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_2"
}
}
},
"root": "root",
"version": 7
}

93
flake.nix Normal file
View File

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

View File

@ -13,7 +13,7 @@ class AIconLabel : public ALabel {
const std::string &format, uint16_t interval = 0, bool ellipsize = false,
bool enable_click = false, bool enable_scroll = false);
virtual ~AIconLabel() = default;
virtual auto update() -> void;
auto update() -> void override;
protected:
Gtk::Image image_;

View File

@ -14,7 +14,7 @@ class ALabel : public AModule {
uint16_t interval = 0, bool ellipsize = false, bool enable_click = false,
bool enable_scroll = false);
virtual ~ALabel() = default;
virtual auto update() -> void;
auto update() -> void override;
virtual std::string getIcon(uint16_t, const std::string &alt = "", uint16_t max = 0);
virtual std::string getIcon(uint16_t, const std::vector<std::string> &alts, uint16_t max = 0);
@ -25,7 +25,7 @@ class ALabel : public AModule {
bool alt_ = false;
std::string default_format_;
virtual bool handleToggle(GdkEventButton *const &e);
bool handleToggle(GdkEventButton *const &e) override;
virtual std::string getState(uint8_t value, bool lesser = false);
};

View File

@ -11,15 +11,20 @@ namespace waybar {
class AModule : public IModule {
public:
AModule(const Json::Value &, const std::string &, const std::string &, bool enable_click = false,
bool enable_scroll = false);
virtual ~AModule();
virtual auto update() -> void;
virtual operator Gtk::Widget &();
auto update() -> void override;
virtual auto refresh(int) -> void{};
operator Gtk::Widget &() override;
auto doAction(const std::string &name) -> void override;
Glib::Dispatcher dp;
protected:
// Don't need to make an object directly
// Derived classes are able to use it
AModule(const Json::Value &, const std::string &, const std::string &, bool enable_click = false,
bool enable_scroll = false);
enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT };
SCROLL_DIR getScrollDir(GdkEventScroll *e);
@ -36,6 +41,7 @@ class AModule : public IModule {
std::vector<int> pid_;
gdouble distance_scrolled_y_;
gdouble distance_scrolled_x_;
std::map<std::string, std::string> eventActionMap_;
static const inline std::map<std::pair<uint, GdkEventType>, std::string> eventMap_{
{std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), "on-click"},
{std::make_pair(1, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click"},

View File

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

View File

@ -1,7 +1,7 @@
#pragma once
#include <json/json.h>
#ifdef HAVE_LIBDATE
#if defined(HAVE_CHRONO_TIMEZONES) || defined(HAVE_LIBDATE)
#include "modules/clock.hpp"
#else
#include "modules/simpleclock.hpp"
@ -18,15 +18,20 @@
#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"
#include "modules/hyprland/workspaces.hpp"
#endif
#if defined(__FreeBSD__) || (defined(__linux__) && !defined(NO_FILESYSTEM))
#include "modules/battery.hpp"
@ -79,6 +84,9 @@
#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"

View File

@ -12,10 +12,10 @@ namespace waybar {
class Group : public AModule {
public:
Group(const std::string&, const Bar&, const Json::Value&);
Group(const std::string&, const std::string&, const Json::Value&, bool);
~Group() = default;
auto update() -> void;
operator Gtk::Widget&();
auto update() -> void override;
operator Gtk::Widget&() override;
Gtk::Box box;
};

View File

@ -6,6 +6,7 @@
#include <vector>
#include "ALabel.hpp"
#include "giomm/dbusproxy.h"
#include "util/json.hpp"
#include "util/sleeper_thread.hpp"
@ -39,8 +40,8 @@ class Backlight : public ALabel {
public:
Backlight(const std::string &, const Json::Value &);
~Backlight();
auto update() -> void;
virtual ~Backlight();
auto update() -> void override;
private:
template <class ForwardIt>
@ -50,6 +51,8 @@ class Backlight : public ALabel {
template <class ForwardIt, class Inserter>
static void enumerate_devices(ForwardIt first, ForwardIt last, Inserter inserter, udev *udev);
bool handleScroll(GdkEventScroll *e) override;
const std::string preferred_device_;
static constexpr int EPOLL_MAX_EVENTS = 16;
@ -60,5 +63,7 @@ class Backlight : public ALabel {
std::vector<BacklightDev> devices_;
// thread must destruct before shared data
util::SleeperThread udev_thread_;
Glib::RefPtr<Gio::DBus::Proxy> login_proxy_;
};
} // namespace waybar::modules

View File

@ -29,8 +29,8 @@ namespace fs = std::filesystem;
class Battery : public ALabel {
public:
Battery(const std::string&, const Json::Value&);
~Battery();
auto update() -> void;
virtual ~Battery();
auto update() -> void override;
private:
static inline const fs::path data_dir_ = "/sys/class/power_supply/";

View File

@ -45,8 +45,8 @@ class Bluetooth : public ALabel {
public:
Bluetooth(const std::string&, const Json::Value&);
~Bluetooth() = default;
auto update() -> void;
virtual ~Bluetooth() = default;
auto update() -> void override;
private:
static auto onInterfaceAddedOrRemoved(GDBusObjectManager*, GDBusObject*, GDBusInterface*,

46
include/modules/cava.hpp Normal file
View File

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

View File

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

View File

@ -17,8 +17,8 @@ namespace waybar::modules {
class Cpu : public ALabel {
public:
Cpu(const std::string&, const Json::Value&);
~Cpu() = default;
auto update() -> void;
virtual ~Cpu() = default;
auto update() -> void override;
private:
double getCpuLoad();

View File

@ -15,9 +15,9 @@ namespace waybar::modules {
class Custom : public ALabel {
public:
Custom(const std::string&, const std::string&, const Json::Value&);
~Custom();
auto update() -> void;
void refresh(int /*signal*/);
virtual ~Custom();
auto update() -> void override;
void refresh(int /*signal*/) override;
private:
void delayWorker();
@ -25,8 +25,8 @@ class Custom : public ALabel {
void parseOutputRaw();
void parseOutputJson();
void handleEvent();
bool handleScroll(GdkEventScroll* e);
bool handleToggle(GdkEventButton* const& e);
bool handleScroll(GdkEventScroll* e) override;
bool handleToggle(GdkEventButton* const& e) override;
const std::string name_;
std::string text_;

View File

@ -14,8 +14,8 @@ namespace waybar::modules {
class Disk : public ALabel {
public:
Disk(const std::string&, const Json::Value&);
~Disk() = default;
auto update() -> void;
virtual ~Disk() = default;
auto update() -> void override;
private:
util::SleeperThread thread_;

View File

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

View File

@ -18,8 +18,8 @@ namespace waybar::modules {
class Gamemode : public AModule {
public:
Gamemode(const std::string &, const Json::Value &);
~Gamemode();
auto update() -> void;
virtual ~Gamemode();
auto update() -> void override;
private:
const std::string DEFAULT_ICON_NAME = "input-gaming-symbolic";
@ -39,7 +39,7 @@ class Gamemode : public AModule {
const Glib::VariantContainerBase &arguments);
void getData();
bool handleToggle(GdkEventButton *const &);
bool handleToggle(GdkEventButton *const &) override;
// Config
std::string format = DEFAULT_FORMAT;

View File

@ -6,6 +6,8 @@
#include <string>
#include <thread>
#include "util/json.hpp"
namespace waybar::modules::hyprland {
class EventHandler {
@ -22,12 +24,14 @@ class IPC {
void unregisterForIPC(EventHandler*);
std::string getSocket1Reply(const std::string& rq);
Json::Value getSocket1JsonReply(const std::string& rq);
private:
void startIPC();
void parseIPC(const std::string&);
std::mutex callbackMutex;
util::JsonParser parser_;
std::list<std::pair<std::string, EventHandler*>> callbacks;
};

View File

@ -10,20 +10,29 @@ namespace waybar::modules::hyprland {
class Language : public waybar::ALabel, public EventHandler {
public:
Language(const std::string&, const waybar::Bar&, const Json::Value&);
~Language();
virtual ~Language();
auto update() -> void;
auto update() -> void override;
private:
void onEvent(const std::string&);
void onEvent(const std::string&) override;
void initLanguage();
std::string getShortFrom(const std::string&);
struct Layout {
std::string full_name;
std::string short_name;
std::string variant;
std::string short_description;
};
auto getLayout(const std::string&) -> Layout;
std::mutex mutex_;
const Bar& bar_;
util::JsonParser parser_;
std::string layoutName_;
Layout layout_;
};
} // namespace waybar::modules::hyprland

View File

@ -10,12 +10,12 @@ namespace waybar::modules::hyprland {
class Submap : public waybar::ALabel, public EventHandler {
public:
Submap(const std::string&, const waybar::Bar&, const Json::Value&);
~Submap();
virtual ~Submap();
auto update() -> void;
auto update() -> void override;
private:
void onEvent(const std::string&);
void onEvent(const std::string&) override;
std::mutex mutex_;
const Bar& bar_;

View File

@ -1,7 +1,5 @@
#include <fmt/format.h>
#include <tuple>
#include "ALabel.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
@ -12,20 +10,37 @@ namespace waybar::modules::hyprland {
class Window : public waybar::ALabel, public EventHandler {
public:
Window(const std::string&, const waybar::Bar&, const Json::Value&);
~Window();
virtual ~Window();
auto update() -> void;
auto update() -> void override;
private:
int getActiveWorkspaceID(std::string);
std::string getLastWindowTitle(int);
void onEvent(const std::string&);
struct Workspace {
int id;
int windows;
std::string last_window;
std::string last_window_title;
static auto parse(const Json::Value&) -> Workspace;
};
auto getActiveWorkspace(const std::string&) -> Workspace;
auto getActiveWorkspace() -> Workspace;
void onEvent(const std::string&) override;
void queryActiveWorkspace();
void setClass(const std::string&, bool enable);
bool separate_outputs;
std::mutex mutex_;
const Bar& bar_;
util::JsonParser parser_;
std::string lastView;
std::string last_title_;
Workspace workspace_;
std::string solo_class_;
std::string last_solo_class_;
bool solo_;
bool all_floating_;
bool fullscreen_;
};
} // namespace waybar::modules::hyprland

View File

@ -0,0 +1,64 @@
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <memory>
#include "AModule.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
namespace waybar::modules::hyprland {
struct WorkspaceDto {
int id;
static WorkspaceDto parse(const Json::Value& value);
};
class Workspace {
public:
Workspace(int id);
Workspace(WorkspaceDto dto);
int id() const { return id_; };
int active() const { return active_; };
std::string& select_icon(std::map<std::string, std::string>& icons_map);
void set_active(bool value = true) { active_ = value; };
Gtk::Button& button() { return button_; };
void update(const std::string& format, const std::string& icon);
private:
int id_;
bool active_;
Gtk::Button button_;
Gtk::Box content_;
Gtk::Label label_;
};
class Workspaces : public AModule, public EventHandler {
public:
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Workspaces();
void update() override;
void init();
private:
void onEvent(const std::string&) override;
void sort_workspaces();
void create_workspace(int id);
void remove_workspace(int id);
std::string format_;
std::map<std::string, std::string> icons_map_;
bool with_icon_;
int active_workspace_id;
std::vector<std::unique_ptr<Workspace>> workspaces_;
std::vector<int> workspaces_to_create_;
std::vector<int> workspaces_to_remove_;
std::mutex mutex_;
const Bar& bar_;
Gtk::Box box_;
};
} // namespace waybar::modules::hyprland

View File

@ -13,13 +13,13 @@ class IdleInhibitor : public ALabel {
public:
IdleInhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
~IdleInhibitor();
auto update() -> void;
virtual ~IdleInhibitor();
auto update() -> void override;
static std::list<waybar::AModule*> modules;
static bool status;
private:
bool handleToggle(GdkEventButton* const& e);
bool handleToggle(GdkEventButton* const& e) override;
void toggleStatus();
const Bar& bar_;

View File

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

View File

@ -12,12 +12,12 @@ namespace waybar::modules {
class Inhibitor : public ALabel {
public:
Inhibitor(const std::string&, const waybar::Bar&, const Json::Value&);
~Inhibitor() override;
auto update() -> void;
virtual ~Inhibitor();
auto update() -> void override;
auto activated() -> bool;
private:
auto handleToggle(::GdkEventButton* const& e) -> bool;
auto handleToggle(::GdkEventButton* const& e) -> bool override;
const std::unique_ptr<::GDBusConnection, void (*)(::GDBusConnection*)> dbus_;
const std::string inhibitors_;

View File

@ -14,8 +14,8 @@ namespace waybar::modules {
class JACK : public ALabel {
public:
JACK(const std::string &, const Json::Value &);
~JACK() = default;
auto update() -> void;
virtual ~JACK() = default;
auto update() -> void override;
int bufSize(jack_nframes_t size);
int sampleRate(jack_nframes_t rate);

View File

@ -19,8 +19,8 @@ namespace waybar::modules {
class KeyboardState : public AModule {
public:
KeyboardState(const std::string&, const waybar::Bar&, const Json::Value&);
~KeyboardState();
auto update() -> void;
virtual ~KeyboardState();
auto update() -> void override;
private:
auto tryAddDevice(const std::string&) -> void;

View File

@ -13,8 +13,8 @@ namespace waybar::modules {
class Memory : public ALabel {
public:
Memory(const std::string&, const Json::Value&);
~Memory() = default;
auto update() -> void;
virtual ~Memory() = default;
auto update() -> void override;
private:
void parseMeminfo();

View File

@ -37,7 +37,7 @@ class MPD : public ALabel {
public:
MPD(const std::string&, const Json::Value&);
virtual ~MPD() noexcept = default;
auto update() -> void;
auto update() -> void override;
private:
std::string getTag(mpd_tag_type type, unsigned idx = 0) const;

View File

@ -16,12 +16,12 @@ extern "C" {
namespace waybar::modules::mpris {
class Mpris : public AModule {
class Mpris : public ALabel {
public:
Mpris(const std::string&, const Json::Value&);
~Mpris();
auto update() -> void;
bool handleToggle(GdkEventButton* const&);
virtual ~Mpris();
auto update() -> void override;
bool handleToggle(GdkEventButton* const&) override;
private:
static auto onPlayerNameAppeared(PlayerctlPlayerManager*, PlayerctlPlayerName*, gpointer) -> void;
@ -39,21 +39,40 @@ class Mpris : public AModule {
std::optional<std::string> artist;
std::optional<std::string> album;
std::optional<std::string> title;
std::optional<std::string> length; // as HH:MM:SS
std::optional<std::string> length; // as HH:MM:SS
std::optional<std::string> position; // same format
};
auto getPlayerInfo() -> std::optional<PlayerInfo>;
auto getIcon(const Json::Value&, const std::string&) -> std::string;
Gtk::Box box_;
Gtk::Label label_;
auto getIconFromJson(const Json::Value&, const std::string&) -> std::string;
auto getArtistStr(const PlayerInfo&, bool) -> std::string;
auto getAlbumStr(const PlayerInfo&, bool) -> std::string;
auto getTitleStr(const PlayerInfo&, bool) -> std::string;
auto getLengthStr(const PlayerInfo&, bool) -> std::string;
auto getPositionStr(const PlayerInfo&, bool) -> std::string;
auto getDynamicStr(const PlayerInfo&, bool, bool) -> std::string;
// config
std::string format_;
std::string format_playing_;
std::string format_paused_;
std::string format_stopped_;
std::chrono::seconds interval_;
std::string tooltip_;
std::string tooltip_playing_;
std::string tooltip_paused_;
std::string tooltip_stopped_;
int artist_len_;
int album_len_;
int title_len_;
int dynamic_len_;
std::string dynamic_separator_;
std::vector<std::string> dynamic_order_;
std::vector<std::string> dynamic_prio_;
bool truncate_hours_;
bool tooltip_len_limits_;
std::string ellipsis_;
std::string player_;
std::vector<std::string> ignored_players_;
@ -63,6 +82,7 @@ class Mpris : public AModule {
std::string lastPlayer;
util::SleeperThread thread_;
std::chrono::time_point<std::chrono::system_clock> last_update_;
};
} // namespace waybar::modules::mpris

View File

@ -21,8 +21,8 @@ namespace waybar::modules {
class Network : public ALabel {
public:
Network(const std::string&, const Json::Value&);
~Network();
auto update() -> void;
virtual ~Network();
auto update() -> void override;
private:
static const uint8_t MAX_RETRY = 5;
@ -62,6 +62,7 @@ class Network : public ALabel {
bool want_link_dump_;
bool want_addr_dump_;
bool dump_in_progress_;
bool is_p2p_;
unsigned long long bandwidth_down_total_;
unsigned long long bandwidth_up_total_;
@ -77,7 +78,6 @@ class Network : public ALabel {
int32_t signal_strength_dbm_;
uint8_t signal_strength_;
std::string signal_strength_app_;
float frequency_;
uint32_t route_priority;
util::SleeperThread thread_;
@ -85,6 +85,7 @@ class Network : public ALabel {
#ifdef WANT_RFKILL
util::Rfkill rfkill_;
#endif
float frequency_;
};
} // namespace waybar::modules

View File

@ -14,8 +14,8 @@ namespace waybar::modules {
class Pulseaudio : public ALabel {
public:
Pulseaudio(const std::string&, const Json::Value&);
~Pulseaudio();
auto update() -> void;
virtual ~Pulseaudio();
auto update() -> void override;
private:
static void subscribeCb(pa_context*, pa_subscription_event_type_t, uint32_t, void*);
@ -25,7 +25,7 @@ class Pulseaudio : public ALabel {
static void serverInfoCb(pa_context*, const pa_server_info*, void*);
static void volumeModifyCb(pa_context*, int, void*);
bool handleScroll(GdkEventScroll* e);
bool handleScroll(GdkEventScroll* e) override;
const std::vector<std::string> getPulseIcon() const;
pa_threaded_mainloop* mainloop_;

View File

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

View File

@ -11,7 +11,7 @@ namespace waybar::modules::river {
class Mode : public waybar::ALabel {
public:
Mode(const std::string &, const waybar::Bar &, const Json::Value &);
~Mode();
virtual ~Mode();
// Handlers for wayland events
void handle_mode(const char *mode);

View File

@ -14,7 +14,7 @@ namespace waybar::modules::river {
class Tags : public waybar::AModule {
public:
Tags(const std::string &, const waybar::Bar &, const Json::Value &);
~Tags();
virtual ~Tags();
// Handlers for wayland events
void handle_focused_tags(uint32_t tags);

View File

@ -13,7 +13,7 @@ namespace waybar::modules::river {
class Window : public waybar::ALabel {
public:
Window(const std::string &, const waybar::Bar &, const Json::Value &);
~Window();
virtual ~Window();
// Handlers for wayland events
void handle_focused_view(const char *title);

View File

@ -10,8 +10,8 @@ namespace waybar::modules {
class Clock : public ALabel {
public:
Clock(const std::string&, const Json::Value&);
~Clock() = default;
auto update() -> void;
virtual ~Clock() = default;
auto update() -> void override;
private:
util::SleeperThread thread_;

View File

@ -12,12 +12,12 @@ namespace waybar::modules {
class Sndio : public ALabel {
public:
Sndio(const std::string &, const Json::Value &);
~Sndio();
auto update() -> void;
virtual ~Sndio();
auto update() -> void override;
auto set_desc(struct sioctl_desc *, unsigned int) -> void;
auto put_val(unsigned int, unsigned int) -> void;
bool handleScroll(GdkEventScroll *);
bool handleToggle(GdkEventButton *const &);
bool handleScroll(GdkEventScroll *) override;
bool handleToggle(GdkEventButton *const &) override;
private:
auto connect_to_sndio() -> void;

View File

@ -13,8 +13,8 @@ namespace waybar::modules::SNI {
class Tray : public AModule {
public:
Tray(const std::string&, const Bar&, const Json::Value&);
~Tray() = default;
auto update() -> void;
virtual ~Tray() = default;
auto update() -> void override;
private:
void onAdd(std::unique_ptr<Item>& item);

View File

@ -8,6 +8,8 @@
#include <cstring>
#include <memory>
#include <mutex>
#include <stdexcept>
#include <string>
#include "ipc.hpp"
#include "util/sleeper_thread.hpp"

View File

@ -17,8 +17,8 @@ namespace waybar::modules::sway {
class Language : public ALabel, public sigc::trackable {
public:
Language(const std::string& id, const Json::Value& config);
~Language() = default;
auto update() -> void;
virtual ~Language() = default;
auto update() -> void override;
private:
enum class DispayedShortFlag { None = 0, ShortName = 1, ShortDescription = 1 << 1 };

View File

@ -13,8 +13,8 @@ namespace waybar::modules::sway {
class Mode : public ALabel, public sigc::trackable {
public:
Mode(const std::string&, const Json::Value&);
~Mode() = default;
auto update() -> void;
virtual ~Mode() = default;
auto update() -> void override;
private:
void onEvent(const struct Ipc::ipc_response&);

View File

@ -15,8 +15,8 @@ namespace waybar::modules::sway {
class Scratchpad : public ALabel {
public:
Scratchpad(const std::string&, const Json::Value&);
~Scratchpad() = default;
auto update() -> void;
virtual ~Scratchpad() = default;
auto update() -> void override;
private:
auto getTree() -> void;

View File

@ -15,14 +15,15 @@ namespace waybar::modules::sway {
class Window : public AIconLabel, public sigc::trackable {
public:
Window(const std::string&, const waybar::Bar&, const Json::Value&);
~Window() = default;
auto update() -> void;
virtual ~Window() = default;
auto update() -> void override;
private:
void setClass(std::string classname, bool enable);
void onEvent(const struct Ipc::ipc_response&);
void onCmd(const struct Ipc::ipc_response&);
std::tuple<std::size_t, int, std::string, std::string, std::string, std::string> getFocusedNode(
const Json::Value& nodes, std::string& output);
std::tuple<std::size_t, int, int, std::string, std::string, std::string, std::string, std::string>
getFocusedNode(const Json::Value& nodes, std::string& output);
void getTree();
void updateAppIconName();
void updateAppIcon();
@ -32,12 +33,14 @@ class Window : public AIconLabel, public sigc::trackable {
int windowId_;
std::string app_id_;
std::string app_class_;
std::string layout_;
std::string old_app_id_;
std::size_t app_nb_;
std::string shell_;
unsigned app_icon_size_{24};
bool update_app_icon_{true};
std::string app_icon_name_;
int floating_count_;
util::JsonParser parser_;
std::mutex mutex_;
Ipc ipc_;

View File

@ -4,6 +4,7 @@
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <string_view>
#include <unordered_map>
#include "AModule.hpp"
@ -17,11 +18,13 @@ namespace waybar::modules::sway {
class Workspaces : public AModule, public sigc::trackable {
public:
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
~Workspaces() = default;
auto update() -> void;
virtual ~Workspaces() = default;
auto update() -> void override;
private:
static inline const std::string workspace_switch_cmd_ = "workspace {} \"{}\"";
static constexpr std::string_view workspace_switch_cmd_ = "workspace {} \"{}\"";
static constexpr std::string_view persistent_workspace_switch_cmd_ =
R"(workspace {} "{}"; move workspace to output "{}"; workspace {} "{}")";
static int convertWorkspaceNameToNum(std::string name);
@ -34,7 +37,7 @@ class Workspaces : public AModule, public sigc::trackable {
const std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const;
uint16_t getWorkspaceIndex(const std::string& name) const;
std::string trimWorkspaceName(std::string);
bool handleScroll(GdkEventScroll*);
bool handleScroll(GdkEventScroll*) override;
const Bar& bar_;
std::vector<Json::Value> workspaces_;

View File

@ -12,8 +12,8 @@ namespace waybar::modules {
class Temperature : public ALabel {
public:
Temperature(const std::string&, const Json::Value&);
~Temperature() = default;
auto update() -> void;
virtual ~Temperature() = default;
auto update() -> void override;
private:
float getTemperature();

View File

@ -19,8 +19,8 @@ namespace waybar::modules::upower {
class UPower : public AModule {
public:
UPower(const std::string &, const Json::Value &);
~UPower();
auto update() -> void;
virtual ~UPower();
auto update() -> void override;
private:
typedef std::unordered_map<std::string, UpDevice *> Devices;
@ -45,7 +45,7 @@ class UPower : public AModule {
void resetDevices();
void removeDevices();
bool show_tooltip_callback(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &tooltip);
bool handleToggle(GdkEventButton *const &);
bool handleToggle(GdkEventButton *const &) override;
std::string timeToString(gint64 time);
const std::string getDeviceStatus(UpDeviceState &state);
@ -74,6 +74,7 @@ class UPower : public AModule {
bool showAltText;
bool upowerRunning;
guint upowerWatcher_id;
std::string nativePath_;
};
} // namespace waybar::modules::upower

View File

@ -24,7 +24,7 @@ class UPowerTooltip : public Gtk::Window {
public:
UPowerTooltip(uint iconSize, uint tooltipSpacing, uint tooltipPadding);
~UPowerTooltip();
virtual ~UPowerTooltip();
uint updateTooltip(Devices& devices);
};

View File

@ -11,8 +11,8 @@ namespace waybar::modules {
class User : public AIconLabel {
public:
User(const std::string&, const Json::Value&);
~User() = default;
auto update() -> void;
virtual ~User() = default;
auto update() -> void override;
bool handleToggle(GdkEventButton* const& e) override;

View File

@ -13,25 +13,32 @@ namespace waybar::modules {
class Wireplumber : public ALabel {
public:
Wireplumber(const std::string&, const Json::Value&);
~Wireplumber();
auto update() -> void;
virtual ~Wireplumber();
auto update() -> void override;
private:
void loadRequiredApiModules();
void prepare();
void activatePlugins();
static void updateVolume(waybar::modules::Wireplumber* self);
static void updateNodeName(waybar::modules::Wireplumber* self);
static uint32_t getDefaultNodeId(waybar::modules::Wireplumber* self);
static void updateVolume(waybar::modules::Wireplumber* self, uint32_t id);
static void updateNodeName(waybar::modules::Wireplumber* self, uint32_t id);
static void onPluginActivated(WpObject* p, GAsyncResult* res, waybar::modules::Wireplumber* self);
static void onObjectManagerInstalled(waybar::modules::Wireplumber* self);
static void onMixerChanged(waybar::modules::Wireplumber* self, uint32_t id);
static void onDefaultNodesApiChanged(waybar::modules::Wireplumber* self);
bool handleScroll(GdkEventScroll* e) override;
WpCore* wp_core_;
GPtrArray* apis_;
WpObjectManager* om_;
WpPlugin* mixer_api_;
WpPlugin* def_nodes_api_;
gchar* default_node_name_;
uint32_t pending_plugins_;
bool muted_;
double volume_;
double min_step_;
uint32_t node_id_{0};
std::string node_name_;
};

View File

@ -40,6 +40,8 @@ class Task {
FULLSCREEN = (1 << 3),
INVALID = (1 << 4)
};
// made public so TaskBar can reorder based on configuration.
Gtk::Button button;
private:
static uint32_t global_id;
@ -53,7 +55,6 @@ class Task {
uint32_t id_;
Gtk::Button button_;
Gtk::Box content_;
Gtk::Image icon_;
Gtk::Label text_before_;

View File

@ -22,7 +22,7 @@ class WorkspaceGroup;
class Workspace {
public:
Workspace(const waybar::Bar &bar, const Json::Value &config, WorkspaceGroup &workspace_group,
zext_workspace_handle_v1 *workspace, uint32_t id);
zext_workspace_handle_v1 *workspace, uint32_t id, std::string name);
~Workspace();
auto update() -> void;
@ -30,11 +30,15 @@ class Workspace {
auto is_active() const -> bool { return state_ & static_cast<uint32_t>(State::ACTIVE); }
auto is_urgent() const -> bool { return state_ & static_cast<uint32_t>(State::URGENT); }
auto is_hidden() const -> bool { return state_ & static_cast<uint32_t>(State::HIDDEN); }
auto is_empty() const -> bool { return state_ & static_cast<uint32_t>(State::EMPTY); }
auto is_persistent() const -> bool { return persistent_; }
// wlr stuff
auto handle_name(const std::string &name) -> void;
auto handle_coordinates(const std::vector<uint32_t> &coordinates) -> void;
auto handle_state(const std::vector<uint32_t> &state) -> void;
auto handle_remove() -> void;
auto make_persistent() -> void;
auto handle_duplicate() -> void;
auto handle_done() -> void;
auto handle_clicked(GdkEventButton *bt) -> bool;
@ -48,6 +52,7 @@ class Workspace {
ACTIVE = (1 << 0),
URGENT = (1 << 1),
HIDDEN = (1 << 2),
EMPTY = (1 << 3),
};
private:
@ -67,6 +72,7 @@ class Workspace {
static std::map<std::string, std::string> icons_map_;
std::string format_;
bool with_icon_ = false;
bool persistent_ = false;
Gtk::Button button_;
Gtk::Box content_;
@ -87,11 +93,14 @@ class WorkspaceGroup {
auto active_only() const -> bool;
auto creation_delayed() const -> bool;
auto workspaces() -> std::vector<std::unique_ptr<Workspace>> & { return workspaces_; }
auto persistent_workspaces() -> std::vector<std::string> & { return persistent_workspaces_; }
auto sort_workspaces() -> void;
auto set_need_to_sort() -> void { need_to_sort = true; }
auto add_button(Gtk::Button &button) -> void;
auto remove_button(Gtk::Button &button) -> void;
auto fill_persistent_workspaces() -> void;
auto create_persistent_workspaces() -> void;
// wlr stuff
auto handle_workspace_create(zext_workspace_handle_v1 *workspace_handle) -> void;
@ -115,6 +124,8 @@ class WorkspaceGroup {
uint32_t id_;
std::vector<std::unique_ptr<Workspace>> workspaces_;
bool need_to_sort = false;
std::vector<std::string> persistent_workspaces_;
bool persistent_created_ = false;
};
class WorkspaceManager : public AModule {

View File

@ -989,7 +989,7 @@ struct Help : Opt {
showHelpFlag = flag;
return ParserResult::ok(ParseResultType::ShortCircuitAll);
}) {
static_cast<Opt &> (*this)("display usage information")["-?"]["-h"]["--help"].optional();
static_cast<Opt &>(*this)("display usage information")["-?"]["-h"]["--help"].optional();
}
};

View File

@ -1,5 +1,6 @@
#pragma once
#include <fcntl.h>
#include <giomm.h>
#include <spdlog/spdlog.h>
#include <sys/wait.h>
@ -68,7 +69,11 @@ inline int close(FILE* fp, pid_t pid) {
inline FILE* open(const std::string& cmd, int& pid) {
if (cmd == "") return nullptr;
int fd[2];
if (pipe(fd) != 0) {
// Open the pipe with the close-on-exec flag set, so it will not be inherited
// by any other subprocesses launched by other threads (which could result in
// the pipe staying open after this child dies, causing us to hang when trying
// to read from it)
if (pipe2(fd, O_CLOEXEC) != 0) {
spdlog::error("Unable to pipe fd");
return nullptr;
}
@ -77,6 +82,8 @@ inline FILE* open(const std::string& cmd, int& pid) {
if (child_pid < 0) {
spdlog::error("Unable to exec cmd {}, error {}", cmd.c_str(), strerror(errno));
::close(fd[0]);
::close(fd[1]);
return nullptr;
}

60
include/util/date.hpp Normal file
View File

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

View File

@ -66,9 +66,9 @@ struct formatter<pow_format> {
std::string string;
switch (spec) {
case '>':
return format_to(ctx.out(), "{:>{}}", fmt::format("{}", s), max_width);
return fmt::format_to(ctx.out(), "{:>{}}", fmt::format("{}", s), max_width);
case '<':
return format_to(ctx.out(), "{:<{}}", fmt::format("{}", s), max_width);
return fmt::format_to(ctx.out(), "{:<{}}", fmt::format("{}", s), max_width);
case '=':
format = "{coefficient:<{number_width}.1f}{padding}{prefix}{unit}";
break;
@ -77,8 +77,8 @@ struct formatter<pow_format> {
format = "{coefficient:.1f}{prefix}{unit}";
break;
}
return format_to(
ctx.out(), format, fmt::arg("coefficient", fraction),
return fmt::format_to(
ctx.out(), fmt::runtime(format), fmt::arg("coefficient", fraction),
fmt::arg("number_width", number_width),
fmt::arg("prefix", std::string() + units[pow] + ((s.binary_ && pow) ? "i" : "")),
fmt::arg("unit", s.unit_),

14
include/util/gtk_icon.hpp Normal file
View File

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

View File

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

View File

@ -4,5 +4,5 @@
#include <string>
namespace waybar::util {
std::string rewriteTitle(const std::string&, const Json::Value&);
std::string rewriteString(const std::string&, const Json::Value&);
}

View File

@ -6,6 +6,8 @@
#include <functional>
#include <thread>
#include "prepare_for_sleep.h"
namespace waybar::util {
/**
@ -33,7 +35,11 @@ class SleeperThread {
signal_ = false;
func();
}
}} {}
}} {
connection_ = prepare_for_sleep().connect([this](bool sleep) {
if (not sleep) wake_up();
});
}
SleeperThread& operator=(std::function<void()> func) {
thread_ = std::thread([this, func] {
@ -42,6 +48,11 @@ class SleeperThread {
func();
}
});
if (connection_.empty()) {
connection_ = prepare_for_sleep().connect([this](bool sleep) {
if (not sleep) wake_up();
});
}
return *this;
}
@ -61,7 +72,7 @@ class SleeperThread {
return condvar_.wait_until(lk, time_point, [this] { return signal_ || !do_run_; });
}
auto wake_up() {
void wake_up() {
{
std::lock_guard<std::mutex> lck(mutex_);
signal_ = true;
@ -96,6 +107,7 @@ class SleeperThread {
std::mutex mutex_;
bool do_run_ = true;
bool signal_ = false;
sigc::connection connection_;
};
} // namespace waybar::util

View File

@ -1,39 +0,0 @@
#pragma once
#include <date/tz.h>
#include <fmt/format.h>
namespace waybar {
struct waybar_time {
std::locale locale;
date::zoned_seconds ztime;
};
} // namespace waybar
template <>
struct fmt::formatter<waybar::waybar_time> {
std::string_view specs;
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin();
if (it != ctx.end() && *it == ':') {
++it;
}
auto end = it;
while (end != ctx.end() && *end != '}') {
++end;
}
if (end != it) {
specs = {it, std::string_view::size_type(end - it)};
}
return end;
}
template <typename FormatContext>
auto format(const waybar::waybar_time& t, FormatContext& ctx) {
return format_to(ctx.out(), "{}", date::format(t.locale, fmt::to_string(specs), t.ztime));
}
};

View File

@ -58,16 +58,25 @@ The *backlight* module displays the current backlight level.
*on-scroll-up*: ++
typeof: string ++
Command to execute when performing a scroll up on the module.
Command to execute when performing a scroll up on the module. This replaces the default behaviour of brightness control.
*on-scroll-down*: ++
typeof: string
Command to execute when performing a scroll down on the module.
Command to execute when performing a scroll down on the module. This replaces the default behaviour of brightness control.
*smooth-scrolling-threshold*: ++
typeof: double
Threshold to be used when scrolling.
*reverse-scrolling*: ++
typeof: bool ++
Option to reverse the scroll direction.
*scroll-step*: ++
typeof: float ++
default: 1.0 ++
The speed in which to change the brightness when scrolling.
# EXAMPLE:
```

View File

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

49
man/waybar-dwl-tags.5.scd Normal file
View File

@ -0,0 +1,49 @@
waybar-dwl-tags(5)
# NAME
waybar - dwl tags module
# DESCRIPTION
The *tags* module displays the current state of tags in dwl.
# CONFIGURATION
Addressed by *dwl/tags*
*num-tags*: ++
typeof: uint ++
default: 9 ++
The number of tags that should be displayed. Max 32.
*tag-labels*: ++
typeof: array ++
The label to display for each tag.
*disable-click*: ++
typeof: bool ++
default: false ++
If set to false, you can left click to set focused tag. Right click to toggle tag focus. If set to true this behaviour is disabled.
# EXAMPLE
```
"dwl/tags": {
"num-tags": 5
}
```
# STYLE
- *#tags button*
- *#tags button.occupied*
- *#tags button.focused*
- *#tags button.urgent*
Note that occupied/focused/urgent status may overlap. That is, a tag may be
both occupied and focused at the same time.
# SEE ALSO
waybar(5), dwl(1)

View File

@ -15,7 +15,7 @@ Addressed by *hyprland/language*
*format*: ++
typeof: string ++
default: {} ++
The format, how information should be displayed. On {} the currently selected language is displayed.
The format, how information should be displayed.
*format-<lang>* ++
typeof: string++
@ -26,12 +26,22 @@ Addressed by *hyprland/language*
Specifies which keyboard to use from hyprctl devices output. Using the option that begins with "at-translated-set..." is recommended.
# FORMAT REPLACEMENTS
*{short}*: Short name of layout (e.g. "us"). Equals to {}.
*{shortDescription}*: Short description of layout (e.g. "en").
*{long}*: Long name of layout (e.g. "English (Dvorak)").
*{variant}*: Variant of layout (e.g. "dvorak").
# EXAMPLES
```
"hyprland/language": {
"format": "Lang: {}"
"format": "Lang: {long}"
"format-en": "AMERICA, HELL YEAH!"
"format-tr": "As bayrakları"
"keyboard-name": "at-translated-set-2-keyboard"

View File

@ -0,0 +1,59 @@
waybar-wlr-workspaces(5)
# NAME
waybar - hyprland workspaces module
# DESCRIPTION
The *workspaces* module displays the currently used workspaces in hyprland compositor.
# CONFIGURATION
Addressed by *hyprland/workspaces*
*format*: ++
typeof: string ++
default: {id} ++
The format, how information should be displayed.
*format-icons*: ++
typeof: array ++
Based on the workspace id and state, the corresponding icon gets selected. See *icons*.
# FORMAT REPLACEMENTS
*{id}*: id of workspace assigned by compositor
*{icon}*: Icon, as defined in *format-icons*.
# ICONS
Additional to workspace name matching, the following *format-icons* can be set.
- *default*: Will be shown, when no string match is found.
- *active*: Will be shown, when workspace is active
# EXAMPLES
```
"wlr/workspaces": {
"format": "{name}: {icon}",
"format-icons": {
"1": "",
"2": "",
"3": "",
"4": "",
"5": "",
"active": "",
"default": ""
},
"sort-by-number": true
}
```
# Style
- *#workspaces*
- *#workspaces button*
- *#workspaces button.active*

View File

@ -1,4 +1,4 @@
waybar-custom(5)
waybar-image(5)
# NAME
@ -10,12 +10,13 @@ The *image* module displays an image from a path.
# CONFIGURATION
Addressed by *custom/<name>*
*path*: ++
typeof: string ++
The path to the image.
*exec*: ++
typeof: string ++
The path to the script, which should return image path file
it will only execute if the path is not set
*size*: ++
typeof: integer ++
The width/height to render the image.
@ -56,17 +57,31 @@ Addressed by *custom/<name>*
typeof: double ++
Threshold to be used when scrolling.
# EXAMPLES
*tooltip*: ++
typeof: bool ++
default: true ++
Option to enable tooltip on hover.
## Spotify:
# SCRIPT OUTPUT
## mpd:
Similar to the *custom* module, output values of the script is *newline* separated.
The following is the output format:
```
"image/album-art": {
$path\\n$tooltip
```
# EXAMPLES
```
"image#album-art": {
"path": "/tmp/mpd_art",
"size": 32,
"interval": 5,
"on-click": "mpc toggle"
}
```
# STYLE
- *#image*

View File

@ -74,20 +74,20 @@ Addressed by *mpd*
Tooltip information displayed when the MPD server can't be reached.
*artist-len*: ++
typeof: integer ++
Maximum length of the Artist tag.
typeof: integer ++
Maximum length of the Artist tag.
*album-len*: ++
typeof: integer ++
Maximum length of the Album tag.
typeof: integer ++
Maximum length of the Album tag.
*album-artist-len*: ++
typeof: integer ++
Maximum length of the Album Artist tag.
typeof: integer ++
Maximum length of the Album Artist tag.
*title-len*: ++
typeof: integer ++
Maximum length of the Title tag.
typeof: integer ++
Maximum length of the Title tag.
*rotate*: ++
typeof: integer ++
@ -98,12 +98,12 @@ Addressed by *mpd*
The maximum length in character the module should display.
*min-length*: ++
typeof: integer ++
The minimum length in characters the module should take up.
typeof: integer ++
The minimum length in characters the module should take up.
*align*: ++
typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*on-click*: ++
typeof: string ++

View File

@ -33,6 +33,100 @@ The *mpris* module displays currently playing media via libplayerctl.
typeof: string ++
The status-specific text format.
*tooltip*: ++
typeof: bool ++
default: true ++
Option to disable tooltip on hover.
*tooltip-format*: ++
typeof: string ++
default: {player} ({status}) {dynamic} ++
The tooltip text format.
*tooltip-format-[status]*: ++
typeof: string ++
The status-specific tooltip format.
*artist-len*: ++
typeof: integer ++
Maximum length of the Artist tag (Wide/Fullwidth Unicode characters
count as two). Set to zero to hide the artist in `{dynamic}` tag.
*album-len*: ++
typeof: integer ++
Maximum length of the Album tag (Wide/Fullwidth Unicode characters count
as two). Set to zero to hide the album in `{dynamic}` tag.
*title-len*: ++
typeof: integer ++
Maximum length of the Title tag (Wide/Fullwidth Unicode characters count
as two). Set to zero to hide the title in `{dynamic}` tag.
*dynamic-len*: ++
typeof: integer ++
Maximum length of the Dynamic tag (Wide/Fullwidth Unicode characters ++
count as two). The dynamic tag will not truncate any tags beyond their ++
set length limits, instead, it will attempt to fit as much of the ++
available tags as possible. It is recommended you set title-len to ++
something less than or equal to this value, so the title will always be ++
displayed.
*dynamic-order*: ++
typeof: []string ++
default: ["title", "artist", "album", "position", "length"] ++
Order of the tags shown by Dynamic tag. The position and length tags ++
will always be combined in the format [{position}/{length}]. The order ++
of these tags in relation to other tags will be determined based on the ++
declaration of the first among the two tags. Absence in this list means ++
force exclusion.
*dynamic-importance-order*: ++
typeof: []string ++
default: ["title", "artist", "album", "position", "length"] ++
Priority of the tags when truncating the Dynamic tag. The final ones ++
will be the first to be truncated. Absence in this list means force ++
inclusion.
*dynamic-separator*: ++
typeof: string ++
default: " - " ++
These characters will be used to separate two different tags, except ++
when one of these tags is position and length.
*truncate-hours*: ++
typeof: bool ++
default: true ++
Whether to hide hours when media duration is less than an hour long.
*enable-tooltip-len-limits*: ++
typeof: bool ++
default: false ++
Option to enable the length limits for the tooltip as well. By default
the tooltip ignores all length limits.
*ellipsis*: ++
typeof: string ++
default: "…" ++
This character will be used when any of the tags exceed their maximum
length. If you don't want to use an ellipsis, set this to empty string.
*rotate*: ++
typeof: integer ++
Positive value to rotate the text label.
*max-length*: ++
typeof: integer ++
The maximum length in character the module should display.
*min-length*: ++
typeof: integer ++
The minimum length in characters the module should take up.
*align*: ++
typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned.
If the module is rotated, it will follow the flow of the text.
*on-click*: ++
typeof: string ++
default: play-pause ++
@ -49,11 +143,11 @@ The *mpris* module displays currently playing media via libplayerctl.
Overwrite default action toggles.
*player-icons*: ++
typeof: map[string]string
typeof: map[string]string ++
Allows setting _{player-icon}_ based on player-name property.
*status-icons*: ++
typeof: map[string]string
typeof: map[string]string ++
Allows setting _{status-icon}_ based on player status (playing, paused,
stopped).
@ -75,16 +169,16 @@ The *mpris* module displays currently playing media via libplayerctl.
*{dynamic}*: Use _{artist}_, _{album}_, _{title}_ and _{length}_, automatically omit++
empty values
*{player-icon}*: Chooses an icon from _player-icons_ based on _{player}_
*{player_icon}*: Chooses an icon from _player-icons_ based on _{player}_
*{status-icon}*: Chooses an icon from _status-icons_ based on _{status}_
*{status_icon}*: Chooses an icon from _status-icons_ based on _{status}_
# EXAMPLES
```
"mpris": {
"format": "DEFAULT: {player_icon} {dynamic}",
"format-paused": "DEFAULT: {status_icon} <i>{dynamic}</i>",
"format": "{player_icon} {dynamic}",
"format-paused": "{status_icon} <i>{dynamic}</i>",
"player-icons": {
"default": "▶",
"mpv": "🎵"

View File

@ -51,12 +51,12 @@ Additionally you can control the volume by scrolling *up* or *down* while the cu
The maximum length in character the module should display.
*min-length*: ++
typeof: integer ++
The minimum length in characters the module should take up.
typeof: integer ++
The minimum length in characters the module should take up.
*align*: ++
typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*scroll-step*: ++
typeof: float ++
@ -91,6 +91,10 @@ Additionally you can control the volume by scrolling *up* or *down* while the cu
typeof: double ++
Threshold to be used when scrolling.
*reverse-scrolling*: ++
typeof: bool ++
Option to reverse the scroll direction.
*tooltip*: ++
typeof: bool ++
default: true ++

View File

@ -0,0 +1,67 @@
waybar-river-layout(5)
# NAME
waybar - river layout module
# DESCRIPTION
The *layout* module displays the current layout in river.
It may not be set until a layout is first applied.
# CONFIGURATION
Addressed by *river/layout*
*format*: ++
typeof: string ++
default: {} ++
The format, how information should be displayed. On {} data gets inserted.
*rotate*: ++
typeof: integer ++
Positive value to rotate the text label.
*max-length*: ++
typeof: integer ++
The maximum length in character the module should display.
*min-length*: ++
typeof: integer ++
The minimum length in characters the module should take up.
*align*: ++
typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*on-click*: ++
typeof: string ++
Command to execute when clicked on the module.
*on-click-middle*: ++
typeof: string ++
Command to execute when middle-clicked on the module using mousewheel.
*on-click-right*: ++
typeof: string ++
Command to execute when you right clicked on the module.
# EXAMPLE
```
"river/layout": {
"format": "{}",
"min-length": 4,
"align": "right"
}
```
# STYLE
- *#layout*
- *#layout.focused* Applied when the output this module's bar belongs to is focused.
# SEE ALSO
waybar(5), river(1)

View File

@ -66,9 +66,28 @@ Addressed by *sway/window*
default: true ++
Option to disable tooltip on hover.
*all-outputs*: ++
typeof: bool ++
default: false ++
Option to show the focused window along with its workspace styles on all outputs.
*offscreen-css*: ++
typeof: bool ++
default: false ++
Only effective when all-outputs is true. Adds style according to present windows on unfocused outputs instead of showing the focused window and style.
*offscreen-css-text*: ++
typeof: string ++
Only effective when both all-outputs and offscreen-style are true. On screens currently not focused, show the given text along with that workspaces styles.
*show-focused-workspace-name*: ++
typeof: bool ++
default: false ++
If the workspace itself is focused and the workspace contains nodes or floating_nodes, show the workspace name. If not set, text remains empty but styles according to nodes in the workspace are still applied.
*rewrite*: ++
typeof: object ++
Rules to rewrite window title. See *rewrite rules*.
Rules to rewrite the module format output. See *rewrite rules*.
*icon*: ++
typeof: bool ++
@ -97,7 +116,7 @@ captures of the expression.
Regular expression and replacement follow ECMA-script rules.
If no expression matches, the title is left unchanged.
If no expression matches, the format output is left unchanged.
Invalid expressions (e.g., mismatched parentheses) are skipped.
@ -117,6 +136,10 @@ Invalid expressions (e.g., mismatched parentheses) are skipped.
# STYLE
- *#window*
- *window#waybar.empty* When no windows is in the workspace
- *window#waybar.solo* When one window is in the workspace
- *window#waybar.empty* When no windows are in the workspace, or screen is not focused and offscreen-css option is not set
- *window#waybar.solo* When one tiled window is in the workspace
- *window#waybar.floating* When there are only floating windows in the workspace
- *window#waybar.stacked* When there is more than one window in the workspace and the workspace layout is stacked
- *window#waybar.tabbed* When there is more than one window in the workspace and the workspace layout is tabbed
- *window#waybar.tiled* When there is more than one window in the workspace and the workspace layout is splith or splitv
- *window#waybar.<app_id>* Where *app_id* is the app_id or *instance* name like (*chromium*) of the only window in the workspace

View File

@ -77,6 +77,11 @@ Addressed by *sway/workspaces*
typeof: bool ++
Whether to sort workspaces alphabetically. Please note this can make "swaymsg workspace prev/next" move to workspaces inconsistent with the ordering shown in Waybar.
warp-on-scroll: ++
typeof: bool ++
default: true ++
If set to false, you can scroll to cycle through workspaces without mouse warping being enabled. If set to true this behaviour is disabled.
# FORMAT REPLACEMENTS
*{value}*: Name of the workspace, as defined by sway.
@ -87,6 +92,8 @@ Addressed by *sway/workspaces*
*{index}*: Index of the workspace.
*{output}*: Output where the workspace is located.
# ICONS
Additional to workspace name matching, the following *format-icons* can be set.

View File

@ -19,6 +19,8 @@ Addressed by *temperature*
*hwmon-path*: ++
typeof: string ++
The temperature path to use, e.g. */sys/class/hwmon/hwmon2/temp1_input* instead of one in */sys/class/thermal/*.
This can also be an array of strings. In this case, waybar will check each item in the array and use the first valid one.
This is suitable if you want to share the same configuration file among different machines with different hardware configurations.
*hwmon-path-abs*: ++
typeof: string ++
@ -117,7 +119,7 @@ Addressed by *temperature*
```
"temperature": {
// "thermal-zone": 2,
// "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
// "hwmon-path": ["/sys/class/hwmon/hwmon2/temp1_input", "/sys/class/thermal/thermal_zone0/temp"],
// "critical-threshold": 80,
// "format-critical": "{temperatureC}°C ",
"format": "{temperatureC}°C "

View File

@ -11,6 +11,12 @@ compatible devices in the tooltip.
# CONFIGURATION
*native-path*: ++
typeof: string ++
default: ++
The battery to monitor. Refer to the https://upower.freedesktop.org/docs/UpDevice.html#UpDevice--native-path ++
Can be obtained using `upower --dump`
*icon-size*: ++
typeof: integer ++
default: 20 ++
@ -68,6 +74,25 @@ depending on the charging state.
"tooltip-spacing": 20
}
```
```
"upower": {
"native-path": "/org/bluez/hci0/dev_D4_AE_41_38_D0_EF",
"icon-size": 20,
"hide-if-empty": true,
"tooltip": true,
"tooltip-spacing": 20
}
```
```
"upower": {
"native-path": "battery_sony_controller_battery_d0o27o88o32ofcoee",
"icon-size": 20,
"hide-if-empty": true,
"tooltip": true,
"tooltip-spacing": 20
}
```
# STYLE

View File

@ -11,59 +11,77 @@ The *wireplumber* module displays the current volume reported by WirePlumber.
# CONFIGURATION
*format*: ++
typeof: string ++
default: *{volume}%* ++
The format, how information should be displayed. This format is used when other formats aren't specified.
typeof: string ++
default: *{volume}%* ++
The format, how information should be displayed. This format is used when other formats aren't specified.
*format-muted*: ++
typeof: string ++
This format is used when the sound is muted.
*format-muted*: ++
typeof: string ++
This format is used when the sound is muted.
*tooltip*: ++
typeof: bool ++
default: *true* ++
Option to disable tooltip on hover.
typeof: bool ++
default: *true* ++
Option to disable tooltip on hover.
*tooltip-format*: ++
typeof: string ++
default: *{node_name}* ++
The format of information displayed in the tooltip.
typeof: string ++
default: *{node_name}* ++
The format of information displayed in the tooltip.
*rotate*: ++
typeof: integer ++
Positive value to rotate the text label.
typeof: integer ++
Positive value to rotate the text label.
*states*: ++
typeof: object ++
A number of volume states which get activated on certain volume levels. See *waybar-states(5)*.
typeof: object ++
A number of volume states which get activated on certain volume levels. See *waybar-states(5)*.
*max-length*: ++
typeof: integer ++
The maximum length in character the module should display.
typeof: integer ++
The maximum length in character the module should display.
*min-length*: ++
typeof: integer ++
The minimum length in characters the module should take up.
typeof: integer ++
The minimum length in characters the module should take up.
*align*: ++
typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
typeof: float ++
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
*scroll-step*: ++
typeof: float ++
default: 1.0 ++
The speed in which to change the volume when scrolling.
*on-click*: ++
typeof: string ++
Command to execute when clicked on the module.
typeof: string ++
Command to execute when clicked on the module.
*on-click-middle*: ++
typeof: string ++
Command to execute when middle-clicked on the module using mousewheel.
typeof: string ++
Command to execute when middle-clicked on the module using mousewheel.
*on-click-right*: ++
typeof: string ++
Command to execute when you right clicked on the module.
typeof: string ++
Command to execute when you right clicked on the module.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
typeof: string ++
Command to execute when the module is updated.
*on-scroll-up*: ++
typeof: string ++
Command to execute when scrolling up on the module. This replaces the default behaviour of volume control.
*on-scroll-down*: ++
typeof: string ++
Command to execute when scrolling down on the module. This replaces the default behaviour of volume control.
*max-volume*: ++
typeof: float ++
default: 100 ++
The maximum volume that can be set, in percentage.
# FORMAT REPLACEMENTS

View File

@ -52,6 +52,11 @@ Addressed by *wlr/taskbar*
default: false ++
If set to true, always reorder the tasks in the taskbar so that the currently active one is first. Otherwise don't reorder.
*sort-by-app-id*: ++
typeof: bool ++
default: false ++
If set to true, group tasks by their app_id. Cannot be used with 'active-first'.
*on-click*: ++
typeof: string ++
The action which should be triggered when clicking on the application button with the left mouse button.
@ -76,6 +81,10 @@ Addressed by *wlr/taskbar*
typeof: object ++
Dictionary of app_id to be replaced with
*rewrite*: ++
typeof: object ++
Rules to rewrite the module format output. See *rewrite rules*.
# FORMAT REPLACEMENTS
*{icon}*: The icon of the application.
@ -104,6 +113,18 @@ Addressed by *wlr/taskbar*
*close*: Close the application.
# REWRITE RULES
*rewrite* is an object where keys are regular expressions and values are
rewrite rules if the expression matches. Rules may contain references to
captures of the expression.
Regular expression and replacement follow ECMA-script rules.
If no expression matches, the format output is left unchanged.
Invalid expressions (e.g., mismatched parentheses) are skipped.
# EXAMPLES
```
@ -119,6 +140,10 @@ Addressed by *wlr/taskbar*
],
"app_ids-mapping": {
"firefoxdeveloperedition": "firefox-developer-edition"
},
"rewrite": {
"Firefox Web Browser": "Firefox",
"Foot Server": "Terminal"
}
}
```

View File

@ -65,7 +65,7 @@ Addressed by *wlr/workspaces*
Additional to workspace name matching, the following *format-icons* can be set.
- *default*: Will be shown, when no string match is found.
- *focused*: Will be shown, when workspace is focused
- *active*: Will be shown, when workspace is active
# EXAMPLES
@ -78,7 +78,7 @@ Additional to workspace name matching, the following *format-icons* can be set.
"3": "",
"4": "",
"5": "",
"focused": "",
"active": "",
"default": ""
},
"sort-by-number": true

View File

@ -30,6 +30,8 @@ Also a minimal example configuration can be found on the at the bottom of this m
*output* ++
typeof: string|array ++
Specifies on which screen this bar will be displayed. Exclamation mark(*!*) can be used to exclude specific output.
Output specification follows sway's and can either be the output port such as "HDMI-A-1" or a string consisting of the make, model and serial such as "Some Company ABC123 0x00000000". See *sway-output(5)* for details.
In an array, star '*\**' can be used at the end to accept all outputs, in case all previous entries are exclusions.
*position* ++
typeof: string ++
@ -77,7 +79,12 @@ Also a minimal example configuration can be found on the at the bottom of this m
Selects one of the preconfigured display modes. This is an equivalent of the sway-bar(5) *mode* command and supports the same values: *dock*, *hide*, *invisible*, *overlay*. ++
Note: *hide* and *invisible* modes may be not as useful without Sway IPC.
modifier-reset ++
*start_hidden* ++
typeof: bool ++
default: *false* ++
Option to start the bar hidden.
*modifier-reset* ++
typeof: string ++
default: *press*
Defines the timing of modifier key to reset the bar visibility.
@ -242,6 +249,7 @@ A module group is defined by specifying a module named "group/some-group-name".
"modules-right": ["group/hardware", "clock"],
"group/hardware": {
"orientation": "vertical",
"modules": [
"cpu",
"memory",
@ -253,6 +261,8 @@ A module group is defined by specifying a module named "group/some-group-name".
}
```
Valid options for the (optional) "orientation" property are: "horizontal", "vertical", "inherit", and "orthogonal" (default).
# SUPPORTED MODULES
- *waybar-backlight(5)*
@ -263,6 +273,7 @@ A module group is defined by specifying a module named "group/some-group-name".
- *waybar-custom(5)*
- *waybar-disk(5)*
- *waybar-idle-inhibitor(5)*
- *waybar-image(5)*
- *waybar-keyboard-state(5)*
- *waybar-memory(5)*
- *waybar-mpd(5)*
@ -272,12 +283,18 @@ A module group is defined by specifying a module named "group/some-group-name".
- *waybar-river-mode(5)*
- *waybar-river-tags(5)*
- *waybar-river-window(5)*
- *waybar-river-layout(5)*
- *waybar-states(5)*
- *waybar-sway-mode(5)*
- *waybar-sway-scratchpad(5)*
- *waybar-sway-window(5)*
- *waybar-sway-workspaces(5)*
- *waybar-wireplumber(5)*
- *waybar-wlr-taskbar(5)*
- *waybar-wlr-workspaces(5)*
- *waybar-temperature(5)*
- *waybar-tray(5)*
# SEE ALSO
*sway-output(5)*

View File

@ -1,8 +1,8 @@
project(
'waybar', 'cpp', 'c',
version: '0.9.17',
version: '0.9.19',
license: 'MIT',
meson_version: '>= 0.49.0',
meson_version: '>= 0.50.0',
default_options : [
'cpp_std=c++17',
'buildtype=release',
@ -123,11 +123,18 @@ gtk_layer_shell = dependency('gtk-layer-shell-0',
required: get_option('gtk-layer-shell'),
fallback : ['gtk-layer-shell', 'gtk_layer_shell_dep'])
systemd = dependency('systemd', required: get_option('systemd'))
tz_dep = dependency('date',
required: false,
default_options : [ 'use_system_tzdb=true' ],
modules : [ 'date::date', 'date::date-tz' ],
fallback: [ 'date', 'tz_dep' ])
cpp_lib_chrono = compiler.compute_int('__cpp_lib_chrono', prefix : '#include <chrono>')
have_chrono_timezones = cpp_lib_chrono >= 201907
if have_chrono_timezones
tz_dep = declare_dependency()
else
tz_dep = dependency('date',
required: false,
default_options : [ 'use_system_tzdb=true' ],
modules : [ 'date::date', 'date::date-tz' ],
fallback: [ 'date', 'tz_dep' ])
endif
prefix = get_option('prefix')
sysconfdir = get_option('sysconfdir')
@ -163,11 +170,15 @@ src_files = files(
'src/client.cpp',
'src/config.cpp',
'src/group.cpp',
'src/util/prepare_for_sleep.cpp',
'src/util/ustring_clen.cpp',
'src/util/sanitize_str.cpp',
'src/util/rewrite_title.cpp'
'src/util/rewrite_string.cpp',
'src/util/gtk_icon.cpp'
)
inc_dirs = ['include']
if is_linux
add_project_arguments('-DHAVE_CPU_LINUX', language: 'cpp')
add_project_arguments('-DHAVE_MEMORY_LINUX', language: 'cpp')
@ -217,6 +228,12 @@ if true
src_files += 'src/modules/river/mode.cpp'
src_files += 'src/modules/river/tags.cpp'
src_files += 'src/modules/river/window.cpp'
src_files += 'src/modules/river/layout.cpp'
endif
if true
add_project_arguments('-DHAVE_DWL', language: 'cpp')
src_files += 'src/modules/dwl/tags.cpp'
endif
if true
@ -225,6 +242,7 @@ if true
src_files += 'src/modules/hyprland/window.cpp'
src_files += 'src/modules/hyprland/language.cpp'
src_files += 'src/modules/hyprland/submap.cpp'
src_files += 'src/modules/hyprland/workspaces.cpp'
endif
if libnl.found() and libnlgen.found()
@ -312,7 +330,10 @@ if get_option('rfkill').enabled() and is_linux
)
endif
if tz_dep.found()
if have_chrono_timezones
add_project_arguments('-DHAVE_CHRONO_TIMEZONES', language: 'cpp')
src_files += 'src/modules/clock.cpp'
elif tz_dep.found()
add_project_arguments('-DHAVE_LIBDATE', language: 'cpp')
src_files += 'src/modules/clock.cpp'
else
@ -323,6 +344,17 @@ if get_option('experimental')
add_project_arguments('-DUSE_EXPERIMENTAL', language: 'cpp')
endif
cava = dependency('cava',
version : '>=0.8.4',
required: get_option('cava'),
fallback : ['cava', 'cava_dep'],
not_found_message: 'cava is not found. Building waybar without cava')
if cava.found()
add_project_arguments('-DHAVE_LIBCAVA', language: 'cpp')
src_files += 'src/modules/cava.cpp'
endif
subdir('protocol')
executable(
@ -356,9 +388,10 @@ executable(
gtk_layer_shell,
libsndio,
tz_dep,
xkbregistry
xkbregistry,
cava
],
include_directories: [include_directories('include')],
include_directories: inc_dirs,
install: true,
)
@ -395,6 +428,7 @@ if scdoc.found()
'waybar-disk.5.scd',
'waybar-gamemode.5.scd',
'waybar-idle-inhibitor.5.scd',
'waybar-image.5.scd',
'waybar-keyboard-state.5.scd',
'waybar-memory.5.scd',
'waybar-mpd.5.scd',
@ -404,6 +438,7 @@ if scdoc.found()
'waybar-river-mode.5.scd',
'waybar-river-tags.5.scd',
'waybar-river-window.5.scd',
'waybar-river-layout.5.scd',
'waybar-sway-language.5.scd',
'waybar-sway-mode.5.scd',
'waybar-sway-scratchpad.5.scd',
@ -417,6 +452,8 @@ if scdoc.found()
'waybar-bluetooth.5.scd',
'waybar-sndio.5.scd',
'waybar-upower.5.scd',
'waybar-wireplumber.5.scd',
'waybar-dwl-tags.5.scd',
]
if (giounix.found() and not get_option('logind').disabled())
@ -447,7 +484,7 @@ endif
catch2 = dependency(
'catch2',
version: '>=3.0.0',
version: '>=2.0.0',
fallback: ['catch2', 'catch2_dep'],
required: get_option('tests'),
)

View File

@ -18,3 +18,4 @@ option('tests', type: 'feature', value: 'auto', description: 'Enable tests')
option('experimental', type : 'boolean', value : false, description: 'Enable experimental features')
option('jack', type: 'feature', value: 'auto', description: 'Enable support for JACK')
option('wireplumber', type: 'feature', value: 'auto', description: 'Enable support for WirePlumber')
option('cava', type: 'feature', value: 'auto', description: 'Enable support for Cava')

20
nix/default.nix Normal file
View File

@ -0,0 +1,20 @@
{ lib
, waybar
, version
}:
waybar.overrideAttrs (prev: {
inherit version;
# version = "0.9.17";
src = lib.cleanSourceWith {
filter = name: type:
let
baseName = baseNameOf (toString name);
in
! (
lib.hasSuffix ".nix" baseName
);
src = lib.cleanSource ../.;
};
})

View File

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This is largely ripped from somebar's ipc patchset; just with some personal modifications.
I would probably just submit raphi's patchset but I don't think that would be polite.
-->
<protocol name="dwl_ipc_unstable_v2">
<description summary="inter-proccess-communication about dwl's state">
This protocol allows clients to update and get updates from dwl.
Warning! The protocol described in this file is experimental and
backward incompatible changes may be made. Backward compatible
changes may be added together with the corresponding interface
version bump.
Backward incompatible changes are done by bumping the version
number in the protocol and interface names and resetting the
interface version. Once the protocol is to be declared stable,
the 'z' prefix and the version number in the protocol and
interface names are removed and the interface version number is
reset.
</description>
<interface name="zdwl_ipc_manager_v2" version="1">
<description summary="manage dwl state">
This interface is exposed as a global in wl_registry.
Clients can use this interface to get a dwl_ipc_output.
After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events.
The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client.
</description>
<request name="release" type="destructor">
<description summary="release dwl_ipc_manager">
Indicates that the client will not the dwl_ipc_manager object anymore.
Objects created through this instance are not affected.
</description>
</request>
<request name="get_output">
<description summary="get a dwl_ipc_outout for a wl_output">
Get a dwl_ipc_outout for the specified wl_output.
</description>
<arg name="id" type="new_id" interface="zdwl_ipc_output_v2"/>
<arg name="output" type="object" interface="wl_output"/>
</request>
<event name="tags">
<description summary="Announces tag amount">
This event is sent after binding.
A roundtrip after binding guarantees the client recieved all tags.
</description>
<arg name="amount" type="uint"/>
</event>
<event name="layout">
<description summary="Announces a layout">
This event is sent after binding.
A roundtrip after binding guarantees the client recieved all layouts.
</description>
<arg name="name" type="string"/>
</event>
</interface>
<interface name="zdwl_ipc_output_v2" version="1">
<description summary="control dwl output">
Observe and control a dwl output.
Events are double-buffered:
Clients should cache events and redraw when a dwl_ipc_output.frame event is sent.
Request are not double-buffered:
The compositor will update immediately upon request.
</description>
<enum name="tag_state">
<entry name="none" value="0" summary="no state"/>
<entry name="active" value="1" summary="tag is active"/>
<entry name="urgent" value="2" summary="tag has at least one urgent client"/>
</enum>
<request name="release" type="destructor">
<description summary="release dwl_ipc_outout">
Indicates to that the client no longer needs this dwl_ipc_output.
</description>
</request>
<event name="toggle_visibility">
<description summary="Toggle client visibilty">
Indicates the client should hide or show themselves.
If the client is visible then hide, if hidden then show.
</description>
</event>
<event name="active">
<description summary="Update the selected output.">
Indicates if the output is active. Zero is invalid, nonzero is valid.
</description>
<arg name="active" type="uint"/>
</event>
<event name="tag">
<description summary="Update the state of a tag.">
Indicates that a tag has been updated.
</description>
<arg name="tag" type="uint" summary="Index of the tag"/>
<arg name="state" type="uint" enum="tag_state" summary="The state of the tag."/>
<arg name="clients" type="uint" summary="The number of clients in the tag."/>
<arg name="focused" type="uint" summary="If there is a focused client. Nonzero being valid, zero being invalid."/>
</event>
<event name="layout">
<description summary="Update the layout.">
Indicates a new layout is selected.
</description>
<arg name="layout" type="uint" summary="Index of the layout."/>
</event>
<event name="title">
<description summary="Update the title.">
Indicates the title has changed.
</description>
<arg name="title" type="string" summary="The new title name."/>
</event>
<event name="appid" since="1">
<description summary="Update the appid.">
Indicates the appid has changed.
</description>
<arg name="appid" type="string" summary="The new appid."/>
</event>
<event name="layout_symbol" since="1">
<description summary="Update the current layout symbol">
Indicates the layout has changed. Since layout symbols are dynamic.
As opposed to the zdwl_ipc_manager.layout event, this should take precendence when displaying.
You can ignore the zdwl_ipc_output.layout event.
</description>
<arg name="layout" type="string" summary="The new layout"/>
</event>
<event name="frame">
<description summary="The update sequence is done.">
Indicates that a sequence of status updates have finished and the client should redraw.
</description>
</event>
<request name="set_tags">
<description summary="Set the active tags of this output"/>
<arg name="tagmask" type="uint" summary="bitmask of the tags that should be set."/>
<arg name="toggle_tagset" type="uint" summary="toggle the selected tagset, zero for invalid, nonzero for valid."/>
</request>
<request name="set_client_tags">
<description summary="Set the tags of the focused client.">
The tags are updated as follows:
new_tags = (current_tags AND and_tags) XOR xor_tags
</description>
<arg name="and_tags" type="uint"/>
<arg name="xor_tags" type="uint"/>
</request>
<request name="set_layout">
<description summary="Set the layout of this output"/>
<arg name="index" type="uint" summary="index of a layout recieved by dwl_ipc_manager.layout"/>
</request>
</interface>
</protocol>

View File

@ -30,6 +30,7 @@ client_protocols = [
['ext-workspace-unstable-v1.xml'],
['river-status-unstable-v1.xml'],
['river-control-unstable-v1.xml'],
['dwl-ipc-unstable-v2.xml'],
]
client_protos_src = []

View File

@ -16,7 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
</copyright>
<interface name="zriver_status_manager_v1" version="3">
<interface name="zriver_status_manager_v1" version="4">
<description summary="manage river status objects">
A global factory for objects that receive status information specific
to river. It could be used to implement, for example, a status bar.
@ -47,7 +47,7 @@
</request>
</interface>
<interface name="zriver_output_status_v1" version="2">
<interface name="zriver_output_status_v1" version="4">
<description summary="track output tags and focus">
This interface allows clients to receive information about the current
windowing state of an output.
@ -83,6 +83,21 @@
</description>
<arg name="tags" type="uint" summary="32-bit bitfield"/>
</event>
<event name="layout_name" since="4">
<description summary="name of the layout">
Sent once on binding the interface should a layout name exist and again
whenever the name changes.
</description>
<arg name="name" type="string" summary="layout name"/>
</event>
<event name="layout_name_clear" since="4">
<description summary="name of the layout">
Sent when the current layout name has been removed without a new one
being set, for example when the active layout generator disconnects.
</description>
</event>
</interface>
<interface name="zriver_seat_status_v1" version="3">

View File

@ -12,6 +12,7 @@
// "sway/workspaces": {
// "disable-scroll": true,
// "all-outputs": true,
// "warp-on-scroll": false,
// "format": "{name}: {icon}",
// "format-icons": {
// "1": "",

View File

@ -12,6 +12,20 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
config_(std::move(config)),
distance_scrolled_y_(0.0),
distance_scrolled_x_(0.0) {
// Configure module action Map
const Json::Value actions{config_["actions"]};
for (Json::Value::const_iterator it = actions.begin(); it != actions.end(); ++it) {
if (it.key().isString() && it->isString())
if (eventActionMap_.count(it.key().asString()) == 0) {
eventActionMap_.insert({it.key().asString(), it->asString()});
enable_click = true;
enable_scroll = true;
} else
spdlog::warn("Dublicate action is ignored: {0}", it.key().asString());
else
spdlog::warn("Wrong actions section configuration. See config by index: {}", it.index());
}
// configure events' user commands
if (enable_click) {
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
@ -48,19 +62,33 @@ auto AModule::update() -> void {
pid_.push_back(util::command::forkExec(config_["on-update"].asString()));
}
}
// Get mapping between event name and module action name
// Then call overrided doAction in order to call appropriate module action
auto AModule::doAction(const std::string& name) -> void {
if (!name.empty()) {
const std::map<std::string, std::string>::const_iterator& recA{eventActionMap_.find(name)};
// Call overrided action if derrived class has implemented it
if (recA != eventActionMap_.cend() && name != recA->second) this->doAction(recA->second);
}
}
bool AModule::handleToggle(GdkEventButton* const& e) {
std::string format{};
const std::map<std::pair<uint, GdkEventType>, std::string>::const_iterator& rec{
eventMap_.find(std::pair(e->button, e->type))};
std::string format{(rec != eventMap_.cend()) ? rec->second : std::string{""}};
if (rec != eventMap_.cend()) {
// First call module actions
this->AModule::doAction(rec->second);
format = rec->second;
}
// Second call user scripts
if (!format.empty()) {
if (config_[format].isString())
format = config_[format].asString();
else
format.clear();
}
if (!format.empty()) {
pid_.push_back(util::command::forkExec(format));
}
@ -69,11 +97,21 @@ bool AModule::handleToggle(GdkEventButton* const& e) {
}
AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) {
// only affects up/down
bool reverse = config_["reverse-scrolling"].asBool();
bool reverse_mouse = config_["reverse-mouse-scrolling"].asBool();
// ignore reverse-scrolling if event comes from a mouse wheel
GdkDevice* device = gdk_event_get_source_device((GdkEvent*)e);
if (device != NULL && gdk_device_get_source(device) == GDK_SOURCE_MOUSE) {
reverse = reverse_mouse;
}
switch (e->direction) {
case GDK_SCROLL_UP:
return SCROLL_DIR::UP;
return reverse ? SCROLL_DIR::DOWN : SCROLL_DIR::UP;
case GDK_SCROLL_DOWN:
return SCROLL_DIR::DOWN;
return reverse ? SCROLL_DIR::UP : SCROLL_DIR::DOWN;
case GDK_SCROLL_LEFT:
return SCROLL_DIR::LEFT;
case GDK_SCROLL_RIGHT:
@ -90,9 +128,9 @@ AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) {
}
if (distance_scrolled_y_ < -threshold) {
dir = SCROLL_DIR::UP;
dir = reverse ? SCROLL_DIR::DOWN : SCROLL_DIR::UP;
} else if (distance_scrolled_y_ > threshold) {
dir = SCROLL_DIR::DOWN;
dir = reverse ? SCROLL_DIR::UP : SCROLL_DIR::DOWN;
} else if (distance_scrolled_x_ > threshold) {
dir = SCROLL_DIR::RIGHT;
} else if (distance_scrolled_x_ < -threshold) {
@ -122,11 +160,19 @@ AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) {
bool AModule::handleScroll(GdkEventScroll* e) {
auto dir = getScrollDir(e);
if (dir == SCROLL_DIR::UP && config_["on-scroll-up"].isString()) {
pid_.push_back(util::command::forkExec(config_["on-scroll-up"].asString()));
} else if (dir == SCROLL_DIR::DOWN && config_["on-scroll-down"].isString()) {
pid_.push_back(util::command::forkExec(config_["on-scroll-down"].asString()));
}
std::string eventName{};
if (dir == SCROLL_DIR::UP)
eventName = "on-scroll-up";
else if (dir == SCROLL_DIR::DOWN)
eventName = "on-scroll-down";
// First call module actions
this->AModule::doAction(eventName);
// Second call user scripts
if (config_[eventName].isString())
pid_.push_back(util::command::forkExec(config_[eventName].asString()));
dp.emit();
return true;
}

View File

@ -593,6 +593,10 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
setMode(MODE_DEFAULT);
}
if (config["start_hidden"].asBool()) {
setVisible(false);
}
window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap));
#if HAVE_SWAY
@ -725,10 +729,7 @@ void waybar::Bar::setupAltFormatKeyForModuleList(const char* module_list_name) {
void waybar::Bar::handleSignal(int signal) {
for (auto& module : modules_all_) {
auto* custom = dynamic_cast<waybar::modules::Custom*>(module.get());
if (custom != nullptr) {
custom->refresh(signal);
}
module->refresh(signal);
}
}
@ -742,7 +743,13 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
AModule* module;
if (ref.compare(0, 6, "group/") == 0 && ref.size() > 6) {
auto group_module = new waybar::Group(ref, *this, config[ref]);
auto hash_pos = ref.find('#');
auto id_name = ref.substr(6, hash_pos - 6);
auto class_name = hash_pos != std::string::npos ? ref.substr(hash_pos + 1) : "";
auto parent = group ? group : &this->box_;
auto vertical = parent->get_orientation() == Gtk::ORIENTATION_VERTICAL;
auto group_module = new waybar::Group(id_name, class_name, config[ref], vertical);
getModules(factory, ref, &group_module->box);
module = group_module;
} else {
@ -764,11 +771,11 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
modules_right_.emplace_back(module_sp);
}
}
module->dp.connect([module, name] {
module->dp.connect([module, ref] {
try {
module->update();
} catch (const std::exception& e) {
spdlog::error("{}: {}", name.asString(), e.what());
spdlog::error("{}: {}", ref, e.what());
}
});
} catch (const std::exception& e) {

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