Compare commits
375 Commits
Author | SHA1 | Date |
---|---|---|
Jonas Letzbor | 2df0e7cf9e | |
Alexis Rouillard | f4da203915 | |
Peter Jones | 637b220f82 | |
Alexis Rouillard | 365e77af58 | |
zspher | 1b1442e3ba | |
Alexis Rouillard | 7163752aa0 | |
Jack Wilsdon | e9350cf25f | |
Alexis Rouillard | 1a1a61e917 | |
zjeffer | 532a90259b | |
zjeffer | cf66604f85 | |
Alexis Rouillard | 9332697ec1 | |
Alexis Rouillard | ab735f723c | |
Austin Horstman | c5b5b64dfa | |
Austin Horstman | 381fe83008 | |
Austin Horstman | 8adb0a5644 | |
Alexis Rouillard | 0d518cb5a3 | |
Austin Horstman | 24e8766aaa | |
alttabber | 29e3d8c371 | |
Alexis Rouillard | 57f2a57dac | |
John Titor | b6ca3ea4d9 | |
John Titor | 1a9952d0c0 | |
Alex | a4a4be3381 | |
Alexis Rouillard | b7ce0b05b1 | |
Alexis Rouillard | af87388eb4 | |
Alexis Rouillard | 2aa8008ae2 | |
Alexis Rouillard | d4413f5fa6 | |
Alexis Rouillard | af7945197e | |
Alexis Rouillard | ac2fa9870f | |
Alexis Rouillard | a3ac6cb099 | |
Alexis Rouillard | dc203b8439 | |
Austin Horstman | f5bb086460 | |
Austin Horstman | 9ba9d57c8c | |
Austin Horstman | 82ae474002 | |
Austin Horstman | 56319a4705 | |
Austin Horstman | 07c91c200a | |
Austin Horstman | d73051e980 | |
Austin Horstman | 9fe51af6b0 | |
Austin Horstman | e4353e548a | |
Alexis Rouillard | 63bb338343 | |
Unreal Hoang | d012124c03 | |
Alexis Rouillard | 10664922c9 | |
Viktar Lukashonak | 60a613ae51 | |
Alexis Rouillard | 35a9ca476d | |
yangyingchao | b8e68b0e63 | |
wmlhwl | b61ea62732 | |
Alexis Rouillard | 8ad7c75d79 | |
Viktar Lukashonak | 5a1454ab31 | |
Viktar Lukashonak | b288fdf8c1 | |
Alexis Rouillard | 912d0e83f3 | |
Lasse Luttermann | 3c075bcc53 | |
Lasse Luttermann | ba8a88acfb | |
zjeffer | e27488b48c | |
zjeffer | 1828a94b6c | |
zjeffer | 49afcdf715 | |
zjeffer | ff84c6dbaf | |
Alexis Rouillard | cb2d54a237 | |
Viktar Lukashonak | 5fe99ea0e1 | |
giskard | b980dab6df | |
giskard | e298bf922f | |
ViktarL | 2ead1bbf84 | |
Tuur Vanhoutte | 29917fb073 | |
Alex | e627879b16 | |
Alex | 0572e02d7e | |
Eldar Yusupov | df1a9c5509 | |
Lars-Ragnar A. Haugen | e7779b5458 | |
Alex | fc6d708fb6 | |
Lars-Ragnar A. Haugen | a453ea3c70 | |
Lars-Ragnar A. Haugen | 8e8ce0c6bc | |
Bintang | c4e0c569aa | |
柳芭老爹 | 231d6972d7 | |
Jacob Birkett | 50476edc98 | |
Lars-Ragnar A. Haugen | 0b6476da32 | |
Jan Beich | 79ae530bd2 | |
Tuur Vanhoutte | f41458ea24 | |
clayton craft | 2481f7a292 | |
Alex | 61ac7e4e10 | |
Milo Mordaunt | 9a3044a54f | |
Alexis Rouillard | a597a994d2 | |
Kiri | a2c5a8215b | |
Kiri | 57197b8e01 | |
Kiri | 5c4e368819 | |
Kiri | 8d962430dd | |
Kiri | 54a85ea15f | |
Kiri | efa7dc7ba4 | |
Alex | a04016e0b6 | |
Alexis Rouillard | 08b0ed1b79 | |
Lars-Ragnar A. Haugen | 5b7d0a2810 | |
Alex | 501e63fba6 | |
Alexis Rouillard | 5ce5ceba62 | |
drendog | 2123995b03 | |
Alexis Rouillard | 87cc40e6e2 | |
Lars-Ragnar A. Haugen | 6c1125c1fe | |
Alex | 937bf2ba5d | |
Alexis Rouillard | 77df0c3e3b | |
Alexis Rouillard | 95788e8081 | |
vawvaw | f75b2ae91f | |
joesri | 2673a5a4f1 | |
Alex | 8ef4ddd7ef | |
Alexis Rouillard | f26efae569 | |
Kiri | 67bf98a93e | |
Alexis Rouillard | dd092a5fc1 | |
Alexis Rouillard | 3efebc2822 | |
Alexis Rouillard | fbcd7ebbfa | |
Jan-Peter Dhallé | fb88c06d78 | |
Raphael Nestler | 133dfc2e85 | |
Alexis Rouillard | ddacb111a9 | |
hrdl | 74773885c6 | |
Kiri | 3d54a6002d | |
Kiri | da47c94480 | |
Kiri | 986b348bc7 | |
Kiri | 421ba6e31a | |
Tom Benham | 084b561d5b | |
Tom Benham | cd3d588abd | |
Kiri | 24690248db | |
Kiri | 805faa47e6 | |
Kiri | a59593fde1 | |
Kiri | 7f1e623f77 | |
Kiri | 43511992d9 | |
Alexis Rouillard | e8038ef9f3 | |
Alex | a9088c7e7d | |
Alexis Rouillard | 896c578c0e | |
Hristo Venev | f68ac9119a | |
Daniel Kahn Gillmor | 3d15b96429 | |
Alexis Rouillard | 42dc9cb85f | |
Bruce Mills | 245043f9e7 | |
Alexis Rouillard | 3de9e0cbd3 | |
kvark | 9b4fc6d16b | |
Alexis Rouillard | ddc767cd81 | |
Kuruyia | fe15530f34 | |
Alexis Rouillard | b652b4296d | |
Alexis Rouillard | e8627e140c | |
Alexis Rouillard | d6c0d59224 | |
Lin Xianyi | 5056309963 | |
Alexis Rouillard | 487ab23259 | |
cptpcrd | e3ceaf63d1 | |
Alexis Rouillard | c6cbf57a38 | |
encbar5 | abd7ca2a1e | |
Sano | 70ef406d6b | |
Mauro Guida | 7cd2a6c003 | |
Alexis Rouillard | cc084f5f86 | |
Alex | 19f3ce6f85 | |
Alexis Rouillard | 32e241dc47 | |
Alexis Rouillard | c4907a6065 | |
Alexis Rouillard | f228c13802 | |
Alexis Rouillard | e30ddda23a | |
Alexis Rouillard | 38634a0ca8 | |
Alex | fe0716bf39 | |
Alexis Rouillard | 9d95eaaac4 | |
Ryan Walklin | 2326727ccb | |
Alexis Rouillard | 1ecca055f7 | |
Mauro Guida | c841bf567b | |
Alexis Rouillard | 49a13ab28f | |
Mauro Guida | 6d690ad48b | |
Alexis Rouillard | b9688eb067 | |
wispl | 0fcf6bcebc | |
wispl | cf3389e5d7 | |
Alexis Rouillard | cbe42a8536 | |
Alexis Rouillard | 73e24af71c | |
hrdl | 856a34e16d | |
Jo De Boeck | 2ffd9a94a5 | |
leiserfg | 67218d5554 | |
Bartel Sielski | bbb69bd977 | |
Bartel Sielski | bd8b215416 | |
Alexis Rouillard | 2c927de4c6 | |
Tom Benham | 736309ef1f | |
Alexis Rouillard | ca17bdb214 | |
Jannik | f014a7d2e5 | |
Alexis Rouillard | 376b4d1c09 | |
DreamMaoMao | c5a6299398 | |
Alexis Rouillard | 8174dce776 | |
Nicola Revelant | 01ff7ebb36 | |
Nicola Revelant | fbf66530a3 | |
Nicola Revelant | e1f876b981 | |
Alexis Rouillard | 1eb509a86d | |
Nicola Revelant | 2d12236726 | |
luzpaz | 4ccefa0902 | |
Alexis Rouillard | fc4b9fa22b | |
Aleksei Bavshin | dcddddd3f1 | |
Eldar Yusupov | 17734f0364 | |
Alex | 32eac3ccb7 | |
Alexis Rouillard | 20f08b881a | |
Alexis Rouillard | 214858f413 | |
Jo De Boeck | 7b3d155608 | |
Robin Ole Heinemann | 207e99876d | |
Tom Benham | 68889494d0 | |
Alexis Rouillard | 4c46d7d245 | |
Merlin Sievers | 25b85800a5 | |
Alexis Rouillard | 380607583e | |
Tom Benham | df7f1fffcf | |
Alexis Rouillard | 26af1066e1 | |
Alexis Rouillard | 97cd2b47b8 | |
Erik Reider | 9de0e393ab | |
Félix Baylac Jacqué | 5578c122ab | |
Félix Baylac Jacqué | 5ba7c9eb60 | |
Félix Baylac Jacqué | cc759a8b8f | |
Félix Baylac Jacqué | bddc870340 | |
Félix Baylac Jacqué | 09bb6a055d | |
Félix Baylac Jacqué | 61fed6a214 | |
Aleksei Bavshin | c03fa38974 | |
Aleksei Bavshin | bb60d41842 | |
Aleksei Bavshin | 653c24cee1 | |
Alexis Rouillard | bdff489850 | |
Félix Baylac Jacqué | 162b41c4d0 | |
Aleksei Bavshin | 55915f95f1 | |
alttabber | d9abc080e1 | |
Alexis Rouillard | e7c7ef6814 | |
Alexis Rouillard | 04f73e7303 | |
Azazel | ba48d26dd4 | |
Jo De Boeck | 5a887fe1ef | |
Alexis Rouillard | e79ea93d7d | |
Azazel | 615c9050e7 | |
Azazel | c59bb509bd | |
Azazel | a7d8b1bacf | |
Félix Baylac Jacqué | 968f469289 | |
Félix Baylac Jacqué | c38d05b04f | |
Azazel | 695c786354 | |
Azazel | 16aced7f9f | |
Anthony Ruhier | d6d4d87cf7 | |
Anthony Ruhier | b3ee94d87a | |
Azazel | 3a5aa5ee83 | |
Azazel | 0ead42e52b | |
Alexis Rouillard | 6703adc37f | |
Aleksei Bavshin | 43aabf046c | |
Aleksei Bavshin | 2108959644 | |
Alexis Rouillard | 3a33c0b290 | |
Alexis Rouillard | fb193529fc | |
Alexis Rouillard | 75dce1ef4b | |
Jannik | 9bc8de8876 | |
zjeffer | 42f4386e2e | |
zjeffer | edd723d95c | |
Aleksei Bavshin | 05fbbc1c43 | |
Aleksei Bavshin | 2540c07f1d | |
Jannik | 4cc2800a78 | |
Jannik | 16079eae09 | |
Aleksei Bavshin | 188789592e | |
Aleksei Bavshin | 99c48bca36 | |
Alexis Rouillard | 601af3de81 | |
Jonny Tischbein | 3d31e9a22a | |
Alexis Rouillard | 793394c862 | |
aokblast | 514d00803c | |
Alexis Rouillard | 977c66e7c5 | |
Alex | 450a344426 | |
Aleksei Bavshin | 5fc2b97194 | |
Alex | efb2eb5073 | |
Alexis Rouillard | 1606dce62e | |
Jo De Boeck | bb843e0494 | |
Alexis Rouillard | 1b4008c58b | |
Alex | a45932973a | |
Lin Xianyi | 00ee538c95 | |
Alexis Rouillard | 4ef5b48474 | |
Tom Benham | e6aa06cdf3 | |
Alex | e42635197c | |
Alex | b8324be8c4 | |
Alexis Rouillard | 197bc6a877 | |
Alexis Rouillard | 536933ca24 | |
Alexis Rouillard | a118af0d1b | |
Aleksei Bavshin | f885baba61 | |
Aleksei Bavshin | a2deff3689 | |
Aleksei Bavshin | 5d6acfd1d4 | |
Aleksei Bavshin | d59d6e8765 | |
Aleksei Bavshin | bdb2f2bd1a | |
Jeremy Huang | 4a5444d196 | |
Alexis Rouillard | ce5a1cf2f9 | |
Aleksei Bavshin | c6f5cbdf0c | |
Alexis Rouillard | 6048e23e09 | |
Alexis Rouillard | 3d75167e67 | |
Alexis Rouillard | ee2407496f | |
Alex | 175852e527 | |
Alexis Rouillard | d36f15c26b | |
Alexis Rouillard | 742cd7f371 | |
Alex | 41b2d0cb29 | |
Aleksei Bavshin | a95b6a39c9 | |
Alex | bd0bf836c7 | |
Alexis Rouillard | ae1e11db22 | |
Alexis Rouillard | 347197865f | |
Alexis Rouillard | 91b79a2e9e | |
Alexis Rouillard | 70dc388dff | |
Alexis Rouillard | bba8da76b6 | |
Alexis Rouillard | 9abd0da1c7 | |
Alexis Rouillard | 6fbae3bd7b | |
Alexis Rouillard | 9191cae13b | |
Alexis Rouillard | a18b6dcc29 | |
Alexis Rouillard | c553e3028e | |
Tom Benham | 745d5687b8 | |
Aleksei Bavshin | 8a4a44896a | |
Aleksei Bavshin | 4420447e74 | |
zjeffer | 11310b89f0 | |
zjeffer | a02bacdd53 | |
Aleksei Bavshin | 543290ab07 | |
Aleksei Bavshin | fd5a03dc5f | |
Aleksei Bavshin | f3063e86aa | |
Aleksei Bavshin | 3cb587945a | |
Aleksei Bavshin | 9a21884272 | |
Aleksei Bavshin | 4f5dd53571 | |
Aleksei Bavshin | 4b34486143 | |
Aleksei Bavshin | 63935ba0fb | |
Aleksei Bavshin | d9f9fb51ff | |
Aleksei Bavshin | c2f37705ad | |
Aleksei Bavshin | 72406fa3f2 | |
Aleksei Bavshin | 104accdc34 | |
Viktar Lukashonak | d7d4dca6ba | |
Josh Jones | 7f3e396383 | |
Alexis Rouillard | 3cd311819b | |
Josh Jones | 9c3881f6f8 | |
Aleksei Bavshin | d590d508ca | |
Aleksei Bavshin | 2f555a6936 | |
alttabber | 9ea470410f | |
Alexis Rouillard | 28cd9dff47 | |
alttabber | 77c7b91b40 | |
Niklas Haas | a0bac34329 | |
Alexis Rouillard | 2c244b5e83 | |
zjeffer | dd8d6fbe6c | |
Jannik | acf6611098 | |
Jannik | a2925fa5da | |
Jannik | 240b49f9d2 | |
Jannik | d4331ce7fe | |
Alexis Rouillard | 4d076a71f7 | |
OpenSauce04 | 90c2415b64 | |
Jannik | 692f8f4ea4 | |
Jannik | 61be2267ab | |
Jannik | c30541b954 | |
Jannik | 3bfcd5e086 | |
Alexis Rouillard | b6f4a0dae2 | |
Imran Haider | 92875711c6 | |
Merlin Sievers | 89b3203bfa | |
Jannik | 08b32cb901 | |
Josh Jones | 1fa1045af9 | |
Josh Jones | e02cb9cfb9 | |
Josh Jones | 718dd4afae | |
Jo De Boeck | c641d52e06 | |
Jannik | 029b380c15 | |
Alexis Rouillard | 4c5ff80bbd | |
Alex | f1016322b9 | |
Alex | 6dcae2cade | |
Alex | fb6658e8fd | |
Alexis Rouillard | 1dce607c42 | |
dpayne | 10cb4180f6 | |
Alexis Rouillard | 5534fc48b1 | |
dpayne | 9556b0fe89 | |
Alexis Rouillard | ddad6ce136 | |
Jay-716 | 14d168c254 | |
Jay-716 | 167f04a4df | |
Alexis Rouillard | 5f115785cf | |
Alexis Rouillard | 7caf0b9ec4 | |
Paul Rey | 94633c346a | |
Siddhartha Singh | 7e76369ec8 | |
Paul Rey | 002ff002fe | |
Alexis Rouillard | 0948a407d0 | |
Arnesh Roychowdhury | 90b5b21394 | |
Alexis Rouillard | 8e2fa0fdbd | |
Paul Rey | 0af8f5c691 | |
dpayne | 970a7519d4 | |
Alexis Rouillard | 0d9c492998 | |
SquishyPandaDev | 82b632e4ec | |
Alexis Rouillard | 27fec51439 | |
dpayne | 20fa578b12 | |
dpayne | f7eca99496 | |
dpayne | 53233e47a3 | |
dpayne | d7ed4f1fa8 | |
ArneshRC | d14a4a2b1a | |
ArneshRC | dacffdb095 | |
ArneshRC | 74e863ed73 | |
Arnesh Roychowdhury | 3de6d2e859 | |
Alexis Rouillard | 6e12f81223 | |
Maëlys Bras de fer | 4f0fbaba8e | |
Alexis Rouillard | 392f83e71d | |
Maëlys Bras de fer | d343f616fc | |
Arnesh Roychowdhury | 8c502378aa | |
Alexis Rouillard | 07eabc5328 | |
Joshua Manchester | 95ffc291f6 | |
zjeffer | 8f5d0098d6 | |
Arnesh Roychowdhury | 4eef1ce10f | |
Arnesh Roychowdhury | f1f3442e38 | |
ArneshRC | 3390c16f52 | |
Yaroslav Chvanov | c420b40668 |
24
.clang-tidy
24
.clang-tidy
|
@ -15,15 +15,15 @@ Checks: >
|
|||
-readability-redundant-member-init,
|
||||
-readability-redundant-string-init,
|
||||
-readability-identifier-length
|
||||
CheckOptions:
|
||||
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
|
||||
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.StructCase, value: CamelCase }
|
||||
- { key: readability-identifier-naming.FunctionCase, value: camelBack }
|
||||
- { key: readability-identifier-naming.VariableCase, value: camelBack }
|
||||
- { key: readability-identifier-naming.PrivateMemberCase, value: camelBack }
|
||||
- { key: readability-identifier-naming.PrivateMemberPrefix, value: m_ }
|
||||
- { 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 }
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
bug:
|
||||
- "(crash|bug|error|coredump|freeze|segfault|issue|problem)"
|
||||
|
||||
enhancement:
|
||||
- "(feature|enhancement|improvement|request|suggestion)"
|
||||
|
||||
hyprland:
|
||||
- "(hyprland)"
|
||||
|
||||
network:
|
||||
- "(network|wifi|ethernet)"
|
||||
|
||||
bluetooth:
|
||||
- "(bluetooth|bluez)"
|
||||
|
||||
sway:
|
||||
- "(sway)"
|
||||
|
||||
cpu:
|
||||
- "(cpu)"
|
||||
|
||||
memory:
|
||||
- "(memory|ram)"
|
||||
|
||||
disk:
|
||||
- "(disk|storage)"
|
||||
|
||||
battery:
|
||||
- "(upower|battery)"
|
||||
|
||||
sni:
|
||||
- "(sni|tray)"
|
||||
|
||||
dwl:
|
||||
- "(dwl)"
|
||||
|
||||
custom:
|
||||
- "(custom|module|extension|plugin|script)"
|
||||
|
||||
mpd:
|
||||
- "(mpd|music)"
|
||||
|
||||
audio:
|
||||
- "(pulseaudio|alsa|jack|audio|pirewire|wireplumber)"
|
||||
|
||||
temperature:
|
||||
- "(temperature|thermal|hwmon)"
|
||||
|
||||
clock:
|
||||
- "(clock|time|date)"
|
||||
|
||||
gamemode:
|
||||
- "(gamemode|game|gaming)"
|
||||
|
||||
inhibitor:
|
||||
- "(inhibitor|idle|lock|suspend|hibernate|logout)"
|
||||
|
||||
cava:
|
||||
- "(cava|audio-visualizer)"
|
||||
|
||||
backlight:
|
||||
- "(backlight|brightness)"
|
||||
|
||||
keyboard:
|
||||
- "(keyboard|keymap|layout|shortcut)"
|
|
@ -2,14 +2,18 @@ name: clang-format
|
|||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-format-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: DoozyX/clang-format-lint-action@v0.16.2
|
||||
name: clang-format
|
||||
with:
|
||||
source: '.'
|
||||
extensions: 'hpp,h,cpp,c'
|
||||
clangFormatVersion: 16
|
||||
- uses: actions/checkout@v3
|
||||
- uses: DoozyX/clang-format-lint-action@v0.16.2
|
||||
name: clang-format
|
||||
with:
|
||||
source: "."
|
||||
extensions: "hpp,h,cpp,c"
|
||||
clangFormatVersion: 16
|
||||
|
|
|
@ -2,6 +2,10 @@ name: clang-tidy
|
|||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-tidy-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -13,7 +17,11 @@ jobs:
|
|||
run: |
|
||||
meson -Dcpp_std=c++20 build # necessary to generate compile_commands.json
|
||||
ninja -C build # necessary to find certain .h files (xdg, wayland, etc.)
|
||||
- uses: cpp-linter/cpp-linter-action@v2.7.5
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10' # to be kept in sync with cpp-linter-action
|
||||
update-environment: true # the python dist installed by the action needs LD_LIBRARY_PATH to work
|
||||
- uses: cpp-linter/cpp-linter-action@v2.9.1
|
||||
name: clang-tidy
|
||||
id: clang-tidy-check
|
||||
env:
|
|
@ -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 }}
|
|
@ -2,28 +2,35 @@ name: freebsd
|
|||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-freebsd-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
clang:
|
||||
# Run actions in a FreeBSD VM on the macos-12 runner
|
||||
# Run actions in a FreeBSD VM on the ubuntu runner
|
||||
# https://github.com/actions/runner/issues/385 - for FreeBSD runner support
|
||||
# https://github.com/actions/virtual-environments/issues/4060 - for lack of VirtualBox on MacOS 11 runners
|
||||
runs-on: macos-12
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Test in FreeBSD VM
|
||||
uses: cross-platform-actions/action@v0.21.1
|
||||
uses: cross-platform-actions/action@v0.23.0
|
||||
timeout-minutes: 180
|
||||
env:
|
||||
CPPFLAGS: '-isystem/usr/local/include'
|
||||
LDFLAGS: '-L/usr/local/lib'
|
||||
with:
|
||||
operating_system: freebsd
|
||||
version: "13.2"
|
||||
environment_variables: CPPFLAGS=-isystem/usr/local/include LDFLAGS=-L/usr/local/lib
|
||||
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
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
name: "Issue Labeler"
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: github/issue-labeler@v3.4
|
||||
with:
|
||||
configuration-path: .github/labeler.yml
|
||||
enable-versioned-regex: 0
|
||||
include-title: 1
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -2,6 +2,10 @@ name: linux
|
|||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-linux-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
|
@ -14,9 +18,6 @@ jobs:
|
|||
- opensuse
|
||||
- gentoo
|
||||
cpp_std: [c++20]
|
||||
include:
|
||||
- distro: fedora
|
||||
cpp_std: c++20
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
|
@ -25,7 +26,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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -48,3 +48,5 @@ packagecache
|
|||
# Nix
|
||||
result
|
||||
result-*
|
||||
|
||||
.ccls-cache
|
||||
|
|
|
@ -3,11 +3,47 @@
|
|||
FROM debian:sid
|
||||
|
||||
RUN apt update && \
|
||||
apt install -y \
|
||||
build-essential meson ninja-build git pkg-config libinput10 libpugixml-dev libinput-dev \
|
||||
wayland-protocols libwayland-client0 libwayland-cursor0 libwayland-dev \
|
||||
libegl1-mesa-dev libgles2-mesa-dev libgbm-dev libxkbcommon-dev libudev-dev libpixman-1-dev \
|
||||
libgtkmm-3.0-dev libjsoncpp-dev scdoc libdbusmenu-gtk3-dev libnl-3-dev libnl-genl-3-dev \
|
||||
libpulse-dev libmpdclient-dev gobject-introspection libgirepository1.0-dev libxkbcommon-dev \
|
||||
libxkbregistry-dev libxkbregistry0 libplayerctl-dev sudo python3-venv python3-pip && \
|
||||
apt clean
|
||||
apt install --no-install-recommends --no-install-suggests -y \
|
||||
build-essential \
|
||||
catch2 \
|
||||
cmake \
|
||||
git \
|
||||
gobject-introspection \
|
||||
libdbusmenu-gtk3-dev \
|
||||
libegl1-mesa-dev \
|
||||
libfmt-dev \
|
||||
libgbm-dev \
|
||||
libgirepository1.0-dev \
|
||||
libgles2-mesa-dev \
|
||||
libgtk-layer-shell-dev \
|
||||
libgtkmm-3.0-dev \
|
||||
libhowardhinnant-date-dev \
|
||||
libiniparser-dev \
|
||||
libinput-dev \
|
||||
libjack-jackd2-dev \
|
||||
libjsoncpp-dev \
|
||||
libmpdclient-dev \
|
||||
libnl-3-dev \
|
||||
libnl-genl-3-dev \
|
||||
libpixman-1-dev \
|
||||
libplayerctl-dev \
|
||||
libpugixml-dev \
|
||||
libpulse-dev \
|
||||
libsndio-dev \
|
||||
libspdlog-dev \
|
||||
libudev-dev \
|
||||
libupower-glib-dev \
|
||||
libwayland-dev \
|
||||
libwireplumber-0.5-dev \
|
||||
libxkbcommon-dev \
|
||||
libxkbregistry-dev \
|
||||
locales \
|
||||
meson \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
scdoc \
|
||||
sudo \
|
||||
wayland-protocols \
|
||||
&& apt clean
|
||||
|
|
|
@ -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
|
||||
|
|
4
Makefile
4
Makefile
|
@ -3,11 +3,11 @@
|
|||
default: build
|
||||
|
||||
build:
|
||||
meson build
|
||||
meson setup build
|
||||
ninja -C build
|
||||
|
||||
build-debug:
|
||||
meson build --buildtype=debug
|
||||
meson setup build --buildtype=debug
|
||||
ninja -C build
|
||||
|
||||
install: build
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
- Sway (Workspaces, Binding mode, Focused window name)
|
||||
- River (Mapping mode, Tags, Focused window name)
|
||||
- Hyprland (Window Icons, Workspaces, Focused window name)
|
||||
- DWL (Tags) [requires dwl ipc patch](https://github.com/djpohly/dwl/wiki/ipc)
|
||||
- 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
|
||||
- Battery
|
||||
- UPower
|
||||
- Power profiles daemon
|
||||
- Network
|
||||
- Bluetooth
|
||||
- Pulseaudio
|
||||
|
@ -36,7 +37,7 @@
|
|||
|
||||
Waybar is available from a number of Linux distributions:
|
||||
|
||||
[![Packaging status](https://repology.org/badge/vertical-allrepos/waybar.svg)](https://repology.org/project/waybar/versions)
|
||||
[![Packaging status](https://repology.org/badge/vertical-allrepos/waybar.svg?columns=3&header=Waybar%20Downstream%20Packaging)](https://repology.org/project/waybar/versions)
|
||||
|
||||
An Ubuntu PPA with more recent versions is available
|
||||
[here](https://launchpad.net/~nschloe/+archive/ubuntu/waybar).
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1704538339,
|
||||
"narHash": "sha256-1734d3mQuux9ySvwf6axRWZRBhtcZA9Q8eftD6EZg6U=",
|
||||
"lastModified": 1711163522,
|
||||
"narHash": "sha256-YN/Ciidm+A0fmJPWlHBGvVkcarYWSC+s3NTPk/P+q3c=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "46ae0210ce163b3cba6c7da08840c1d63de9c701",
|
||||
"rev": "44d0940ea560dee511026a53f0e2e2cde489b4d4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
38
flake.nix
38
flake.nix
|
@ -16,7 +16,12 @@
|
|||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
]
|
||||
(system: func (import nixpkgs { inherit system; }));
|
||||
(system: func (import nixpkgs {
|
||||
inherit system;
|
||||
overlays = with self.overlays; [
|
||||
waybar
|
||||
];
|
||||
}));
|
||||
|
||||
mkDate = longDate: (lib.concatStringsSep "-" [
|
||||
(builtins.substring 0 4 longDate)
|
||||
|
@ -46,22 +51,25 @@
|
|||
};
|
||||
});
|
||||
|
||||
overlays.default = final: prev: {
|
||||
waybar = final.callPackage ./nix/default.nix {
|
||||
# take the first "version: '...'" from meson.build
|
||||
version =
|
||||
(builtins.head (builtins.split "'"
|
||||
(builtins.elemAt
|
||||
(builtins.split " version: '" (builtins.readFile ./meson.build))
|
||||
2)))
|
||||
+ "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
overlays = {
|
||||
default = self.overlays.waybar;
|
||||
waybar = final: prev: {
|
||||
waybar = final.callPackage ./nix/default.nix {
|
||||
waybar = prev.waybar;
|
||||
# take the first "version: '...'" from meson.build
|
||||
version =
|
||||
(builtins.head (builtins.split "'"
|
||||
(builtins.elemAt
|
||||
(builtins.split " version: '" (builtins.readFile ./meson.build))
|
||||
2)))
|
||||
+ "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
packages = genSystems (pkgs:
|
||||
let packages = self.overlays.default pkgs pkgs;
|
||||
in packages // {
|
||||
default = packages.waybar;
|
||||
});
|
||||
packages = genSystems (pkgs: {
|
||||
default = self.packages.${pkgs.stdenv.hostPlatform.system}.waybar;
|
||||
inherit (pkgs) waybar;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace waybar {
|
|||
|
||||
class AModule : public IModule {
|
||||
public:
|
||||
static constexpr const char *MODULE_CLASS = "module";
|
||||
|
||||
virtual ~AModule();
|
||||
auto update() -> void override;
|
||||
virtual auto refresh(int) -> void{};
|
||||
|
@ -35,13 +37,18 @@ class AModule : public IModule {
|
|||
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);
|
||||
|
||||
private:
|
||||
bool handleUserEvent(GdkEventButton *const &ev);
|
||||
const bool isTooltip;
|
||||
bool hasUserEvents_;
|
||||
std::vector<int> pid_;
|
||||
gdouble distance_scrolled_y_;
|
||||
gdouble distance_scrolled_x_;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <json/json.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "AModule.hpp"
|
||||
|
@ -41,7 +42,7 @@ struct bar_margins {
|
|||
};
|
||||
|
||||
struct bar_mode {
|
||||
bar_layer layer;
|
||||
std::optional<bar_layer> layer;
|
||||
bool exclusive;
|
||||
bool passthrough;
|
||||
bool visible;
|
||||
|
@ -53,34 +54,18 @@ class BarIpcClient;
|
|||
}
|
||||
#endif // HAVE_SWAY
|
||||
|
||||
class BarSurface {
|
||||
protected:
|
||||
BarSurface() = default;
|
||||
|
||||
public:
|
||||
virtual void setExclusiveZone(bool enable) = 0;
|
||||
virtual void setLayer(bar_layer layer) = 0;
|
||||
virtual void setMargins(const struct bar_margins &margins) = 0;
|
||||
virtual void setPassThrough(bool enable) = 0;
|
||||
virtual void setPosition(const std::string_view &position) = 0;
|
||||
virtual void setSize(uint32_t width, uint32_t height) = 0;
|
||||
virtual void commit(){};
|
||||
|
||||
virtual ~BarSurface() = default;
|
||||
};
|
||||
|
||||
class Bar {
|
||||
public:
|
||||
using bar_mode_map = std::map<std::string_view, struct bar_mode>;
|
||||
using bar_mode_map = std::map<std::string, struct bar_mode>;
|
||||
static const bar_mode_map PRESET_MODES;
|
||||
static const std::string_view MODE_DEFAULT;
|
||||
static const std::string_view MODE_INVISIBLE;
|
||||
static const std::string MODE_DEFAULT;
|
||||
static const std::string MODE_INVISIBLE;
|
||||
|
||||
Bar(struct waybar_output *w_output, const Json::Value &);
|
||||
Bar(const Bar &) = delete;
|
||||
~Bar();
|
||||
|
||||
void setMode(const std::string_view &);
|
||||
void setMode(const std::string &mode);
|
||||
void setVisible(bool visible);
|
||||
void toggle();
|
||||
void handleSignal(int);
|
||||
|
@ -89,8 +74,9 @@ class Bar {
|
|||
Json::Value config;
|
||||
struct wl_surface *surface;
|
||||
bool visible = true;
|
||||
bool vertical = false;
|
||||
Gtk::Window window;
|
||||
Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL;
|
||||
Gtk::PositionType position = Gtk::POS_TOP;
|
||||
|
||||
int x_global;
|
||||
int y_global;
|
||||
|
@ -106,6 +92,8 @@ class Bar {
|
|||
void setupAltFormatKeyForModule(const std::string &module_name);
|
||||
void setupAltFormatKeyForModuleList(const char *module_list_name);
|
||||
void setMode(const bar_mode &);
|
||||
void setPassThrough(bool passthrough);
|
||||
void setPosition(Gtk::PositionType position);
|
||||
void onConfigure(GdkEventConfigure *ev);
|
||||
void configureGlobalOffset(int width, int height);
|
||||
void onOutputGeometryChanged();
|
||||
|
@ -115,8 +103,9 @@ class Bar {
|
|||
std::string last_mode_{MODE_DEFAULT};
|
||||
|
||||
struct bar_margins margins_;
|
||||
uint32_t width_, height_;
|
||||
bool passthrough_;
|
||||
|
||||
std::unique_ptr<BarSurface> surface_impl_;
|
||||
Gtk::Box left_;
|
||||
Gtk::Box center_;
|
||||
Gtk::Box right_;
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#include "bar.hpp"
|
||||
#include "config.hpp"
|
||||
#include "util/css_reload_helper.hpp"
|
||||
#include "util/portal.hpp"
|
||||
|
||||
struct zwlr_layer_shell_v1;
|
||||
struct zwp_idle_inhibitor_v1;
|
||||
struct zwp_idle_inhibit_manager_v1;
|
||||
|
||||
|
@ -25,7 +25,6 @@ class Client {
|
|||
Glib::RefPtr<Gdk::Display> gdk_display;
|
||||
struct wl_display *wl_display = nullptr;
|
||||
struct wl_registry *registry = nullptr;
|
||||
struct zwlr_layer_shell_v1 *layer_shell = nullptr;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager = nullptr;
|
||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager = nullptr;
|
||||
std::vector<std::unique_ptr<Bar>> bars;
|
||||
|
@ -55,6 +54,8 @@ class Client {
|
|||
Glib::RefPtr<Gtk::CssProvider> css_provider_;
|
||||
std::unique_ptr<Portal> portal;
|
||||
std::list<struct waybar_output> outputs_;
|
||||
std::unique_ptr<CssReloadHelper> m_cssReloadHelper;
|
||||
std::string m_cssFile;
|
||||
};
|
||||
|
||||
} // namespace waybar
|
||||
|
|
|
@ -1,110 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <json/json.h>
|
||||
#if defined(HAVE_CHRONO_TIMEZONES) || defined(HAVE_LIBDATE)
|
||||
#include "modules/clock.hpp"
|
||||
#else
|
||||
#include "modules/simpleclock.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_SWAY
|
||||
#include "modules/sway/language.hpp"
|
||||
#include "modules/sway/mode.hpp"
|
||||
#include "modules/sway/scratchpad.hpp"
|
||||
#include "modules/sway/window.hpp"
|
||||
#include "modules/sway/workspaces.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_WLR
|
||||
#include "modules/wlr/taskbar.hpp"
|
||||
#include "modules/wlr/workspace_manager.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_RIVER
|
||||
#include "modules/river/layout.hpp"
|
||||
#include "modules/river/mode.hpp"
|
||||
#include "modules/river/tags.hpp"
|
||||
#include "modules/river/window.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_DWL
|
||||
#include "modules/dwl/tags.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_HYPRLAND
|
||||
#include "modules/hyprland/backend.hpp"
|
||||
#include "modules/hyprland/language.hpp"
|
||||
#include "modules/hyprland/submap.hpp"
|
||||
#include "modules/hyprland/window.hpp"
|
||||
#include "modules/hyprland/workspaces.hpp"
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || (defined(__linux__) && !defined(NO_FILESYSTEM))
|
||||
#include "modules/battery.hpp"
|
||||
#endif
|
||||
#if defined(HAVE_CPU_LINUX) || defined(HAVE_CPU_BSD)
|
||||
#include "modules/cpu.hpp"
|
||||
#include "modules/cpu_frequency.hpp"
|
||||
#include "modules/cpu_usage.hpp"
|
||||
#include "modules/load.hpp"
|
||||
#endif
|
||||
#include "modules/idle_inhibitor.hpp"
|
||||
#if defined(HAVE_MEMORY_LINUX) || defined(HAVE_MEMORY_BSD)
|
||||
#include "modules/memory.hpp"
|
||||
#endif
|
||||
#include "modules/disk.hpp"
|
||||
#ifdef HAVE_DBUSMENU
|
||||
#include "modules/sni/tray.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_MPRIS
|
||||
#include "modules/mpris/mpris.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBNL
|
||||
#include "modules/network.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBUDEV
|
||||
#include "modules/backlight.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBEVDEV
|
||||
#include "modules/keyboard_state.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_GAMEMODE
|
||||
#include "modules/gamemode.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_UPOWER
|
||||
#include "modules/upower/upower.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_PIPEWIRE
|
||||
#include "modules/privacy/privacy.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBPULSE
|
||||
#include "modules/pulseaudio.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBMPDCLIENT
|
||||
#include "modules/mpd/mpd.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBSNDIO
|
||||
#include "modules/sndio.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_GIO_UNIX
|
||||
#include "modules/bluetooth.hpp"
|
||||
#include "modules/inhibitor.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBJACK
|
||||
#include "modules/jack.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBWIREPLUMBER
|
||||
#include "modules/wireplumber.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_LIBCAVA
|
||||
#include "modules/cava.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_SYSTEMD_MONITOR
|
||||
#include "modules/systemd_failed_units.hpp"
|
||||
#endif
|
||||
#include "bar.hpp"
|
||||
#include "modules/cffi.hpp"
|
||||
#include "modules/custom.hpp"
|
||||
#include "modules/image.hpp"
|
||||
#include "modules/temperature.hpp"
|
||||
#include "modules/user.hpp"
|
||||
|
||||
#include <AModule.hpp>
|
||||
|
||||
namespace waybar {
|
||||
|
||||
class Bar;
|
||||
|
||||
class Factory {
|
||||
public:
|
||||
Factory(const Bar& bar, const Json::Value& config);
|
||||
|
|
|
@ -11,15 +11,13 @@ namespace waybar {
|
|||
|
||||
class Group : public AModule {
|
||||
public:
|
||||
Group(const std::string&, const std::string&, const Json::Value&, bool);
|
||||
Group(const std::string &, const std::string &, const Json::Value &, bool);
|
||||
virtual ~Group() = 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;
|
||||
|
@ -28,8 +26,8 @@ class Group : public AModule {
|
|||
bool is_first_widget = true;
|
||||
bool is_drawer = 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;
|
||||
};
|
||||
|
||||
} // namespace waybar
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef FILESYSTEM_EXPERIMENTAL
|
||||
#include <experimental/filesystem>
|
||||
#else
|
||||
#include <filesystem>
|
||||
#endif
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <filesystem>
|
||||
#if defined(__linux__)
|
||||
#include <sys/inotify.h>
|
||||
#endif
|
||||
|
@ -16,19 +13,16 @@
|
|||
#include <vector>
|
||||
|
||||
#include "ALabel.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "util/sleeper_thread.hpp"
|
||||
|
||||
namespace waybar::modules {
|
||||
|
||||
#ifdef FILESYSTEM_EXPERIMENTAL
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#else
|
||||
namespace fs = std::filesystem;
|
||||
#endif
|
||||
|
||||
class Battery : public ALabel {
|
||||
public:
|
||||
Battery(const std::string&, const Json::Value&);
|
||||
Battery(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||
virtual ~Battery();
|
||||
auto update() -> void override;
|
||||
|
||||
|
@ -38,8 +32,9 @@ class Battery : public ALabel {
|
|||
void refreshBatteries();
|
||||
void worker();
|
||||
const std::string getAdapterStatus(uint8_t capacity) const;
|
||||
const std::tuple<uint8_t, float, std::string, float> getInfos();
|
||||
std::tuple<uint8_t, float, std::string, float, uint16_t, float> getInfos();
|
||||
const std::string formatTimeRemaining(float hoursRemaining);
|
||||
void setBarClass(std::string&);
|
||||
|
||||
int global_watch;
|
||||
std::map<fs::path, int> batteries_;
|
||||
|
@ -49,6 +44,7 @@ class Battery : public ALabel {
|
|||
std::mutex battery_list_mutex_;
|
||||
std::string old_status_;
|
||||
bool warnFirstTime_{true};
|
||||
const Bar& bar_;
|
||||
|
||||
util::SleeperThread thread_;
|
||||
util::SleeperThread thread_battery_update_;
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace waybar::modules {
|
|||
|
||||
const std::string kCldPlaceholder{"calendar"};
|
||||
const std::string kTZPlaceholder{"tz_list"};
|
||||
const std::string kOrdPlaceholder{"ordinal_date"};
|
||||
|
||||
enum class CldMode { MONTH, YEAR };
|
||||
enum class WS { LEFT, RIGHT, HIDDEN };
|
||||
|
@ -20,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
|
||||
/*
|
||||
|
@ -40,6 +43,7 @@ class Clock final : public ALabel {
|
|||
const int cldMonColLen_{20}; // calendar month column length
|
||||
WS cldWPos_{WS::HIDDEN}; // calendar week side to print
|
||||
months cldCurrShift_{0}; // calendar months shift
|
||||
int cldShift_{1}; // calendar months shift factor
|
||||
year_month_day cldYearShift_; // calendar Year mode. Cached ymd
|
||||
std::string cldYearCached_; // calendar Year mode. Cached calendar
|
||||
year_month cldMonShift_; // calendar Month mode. Cached ym
|
||||
|
@ -50,6 +54,9 @@ class Clock final : public ALabel {
|
|||
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*;
|
||||
|
||||
// time zoned time in tooltip
|
||||
const bool tzInTooltip_; // if need to print time zones text
|
||||
std::vector<const time_zone*> tzList_; // time zones list
|
||||
|
@ -57,12 +64,18 @@ class Clock final : public ALabel {
|
|||
std::string tzText_{""}; // time zones text to print
|
||||
util::SleeperThread thread_;
|
||||
|
||||
// ordinal date in tooltip
|
||||
const bool ordInTooltip_;
|
||||
std::string ordText_{""};
|
||||
auto get_ordinal_date(const year_month_day& today) -> std::string;
|
||||
|
||||
auto getTZtext(sys_seconds now) -> std::string;
|
||||
auto first_day_of_week() -> weekday;
|
||||
// Module actions
|
||||
void cldModeSwitch();
|
||||
void cldShift_up();
|
||||
void cldShift_down();
|
||||
void cldShift_reset();
|
||||
void tz_up();
|
||||
void tz_down();
|
||||
// Module Action Map
|
||||
|
@ -70,6 +83,7 @@ class Clock final : public ALabel {
|
|||
{"mode", &waybar::modules::Clock::cldModeSwitch},
|
||||
{"shift_up", &waybar::modules::Clock::cldShift_up},
|
||||
{"shift_down", &waybar::modules::Clock::cldShift_down},
|
||||
{"shift_reset", &waybar::modules::Clock::cldShift_reset},
|
||||
{"tz_up", &waybar::modules::Clock::tz_up},
|
||||
{"tz_down", &waybar::modules::Clock::tz_down}};
|
||||
};
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "AAppIconLabel.hpp"
|
||||
#include "bar.hpp"
|
||||
#include "dwl-ipc-unstable-v2-client-protocol.h"
|
||||
#include "util/json.hpp"
|
||||
|
||||
namespace waybar::modules::dwl {
|
||||
|
||||
class Window : public AAppIconLabel, public sigc::trackable {
|
||||
public:
|
||||
Window(const std::string &, const waybar::Bar &, const Json::Value &);
|
||||
~Window();
|
||||
|
||||
void handle_layout(const uint32_t layout);
|
||||
void handle_title(const char *title);
|
||||
void handle_appid(const char *ppid);
|
||||
void handle_layout_symbol(const char *layout_symbol);
|
||||
void handle_frame();
|
||||
|
||||
struct zdwl_ipc_manager_v2 *status_manager_;
|
||||
|
||||
private:
|
||||
const Bar &bar_;
|
||||
|
||||
std::string title_;
|
||||
std::string appid_;
|
||||
std::string layout_symbol_;
|
||||
uint32_t layout_;
|
||||
|
||||
struct zdwl_ipc_output_v2 *output_status_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::dwl
|
|
@ -20,8 +20,8 @@ class IPC {
|
|||
public:
|
||||
IPC() { startIPC(); }
|
||||
|
||||
void registerForIPC(const std::string&, EventHandler*);
|
||||
void unregisterForIPC(EventHandler*);
|
||||
void registerForIPC(const std::string& ev, EventHandler* ev_handler);
|
||||
void unregisterForIPC(EventHandler* handler);
|
||||
|
||||
static std::string getSocket1Reply(const std::string& rq);
|
||||
Json::Value getSocket1JsonReply(const std::string& rq);
|
||||
|
@ -30,9 +30,9 @@ class IPC {
|
|||
void startIPC();
|
||||
void parseIPC(const std::string&);
|
||||
|
||||
std::mutex m_callbackMutex;
|
||||
util::JsonParser m_parser;
|
||||
std::list<std::pair<std::string, EventHandler*>> m_callbacks;
|
||||
std::mutex callbackMutex_;
|
||||
util::JsonParser parser_;
|
||||
std::list<std::pair<std::string, EventHandler*>> callbacks_;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<IPC> gIPC;
|
||||
|
|
|
@ -30,7 +30,7 @@ class Language : public waybar::ALabel, public EventHandler {
|
|||
std::string short_description;
|
||||
};
|
||||
|
||||
auto getLayout(const std::string&) -> Layout;
|
||||
static auto getLayout(const std::string&) -> Layout;
|
||||
|
||||
std::mutex mutex_;
|
||||
const Bar& bar_;
|
||||
|
|
|
@ -14,17 +14,20 @@ namespace waybar::modules::hyprland {
|
|||
class Submap : public waybar::ALabel, public EventHandler {
|
||||
public:
|
||||
Submap(const std::string&, const waybar::Bar&, const Json::Value&);
|
||||
virtual ~Submap();
|
||||
~Submap() override;
|
||||
|
||||
auto update() -> void override;
|
||||
|
||||
private:
|
||||
void onEvent(const std::string&) override;
|
||||
auto parseConfig(const Json::Value&) -> void;
|
||||
void onEvent(const std::string& ev) override;
|
||||
|
||||
std::mutex mutex_;
|
||||
const Bar& bar_;
|
||||
util::JsonParser parser_;
|
||||
std::string submap_;
|
||||
bool always_on_ = false;
|
||||
std::string default_submap_ = "Default";
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
|
|
@ -25,7 +25,7 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
|||
std::string last_window;
|
||||
std::string last_window_title;
|
||||
|
||||
static auto parse(const Json::Value&) -> Workspace;
|
||||
static auto parse(const Json::Value& value) -> Workspace;
|
||||
};
|
||||
|
||||
struct WindowData {
|
||||
|
@ -41,24 +41,25 @@ class Window : public waybar::AAppIconLabel, public EventHandler {
|
|||
static auto parse(const Json::Value&) -> WindowData;
|
||||
};
|
||||
|
||||
auto getActiveWorkspace(const std::string&) -> Workspace;
|
||||
auto getActiveWorkspace() -> Workspace;
|
||||
void onEvent(const std::string&) override;
|
||||
static auto getActiveWorkspace(const std::string&) -> Workspace;
|
||||
static auto getActiveWorkspace() -> Workspace;
|
||||
void onEvent(const std::string& ev) override;
|
||||
void queryActiveWorkspace();
|
||||
void setClass(const std::string&, bool enable);
|
||||
|
||||
bool separate_outputs;
|
||||
bool separateOutputs_;
|
||||
std::mutex mutex_;
|
||||
const Bar& bar_;
|
||||
util::JsonParser parser_;
|
||||
WindowData window_data_;
|
||||
WindowData windowData_;
|
||||
Workspace workspace_;
|
||||
std::string solo_class_;
|
||||
std::string last_solo_class_;
|
||||
std::string soloClass_;
|
||||
std::string lastSoloClass_;
|
||||
bool solo_;
|
||||
bool all_floating_;
|
||||
bool allFloating_;
|
||||
bool swallowing_;
|
||||
bool fullscreen_;
|
||||
bool focused_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::hyprland
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -17,6 +17,8 @@
|
|||
#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,92 +28,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_active; };
|
||||
bool isSpecial() const { return m_isSpecial; };
|
||||
bool isPersistent() const { return m_isPersistent; };
|
||||
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_active = value; };
|
||||
void setPersistent(bool value = true) { m_isPersistent = 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; };
|
||||
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_active = false;
|
||||
bool m_isSpecial = false;
|
||||
bool m_isPersistent = false;
|
||||
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&);
|
||||
|
@ -122,6 +38,8 @@ 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; }
|
||||
|
||||
|
@ -135,15 +53,28 @@ class Workspaces : public AModule, public EventHandler {
|
|||
void onEvent(const std::string& e) override;
|
||||
void updateWindowCount();
|
||||
void sortWorkspaces();
|
||||
void createWorkspace(Json::Value const& workspace_data,
|
||||
Json::Value const& clients_data = Json::Value::nullRef);
|
||||
void createWorkspace(Json::Value const& workspaceData,
|
||||
Json::Value const& clientsData = Json::Value::nullRef);
|
||||
|
||||
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;
|
||||
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 populatePersistentWorkspacesConfig(const Json::Value& config) -> void;
|
||||
auto populateFormatWindowSeparatorConfig(const Json::Value& config) -> void;
|
||||
auto populateWindowRewriteConfig(const Json::Value& config) -> void;
|
||||
|
||||
void registerIpc();
|
||||
|
||||
// workspace events
|
||||
void onWorkspaceActivated(std::string const& payload);
|
||||
void onSpecialWorkspaceActivated(std::string const& payload);
|
||||
void onWorkspaceDestroyed(std::string const& payload);
|
||||
void onWorkspaceCreated(std::string const& workspaceName,
|
||||
Json::Value const& clientsData = Json::Value::nullRef);
|
||||
|
@ -160,16 +91,32 @@ class Workspaces : public AModule, public EventHandler {
|
|||
|
||||
void onWindowTitleEvent(std::string const& payload);
|
||||
|
||||
void onConfigReloaded();
|
||||
|
||||
int windowRewritePriorityFunction(std::string const& window_rule);
|
||||
|
||||
// Update methods
|
||||
void doUpdate();
|
||||
void removeWorkspacesToRemove();
|
||||
void createWorkspacesToCreate();
|
||||
std::vector<std::string> getVisibleWorkspaces();
|
||||
void updateWorkspaceStates(const std::vector<std::string>& visibleWorkspaces);
|
||||
bool updateWindowsToCreate();
|
||||
|
||||
void extendOrphans(int workspaceId, Json::Value const& clientsJson);
|
||||
void registerOrphanWindow(WindowCreationPayload create_window_paylod);
|
||||
void registerOrphanWindow(WindowCreationPayload create_window_payload);
|
||||
|
||||
void initializeWorkspaces();
|
||||
void setCurrentMonitorId();
|
||||
void loadPersistentWorkspacesFromConfig(Json::Value const& clientsJson);
|
||||
void loadPersistentWorkspacesFromWorkspaceRules(const Json::Value& clientsJson);
|
||||
|
||||
bool m_allOutputs = false;
|
||||
bool m_showSpecial = false;
|
||||
bool m_activeOnly = false;
|
||||
bool m_specialVisibleOnly = false;
|
||||
bool m_moveToMonitor = false;
|
||||
Json::Value m_persistentWorkspaceConfig;
|
||||
|
||||
// Map for windows stored in workspaces not present in the current bar.
|
||||
// This happens when the user has multiple monitors (hence, multiple bars)
|
||||
|
@ -184,11 +131,6 @@ class Workspaces : public AModule, public EventHandler {
|
|||
{"NUMBER", SortMethod::NUMBER},
|
||||
{"DEFAULT", SortMethod::DEFAULT}};
|
||||
|
||||
void fillPersistentWorkspaces();
|
||||
void createPersistentWorkspaces();
|
||||
std::vector<std::string> m_persistentWorkspacesToCreate;
|
||||
bool m_persistentCreated = false;
|
||||
|
||||
std::string m_format;
|
||||
|
||||
std::map<std::string, std::string> m_iconsMap;
|
||||
|
@ -199,6 +141,7 @@ class Workspaces : public AModule, public EventHandler {
|
|||
bool m_withIcon;
|
||||
uint64_t m_monitorId;
|
||||
std::string m_activeWorkspaceName;
|
||||
std::string m_activeSpecialWorkspaceName;
|
||||
std::vector<std::unique_ptr<Workspace>> m_workspaces;
|
||||
std::vector<std::pair<Json::Value, Json::Value>> m_workspacesToCreate;
|
||||
std::vector<std::string> m_workspacesToRemove;
|
||||
|
|
|
@ -148,6 +148,7 @@ class Stopped : public State {
|
|||
class Disconnected : public State {
|
||||
Context* const ctx_;
|
||||
sigc::connection timer_connection_;
|
||||
int last_interval_;
|
||||
|
||||
public:
|
||||
Disconnected(Context* const ctx) : ctx_{ctx} {}
|
||||
|
@ -162,7 +163,7 @@ class Disconnected : public State {
|
|||
Disconnected(Disconnected const&) = delete;
|
||||
Disconnected& operator=(Disconnected const&) = delete;
|
||||
|
||||
void arm_timer(int interval) noexcept;
|
||||
bool arm_timer(int interval) noexcept;
|
||||
void disarm_timer() noexcept;
|
||||
|
||||
bool on_timer();
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "ALabel.hpp"
|
||||
#include "giomm/dbusproxy.h"
|
||||
|
||||
namespace waybar::modules {
|
||||
|
||||
struct Profile {
|
||||
std::string name;
|
||||
std::string driver;
|
||||
};
|
||||
|
||||
class PowerProfilesDaemon : public ALabel {
|
||||
public:
|
||||
PowerProfilesDaemon(const std::string &, const Json::Value &);
|
||||
auto update() -> void override;
|
||||
void profileChangedCb(const Gio::DBus::Proxy::MapChangedProperties &,
|
||||
const std::vector<Glib::ustring> &);
|
||||
void busConnectedCb(Glib::RefPtr<Gio::AsyncResult> &r);
|
||||
void getAllPropsCb(Glib::RefPtr<Gio::AsyncResult> &r);
|
||||
void setPropCb(Glib::RefPtr<Gio::AsyncResult> &r);
|
||||
void populateInitState();
|
||||
bool handleToggle(GdkEventButton *const &e) override;
|
||||
|
||||
private:
|
||||
// True if we're connected to the dbug interface. False if we're
|
||||
// not.
|
||||
bool connected_;
|
||||
// Look for a profile name in the list of available profiles and
|
||||
// switch activeProfile_ to it.
|
||||
void switchToProfile(std::string const &);
|
||||
// Used to toggle/display the profiles
|
||||
std::vector<Profile> availableProfiles_;
|
||||
// Points to the active profile in the profiles list
|
||||
std::vector<Profile>::iterator activeProfile_;
|
||||
// Current CSS class applied to the label
|
||||
std::string currentStyle_;
|
||||
// Format string
|
||||
std::string tooltipFormat_;
|
||||
// DBus Proxy used to track the current active profile
|
||||
Glib::RefPtr<Gio::DBus::Proxy> powerProfilesProxy_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules
|
|
@ -1,10 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "ALabel.hpp"
|
||||
#include "gtkmm/box.h"
|
||||
#include "modules/privacy/privacy_item.hpp"
|
||||
#include "util/pipewire/pipewire_backend.hpp"
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
|
||||
#include <json/value.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "gtkmm/box.h"
|
||||
|
|
|
@ -76,6 +76,8 @@ class Item : public sigc::trackable {
|
|||
void makeMenu();
|
||||
bool handleClick(GdkEventButton* const& /*ev*/);
|
||||
bool handleScroll(GdkEventScroll* const&);
|
||||
bool handleMouseEnter(GdkEventCrossing* const&);
|
||||
bool handleMouseLeave(GdkEventCrossing* const&);
|
||||
|
||||
// smooth scrolling threshold
|
||||
gdouble scroll_threshold_ = 0;
|
||||
|
|
|
@ -56,6 +56,7 @@ class Language : public ALabel, public sigc::trackable {
|
|||
Layout layout_;
|
||||
std::string tooltip_format_ = "";
|
||||
std::map<std::string, Layout> layouts_map_;
|
||||
bool hide_single_;
|
||||
bool is_variant_displayed;
|
||||
std::byte displayed_short_flag = static_cast<std::byte>(DispayedShortFlag::None);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "client.hpp"
|
||||
#include "modules/sway/ipc/client.hpp"
|
||||
#include "util/json.hpp"
|
||||
#include "util/regex_collection.hpp"
|
||||
|
||||
namespace waybar::modules::sway {
|
||||
|
||||
|
@ -27,10 +28,13 @@ class Workspaces : public AModule, public sigc::trackable {
|
|||
R"(workspace {} "{}"; move workspace to output "{}"; workspace {} "{}")";
|
||||
|
||||
static int convertWorkspaceNameToNum(std::string name);
|
||||
static int windowRewritePriorityFunction(std::string const& window_rule);
|
||||
|
||||
void onCmd(const struct Ipc::ipc_response&);
|
||||
void onEvent(const struct Ipc::ipc_response&);
|
||||
bool filterButtons();
|
||||
static bool hasFlag(const Json::Value&, const std::string&);
|
||||
void updateWindows(const Json::Value&, std::string&);
|
||||
Gtk::Button& addButton(const Json::Value&);
|
||||
void onButtonReady(const Json::Value&, Gtk::Button&);
|
||||
std::string getIcon(const std::string&, const Json::Value&);
|
||||
|
@ -44,6 +48,9 @@ class Workspaces : public AModule, public sigc::trackable {
|
|||
std::vector<std::string> high_priority_named_;
|
||||
std::vector<std::string> workspaces_order_;
|
||||
Gtk::Box box_;
|
||||
std::string m_formatWindowSeperator;
|
||||
std::string m_windowRewriteDefault;
|
||||
util::RegexCollection m_windowRewriteRules;
|
||||
util::JsonParser parser_;
|
||||
std::unordered_map<std::string, Gtk::Button> buttons_;
|
||||
std::mutex mutex_;
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <giomm/dbusproxy.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ALabel.hpp"
|
||||
|
||||
namespace waybar::modules {
|
||||
|
||||
class SystemdFailedUnits : public ALabel {
|
||||
public:
|
||||
SystemdFailedUnits(const std::string&, const Json::Value&);
|
||||
SystemdFailedUnits(const std::string &, const Json::Value &);
|
||||
virtual ~SystemdFailedUnits();
|
||||
auto update() -> void override;
|
||||
|
||||
|
@ -18,8 +19,8 @@ class SystemdFailedUnits : public ALabel {
|
|||
std::string format_ok;
|
||||
|
||||
bool update_pending;
|
||||
std::string last_status;
|
||||
uint32_t nr_failed_system, nr_failed_user;
|
||||
std::string last_status;
|
||||
Glib::RefPtr<Gio::DBus::Proxy> system_proxy, user_proxy;
|
||||
|
||||
void notify_cb(const Glib::ustring &sender_name, const Glib::ustring &signal_name,
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
#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 lastStatus_;
|
||||
Glib::ustring label_markup_;
|
||||
std::mutex mutex_;
|
||||
Glib::RefPtr<Gtk::IconTheme> gtkTheme_;
|
||||
bool sleeping_;
|
||||
|
||||
// Technical functions
|
||||
void addDevice(UpDevice *);
|
||||
void removeDevice(const gchar *);
|
||||
void removeDevices();
|
||||
void resetDevices();
|
||||
void setDisplayDevice();
|
||||
const Glib::ustring getText(const upDevice_output &upDevice_, const std::string &format);
|
||||
bool queryTooltipCb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &);
|
||||
|
||||
// DBUS variables
|
||||
guint watcherID_;
|
||||
Glib::RefPtr<Gio::DBus::Connection> conn_;
|
||||
guint subscrID_{0u};
|
||||
|
||||
// UPower variables
|
||||
UpClient *upClient_;
|
||||
upDevice_output upDevice_; // Device to display
|
||||
typedef std::unordered_map<std::string, upDevice_output> Devices;
|
||||
Devices devices_;
|
||||
bool upRunning_{true};
|
||||
|
||||
// DBus callbacks
|
||||
void getConn_cb(Glib::RefPtr<Gio::AsyncResult> &result);
|
||||
void onAppear(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &,
|
||||
const Glib::ustring &);
|
||||
void onVanished(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &);
|
||||
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
|
||||
const Glib::ustring &sender_name, const Glib::ustring &object_path,
|
||||
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
|
||||
const Glib::VariantContainerBase ¶meters);
|
||||
|
||||
// UPower callbacks
|
||||
static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data);
|
||||
static void deviceRemoved_cb(UpClient *client, const gchar *objectPath, gpointer data);
|
||||
static void deviceNotify_cb(UpDevice *device, GParamSpec *pspec, gpointer user_data);
|
||||
// UPower secondary functions
|
||||
void getUpDeviceInfo(upDevice_output &upDevice_);
|
||||
};
|
||||
|
||||
} // namespace waybar::modules
|
|
@ -1,81 +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;
|
||||
guint login1_id;
|
||||
GDBusConnection *login1_connection;
|
||||
std::unique_ptr<UPowerTooltip> upower_tooltip;
|
||||
std::string lastStatus;
|
||||
bool showAltText;
|
||||
bool showIcon = true;
|
||||
bool upowerRunning;
|
||||
guint upowerWatcher_id;
|
||||
std::string nativePath_;
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::upower
|
|
@ -1,33 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <libupower-glib/upower.h>
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "gtkmm/box.h"
|
||||
#include "gtkmm/label.h"
|
||||
#include "gtkmm/window.h"
|
||||
|
||||
namespace waybar::modules::upower {
|
||||
|
||||
class UPowerTooltip : public Gtk::Window {
|
||||
private:
|
||||
typedef std::unordered_map<std::string, UpDevice*> Devices;
|
||||
|
||||
const std::string getDeviceIcon(UpDeviceKind& kind);
|
||||
|
||||
std::unique_ptr<Gtk::Box> contentBox;
|
||||
|
||||
uint iconSize;
|
||||
uint tooltipSpacing;
|
||||
uint tooltipPadding;
|
||||
|
||||
public:
|
||||
UPowerTooltip(uint iconSize, uint tooltipSpacing, uint tooltipPadding);
|
||||
virtual ~UPowerTooltip();
|
||||
|
||||
uint updateTooltip(Devices& devices);
|
||||
};
|
||||
|
||||
} // namespace waybar::modules::upower
|
|
@ -17,12 +17,15 @@ class Wireplumber : public ALabel {
|
|||
auto update() -> void override;
|
||||
|
||||
private:
|
||||
void loadRequiredApiModules();
|
||||
void asyncLoadRequiredApiModules();
|
||||
void prepare();
|
||||
void activatePlugins();
|
||||
static void updateVolume(waybar::modules::Wireplumber* self, uint32_t id);
|
||||
static void updateNodeName(waybar::modules::Wireplumber* self, uint32_t id);
|
||||
static void onPluginActivated(WpObject* p, GAsyncResult* res, waybar::modules::Wireplumber* self);
|
||||
static void onDefaultNodesApiLoaded(WpObject* p, GAsyncResult* res,
|
||||
waybar::modules::Wireplumber* self);
|
||||
static void onMixerApiLoaded(WpObject* p, GAsyncResult* res, waybar::modules::Wireplumber* self);
|
||||
static void onObjectManagerInstalled(waybar::modules::Wireplumber* self);
|
||||
static void onMixerChanged(waybar::modules::Wireplumber* self, uint32_t id);
|
||||
static void onDefaultNodesApiChanged(waybar::modules::Wireplumber* self);
|
||||
|
|
|
@ -21,11 +21,19 @@
|
|||
#include "giomm/desktopappinfo.h"
|
||||
#include "util/json.hpp"
|
||||
#include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
|
||||
#include "modules/sway/ipc/client.hpp"
|
||||
|
||||
namespace waybar::modules::wlr {
|
||||
|
||||
class Taskbar;
|
||||
|
||||
class SwayScratchpad {
|
||||
public:
|
||||
int id;
|
||||
std::string app_id;
|
||||
std::string title;
|
||||
};
|
||||
|
||||
class Task {
|
||||
public:
|
||||
Task(const waybar::Bar &, const Json::Value &, Taskbar *,
|
||||
|
@ -54,6 +62,7 @@ class Task {
|
|||
struct wl_seat *seat_;
|
||||
|
||||
uint32_t id_;
|
||||
uint32_t swayId_;
|
||||
|
||||
Gtk::Box content_;
|
||||
Gtk::Image icon_;
|
||||
|
@ -62,6 +71,8 @@ class Task {
|
|||
Glib::RefPtr<Gio::DesktopAppInfo> app_info_;
|
||||
bool button_visible_ = false;
|
||||
bool ignored_ = false;
|
||||
bool only_scratchpad_ = false;
|
||||
bool isScratchpadMode_ = false;
|
||||
|
||||
bool with_icon_ = false;
|
||||
bool with_name_ = false;
|
||||
|
@ -86,12 +97,15 @@ class Task {
|
|||
bool image_load_icon(Gtk::Image &image, const Glib::RefPtr<Gtk::IconTheme> &icon_theme,
|
||||
Glib::RefPtr<Gio::DesktopAppInfo> app_info, int size);
|
||||
void hide_if_ignored();
|
||||
bool hideNoScratchpad();
|
||||
|
||||
public:
|
||||
/* Getter functions */
|
||||
uint32_t id() const { return id_; }
|
||||
uint32_t swayId() const { return swayId_; }
|
||||
std::string title() const { return title_; }
|
||||
std::string app_id() const { return app_id_; }
|
||||
bool isScratchpadMode() const { return isScratchpadMode_; }
|
||||
uint32_t state() const { return state_; }
|
||||
bool maximized() const { return state_ & MAXIMIZED; }
|
||||
bool minimized() const { return state_ & MINIMIZED; }
|
||||
|
@ -117,6 +131,8 @@ class Task {
|
|||
void handle_drag_data_received(const Glib::RefPtr<Gdk::DragContext> &context, int x, int y,
|
||||
Gtk::SelectionData selection_data, guint info, guint time);
|
||||
|
||||
void setManualForSway(const int id, const std::string app_id, const std::string title);
|
||||
|
||||
public:
|
||||
bool operator==(const Task &) const;
|
||||
bool operator!=(const Task &) const;
|
||||
|
@ -153,6 +169,15 @@ class Taskbar : public waybar::AModule {
|
|||
struct zwlr_foreign_toplevel_manager_v1 *manager_;
|
||||
struct wl_seat *seat_;
|
||||
|
||||
/* Sway scratchpad indicator */
|
||||
std::mutex mutex_;
|
||||
waybar::modules::sway::Ipc ipc_;
|
||||
auto getSwayTree() -> void;
|
||||
auto onSwayCmd(const struct waybar::modules::sway::Ipc::ipc_response&) -> void;
|
||||
auto onSwayEvent(const struct waybar::modules::sway::Ipc::ipc_response&) -> void;
|
||||
util::JsonParser parser_;
|
||||
std::map<std::string, Task> swayWorkspaceMap;
|
||||
|
||||
public:
|
||||
/* Callbacks for global registration */
|
||||
void register_manager(struct wl_registry *, uint32_t name, uint32_t version);
|
||||
|
|
|
@ -22,6 +22,7 @@ class AudioBackend {
|
|||
static void sourceInfoCb(pa_context*, const pa_source_info* i, int, void* data);
|
||||
static void serverInfoCb(pa_context*, const pa_server_info*, void*);
|
||||
static void volumeModifyCb(pa_context*, int, void*);
|
||||
void connectContext();
|
||||
|
||||
pa_threaded_mainloop* mainloop_;
|
||||
pa_mainloop_api* mainloop_api_;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
std::scoped_lock<std::mutex> lock((backend).udev_thread_mutex_); \
|
||||
__devices = (backend).devices_; \
|
||||
} \
|
||||
auto varname = (backend).best_device(__devices.cbegin(), __devices.cend(), preferred_device);
|
||||
auto varname = (backend).best_device(__devices, preferred_device);
|
||||
|
||||
namespace waybar::util {
|
||||
|
||||
|
@ -61,16 +61,10 @@ class BacklightBackend {
|
|||
void set_scaled_brightness(std::string preferred_device, int brightness);
|
||||
int get_scaled_brightness(std::string preferred_device);
|
||||
|
||||
template <class ForwardIt, class Inserter>
|
||||
static void upsert_device(ForwardIt first, ForwardIt last, Inserter inserter, udev_device *dev);
|
||||
|
||||
template <class ForwardIt, class Inserter>
|
||||
static void enumerate_devices(ForwardIt first, ForwardIt last, Inserter inserter, udev *udev);
|
||||
|
||||
bool is_login_proxy_initialized() const { return static_cast<bool>(login_proxy_); }
|
||||
|
||||
template <class ForwardIt>
|
||||
static const BacklightDevice *best_device(ForwardIt first, ForwardIt last, std::string_view);
|
||||
static const BacklightDevice *best_device(const std::vector<BacklightDevice> &devices,
|
||||
std::string_view);
|
||||
|
||||
std::vector<BacklightDevice> devices_;
|
||||
std::mutex udev_thread_mutex_;
|
||||
|
@ -90,4 +84,4 @@ class BacklightBackend {
|
|||
static constexpr int EPOLL_MAX_EVENTS = 16;
|
||||
};
|
||||
|
||||
} // namespace waybar::util
|
||||
} // namespace waybar::util
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "giomm/file.h"
|
||||
#include "giomm/filemonitor.h"
|
||||
#include "glibmm/refptr.h"
|
||||
|
||||
struct pollfd;
|
||||
|
||||
namespace waybar {
|
||||
class CssReloadHelper {
|
||||
public:
|
||||
CssReloadHelper(std::string cssFile, std::function<void()> callback);
|
||||
|
||||
virtual ~CssReloadHelper() = default;
|
||||
|
||||
virtual void monitorChanges();
|
||||
|
||||
protected:
|
||||
std::vector<std::string> parseImports(const std::string& cssFile);
|
||||
|
||||
void parseImports(const std::string& cssFile, std::unordered_map<std::string, bool>& imports);
|
||||
|
||||
void watchFiles(const std::vector<std::string>& files);
|
||||
|
||||
bool handleInotifyEvents(int fd);
|
||||
|
||||
bool watch(int inotifyFd, pollfd* pollFd);
|
||||
|
||||
virtual std::string getFileContents(const std::string& filename);
|
||||
|
||||
virtual std::string findPath(const std::string& filename);
|
||||
|
||||
void handleFileChange(Glib::RefPtr<Gio::File> const& file,
|
||||
Glib::RefPtr<Gio::File> const& other_type,
|
||||
Gio::FileMonitorEvent event_type);
|
||||
|
||||
private:
|
||||
std::string m_cssFile;
|
||||
|
||||
std::function<void()> m_callback;
|
||||
|
||||
std::vector<std::tuple<Glib::RefPtr<Gio::FileMonitor>>> m_fileMonitors;
|
||||
};
|
||||
} // namespace waybar
|
|
@ -30,10 +30,6 @@ template <typename T>
|
|||
inline auto format(const std::locale& loc, const char* spec, const T& arg) {
|
||||
return date::format(loc, std::regex_replace(spec, std::regex("\\{:L|\\}"), ""), arg);
|
||||
}
|
||||
|
||||
constexpr decltype(auto) operator""d(unsigned long long d) noexcept {
|
||||
return date::operator""_d(d); // very verbose, but it works
|
||||
}
|
||||
#endif
|
||||
} // namespace date
|
||||
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
#include <fmt/ostream.h>
|
||||
#include <json/json.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <codecvt>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
#include <regex>
|
||||
|
||||
#if (FMT_VERSION >= 90000)
|
||||
|
||||
template <>
|
||||
|
@ -12,25 +18,30 @@ struct fmt::formatter<Json::Value> : ostream_formatter {};
|
|||
|
||||
namespace waybar::util {
|
||||
|
||||
struct JsonParser {
|
||||
JsonParser() {}
|
||||
class JsonParser {
|
||||
public:
|
||||
JsonParser() = default;
|
||||
|
||||
const Json::Value parse(const std::string& data) const {
|
||||
Json::Value root(Json::objectValue);
|
||||
if (data.empty()) {
|
||||
return root;
|
||||
Json::Value parse(const std::string& jsonStr) {
|
||||
Json::Value root;
|
||||
|
||||
// replace all occurrences of "\x" with "\u00", because JSON doesn't allow "\x" escape sequences
|
||||
std::string modifiedJsonStr = replaceHexadecimalEscape(jsonStr);
|
||||
|
||||
std::istringstream jsonStream(modifiedJsonStr);
|
||||
std::string errs;
|
||||
if (!Json::parseFromStream(m_readerBuilder, jsonStream, &root, &errs)) {
|
||||
throw std::runtime_error("Error parsing JSON: " + errs);
|
||||
}
|
||||
std::unique_ptr<Json::CharReader> const reader(builder_.newCharReader());
|
||||
std::string err;
|
||||
bool res = reader->parse(data.c_str(), data.c_str() + data.size(), &root, &err);
|
||||
if (!res) throw std::runtime_error(err);
|
||||
return root;
|
||||
}
|
||||
|
||||
~JsonParser() = default;
|
||||
|
||||
private:
|
||||
Json::CharReaderBuilder builder_;
|
||||
};
|
||||
Json::CharReaderBuilder m_readerBuilder;
|
||||
|
||||
static std::string replaceHexadecimalEscape(const std::string& str) {
|
||||
static std::regex re("\\\\x");
|
||||
return std::regex_replace(str, re, "\\u00");
|
||||
}
|
||||
};
|
||||
} // namespace waybar::util
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "util/backend_common.hpp"
|
||||
#include "util/pipewire/privacy_node_info.hpp"
|
||||
|
||||
|
@ -13,7 +15,8 @@ class PipewireBackend {
|
|||
pw_context* context_;
|
||||
pw_core* core_;
|
||||
|
||||
spa_hook registry_listener;
|
||||
pw_registry* registry_;
|
||||
spa_hook registryListener_;
|
||||
|
||||
/* Hack to keep constructor inaccessible but still public.
|
||||
* This is required to be able to use std::make_shared.
|
||||
|
@ -21,20 +24,22 @@ class PipewireBackend {
|
|||
* pointer because the destructor will manually free memory, and this could be
|
||||
* a problem with C++20's copy and move semantics.
|
||||
*/
|
||||
struct private_constructor_tag {};
|
||||
struct PrivateConstructorTag {};
|
||||
|
||||
public:
|
||||
std::mutex mutex_;
|
||||
|
||||
pw_registry* registry;
|
||||
|
||||
sigc::signal<void> privacy_nodes_changed_signal_event;
|
||||
|
||||
std::unordered_map<uint32_t, PrivacyNodeInfo*> privacy_nodes;
|
||||
std::mutex mutex_;
|
||||
|
||||
static std::shared_ptr<PipewireBackend> getInstance();
|
||||
|
||||
PipewireBackend(private_constructor_tag tag);
|
||||
// Handlers for PipeWire events
|
||||
void handleRegistryEventGlobal(uint32_t id, uint32_t permissions, const char* type,
|
||||
uint32_t version, const struct spa_dict* props);
|
||||
void handleRegistryEventGlobalRemove(uint32_t id);
|
||||
|
||||
PipewireBackend(PrivateConstructorTag tag);
|
||||
~PipewireBackend();
|
||||
};
|
||||
} // namespace waybar::util::PipewireBackend
|
||||
|
|
|
@ -34,29 +34,12 @@ class PrivacyNodeInfo {
|
|||
|
||||
void *data;
|
||||
|
||||
std::string get_name() {
|
||||
const std::vector<std::string *> names{&application_name, &node_name};
|
||||
std::string name = "Unknown Application";
|
||||
for (auto &name_ : names) {
|
||||
if (name_ != nullptr && name_->length() > 0) {
|
||||
name = *name_;
|
||||
name[0] = toupper(name[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
std::string getName();
|
||||
std::string getIconName();
|
||||
|
||||
std::string get_icon_name() {
|
||||
const std::vector<std::string *> names{&application_icon_name, &pipewire_access_portal_app_id,
|
||||
&application_name, &node_name};
|
||||
const std::string name = "application-x-executable-symbolic";
|
||||
for (auto &name_ : names) {
|
||||
if (name_ != nullptr && name_->length() > 0 && DefaultGtkIconThemeWrapper::has_icon(*name_)) {
|
||||
return *name_;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
// Handlers for PipeWire events
|
||||
void handleProxyEventDestroy();
|
||||
void handleNodeEventInfo(const struct pw_node_info *info);
|
||||
};
|
||||
|
||||
} // namespace waybar::util::PipewireBackend
|
||||
|
|
|
@ -30,7 +30,11 @@ The *backlight* module displays the current backlight level.
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
|
|
|
@ -61,7 +61,11 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer++
|
||||
|
@ -115,6 +119,10 @@ The *battery* module displays the current capacity and state (eg. charging) of y
|
|||
|
||||
*{time}*: Estimate of time until full or empty. Note that this is based on the power draw at the last refresh time, not an average.
|
||||
|
||||
*{cycles}*: Amount of charge cycles the highest-capacity battery has seen. *(Linux only)*
|
||||
|
||||
*{health}*: The percentage of the highest-capacity battery's original maximum charge it can still hold.
|
||||
|
||||
# TIME FORMAT
|
||||
|
||||
The *battery* module allows you to define how time should be formatted via *format-time*.
|
||||
|
@ -167,3 +175,10 @@ The *battery* module allows one to define custom formats based on up to two fact
|
|||
- *<state>* can be defined in the *config*. For more information see *states*.
|
||||
- *#battery.<status>.<state>*
|
||||
- Combination of both *<status>* and *<state>*.
|
||||
|
||||
The following classes are applied to the entire Waybar rather than just the
|
||||
battery widget:
|
||||
|
||||
- *window#waybar.battery-<state>*
|
||||
- *<state>* can be defined in the *config*, as previously mentioned.
|
||||
|
||||
|
|
|
@ -66,7 +66,11 @@ Addressed by *bluetooth*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -157,6 +157,7 @@ View all valid format options in *strftime(3)* or have a look https://en.cpprefe
|
|||
|
||||
- *{calendar}*: Current month calendar
|
||||
- *{tz_list}*: List of time in the rest timezones, if more than one timezone is set in the config
|
||||
- *{ordinal_date}*: The current day in (English) ordinal form, e.g. 21st
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
|
|
|
@ -35,7 +35,11 @@ The *cpu* module displays the current CPU utilization.
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
|
|
|
@ -72,7 +72,11 @@ Addressed by *custom/<name>*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
@ -107,6 +111,11 @@ Addressed by *custom/<name>*
|
|||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*tooltip-format*: ++
|
||||
typeof: string ++
|
||||
The tooltip format. If specified, overrides any tooltip output from the script in *exec*. ++
|
||||
Uses the same format replacements as *format*.
|
||||
|
||||
*escape*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
|
|
|
@ -45,7 +45,11 @@ Addressed by *disk*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
waybar-dwl-window(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - dwl window module
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
The *window* module displays the title of the currently focused window in DWL
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
Addressed by *dwl/window*
|
||||
|
||||
*format*: ++
|
||||
typeof: string ++
|
||||
default: {title} ++
|
||||
The format, how information should be displayed.
|
||||
|
||||
*rotate*: ++
|
||||
typeof: integer ++
|
||||
Positive value to rotate the text label.
|
||||
|
||||
*max-length*: ++
|
||||
typeof: integer ++
|
||||
The maximum length in character the module should display.
|
||||
|
||||
*min-length*: ++
|
||||
typeof: integer ++
|
||||
The minimum length in characters the module should accept.
|
||||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
Command to execute when clicked on the module.
|
||||
|
||||
*on-click-middle*: ++
|
||||
typeof: string ++
|
||||
Command to execute when middle-clicked on the module using mousewheel.
|
||||
|
||||
*on-click-right*: ++
|
||||
typeof: string ++
|
||||
Command to execute when you right-click on the module.
|
||||
|
||||
*on-update*: ++
|
||||
typeof: string ++
|
||||
Command to execute when the module is updated.
|
||||
|
||||
*on-scroll-up*: ++
|
||||
typeof: string ++
|
||||
Command to execute when scrolling up on the module.
|
||||
|
||||
*on-scroll-down*: ++
|
||||
typeof: string ++
|
||||
Command to execute when scrolling down on the module.
|
||||
|
||||
*smooth-scrolling-threshold*: ++
|
||||
typeof: double ++
|
||||
Threshold to be used when scrolling.
|
||||
|
||||
*tooltip*: ++
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*rewrite*: ++
|
||||
typeof: object ++
|
||||
Rules to rewrite the module format output. See *rewrite rules*.
|
||||
|
||||
*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
|
||||
|
||||
*{title}*: The title of the focused window.
|
||||
|
||||
*{app_id}*: The app_id of the focused window.
|
||||
|
||||
*{layout}*: The layout 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 format output is left unchanged.
|
||||
|
||||
Invalid expressions (e.g., mismatched parentheses) are skipped.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
"dwl/window": {
|
||||
"format": "{}",
|
||||
"max-length": 50,
|
||||
"rewrite": {
|
||||
"(.*) - Mozilla Firefox": "🌎 $1",
|
||||
"(.*) - zsh": "> [$1]"
|
||||
}
|
||||
}
|
||||
```
|
|
@ -31,7 +31,11 @@ Addressed by *hyprland/submap*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
@ -66,6 +70,16 @@ Addressed by *hyprland/submap*
|
|||
default: true ++
|
||||
Option to disable tooltip on hover.
|
||||
|
||||
*always-on*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Option to display the widget even when there's no active submap.
|
||||
|
||||
*default-submap* ++
|
||||
typeof: string ++
|
||||
default: Default ++
|
||||
Option to set the submap name to display when not in an active submap.
|
||||
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
|
@ -80,3 +94,4 @@ Addressed by *hyprland/submap*
|
|||
# STYLE
|
||||
|
||||
- *#submap*
|
||||
- *#submap.<name>*
|
||||
|
|
|
@ -42,6 +42,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 ++
|
||||
|
@ -52,6 +57,13 @@ Addressed by *hyprland/workspaces*
|
|||
default: false ++
|
||||
If set to true, only the active workspace will be shown.
|
||||
|
||||
*move-to-monitor*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
If set to true, open the workspace on the current monitor when clicking on a workspace button.
|
||||
Otherwise, the workspace will open on the monitor where it was previously assigned.
|
||||
Analog to using `focusworkspaceoncurrentmonitor` dispatcher instead of `workspace` in Hyprland.
|
||||
|
||||
*ignore-workspaces*: ++
|
||||
typeof: array ++
|
||||
default: [] ++
|
||||
|
@ -139,6 +151,7 @@ Additional to workspace name matching, the following *format-icons* can be set.
|
|||
}
|
||||
```
|
||||
|
||||
```
|
||||
"hyprland/workspaces": {
|
||||
// Formatting omitted for brevity
|
||||
"ignore-workspaces": [
|
||||
|
@ -157,3 +170,4 @@ Additional to workspace name matching, the following *format-icons* can be set.
|
|||
- *#workspaces button.persistent*
|
||||
- *#workspaces button.special*
|
||||
- *#workspaces button.urgent*
|
||||
- *#workspaces button.hosting-monitor* (gets applied if workspace-monitor == waybar-monitor)
|
||||
|
|
|
@ -33,7 +33,11 @@ screensaver, also known as "presentation mode".
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -87,3 +87,4 @@ $path\\n$tooltip
|
|||
# STYLE
|
||||
|
||||
- *#image*
|
||||
- *#image.empty*
|
||||
|
|
|
@ -37,7 +37,11 @@ See *systemd-inhibit*(1) for more information.
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -63,7 +63,11 @@ Addressed by *jack*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -45,7 +45,11 @@ Addressed by *memory*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -103,7 +103,11 @@ Addressed by *mpd*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -119,8 +119,11 @@ The *mpris* module displays currently playing media via libplayerctl.
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. ++
|
||||
If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
@ -139,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
|
||||
|
|
|
@ -70,7 +70,11 @@ Addressed by *network*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
waybar-power-profiles-daemon(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar - power-profiles-daemon module
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
The *power-profiles-daemon* module displays the active power-profiles-daemon profile and cycle through the available profiles on click.
|
||||
|
||||
# FILES
|
||||
|
||||
$XDG_CONFIG_HOME/waybar/config
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
|
||||
[- *Option*
|
||||
:- *Typeof*
|
||||
:- *Default*
|
||||
:= *Description*
|
||||
|[ *format*
|
||||
:[ string
|
||||
:[ "{icon}"
|
||||
:[ Message displayed on the bar. {icon} and {profile} are respectively substituted with the icon representing the active profile and its full name.
|
||||
|[ *tooltip-format*
|
||||
:[ string
|
||||
:[ "Power profile: {profile}\\nDriver: {driver}"
|
||||
:[ Messaged displayed in the module tooltip. {icon} and {profile} are respectively substituted with the icon representing the active profile and its full name.
|
||||
|[ *tooltip*
|
||||
:[ bool
|
||||
:[ true
|
||||
:[ Display the tooltip.
|
||||
|[ *format-icons*
|
||||
:[ object
|
||||
:[ See default value in the example below.
|
||||
:[ Icons used to represent the various power-profile. *Note*: the default configuration uses the font-awesome icons. You may want to override it if you don't have this font installed on your system.
|
||||
|
||||
|
||||
# CONFIGURATION EXAMPLES
|
||||
|
||||
Compact display (default config):
|
||||
|
||||
```
|
||||
"power-profiles-daemon": {
|
||||
"format": "{icon}",
|
||||
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
|
||||
"tooltip": true,
|
||||
"format-icons": {
|
||||
"default": "",
|
||||
"performance": "",
|
||||
"balanced": "",
|
||||
"power-saver": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Display the full profile name:
|
||||
|
||||
```
|
||||
"power-profiles-daemon": {
|
||||
"format": "{icon} {profile}",
|
||||
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
|
||||
"tooltip": true,
|
||||
"format-icons": {
|
||||
"default": "",
|
||||
"performance": "",
|
||||
"balanced": "",
|
||||
"power-saver": ""
|
||||
}
|
||||
}
|
||||
```
|
|
@ -56,7 +56,11 @@ Additionally, you can control the volume by scrolling *up* or *down* while the c
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*scroll-step*: ++
|
||||
typeof: float ++
|
||||
|
|
|
@ -33,7 +33,11 @@ Addressed by *river/layout*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -31,7 +31,11 @@ Addressed by *river/mode*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -31,7 +31,11 @@ Addressed by *river/window*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -32,7 +32,11 @@ cursor is over the module, and clicking on the module toggles mute.
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*scroll-step*: ++
|
||||
typeof: int ++
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
waybar-styles(5)
|
||||
|
||||
# NAME
|
||||
|
||||
waybar-styles - using stylesheets for waybar
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
Waybar uses Cascading Style Sheets (CSS) to configure its appearance.
|
||||
|
||||
It uses the first file found in this search order:
|
||||
|
||||
- *$XDG_CONFIG_HOME/waybar/style.css*
|
||||
- *~/.config/waybar/style.css*
|
||||
- *~/waybar/style.css*
|
||||
- */etc/xdg/waybar/style.css*
|
||||
- *@sysconfdir@/xdg/waybar/style.css*
|
||||
|
||||
# EXAMPLE
|
||||
|
||||
An example user-controlled stylesheet that just changes the color of the clock to be green on black, while keeping the rest of the system config the same would be:
|
||||
|
||||
```
|
||||
@import url("file:///etc/xdg/waybar/style.css")
|
||||
|
||||
#clock {
|
||||
background: #000000;
|
||||
color: #00ff00;
|
||||
}
|
||||
```
|
||||
|
||||
## Hover-effect
|
||||
|
||||
You can apply special styling to any module for when the cursor hovers it.
|
||||
|
||||
```
|
||||
#clock:hover {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
```
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
- *waybar(5)*
|
|
@ -17,6 +17,11 @@ Addressed by *sway/language*
|
|||
default: {} ++
|
||||
The format, how layout should be displayed.
|
||||
|
||||
*hide-single-layout*: ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
Defines visibility of the module if a single layout is configured
|
||||
|
||||
*tooltip-format*: ++
|
||||
typeof: string ++
|
||||
default: {} ++
|
||||
|
|
|
@ -31,7 +31,11 @@ Addressed by *sway/mode*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -31,7 +31,11 @@ Addressed by *sway/window*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -82,6 +82,23 @@ warp-on-scroll: ++
|
|||
default: true ++
|
||||
If set to false, you can scroll to cycle through workspaces without mouse warping being enabled. If set to true this behaviour is disabled.
|
||||
|
||||
*window-rewrite*: ++
|
||||
typeof: object ++
|
||||
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.
|
||||
|
||||
*window-rewrite-default*:
|
||||
typeof: string ++
|
||||
default: "?" ++
|
||||
The default method of representation for a workspace's window. This will be used for windows whose classes do not match any of the rules in *window-rewrite*.
|
||||
|
||||
*format-window-separator*: ++
|
||||
typeof: string ++
|
||||
default: " " ++
|
||||
The separator to be used between windows in a workspace.
|
||||
|
||||
|
||||
# FORMAT REPLACEMENTS
|
||||
|
||||
*{value}*: Name of the workspace, as defined by sway.
|
||||
|
@ -94,6 +111,8 @@ warp-on-scroll: ++
|
|||
|
||||
*{output}*: Output where the workspace is located.
|
||||
|
||||
*{windows}*: Result from window-rewrite
|
||||
|
||||
# ICONS
|
||||
|
||||
Additional to workspace name matching, the following *format-icons* can be set.
|
||||
|
@ -143,6 +162,19 @@ n.b.: the list of outputs can be obtained from command line using *swaymsg -t ge
|
|||
}
|
||||
```
|
||||
|
||||
```
|
||||
"sway/workspaces": {
|
||||
"format": "<span size='larger'>{name}</span> {windows}",
|
||||
"format-window-separator": " | ",
|
||||
"window-rewrite-default": "{name}",
|
||||
"window-format": "<span color='#e0e0e0'>{name}</span>",
|
||||
"window-rewrite": {
|
||||
"class<firefox>": "",
|
||||
"class<kitty>": "k",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Style
|
||||
|
||||
- *#workspaces button*
|
||||
|
@ -150,5 +182,6 @@ n.b.: the list of outputs can be obtained from command line using *swaymsg -t ge
|
|||
- *#workspaces button.focused*
|
||||
- *#workspaces button.urgent*
|
||||
- *#workspaces button.persistent*
|
||||
- *#workspaces button.empty*
|
||||
- *#workspaces button.current_output*
|
||||
- *#workspaces button#sway-workspace-${name}*
|
||||
|
|
|
@ -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 ++
|
||||
|
@ -71,7 +72,11 @@ Addressed by *temperature*
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*on-click*: ++
|
||||
typeof: string ++
|
||||
|
|
|
@ -47,7 +47,11 @@ The *wireplumber* module displays the current volume reported by WirePlumber.
|
|||
|
||||
*align*: ++
|
||||
typeof: float ++
|
||||
The alignment of the text, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
The alignment of the label within the module, where 0 is left-aligned and 1 is right-aligned. If the module is rotated, it will follow the flow of the text.
|
||||
|
||||
*justify*: ++
|
||||
typeof: string ++
|
||||
The alignment of the text within the module's label, allowing options 'left', 'right', or 'center' to define the positioning.
|
||||
|
||||
*scroll-step*: ++
|
||||
typeof: float ++
|
||||
|
|
|
@ -16,9 +16,11 @@ Valid locations for this file are:
|
|||
- */etc/xdg/waybar/*
|
||||
- *@sysconfdir@/xdg/waybar/*
|
||||
|
||||
A good starting point is the default configuration found at https://github.com/Alexays/Waybar/blob/master/resources/config
|
||||
A good starting point is the default configuration found at https://github.com/Alexays/Waybar/blob/master/resources/config.jsonc
|
||||
Also, a minimal example configuration can be found at the bottom of this man page.
|
||||
|
||||
The visual display elements for waybar use a CSS stylesheet, see *waybar-styles(5)* for details.
|
||||
|
||||
# BAR CONFIGURATION
|
||||
|
||||
*layer* ++
|
||||
|
@ -108,12 +110,6 @@ Also, a minimal example configuration can be found at the bottom of this man pag
|
|||
Option to pass any pointer events to the window under the bar.
|
||||
Intended to be used with either *top* or *overlay* layers and without exclusive zone.
|
||||
|
||||
*gtk-layer-shell* ++
|
||||
typeof: bool ++
|
||||
default: true ++
|
||||
Option to disable the use of gtk-layer-shell for popups.
|
||||
Only functional if compiled with gtk-layer-shell support.
|
||||
|
||||
*ipc* ++
|
||||
typeof: bool ++
|
||||
default: false ++
|
||||
|
@ -130,6 +126,11 @@ Also, a minimal example configuration can be found at the bottom of this man pag
|
|||
Each file can contain a single object with any of the bar configuration options. In case of duplicate options, the first defined value takes precedence, i.e. including file -> first included file -> etc. Nested includes are permitted, but make sure to avoid circular imports.
|
||||
For a multi-bar config, the include directive affects only current bar configuration object.
|
||||
|
||||
*reload_style_on_change* ++
|
||||
typeof: bool ++
|
||||
default: *false* ++
|
||||
Option to enable reloading the css style if a modification is detected on the style sheet file or any imported css files.
|
||||
|
||||
# MODULE FORMAT
|
||||
|
||||
You can use PangoMarkupFormat (See https://developer.gnome.org/pango/stable/PangoMarkupFormat.html#PangoMarkupFormat).
|
||||
|
@ -311,6 +312,7 @@ A group may hide all but one element, showing them only on mouse hover. In order
|
|||
- *waybar-custom(5)*
|
||||
- *waybar-disk(5)*
|
||||
- *waybar-dwl-tags(5)*
|
||||
- *waybar-dwl-window(5)*
|
||||
- *waybar-gamemode(5)*
|
||||
- *waybar-hyprland-language(5)*
|
||||
- *waybar-hyprland-submap(5)*
|
||||
|
@ -347,3 +349,4 @@ A group may hide all but one element, showing them only on mouse hover. In order
|
|||
# SEE ALSO
|
||||
|
||||
*sway-output(5)*
|
||||
*waybar-styles(5)"
|
||||
|
|
357
meson.build
357
meson.build
|
@ -1,8 +1,8 @@
|
|||
project(
|
||||
'waybar', 'cpp', 'c',
|
||||
version: '0.9.24',
|
||||
version: '0.10.3',
|
||||
license: 'MIT',
|
||||
meson_version: '>= 0.50.0',
|
||||
meson_version: '>= 0.59.0',
|
||||
default_options : [
|
||||
'cpp_std=c++20',
|
||||
'buildtype=release',
|
||||
|
@ -22,8 +22,6 @@ endif
|
|||
|
||||
if compiler.has_link_argument('-lc++fs')
|
||||
cpp_link_args += ['-lc++fs']
|
||||
elif compiler.has_link_argument('-lc++experimental')
|
||||
cpp_link_args += ['-lc++experimental']
|
||||
elif compiler.has_link_argument('-lstdc++fs')
|
||||
cpp_link_args += ['-lstdc++fs']
|
||||
endif
|
||||
|
@ -33,10 +31,10 @@ git = find_program('git', native: true, required: false)
|
|||
if not git.found()
|
||||
add_project_arguments('-DVERSION="@0@"'.format(meson.project_version()), language: 'cpp')
|
||||
else
|
||||
git_path = run_command([git.path(), 'rev-parse', '--show-toplevel']).stdout().strip()
|
||||
if meson.source_root() == git_path
|
||||
git_commit_hash = run_command([git.path(), 'describe', '--always', '--tags']).stdout().strip()
|
||||
git_branch = run_command([git.path(), 'rev-parse', '--abbrev-ref', 'HEAD']).stdout().strip()
|
||||
git_path = run_command(git, 'rev-parse', '--show-toplevel', check: false).stdout().strip()
|
||||
if meson.project_source_root() == git_path
|
||||
git_commit_hash = run_command(git, 'describe', '--always', '--tags', check: false).stdout().strip()
|
||||
git_branch = run_command(git, 'rev-parse', '--abbrev-ref', 'HEAD', check: false).stdout().strip()
|
||||
version = '"@0@ (branch \'@1@\')"'.format(git_commit_hash, git_branch)
|
||||
add_project_arguments('-DVERSION=@0@'.format(version), language: 'cpp')
|
||||
else
|
||||
|
@ -44,15 +42,6 @@ else
|
|||
endif
|
||||
endif
|
||||
|
||||
if not compiler.has_header('filesystem')
|
||||
if compiler.has_header('experimental/filesystem')
|
||||
add_project_arguments('-DFILESYSTEM_EXPERIMENTAL', language: 'cpp')
|
||||
else
|
||||
add_project_arguments('-DNO_FILESYSTEM', language: 'cpp')
|
||||
warning('No filesystem header found, some modules may not work')
|
||||
endif
|
||||
endif
|
||||
|
||||
code = '''
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
|
@ -86,10 +75,7 @@ wayland_cursor = dependency('wayland-cursor')
|
|||
wayland_protos = dependency('wayland-protocols')
|
||||
gtkmm = dependency('gtkmm-3.0', version : ['>=3.22.0'])
|
||||
dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk'))
|
||||
giounix = dependency('gio-unix-2.0', required: (get_option('dbusmenu-gtk').enabled() or
|
||||
get_option('logind').enabled() or
|
||||
get_option('upower_glib').enabled() or
|
||||
get_option('mpris').enabled()))
|
||||
giounix = dependency('gio-unix-2.0')
|
||||
jsoncpp = dependency('jsoncpp', version : ['>=1.9.2'], fallback : ['jsoncpp', 'jsoncpp_dep'])
|
||||
sigcpp = dependency('sigc++-2.0')
|
||||
libinotify = dependency('libinotify', required: false)
|
||||
|
@ -106,7 +92,7 @@ libevdev = dependency('libevdev', required: get_option('libevdev'))
|
|||
libmpdclient = dependency('libmpdclient', required: get_option('mpd'))
|
||||
xkbregistry = dependency('xkbregistry')
|
||||
libjack = dependency('jack', required: get_option('jack'))
|
||||
libwireplumber = dependency('wireplumber-0.4', required: get_option('wireplumber'))
|
||||
libwireplumber = dependency('wireplumber-0.5', required: get_option('wireplumber'))
|
||||
|
||||
libsndio = compiler.find_library('sndio', required: get_option('sndio'))
|
||||
if libsndio.found()
|
||||
|
@ -120,9 +106,9 @@ if libsndio.found()
|
|||
endif
|
||||
endif
|
||||
|
||||
gtk_layer_shell = dependency('gtk-layer-shell-0',
|
||||
required: get_option('gtk-layer-shell'),
|
||||
fallback : ['gtk-layer-shell', 'gtk_layer_shell_dep'])
|
||||
gtk_layer_shell = dependency('gtk-layer-shell-0', version: ['>=0.6.0'],
|
||||
default_options: ['introspection=false', 'vapi=false'],
|
||||
fallback: ['gtk-layer-shell', 'gtk_layer_shell'])
|
||||
systemd = dependency('systemd', required: get_option('systemd'))
|
||||
|
||||
cpp_lib_chrono = compiler.compute_int('__cpp_lib_chrono', prefix : '#include <chrono>')
|
||||
|
@ -157,10 +143,10 @@ sysconfdir = get_option('sysconfdir')
|
|||
conf_data = configuration_data()
|
||||
conf_data.set('prefix', prefix)
|
||||
|
||||
add_project_arguments('-DSYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir)), language : 'cpp')
|
||||
add_project_arguments('-DSYSCONFDIR="@0@"'.format(prefix / sysconfdir), language : 'cpp')
|
||||
|
||||
if systemd.found()
|
||||
user_units_dir = systemd.get_pkgconfig_variable('systemduserunitdir')
|
||||
user_units_dir = systemd.get_variable(pkgconfig: 'systemduserunitdir')
|
||||
|
||||
configure_file(
|
||||
configuration: conf_data,
|
||||
|
@ -196,7 +182,17 @@ src_files = files(
|
|||
'src/util/sanitize_str.cpp',
|
||||
'src/util/rewrite_string.cpp',
|
||||
'src/util/gtk_icon.cpp',
|
||||
'src/util/regex_collection.cpp'
|
||||
'src/util/regex_collection.cpp',
|
||||
'src/util/css_reload_helper.cpp'
|
||||
)
|
||||
|
||||
man_files = files(
|
||||
'man/waybar-custom.5.scd',
|
||||
'man/waybar-disk.5.scd',
|
||||
'man/waybar-idle-inhibitor.5.scd',
|
||||
'man/waybar-image.5.scd',
|
||||
'man/waybar-states.5.scd',
|
||||
'man/waybar-temperature.5.scd',
|
||||
)
|
||||
|
||||
inc_dirs = ['include']
|
||||
|
@ -207,6 +203,7 @@ if is_linux
|
|||
add_project_arguments('-DHAVE_SYSTEMD_MONITOR', language: 'cpp')
|
||||
src_files += files(
|
||||
'src/modules/battery.cpp',
|
||||
'src/modules/bluetooth.cpp',
|
||||
'src/modules/cffi.cpp',
|
||||
'src/modules/cpu.cpp',
|
||||
'src/modules/cpu_frequency/common.cpp',
|
||||
|
@ -215,8 +212,18 @@ if is_linux
|
|||
'src/modules/cpu_usage/linux.cpp',
|
||||
'src/modules/memory/common.cpp',
|
||||
'src/modules/memory/linux.cpp',
|
||||
'src/modules/power_profiles_daemon.cpp',
|
||||
'src/modules/systemd_failed_units.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-battery.5.scd',
|
||||
'man/waybar-bluetooth.5.scd',
|
||||
'man/waybar-cffi.5.scd',
|
||||
'man/waybar-cpu.5.scd',
|
||||
'man/waybar-memory.5.scd',
|
||||
'man/waybar-systemd-failed-units.5.scd',
|
||||
'man/waybar-power-profiles-daemon.5.scd',
|
||||
)
|
||||
elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd
|
||||
add_project_arguments('-DHAVE_CPU_BSD', language: 'cpp')
|
||||
add_project_arguments('-DHAVE_MEMORY_BSD', language: 'cpp')
|
||||
|
@ -230,97 +237,151 @@ elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd
|
|||
'src/modules/memory/bsd.cpp',
|
||||
'src/modules/memory/common.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-cffi.5.scd',
|
||||
'man/waybar-cpu.5.scd',
|
||||
'man/waybar-memory.5.scd',
|
||||
)
|
||||
if is_freebsd
|
||||
src_files += files(
|
||||
'src/modules/battery.cpp',
|
||||
)
|
||||
src_files += files('src/modules/battery.cpp')
|
||||
man_files += files('man/waybar-battery.5.scd')
|
||||
endif
|
||||
endif
|
||||
|
||||
add_project_arguments('-DHAVE_SWAY', language: 'cpp')
|
||||
src_files += [
|
||||
'src/modules/sway/ipc/client.cpp',
|
||||
'src/modules/sway/bar.cpp',
|
||||
'src/modules/sway/mode.cpp',
|
||||
'src/modules/sway/language.cpp',
|
||||
'src/modules/sway/window.cpp',
|
||||
'src/modules/sway/workspaces.cpp',
|
||||
'src/modules/sway/scratchpad.cpp'
|
||||
]
|
||||
if true
|
||||
add_project_arguments('-DHAVE_SWAY', language: 'cpp')
|
||||
src_files += files(
|
||||
'src/modules/sway/ipc/client.cpp',
|
||||
'src/modules/sway/bar.cpp',
|
||||
'src/modules/sway/mode.cpp',
|
||||
'src/modules/sway/language.cpp',
|
||||
'src/modules/sway/window.cpp',
|
||||
'src/modules/sway/workspaces.cpp',
|
||||
'src/modules/sway/scratchpad.cpp'
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-sway-language.5.scd',
|
||||
'man/waybar-sway-mode.5.scd',
|
||||
'man/waybar-sway-scratchpad.5.scd',
|
||||
'man/waybar-sway-window.5.scd',
|
||||
'man/waybar-sway-workspaces.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if true
|
||||
add_project_arguments('-DHAVE_WLR', language: 'cpp')
|
||||
src_files += 'src/modules/wlr/taskbar.cpp'
|
||||
src_files += 'src/modules/wlr/workspace_manager.cpp'
|
||||
src_files += 'src/modules/wlr/workspace_manager_binding.cpp'
|
||||
add_project_arguments('-DHAVE_WLR_TASKBAR', language: 'cpp')
|
||||
src_files += files('src/modules/wlr/taskbar.cpp')
|
||||
man_files += files('man/waybar-wlr-taskbar.5.scd')
|
||||
endif
|
||||
|
||||
if true
|
||||
add_project_arguments('-DHAVE_RIVER', language: 'cpp')
|
||||
src_files += 'src/modules/river/mode.cpp'
|
||||
src_files += 'src/modules/river/tags.cpp'
|
||||
src_files += 'src/modules/river/window.cpp'
|
||||
src_files += 'src/modules/river/layout.cpp'
|
||||
src_files += files(
|
||||
'src/modules/river/layout.cpp',
|
||||
'src/modules/river/mode.cpp',
|
||||
'src/modules/river/tags.cpp',
|
||||
'src/modules/river/window.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-river-layout.5.scd',
|
||||
'man/waybar-river-mode.5.scd',
|
||||
'man/waybar-river-tags.5.scd',
|
||||
'man/waybar-river-window.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if true
|
||||
add_project_arguments('-DHAVE_DWL', language: 'cpp')
|
||||
src_files += 'src/modules/dwl/tags.cpp'
|
||||
src_files += files('src/modules/dwl/tags.cpp')
|
||||
src_files += files('src/modules/dwl/window.cpp')
|
||||
man_files += files('man/waybar-dwl-tags.5.scd')
|
||||
man_files += files('man/waybar-dwl-window.5.scd')
|
||||
endif
|
||||
|
||||
if true
|
||||
add_project_arguments('-DHAVE_HYPRLAND', language: 'cpp')
|
||||
src_files += 'src/modules/hyprland/backend.cpp'
|
||||
src_files += 'src/modules/hyprland/window.cpp'
|
||||
src_files += 'src/modules/hyprland/language.cpp'
|
||||
src_files += 'src/modules/hyprland/submap.cpp'
|
||||
src_files += 'src/modules/hyprland/workspaces.cpp'
|
||||
src_files += files(
|
||||
'src/modules/hyprland/backend.cpp',
|
||||
'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',
|
||||
'man/waybar-hyprland-submap.5.scd',
|
||||
'man/waybar-hyprland-window.5.scd',
|
||||
'man/waybar-hyprland-workspaces.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if libnl.found() and libnlgen.found()
|
||||
add_project_arguments('-DHAVE_LIBNL', language: 'cpp')
|
||||
src_files += 'src/modules/network.cpp'
|
||||
src_files += files('src/modules/network.cpp')
|
||||
man_files += files('man/waybar-network.5.scd')
|
||||
endif
|
||||
|
||||
if (giounix.found() and not get_option('logind').disabled())
|
||||
add_project_arguments('-DHAVE_GAMEMODE', language: 'cpp')
|
||||
src_files += 'src/modules/gamemode.cpp'
|
||||
if not get_option('logind').disabled()
|
||||
add_project_arguments('-DHAVE_GAMEMODE', '-DHAVE_LOGIND_INHIBITOR', language: 'cpp')
|
||||
src_files += files(
|
||||
'src/modules/gamemode.cpp',
|
||||
'src/modules/inhibitor.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-gamemode.5.scd',
|
||||
'man/waybar-inhibitor.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if (upower_glib.found() and giounix.found() and not get_option('logind').disabled())
|
||||
if (upower_glib.found() and not get_option('logind').disabled())
|
||||
add_project_arguments('-DHAVE_UPOWER', language: 'cpp')
|
||||
src_files += 'src/modules/upower/upower.cpp'
|
||||
src_files += 'src/modules/upower/upower_tooltip.cpp'
|
||||
src_files += files('src/modules/upower.cpp')
|
||||
man_files += files('man/waybar-upower.5.scd')
|
||||
endif
|
||||
|
||||
|
||||
if (pipewire.found())
|
||||
if pipewire.found()
|
||||
add_project_arguments('-DHAVE_PIPEWIRE', language: 'cpp')
|
||||
src_files += 'src/modules/privacy/privacy.cpp'
|
||||
src_files += 'src/modules/privacy/privacy_item.cpp'
|
||||
src_files += 'src/util/pipewire_backend.cpp'
|
||||
src_files += files(
|
||||
'src/modules/privacy/privacy.cpp',
|
||||
'src/modules/privacy/privacy_item.cpp',
|
||||
'src/util/pipewire/pipewire_backend.cpp',
|
||||
'src/util/pipewire/privacy_node_info.cpp',
|
||||
)
|
||||
man_files += files('man/waybar-privacy.5.scd')
|
||||
endif
|
||||
|
||||
if (playerctl.found() and giounix.found() and not get_option('logind').disabled())
|
||||
if playerctl.found()
|
||||
add_project_arguments('-DHAVE_MPRIS', language: 'cpp')
|
||||
src_files += 'src/modules/mpris/mpris.cpp'
|
||||
src_files += files('src/modules/mpris/mpris.cpp')
|
||||
man_files += files('man/waybar-mpris.5.scd')
|
||||
endif
|
||||
|
||||
if libpulse.found()
|
||||
add_project_arguments('-DHAVE_LIBPULSE', language: 'cpp')
|
||||
src_files += 'src/modules/pulseaudio.cpp'
|
||||
src_files += 'src/modules/pulseaudio_slider.cpp'
|
||||
src_files += 'src/util/audio_backend.cpp'
|
||||
src_files += files(
|
||||
'src/modules/pulseaudio.cpp',
|
||||
'src/modules/pulseaudio_slider.cpp',
|
||||
'src/util/audio_backend.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-pulseaudio.5.scd',
|
||||
'man/waybar-pulseaudio-slider.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if libjack.found()
|
||||
add_project_arguments('-DHAVE_LIBJACK', language: 'cpp')
|
||||
src_files += 'src/modules/jack.cpp'
|
||||
src_files += files('src/modules/jack.cpp')
|
||||
man_files += files('man/waybar-jack.5.scd')
|
||||
endif
|
||||
|
||||
if libwireplumber.found()
|
||||
add_project_arguments('-DHAVE_LIBWIREPLUMBER', language: 'cpp')
|
||||
src_files += 'src/modules/wireplumber.cpp'
|
||||
src_files += files('src/modules/wireplumber.cpp')
|
||||
man_files += files('man/waybar-wireplumber.5.scd')
|
||||
endif
|
||||
|
||||
if dbusmenu_gtk.found()
|
||||
|
@ -331,40 +392,46 @@ if dbusmenu_gtk.found()
|
|||
'src/modules/sni/host.cpp',
|
||||
'src/modules/sni/item.cpp'
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-tray.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if libudev.found() and (is_linux or libepoll.found())
|
||||
add_project_arguments('-DHAVE_LIBUDEV', language: 'cpp')
|
||||
src_files += 'src/modules/backlight.cpp'
|
||||
src_files += 'src/modules/backlight_slider.cpp'
|
||||
src_files += 'src/util/backlight_backend.cpp'
|
||||
src_files += files(
|
||||
'src/modules/backlight.cpp',
|
||||
'src/modules/backlight_slider.cpp',
|
||||
'src/util/backlight_backend.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-backlight.5.scd',
|
||||
'man/waybar-backlight-slider.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if libevdev.found() and (is_linux or libepoll.found()) and libinput.found() and (is_linux or libinotify.found())
|
||||
add_project_arguments('-DHAVE_LIBEVDEV', language: 'cpp')
|
||||
add_project_arguments('-DHAVE_LIBINPUT', language: 'cpp')
|
||||
src_files += 'src/modules/keyboard_state.cpp'
|
||||
src_files += files('src/modules/keyboard_state.cpp')
|
||||
man_files += files('man/waybar-keyboard-state.5.scd')
|
||||
endif
|
||||
|
||||
if libmpdclient.found()
|
||||
add_project_arguments('-DHAVE_LIBMPDCLIENT', language: 'cpp')
|
||||
src_files += 'src/modules/mpd/mpd.cpp'
|
||||
src_files += 'src/modules/mpd/state.cpp'
|
||||
endif
|
||||
|
||||
if gtk_layer_shell.found()
|
||||
add_project_arguments('-DHAVE_GTK_LAYER_SHELL', language: 'cpp')
|
||||
src_files += files(
|
||||
'src/modules/mpd/mpd.cpp',
|
||||
'src/modules/mpd/state.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-mpd.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
if libsndio.found()
|
||||
add_project_arguments('-DHAVE_LIBSNDIO', language: 'cpp')
|
||||
src_files += 'src/modules/sndio.cpp'
|
||||
endif
|
||||
|
||||
if (giounix.found() and not get_option('logind').disabled())
|
||||
add_project_arguments('-DHAVE_GIO_UNIX', language: 'cpp')
|
||||
src_files += 'src/modules/inhibitor.cpp'
|
||||
src_files += 'src/modules/bluetooth.cpp'
|
||||
src_files += files('src/modules/sndio.cpp')
|
||||
man_files += files('man/waybar-sndio.5.scd')
|
||||
endif
|
||||
|
||||
if get_option('rfkill').enabled() and is_linux
|
||||
|
@ -376,27 +443,38 @@ endif
|
|||
|
||||
if have_chrono_timezones
|
||||
add_project_arguments('-DHAVE_CHRONO_TIMEZONES', language: 'cpp')
|
||||
src_files += 'src/modules/clock.cpp'
|
||||
src_files += files('src/modules/clock.cpp')
|
||||
man_files += files('man/waybar-clock.5.scd')
|
||||
elif tz_dep.found()
|
||||
add_project_arguments('-DHAVE_LIBDATE', language: 'cpp')
|
||||
src_files += 'src/modules/clock.cpp'
|
||||
src_files += files('src/modules/clock.cpp')
|
||||
man_files += files('man/waybar-clock.5.scd')
|
||||
else
|
||||
src_files += 'src/modules/simpleclock.cpp'
|
||||
src_files += files('src/modules/simpleclock.cpp')
|
||||
man_files += files('man/waybar-clock.5.scd')
|
||||
endif
|
||||
|
||||
if get_option('experimental')
|
||||
add_project_arguments('-DUSE_EXPERIMENTAL', language: 'cpp')
|
||||
add_project_arguments('-DHAVE_WLR_WORKSPACES', language: 'cpp')
|
||||
src_files += files(
|
||||
'src/modules/wlr/workspace_manager.cpp',
|
||||
'src/modules/wlr/workspace_manager_binding.cpp',
|
||||
)
|
||||
man_files += files(
|
||||
'man/waybar-wlr-workspaces.5.scd',
|
||||
)
|
||||
endif
|
||||
|
||||
cava = dependency('cava',
|
||||
version : '>=0.9.1',
|
||||
version : '>=0.10.2',
|
||||
required: get_option('cava'),
|
||||
fallback : ['cava', 'cava_dep'],
|
||||
not_found_message: 'cava is not found. Building waybar without cava')
|
||||
|
||||
if cava.found()
|
||||
add_project_arguments('-DHAVE_LIBCAVA', language: 'cpp')
|
||||
src_files += 'src/modules/cava.cpp'
|
||||
src_files += files('src/modules/cava.cpp')
|
||||
man_files += files('man/waybar-cava.5.scd')
|
||||
endif
|
||||
|
||||
subdir('protocol')
|
||||
|
@ -444,79 +522,34 @@ executable(
|
|||
)
|
||||
|
||||
install_data(
|
||||
'./resources/config',
|
||||
'./resources/style.css',
|
||||
install_dir: sysconfdir + '/xdg/waybar'
|
||||
'resources/config.jsonc',
|
||||
'resources/style.css',
|
||||
install_dir: sysconfdir / 'xdg/waybar'
|
||||
)
|
||||
|
||||
scdoc = dependency('scdoc', version: '>=1.9.2', native: true, required: get_option('man-pages'))
|
||||
|
||||
if scdoc.found()
|
||||
scdoc_prog = find_program(scdoc.get_pkgconfig_variable('scdoc'), native: true)
|
||||
sh = find_program('sh', native: true)
|
||||
|
||||
main_manpage = configure_file(
|
||||
man_files += configure_file(
|
||||
input: 'man/waybar.5.scd.in',
|
||||
output: 'waybar.5.scd',
|
||||
configuration: {
|
||||
'sysconfdir': join_paths(prefix, sysconfdir)
|
||||
'sysconfdir': prefix / sysconfdir
|
||||
}
|
||||
)
|
||||
|
||||
main_manpage_path = join_paths(meson.build_root(), '@0@'.format(main_manpage))
|
||||
man_files += configure_file(
|
||||
input: 'man/waybar-styles.5.scd.in',
|
||||
output: 'waybar-styles.5.scd',
|
||||
configuration: {
|
||||
'sysconfdir': prefix / sysconfdir
|
||||
}
|
||||
)
|
||||
|
||||
fs = import('fs')
|
||||
mandir = get_option('mandir')
|
||||
man_files = [
|
||||
main_manpage_path,
|
||||
'waybar-backlight.5.scd',
|
||||
'waybar-backlight-slider.5.scd',
|
||||
'waybar-battery.5.scd',
|
||||
'waybar-cava.5.scd',
|
||||
'waybar-cffi.5.scd',
|
||||
'waybar-clock.5.scd',
|
||||
'waybar-cpu.5.scd',
|
||||
'waybar-custom.5.scd',
|
||||
'waybar-disk.5.scd',
|
||||
'waybar-gamemode.5.scd',
|
||||
'waybar-idle-inhibitor.5.scd',
|
||||
'waybar-image.5.scd',
|
||||
'waybar-keyboard-state.5.scd',
|
||||
'waybar-memory.5.scd',
|
||||
'waybar-mpd.5.scd',
|
||||
'waybar-mpris.5.scd',
|
||||
'waybar-network.5.scd',
|
||||
'waybar-pulseaudio.5.scd',
|
||||
'waybar-pulseaudio-slider.5.scd',
|
||||
'waybar-privacy.5.scd',
|
||||
'waybar-river-mode.5.scd',
|
||||
'waybar-river-tags.5.scd',
|
||||
'waybar-river-window.5.scd',
|
||||
'waybar-river-layout.5.scd',
|
||||
'waybar-sway-language.5.scd',
|
||||
'waybar-sway-mode.5.scd',
|
||||
'waybar-sway-scratchpad.5.scd',
|
||||
'waybar-sway-window.5.scd',
|
||||
'waybar-sway-workspaces.5.scd',
|
||||
'waybar-systemd-failed-units.5.scd',
|
||||
'waybar-temperature.5.scd',
|
||||
'waybar-tray.5.scd',
|
||||
'waybar-states.5.scd',
|
||||
'waybar-wlr-taskbar.5.scd',
|
||||
'waybar-wlr-workspaces.5.scd',
|
||||
'waybar-bluetooth.5.scd',
|
||||
'waybar-sndio.5.scd',
|
||||
'waybar-upower.5.scd',
|
||||
'waybar-wireplumber.5.scd',
|
||||
'waybar-dwl-tags.5.scd',
|
||||
]
|
||||
|
||||
if (giounix.found() and not get_option('logind').disabled())
|
||||
man_files += 'waybar-inhibitor.5.scd'
|
||||
endif
|
||||
|
||||
foreach file : man_files
|
||||
path = '@0@'.format(file)
|
||||
basename = path.split('/')[-1]
|
||||
basename = fs.name(file)
|
||||
|
||||
topic = basename.split('.')[-3]
|
||||
section = basename.split('.')[-2]
|
||||
|
@ -524,12 +557,11 @@ if scdoc.found()
|
|||
|
||||
custom_target(
|
||||
output,
|
||||
# drops the 'man' if `path` is an absolute path
|
||||
input: join_paths('man', path),
|
||||
input: file,
|
||||
output: output,
|
||||
command: [
|
||||
sh, '-c', '@0@ < @INPUT@ > @1@'.format(scdoc_prog.path(), output)
|
||||
],
|
||||
command: scdoc.get_variable('scdoc'),
|
||||
feed: true,
|
||||
capture: true,
|
||||
install: true,
|
||||
install_dir: '@0@/man@1@'.format(mandir, section)
|
||||
)
|
||||
|
@ -538,7 +570,7 @@ endif
|
|||
|
||||
catch2 = dependency(
|
||||
'catch2',
|
||||
version: '>=3.5.1',
|
||||
default_options: [ 'tests=false' ],
|
||||
fallback: ['catch2', 'catch2_dep'],
|
||||
required: get_option('tests'),
|
||||
)
|
||||
|
@ -554,7 +586,6 @@ if clangtidy.found()
|
|||
command: [
|
||||
clangtidy,
|
||||
'-checks=*,-fuchsia-default-arguments',
|
||||
'-p', meson.build_root()
|
||||
'-p', meson.project_build_root()
|
||||
] + src_files)
|
||||
endif
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ option('systemd', type: 'feature', value: 'auto', description: 'Install systemd
|
|||
option('dbusmenu-gtk', type: 'feature', value: 'auto', description: 'Enable support for tray')
|
||||
option('man-pages', type: 'feature', value: 'auto', description: 'Generate and install man pages')
|
||||
option('mpd', type: 'feature', value: 'auto', description: 'Enable support for the Music Player Daemon')
|
||||
option('gtk-layer-shell', type: 'feature', value: 'auto', description: 'Use gtk-layer-shell library for popups support')
|
||||
option('rfkill', type: 'feature', value: 'auto', description: 'Enable support for RFKILL')
|
||||
option('sndio', type: 'feature', value: 'auto', description: 'Enable support for sndio')
|
||||
option('logind', type: 'feature', value: 'auto', description: 'Enable support for logind')
|
||||
|
|
|
@ -4,27 +4,36 @@
|
|||
, version
|
||||
}:
|
||||
let
|
||||
catch2_3 = {
|
||||
src = pkgs.fetchFromGitHub
|
||||
{
|
||||
owner = "catchorg";
|
||||
repo = "Catch2";
|
||||
rev = "v3.5.1";
|
||||
hash = "sha256-OyYNUfnu6h1+MfCF8O+awQ4Usad0qrdCtdZhYgOY+Vw=";
|
||||
};
|
||||
libcava = rec {
|
||||
version = "0.10.2";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "LukashonakV";
|
||||
repo = "cava";
|
||||
rev = version;
|
||||
hash = "sha256-jU7RQV2txruu/nUUl0TzjK4nai7G38J1rcTjO7UXumY=";
|
||||
};
|
||||
};
|
||||
in
|
||||
(waybar.overrideAttrs (oldAttrs: rec {
|
||||
inherit version;
|
||||
(waybar.overrideAttrs (
|
||||
oldAttrs: {
|
||||
inherit version;
|
||||
|
||||
src = lib.cleanSourceWith {
|
||||
filter = name: type: type != "regular" || !lib.hasSuffix ".nix" name;
|
||||
src = lib.cleanSource ../.;
|
||||
};
|
||||
})
|
||||
).override {
|
||||
catch2_3 = pkgs.catch2_3.overrideAttrs (oldAttrs: {
|
||||
version = "3.5.1";
|
||||
src = catch2_3.src;
|
||||
});
|
||||
}
|
||||
src = lib.cleanSourceWith {
|
||||
filter = name: type: type != "regular" || !lib.hasSuffix ".nix" name;
|
||||
src = lib.cleanSource ../.;
|
||||
};
|
||||
|
||||
mesonFlags = lib.remove "-Dgtk-layer-shell=enabled" oldAttrs.mesonFlags;
|
||||
|
||||
buildInputs = (builtins.filter (p: p.pname != "wireplumber") oldAttrs.buildInputs) ++ [
|
||||
pkgs.wireplumber
|
||||
];
|
||||
|
||||
postUnpack = ''
|
||||
pushd "$sourceRoot"
|
||||
cp -R --no-preserve=mode,ownership ${libcava.src} subprojects/cava-${libcava.version}
|
||||
patchShebangs .
|
||||
popd
|
||||
'';
|
||||
}
|
||||
))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
wl_protocol_dir = wayland_protos.get_pkgconfig_variable('pkgdatadir')
|
||||
wl_protocol_dir = wayland_protos.get_variable(pkgconfig: 'pkgdatadir')
|
||||
|
||||
wayland_scanner = find_program('wayland-scanner')
|
||||
|
||||
|
@ -25,7 +25,6 @@ client_protocols = [
|
|||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'],
|
||||
['wlr-layer-shell-unstable-v1.xml'],
|
||||
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
||||
['ext-workspace-unstable-v1.xml'],
|
||||
['river-status-unstable-v1.xml'],
|
||||
|
@ -44,7 +43,7 @@ endforeach
|
|||
|
||||
gdbus_codegen = find_program('gdbus-codegen')
|
||||
|
||||
r = run_command(gdbus_codegen, '--body', '--output', '/dev/null')
|
||||
r = run_command(gdbus_codegen, '--body', '--output', '/dev/null', check: false)
|
||||
if r.returncode() != 0
|
||||
gdbus_code_dsnw = custom_target(
|
||||
'dbus-status-notifier-watcher.[ch]',
|
||||
|
|
|
@ -1,311 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_layer_shell_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2017 Drew DeVault
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation, and that the name of
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwlr_layer_shell_v1" version="3">
|
||||
<description summary="create surfaces that are layers of the desktop">
|
||||
Clients can use this interface to assign the surface_layer role to
|
||||
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
rendered with a defined z-depth respective to each other. They may also be
|
||||
anchored to the edges and corners of a screen and specify input handling
|
||||
semantics. This interface should be suitable for the implementation of
|
||||
many desktop shell components, and a broad number of other applications
|
||||
that interact with the desktop.
|
||||
</description>
|
||||
|
||||
<request name="get_layer_surface">
|
||||
<description summary="create a layer_surface from a surface">
|
||||
Create a layer surface for an existing surface. This assigns the role of
|
||||
layer_surface, or raises a protocol error if another role is already
|
||||
assigned.
|
||||
|
||||
Creating a layer surface from a wl_surface which has a buffer attached
|
||||
or committed is a client error, and any attempts by a client to attach
|
||||
or manipulate a buffer prior to the first layer_surface.configure call
|
||||
must also be treated as errors.
|
||||
|
||||
You may pass NULL for output to allow the compositor to decide which
|
||||
output to use. Generally this will be the one that the user most
|
||||
recently interacted with.
|
||||
|
||||
Clients can specify a namespace that defines the purpose of the layer
|
||||
surface.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||
<arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/>
|
||||
<arg name="np" type="string" summary="namespace for the layer surface"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="role" value="0" summary="wl_surface has another role"/>
|
||||
<entry name="invalid_layer" value="1" summary="layer value is invalid"/>
|
||||
<entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/>
|
||||
</enum>
|
||||
|
||||
<enum name="layer">
|
||||
<description summary="available layers for surfaces">
|
||||
These values indicate which layers a surface can be rendered in. They
|
||||
are ordered by z depth, bottom-most first. Traditional shell surfaces
|
||||
will typically be rendered between the bottom and top layers.
|
||||
Fullscreen shell surfaces are typically rendered at the top layer.
|
||||
Multiple surfaces can share a single layer, and ordering within a
|
||||
single layer is undefined.
|
||||
</description>
|
||||
|
||||
<entry name="background" value="0"/>
|
||||
<entry name="bottom" value="1"/>
|
||||
<entry name="top" value="2"/>
|
||||
<entry name="overlay" value="3"/>
|
||||
</enum>
|
||||
|
||||
<!-- Version 3 additions -->
|
||||
|
||||
<request name="destroy" type="destructor" since="3">
|
||||
<description summary="destroy the layer_shell object">
|
||||
This request indicates that the client will not use the layer_shell
|
||||
object any more. Objects that have been created through this instance
|
||||
are not affected.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_layer_surface_v1" version="3">
|
||||
<description summary="layer metadata interface">
|
||||
An interface that may be implemented by a wl_surface, for surfaces that
|
||||
are designed to be rendered as a layer of a stacked desktop-like
|
||||
environment.
|
||||
|
||||
Layer surface state (layer, size, anchor, exclusive zone,
|
||||
margin, interactivity) is double-buffered, and will be applied at the
|
||||
time wl_surface.commit of the corresponding wl_surface is called.
|
||||
</description>
|
||||
|
||||
<request name="set_size">
|
||||
<description summary="sets the size of the surface">
|
||||
Sets the size of the surface in surface-local coordinates. The
|
||||
compositor will display the surface centered with respect to its
|
||||
anchors.
|
||||
|
||||
If you pass 0 for either value, the compositor will assign it and
|
||||
inform you of the assignment in the configure event. You must set your
|
||||
anchor to opposite edges in the dimensions you omit; not doing so is a
|
||||
protocol error. Both values are 0 by default.
|
||||
|
||||
Size is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="height" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="set_anchor">
|
||||
<description summary="configures the anchor point of the surface">
|
||||
Requests that the compositor anchor the surface to the specified edges
|
||||
and corners. If two orthogonal edges are specified (e.g. 'top' and
|
||||
'left'), then the anchor point will be the intersection of the edges
|
||||
(e.g. the top left corner of the output); otherwise the anchor point
|
||||
will be centered on that edge, or in the center if none is specified.
|
||||
|
||||
Anchor is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="anchor" type="uint" enum="anchor"/>
|
||||
</request>
|
||||
|
||||
<request name="set_exclusive_zone">
|
||||
<description summary="configures the exclusive geometry of this surface">
|
||||
Requests that the compositor avoids occluding an area with other
|
||||
surfaces. The compositor's use of this information is
|
||||
implementation-dependent - do not assume that this region will not
|
||||
actually be occluded.
|
||||
|
||||
A positive value is only meaningful if the surface is anchored to one
|
||||
edge or an edge and both perpendicular edges. If the surface is not
|
||||
anchored, anchored to only two perpendicular edges (a corner), anchored
|
||||
to only two parallel edges or anchored to all edges, a positive value
|
||||
will be treated the same as zero.
|
||||
|
||||
A positive zone is the distance from the edge in surface-local
|
||||
coordinates to consider exclusive.
|
||||
|
||||
Surfaces that do not wish to have an exclusive zone may instead specify
|
||||
how they should interact with surfaces that do. If set to zero, the
|
||||
surface indicates that it would like to be moved to avoid occluding
|
||||
surfaces with a positive exclusive zone. If set to -1, the surface
|
||||
indicates that it would not like to be moved to accommodate for other
|
||||
surfaces, and the compositor should extend it all the way to the edges
|
||||
it is anchored to.
|
||||
|
||||
For example, a panel might set its exclusive zone to 10, so that
|
||||
maximized shell surfaces are not shown on top of it. A notification
|
||||
might set its exclusive zone to 0, so that it is moved to avoid
|
||||
occluding the panel, but shell surfaces are shown underneath it. A
|
||||
wallpaper or lock screen might set their exclusive zone to -1, so that
|
||||
they stretch below or over the panel.
|
||||
|
||||
The default value is 0.
|
||||
|
||||
Exclusive zone is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="zone" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_margin">
|
||||
<description summary="sets a margin from the anchor point">
|
||||
Requests that the surface be placed some distance away from the anchor
|
||||
point on the output, in surface-local coordinates. Setting this value
|
||||
for edges you are not anchored to has no effect.
|
||||
|
||||
The exclusive zone includes the margin.
|
||||
|
||||
Margin is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="top" type="int"/>
|
||||
<arg name="right" type="int"/>
|
||||
<arg name="bottom" type="int"/>
|
||||
<arg name="left" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_keyboard_interactivity">
|
||||
<description summary="requests keyboard events">
|
||||
Set to 1 to request that the seat send keyboard events to this layer
|
||||
surface. For layers below the shell surface layer, the seat will use
|
||||
normal focus semantics. For layers above the shell surface layers, the
|
||||
seat will always give exclusive keyboard focus to the top-most layer
|
||||
which has keyboard interactivity set to true.
|
||||
|
||||
Layer surfaces receive pointer, touch, and tablet events normally. If
|
||||
you do not want to receive them, set the input region on your surface
|
||||
to an empty region.
|
||||
|
||||
Events is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="keyboard_interactivity" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="get_popup">
|
||||
<description summary="assign this layer_surface as an xdg_popup parent">
|
||||
This assigns an xdg_popup's parent to this layer_surface. This popup
|
||||
should have been created via xdg_surface::get_popup with the parent set
|
||||
to NULL, and this request must be invoked before committing the popup's
|
||||
initial state.
|
||||
|
||||
See the documentation of xdg_popup for more details about what an
|
||||
xdg_popup is and how it is used.
|
||||
</description>
|
||||
<arg name="popup" type="object" interface="xdg_popup"/>
|
||||
</request>
|
||||
|
||||
<request name="ack_configure">
|
||||
<description summary="ack a configure event">
|
||||
When a configure event is received, if a client commits the
|
||||
surface in response to the configure event, then the client
|
||||
must make an ack_configure request sometime before the commit
|
||||
request, passing along the serial of the configure event.
|
||||
|
||||
If the client receives multiple configure events before it
|
||||
can respond to one, it only has to ack the last configure event.
|
||||
|
||||
A client is not required to commit immediately after sending
|
||||
an ack_configure request - it may even ack_configure several times
|
||||
before its next surface commit.
|
||||
|
||||
A client may send multiple ack_configure requests before committing, but
|
||||
only the last request sent before a commit indicates which configure
|
||||
event the client really is responding to.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="the serial from the configure event"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the layer_surface">
|
||||
This request destroys the layer surface.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="configure">
|
||||
<description summary="suggest a surface change">
|
||||
The configure event asks the client to resize its surface.
|
||||
|
||||
Clients should arrange their surface for the new states, and then send
|
||||
an ack_configure request with the serial sent in this configure event at
|
||||
some point before committing the new surface.
|
||||
|
||||
The client is free to dismiss all but the last configure event it
|
||||
received.
|
||||
|
||||
The width and height arguments specify the size of the window in
|
||||
surface-local coordinates.
|
||||
|
||||
The size is a hint, in the sense that the client is free to ignore it if
|
||||
it doesn't resize, pick a smaller size (to satisfy aspect ratio or
|
||||
resize in steps of NxM pixels). If the client picks a smaller size and
|
||||
is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the
|
||||
surface will be centered on this axis.
|
||||
|
||||
If the width or height arguments are zero, it means the client should
|
||||
decide its own window dimension.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="height" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="closed">
|
||||
<description summary="surface should be closed">
|
||||
The closed event is sent by the compositor when the surface will no
|
||||
longer be shown. The output may have been destroyed or the user may
|
||||
have asked for it to be removed. Further changes to the surface will be
|
||||
ignored. The client should destroy the resource after receiving this
|
||||
event, and create a new surface if they so choose.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
|
||||
<entry name="invalid_size" value="1" summary="size is invalid"/>
|
||||
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
|
||||
</enum>
|
||||
|
||||
<enum name="anchor" bitfield="true">
|
||||
<entry name="top" value="1" summary="the top edge of the anchor rectangle"/>
|
||||
<entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/>
|
||||
<entry name="left" value="4" summary="the left edge of the anchor rectangle"/>
|
||||
<entry name="right" value="8" summary="the right edge of the anchor rectangle"/>
|
||||
</enum>
|
||||
|
||||
<!-- Version 2 additions -->
|
||||
|
||||
<request name="set_layer" since="2">
|
||||
<description summary="change the layer of the surface">
|
||||
Change the layer that the surface is rendered on.
|
||||
|
||||
Layer is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
|
@ -1,3 +1,4 @@
|
|||
// -*- mode: jsonc -*-
|
||||
{
|
||||
// "layer": "top", // Waybar at top layer
|
||||
// "position": "bottom", // Waybar position (top|bottom|left|right)
|
||||
|
@ -5,9 +6,32 @@
|
|||
// "width": 1280, // Waybar width
|
||||
"spacing": 4, // Gaps between modules (4px)
|
||||
// Choose the order of the modules
|
||||
"modules-left": ["sway/workspaces", "sway/mode", "sway/scratchpad", "custom/media"],
|
||||
"modules-center": ["sway/window"],
|
||||
"modules-right": ["mpd", "idle_inhibitor", "pulseaudio", "network", "cpu", "memory", "temperature", "backlight", "keyboard-state", "sway/language", "battery", "battery#bat2", "clock", "tray"],
|
||||
"modules-left": [
|
||||
"sway/workspaces",
|
||||
"sway/mode",
|
||||
"sway/scratchpad",
|
||||
"custom/media"
|
||||
],
|
||||
"modules-center": [
|
||||
"sway/window"
|
||||
],
|
||||
"modules-right": [
|
||||
"mpd",
|
||||
"idle_inhibitor",
|
||||
"pulseaudio",
|
||||
"network",
|
||||
"power-profiles-daemon",
|
||||
"cpu",
|
||||
"memory",
|
||||
"temperature",
|
||||
"backlight",
|
||||
"keyboard-state",
|
||||
"sway/language",
|
||||
"battery",
|
||||
"battery#bat2",
|
||||
"clock",
|
||||
"tray"
|
||||
],
|
||||
// Modules configuration
|
||||
// "sway/workspaces": {
|
||||
// "disable-scroll": true,
|
||||
|
@ -49,7 +73,7 @@
|
|||
"format-disconnected": "Disconnected ",
|
||||
"format-stopped": "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ",
|
||||
"unknown-tag": "N/A",
|
||||
"interval": 2,
|
||||
"interval": 5,
|
||||
"consume-icons": {
|
||||
"on": " "
|
||||
},
|
||||
|
@ -113,6 +137,7 @@
|
|||
"critical": 15
|
||||
},
|
||||
"format": "{capacity}% {icon}",
|
||||
"format-full": "{capacity}% {icon}",
|
||||
"format-charging": "{capacity}% ",
|
||||
"format-plugged": "{capacity}% ",
|
||||
"format-alt": "{time} {icon}",
|
||||
|
@ -123,6 +148,17 @@
|
|||
"battery#bat2": {
|
||||
"bat": "BAT2"
|
||||
},
|
||||
"power-profiles-daemon": {
|
||||
"format": "{icon}",
|
||||
"tooltip-format": "Power profile: {profile}\nDriver: {driver}",
|
||||
"tooltip": true,
|
||||
"format-icons": {
|
||||
"default": "",
|
||||
"performance": "",
|
||||
"balanced": "",
|
||||
"power-saver": ""
|
||||
}
|
||||
},
|
||||
"network": {
|
||||
// "interface": "wlp2*", // (Optional) To force the use of this interface
|
||||
"format-wifi": "{essid} ({signalStrength}%) ",
|
||||
|
@ -164,4 +200,3 @@
|
|||
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ def signal_handler(sig, frame):
|
|||
|
||||
|
||||
class PlayerManager:
|
||||
def __init__(self, selected_player=None):
|
||||
def __init__(self, selected_player=None, excluded_player=[]):
|
||||
self.manager = Playerctl.PlayerManager()
|
||||
self.loop = GLib.MainLoop()
|
||||
self.manager.connect(
|
||||
|
@ -35,11 +35,14 @@ class PlayerManager:
|
|||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||
self.selected_player = selected_player
|
||||
self.excluded_player = excluded_player.split(',') if excluded_player else []
|
||||
|
||||
self.init_players()
|
||||
|
||||
def init_players(self):
|
||||
for player in self.manager.props.player_names:
|
||||
if player.name in self.excluded_player:
|
||||
continue
|
||||
if self.selected_player is not None and self.selected_player != player.name:
|
||||
logger.debug(f"{player.name} is not the filtered player, skipping it")
|
||||
continue
|
||||
|
@ -133,6 +136,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:
|
||||
|
@ -149,6 +156,8 @@ def parse_arguments():
|
|||
# Increase verbosity with every occurrence of -v
|
||||
parser.add_argument("-v", "--verbose", action="count", default=0)
|
||||
|
||||
parser.add_argument("-x", "--exclude", "- Comma-separated list of excluded player")
|
||||
|
||||
# Define for which player we"re listening
|
||||
parser.add_argument("--player")
|
||||
|
||||
|
@ -174,7 +183,10 @@ def main():
|
|||
logger.info("Creating player manager")
|
||||
if arguments.player:
|
||||
logger.info(f"Filtering for player: {arguments.player}")
|
||||
player = PlayerManager(arguments.player)
|
||||
if arguments.exclude:
|
||||
logger.info(f"Exclude player {arguments.exclude}")
|
||||
|
||||
player = PlayerManager(arguments.player, arguments.exclude)
|
||||
player.run()
|
||||
|
||||
|
||||
|
|
|
@ -48,6 +48,11 @@ button:hover {
|
|||
box-shadow: inset 0 -3px #ffffff;
|
||||
}
|
||||
|
||||
/* you can set a style on hover for any module like this */
|
||||
#pulseaudio:hover {
|
||||
background-color: #a37800;
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
padding: 0 5px;
|
||||
background-color: transparent;
|
||||
|
@ -69,7 +74,7 @@ button:hover {
|
|||
|
||||
#mode {
|
||||
background-color: #64727D;
|
||||
border-bottom: 3px solid #ffffff;
|
||||
box-shadow: inset 0 -3px #ffffff;
|
||||
}
|
||||
|
||||
#clock,
|
||||
|
@ -87,6 +92,7 @@ button:hover {
|
|||
#mode,
|
||||
#idle_inhibitor,
|
||||
#scratchpad,
|
||||
#power-profiles-daemon,
|
||||
#mpd {
|
||||
padding: 0 10px;
|
||||
color: #ffffff;
|
||||
|
@ -128,16 +134,36 @@ button:hover {
|
|||
}
|
||||
}
|
||||
|
||||
/* Using steps() instead of linear as a timing function to limit cpu usage */
|
||||
#battery.critical:not(.charging) {
|
||||
background-color: #f53c3c;
|
||||
color: #ffffff;
|
||||
animation-name: blink;
|
||||
animation-duration: 0.5s;
|
||||
animation-timing-function: linear;
|
||||
animation-timing-function: steps(12);
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
#power-profiles-daemon {
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
#power-profiles-daemon.performance {
|
||||
background-color: #f53c3c;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#power-profiles-daemon.balanced {
|
||||
background-color: #2980b9;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#power-profiles-daemon.power-saver {
|
||||
background-color: #2ecc71;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
label:focus {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
|
|
@ -24,18 +24,61 @@ AAppIconLabel::AAppIconLabel(const Json::Value& config, const std::string& name,
|
|||
image_.set_pixel_size(app_icon_size_);
|
||||
}
|
||||
|
||||
std::string toLowerCase(const std::string& input) {
|
||||
std::string result = input;
|
||||
std::transform(result.begin(), result.end(), result.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<std::string> getFileBySuffix(const std::string& dir, const std::string& suffix,
|
||||
bool check_lower_case) {
|
||||
if (!std::filesystem::exists(dir)) {
|
||||
return {};
|
||||
}
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(dir)) {
|
||||
if (entry.is_regular_file()) {
|
||||
std::string filename = entry.path().filename().string();
|
||||
if (filename.size() < suffix.size()) {
|
||||
continue;
|
||||
}
|
||||
if ((filename.compare(filename.size() - suffix.size(), suffix.size(), suffix) == 0) ||
|
||||
(check_lower_case && filename.compare(filename.size() - suffix.size(), suffix.size(),
|
||||
toLowerCase(suffix)) == 0)) {
|
||||
return entry.path().string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::string> getFileBySuffix(const std::string& dir, const std::string& suffix) {
|
||||
return getFileBySuffix(dir, suffix, false);
|
||||
}
|
||||
|
||||
std::optional<std::string> getDesktopFilePath(const std::string& app_identifier,
|
||||
const std::string& alternative_app_identifier) {
|
||||
if (app_identifier.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto data_dirs = Glib::get_system_data_dirs();
|
||||
for (const auto& data_dir : data_dirs) {
|
||||
const auto data_app_dir = data_dir + "applications/";
|
||||
auto desktop_file_path = data_app_dir + app_identifier + ".desktop";
|
||||
if (std::filesystem::exists(desktop_file_path)) {
|
||||
const auto data_app_dir = data_dir + "/applications/";
|
||||
auto desktop_file_suffix = app_identifier + ".desktop";
|
||||
// searching for file by suffix catches cases like terminal emulator "foot" where class is
|
||||
// "footclient" and desktop file is named "org.codeberg.dnkl.footclient.desktop"
|
||||
auto desktop_file_path = getFileBySuffix(data_app_dir, desktop_file_suffix, true);
|
||||
// "true" argument allows checking for lowercase - this catches cases where class name is
|
||||
// "LibreWolf" and desktop file is named "librewolf.desktop"
|
||||
if (desktop_file_path.has_value()) {
|
||||
return desktop_file_path;
|
||||
}
|
||||
if (!alternative_app_identifier.empty()) {
|
||||
desktop_file_path = data_app_dir + alternative_app_identifier + ".desktop";
|
||||
if (std::filesystem::exists(desktop_file_path)) {
|
||||
desktop_file_suffix = alternative_app_identifier + ".desktop";
|
||||
desktop_file_path = getFileBySuffix(data_app_dir, desktop_file_suffix, true);
|
||||
if (desktop_file_path.has_value()) {
|
||||
return desktop_file_path;
|
||||
}
|
||||
}
|
||||
|
@ -58,16 +101,9 @@ std::optional<Glib::ustring> getIconName(const std::string& app_identifier,
|
|||
return app_identifier_desktop;
|
||||
}
|
||||
|
||||
const auto to_lower = [](const std::string& str) {
|
||||
auto str_cpy = str;
|
||||
std::transform(str_cpy.begin(), str_cpy.end(), str_cpy.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
return str;
|
||||
};
|
||||
|
||||
const auto first_space = app_identifier.find_first_of(' ');
|
||||
if (first_space != std::string::npos) {
|
||||
const auto first_word = to_lower(app_identifier.substr(0, first_space));
|
||||
const auto first_word = toLowerCase(app_identifier.substr(0, first_space));
|
||||
if (DefaultGtkIconThemeWrapper::has_icon(first_word)) {
|
||||
return first_word;
|
||||
}
|
||||
|
@ -75,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 = to_lower(app_identifier.substr(0, first_dash));
|
||||
const auto first_word = toLowerCase(app_identifier.substr(0, first_dash));
|
||||
if (DefaultGtkIconThemeWrapper::has_icon(first_word)) {
|
||||
return first_word;
|
||||
}
|
||||
|
|
|
@ -9,10 +9,23 @@ AIconLabel::AIconLabel(const Json::Value &config, const std::string &name, const
|
|||
bool enable_click, bool enable_scroll)
|
||||
: ALabel(config, name, id, format, interval, ellipsize, enable_click, enable_scroll) {
|
||||
event_box_.remove();
|
||||
label_.unset_name();
|
||||
label_.get_style_context()->remove_class(MODULE_CLASS);
|
||||
box_.get_style_context()->add_class(MODULE_CLASS);
|
||||
if (!id.empty()) {
|
||||
label_.get_style_context()->remove_class(id);
|
||||
box_.get_style_context()->add_class(id);
|
||||
}
|
||||
|
||||
box_.set_orientation(Gtk::Orientation::ORIENTATION_HORIZONTAL);
|
||||
box_.set_spacing(8);
|
||||
box_.set_name(name);
|
||||
|
||||
int spacing = config_["icon-spacing"].isInt() ? config_["icon-spacing"].asInt() : 8;
|
||||
box_.set_spacing(spacing);
|
||||
|
||||
box_.add(image_);
|
||||
box_.add(label_);
|
||||
|
||||
event_box_.add(box_);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
|
|||
if (!id.empty()) {
|
||||
label_.get_style_context()->add_class(id);
|
||||
}
|
||||
label_.get_style_context()->add_class(MODULE_CLASS);
|
||||
event_box_.add(label_);
|
||||
if (config_["max-length"].isUInt()) {
|
||||
label_.set_max_width_chars(config_["max-length"].asInt());
|
||||
|
@ -49,6 +50,17 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st
|
|||
label_.set_xalign(align);
|
||||
}
|
||||
}
|
||||
|
||||
if (config_["justify"].isString()) {
|
||||
auto justify_str = config_["justify"].asString();
|
||||
if (justify_str == "left") {
|
||||
label_.set_justify(Gtk::Justification::JUSTIFY_LEFT);
|
||||
} else if (justify_str == "right") {
|
||||
label_.set_justify(Gtk::Justification::JUSTIFY_RIGHT);
|
||||
} else if (justify_str == "center") {
|
||||
label_.set_justify(Gtk::Justification::JUSTIFY_CENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto ALabel::update() -> void { AModule::update(); }
|
||||
|
|
|
@ -15,6 +15,7 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
|
|||
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) {
|
||||
|
@ -27,18 +28,24 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
|
|||
spdlog::warn("Wrong actions section configuration. See config by index: {}", it.index());
|
||||
}
|
||||
|
||||
event_box_.signal_enter_notify_event().connect(sigc::mem_fun(*this, &AModule::handleMouseEnter));
|
||||
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 =
|
||||
|
@ -51,7 +58,9 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std::
|
|||
event_box_.add_events(Gdk::BUTTON_RELEASE_MASK);
|
||||
event_box_.signal_button_release_event().connect(sigc::mem_fun(*this, &AModule::handleRelease));
|
||||
}
|
||||
if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString() || enable_scroll) {
|
||||
if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString() ||
|
||||
config_["on-scroll-left"].isString() || config_["on-scroll-right"].isString() ||
|
||||
enable_scroll) {
|
||||
event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK);
|
||||
event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &AModule::handleScroll));
|
||||
}
|
||||
|
@ -81,6 +90,34 @@ auto AModule::doAction(const std::string& name) -> void {
|
|||
}
|
||||
}
|
||||
|
||||
void AModule::setCursor(Gdk::CursorType c) {
|
||||
auto cursor = Gdk::Cursor::create(c);
|
||||
auto gdk_window = event_box_.get_window();
|
||||
gdk_window->set_cursor(cursor);
|
||||
}
|
||||
|
||||
bool AModule::handleMouseEnter(GdkEventCrossing* const& e) {
|
||||
if (auto* module = event_box_.get_child(); module != nullptr) {
|
||||
module->set_state_flags(Gtk::StateFlags::STATE_FLAG_PRELIGHT);
|
||||
}
|
||||
|
||||
if (hasUserEvents_) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (hasUserEvents_) {
|
||||
setCursor(Gdk::ARROW);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AModule::handleToggle(GdkEventButton* const& e) { return handleUserEvent(e); }
|
||||
|
||||
bool AModule::handleRelease(GdkEventButton* const& e) { return handleUserEvent(e); }
|
||||
|
@ -89,6 +126,7 @@ 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);
|
||||
|
@ -179,6 +217,10 @@ bool AModule::handleScroll(GdkEventScroll* e) {
|
|||
eventName = "on-scroll-up";
|
||||
else if (dir == SCROLL_DIR::DOWN)
|
||||
eventName = "on-scroll-down";
|
||||
else if (dir == SCROLL_DIR::LEFT)
|
||||
eventName = "on-scroll-left";
|
||||
else if (dir == SCROLL_DIR::RIGHT)
|
||||
eventName = "on-scroll-right";
|
||||
|
||||
// First call module actions
|
||||
this->AModule::doAction(eventName);
|
||||
|
|
|
@ -13,6 +13,7 @@ ASlider::ASlider(const Json::Value& config, const std::string& name, const std::
|
|||
if (!id.empty()) {
|
||||
scale_.get_style_context()->add_class(id);
|
||||
}
|
||||
scale_.get_style_context()->add_class(MODULE_CLASS);
|
||||
event_box_.add(scale_);
|
||||
scale_.signal_value_changed().connect(sigc::mem_fun(*this, &ASlider::onValueChanged));
|
||||
|
||||
|
|
626
src/bar.cpp
626
src/bar.cpp
|
@ -1,16 +1,13 @@
|
|||
#ifdef HAVE_GTK_LAYER_SHELL
|
||||
#include <gtk-layer-shell.h>
|
||||
#endif
|
||||
#include "bar.hpp"
|
||||
|
||||
#include <gtk-layer-shell.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "bar.hpp"
|
||||
#include "client.hpp"
|
||||
#include "factory.hpp"
|
||||
#include "group.hpp"
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_SWAY
|
||||
#include "modules/sway/bar.hpp"
|
||||
|
@ -25,9 +22,6 @@ static constexpr const char* MIN_WIDTH_MSG =
|
|||
|
||||
static constexpr const char* BAR_SIZE_MSG = "Bar configured (width: {}, height: {}) for output: {}";
|
||||
|
||||
static constexpr const char* SIZE_DEFINED =
|
||||
"{} size is defined in the config file so it will stay like that";
|
||||
|
||||
const Bar::bar_mode_map Bar::PRESET_MODES = { //
|
||||
{"default",
|
||||
{// Special mode to hold the global bar configuration
|
||||
|
@ -49,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}},
|
||||
|
@ -60,12 +54,12 @@ const Bar::bar_mode_map Bar::PRESET_MODES = { //
|
|||
.passthrough = true,
|
||||
.visible = true}}};
|
||||
|
||||
const std::string_view Bar::MODE_DEFAULT = "default";
|
||||
const std::string_view Bar::MODE_INVISIBLE = "invisible";
|
||||
const std::string Bar::MODE_DEFAULT = "default";
|
||||
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") {
|
||||
|
@ -93,11 +87,38 @@ void from_json(const Json::Value& j, bar_mode& m) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Deserializer for enum Gtk::PositionType */
|
||||
void from_json(const Json::Value& j, Gtk::PositionType& pos) {
|
||||
if (j == "left") {
|
||||
pos = Gtk::POS_LEFT;
|
||||
} else if (j == "right") {
|
||||
pos = Gtk::POS_RIGHT;
|
||||
} else if (j == "top") {
|
||||
pos = Gtk::POS_TOP;
|
||||
} else if (j == "bottom") {
|
||||
pos = Gtk::POS_BOTTOM;
|
||||
}
|
||||
}
|
||||
|
||||
Glib::ustring to_string(Gtk::PositionType pos) {
|
||||
switch (pos) {
|
||||
case Gtk::POS_LEFT:
|
||||
return "left";
|
||||
case Gtk::POS_RIGHT:
|
||||
return "right";
|
||||
case Gtk::POS_TOP:
|
||||
return "top";
|
||||
case Gtk::POS_BOTTOM:
|
||||
return "bottom";
|
||||
}
|
||||
throw std::runtime_error("Invalid Gtk::PositionType");
|
||||
}
|
||||
|
||||
/* Deserializer for JSON Object -> map<string compatible type, Value>
|
||||
* 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_view, Key>::value>>
|
||||
typename = std::enable_if_t<std::is_convertible<std::string, Key>::value>>
|
||||
void from_json(const Json::Value& j, std::map<Key, Value>& m) {
|
||||
if (j.isObject()) {
|
||||
for (auto it = j.begin(); it != j.end(); ++it) {
|
||||
|
@ -106,375 +127,6 @@ void from_json(const Json::Value& j, std::map<Key, Value>& m) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_GTK_LAYER_SHELL
|
||||
struct GLSSurfaceImpl : public BarSurface, public sigc::trackable {
|
||||
GLSSurfaceImpl(Gtk::Window& window, struct waybar_output& output) : window_{window} {
|
||||
output_name_ = output.name;
|
||||
// this has to be executed before GtkWindow.realize
|
||||
gtk_layer_init_for_window(window_.gobj());
|
||||
gtk_layer_set_keyboard_interactivity(window.gobj(), FALSE);
|
||||
gtk_layer_set_monitor(window_.gobj(), output.monitor->gobj());
|
||||
gtk_layer_set_namespace(window_.gobj(), "waybar");
|
||||
|
||||
window.signal_map_event().connect_notify(sigc::mem_fun(*this, &GLSSurfaceImpl::onMap));
|
||||
window.signal_configure_event().connect_notify(
|
||||
sigc::mem_fun(*this, &GLSSurfaceImpl::onConfigure));
|
||||
}
|
||||
|
||||
void setExclusiveZone(bool enable) override {
|
||||
if (enable) {
|
||||
gtk_layer_auto_exclusive_zone_enable(window_.gobj());
|
||||
} else {
|
||||
gtk_layer_set_exclusive_zone(window_.gobj(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void setMargins(const struct bar_margins& margins) override {
|
||||
gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_LEFT, margins.left);
|
||||
gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_RIGHT, margins.right);
|
||||
gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_TOP, margins.top);
|
||||
gtk_layer_set_margin(window_.gobj(), GTK_LAYER_SHELL_EDGE_BOTTOM, margins.bottom);
|
||||
}
|
||||
|
||||
void setLayer(bar_layer value) override {
|
||||
auto layer = GTK_LAYER_SHELL_LAYER_BOTTOM;
|
||||
if (value == bar_layer::TOP) {
|
||||
layer = GTK_LAYER_SHELL_LAYER_TOP;
|
||||
} else if (value == bar_layer::OVERLAY) {
|
||||
layer = GTK_LAYER_SHELL_LAYER_OVERLAY;
|
||||
}
|
||||
gtk_layer_set_layer(window_.gobj(), layer);
|
||||
}
|
||||
|
||||
void setPassThrough(bool enable) override {
|
||||
passthrough_ = enable;
|
||||
auto gdk_window = window_.get_window();
|
||||
if (gdk_window) {
|
||||
Cairo::RefPtr<Cairo::Region> region;
|
||||
if (enable) {
|
||||
region = Cairo::Region::create();
|
||||
}
|
||||
gdk_window->input_shape_combine_region(region, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void setPosition(const std::string_view& position) override {
|
||||
auto unanchored = GTK_LAYER_SHELL_EDGE_BOTTOM;
|
||||
vertical_ = false;
|
||||
if (position == "bottom") {
|
||||
unanchored = GTK_LAYER_SHELL_EDGE_TOP;
|
||||
} else if (position == "left") {
|
||||
unanchored = GTK_LAYER_SHELL_EDGE_RIGHT;
|
||||
vertical_ = true;
|
||||
} else if (position == "right") {
|
||||
vertical_ = true;
|
||||
unanchored = GTK_LAYER_SHELL_EDGE_LEFT;
|
||||
}
|
||||
for (auto edge : {GTK_LAYER_SHELL_EDGE_LEFT, GTK_LAYER_SHELL_EDGE_RIGHT,
|
||||
GTK_LAYER_SHELL_EDGE_TOP, GTK_LAYER_SHELL_EDGE_BOTTOM}) {
|
||||
gtk_layer_set_anchor(window_.gobj(), edge, unanchored != edge);
|
||||
}
|
||||
|
||||
// Disable anchoring for other edges too if the width
|
||||
// or the height has been set to a value other than 'auto'
|
||||
// otherwise the bar will use all space
|
||||
if (vertical_ && height_ > 1) {
|
||||
gtk_layer_set_anchor(window_.gobj(), GTK_LAYER_SHELL_EDGE_BOTTOM, false);
|
||||
gtk_layer_set_anchor(window_.gobj(), GTK_LAYER_SHELL_EDGE_TOP, false);
|
||||
} else if (!vertical_ && width_ > 1) {
|
||||
gtk_layer_set_anchor(window_.gobj(), GTK_LAYER_SHELL_EDGE_LEFT, false);
|
||||
gtk_layer_set_anchor(window_.gobj(), GTK_LAYER_SHELL_EDGE_RIGHT, false);
|
||||
}
|
||||
}
|
||||
|
||||
void setSize(uint32_t width, uint32_t height) override {
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
window_.set_size_request(width_, height_);
|
||||
};
|
||||
|
||||
private:
|
||||
Gtk::Window& window_;
|
||||
std::string output_name_;
|
||||
uint32_t width_;
|
||||
uint32_t height_;
|
||||
bool passthrough_ = false;
|
||||
bool vertical_ = false;
|
||||
|
||||
void onMap(GdkEventAny* ev) { setPassThrough(passthrough_); }
|
||||
|
||||
void onConfigure(GdkEventConfigure* ev) {
|
||||
/*
|
||||
* GTK wants new size for the window.
|
||||
* Actual resizing and management of the exclusve zone is handled within the gtk-layer-shell
|
||||
* code. This event handler only updates stored size of the window and prints some warnings.
|
||||
*
|
||||
* Note: forced resizing to a window smaller than required by GTK would not work with
|
||||
* gtk-layer-shell.
|
||||
*/
|
||||
if (vertical_) {
|
||||
if (width_ > 1 && ev->width > static_cast<int>(width_)) {
|
||||
spdlog::warn(MIN_WIDTH_MSG, width_, ev->width);
|
||||
}
|
||||
} else {
|
||||
if (height_ > 1 && ev->height > static_cast<int>(height_)) {
|
||||
spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height);
|
||||
}
|
||||
}
|
||||
width_ = ev->width;
|
||||
height_ = ev->height;
|
||||
spdlog::info(BAR_SIZE_MSG, width_, height_, output_name_);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct RawSurfaceImpl : public BarSurface, public sigc::trackable {
|
||||
RawSurfaceImpl(Gtk::Window& window, struct waybar_output& output) : window_{window} {
|
||||
output_ = gdk_wayland_monitor_get_wl_output(output.monitor->gobj());
|
||||
output_name_ = output.name;
|
||||
|
||||
window.signal_realize().connect_notify(sigc::mem_fun(*this, &RawSurfaceImpl::onRealize));
|
||||
window.signal_map_event().connect_notify(sigc::mem_fun(*this, &RawSurfaceImpl::onMap));
|
||||
window.signal_configure_event().connect_notify(
|
||||
sigc::mem_fun(*this, &RawSurfaceImpl::onConfigure));
|
||||
|
||||
if (window.get_realized()) {
|
||||
onRealize();
|
||||
}
|
||||
}
|
||||
|
||||
void setExclusiveZone(bool enable) override {
|
||||
exclusive_zone_ = enable;
|
||||
if (layer_surface_) {
|
||||
auto zone = 0;
|
||||
if (enable) {
|
||||
// exclusive zone already includes margin for anchored edge,
|
||||
// only opposite margin should be added
|
||||
if ((anchor_ & VERTICAL_ANCHOR) == VERTICAL_ANCHOR) {
|
||||
zone += width_;
|
||||
zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) ? margins_.right : margins_.left;
|
||||
} else {
|
||||
zone += height_;
|
||||
zone += (anchor_ & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) ? margins_.bottom : margins_.top;
|
||||
}
|
||||
}
|
||||
spdlog::debug("Set exclusive zone {} for output {}", zone, output_name_);
|
||||
zwlr_layer_surface_v1_set_exclusive_zone(layer_surface_.get(), zone);
|
||||
}
|
||||
}
|
||||
|
||||
void setLayer(bar_layer layer) override {
|
||||
layer_ = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
||||
if (layer == bar_layer::TOP) {
|
||||
layer_ = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
|
||||
} else if (layer == bar_layer::OVERLAY) {
|
||||
layer_ = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
|
||||
}
|
||||
// updating already mapped window
|
||||
if (layer_surface_) {
|
||||
if (zwlr_layer_surface_v1_get_version(layer_surface_.get()) >=
|
||||
ZWLR_LAYER_SURFACE_V1_SET_LAYER_SINCE_VERSION) {
|
||||
zwlr_layer_surface_v1_set_layer(layer_surface_.get(), layer_);
|
||||
} else {
|
||||
spdlog::warn("Unable to change layer: layer-shell implementation is too old");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setMargins(const struct bar_margins& margins) override {
|
||||
margins_ = margins;
|
||||
// updating already mapped window
|
||||
if (layer_surface_) {
|
||||
zwlr_layer_surface_v1_set_margin(layer_surface_.get(), margins_.top, margins_.right,
|
||||
margins_.bottom, margins_.left);
|
||||
}
|
||||
}
|
||||
|
||||
void setPassThrough(bool enable) override {
|
||||
passthrough_ = enable;
|
||||
/* GTK overwrites any region changes applied directly to the wl_surface,
|
||||
* thus the same GTK region API as in the GLS impl has to be used. */
|
||||
auto gdk_window = window_.get_window();
|
||||
if (gdk_window) {
|
||||
Cairo::RefPtr<Cairo::Region> region;
|
||||
if (enable) {
|
||||
region = Cairo::Region::create();
|
||||
}
|
||||
gdk_window->input_shape_combine_region(region, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void setPosition(const std::string_view& position) override {
|
||||
anchor_ = HORIZONTAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
||||
if (position == "bottom") {
|
||||
anchor_ = HORIZONTAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||
} else if (position == "left") {
|
||||
anchor_ = VERTICAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
||||
} else if (position == "right") {
|
||||
anchor_ = VERTICAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||
}
|
||||
|
||||
// updating already mapped window
|
||||
if (layer_surface_) {
|
||||
zwlr_layer_surface_v1_set_anchor(layer_surface_.get(), anchor_);
|
||||
}
|
||||
}
|
||||
|
||||
void setSize(uint32_t width, uint32_t height) override {
|
||||
configured_width_ = width_ = width;
|
||||
configured_height_ = height_ = height;
|
||||
// layer_shell.configure handler should update exclusive zone if size changes
|
||||
window_.set_size_request(width, height);
|
||||
};
|
||||
|
||||
void commit() override {
|
||||
if (surface_) {
|
||||
wl_surface_commit(surface_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static uint8_t VERTICAL_ANCHOR =
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||
constexpr static uint8_t HORIZONTAL_ANCHOR =
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||
|
||||
template <auto fn>
|
||||
using deleter_fn = std::integral_constant<decltype(fn), fn>;
|
||||
using layer_surface_ptr =
|
||||
std::unique_ptr<zwlr_layer_surface_v1, deleter_fn<zwlr_layer_surface_v1_destroy>>;
|
||||
|
||||
Gtk::Window& window_;
|
||||
std::string output_name_;
|
||||
uint32_t configured_width_ = 0;
|
||||
uint32_t configured_height_ = 0;
|
||||
uint32_t width_ = 0;
|
||||
uint32_t height_ = 0;
|
||||
uint8_t anchor_ = HORIZONTAL_ANCHOR | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
||||
bool exclusive_zone_ = true;
|
||||
bool passthrough_ = false;
|
||||
struct bar_margins margins_;
|
||||
|
||||
zwlr_layer_shell_v1_layer layer_ = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM;
|
||||
struct wl_output* output_ = nullptr; // owned by GTK
|
||||
struct wl_surface* surface_ = nullptr; // owned by GTK
|
||||
layer_surface_ptr layer_surface_;
|
||||
|
||||
void onRealize() {
|
||||
auto gdk_window = window_.get_window()->gobj();
|
||||
gdk_wayland_window_set_use_custom_surface(gdk_window);
|
||||
}
|
||||
|
||||
void onMap(GdkEventAny* ev) {
|
||||
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
||||
.configure = onSurfaceConfigure,
|
||||
.closed = onSurfaceClosed,
|
||||
};
|
||||
auto client = Client::inst();
|
||||
auto gdk_window = window_.get_window()->gobj();
|
||||
surface_ = gdk_wayland_window_get_wl_surface(gdk_window);
|
||||
|
||||
layer_surface_.reset(zwlr_layer_shell_v1_get_layer_surface(client->layer_shell, surface_,
|
||||
output_, layer_, "waybar"));
|
||||
|
||||
zwlr_layer_surface_v1_add_listener(layer_surface_.get(), &layer_surface_listener, this);
|
||||
zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface_.get(), false);
|
||||
zwlr_layer_surface_v1_set_anchor(layer_surface_.get(), anchor_);
|
||||
zwlr_layer_surface_v1_set_margin(layer_surface_.get(), margins_.top, margins_.right,
|
||||
margins_.bottom, margins_.left);
|
||||
|
||||
setSurfaceSize(width_, height_);
|
||||
setExclusiveZone(exclusive_zone_);
|
||||
setPassThrough(passthrough_);
|
||||
|
||||
commit();
|
||||
wl_display_roundtrip(client->wl_display);
|
||||
}
|
||||
|
||||
void onConfigure(GdkEventConfigure* ev) {
|
||||
/*
|
||||
* GTK wants new size for the window.
|
||||
*
|
||||
* Prefer configured size if it's non-default.
|
||||
* If the size is not set and the window is smaller than requested by GTK, request resize from
|
||||
* layer surface.
|
||||
*/
|
||||
auto tmp_height = height_;
|
||||
auto tmp_width = width_;
|
||||
if (ev->height > static_cast<int>(height_)) {
|
||||
// Default minimal value
|
||||
if (height_ > 1) {
|
||||
spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height);
|
||||
}
|
||||
if (configured_height_ > 1) {
|
||||
spdlog::info(SIZE_DEFINED, "Height");
|
||||
} else {
|
||||
tmp_height = ev->height;
|
||||
}
|
||||
}
|
||||
if (ev->width > static_cast<int>(width_)) {
|
||||
// Default minimal value
|
||||
if (width_ > 1) {
|
||||
spdlog::warn(MIN_WIDTH_MSG, width_, ev->width);
|
||||
}
|
||||
if (configured_width_ > 1) {
|
||||
spdlog::info(SIZE_DEFINED, "Width");
|
||||
} else {
|
||||
tmp_width = ev->width;
|
||||
}
|
||||
}
|
||||
if (tmp_width != width_ || tmp_height != height_) {
|
||||
setSurfaceSize(tmp_width, tmp_height);
|
||||
commit();
|
||||
}
|
||||
}
|
||||
|
||||
void setSurfaceSize(uint32_t width, uint32_t height) {
|
||||
/* If the client is anchored to two opposite edges, layer_surface.configure will return
|
||||
* size without margins for the axis.
|
||||
* layer_surface.set_size, however, expects size with margins for the anchored axis.
|
||||
* This is not specified by wlr-layer-shell and based on actual behavior of sway.
|
||||
*
|
||||
* If the size for unanchored axis is not set (0), change request to 1 to avoid automatic
|
||||
* assignment by the compositor.
|
||||
*/
|
||||
if ((anchor_ & VERTICAL_ANCHOR) == VERTICAL_ANCHOR) {
|
||||
width = width > 0 ? width : 1;
|
||||
if (height > 1) {
|
||||
height += margins_.top + margins_.bottom;
|
||||
}
|
||||
} else {
|
||||
height = height > 0 ? height : 1;
|
||||
if (width > 1) {
|
||||
width += margins_.right + margins_.left;
|
||||
}
|
||||
}
|
||||
spdlog::debug("Set surface size {}x{} for output {}", width, height, output_name_);
|
||||
zwlr_layer_surface_v1_set_size(layer_surface_.get(), width, height);
|
||||
}
|
||||
|
||||
static void onSurfaceConfigure(void* data, struct zwlr_layer_surface_v1* surface, uint32_t serial,
|
||||
uint32_t width, uint32_t height) {
|
||||
auto o = static_cast<RawSurfaceImpl*>(data);
|
||||
if (width != o->width_ || height != o->height_) {
|
||||
o->width_ = width;
|
||||
o->height_ = height;
|
||||
o->window_.set_size_request(o->width_, o->height_);
|
||||
o->window_.resize(o->width_, o->height_);
|
||||
o->setExclusiveZone(o->exclusive_zone_);
|
||||
spdlog::info(BAR_SIZE_MSG, o->width_ == 1 ? "auto" : std::to_string(o->width_),
|
||||
o->height_ == 1 ? "auto" : std::to_string(o->height_), o->output_name_);
|
||||
o->commit();
|
||||
}
|
||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||
}
|
||||
|
||||
static void onSurfaceClosed(void* data, struct zwlr_layer_surface_v1* /* surface */) {
|
||||
auto o = static_cast<RawSurfaceImpl*>(data);
|
||||
o->layer_surface_.reset();
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace waybar
|
||||
|
||||
waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
||||
|
@ -493,17 +145,18 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
|||
window.set_decorated(false);
|
||||
window.get_style_context()->add_class(output->name);
|
||||
window.get_style_context()->add_class(config["name"].asString());
|
||||
window.get_style_context()->add_class(config["position"].asString());
|
||||
|
||||
auto position = config["position"].asString();
|
||||
from_json(config["position"], position);
|
||||
orientation = (position == Gtk::POS_LEFT || position == Gtk::POS_RIGHT)
|
||||
? Gtk::ORIENTATION_VERTICAL
|
||||
: Gtk::ORIENTATION_HORIZONTAL;
|
||||
|
||||
if (position == "right" || position == "left") {
|
||||
left_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
||||
center_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
||||
right_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
||||
box_ = Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0);
|
||||
vertical = true;
|
||||
}
|
||||
window.get_style_context()->add_class(to_string(position));
|
||||
|
||||
left_ = Gtk::Box(orientation, 0);
|
||||
center_ = Gtk::Box(orientation, 0);
|
||||
right_ = Gtk::Box(orientation, 0);
|
||||
box_ = Gtk::Box(orientation, 0);
|
||||
|
||||
left_.get_style_context()->add_class("modules-left");
|
||||
center_.get_style_context()->add_class("modules-center");
|
||||
|
@ -516,8 +169,8 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
|||
right_.set_spacing(spacing);
|
||||
}
|
||||
|
||||
uint32_t height = config["height"].isUInt() ? config["height"].asUInt() : 0;
|
||||
uint32_t width = config["width"].isUInt() ? config["width"].asUInt() : 0;
|
||||
height_ = config["height"].isUInt() ? config["height"].asUInt() : 0;
|
||||
width_ = config["width"].isUInt() ? config["width"].asUInt() : 0;
|
||||
|
||||
if (config["margin-top"].isInt() || config["margin-right"].isInt() ||
|
||||
config["margin-bottom"].isInt() || config["margin-left"].isInt()) {
|
||||
|
@ -568,21 +221,23 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
|||
output->monitor->property_geometry().signal_changed().connect(
|
||||
sigc::mem_fun(*this, &Bar::onOutputGeometryChanged));
|
||||
|
||||
#ifdef HAVE_GTK_LAYER_SHELL
|
||||
bool use_gls = config["gtk-layer-shell"].isBool() ? config["gtk-layer-shell"].asBool() : true;
|
||||
if (use_gls) {
|
||||
surface_impl_ = std::make_unique<GLSSurfaceImpl>(window, *output);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
surface_impl_ = std::make_unique<RawSurfaceImpl>(window, *output);
|
||||
}
|
||||
// this has to be executed before GtkWindow.realize
|
||||
auto* gtk_window = window.gobj();
|
||||
gtk_layer_init_for_window(gtk_window);
|
||||
gtk_layer_set_keyboard_mode(gtk_window, GTK_LAYER_SHELL_KEYBOARD_MODE_NONE);
|
||||
gtk_layer_set_monitor(gtk_window, output->monitor->gobj());
|
||||
gtk_layer_set_namespace(gtk_window, "waybar");
|
||||
|
||||
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_LEFT, margins_.left);
|
||||
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, margins_.right);
|
||||
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_TOP, margins_.top);
|
||||
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_BOTTOM, margins_.bottom);
|
||||
|
||||
window.set_size_request(width_, height_);
|
||||
|
||||
surface_impl_->setMargins(margins_);
|
||||
surface_impl_->setSize(width, height);
|
||||
// Position needs to be set after calculating the height due to the
|
||||
// GTK layer shell anchors logic relying on the dimensions of the bar.
|
||||
surface_impl_->setPosition(position);
|
||||
setPosition(position);
|
||||
|
||||
/* Read custom modes if available */
|
||||
if (auto modes = config.get("modes", {}); modes.isObject()) {
|
||||
|
@ -638,7 +293,7 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
|||
/* Need to define it here because of forward declared members */
|
||||
waybar::Bar::~Bar() = default;
|
||||
|
||||
void waybar::Bar::setMode(const std::string_view& mode) {
|
||||
void waybar::Bar::setMode(const std::string& mode) {
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
auto style = window.get_style_context();
|
||||
|
@ -659,9 +314,23 @@ void waybar::Bar::setMode(const std::string_view& mode) {
|
|||
}
|
||||
|
||||
void waybar::Bar::setMode(const struct bar_mode& mode) {
|
||||
surface_impl_->setLayer(mode.layer);
|
||||
surface_impl_->setExclusiveZone(mode.exclusive);
|
||||
surface_impl_->setPassThrough(mode.passthrough);
|
||||
auto* gtk_window = window.gobj();
|
||||
|
||||
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) {
|
||||
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_OVERLAY);
|
||||
}
|
||||
|
||||
if (mode.exclusive) {
|
||||
gtk_layer_auto_exclusive_zone_enable(gtk_window);
|
||||
} else {
|
||||
gtk_layer_set_exclusive_zone(gtk_window, 0);
|
||||
}
|
||||
|
||||
setPassThrough(passthrough_ = mode.passthrough);
|
||||
|
||||
if (mode.visible) {
|
||||
window.get_style_context()->remove_class("hidden");
|
||||
|
@ -670,7 +339,58 @@ void waybar::Bar::setMode(const struct bar_mode& mode) {
|
|||
window.get_style_context()->add_class("hidden");
|
||||
window.set_opacity(0);
|
||||
}
|
||||
surface_impl_->commit();
|
||||
}
|
||||
|
||||
void waybar::Bar::setPassThrough(bool passthrough) {
|
||||
auto gdk_window = window.get_window();
|
||||
if (gdk_window) {
|
||||
Cairo::RefPtr<Cairo::Region> region;
|
||||
if (passthrough) {
|
||||
region = Cairo::Region::create();
|
||||
}
|
||||
gdk_window->input_shape_combine_region(region, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void waybar::Bar::setPosition(Gtk::PositionType position) {
|
||||
std::array<gboolean, GTK_LAYER_SHELL_EDGE_ENTRY_NUMBER> anchors;
|
||||
anchors.fill(TRUE);
|
||||
|
||||
auto orientation = (position == Gtk::POS_LEFT || position == Gtk::POS_RIGHT)
|
||||
? Gtk::ORIENTATION_VERTICAL
|
||||
: Gtk::ORIENTATION_HORIZONTAL;
|
||||
|
||||
switch (position) {
|
||||
case Gtk::POS_LEFT:
|
||||
anchors[GTK_LAYER_SHELL_EDGE_RIGHT] = FALSE;
|
||||
break;
|
||||
case Gtk::POS_RIGHT:
|
||||
anchors[GTK_LAYER_SHELL_EDGE_LEFT] = FALSE;
|
||||
break;
|
||||
case Gtk::POS_BOTTOM:
|
||||
anchors[GTK_LAYER_SHELL_EDGE_TOP] = FALSE;
|
||||
break;
|
||||
default: /* Gtk::POS_TOP */
|
||||
anchors[GTK_LAYER_SHELL_EDGE_BOTTOM] = FALSE;
|
||||
break;
|
||||
};
|
||||
// Disable anchoring for other edges too if the width
|
||||
// or the height has been set to a value other than 'auto'
|
||||
// otherwise the bar will use all space
|
||||
uint32_t configured_width = config["width"].isUInt() ? config["width"].asUInt() : 0;
|
||||
uint32_t configured_height = config["height"].isUInt() ? config["height"].asUInt() : 0;
|
||||
if (orientation == Gtk::ORIENTATION_VERTICAL && configured_height > 1) {
|
||||
anchors[GTK_LAYER_SHELL_EDGE_TOP] = FALSE;
|
||||
anchors[GTK_LAYER_SHELL_EDGE_BOTTOM] = FALSE;
|
||||
} else if (orientation == Gtk::ORIENTATION_HORIZONTAL && configured_width > 1) {
|
||||
anchors[GTK_LAYER_SHELL_EDGE_LEFT] = FALSE;
|
||||
anchors[GTK_LAYER_SHELL_EDGE_RIGHT] = FALSE;
|
||||
}
|
||||
|
||||
for (auto edge : {GTK_LAYER_SHELL_EDGE_LEFT, GTK_LAYER_SHELL_EDGE_RIGHT, GTK_LAYER_SHELL_EDGE_TOP,
|
||||
GTK_LAYER_SHELL_EDGE_BOTTOM}) {
|
||||
gtk_layer_set_anchor(window.gobj(), edge, anchors[edge]);
|
||||
}
|
||||
}
|
||||
|
||||
void waybar::Bar::onMap(GdkEventAny*) {
|
||||
|
@ -680,6 +400,8 @@ void waybar::Bar::onMap(GdkEventAny*) {
|
|||
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));
|
||||
|
||||
setPassThrough(passthrough_);
|
||||
}
|
||||
|
||||
void waybar::Bar::setVisible(bool value) {
|
||||
|
@ -727,7 +449,17 @@ void waybar::Bar::setupAltFormatKeyForModuleList(const char* module_list_name) {
|
|||
Json::Value& modules = config[module_list_name];
|
||||
for (const Json::Value& module_name : modules) {
|
||||
if (module_name.isString()) {
|
||||
setupAltFormatKeyForModule(module_name.asString());
|
||||
auto ref = module_name.asString();
|
||||
if (ref.compare(0, 6, "group/") == 0 && ref.size() > 6) {
|
||||
Json::Value& group_modules = config[ref]["modules"];
|
||||
for (const Json::Value& module_name : group_modules) {
|
||||
if (module_name.isString()) {
|
||||
setupAltFormatKeyForModule(module_name.asString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setupAltFormatKeyForModule(ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -824,39 +556,63 @@ auto waybar::Bar::setupWidgets() -> void {
|
|||
}
|
||||
|
||||
void waybar::Bar::onConfigure(GdkEventConfigure* ev) {
|
||||
/*
|
||||
* GTK wants new size for the window.
|
||||
* Actual resizing and management of the exclusve zone is handled within the gtk-layer-shell
|
||||
* code. This event handler only updates stored size of the window and prints some warnings.
|
||||
*
|
||||
* Note: forced resizing to a window smaller than required by GTK would not work with
|
||||
* gtk-layer-shell.
|
||||
*/
|
||||
if (orientation == Gtk::ORIENTATION_VERTICAL) {
|
||||
if (width_ > 1 && ev->width > static_cast<int>(width_)) {
|
||||
spdlog::warn(MIN_WIDTH_MSG, width_, ev->width);
|
||||
}
|
||||
} else {
|
||||
if (height_ > 1 && ev->height > static_cast<int>(height_)) {
|
||||
spdlog::warn(MIN_HEIGHT_MSG, height_, ev->height);
|
||||
}
|
||||
}
|
||||
width_ = ev->width;
|
||||
height_ = ev->height;
|
||||
|
||||
configureGlobalOffset(ev->width, ev->height);
|
||||
spdlog::info(BAR_SIZE_MSG, ev->width, ev->height, output->name);
|
||||
}
|
||||
|
||||
void waybar::Bar::configureGlobalOffset(int width, int height) {
|
||||
auto monitor_geometry = *output->monitor->property_geometry().get_value().gobj();
|
||||
auto position = config["position"].asString();
|
||||
int x;
|
||||
int y;
|
||||
if (position == "bottom") {
|
||||
if (width + margins_.left + margins_.right >= monitor_geometry.width)
|
||||
switch (position) {
|
||||
case Gtk::POS_BOTTOM:
|
||||
if (width + margins_.left + margins_.right >= monitor_geometry.width)
|
||||
x = margins_.left;
|
||||
else
|
||||
x = (monitor_geometry.width - width) / 2;
|
||||
y = monitor_geometry.height - height - margins_.bottom;
|
||||
break;
|
||||
case Gtk::POS_LEFT:
|
||||
x = margins_.left;
|
||||
else
|
||||
x = (monitor_geometry.width - width) / 2;
|
||||
y = monitor_geometry.height - height - margins_.bottom;
|
||||
} else if (position == "left") {
|
||||
x = margins_.left;
|
||||
if (height + margins_.top + margins_.bottom >= monitor_geometry.height)
|
||||
if (height + margins_.top + margins_.bottom >= monitor_geometry.height)
|
||||
y = margins_.top;
|
||||
else
|
||||
y = (monitor_geometry.height - height) / 2;
|
||||
break;
|
||||
case Gtk::POS_RIGHT:
|
||||
x = monitor_geometry.width - width - margins_.right;
|
||||
if (height + margins_.top + margins_.bottom >= monitor_geometry.height)
|
||||
y = margins_.top;
|
||||
else
|
||||
y = (monitor_geometry.height - height) / 2;
|
||||
break;
|
||||
default: /* Gtk::POS_TOP */
|
||||
if (width + margins_.left + margins_.right >= monitor_geometry.width)
|
||||
x = margins_.left;
|
||||
else
|
||||
x = (monitor_geometry.width - width) / 2;
|
||||
y = margins_.top;
|
||||
else
|
||||
y = (monitor_geometry.height - height) / 2;
|
||||
} else if (position == "right") {
|
||||
x = monitor_geometry.width - width - margins_.right;
|
||||
if (height + margins_.top + margins_.bottom >= monitor_geometry.height)
|
||||
y = margins_.top;
|
||||
else
|
||||
y = (monitor_geometry.height - height) / 2;
|
||||
} else {
|
||||
// position is top
|
||||
if (width + margins_.left + margins_.right >= monitor_geometry.width)
|
||||
x = margins_.left;
|
||||
else
|
||||
x = (monitor_geometry.width - width) / 2;
|
||||
y = margins_.top;
|
||||
break;
|
||||
}
|
||||
|
||||
x_global = x + monitor_geometry.x;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "client.hpp"
|
||||
|
||||
#include <gtk-layer-shell.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -8,7 +9,6 @@
|
|||
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "util/clara.hpp"
|
||||
#include "util/format.hpp"
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
|
||||
waybar::Client *waybar::Client::inst() {
|
||||
static auto c = new Client();
|
||||
|
@ -18,13 +18,8 @@ waybar::Client *waybar::Client::inst() {
|
|||
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);
|
||||
if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
||||
// limit version to a highest supported by the client protocol file
|
||||
version = std::min<uint32_t>(version, zwlr_layer_shell_v1_interface.version);
|
||||
client->layer_shell = static_cast<struct zwlr_layer_shell_v1 *>(
|
||||
wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, version));
|
||||
} else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0 &&
|
||||
version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
|
||||
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(
|
||||
registry, name, &zxdg_output_manager_v1_interface, ZXDG_OUTPUT_V1_NAME_SINCE_VERSION));
|
||||
} else if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) {
|
||||
|
@ -200,7 +195,12 @@ void waybar::Client::bindInterfaces() {
|
|||
};
|
||||
wl_registry_add_listener(registry, ®istry_listener, this);
|
||||
wl_display_roundtrip(wl_display);
|
||||
if (layer_shell == nullptr || xdg_output_manager == nullptr) {
|
||||
|
||||
if (!gtk_layer_is_supported()) {
|
||||
throw std::runtime_error("The Wayland compositor does not support wlr-layer-shell protocol");
|
||||
}
|
||||
|
||||
if (xdg_output_manager == nullptr) {
|
||||
throw std::runtime_error("Failed to acquire required resources.");
|
||||
}
|
||||
// add existing outputs and subscribe to updates
|
||||
|
@ -262,15 +262,30 @@ int waybar::Client::main(int argc, char *argv[]) {
|
|||
if (!portal) {
|
||||
portal = std::make_unique<waybar::Portal>();
|
||||
}
|
||||
auto css_file = getStyle(style_opt);
|
||||
setupCss(css_file);
|
||||
m_cssFile = getStyle(style_opt);
|
||||
setupCss(m_cssFile);
|
||||
m_cssReloadHelper = std::make_unique<CssReloadHelper>(m_cssFile, [&]() { setupCss(m_cssFile); });
|
||||
portal->signal_appearance_changed().connect([&](waybar::Appearance appearance) {
|
||||
auto css_file = getStyle(style_opt, appearance);
|
||||
setupCss(css_file);
|
||||
});
|
||||
|
||||
auto m_config = config.getConfig();
|
||||
if (m_config.isObject() && m_config["reload_style_on_change"].asBool()) {
|
||||
m_cssReloadHelper->monitorChanges();
|
||||
} else if (m_config.isArray()) {
|
||||
for (const auto &conf : m_config) {
|
||||
if (conf["reload_style_on_change"].asBool()) {
|
||||
m_cssReloadHelper->monitorChanges();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bindInterfaces();
|
||||
gtk_app->hold();
|
||||
gtk_app->run();
|
||||
m_cssReloadHelper.reset(); // stop watching css file
|
||||
bars.clear();
|
||||
return 0;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue