Compare commits

...

248 Commits

Author SHA1 Message Date
Alex
d56dd6ee7f chore: v0.11.0 2024-09-13 09:51:11 +02:00
Alex
1142979581 chore: lint 2024-09-13 09:43:19 +02:00
Alexis Rouillard
8a89706d03 Merge pull request #3551 from YaLTeR/niri
Add niri/workspaces, niri/window, niri/language
2024-09-13 09:41:52 +02:00
Alex
a4d31ab10d fix: sni item fmt 2024-09-13 09:40:35 +02:00
Ivan Molodetskikh
34bfefcd2e niri: Gate behind a meson option 2024-09-13 10:34:55 +03:00
Ivan Molodetskikh
fef0bb995c niri: Replace gnu extension with GDataInputStream 2024-09-13 10:34:55 +03:00
Ivan Molodetskikh
46e7ed35de Add niri/workspaces, niri/window, niri/language 2024-09-13 10:34:55 +03:00
Alex
d623a89cd1 fix: sni item fmt 2024-09-13 09:33:40 +02:00
Alexis Rouillard
1210bcd2b5 Merge pull request #3565 from saveman71/hidpi_image_module
feat: hidpi support for image module
2024-09-13 09:09:51 +02:00
Alexis Rouillard
30f6ed05ec Merge pull request #3554 from 3u13r/fix/upower/dont-override-existing-upDevice
fix/upower: upower module selection with multiple devices
2024-09-13 09:08:49 +02:00
Alex
3ade275d10 fix: version 2024-09-13 09:02:23 +02:00
Alex
4354da2849 chore: disable fmt tests 2024-09-13 08:59:36 +02:00
Alex
6417782af6 chore: lint 2024-09-13 08:55:14 +02:00
Alex
64d99a5884 chore(fmt): std format 2024-09-13 08:50:12 +02:00
Alexis Rouillard
627e4a4a50 Merge pull request #3555 from Alexays/update_flake_lock_action
flake.lock: Update
2024-09-13 08:41:29 +02:00
Alex
c2f1a7894b chore: update deps 2024-09-13 08:40:25 +02:00
Alexis Rouillard
6560e32bc1 Merge pull request #3585 from eltociear/patch-1 2024-09-10 07:37:16 +02:00
Ikko Eltociear Ashimine
70f3c1d9e9 chore: update power_profiles_daemon.cpp
minor fix
2024-09-10 01:16:42 +09:00
github-actions[bot]
7a6960842a flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/52ec9ac3b12395ad677e8b62106f0b98c1f8569d?narHash=sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k%3D' (2024-07-28)
  → 'github:NixOS/nixpkgs/71e91c409d1e654808b2621f28a327acfdad8dc2?narHash=sha256-GnR7/ibgIH1vhoy8cYdmXE6iyZqKqFxQSVkFgosBh6w%3D' (2024-08-28)
2024-09-01 00:11:30 +00:00
Leonard Cohnen
9b5c2dc7ed fix: upower module selection with multiple devices
While looping over all the upower devices, the currently set device that will be rendered in the waybar, is overridden. Since the loop doesn't end when the device is found, the upDevice_ is overridden with NULL in the iteration for the next device.

Now we only override upDevice_ if the current device matches the constraints.

Fixes d2a719d67c ("Redo to minimize code duplication.")
Fixes #3267
2024-08-31 20:44:29 +02:00
Antoine Bolvy
0ee519753c feat: hidpi support for image module 2024-08-27 15:43:19 +02:00
Alexis Rouillard
5d184f74d8 Merge pull request #3506 from soreau/taskbar-minimize-hints
taskbar: Send minimize geometry hints
2024-08-26 13:10:43 +02:00
Scott Moreau
4d89c64bed taskbar: Fixup whitespace 2024-08-26 04:44:22 -06:00
Alexis Rouillard
f665d1da52 Merge pull request #3527 from alebastr/hypr-getaddrinfo
hyprland/backend: drop unnecessary getaddrinfo call
2024-08-26 09:03:51 +02:00
Alexis Rouillard
26329b660a Merge pull request #3534 from ilpianista/bugfix/check-format-source
fix: check format-source before use
2024-08-20 14:03:50 +02:00
Andrea Scarpino
0fb1957dae fix: check format-source before use 2024-08-20 13:57:29 +02:00
Alexis Rouillard
c5a4266329 Merge pull request #3531 from yangyingchao/master
fix crash caused by use bar instance after it is freed (use-after-free)
2024-08-19 09:05:30 +02:00
yangyingchao
fd478bf2ab fix crash caused by use bar instance after it is freed (use-after-free) 2024-08-19 13:47:56 +08:00
Aleksei Bavshin
1f23b30b56 hyprland/backend: drop unnecessary getaddrinfo call
Hyprland hasn't been using TCP sockets for IPC since the first release,
so this getaddrinfo call and its result was never needed.

Additionally, it leaks the `aiRes`, causing test failure under ASan.
2024-08-17 22:32:17 -07:00
Alexis Rouillard
21906f07b3 Merge pull request #3511 from hacrvlq/wireplumber-fix
Accept "default-node-changed" signals from wireplumber, even if only the node ID is changed
2024-08-07 09:22:33 +02:00
hacrvlq
c468119f52 fix(wireplumber): Handle changes to the default node ID 2024-08-06 19:59:58 +02:00
Alexis Rouillard
79d3a1a296 Merge pull request #3494 from yangyingchao/master
fix #3490: expand menu file before opening it
2024-08-05 09:51:35 +02:00
Alexis Rouillard
4ae144a724 Merge pull request #3499 from gergo-salyi/cpuhotplug
Handle offline CPUs and CPU hotplug
2024-08-05 09:51:00 +02:00
Scott Moreau
fdc8431709 taskbar: Send minimize geometry hints
This allows compositors to know the minimize widget geometry so that
minimize animations work properly.
2024-08-04 22:49:51 -06:00
Alexis Rouillard
9d15c666b2 Merge pull request #3493 from Alexays/update_flake_lock_action 2024-08-03 08:10:45 +02:00
Alexis Rouillard
2131678f6b Merge pull request #3500 from khaneliman/group 2024-08-03 08:10:02 +02:00
Austin Horstman
17f07b2452 group: proper fix of enter/leave
Ignore mouse leave event when we are still within the parent element
2024-08-02 23:37:52 -05:00
Austin Horstman
05d69ae822 src/util/css_reload_helper: clang-format 2024-08-02 23:06:53 -05:00
Austin Horstman
3ae81d62bc group: fix hover regression
We aren't including the hover detection on the revealer, so when the
animation fires we fire the leave event which starts an infinite loop of
enter/leave while we watch boxes move back and forth.
2024-08-02 23:06:53 -05:00
Austin Horstman
4efa123183 group: clang-tidy 2024-08-02 23:06:53 -05:00
Gergő Sályi
24a9886952 Handle offline CPUs and CPU hotplug
First of all in case when the number CPUs change
prevent out-of-bound index access in
waybar::modules::CpuUsage::getCpuUsage()

Secondly on Linux when updating CPU usage
read /sys/devices/system/cpu/present
and use it to detect the offline CPUs missing from /proc/stat

For offline CPUs report 0 usage and "offline" in the tooltip

Fixes issue #3498

On Linux one can test this functionality with:
echo 0 > /sys/devices/system/cpu/cpu1/online
echo 1 > /sys/devices/system/cpu/cpu1/online

On non-Linux OSes I'm not sure how to detect offline CPUs,
so I didn't add the offline CPU detection there
but at least CPU number change should not cause a crash there anymore
or cause memory safety issues after this fix
2024-08-02 17:32:07 +02:00
yangyingchao
7ec1343ad5 fix #3490: expand menu file before opening it 2024-08-01 18:06:00 +08:00
github-actions[bot]
7e1fffc455 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/693bc46d169f5af9c992095736e82c3488bf7dbb?narHash=sha256-oedh2RwpjEa%2BTNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA%3D' (2024-07-14)
  → 'github:NixOS/nixpkgs/52ec9ac3b12395ad677e8b62106f0b98c1f8569d?narHash=sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k%3D' (2024-07-28)
2024-08-01 00:09:59 +00:00
Alexis Rouillard
003dd3a9a2 Merge pull request #3457 from RobertMueller2/issue_3414
Issue #3414/clock: Shift ONLY calendar
2024-07-22 09:06:08 +02:00
Alexis Rouillard
cece04e02f Merge pull request #3462 from DomCristaldi/walk-symlink-chain 2024-07-21 09:47:43 +02:00
DomCristaldi
58e21e876e walk up symlink tree
"reload_style_on_change" would check if the target file is a symlink,
but only resolves the first link. If the symlink is acutally a chain of
symlink, such as what happens with NixOS's mkOutOfStoreSymlink, we will
not find the actual file style file.

Update the symlink resolution logic to walk down the symlink chain until
it finds a non-symlink. Also check against a the original filename
(which may be a symlink) to guard against infinitely looping on a
circular symlink chain.
2024-07-20 22:58:03 -04:00
Alexis Rouillard
cb8fc1c10d Merge pull request #3459 from khaneliman/bar-visible 2024-07-20 18:16:06 +02:00
Austin Horstman
a544f4b2cd bar: fix setVisible
Accidentally removed updating the visible variable
2024-07-20 09:33:13 -05:00
Rene D. Obermueller
ee0912a254 Issue #3414/clock: Shift ONLY calendar
Right now, for the tooltip, all times are shifted if shift-down/shift-up
actions are used. But it really only makes sense for this to apply to
the {calendar} replacement, so use shiftedNow there and now for all
the rest.
2024-07-20 09:03:49 +02:00
Alex
15e1547661 chore: 0.10.4 2024-07-17 23:04:05 +02:00
Alexis Rouillard
dcbcf90aef Update freebsd.yml 2024-07-17 22:52:39 +02:00
Alexis Rouillard
ed0ed398b7 Update freebsd.yml 2024-07-17 22:46:58 +02:00
Alexis Rouillard
152053e069 Merge pull request #3398 from khaneliman/cursor
AModule: Cursor config option
2024-07-17 22:40:12 +02:00
Alexis Rouillard
496dd05e14 Merge pull request #3443 from yangyingchao/master
fix #3442
2024-07-17 22:38:22 +02:00
Alexis Rouillard
3ff8fc8a10 Merge pull request #3447 from khaneliman/hyprland-disable
hyprland: disable modules instead of rendering empty
2024-07-17 22:37:48 +02:00
Alexis Rouillard
d061d2259e Merge pull request #3448 from khaneliman/sway
sway/workspaces: remove deprecated field and ignore empty rewrite rules
2024-07-17 22:36:58 +02:00
Austin Horstman
90ac7d5d2c sway/workspaces: support ignore window-rewrite
Similar to hyprland implementation to ignore "" empty rules
2024-07-16 22:50:26 -05:00
Austin Horstman
4295faa7c4 hyprland/backend: throw runtime_error instead of log
Allows us to disable modules entirely when socket connection isn't
working. This is similar to how sway handles their socket connections
disabling modules. This supports a single waybar config for multiple
IPCs.
2024-07-16 18:40:47 -05:00
Austin Horstman
9c40137d05 sway/workspaces: clang-tidy 2024-07-16 18:33:43 -05:00
Austin Horstman
17132b250d sway/workspaces: remove deprecated field
Was deprecated a long time ago, we removed the Hyprland version.
Removing this, as well.
2024-07-16 18:33:43 -05:00
Alexis Rouillard
3f61df4e66 Merge pull request #3416 from Ape/pr/ignored_sink_never_running
pulseaudio: Consider ignored sinks never running
2024-07-16 14:20:32 +02:00
Alexis Rouillard
2d9cc623c2 Merge pull request #3422 from RobertMueller2/issue_feat_3256
feat/issue 3256: Toggle drawer state
2024-07-16 14:19:30 +02:00
Alexis Rouillard
f6ff6492ef Merge pull request #3441 from tchaikov/fmt-format-const 2024-07-16 08:12:29 +02:00
yangyingchao
b65ca334a8 fix #3442 2024-07-16 09:07:39 +08:00
Kefu Chai
b71dfce1f7 Fix build with fmt11
Since fmt 11.0.0, formatter:format() is required to be const. Mark
all of the specializations as const to be compatible with fmt 11.

This change is implemented in the same spirit of 7725f6ed5a.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
2024-07-16 08:46:55 +08:00
Alexis Rouillard
5f3a9d9423 Merge pull request #3440 from khaneliman/hyprland-fix
hyprland/window: fix crash when no return from socket
2024-07-15 19:16:06 +02:00
Austin Horstman
895c870d02 network: use fmt for format
Fixes the gentoo build
2024-07-15 09:44:39 -05:00
Austin Horstman
47d7324a19 client: clang-format 2024-07-15 09:02:27 -05:00
Austin Horstman
b19890c0b1 network: clang-format 2024-07-15 09:02:27 -05:00
Austin Horstman
b41fcdedff hyprland/window: fix crash when no return from socket
Gracefully handle lack of response from the IPC. If socket isn't
available, we already log the IPC isn't running. We dont need to crash
program just because we couldn't get responses. We can just return an
empty object.
2024-07-15 09:02:27 -05:00
Austin Horstman
0a78da0315 flake.lock: update 2024-07-15 08:55:32 -05:00
Alexis Rouillard
3d0fd14f3f Merge pull request #3435 from grimsteel/network-bssid 2024-07-13 07:05:19 +02:00
Siddhant Kameswar
e117bd7cb6 network: add bssid format replacement 2024-07-12 20:46:26 -05:00
Alexis Rouillard
2655660509 Merge pull request #3432 from BSFishy/readme_update 2024-07-11 21:01:52 +02:00
Matt Provost
0dd6af5a7e chore: update meson build command
Signed-off-by: Matt Provost <mattprovost6@gmail.com>
2024-07-11 08:01:54 -05:00
Rene D. Obermueller
e2e5d4d447 feat/issue 3256: Toggle drawer state 2024-07-10 07:42:18 +02:00
Alexis Rouillard
44f39ca0ce Merge pull request #3429 from ziyao233/outgoing/fix-fmt11 2024-07-09 21:08:16 +02:00
Yao Zi
7725f6ed5a Fix build with fmt11
Since fmt 11.0.0, formatter:format() is required to be const.Mark
affected functions as const to stay compatible with fmt 11.

Signed-off-by: Yao Zi <ziyao@disroot.org>
2024-07-08 20:28:26 +00:00
Alexis Rouillard
b26ab1f982 Merge pull request #3417 from yangyingchao/master
(temperature) fix clang-tidy lint .
2024-07-06 09:40:02 +02:00
yangyingchao
21d42baa8e (temperature) fix clang-tidy lint . 2024-07-06 08:16:45 +08:00
Lauri Niskanen
23274a9d57 pulseaudio: Consider ignored sinks never running
If the current sink happens to be ignored it is never considered running
so it will be replaced with another sink.
2024-07-06 01:30:11 +03:00
Austin Horstman
f78f29ee66 AModule: retain existing default behavior when unconfigured 2024-07-03 08:20:48 -05:00
Lars-Ragnar A. Haugen
7e2d8ab2a3 fix(#3239): hide cursor type change behind config flag
also, statically configure the cursor type
2024-07-03 08:11:15 -05:00
Alexis Rouillard
6f994c849d Merge pull request #3407 from khaneliman/rewrite-ignore
modules/hyprland/workspace: ignore empty window-rewrite
2024-07-03 08:41:15 +02:00
Austin Horstman
702e10649e modules/hyprland/workspace: ignore empty window-rewrite
I'd like to ignore some windows from having icons or empty space taken
on the bar. By filtering out empty repr we can supply rewrite rules that
will ignore them from being processed and showing an empty space or
default icon.
2024-07-03 00:21:49 -05:00
Alexis Rouillard
ca3877d0b8 Merge pull request #3325 from williamwith4ms/escape_&_in_mediaplayer.py
fix: display titles with '&' correctly
2024-07-02 22:34:10 +02:00
Alexis Rouillard
18e67afe09 Merge pull request #3404 from khaneliman/clang-tidy
treewide: clang-tidy
2024-07-02 22:33:52 +02:00
Austin Horstman
d66685a3aa util: clang-tidy 2024-07-02 10:38:58 -05:00
Austin Horstman
14c3235c12 src: clang-tidy 2024-07-02 10:38:58 -05:00
Alexis Rouillard
034760e8b6 Merge pull request #3399 from RobertMueller2/discussion_3373
fix example in manpage for pulseaudio/slider
2024-07-01 19:27:02 +02:00
Rene D. Obermueller
8f64caceb5 fix example in manpage for pulseaudio/slider 2024-07-01 18:30:58 +02:00
Alexis Rouillard
9997155617 Merge pull request #3267 from luttermann/upower_model
Add config option to select UPower device based on device model.
2024-07-01 09:22:59 +02:00
Alexis Rouillard
ff0f408ab8 Merge pull request #3380 from alerque/debug-keyboard-layout
Add keyboard debug info to hyprland language module
2024-07-01 09:22:08 +02:00
Alexis Rouillard
3262b375c9 Merge pull request #3377 from fglinka/master
Fix build error on Ubuntu 22.04
2024-07-01 09:21:56 +02:00
Alexis Rouillard
494cedb3bc Merge pull request #3393 from RobertMueller2/issue_3366
workaround for icons not rendered for apps existing before waybar launch
2024-07-01 09:21:40 +02:00
Alexis Rouillard
93000e3fca Merge pull request #3395 from RobertMueller2/issue_33341
add hide-empty-text option to hide module whenever output is empty but format is not
2024-07-01 09:20:56 +02:00
Alexis Rouillard
abfb654f90 Merge pull request #3396 from Alexays/update_flake_lock_action
flake.lock: Update
2024-07-01 09:20:39 +02:00
Alexis Rouillard
9c7a275cd6 Merge pull request #3247 from benjamin-voisin/menu
Adding the ability to have dropdown menu for modules
2024-07-01 09:18:13 +02:00
github-actions[bot]
f609042ece flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/ad57eef4ef0659193044870c731987a6df5cf56b?narHash=sha256-SzDKxseEcHR5KzPXLwsemyTR/kaM9whxeiJohbL04rs%3D' (2024-05-29)
  → 'github:NixOS/nixpkgs/b2852eb9365c6de48ffb0dc2c9562591f652242a?narHash=sha256-C8e9S7RzshSdHB7L%2Bv9I51af1gDM5unhJ2xO1ywxNH8%3D' (2024-06-27)
2024-07-01 00:09:58 +00:00
Rene D. Obermueller
8eee568731 manpage for PR #3395 2024-06-30 21:23:54 +02:00
Rene D. Obermueller
fb24e8cb1f add hide-empty-text option to hide module whenever output is empty but format is not 2024-06-30 21:16:52 +02:00
Rene D. Obermueller
64a3133083 workaround for icons not rendered for apps existing before waybar launch 2024-06-30 14:52:49 +02:00
Alexis Rouillard
64f54e1fce Merge pull request #3389 from khaneliman/cleanup 2024-06-28 21:50:08 +02:00
Austin Horstman
c08660d837 modules/hyprland/backend: handle empty json responses
Fixes https://github.com/Alexays/Waybar/issues/3388
2024-06-28 13:18:44 -05:00
Austin Horstman
f6482c36dc hyprland: clangd cleanup 2024-06-28 13:06:14 -05:00
Alexis Rouillard
ccc3c13212 Update archlinux 2024-06-24 08:58:29 +02:00
Alexis Rouillard
1003c220be Merge pull request #3381 from OpenSauce04/deprioritize-battery-capacity
modules/battery: Deprioritize `capacity` /sys value for battery calculation if other methods are available
2024-06-24 08:57:30 +02:00
OpenSauce04
d68bcbd292 modules/battery: Deprioritize capacity /sys value 2024-06-23 14:39:41 +01:00
Caleb Maclennan
4126502fe8 Add debug information for keyboard layout selection 2024-06-23 00:02:48 +03:00
Felix Glinka
136b207a12 Add suggestion by clang-format 2024-06-21 16:43:21 +02:00
Felix Glinka
c4d769a586 Add explicit constructor to struct Profile
Not adding the constructor causes a compilation error on Ubuntu 22.04
with both clang 14 and gcc 11:

/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/alloc_traits.h:518:4: error: no matching function for call to 'construct_at'
          std::construct_at(__p, std::forward<_Args>(__args)...);
          ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/vector.tcc:117:21: note: in instantiation of function template specialization 'std::allocator_traits<std::allocator<waybar::modules::Profile>>::construct<waybar::modules::Profile, Glib::ustring, Glib::ustring>' requested here
            _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
                           ^
../src/modules/power_profiles_daemon.cpp:106:26: note: in instantiation of function template specialization 'std::vector<waybar::modules::Profile>::emplace_back<Glib::ustring, Glib::ustring>' requested here
      availableProfiles_.emplace_back(std::move(name), std::move(driver));
                         ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = waybar::modules::Profile, _Args = <Glib::ustring, Glib::ustring>]: no matching constructor for initialization of 'waybar::modules::Profile'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
2024-06-21 15:32:04 +02:00
Alexis Rouillard
1c1089bade Merge pull request #3364 from khaneliman/persistent-rename 2024-06-16 09:47:03 +02:00
Austin Horstman
b114b1155c treewide: clang-format 2024-06-15 18:44:46 -05:00
Austin Horstman
f9e693b2a2 modules/hyprland/backend: remove testing log warn 2024-06-15 18:37:25 -05:00
Austin Horstman
bac4d03813 modules/hyprland/workspaces: remove deprecated property 2024-06-15 18:34:45 -05:00
Alexis Rouillard
9ba5825009 Merge pull request #3362 from lukasfink1/bt-dyn-controller-pr
Fix device list not being updated on selecting new bluetooth controller
2024-06-14 14:54:22 +02:00
Lukas Fink
0df3c84c0f Fix device list not being updated on selecting new bluetooth controller 2024-06-14 14:00:55 +02:00
Alexis Rouillard
3f49725834 Merge pull request #3360 from lukasfink1/bt-dyn-controller-pr
Add hotplug detection of bluetooth controllers
2024-06-14 09:06:57 +02:00
Lukas Fink
ab91d0bac3 Add hotplug detection of bluetooth controllers 2024-06-14 02:24:24 +02:00
Alexis Rouillard
79a6229522 Merge pull request #3353 from locked-out/muted_icons
Support for muted icons for pulseaudio devices/ports
2024-06-13 08:47:53 +02:00
Oliver Locke
01438f71a4 Added muted icons usage to waybar-pulseaudio man page 2024-06-13 15:59:42 +10:00
Alex
0bc43c1aa7 fix: lint 2024-06-12 23:08:27 +02:00
Alexis Rouillard
e8a2882796 Merge pull request #3320 from rtgiskard/dev
fix mpris: hide on current player vanished
2024-06-12 23:08:00 +02:00
Alexis Rouillard
b955e92276 Merge pull request #3244 from rtgiskard/fix.privacy
fix privacy: consider only configured modules
2024-06-12 23:07:51 +02:00
Alexis Rouillard
562e1e59b1 Merge pull request #3331 from Eisfunke/eisfunke/regex-collection-replace
Enable using capture groups in window-rewrite
2024-06-12 23:02:52 +02:00
Oliver Locke
892042eb92 Support muted icons for pulseaudio devices/ports 2024-06-12 17:03:39 +10:00
Alexis Rouillard
0251e25f23 Merge pull request #3345 from khaneliman/testing
Organize tests and start Hyprland testing
2024-06-10 21:38:01 +02:00
Alexis Rouillard
9bd09aa1b3 Merge pull request #3318 from Alexays/update_flake_lock_action
flake.lock: Update
2024-06-10 21:36:26 +02:00
giskard
1cd013a09b clock: respect tooltip option 2024-06-10 17:31:00 +08:00
giskard
7721dcdae8 mpris: some clang-tidy fix 2024-06-10 17:31:00 +08:00
giskard
e8d91eb14b mpris: hide on current player vanished 2024-06-10 17:31:00 +08:00
giskard
0773786766 privacy: consider only configured modules
along with the local clang-tidy warning fixes
2024-06-10 17:31:00 +08:00
Austin Horstman
71bb2b64bf subprojects/spdlog: bump spdlog
Fixes alpine build and is a commonly distributed version
2024-06-09 15:08:43 -05:00
Austin Horstman
06fa931de9 Dockerfiles/opensuse: add python3-packaging dependency 2024-06-09 13:41:01 -05:00
Austin Horstman
16ff5ee99b .github/workflows/linux: fail-fast 2024-06-09 13:41:01 -05:00
Austin Horstman
08c5df3633 modules/sway/workspaces: clang-format fix 2024-06-09 13:05:47 -05:00
Austin Horstman
b365831839 test/hyprland/backend: fix 2024-06-09 13:04:09 -05:00
Austin Horstman
959422f143 modules/hyprland/backend: protect against crash when XDG_RUNTIME_DIR not set 2024-06-09 10:18:20 -05:00
Austin Horstman
fa2e21dfd5 modules/hyprland/backend: move getSocketFolder to class 2024-06-09 10:18:20 -05:00
Austin Horstman
58e7abba2c tests: split into separate binaries 2024-06-08 22:43:48 -05:00
Austin Horstman
87eaa75b8a test/hyprland/backend: init 2024-06-08 22:43:48 -05:00
Austin Horstman
749f46f86f test/fixtures: Add GlibTestsFixture 2024-06-08 22:18:23 -05:00
Austin Horstman
0055ee6910 modules/hyprland/workspaces: remove unneccesary visibleWorkspaces variable 2024-06-07 13:56:49 -05:00
Austin Horstman
1b3b45779a modules/hyprland/backend: add getSocketFolder to header 2024-06-07 13:56:49 -05:00
Austin Horstman
e1a6d513cc test/config: add hyprland-workspaces config 2024-06-07 13:56:49 -05:00
Alexis Rouillard
f4da203915 Merge pull request #3336 from pjones/pjones/current-only 2024-06-07 08:35:02 +02:00
Peter Jones
637b220f82 sway/workspaces: Correct behavior when "current-only" is set
The `current-only` workspace setting should display only the active
workspace name as determined by its `focused` attribute.  However,
according to the `get_tree` output, workspaces that contain a focused
window will report `"focused": false` and the window will report
`"focused": true.` In this case, Waybar will not display a workspace
name at all.

This change updates the logic for determining if a workspace is
focused by also looking for a focused window.
2024-06-06 15:29:33 -07:00
Alexis Rouillard
365e77af58 Merge pull request #3332 from zspher/patch-wlr-taskbar 2024-06-05 22:07:55 +02:00
zspher
1b1442e3ba fix: taskbar not applying empty class on empty 2024-06-06 03:23:47 +08:00
Nicolas Lenz
d0a8c1d90d document capturing in window-rewrite 2024-06-05 20:16:30 +02:00
Nicolas Lenz
76c2f3166e format RegexCollection output using match results 2024-06-05 19:58:27 +02:00
williammmm
02eaa8b46e escape & in mediaplayer 2024-06-03 19:46:55 +01:00
giskard
4fbd4f212a privacy: consider only configured modules
along with the local clang-tidy warning fixes
2024-06-02 04:07:12 +08:00
github-actions[bot]
1474cc626d flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/44d0940ea560dee511026a53f0e2e2cde489b4d4?narHash=sha256-YN/Ciidm%2BA0fmJPWlHBGvVkcarYWSC%2Bs3NTPk/P%2Bq3c%3D' (2024-03-23)
  → 'github:NixOS/nixpkgs/ad57eef4ef0659193044870c731987a6df5cf56b?narHash=sha256-SzDKxseEcHR5KzPXLwsemyTR/kaM9whxeiJohbL04rs%3D' (2024-05-29)
2024-06-01 00:09:05 +00:00
Alexis Rouillard
7163752aa0 Merge pull request #3317 from jackwilsdon/patch-1
Fix format replacement names
2024-05-31 17:59:21 +02:00
Jack Wilsdon
e9350cf25f Fix format replacement names 2024-05-31 14:31:29 +00:00
Alexis Rouillard
1a1a61e917 Merge pull request #3313 from zjeffer/fix/zjeffer/dockerfiles 2024-05-30 20:28:55 +02:00
zjeffer
532a90259b Dont fail docker image builds when another build fails 2024-05-30 20:18:33 +02:00
zjeffer
cf66604f85 fix fedora image 2024-05-30 19:35:32 +02:00
Alexis Rouillard
9332697ec1 Merge pull request #3064 from alttabber/master
Hyprland/Workspaces: Added option to hide non-visible special workspaces
2024-05-29 10:23:26 +02:00
Alexis Rouillard
ab735f723c Merge pull request #3309 from khaneliman/workflows 2024-05-29 08:07:05 +02:00
Austin Horstman
c5b5b64dfa modules/temperature: remove unused import 2024-05-28 15:41:10 -05:00
Austin Horstman
381fe83008 Makefile: fix meson deprecations 2024-05-28 15:41:10 -05:00
Austin Horstman
8adb0a5644 .github/workflows: fix meson deprecations 2024-05-28 15:41:10 -05:00
Benjamin Voisin
885290d907 📝 improve waybar-menu file 2024-05-28 21:02:07 +02:00
Benjamin Voisin
8220dbb513 📝 add a wayba-menu entry for documenting popup menus. 2024-05-28 20:42:47 +02:00
Benjamin Voisin
d9f2e0f7d2 📝 add menu config informations in manpages 2024-05-28 20:42:12 +02:00
Benjamin Voisin
161c8c4c47 🥅 do not crash when unable to make the menu
When the menu cannot be built (file not existing, or wrongly formatted),
     the menu is not created and a warning with an explanaition is
     displayed.
2024-05-28 19:31:26 +02:00
Benjamin Voisin
f3ed5ca5af 🌱 update default config with a menu example 2024-05-28 18:18:51 +02:00
Alexis Rouillard
0d518cb5a3 Merge pull request #3308 from khaneliman/bugfix/3280
modules/hyprland/backend: use /tmp
2024-05-28 18:00:53 +02:00
Austin Horstman
24e8766aaa hyprland/backend: use /tmp
Was hardcoded to /tmp in previous versions
2024-05-28 11:00:20 -05:00
alttabber
29e3d8c371 Hide non-visible special workspaces 2024-05-28 17:45:01 +02:00
Benjamin Voisin
c3581fb66b 🥅 only check menu if speciifed in the conf 2024-05-28 17:33:44 +02:00
Alexis Rouillard
57f2a57dac Merge pull request #3306 from JohnRTitor/workflows-patch
workflows: add nix workflows
2024-05-28 10:21:39 +02:00
John Titor
b6ca3ea4d9 worflows: add update-flake-lock action
automatically updates the nix flake lock file

runs once a month
2024-05-28 13:29:25 +05:30
John Titor
1a9952d0c0 workflows: add nix-test workflow
Checks the flake
Builds and tests the package
2024-05-28 13:29:25 +05:30
Alex
a4a4be3381 fix: lint 2024-05-28 09:19:21 +02:00
Alexis Rouillard
b7ce0b05b1 Merge pull request #3281 from VlctM/master
fix(#3211) change layer for mode invisible to nullopt
2024-05-28 09:18:36 +02:00
Alexis Rouillard
af87388eb4 Update docker.yml 2024-05-28 09:13:11 +02:00
Alexis Rouillard
2aa8008ae2 Merge pull request #3259 from zjeffer/docker-images-action
Add GitHub action for nightly Docker image building
2024-05-28 09:11:07 +02:00
Alexis Rouillard
d4413f5fa6 Merge pull request #3255 from LukashonakV/ISSUE#2240
Fix Clock. Tooltip calendar text overflows(#2240)
2024-05-28 09:08:31 +02:00
Alexis Rouillard
af7945197e Merge pull request #3260 from zjeffer/clang-tidy
clang-tidy fixes in the privacy module
2024-05-28 09:07:57 +02:00
Alexis Rouillard
ac2fa9870f Merge pull request #3241 from rtgiskard/master
temperature: allow hwmon-path-abs as array
2024-05-27 09:03:08 +02:00
Alexis Rouillard
a3ac6cb099 Merge pull request #3258 from zjeffer/master
Fix debian dockerfile
2024-05-27 08:47:33 +02:00
Alexis Rouillard
dc203b8439 Merge pull request #3299 from khaneliman/cleanup
hyprland: refactor and cleanup
2024-05-27 08:47:09 +02:00
Austin Horstman
f5bb086460 hyprland/workspaces: sort methods 2024-05-24 14:41:59 -05:00
Austin Horstman
9ba9d57c8c hyprland/windowcreationpayload: sort methods 2024-05-24 14:30:31 -05:00
Austin Horstman
82ae474002 hyprland/workspace: sort methods 2024-05-24 14:29:03 -05:00
Austin Horstman
56319a4705 hyprland/workspaces: break up implementations 2024-05-24 14:21:31 -05:00
Austin Horstman
07c91c200a hyprland/workspaces: break up headers 2024-05-24 14:21:31 -05:00
Austin Horstman
d73051e980 hyprland/workspaces: break up doUpdate 2024-05-24 14:21:31 -05:00
Austin Horstman
9fe51af6b0 hyprland/workspaces: break up parseConfig 2024-05-24 14:21:31 -05:00
Austin Horstman
e4353e548a .gitignore: add .ccls-cache 2024-05-24 14:21:31 -05:00
Alexis Rouillard
63bb338343 Merge pull request #3296 from unrealhoang/nix_cava_bump 2024-05-24 06:16:41 +02:00
Unreal Hoang
d012124c03 cava bump: 0.10.2 for nix 2024-05-24 09:18:25 +09:00
Alexis Rouillard
10664922c9 Merge pull request #3294 from LukashonakV/cava_bump 2024-05-23 23:03:49 +02:00
Viktar Lukashonak
60a613ae51 cava bump: 0.10.2
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2024-05-23 16:15:48 +03:00
Alexis Rouillard
35a9ca476d Merge pull request #3289 from yangyingchao/yc-hacking 2024-05-22 09:17:07 +02:00
yangyingchao
b8e68b0e63 (hyprland) fix crash when failed to parse IPC message
IPC messages are parsed in a dedicated thread, and the thread terminates when
an exception is not caught, which causes the waybar process to crash with
SIGABORT.

While this issue might be related to Hyprland, it is really annoying to see
waybar crash. It would be better to catch those exceptions and report errors
instead of crashing.
2024-05-22 12:52:01 +08:00
wmlhwl
b61ea62732 change layer for mode invisible to nullopt 2024-05-19 13:53:09 +02:00
Alexis Rouillard
8ad7c75d79 Merge pull request #3278 from LukashonakV/ISSUE#3276_cava 2024-05-18 11:42:14 +02:00
Viktar Lukashonak
5a1454ab31 Cava. $XDG_CONFIG_HOME validation
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2024-05-18 11:28:10 +03:00
Viktar Lukashonak
b288fdf8c1 ISSUE#2240. Clock Gtk::Label as a calendar tooltip
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2024-05-17 20:17:33 +03:00
Lasse Luttermann
d2a719d67c Redo to minimize code duplication. 2024-05-16 12:37:53 +02:00
Lasse Luttermann
28ef5b7db2 Fix formatting 2024-05-14 10:21:24 +02:00
Lasse Luttermann
6413f25b8d Add config option to select UPower device based on device model. 2024-05-14 10:13:22 +02:00
Alexis Rouillard
912d0e83f3 Merge pull request #3266 from luttermann/master 2024-05-14 09:37:11 +02:00
Lasse Luttermann
3c075bcc53 Fixed formatting 2024-05-14 08:26:44 +02:00
Lasse Luttermann
ba8a88acfb Do not try to compare a string that may be a null-pointer 2024-05-14 08:16:10 +02:00
zjeffer
e27488b48c clang-tidy improvements in privacy module 2024-05-11 16:19:46 +02:00
zjeffer
1828a94b6c clang-tidy: comment case styling options 2024-05-11 16:19:46 +02:00
zjeffer
49afcdf715 Add GitHub action for nightly Dockerfiles building 2024-05-11 16:16:02 +02:00
zjeffer
ff84c6dbaf fix debian dockerfile 2024-05-11 15:59:20 +02:00
Alexis Rouillard
cb2d54a237 Merge pull request #3248 from LukashonakV/ISSUE3223_upower 2024-05-10 06:50:40 +02:00
Viktar Lukashonak
5fe99ea0e1 Upower. Fix segmentation fault
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2024-05-10 00:00:47 +03:00
Benjamin Voisin
21751b2faa 🎨 clang-tidy 2024-05-09 20:59:25 +02:00
Benjamin Voisin
3b87b83076 ♻️ move GMenu to ALabel class 2024-05-09 18:34:26 +02:00
Benjamin Voisin
884b909e7d add GtkMenu to the AModule class
You can configure what key launch the menu with the "menu" element in
the config, the xml file that describes the menu with the "menu-file"
element in the config, and the actions of each buttons with the
"menu-actions" field.
2024-05-09 17:28:08 +02:00
giskard
b980dab6df doc: update waybar-temperature manual page 2024-05-08 23:56:44 +08:00
giskard
e298bf922f temperature: allow hwmon-path-abs as array 2024-05-08 23:55:51 +08:00
ViktarL
2ead1bbf84 Upower refactoring (#3220)
Signed-off-by: Viktar Lukashonak <myxabeer@gmail.com>
2024-05-07 10:29:52 +02:00
Tuur Vanhoutte
29917fb073 Fix hyprland/language events not working with keyboard names with commas in them (#3224) 2024-05-07 08:26:05 +02:00
Alex
e627879b16 chore: 0.10.3 2024-05-06 10:54:52 +02:00
Alex
0572e02d7e fix: lint 2024-05-06 10:51:30 +02:00
Eldar Yusupov
df1a9c5509 Remove listener when window is destroyed (#3215) 2024-05-06 10:51:14 +02:00
Lars-Ragnar A. Haugen
e7779b5458 feat(#3174): hover for whole group (#3201)
* feat(#3174): hover for whole group

* fix: target eventbox for class also

* fix: actually no reason to add handler, just override AModule

* fix: actually remove existing handler as well

drawer functionality still works from my testing. anything else to think
abotu?

* revert: keep id and class on original box

* refactor: clang-format group.hpp

* dev: try stop workflow
2024-05-06 10:51:03 +02:00
Alex
fc6d708fb6 chore: disable cland-tidy for now 2024-05-06 10:50:55 +02:00
Lars-Ragnar A. Haugen
a453ea3c70 fix(#3210): tooltip-format on custom modules not working in some cases (#3213) 2024-05-06 10:47:52 +02:00
Lars-Ragnar A. Haugen
8e8ce0c6bc feat(#3182): style tray icon on hover (#3203) 2024-05-06 10:47:25 +02:00
Bintang
c4e0c569aa flake: fix overlay not actually being applied (#3208) 2024-05-06 10:46:10 +02:00
柳芭老爹
231d6972d7 fix: custom module mediaplayer doesn't respect argument (#3198)
fix custom module mediaplayer which doesn't consider  --exclude argument on player appear
2024-05-03 08:47:41 +02:00
Jacob Birkett
50476edc98 Nix Flake: Fix overlay (again) (#3196) 2024-05-03 08:31:39 +02:00
Lars-Ragnar A. Haugen
0b6476da32 fix: set cursor appropriately on user event hover (#3195) 2024-05-02 22:09:21 +02:00
Jan Beich
79ae530bd2 pipewire: unbreak build on FreeBSD (#3193) 2024-05-02 08:31:40 +02:00
Tuur Vanhoutte
f41458ea24 Fix Hyprland socketpath changed to XDG_RUNTIME_DIR (#3183) 2024-04-29 19:46:28 +02:00
clayton craft
2481f7a292 upower: fix segfault by initializing lastWarningLevel (#3171)
fixes bd8b215416
2024-04-25 10:36:43 +02:00
Alex
61ac7e4e10 fix: lint 2024-04-25 00:16:15 +02:00
Milo Mordaunt
9a3044a54f Cursor change to indicate module clickability (#3108)
* Indicate clickability on mouse hover

* Avoid messy overrides situation

* Update AModule.cpp

* Update AModule.cpp

* Update AModule.cpp

* Update AModule.cpp

---------

Co-authored-by: Alexis Rouillard <alexisr245@gmail.com>
2024-04-25 00:15:40 +02:00
Alexis Rouillard
a597a994d2 Merge pull request #3167 from kiriDevs/battery-health-fix
fix(battery): Fix `{health}` format replacement
2024-04-24 23:16:18 +02:00
Kiri
a2c5a8215b style(battery): Capitalize float 'F' suffix 2024-04-24 15:07:26 +02:00
Kiri
57197b8e01 feat(battery): Also support energy_full (instead of charge_full) 2024-04-24 14:57:11 +02:00
Kiri
5c4e368819 style(battery): Indent level
It's now *inconsistent* in the file, but clang-tidy should be happy, sooo...
2024-04-24 09:05:11 +00:00
Kiri
8d962430dd fix(battery): Remove duplicate line
This is what happens when you copy-paste from GitHub actions
2024-04-24 09:02:03 +00:00
Kiri
54a85ea15f style: Apply clang-format change
At least I hope I copy-pased it correctly
2024-04-24 08:56:24 +00:00
Kiri
efa7dc7ba4 fix(battery): Register health replacement for main format 2024-04-24 10:34:35 +02:00
Alex
a04016e0b6 chore: 0.10.2 2024-04-23 17:59:08 +02:00
Alexis Rouillard
08b0ed1b79 Merge pull request #3165 from haug1/fix/group-drawer-hover
fix(#3162): hover event did not propagate causing issues
2024-04-23 16:23:05 +02:00
Lars-Ragnar A. Haugen
5b7d0a2810 fix(#3162): hover event did not propagate causing issues 2024-04-23 16:18:54 +02:00
165 changed files with 4634 additions and 2156 deletions

View File

@@ -15,15 +15,15 @@ Checks: >
-readability-redundant-member-init,
-readability-redundant-string-init,
-readability-identifier-length
CheckOptions:
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
- { key: readability-identifier-naming.StructCase, value: CamelCase }
- { key: readability-identifier-naming.FunctionCase, value: camelBack }
- { key: readability-identifier-naming.VariableCase, value: camelBack }
- { key: readability-identifier-naming.PrivateMemberCase, value: camelBack }
- { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
- { key: readability-identifier-naming.EnumCase, value: CamelCase }
- { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
- { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }
# CheckOptions:
# - { key: readability-identifier-naming.NamespaceCase, value: lower_case }
# - { key: readability-identifier-naming.ClassCase, value: CamelCase }
# - { key: readability-identifier-naming.StructCase, value: CamelCase }
# - { key: readability-identifier-naming.FunctionCase, value: camelBack }
# - { key: readability-identifier-naming.VariableCase, value: camelBack }
# - { key: readability-identifier-naming.PrivateMemberCase, value: camelBack }
# - { key: readability-identifier-naming.PrivateMemberSuffix, value: _ }
# - { key: readability-identifier-naming.EnumCase, value: CamelCase }
# - { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
# - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
# - { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE }

View File

@@ -16,4 +16,5 @@ jobs:
with:
source: "."
extensions: "hpp,h,cpp,c"
clangFormatVersion: 16
style: "file:.clang-format"
clangFormatVersion: 18

32
.github/workflows/docker.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Build and Push Docker Image
on:
schedule:
# run every night at midnight
- cron: '0 0 * * *'
jobs:
build-and-push:
runs-on: ubuntu-latest
strategy:
fail-fast: false # don't fail the other jobs if one of the images fails to build
matrix:
os: [ 'alpine', 'archlinux', 'debian', 'fedora', 'gentoo', 'opensuse' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfiles/${{ matrix.os }}
push: true
tags: alexays/waybar:${{ matrix.os }}

View File

@@ -14,23 +14,22 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Test in FreeBSD VM
uses: cross-platform-actions/action@v0.23.0
uses: cross-platform-actions/action@v0.25.0
timeout-minutes: 180
env:
CPPFLAGS: '-isystem/usr/local/include'
LDFLAGS: '-L/usr/local/lib'
with:
operating_system: freebsd
version: "13.2"
version: "14.1"
environment_variables: CPPFLAGS LDFLAGS
sync_files: runner-to-vm
run: |
sudo sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
sudo pkg install -y git # subprojects/date
sudo pkg install -y catch evdev-proto gtk-layer-shell gtkmm30 jsoncpp \
libdbusmenu libevdev libfmt libmpdclient libudev-devd meson \
pkgconf pulseaudio scdoc sndio spdlog wayland-protocols upower \
pkgconf pipewire pulseaudio scdoc sndio spdlog wayland-protocols upower \
libinotify
meson build -Dman-pages=enabled
meson setup build -Dman-pages=enabled
ninja -C build
meson test -C build --no-rebuild --print-errorlogs --suite waybar

View File

@@ -9,6 +9,7 @@ concurrency:
jobs:
build:
strategy:
fail-fast: false
matrix:
distro:
- alpine
@@ -26,7 +27,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: configure
run: meson -Dman-pages=enabled -Dcpp_std=${{matrix.cpp_std}} build
run: meson setup -Dman-pages=enabled -Dcpp_std=${{matrix.cpp_std}} build
- name: build
run: ninja -C build
- name: test

17
.github/workflows/nix-tests.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: "Nix-Tests"
on:
pull_request:
push:
jobs:
nix-flake-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- run: nix flake show
- run: nix flake check --print-build-logs
- run: nix build --print-build-logs

View File

@@ -0,0 +1,21 @@
name: update-flake-lock
on:
workflow_dispatch: # allows manual triggering
schedule:
- cron: '0 0 1 * *' # Run monthly
push:
paths:
- 'flake.nix'
jobs:
lockfile:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Nix
uses: cachix/install-nix-action@v27
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Update flake.lock
uses: DeterminateSystems/update-flake-lock@v21

2
.gitignore vendored
View File

@@ -48,3 +48,5 @@ packagecache
# Nix
result
result-*
.ccls-cache

View File

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

View File

@@ -34,7 +34,7 @@ RUN apt update && \
libudev-dev \
libupower-glib-dev \
libwayland-dev \
libwireplumber-0.4-dev \
libwireplumber-0.5-dev \
libxkbcommon-dev \
libxkbregistry-dev \
locales \

View File

@@ -29,6 +29,6 @@ RUN dnf install -y @c-development \
'pkgconfig(wayland-client)' \
'pkgconfig(wayland-cursor)' \
'pkgconfig(wayland-protocols)' \
'pkgconfig(wireplumber-0.4)' \
'pkgconfig(wireplumber-0.5)' \
'pkgconfig(xkbregistry)' && \
dnf clean all -y

View File

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

View File

@@ -3,11 +3,11 @@
default: build
build:
meson build
meson setup build
ninja -C build
build-debug:
meson build --buildtype=debug
meson setup build --buildtype=debug
ninja -C build
install: build

View File

@@ -8,6 +8,7 @@
- Sway (Workspaces, Binding mode, Focused window name)
- River (Mapping mode, Tags, Focused window name)
- Hyprland (Window Icons, Workspaces, Focused window name)
- Niri (Workspaces, Focused window name, Language)
- DWL (Tags, Focused window name) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
- Tray [#21](https://github.com/Alexays/Waybar/issues/21)
- Local time
@@ -48,7 +49,7 @@ An Ubuntu PPA with more recent versions is available
```bash
$ git clone https://github.com/Alexays/Waybar
$ cd Waybar
$ meson build
$ meson setup build
$ ninja -C build
$ ./build/waybar
# If you want to install it

6
flake.lock generated
View File

@@ -18,11 +18,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1711163522,
"narHash": "sha256-YN/Ciidm+A0fmJPWlHBGvVkcarYWSC+s3NTPk/P+q3c=",
"lastModified": 1724819573,
"narHash": "sha256-GnR7/ibgIH1vhoy8cYdmXE6iyZqKqFxQSVkFgosBh6w=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "44d0940ea560dee511026a53f0e2e2cde489b4d4",
"rev": "71e91c409d1e654808b2621f28a327acfdad8dc2",
"type": "github"
},
"original": {

View File

@@ -16,7 +16,12 @@
"x86_64-linux"
"aarch64-linux"
]
(system: func (import nixpkgs { inherit system; }));
(system: func (import nixpkgs {
inherit system;
overlays = with self.overlays; [
waybar
];
}));
mkDate = longDate: (lib.concatStringsSep "-" [
(builtins.substring 0 4 longDate)
@@ -46,22 +51,25 @@
};
});
overlays.default = final: prev: {
waybar = final.callPackage ./nix/default.nix {
# take the first "version: '...'" from meson.build
version =
(builtins.head (builtins.split "'"
(builtins.elemAt
(builtins.split " version: '" (builtins.readFile ./meson.build))
2)))
+ "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
overlays = {
default = self.overlays.waybar;
waybar = final: prev: {
waybar = final.callPackage ./nix/default.nix {
waybar = prev.waybar;
# take the first "version: '...'" from meson.build
version =
(builtins.head (builtins.split "'"
(builtins.elemAt
(builtins.split " version: '" (builtins.readFile ./meson.build))
2)))
+ "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
};
};
};
packages = genSystems (pkgs:
let packages = self.overlays.default pkgs pkgs;
in packages // {
default = packages.waybar;
});
packages = genSystems (pkgs: {
default = self.packages.${pkgs.stdenv.hostPlatform.system}.waybar;
inherit (pkgs) waybar;
});
};
}

View File

@@ -27,6 +27,10 @@ class ALabel : public AModule {
bool handleToggle(GdkEventButton *const &e) override;
virtual std::string getState(uint8_t value, bool lesser = false);
std::map<std::string, GtkMenuItem *> submenus_;
std::map<std::string, std::string> menuActionsMap_;
static void handleGtkMenuEvent(GtkMenuItem *menuitem, gpointer data);
};
} // namespace waybar

View File

@@ -2,6 +2,7 @@
#include <glibmm/dispatcher.h>
#include <glibmm/markup.h>
#include <gtkmm.h>
#include <gtkmm/eventbox.h>
#include <json/json.h>
@@ -13,9 +14,9 @@ class AModule : public IModule {
public:
static constexpr const char *MODULE_CLASS = "module";
virtual ~AModule();
~AModule() override;
auto update() -> void override;
virtual auto refresh(int) -> void{};
virtual auto refresh(int shouldRefresh) -> void {};
operator Gtk::Widget &() override;
auto doAction(const std::string &name) -> void override;
@@ -31,21 +32,25 @@ class AModule : public IModule {
enum SCROLL_DIR { NONE, UP, DOWN, LEFT, RIGHT };
SCROLL_DIR getScrollDir(GdkEventScroll *e);
bool tooltipEnabled();
bool tooltipEnabled() const;
const std::string name_;
const Json::Value &config_;
Gtk::EventBox event_box_;
virtual void setCursor(Gdk::CursorType const &c);
virtual bool handleToggle(GdkEventButton *const &ev);
virtual bool handleMouseEnter(GdkEventCrossing *const &ev);
virtual bool handleMouseLeave(GdkEventCrossing *const &ev);
virtual bool handleScroll(GdkEventScroll *);
virtual bool handleRelease(GdkEventButton *const &ev);
GObject *menu_;
private:
bool handleUserEvent(GdkEventButton *const &ev);
const bool isTooltip;
bool hasUserEvents_;
std::vector<int> pid_;
gdouble distance_scrolled_y_;
gdouble distance_scrolled_x_;

View File

@@ -9,6 +9,7 @@
#include <json/json.h>
#include <memory>
#include <optional>
#include <vector>
#include "AModule.hpp"
@@ -41,7 +42,7 @@ struct bar_margins {
};
struct bar_mode {
bar_layer layer;
std::optional<bar_layer> layer;
bool exclusive;
bool passthrough;
bool visible;
@@ -53,7 +54,7 @@ class BarIpcClient;
}
#endif // HAVE_SWAY
class Bar {
class Bar : public sigc::trackable {
public:
using bar_mode_map = std::map<std::string, struct bar_mode>;
static const bar_mode_map PRESET_MODES;
@@ -65,7 +66,7 @@ class Bar {
~Bar();
void setMode(const std::string &mode);
void setVisible(bool visible);
void setVisible(bool value);
void toggle();
void handleSignal(int);

View File

@@ -20,6 +20,9 @@ class Config {
static std::optional<std::string> findConfigPath(
const std::vector<std::string> &names, const std::vector<std::string> &dirs = CONFIG_DIRS);
static std::optional<std::string> tryExpandPath(const std::string &base,
const std::string &filename);
Config() = default;
void load(const std::string &config);

View File

@@ -11,15 +11,13 @@ namespace waybar {
class Group : public AModule {
public:
Group(const std::string&, const std::string&, const Json::Value&, bool);
virtual ~Group() = default;
Group(const std::string &, const std::string &, const Json::Value &, bool);
~Group() override = default;
auto update() -> void override;
operator Gtk::Widget&() override;
operator Gtk::Widget &() override;
virtual Gtk::Box& getBox();
void addWidget(Gtk::Widget& widget);
bool handleMouseHover(GdkEventCrossing* const& e);
virtual Gtk::Box &getBox();
void addWidget(Gtk::Widget &widget);
protected:
Gtk::Box box;
@@ -27,9 +25,13 @@ class Group : public AModule {
Gtk::Revealer revealer;
bool is_first_widget = true;
bool is_drawer = false;
bool click_to_reveal = false;
std::string add_class_to_drawer_children;
void addHoverHandlerTo(Gtk::Widget& widget);
bool handleMouseEnter(GdkEventCrossing *const &ev) override;
bool handleMouseLeave(GdkEventCrossing *const &ev) override;
bool handleToggle(GdkEventButton *const &ev) override;
void show_group();
void hide_group();
};
} // namespace waybar

View File

@@ -49,6 +49,9 @@ class Bluetooth : public ALabel {
auto update() -> void override;
private:
static auto onObjectAdded(GDBusObjectManager*, GDBusObject*, gpointer) -> void;
static auto onObjectRemoved(GDBusObjectManager*, GDBusObject*, gpointer) -> void;
static auto onInterfaceAddedOrRemoved(GDBusObjectManager*, GDBusObject*, GDBusInterface*,
gpointer) -> void;
static auto onInterfaceProxyPropertiesChanged(GDBusObjectManagerClient*, GDBusObjectProxy*,

View File

@@ -21,10 +21,12 @@ class Clock final : public ALabel {
auto doAction(const std::string&) -> void override;
private:
const std::locale locale_;
const std::locale m_locale_;
// tooltip
const std::string tlpFmt_;
std::string tlpText_{""}; // tooltip text to print
const std::string m_tlpFmt_;
std::string m_tlpText_{""}; // tooltip text to print
const Glib::RefPtr<Gtk::Label> m_tooltip_; // tooltip as a separate Gtk::Label
bool query_tlp_cb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
// Calendar
const bool cldInTooltip_; // calendar in tooltip
/*
@@ -49,8 +51,8 @@ class Clock final : public ALabel {
day cldBaseDay_{0}; // calendar Cached day. Is used when today is changing(midnight)
std::string cldText_{""}; // calendar text to print
CldMode cldMode_{CldMode::MONTH};
auto get_calendar(const year_month_day& today, const year_month_day& ymd, const time_zone* tz)
-> const std::string;
auto get_calendar(const year_month_day& today, const year_month_day& ymd,
const time_zone* tz) -> const std::string;
// get local time zone
auto local_zone() -> const time_zone*;

View File

@@ -35,6 +35,7 @@ class Custom : public ALabel {
std::string id_;
std::string alt_;
std::string tooltip_;
const bool tooltip_format_enabled_;
std::vector<std::string> class_;
int percentage_;
FILE* fp_;

View File

@@ -14,7 +14,7 @@ namespace waybar::modules::dwl {
class Window : public AAppIconLabel, public sigc::trackable {
public:
Window(const std::string &, const waybar::Bar &, const Json::Value &);
virtual ~Window() = default;
~Window();
void handle_layout(const uint32_t layout);
void handle_title(const char *title);

View File

@@ -1,5 +1,6 @@
#pragma once
#include <filesystem>
#include <list>
#include <memory>
#include <mutex>
@@ -25,6 +26,10 @@ class IPC {
static std::string getSocket1Reply(const std::string& rq);
Json::Value getSocket1JsonReply(const std::string& rq);
static std::filesystem::path getSocketFolder(const char* instanceSig);
protected:
static std::filesystem::path socketFolder_;
private:
void startIPC();

View File

@@ -0,0 +1,61 @@
#pragma once
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <json/value.h>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <regex>
#include <string>
#include <variant>
#include <vector>
#include "AModule.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
#include "util/enum.hpp"
#include "util/regex_collection.hpp"
using WindowAddress = std::string;
namespace waybar::modules::hyprland {
class Workspaces;
class WindowCreationPayload {
public:
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
std::string window_repr);
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
std::string window_class, std::string window_title);
WindowCreationPayload(Json::Value const& client_data);
int incrementTimeSpentUncreated();
bool isEmpty(Workspaces& workspace_manager);
bool reprIsReady() const { return std::holds_alternative<Repr>(m_window); }
std::string repr(Workspaces& workspace_manager);
std::string getWorkspaceName() const { return m_workspaceName; }
WindowAddress getAddress() const { return m_windowAddress; }
void moveToWorksace(std::string& new_workspace_name);
private:
void clearAddr();
void clearWorkspaceName();
using Repr = std::string;
using ClassAndTitle = std::pair<std::string, std::string>;
std::variant<Repr, ClassAndTitle> m_window;
WindowAddress m_windowAddress;
std::string m_workspaceName;
int m_timeSpentUncreated = 0;
};
} // namespace waybar::modules::hyprland

View File

@@ -0,0 +1,88 @@
#pragma once
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <json/value.h>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <regex>
#include <string>
#include <variant>
#include <vector>
#include "AModule.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
#include "modules/hyprland/windowcreationpayload.hpp"
#include "util/enum.hpp"
#include "util/regex_collection.hpp"
using WindowAddress = std::string;
namespace waybar::modules::hyprland {
class Workspaces;
class Workspace {
public:
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
const Json::Value& clients_data = Json::Value::nullRef);
std::string& selectIcon(std::map<std::string, std::string>& icons_map);
Gtk::Button& button() { return m_button; };
int id() const { return m_id; };
std::string name() const { return m_name; };
std::string output() const { return m_output; };
bool isActive() const { return m_isActive; };
bool isSpecial() const { return m_isSpecial; };
bool isPersistent() const { return m_isPersistentRule || m_isPersistentConfig; };
bool isPersistentConfig() const { return m_isPersistentConfig; };
bool isPersistentRule() const { return m_isPersistentRule; };
bool isVisible() const { return m_isVisible; };
bool isEmpty() const { return m_windows == 0; };
bool isUrgent() const { return m_isUrgent; };
bool handleClicked(GdkEventButton* bt) const;
void setActive(bool value = true) { m_isActive = value; };
void setPersistentRule(bool value = true) { m_isPersistentRule = value; };
void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; };
void setUrgent(bool value = true) { m_isUrgent = value; };
void setVisible(bool value = true) { m_isVisible = value; };
void setWindows(uint value) { m_windows = value; };
void setName(std::string const& value) { m_name = value; };
void setOutput(std::string const& value) { m_output = value; };
bool containsWindow(WindowAddress const& addr) const { return m_windowMap.contains(addr); }
void insertWindow(WindowCreationPayload create_window_paylod);
std::string removeWindow(WindowAddress const& addr);
void initializeWindowMap(const Json::Value& clients_data);
bool onWindowOpened(WindowCreationPayload const& create_window_paylod);
std::optional<std::string> closeWindow(WindowAddress const& addr);
void update(const std::string& format, const std::string& icon);
private:
Workspaces& m_workspaceManager;
int m_id;
std::string m_name;
std::string m_output;
uint m_windows;
bool m_isActive = false;
bool m_isSpecial = false;
bool m_isPersistentRule = false; // represents the persistent state in hyprland
bool m_isPersistentConfig = false; // represents the persistent state in the Waybar config
bool m_isUrgent = false;
bool m_isVisible = false;
std::map<WindowAddress, std::string> m_windowMap;
Gtk::Button m_button;
Gtk::Box m_content;
Gtk::Label m_label;
};
} // namespace waybar::modules::hyprland

View File

@@ -4,19 +4,18 @@
#include <gtkmm/label.h>
#include <json/value.h>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <regex>
#include <string>
#include <variant>
#include <vector>
#include "AModule.hpp"
#include "bar.hpp"
#include "modules/hyprland/backend.hpp"
#include "modules/hyprland/windowcreationpayload.hpp"
#include "modules/hyprland/workspace.hpp"
#include "util/enum.hpp"
#include "util/regex_collection.hpp"
@@ -26,97 +25,6 @@ namespace waybar::modules::hyprland {
class Workspaces;
class WindowCreationPayload {
public:
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
std::string window_repr);
WindowCreationPayload(std::string workspace_name, WindowAddress window_address,
std::string window_class, std::string window_title);
WindowCreationPayload(Json::Value const& client_data);
int incrementTimeSpentUncreated();
bool isEmpty(Workspaces& workspace_manager);
bool reprIsReady() const { return std::holds_alternative<Repr>(m_window); }
std::string repr(Workspaces& workspace_manager);
std::string getWorkspaceName() const { return m_workspaceName; }
WindowAddress getAddress() const { return m_windowAddress; }
void moveToWorksace(std::string& new_workspace_name);
private:
void clearAddr();
void clearWorkspaceName();
using Repr = std::string;
using ClassAndTitle = std::pair<std::string, std::string>;
std::variant<Repr, ClassAndTitle> m_window;
WindowAddress m_windowAddress;
std::string m_workspaceName;
int m_timeSpentUncreated = 0;
};
class Workspace {
public:
explicit Workspace(const Json::Value& workspace_data, Workspaces& workspace_manager,
const Json::Value& clients_data = Json::Value::nullRef);
std::string& selectIcon(std::map<std::string, std::string>& icons_map);
Gtk::Button& button() { return m_button; };
int id() const { return m_id; };
std::string name() const { return m_name; };
std::string output() const { return m_output; };
bool isActive() const { return m_isActive; };
bool isSpecial() const { return m_isSpecial; };
bool isPersistent() const { return m_isPersistentRule || m_isPersistentConfig; };
bool isPersistentConfig() const { return m_isPersistentConfig; };
bool isPersistentRule() const { return m_isPersistentRule; };
bool isVisible() const { return m_isVisible; };
bool isEmpty() const { return m_windows == 0; };
bool isUrgent() const { return m_isUrgent; };
bool handleClicked(GdkEventButton* bt) const;
void setActive(bool value = true) { m_isActive = value; };
void setPersistentRule(bool value = true) { m_isPersistentRule = value; };
void setPersistentConfig(bool value = true) { m_isPersistentConfig = value; };
void setUrgent(bool value = true) { m_isUrgent = value; };
void setVisible(bool value = true) { m_isVisible = value; };
void setWindows(uint value) { m_windows = value; };
void setName(std::string const& value) { m_name = value; };
void setOutput(std::string const& value) { m_output = value; };
bool containsWindow(WindowAddress const& addr) const { return m_windowMap.contains(addr); }
void insertWindow(WindowCreationPayload create_window_paylod);
std::string removeWindow(WindowAddress const& addr);
void initializeWindowMap(const Json::Value& clients_data);
bool onWindowOpened(WindowCreationPayload const& create_window_paylod);
std::optional<std::string> closeWindow(WindowAddress const& addr);
void update(const std::string& format, const std::string& icon);
private:
Workspaces& m_workspaceManager;
int m_id;
std::string m_name;
std::string m_output;
uint m_windows;
bool m_isActive = false;
bool m_isSpecial = false;
bool m_isPersistentRule = false; // represents the persistent state in hyprland
bool m_isPersistentConfig = false; // represents the persistent state in the Waybar config
bool m_isUrgent = false;
bool m_isVisible = false;
std::map<WindowAddress, std::string> m_windowMap;
Gtk::Button m_button;
Gtk::Box m_content;
Gtk::Label m_label;
};
class Workspaces : public AModule, public EventHandler {
public:
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
@@ -127,6 +35,7 @@ class Workspaces : public AModule, public EventHandler {
auto allOutputs() const -> bool { return m_allOutputs; }
auto showSpecial() const -> bool { return m_showSpecial; }
auto activeOnly() const -> bool { return m_activeOnly; }
auto specialVisibleOnly() const -> bool { return m_specialVisibleOnly; }
auto moveToMonitor() const -> bool { return m_moveToMonitor; }
auto getBarOutput() const -> std::string { return m_bar.output->name; }
@@ -141,11 +50,24 @@ class Workspaces : public AModule, public EventHandler {
void onEvent(const std::string& e) override;
void updateWindowCount();
void sortWorkspaces();
void createWorkspace(Json::Value const& workspaceData,
Json::Value const& clientsData = Json::Value::nullRef);
void createWorkspace(Json::Value const& workspace_data,
Json::Value const& clients_data = Json::Value::nullRef);
static Json::Value createMonitorWorkspaceData(std::string const& name,
std::string const& monitor);
void removeWorkspace(std::string const& name);
void setUrgentWorkspace(std::string const& windowaddress);
// Config
void parseConfig(const Json::Value& config);
auto populateIconsMap(const Json::Value& formatIcons) -> void;
static auto populateBoolConfig(const Json::Value& config, const std::string& key,
bool& member) -> void;
auto populateSortByConfig(const Json::Value& config) -> void;
auto populateIgnoreWorkspacesConfig(const Json::Value& config) -> void;
auto populateFormatWindowSeparatorConfig(const Json::Value& config) -> void;
auto populateWindowRewriteConfig(const Json::Value& config) -> void;
void registerIpc();
// workspace events
@@ -171,7 +93,13 @@ class Workspaces : public AModule, public EventHandler {
int windowRewritePriorityFunction(std::string const& window_rule);
// Update methods
void doUpdate();
void removeWorkspacesToRemove();
void createWorkspacesToCreate();
static std::vector<std::string> getVisibleWorkspaces();
void updateWorkspaceStates();
bool updateWindowsToCreate();
void extendOrphans(int workspaceId, Json::Value const& clientsJson);
void registerOrphanWindow(WindowCreationPayload create_window_payload);
@@ -184,6 +112,7 @@ class Workspaces : public AModule, public EventHandler {
bool m_allOutputs = false;
bool m_showSpecial = false;
bool m_activeOnly = false;
bool m_specialVisibleOnly = false;
bool m_moveToMonitor = false;
Json::Value m_persistentWorkspaceConfig;

View File

@@ -40,6 +40,7 @@ class Network : public ALabel {
void parseEssid(struct nlattr**);
void parseSignal(struct nlattr**);
void parseFreq(struct nlattr**);
void parseBssid(struct nlattr**);
bool associatedOrJoined(struct nlattr**);
bool checkInterface(std::string name);
auto getInfo() -> void;
@@ -69,6 +70,7 @@ class Network : public ALabel {
std::string state_;
std::string essid_;
std::string bssid_;
bool carrier_;
std::string ifname_;
std::string ipaddr_;

View File

@@ -0,0 +1,52 @@
#pragma once
#include <list>
#include <mutex>
#include <string>
#include <utility>
#include "util/json.hpp"
namespace waybar::modules::niri {
class EventHandler {
public:
virtual void onEvent(const Json::Value& ev) = 0;
virtual ~EventHandler() = default;
};
class IPC {
public:
IPC() { startIPC(); }
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
void unregisterForIPC(EventHandler* handler);
static Json::Value send(const Json::Value& request);
// The data members are only safe to access while dataMutex_ is locked.
std::lock_guard<std::mutex> lockData() { return std::lock_guard(dataMutex_); }
const std::vector<Json::Value>& workspaces() const { return workspaces_; }
const std::vector<Json::Value>& windows() const { return windows_; }
const std::vector<std::string>& keyboardLayoutNames() const { return keyboardLayoutNames_; }
unsigned keyboardLayoutCurrent() const { return keyboardLayoutCurrent_; }
private:
void startIPC();
static int connectToSocket();
void parseIPC(const std::string&);
std::mutex dataMutex_;
std::vector<Json::Value> workspaces_;
std::vector<Json::Value> windows_;
std::vector<std::string> keyboardLayoutNames_;
unsigned keyboardLayoutCurrent_;
util::JsonParser parser_;
std::mutex callbackMutex_;
std::list<std::pair<std::string, EventHandler*>> callbacks_;
};
inline std::unique_ptr<IPC> gIPC;
}; // namespace waybar::modules::niri

View File

@@ -0,0 +1,38 @@
#pragma once
#include <string>
#include "ALabel.hpp"
#include "bar.hpp"
#include "modules/niri/backend.hpp"
namespace waybar::modules::niri {
class Language : public ALabel, public EventHandler {
public:
Language(const std::string &, const Bar &, const Json::Value &);
~Language() override;
void update() override;
private:
void updateFromIPC();
void onEvent(const Json::Value &ev) override;
void doUpdate();
struct Layout {
std::string full_name;
std::string short_name;
std::string variant;
std::string short_description;
};
static Layout getLayout(const std::string &fullName);
std::mutex mutex_;
const Bar &bar_;
std::vector<Layout> layouts_;
unsigned current_idx_;
};
} // namespace waybar::modules::niri

View File

@@ -0,0 +1,28 @@
#pragma once
#include <gtkmm/button.h>
#include <json/value.h>
#include "AAppIconLabel.hpp"
#include "bar.hpp"
#include "modules/niri/backend.hpp"
namespace waybar::modules::niri {
class Window : public AAppIconLabel, public EventHandler {
public:
Window(const std::string &, const Bar &, const Json::Value &);
~Window() override;
void update() override;
private:
void onEvent(const Json::Value &ev) override;
void doUpdate();
void setClass(const std::string &className, bool enable);
const Bar &bar_;
std::string oldAppId_;
};
} // namespace waybar::modules::niri

View File

@@ -0,0 +1,30 @@
#pragma once
#include <gtkmm/button.h>
#include <json/value.h>
#include "AModule.hpp"
#include "bar.hpp"
#include "modules/niri/backend.hpp"
namespace waybar::modules::niri {
class Workspaces : public AModule, public EventHandler {
public:
Workspaces(const std::string &, const Bar &, const Json::Value &);
~Workspaces() override;
void update() override;
private:
void onEvent(const Json::Value &ev) override;
void doUpdate();
Gtk::Button &addButton(const Json::Value &ws);
std::string getIcon(const std::string &value, const Json::Value &ws);
const Bar &bar_;
Gtk::Box box_;
// Map from niri workspace id to button.
std::unordered_map<uint64_t, Gtk::Button> buttons_;
};
} // namespace waybar::modules::niri

View File

@@ -10,6 +10,8 @@ namespace waybar::modules {
struct Profile {
std::string name;
std::string driver;
Profile(std::string n, std::string d) : name(std::move(n)), driver(std::move(d)) {}
};
class PowerProfilesDaemon : public ALabel {

View File

@@ -1,10 +1,7 @@
#pragma once
#include <iostream>
#include <map>
#include <string>
#include "ALabel.hpp"
#include "gtkmm/box.h"
#include "modules/privacy/privacy_item.hpp"
#include "util/pipewire/pipewire_backend.hpp"

View File

@@ -2,9 +2,6 @@
#include <json/value.h>
#include <iostream>
#include <map>
#include <mutex>
#include <string>
#include "gtkmm/box.h"

View File

@@ -76,6 +76,8 @@ class Item : public sigc::trackable {
void makeMenu();
bool handleClick(GdkEventButton* const& /*ev*/);
bool handleScroll(GdkEventScroll* const&);
bool handleMouseEnter(GdkEventCrossing* const&);
bool handleMouseLeave(GdkEventCrossing* const&);
// smooth scrolling threshold
gdouble scroll_threshold_ = 0;

View File

@@ -19,7 +19,7 @@ namespace waybar::modules::sway {
class Workspaces : public AModule, public sigc::trackable {
public:
Workspaces(const std::string&, const waybar::Bar&, const Json::Value&);
virtual ~Workspaces() = default;
~Workspaces() override = default;
auto update() -> void override;
private:
@@ -38,10 +38,10 @@ class Workspaces : public AModule, public sigc::trackable {
Gtk::Button& addButton(const Json::Value&);
void onButtonReady(const Json::Value&, Gtk::Button&);
std::string getIcon(const std::string&, const Json::Value&);
const std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const;
std::string getCycleWorkspace(std::vector<Json::Value>::iterator, bool prev) const;
uint16_t getWorkspaceIndex(const std::string& name) const;
std::string trimWorkspaceName(std::string);
bool handleScroll(GdkEventScroll*) override;
static std::string trimWorkspaceName(std::string);
bool handleScroll(GdkEventScroll* /*unused*/) override;
const Bar& bar_;
std::vector<Json::Value> workspaces_;

View File

@@ -0,0 +1,94 @@
#pragma once
#include <giomm/dbusconnection.h>
#include <gtkmm/icontheme.h>
#include <libupower-glib/upower.h>
#include <unordered_map>
#include "AIconLabel.hpp"
namespace waybar::modules {
class UPower final : public AIconLabel {
public:
UPower(const std::string &, const Json::Value &);
virtual ~UPower();
auto update() -> void override;
private:
const std::string NO_BATTERY{"battery-missing-symbolic"};
// Config
bool showIcon_{true};
bool hideIfEmpty_{true};
int iconSize_{20};
int tooltip_spacing_{4};
int tooltip_padding_{4};
Gtk::Box contentBox_; // tooltip box
std::string tooltipFormat_;
// UPower device info
struct upDevice_output {
UpDevice *upDevice{NULL};
double percentage{0.0};
double temperature{0.0};
guint64 time_full{0u};
guint64 time_empty{0u};
gchar *icon_name{(char *)'\0'};
bool upDeviceValid{false};
UpDeviceState state;
UpDeviceKind kind;
char *nativePath{(char *)'\0'};
char *model{(char *)'\0'};
};
// Technical variables
std::string nativePath_;
std::string model_;
std::string lastStatus_;
Glib::ustring label_markup_;
std::mutex mutex_;
Glib::RefPtr<Gtk::IconTheme> gtkTheme_;
bool sleeping_;
// Technical functions
void addDevice(UpDevice *);
void removeDevice(const gchar *);
void removeDevices();
void resetDevices();
void setDisplayDevice();
const Glib::ustring getText(const upDevice_output &upDevice_, const std::string &format);
bool queryTooltipCb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &);
// DBUS variables
guint watcherID_;
Glib::RefPtr<Gio::DBus::Connection> conn_;
guint subscrID_{0u};
// UPower variables
UpClient *upClient_;
upDevice_output upDevice_; // Device to display
typedef std::unordered_map<std::string, upDevice_output> Devices;
Devices devices_;
bool upRunning_{true};
// DBus callbacks
void getConn_cb(Glib::RefPtr<Gio::AsyncResult> &result);
void onAppear(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &,
const Glib::ustring &);
void onVanished(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &);
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name, const Glib::ustring &object_path,
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters);
// UPower callbacks
static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data);
static void deviceRemoved_cb(UpClient *client, const gchar *objectPath, gpointer data);
static void deviceNotify_cb(UpDevice *device, GParamSpec *pspec, gpointer user_data);
// UPower secondary functions
void getUpDeviceInfo(upDevice_output &upDevice_);
};
} // namespace waybar::modules

View File

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

View File

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

View File

@@ -24,6 +24,10 @@
namespace waybar::modules::wlr {
struct widget_geometry {
int x, y, w, h;
};
class Taskbar;
class Task {
@@ -42,6 +46,7 @@ class Task {
};
// made public so TaskBar can reorder based on configuration.
Gtk::Button button;
struct widget_geometry minimize_hint;
private:
static uint32_t global_id;
@@ -82,6 +87,8 @@ class Task {
private:
std::string repr() const;
std::string state_string(bool = false) const;
void set_minimize_hint();
void on_button_size_allocated(Gtk::Allocation &alloc);
void set_app_info_from_app_id_list(const std::string &app_id_list);
bool image_load_icon(Gtk::Image &image, const Glib::RefPtr<Gtk::IconTheme> &icon_theme,
Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size);

View File

@@ -56,10 +56,10 @@ class BacklightBackend {
void set_previous_best_device(const BacklightDevice *device);
void set_brightness(std::string preferred_device, ChangeType change_type, double step);
void set_brightness(const std::string &preferred_device, ChangeType change_type, double step);
void set_scaled_brightness(std::string preferred_device, int brightness);
int get_scaled_brightness(std::string preferred_device);
void set_scaled_brightness(const std::string &preferred_device, int brightness);
int get_scaled_brightness(const std::string &preferred_device);
bool is_login_proxy_initialized() const { return static_cast<bool>(login_proxy_); }
@@ -70,7 +70,7 @@ class BacklightBackend {
std::mutex udev_thread_mutex_;
private:
void set_brightness_internal(std::string device_name, int brightness, int max_brightness);
void set_brightness_internal(const std::string &device_name, int brightness, int max_brightness);
std::function<void()> on_updated_cb_;
std::chrono::milliseconds polling_interval_;

View File

@@ -622,8 +622,8 @@ inline auto convertInto(std::string const &source, bool &target) -> ParserResult
}
#ifdef CLARA_CONFIG_OPTIONAL_TYPE
template <typename T>
inline auto convertInto(std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T> &target)
-> ParserResult {
inline auto convertInto(std::string const &source,
CLARA_CONFIG_OPTIONAL_TYPE<T> &target) -> ParserResult {
T temp;
auto result = convertInto(source, temp);
if (result) target = std::move(temp);
@@ -751,8 +751,8 @@ class ParserBase {
public:
virtual ~ParserBase() = default;
virtual auto validate() const -> Result { return Result::ok(); }
virtual auto parse(std::string const &exeName, TokenStream const &tokens) const
-> InternalParseResult = 0;
virtual auto parse(std::string const &exeName,
TokenStream const &tokens) const -> InternalParseResult = 0;
virtual auto cardinality() const -> size_t { return 1; }
auto parse(Args const &args) const -> InternalParseResult {
@@ -1098,8 +1098,8 @@ struct Parser : ParserBase {
using ParserBase::parse;
auto parse(std::string const &exeName, TokenStream const &tokens) const
-> InternalParseResult override {
auto parse(std::string const &exeName,
TokenStream const &tokens) const -> InternalParseResult override {
struct ParserInfo {
ParserBase const *parser = nullptr;
size_t count = 0;

View File

@@ -64,7 +64,7 @@ struct fmt::formatter<date::zoned_time<Duration, TimeZonePtr>> {
}
template <typename FormatContext>
auto format(const date::zoned_time<Duration, TimeZonePtr>& ztime, FormatContext& ctx) {
auto format(const date::zoned_time<Duration, TimeZonePtr>& ztime, FormatContext& ctx) const {
if (ctx.locale()) {
const auto loc = ctx.locale().template get<std::locale>();
return fmt::format_to(ctx.out(), "{}", date::format(loc, fmt::to_string(specs), ztime));

View File

@@ -6,7 +6,7 @@
class pow_format {
public:
pow_format(long long val, std::string&& unit, bool binary = false)
: val_(val), unit_(unit), binary_(binary){};
: val_(val), unit_(unit), binary_(binary) {};
long long val_;
std::string unit_;
@@ -45,7 +45,7 @@ struct formatter<pow_format> {
}
template <class FormatContext>
auto format(const pow_format& s, FormatContext& ctx) -> decltype(ctx.out()) {
auto format(const pow_format& s, FormatContext& ctx) const -> decltype(ctx.out()) {
const char* units[] = {"", "k", "M", "G", "T", "P", nullptr};
auto base = s.binary_ ? 1024ull : 1000ll;
@@ -92,7 +92,7 @@ struct formatter<pow_format> {
template <>
struct formatter<Glib::ustring> : formatter<std::string> {
template <typename FormatContext>
auto format(const Glib::ustring& value, FormatContext& ctx) {
auto format(const Glib::ustring& value, FormatContext& ctx) const {
return formatter<std::string>::format(static_cast<std::string>(value), ctx);
}
};

View File

@@ -2,6 +2,8 @@
#include <pipewire/pipewire.h>
#include <unordered_map>
#include "util/backend_common.hpp"
#include "util/pipewire/privacy_node_info.hpp"

View File

@@ -5,6 +5,7 @@
#include <functional>
#include <regex>
#include <string>
#include <utility>
namespace waybar::util {
@@ -17,7 +18,7 @@ struct Rule {
// See https://en.cppreference.com/w/cpp/compiler_support/20 "Parenthesized initialization of
// aggregates"
Rule(std::regex rule, std::string repr, int priority)
: rule(rule), repr(repr), priority(priority) {}
: rule(std::move(rule)), repr(std::move(repr)), priority(priority) {}
};
int default_priority_function(std::string& key);
@@ -36,16 +37,17 @@ class RegexCollection {
std::map<std::string, std::string> regex_cache;
std::string default_repr;
std::string& find_match(std::string& value, bool& matched_any);
std::string find_match(std::string& value, bool& matched_any);
public:
RegexCollection() = default;
RegexCollection(const Json::Value& map, std::string default_repr = "",
std::function<int(std::string&)> priority_function = default_priority_function);
RegexCollection(
const Json::Value& map, std::string default_repr = "",
const std::function<int(std::string&)>& priority_function = default_priority_function);
~RegexCollection() = default;
std::string& get(std::string& value, bool& matched_any);
std::string& get(std::string& value);
};
} // namespace waybar::util
} // namespace waybar::util

View File

@@ -81,6 +81,19 @@ The *backlight* module displays the current backlight level.
default: 1.0 ++
The speed at which to change the brightness when scrolling.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# EXAMPLE:
```

View File

@@ -109,6 +109,19 @@ The *battery* module displays the current capacity and state (eg. charging) of y
default: false ++
Option to enable battery compatibility if not detected.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{capacity}*: Capacity in percentage

View File

@@ -129,6 +129,19 @@ Addressed by *bluetooth*
typeof: string ++
This format is used to define how each connected device should be displayed within the *device_enumerate* format replacement in the tooltip menu.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{status}*: Status of the bluetooth device.

View File

@@ -120,6 +120,18 @@ libcava lives in:
:[ string
:[ /dev/stdout
:[ It's impossible to set it. Waybar sets it to = /dev/stdout for internal needs
|[ *menu*
:[ string
:[
:[ Action that popups the menu.
|[ *menu-file*
:[ string
:[
:[ Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
|[ *menu-actions*
:[ array
:[
:[ The actions corresponding to the buttons of the menu.
Configuration can be provided as:
- The only cava configuration file which is provided through *cava_config*. The rest configuration can be skipped

View File

@@ -84,6 +84,18 @@ $XDG_CONFIG_HOME/waybar/config ++
:[ string
:[ same as format
:[ Tooltip on hover
|[ *menu*
:[ string
:[
:[ Action that popups the menu.
|[ *menu-file*
:[ string
:[
:[ Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
|[ *menu-actions*
:[ array
:[
:[ The actions corresponding to the buttons of the menu.
View all valid format options in *strftime(3)* or have a look https://en.cppreference.com/w/cpp/chrono/duration/formatter

View File

@@ -21,6 +21,10 @@ Addressed by *custom/<name>*
The path to a script, which determines if the script in *exec* should be executed. ++
*exec* will be executed if the exit code of *exec-if* equals 0.
*hide-empty-text*: ++
typeof: bool ++
Disables the module when output is empty, but format might contain additional static content.
*exec-on-event*: ++
typeof: bool ++
default: true ++
@@ -121,6 +125,19 @@ Addressed by *custom/<name>*
default: false ++
Option to enable escaping of script output.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# RETURN-TYPE
When *return-type* is set to *json*, Waybar expects the *exec*-script to output its data in JSON format.

View File

@@ -93,6 +93,19 @@ Addressed by *disk*
typeof: string ++
Use with specific_free, specific_used, and specific_total to force calculation to always be in a certain unit. Accepts kB, kiB, MB, Mib, GB, GiB, TB, TiB.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{percentage_used}*: Percentage of disk in use.

View File

@@ -25,6 +25,19 @@ Addressed by *hyprland/language*
typeof: string ++
Specifies which keyboard to use from hyprctl devices output. Using the option that begins with "at-translated-set..." is recommended.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS

View File

@@ -80,6 +80,19 @@ Addressed by *hyprland/submap*
default: Default ++
Option to set the submap name to display when not in an active submap.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# EXAMPLES

View File

@@ -26,6 +26,7 @@ Addressed by *hyprland/workspaces*
Regex rules to map window class to an icon or preferred method of representation for a workspace's window.
Keys are the rules, while the values are the methods of representation. Values may use the placeholders {class} and {title} to use the window's original class and/or title respectively.
Rules may specify `class<...>`, `title<...>`, or both in order to fine-tune the matching.
You may assign an empty value to a rule to have it ignored from generating any representation in workspaces.
*window-rewrite-default*:
typeof: string ++
@@ -42,6 +43,11 @@ Addressed by *hyprland/workspaces*
default: false ++
If set to true, special workspaces will be shown.
*special-visible-only*: ++
typeof: bool ++
default: false ++
If this and show-special are to true, special workspaces will be shown only if visible.
*all-outputs*: ++
typeof: bool ++
default: false ++
@@ -142,6 +148,7 @@ Additional to workspace name matching, the following *format-icons* can be set.
"class<firefox> title<.*github.*>": "", // Windows whose class is "firefox" and title contains "github". Note that "class" always comes first.
"foot": "", // Windows that contain "foot" in either class or title. For optimization reasons, it will only match against a title if at least one other window explicitly matches against a title.
"code": "󰨞",
"title<.* - (.*) - VSCodium>": "codium $1" // captures part of the window title and formats it into output
}
}
```

View File

@@ -89,6 +89,19 @@ screensaver, also known as "presentation mode".
typeof: string ++
This format is used when the inhibit is deactivated.
*menu*: ++
typeof: string ++
Action that popups the menu. Cannot be "on-click".
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{status}*: status (*activated* or *deactivated*)

View File

@@ -76,6 +76,19 @@ See *systemd-inhibit*(1) for more information.
default: true ++
Option to disable tooltip on hover.
*menu*: ++
typeof: string ++
Action that popups the menu. Cannot be "on-click".
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{status}*: status (*activated* or *deactivated*)

View File

@@ -85,6 +85,19 @@ Addressed by *jack*
typeof: string ++
Command to execute when the module is updated.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{load}*: The current CPU load estimated by JACK.

View File

@@ -84,6 +84,19 @@ Addressed by *memory*
default: true ++
Option to disable tooltip on hover.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{percentage}*: Percentage of memory in use.

153
man/waybar-menu.5.scd Normal file
View File

@@ -0,0 +1,153 @@
waybar-menu(5)
# NAME
waybar - menu property
# OVERVIEW
Some modules support a 'menu', which allows to have a popup menu whan a defined
click is done over the module.
# PROPERTIES
A module that implements a 'menu' needs 3 properties defined in its config :
*menu*: ++
typeof: string ++
Action that popups the menu. The possibles actions are :
[- *Option*
:- *Description*
|[ *on-click*
:< When you left-click on the module
|[ *on-click-release*
:< When you release left button on the module
|[ *on-double-click*
:< When you double left click on the module
|[ *on-triple-click*
:< When you triple left click on the module
|[ *on-click-middle*
:< When you middle click on the module using mousewheel
|[ *on-click-middle-release*
:< When you release mousewheel button on the module
|[ *on-double-click-middle*
:< When you double middle click on the module
|[ *on-triple-click-middle*
:< When you triple middle click on the module
|[ *on-click-right*
:< When you right click on the module using
|[ *on-click-right-release*
:< When you release right button on the module
|[ *on-double-click-right*
:< When you double right click on the module
|[ *on-triple-click-right*
:< When you triple middle click on the module
|[ *on-click-backward*
:< When you click on the module using mouse backward button
|[ *on-click-backward-release*
:< When you release mouse backward button on the module
|[ *on-double-click-backward*
:< When you double click on the module using mouse backward button
|[ *on-triple-click-backward*
:< When you triple click on the module using mouse backawrd button
|[ *on-click-forward*
:< When you click on the module using mouse forward button
|[ *on-click-forward-release*
:< When you release mouse forward button on the module
|[ *on-double-click-forward*
:< When you double click on the module using mouse forward button
|[ *on-triple-click-forward*
:< When you triple click on the module using mouse forward button
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*.
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu. The identifiers of
each actions needs to exists as an id in the 'menu-file' for it to be linked
properly.
# MENU-FILE
The menu-file is an `.xml` file representing a GtkBuilder. Documentation for it
can be found here : https://docs.gtk.org/gtk4/class.Builder.html
Here, it needs to have an element of type GtkMenu with id "menu". Eeach actions
in *menu-actions* are linked to elements in the *menu-file* file by the id of
the elements.
# EXAMPLE
Module config :
```
"custom/power": {
"format" : "⏻ ",
"tooltip": false,
"menu": "on-click",
"menu-file": "~/.config/waybar/power_menu.xml",
"menu-actions": {
"shutdown": "shutdown",
"reboot": "reboot",
"suspend": "systemctl suspend",
"hibernate": "systemctl hibernate",
},
},
```
~/.config/waybar/power_menu.xml :
```
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkMenu" id="menu">
<child>
<object class="GtkMenuItem" id="suspend">
<property name="label">Suspend</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="hibernat">
<property name="label">Hibernate</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="shutdown">
<property name="label">Shutdown</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="delimiter1"/>
</child>
<child>
<object class="GtkMenuItem" id="reboot">
<property name="label">Reboot</property>
</object>
</child>
</object>
</interface>
```
# STYLING MENUS
- *menu*
Style for the menu
- *menuitem*
Style for items in the menu
# EXAMPLE:
```
menu {
border-radius: 15px;
background: #161320;
color: #B5E8E0;
}
menuitem {
border-radius: 15px;
}
```

View File

@@ -162,6 +162,19 @@ Addressed by *mpd*
default: {} ++
Icon to show depending on the "single" option (*{ "on": "...", "off": "..." }*)
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
## WHEN PLAYING/PAUSED

View File

@@ -142,11 +142,11 @@ The *mpris* module displays currently playing media via libplayerctl.
*player-icons*: ++
typeof: map[string]string ++
Allows setting _{player-icon}_ based on player-name property.
Allows setting _{player_icon}_ based on player-name property.
*status-icons*: ++
typeof: map[string]string ++
Allows setting _{status-icon}_ based on player status (playing, paused, stopped).
Allows setting _{status_icon}_ based on player status (playing, paused, stopped).
# FORMAT REPLACEMENTS

View File

@@ -129,6 +129,19 @@ Addressed by *network*
typeof: string ++
This format is used when the displayed interface is disabled.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{ifname}*: Name of the network interface.
@@ -143,6 +156,8 @@ Addressed by *network*
*{essid}*: Name (SSID) of the wireless network.
*{bssid}*: MAC address (BSSID) of the wireless access point.
*{signalStrength}*: Signal strength of the wireless network.
*{signaldBm}*: Signal strength of the wireless network in dBm.

View File

@@ -0,0 +1,58 @@
waybar-niri-language(5)
# NAME
waybar - niri language module
# DESCRIPTION
The *language* module displays the currently selected language in niri.
# CONFIGURATION
Addressed by *niri/language*
*format*: ++
typeof: string ++
default: {} ++
The format, how information should be displayed.
*format-<lang>* ++
typeof: string++
Provide an alternative name to display per language where <lang> is the language of your choosing. Can be passed multiple times with multiple languages as shown by the example below.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{short}*: Short name of layout (e.g. "us"). Equals to {}.
*{shortDescription}*: Short description of layout (e.g. "en").
*{long}*: Long name of layout (e.g. "English (Dvorak)").
*{variant}*: Variant of layout (e.g. "dvorak").
# EXAMPLES
```
"niri/language": {
"format": "Lang: {long}"
"format-en": "AMERICA, HELL YEAH!"
"format-tr": "As bayrakları"
}
```
# STYLE
- *#language*

View File

@@ -0,0 +1,81 @@
waybar-niri-window(5)
# NAME
waybar - niri window module
# DESCRIPTION
The *window* module displays the title of the currently focused window in niri.
# CONFIGURATION
Addressed by *niri/window*
*format*: ++
typeof: string ++
default: {title} ++
The format, how information should be displayed. On {} the current window title is displayed.
*rewrite*: ++
typeof: object ++
Rules to rewrite window title. See *rewrite rules*.
*separate-outputs*: ++
typeof: bool ++
Show the active window of the monitor the bar belongs to, instead of the focused window.
*icon*: ++
typeof: bool ++
default: false ++
Option to hide the application icon.
*icon-size*: ++
typeof: integer ++
default: 24 ++
Option to change the size of the application icon.
# FORMAT REPLACEMENTS
See the output of "niri msg windows" for examples
*{title}*: The current title of the focused window.
*{app_id}*: The current app ID of the focused window.
# REWRITE RULES
*rewrite* is an object where keys are regular expressions and values are
rewrite rules if the expression matches. Rules may contain references to
captures of the expression.
Regular expression and replacement follow ECMA-script rules.
If no expression matches, the title is left unchanged.
Invalid expressions (e.g., mismatched parentheses) are skipped.
# EXAMPLES
```
"niri/window": {
"format": "{}",
"rewrite": {
"(.*) - Mozilla Firefox": "🌎 $1",
"(.*) - zsh": "> [$1]"
}
}
```
# STYLE
- *#window*
- *window#waybar.empty #window* When no windows are on the workspace
The following classes are applied to the entire Waybar rather than just the
window widget:
- *window#waybar.empty* When no windows are in the workspace
- *window#waybar.solo* When only one window is on the workspace
- *window#waybar.<app-id>* Where *app-id* is the app ID of the only window on
the workspace

View File

@@ -0,0 +1,97 @@
waybar-niri-workspaces(5)
# NAME
waybar - niri workspaces module
# DESCRIPTION
The *workspaces* module displays the currently used workspaces in niri.
# CONFIGURATION
Addressed by *niri/workspaces*
*all-outputs*: ++
typeof: bool ++
default: false ++
If set to false, workspaces will only be shown on the output they are on. If set to true all workspaces will be shown on every output.
*format*: ++
typeof: string ++
default: {value} ++
The format, how information should be displayed.
*format-icons*: ++
typeof: array ++
Based on the workspace name, index and state, the corresponding icon gets selected. See *icons*.
*disable-click*: ++
typeof: bool ++
default: false ++
If set to false, you can click to change workspace. If set to true this behaviour is disabled.
*disable-markup*: ++
typeof: bool ++
default: false ++
If set to true, button label will escape pango markup.
*current-only*: ++
typeof: bool ++
default: false ++
If set to true, only the active or focused workspace will be shown.
*on-update*: ++
typeof: string ++
Command to execute when the module is updated.
# FORMAT REPLACEMENTS
*{value}*: Name of the workspace, or index for unnamed workspaces,
as defined by niri.
*{name}*: Name of the workspace for named workspaces.
*{icon}*: Icon, as defined in *format-icons*.
*{index}*: Index of the workspace on its output.
*{output}*: Output where the workspace is located.
# ICONS
Additional to workspace name matching, the following *format-icons* can be set.
- *default*: Will be shown, when no string matches are found.
- *focused*: Will be shown, when workspace is focused.
- *active*: Will be shown, when workspace is active on its output.
# EXAMPLES
```
"niri/workspaces": {
"format": "{icon}",
"format-icons": {
// Named workspaces
// (you need to configure them in niri)
"browser": "",
"discord": "",
"chat": "<b></b>",
// Icons by state
"active": "",
"default": ""
}
}
```
# Style
- *#workspaces button*
- *#workspaces button.focused*: The single focused workspace.
- *#workspaces button.active*: The workspace is active (visible) on its output.
- *#workspaces button.empty*: The workspace is empty.
- *#workspaces button.current_output*: The workspace is from the same output as
the bar that it is displayed on.
- *#workspaces button#niri-workspace-<name>*: Workspaces named this, or index
for unnamed workspaces.

View File

@@ -31,7 +31,7 @@ The volume can be controlled by dragging the slider across the bar or clicking o
```
"modules-right": [
"pulseaudio-slider",
"pulseaudio/slider",
],
"pulseaudio/slider": {
"min": 0,

View File

@@ -113,6 +113,19 @@ Additionally, you can control the volume by scrolling *up* or *down* while the c
typeof: array ++
Sinks in this list will not be shown as active sink by Waybar. Entries should be the sink's description field.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{desc}*: Pulseaudio port's description, for bluetooth it'll be the device name.
@@ -142,6 +155,8 @@ If they are found in the current PulseAudio port name, the corresponding icons w
- *hifi*
- *phone*
Additionally, suffixing a device name or port with *-muted* will cause the icon
to be selected when the corresponding audio device is muted. This applies to *default* as well.
# EXAMPLES
@@ -152,10 +167,12 @@ If they are found in the current PulseAudio port name, the corresponding icons w
"format-muted": "",
"format-icons": {
"alsa_output.pci-0000_00_1f.3.analog-stereo": "",
"alsa_output.pci-0000_00_1f.3.analog-stereo-muted": "",
"headphones": "",
"handsfree": "",
"headset": "",
"phone": "",
"phone-muted": "",
"portable": "",
"car": "",
"default": ["", ""]

View File

@@ -51,6 +51,19 @@ Addressed by *river/layout*
typeof: string ++
Command to execute when you right-click on the module.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# EXAMPLE
```

View File

@@ -65,6 +65,19 @@ Addressed by *river/mode*
typeof: double ++
Threshold to be used when scrolling.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# EXAMPLES
```

View File

@@ -49,6 +49,19 @@ Addressed by *river/window*
typeof: string ++
Command to execute when you right-click on the module.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# EXAMPLES
```

View File

@@ -74,6 +74,19 @@ cursor is over the module, and clicking on the module toggles mute.
typeof: double ++
Threshold to be used when scrolling.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{volume}*: Volume in percentage.

View File

@@ -39,6 +39,40 @@ You can apply special styling to any module for when the cursor hovers it.
}
```
## Setting cursor style
Most, if not all, module types support setting the `cursor` option. This is
configured in your `config.jsonc`. If set to `false`, when hovering the module a
"pointer"(as commonly known from web CSS styling `cursor: pointer`) style cursor
will not be shown. Default behavior is to indicate an interaction event is
available.
There are more cursor types to choose from by setting the `cursor` option to
a number, see Gdk3 official docs for all possible cursor types:
https://docs.gtk.org/gdk3/enum.CursorType.html.
However, note that not all cursor options listed may be available on
your system. If you attempt to use a cursor which is not available, the
application will crash.
Example of disabling pointer(`Gdk::Hand2`) cursor type on a custom module:
```
"custom/my-custom-module": {
...
"cursor": false,
}
```
Example of setting cursor type to `Gdk::Boat`(according to
https://docs.gtk.org/gdk3/enum.CursorType.html#boat):
```
"custom/my-custom-module": {
...
"cursor": 8,
}
```
# SEE ALSO
- *waybar(5)*

View File

@@ -32,6 +32,19 @@ Addressed by *sway/language*
default: true ++
Option to disable tooltip on hover.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{short}*: Short name of layout (e.g. "us"). Equals to {}.

View File

@@ -70,6 +70,19 @@ Addressed by *sway/mode*
default: true ++
Option to disable tooltip on hover.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# EXAMPLES
```

View File

@@ -36,6 +36,19 @@ Addressed by *sway/scratchpad*
default: {app}: {title} ++
The format, how information in the tooltip should be displayed.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{icon}*: Icon, as defined in *format-icons*.

View File

@@ -87,6 +87,7 @@ warp-on-scroll: ++
Regex rules to map window class to an icon or preferred method of representation for a workspace's window.
Keys are the rules, while the values are the methods of representation.
Rules may specify `class<...>`, `title<...>`, or both in order to fine-tune the matching.
You may assign an empty value to a rule to have it ignored from generating any representation in workspaces.
*window-rewrite-default*:
typeof: string ++
@@ -171,6 +172,7 @@ n.b.: the list of outputs can be obtained from command line using *swaymsg -t ge
"window-rewrite": {
"class<firefox>": "",
"class<kitty>": "k",
"title<.* - (.*) - VSCodium>": "codium $1" // captures part of the window title and formats it into output
}
}
```

View File

@@ -36,6 +36,19 @@ Addressed by *systemd-failed-units*
default: *true* ++
Option to hide this module when there is no failing units.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{nr_failed_system}*: Number of failed units from systemwide (PID=1) systemd.

View File

@@ -25,6 +25,7 @@ Addressed by *temperature*
*hwmon-path-abs*: ++
typeof: string ++
The path of the hwmon-directory of the device, e.g. */sys/devices/pci0000:00/0000:00:18.3/hwmon*. (Note that the subdirectory *hwmon/hwmon#*, where *#* is a number is not part of the path!) Has to be used together with *input-filename*.
This can also be an array of strings, for which, it just works like *hwmon-path*.
*input-filename*: ++
typeof: string ++
@@ -110,6 +111,19 @@ Addressed by *temperature*
default: true ++
Option to disable tooltip on hover.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{temperatureC}*: Temperature in Celsius.

View File

@@ -17,6 +17,12 @@ compatible devices in the tooltip.
The battery to monitor. Refer to the https://upower.freedesktop.org/docs/UpDevice.html#UpDevice--native-path ++
Can be obtained using `upower --dump`
*model*: ++
typeof: string ++
default: ++
The battery to monitor, based on the model. (this option is ignored if *native-path* is given). ++
Can be obtained using `upower --dump`
*icon-size*: ++
typeof: integer ++
default: 20 ++
@@ -62,6 +68,19 @@ compatible devices in the tooltip.
default: true ++
Option to disable battery icon.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{percentage}*: The battery capacity in percentage

View File

@@ -87,6 +87,19 @@ The *wireplumber* module displays the current volume reported by WirePlumber.
default: 100 ++
The maximum volume that can be set, in percentage.
*menu*: ++
typeof: string ++
Action that popups the menu.
*menu-file*: ++
typeof: string ++
Location of the menu descriptor file. There need to be an element of type
GtkMenu with id *menu*
*menu-actions*: ++
typeof: array ++
The actions corresponding to the buttons of the menu.
# FORMAT REPLACEMENTS
*{volume}*: Volume in percentage.

View File

@@ -278,6 +278,11 @@ A group may hide all but one element, showing them only on mouse hover. In order
default: "hidden" ++
Defines the CSS class to be applied to the hidden elements.
*click-to-reveal*: ++
typeof: bool ++
default: false ++
Whether left click should reveal the content rather than mouse over. Note that grouped modules may still process their own on-click events.
*transition-left-to-right*: ++
typeof: bool ++
default: true ++
@@ -318,6 +323,9 @@ A group may hide all but one element, showing them only on mouse hover. In order
- *waybar-hyprland-submap(5)*
- *waybar-hyprland-window(5)*
- *waybar-hyprland-workspaces(5)*
- *waybar-niri-language(5)*
- *waybar-niri-window(5)*
- *waybar-niri-workspaces(5)*
- *waybar-idle-inhibitor(5)*
- *waybar-image(5)*
- *waybar-inhibitor(5)*

View File

@@ -1,6 +1,6 @@
project(
'waybar', 'cpp', 'c',
version: '0.10.1',
version: '0.11.0',
license: 'MIT',
meson_version: '>= 0.59.0',
default_options : [
@@ -69,7 +69,7 @@ is_openbsd = host_machine.system() == 'openbsd'
thread_dep = dependency('threads')
fmt = dependency('fmt', version : ['>=8.1.1'], fallback : ['fmt', 'fmt_dep'])
spdlog = dependency('spdlog', version : ['>=1.10.0'], fallback : ['spdlog', 'spdlog_dep'], default_options : ['external_fmt=enabled'])
spdlog = dependency('spdlog', version : ['>=1.10.0'], fallback : ['spdlog', 'spdlog_dep'], default_options : ['external_fmt=enabled', 'std_format=disabled', 'tests=disabled'])
wayland_client = dependency('wayland-client')
wayland_cursor = dependency('wayland-cursor')
wayland_protos = dependency('wayland-protocols')
@@ -192,6 +192,7 @@ man_files = files(
'man/waybar-idle-inhibitor.5.scd',
'man/waybar-image.5.scd',
'man/waybar-states.5.scd',
'man/waybar-menu.5.scd',
'man/waybar-temperature.5.scd',
)
@@ -305,7 +306,9 @@ if true
'src/modules/hyprland/language.cpp',
'src/modules/hyprland/submap.cpp',
'src/modules/hyprland/window.cpp',
'src/modules/hyprland/workspace.cpp',
'src/modules/hyprland/workspaces.cpp',
'src/modules/hyprland/windowcreationpayload.cpp',
)
man_files += files(
'man/waybar-hyprland-language.5.scd',
@@ -315,6 +318,21 @@ if true
)
endif
if get_option('niri')
add_project_arguments('-DHAVE_NIRI', language: 'cpp')
src_files += files(
'src/modules/niri/backend.cpp',
'src/modules/niri/language.cpp',
'src/modules/niri/window.cpp',
'src/modules/niri/workspaces.cpp',
)
man_files += files(
'man/waybar-niri-language.5.scd',
'man/waybar-niri-window.5.scd',
'man/waybar-niri-workspaces.5.scd',
)
endif
if libnl.found() and libnlgen.found()
add_project_arguments('-DHAVE_LIBNL', language: 'cpp')
src_files += files('src/modules/network.cpp')
@@ -335,10 +353,7 @@ endif
if (upower_glib.found() and not get_option('logind').disabled())
add_project_arguments('-DHAVE_UPOWER', language: 'cpp')
src_files += files(
'src/modules/upower/upower.cpp',
'src/modules/upower/upower_tooltip.cpp',
)
src_files += files('src/modules/upower.cpp')
man_files += files('man/waybar-upower.5.scd')
endif
@@ -467,7 +482,7 @@ if get_option('experimental')
endif
cava = dependency('cava',
version : '>=0.10.1',
version : '>=0.10.2',
required: get_option('cava'),
fallback : ['cava', 'cava_dep'],
not_found_message: 'cava is not found. Building waybar without cava')

View File

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

View File

@@ -5,12 +5,12 @@
}:
let
libcava = rec {
version = "0.10.1";
version = "0.10.2";
src = pkgs.fetchFromGitHub {
owner = "LukashonakV";
repo = "cava";
rev = version;
hash = "sha256-iIYKvpOWafPJB5XhDOSIW9Mb4I3A4pcgIIPQdQYEqUw=";
hash = "sha256-jU7RQV2txruu/nUUl0TzjK4nai7G38J1rcTjO7UXumY=";
};
};
in

View File

@@ -30,7 +30,8 @@
"battery",
"battery#bat2",
"clock",
"tray"
"tray",
"custom/power"
],
// Modules configuration
// "sway/workspaces": {
@@ -198,5 +199,17 @@
"escape": true,
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
},
"custom/power": {
"format" : "⏻ ",
"tooltip": false,
"menu": "on-click",
"menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder
"menu-actions": {
"shutdown": "shutdown",
"reboot": "reboot",
"suspend": "systemctl suspend",
"hibernate": "systemctl hibernate"
}
}
}

View File

@@ -113,6 +113,7 @@ class PlayerManager:
player_name = player.props.player_name
artist = player.get_artist()
title = player.get_title()
title = title.replace("&", "&amp;")
track_info = ""
if player_name == "spotify" and "mpris:trackid" in metadata.keys() and ":ad:" in player.props.metadata["mpris:trackid"]:
@@ -136,6 +137,10 @@ class PlayerManager:
def on_player_appeared(self, _, player):
logger.info(f"Player has appeared: {player.name}")
if player.name in self.excluded_player:
logger.debug(
"New player appeared, but it's in exclude player list, skipping")
return
if player is not None and (self.selected_player is None or player.name == self.selected_player):
self.init_player(player)
else:

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkMenu" id="menu">
<child>
<object class="GtkMenuItem" id="suspend">
<property name="label">Suspend</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="hibernate">
<property name="label">Hibernate</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="shutdown">
<property name="label">Shutdown</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="delimiter1"/>
</child>
<child>
<object class="GtkMenuItem" id="reboot">
<property name="label">Reboot</property>
</object>
</child>
</object>
</interface>

View File

@@ -96,14 +96,14 @@ std::optional<Glib::ustring> getIconName(const std::string& app_identifier,
return app_identifier;
}
const auto app_identifier_desktop = app_identifier + "-desktop";
auto app_identifier_desktop = app_identifier + "-desktop";
if (DefaultGtkIconThemeWrapper::has_icon(app_identifier_desktop)) {
return app_identifier_desktop;
}
const auto first_space = app_identifier.find_first_of(' ');
auto first_space = app_identifier.find_first_of(' ');
if (first_space != std::string::npos) {
const auto first_word = toLowerCase(app_identifier.substr(0, first_space));
auto first_word = toLowerCase(app_identifier.substr(0, first_space));
if (DefaultGtkIconThemeWrapper::has_icon(first_word)) {
return first_word;
}
@@ -111,7 +111,7 @@ std::optional<Glib::ustring> getIconName(const std::string& app_identifier,
const auto first_dash = app_identifier.find_first_of('-');
if (first_dash != std::string::npos) {
const auto first_word = toLowerCase(app_identifier.substr(0, first_dash));
auto first_word = toLowerCase(app_identifier.substr(0, first_dash));
if (DefaultGtkIconThemeWrapper::has_icon(first_word)) {
return first_word;
}

View File

@@ -2,14 +2,20 @@
#include <fmt/format.h>
#include <fstream>
#include <iostream>
#include <util/command.hpp>
#include "config.hpp"
namespace waybar {
ALabel::ALabel(const Json::Value& config, const std::string& name, const std::string& id,
const std::string& format, uint16_t interval, bool ellipsize, bool enable_click,
bool enable_scroll)
: AModule(config, name, id, config["format-alt"].isString() || enable_click, enable_scroll),
: AModule(config, name, id,
config["format-alt"].isString() || config["menu"].isString() || enable_click,
enable_scroll),
format_(config_["format"].isString() ? config_["format"].asString() : format),
interval_(config_["interval"] == "once"
? std::chrono::seconds::max()
@@ -51,6 +57,55 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
}
}
// If a GTKMenu is requested in the config
if (config_["menu"].isString()) {
// Create the GTKMenu widget
try {
// Check that the file exists
std::string menuFile = config_["menu-file"].asString();
// there might be "~" or "$HOME" in original path, try to expand it.
auto result = Config::tryExpandPath(menuFile, "");
if (!result.has_value()) {
throw std::runtime_error("Failed to expand file: " + menuFile);
}
menuFile = result.value();
// Read the menu descriptor file
std::ifstream file(menuFile);
if (!file.is_open()) {
throw std::runtime_error("Failed to open file: " + menuFile);
}
std::stringstream fileContent;
fileContent << file.rdbuf();
GtkBuilder* builder = gtk_builder_new();
// Make the GtkBuilder and check for errors in his parsing
if (gtk_builder_add_from_string(builder, fileContent.str().c_str(), -1, nullptr) == 0U) {
throw std::runtime_error("Error found in the file " + menuFile);
}
menu_ = gtk_builder_get_object(builder, "menu");
if (menu_ == nullptr) {
throw std::runtime_error("Failed to get 'menu' object from GtkBuilder");
}
submenus_ = std::map<std::string, GtkMenuItem*>();
menuActionsMap_ = std::map<std::string, std::string>();
// Linking actions to the GTKMenu based on
for (Json::Value::const_iterator it = config_["menu-actions"].begin();
it != config_["menu-actions"].end(); ++it) {
std::string key = it.key().asString();
submenus_[key] = GTK_MENU_ITEM(gtk_builder_get_object(builder, key.c_str()));
menuActionsMap_[key] = it->asString();
g_signal_connect(submenus_[key], "activate", G_CALLBACK(handleGtkMenuEvent),
(gpointer)menuActionsMap_[key].c_str());
}
} catch (std::runtime_error& e) {
spdlog::warn("Error while creating the menu : {}. Menu popup not activated.", e.what());
}
}
if (config_["justify"].isString()) {
auto justify_str = config_["justify"].asString();
if (justify_str == "left") {
@@ -76,7 +131,7 @@ std::string ALabel::getIcon(uint16_t percentage, const std::string& alt, uint16_
}
if (format_icons.isArray()) {
auto size = format_icons.size();
if (size) {
if (size != 0U) {
auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1);
format_icons = format_icons[idx];
}
@@ -102,7 +157,7 @@ std::string ALabel::getIcon(uint16_t percentage, const std::vector<std::string>&
}
if (format_icons.isArray()) {
auto size = format_icons.size();
if (size) {
if (size != 0U) {
auto idx = std::clamp(percentage / ((max == 0 ? 100 : max) / size), 0U, size - 1);
format_icons = format_icons[idx];
}
@@ -125,6 +180,10 @@ bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
return AModule::handleToggle(e);
}
void ALabel::handleGtkMenuEvent(GtkMenuItem* /*menuitem*/, gpointer data) {
waybar::util::command::res res = waybar::util::command::exec((char*)data, "GtkMenu");
}
std::string ALabel::getState(uint8_t value, bool lesser) {
if (!config_["states"].isObject()) {
return "";

View File

@@ -1,28 +1,33 @@
#include "AModule.hpp"
#include <fmt/format.h>
#include <spdlog/spdlog.h>
#include <util/command.hpp>
#include "gdk/gdk.h"
#include "gdkmm/cursor.h"
namespace waybar {
AModule::AModule(const Json::Value& config, const std::string& name, const std::string& id,
bool enable_click, bool enable_scroll)
: name_(std::move(name)),
config_(std::move(config)),
: name_(name),
config_(config),
isTooltip{config_["tooltip"].isBool() ? config_["tooltip"].asBool() : true},
distance_scrolled_y_(0.0),
distance_scrolled_x_(0.0) {
// Configure module action Map
const Json::Value actions{config_["actions"]};
for (Json::Value::const_iterator it = actions.begin(); it != actions.end(); ++it) {
if (it.key().isString() && it->isString())
if (eventActionMap_.count(it.key().asString()) == 0) {
if (!eventActionMap_.contains(it.key().asString())) {
eventActionMap_.insert({it.key().asString(), it->asString()});
enable_click = true;
enable_scroll = true;
} else
spdlog::warn("Dublicate action is ignored: {0}", it.key().asString());
spdlog::warn("Duplicate action is ignored: {0}", it.key().asString());
else
spdlog::warn("Wrong actions section configuration. See config by index: {}", it.index());
}
@@ -31,17 +36,20 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
event_box_.signal_leave_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseLeave));
// configure events' user commands
// hasUserEvent is true if any element from eventMap_ is satisfying the condition in the lambda
bool hasUserEvent =
// hasUserEvents is true if any element from eventMap_ is satisfying the condition in the lambda
bool hasUserEvents =
std::find_if(eventMap_.cbegin(), eventMap_.cend(), [&config](const auto& eventEntry) {
// True if there is any non-release type event
return eventEntry.first.second != GdkEventType::GDK_BUTTON_RELEASE &&
config[eventEntry.second].isString();
}) != eventMap_.cend();
if (enable_click || hasUserEvent) {
if (enable_click || hasUserEvents) {
hasUserEvents_ = true;
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &AModule::handleToggle));
} else {
hasUserEvents_ = false;
}
bool hasReleaseEvent =
@@ -60,6 +68,17 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &AModule::handleScroll));
}
// Respect user configuration of cursor
if (config_.isMember("cursor")) {
if (config_["cursor"].isBool() && config_["cursor"].asBool()) {
setCursor(Gdk::HAND2);
} else if (config_["cursor"].isInt()) {
setCursor(Gdk::CursorType(config_["cursor"].asInt()));
} else {
spdlog::warn("unknown cursor option configured on module {}", name_);
}
}
}
AModule::~AModule() {
@@ -86,18 +105,47 @@ auto AModule::doAction(const std::string& name) -> void {
}
}
void AModule::setCursor(Gdk::CursorType const& c) {
auto gdk_window = event_box_.get_window();
if (gdk_window) {
auto cursor = Gdk::Cursor::create(c);
gdk_window->set_cursor(cursor);
} else {
// window may not be accessible yet, in this case,
// schedule another call for setting the cursor in 1 sec
Glib::signal_timeout().connect_seconds(
[this, c]() {
setCursor(c);
return false;
},
1);
}
}
bool AModule::handleMouseEnter(GdkEventCrossing* const& e) {
if (auto* module = event_box_.get_child(); module != nullptr) {
module->set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
}
return true;
// Default behavior indicating event availability
if (hasUserEvents_ && !config_.isMember("cursor")) {
setCursor(Gdk::HAND2);
}
return false;
}
bool AModule::handleMouseLeave(GdkEventCrossing* const& e) {
if (auto* module = event_box_.get_child(); module != nullptr) {
module->unset_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
}
return true;
// Default behavior indicating event availability
if (hasUserEvents_ && !config_.isMember("cursor")) {
setCursor(Gdk::ARROW);
}
return false;
}
bool AModule::handleToggle(GdkEventButton* const& e) { return handleUserEvent(e); }
@@ -108,12 +156,23 @@ bool AModule::handleUserEvent(GdkEventButton* const& e) {
std::string format{};
const std::map<std::pair<uint, GdkEventType>, std::string>::const_iterator& rec{
eventMap_.find(std::pair(e->button, e->type))};
if (rec != eventMap_.cend()) {
// First call module actions
this->AModule::doAction(rec->second);
format = rec->second;
}
// Check that a menu has been configured
if (config_["menu"].isString()) {
// Check if the event is the one specified for the "menu" option
if (rec->second == config_["menu"].asString()) {
// Popup the menu
gtk_widget_show_all(GTK_WIDGET(menu_));
gtk_menu_popup_at_pointer(GTK_MENU(menu_), reinterpret_cast<GdkEvent*>(e));
}
}
// Second call user scripts
if (!format.empty()) {
if (config_[format].isString())
@@ -135,7 +194,7 @@ AModule::SCROLL_DIR AModule::getScrollDir(GdkEventScroll* e) {
// ignore reverse-scrolling if event comes from a mouse wheel
GdkDevice* device = gdk_event_get_source_device((GdkEvent*)e);
if (device != NULL && gdk_device_get_source(device) == GDK_SOURCE_MOUSE) {
if (device != nullptr && gdk_device_get_source(device) == GDK_SOURCE_MOUSE) {
reverse = reverse_mouse;
}
@@ -213,7 +272,7 @@ bool AModule::handleScroll(GdkEventScroll* e) {
return true;
}
bool AModule::tooltipEnabled() { return isTooltip; }
bool AModule::tooltipEnabled() const { return isTooltip; }
AModule::operator Gtk::Widget&() { return event_box_; }

View File

@@ -43,7 +43,7 @@ const Bar::bar_mode_map Bar::PRESET_MODES = { //
.visible = true}},
{"invisible",
{//
.layer = bar_layer::BOTTOM,
.layer = std::nullopt,
.exclusive = false,
.passthrough = true,
.visible = false}},
@@ -59,7 +59,7 @@ const std::string Bar::MODE_INVISIBLE = "invisible";
const std::string_view DEFAULT_BAR_ID = "bar-0";
/* Deserializer for enum bar_layer */
void from_json(const Json::Value& j, bar_layer& l) {
void from_json(const Json::Value& j, std::optional<bar_layer>& l) {
if (j == "bottom") {
l = bar_layer::BOTTOM;
} else if (j == "top") {
@@ -72,16 +72,16 @@ void from_json(const Json::Value& j, bar_layer& l) {
/* Deserializer for struct bar_mode */
void from_json(const Json::Value& j, bar_mode& m) {
if (j.isObject()) {
if (auto v = j["layer"]; v.isString()) {
if (const auto& v = j["layer"]; v.isString()) {
from_json(v, m.layer);
}
if (auto v = j["exclusive"]; v.isBool()) {
if (const auto& v = j["exclusive"]; v.isBool()) {
m.exclusive = v.asBool();
}
if (auto v = j["passthrough"]; v.isBool()) {
if (const auto& v = j["passthrough"]; v.isBool()) {
m.passthrough = v.asBool();
}
if (auto v = j["visible"]; v.isBool()) {
if (const auto& v = j["visible"]; v.isBool()) {
m.visible = v.asBool();
}
}
@@ -118,7 +118,7 @@ Glib::ustring to_string(Gtk::PositionType pos) {
* Assumes that all the values in the object are deserializable to the same type.
*/
template <typename Key, typename Value,
typename = std::enable_if_t<std::is_convertible<std::string, Key>::value>>
typename = std::enable_if_t<std::is_convertible_v<std::string, Key>>>
void from_json(const Json::Value& j, std::map<Key, Value>& m) {
if (j.isObject()) {
for (auto it = j.begin(); it != j.end(); ++it) {
@@ -316,13 +316,13 @@ void waybar::Bar::setMode(const std::string& mode) {
void waybar::Bar::setMode(const struct bar_mode& mode) {
auto* gtk_window = window.gobj();
auto layer = GTK_LAYER_SHELL_LAYER_BOTTOM;
if (mode.layer == bar_layer::TOP) {
layer = GTK_LAYER_SHELL_LAYER_TOP;
if (mode.layer == bar_layer::BOTTOM) {
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_BOTTOM);
} else if (mode.layer == bar_layer::TOP) {
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_TOP);
} else if (mode.layer == bar_layer::OVERLAY) {
layer = GTK_LAYER_SHELL_LAYER_OVERLAY;
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_OVERLAY);
}
gtk_layer_set_layer(gtk_window, layer);
if (mode.exclusive) {
gtk_layer_auto_exclusive_zone_enable(gtk_window);
@@ -393,11 +393,11 @@ void waybar::Bar::setPosition(Gtk::PositionType position) {
}
}
void waybar::Bar::onMap(GdkEventAny*) {
void waybar::Bar::onMap(GdkEventAny* /*unused*/) {
/*
* Obtain a pointer to the custom layer surface for modules that require it (idle_inhibitor).
*/
auto gdk_window = window.get_window()->gobj();
auto* gdk_window = window.get_window()->gobj();
surface = gdk_wayland_window_get_wl_surface(gdk_window);
configureGlobalOffset(gdk_window_get_width(gdk_window), gdk_window_get_height(gdk_window));
@@ -473,7 +473,7 @@ void waybar::Bar::handleSignal(int signal) {
void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
waybar::Group* group = nullptr) {
auto module_list = group ? config[pos]["modules"] : config[pos];
auto module_list = group != nullptr ? config[pos]["modules"] : config[pos];
if (module_list.isArray()) {
for (const auto& name : module_list) {
try {
@@ -485,10 +485,10 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
auto id_name = ref.substr(6, hash_pos - 6);
auto class_name = hash_pos != std::string::npos ? ref.substr(hash_pos + 1) : "";
auto vertical = (group ? group->getBox().get_orientation() : box_.get_orientation()) ==
Gtk::ORIENTATION_VERTICAL;
auto vertical = (group != nullptr ? group->getBox().get_orientation()
: box_.get_orientation()) == Gtk::ORIENTATION_VERTICAL;
auto group_module = new waybar::Group(id_name, class_name, config[ref], vertical);
auto* group_module = new waybar::Group(id_name, class_name, config[ref], vertical);
getModules(factory, ref, group_module);
module = group_module;
} else {
@@ -497,7 +497,7 @@ void waybar::Bar::getModules(const Factory& factory, const std::string& pos,
std::shared_ptr<AModule> module_sp(module);
modules_all_.emplace_back(module_sp);
if (group) {
if (group != nullptr) {
group->addWidget(*module);
} else {
if (pos == "modules-left") {

View File

@@ -4,6 +4,7 @@
#include <spdlog/spdlog.h>
#include <iostream>
#include <utility>
#include "gtkmm/icontheme.h"
#include "idle-inhibit-unstable-v1-client-protocol.h"
@@ -11,13 +12,13 @@
#include "util/format.hpp"
waybar::Client *waybar::Client::inst() {
static auto c = new Client();
static auto *c = new Client();
return c;
}
void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version) {
auto client = static_cast<Client *>(data);
auto *client = static_cast<Client *>(data);
if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 &&
version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
client->xdg_output_manager = static_cast<struct zxdg_output_manager_v1 *>(wl_registry_bind(
@@ -42,7 +43,7 @@ void waybar::Client::handleOutput(struct waybar_output &output) {
.description = &handleOutputDescription,
};
// owned by output->monitor; no need to destroy
auto wl_output = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
auto *wl_output = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
output.xdg_output.reset(zxdg_output_manager_v1_get_xdg_output(xdg_output_manager, wl_output));
zxdg_output_v1_add_listener(output.xdg_output.get(), &xdgOutputListener, &output);
}
@@ -61,7 +62,7 @@ std::vector<Json::Value> waybar::Client::getOutputConfigs(struct waybar_output &
}
void waybar::Client::handleOutputDone(void *data, struct zxdg_output_v1 * /*xdg_output*/) {
auto client = waybar::Client::inst();
auto *client = waybar::Client::inst();
try {
auto &output = client->getOutput(data);
/**
@@ -85,24 +86,24 @@ void waybar::Client::handleOutputDone(void *data, struct zxdg_output_v1 * /*xdg_
}
}
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
std::cerr << e.what() << '\n';
}
}
void waybar::Client::handleOutputName(void *data, struct zxdg_output_v1 * /*xdg_output*/,
const char *name) {
auto client = waybar::Client::inst();
auto *client = waybar::Client::inst();
try {
auto &output = client->getOutput(data);
output.name = name;
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
std::cerr << e.what() << '\n';
}
}
void waybar::Client::handleOutputDescription(void *data, struct zxdg_output_v1 * /*xdg_output*/,
const char *description) {
auto client = waybar::Client::inst();
auto *client = waybar::Client::inst();
try {
auto &output = client->getOutput(data);
const char *open_paren = strrchr(description, '(');
@@ -111,18 +112,19 @@ void waybar::Client::handleOutputDescription(void *data, struct zxdg_output_v1 *
size_t identifier_length = open_paren - description;
output.identifier = std::string(description, identifier_length - 1);
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
std::cerr << e.what() << '\n';
}
}
void waybar::Client::handleMonitorAdded(Glib::RefPtr<Gdk::Monitor> monitor) {
auto &output = outputs_.emplace_back();
output.monitor = monitor;
output.monitor = std::move(monitor);
handleOutput(output);
}
void waybar::Client::handleMonitorRemoved(Glib::RefPtr<Gdk::Monitor> monitor) {
spdlog::debug("Output removed: {} {}", monitor->get_manufacturer(), monitor->get_model());
spdlog::debug("Output removed: {} {}", monitor->get_manufacturer().c_str(),
monitor->get_model().c_str());
/* This event can be triggered from wl_display_roundtrip called by GTK or our code.
* Defer destruction of bars for the output to the next iteration of the event loop to avoid
* deleting objects referenced by currently executed code.
@@ -154,15 +156,15 @@ const std::string waybar::Client::getStyle(const std::string &style,
std::vector<std::string> search_files;
switch (appearance.value_or(portal->getAppearance())) {
case waybar::Appearance::LIGHT:
search_files.push_back("style-light.css");
search_files.emplace_back("style-light.css");
break;
case waybar::Appearance::DARK:
search_files.push_back("style-dark.css");
search_files.emplace_back("style-dark.css");
break;
case waybar::Appearance::UNKNOWN:
break;
}
search_files.push_back("style.css");
search_files.emplace_back("style.css");
css_file = Config::findConfigPath(search_files);
} else {
css_file = style;
@@ -196,7 +198,7 @@ void waybar::Client::bindInterfaces() {
wl_registry_add_listener(registry, &registry_listener, this);
wl_display_roundtrip(wl_display);
if (!gtk_layer_is_supported()) {
if (gtk_layer_is_supported() == 0) {
throw std::runtime_error("The Wayland compositor does not support wlr-layer-shell protocol");
}
@@ -233,11 +235,11 @@ int waybar::Client::main(int argc, char *argv[]) {
return 1;
}
if (show_help) {
std::cout << cli << std::endl;
std::cout << cli << '\n';
return 0;
}
if (show_version) {
std::cout << "Waybar v" << VERSION << std::endl;
std::cout << "Waybar v" << VERSION << '\n';
return 0;
}
if (!log_level.empty()) {

View File

@@ -21,10 +21,11 @@ const std::vector<std::string> Config::CONFIG_DIRS = {
const char *Config::CONFIG_PATH_ENV = "WAYBAR_CONFIG_DIR";
std::optional<std::string> tryExpandPath(const std::string base, const std::string filename) {
std::optional<std::string> Config::tryExpandPath(const std::string &base,
const std::string &filename) {
fs::path path;
if (filename != "") {
if (!filename.empty()) {
path = fs::path(base) / fs::path(filename);
} else {
path = fs::path(base);
@@ -129,9 +130,9 @@ bool isValidOutput(const Json::Value &config, const std::string &name,
if (config_output.substr(0, 1) == "!") {
if (config_output.substr(1) == name || config_output.substr(1) == identifier) {
return false;
} else {
continue;
}
continue;
}
if (config_output == name || config_output == identifier) {
return true;
@@ -142,7 +143,9 @@ bool isValidOutput(const Json::Value &config, const std::string &name,
}
}
return false;
} else if (config["output"].isString()) {
}
if (config["output"].isString()) {
auto config_output = config["output"].asString();
if (!config_output.empty()) {
if (config_output.substr(0, 1) == "!") {

View File

@@ -36,6 +36,11 @@
#include "modules/hyprland/window.hpp"
#include "modules/hyprland/workspaces.hpp"
#endif
#ifdef HAVE_NIRI
#include "modules/niri/language.hpp"
#include "modules/niri/window.hpp"
#include "modules/niri/workspaces.hpp"
#endif
#if defined(__FreeBSD__) || defined(__linux__)
#include "modules/battery.hpp"
#endif
@@ -70,7 +75,7 @@
#include "modules/gamemode.hpp"
#endif
#ifdef HAVE_UPOWER
#include "modules/upower/upower.hpp"
#include "modules/upower.hpp"
#endif
#ifdef HAVE_PIPEWIRE
#include "modules/privacy/privacy.hpp"
@@ -130,7 +135,7 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name,
#endif
#ifdef HAVE_UPOWER
if (ref == "upower") {
return new waybar::modules::upower::UPower(id, config_[name]);
return new waybar::modules::UPower(id, config_[name]);
}
#endif
#ifdef HAVE_PIPEWIRE
@@ -205,6 +210,17 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name,
if (ref == "hyprland/workspaces") {
return new waybar::modules::hyprland::Workspaces(id, bar_, config_[name]);
}
#endif
#ifdef HAVE_NIRI
if (ref == "niri/language") {
return new waybar::modules::niri::Language(id, bar_, config_[name]);
}
if (ref == "niri/window") {
return new waybar::modules::niri::Window(id, bar_, config_[name]);
}
if (ref == "niri/workspaces") {
return new waybar::modules::niri::Workspaces(id, bar_, config_[name]);
}
#endif
if (ref == "idle_inhibitor") {
return new waybar::modules::IdleInhibitor(id, bar_, config_[name]);

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