Compare commits
608 Commits
scale-work
...
v0.47.0
Author | SHA1 | Date | |
---|---|---|---|
|
04ac46c543 | ||
|
2f55806d6f | ||
|
3b207d29bd | ||
|
6bd6c5512e | ||
|
bb5b09def0 | ||
|
efe29a2461 | ||
|
e951011503 | ||
|
16aeb24bc1 | ||
|
74d0f34cf3 | ||
|
4abf9155ee | ||
|
0a28e13787 | ||
|
3cd6e3960f | ||
|
8b1d6e3009 | ||
|
445acec2a2 | ||
|
45c3787e75 | ||
|
9199a9746d | ||
|
bce58d9d65 | ||
|
f3fc8d599a | ||
|
107723bdf4 | ||
|
065e89648b | ||
|
354d4594de | ||
|
089fdd1ea0 | ||
|
1815f9a2e5 | ||
|
d8f79d7678 | ||
|
80b2fd135b | ||
|
fda9790cde | ||
|
9b3f71390c | ||
|
0e5d03a557 | ||
|
57a39984dd | ||
|
944e36ea2e | ||
|
4a1b960cbe | ||
|
5d8261aee2 | ||
|
d075d1cab9 | ||
|
bb099e5733 | ||
|
dadb2e0949 | ||
|
a8c2d5a616 | ||
|
465cf66df1 | ||
|
1a0a22ad03 | ||
|
0a1ae48a9f | ||
|
ae403e6a05 | ||
|
ae4e38d9d5 | ||
|
ecae3c5e4b | ||
|
f1bd62806e | ||
|
fda5626594 | ||
|
c90dbfab6f | ||
|
d335c8f101 | ||
|
c8a0443adc | ||
|
ce48bc5408 | ||
|
da6e966313 | ||
|
a661203bb6 | ||
|
9e8d9791c7 | ||
|
2d82a92324 | ||
|
407453166c | ||
|
8dd2cd41fb | ||
|
0a0e56d99c | ||
|
086fd7ece8 | ||
|
4da9b7cc5b | ||
|
f56153a9c1 | ||
|
a36fa5c229 | ||
|
fdfcfc824e | ||
|
d01756c1f4 | ||
|
078e13f463 | ||
|
47d645d84a | ||
|
b65f8a8723 | ||
|
401a3bae61 | ||
|
76a899627e | ||
|
b7a3c45269 | ||
|
2bad73354a | ||
|
0dc7367a70 | ||
|
52b9ae592b | ||
|
25add26881 | ||
|
f16f170433 | ||
|
a6b263713a | ||
|
4f0f512cab | ||
|
a3a7499317 | ||
|
b117fae3b4 | ||
|
2671656a75 | ||
|
2778aff08f | ||
|
9e4f90aedf | ||
|
15dc024a39 | ||
|
3b85690aa6 | ||
|
cef09fbfe6 | ||
|
a8b568c6c4 | ||
|
b5fb6110ab | ||
|
da9252a23e | ||
|
8475a8ef99 | ||
|
f9c37ca43b | ||
|
9dc9366fc6 | ||
|
85aba23cbe | ||
|
2d1ebadb9b | ||
|
e66eab7b6a | ||
|
c9822b08f9 | ||
|
983bc067da | ||
|
b320bc2dc6 | ||
|
ad64726f5d | ||
|
5fa2594659 | ||
|
75727e7c17 | ||
|
67e1e46f9b | ||
|
308b1f3afb | ||
|
c143907857 | ||
|
830350a1f7 | ||
|
95542e4488 | ||
|
5642ed331d | ||
|
c7086f936a | ||
|
b9f110ef87 | ||
|
1bf4937b02 | ||
|
6a90b50545 | ||
|
602d6b7356 | ||
|
780e3dd542 | ||
|
f1a7a7497e | ||
|
f390f48a07 | ||
|
1b06d222cf | ||
|
391ff29110 | ||
|
a5c14370c1 | ||
|
b0bae15499 | ||
|
e8317ae34d | ||
|
a25d228840 | ||
|
60f069d540 | ||
|
2e6e0e9278 | ||
|
f69e72eca1 | ||
|
b0cd9972e8 | ||
|
f3c49c1295 | ||
|
4971725b69 | ||
|
1697171fc0 | ||
|
81721b8aa8 | ||
|
365caa49ff | ||
|
94381e5999 | ||
|
42fd366046 | ||
|
cbd2451570 | ||
|
dde3e082c9 | ||
|
9f3c9ac01a | ||
|
7f177fa1cf | ||
|
d64ac47202 | ||
|
4e93b2def5 | ||
|
aff34089c4 | ||
|
1989b0049f | ||
|
9f933da1c5 | ||
|
af301312d5 | ||
|
8c14c2a5f4 | ||
|
cb211d83f6 | ||
|
fde569db65 | ||
|
5b37d53992 | ||
|
deb077c346 | ||
|
3f40d6d936 | ||
|
a364e80425 | ||
|
2b01a5bcf6 | ||
|
8d4c18d723 | ||
|
c600e1aaff | ||
|
cca0adf6a3 | ||
|
534adad6b1 | ||
|
775111b603 | ||
|
85632e7c33 | ||
|
43ca66779b | ||
|
e75e2cdac7 | ||
|
2eaa4d80a0 | ||
|
dddb64dc35 | ||
|
1a3d17da91 | ||
|
2a24a61126 | ||
|
2e2e2e2cad | ||
|
68a5842f06 | ||
|
5f7ad767db | ||
|
a4a4fffffb | ||
|
1830296df3 | ||
|
e536b02248 | ||
|
1cc1a46c2e | ||
|
31422ae25d | ||
|
57921d7dbd | ||
|
8e8073c421 | ||
|
52ee7a8748 | ||
|
71dc9f6128 | ||
|
fd67ee9ecd | ||
|
bec18dc6f9 | ||
|
5b714f05f8 | ||
|
7c43eed2c1 | ||
|
23e7d8f6a7 | ||
|
df06cb4d71 | ||
|
0fec38fe72 | ||
|
80a4852266 | ||
|
4c4471c66d | ||
|
6378c8ed65 | ||
|
49e5f9c428 | ||
|
5f1df55fcb | ||
|
e2c78c00e5 | ||
|
bd7092a9fe | ||
|
c7d9719910 | ||
|
7ae7920572 | ||
|
4b6163aef3 | ||
|
788ae58897 | ||
|
bba2d9a197 | ||
|
e340e9f431 | ||
|
c2d14a2013 | ||
|
95cdedee04 | ||
|
0706c1a1f7 | ||
|
aecf1abddd | ||
|
b9f82e9968 | ||
|
e06b520427 | ||
|
dab50b3ef3 | ||
|
eaac5c7cbd | ||
|
a5234f26e4 | ||
|
de3ad245dc | ||
|
db24964877 | ||
|
9f7a96b997 | ||
|
3cba4ba44e | ||
|
8237627f3a | ||
|
35e134e570 | ||
|
452a7e6905 | ||
|
61a51bb4ef | ||
|
aefaeedf5e | ||
|
cef5e6dd7c | ||
|
7c03e9d376 | ||
|
df956a0f6f | ||
|
33f271c29a | ||
|
e892310953 | ||
|
4d05677e8d | ||
|
c16044a5c8 | ||
|
d94d8b4ab2 | ||
|
bb5c3f2702 | ||
|
0a27af8cd1 | ||
|
c106f454c1 | ||
|
875b598a33 | ||
|
8bbeee1173 | ||
|
b1e5cc66bd | ||
|
5ff02902ee | ||
|
cccca7c02e | ||
|
10a4365f7d | ||
|
a7a6eedc21 | ||
|
888bdf4e23 | ||
|
ceef4fb3a5 | ||
|
22f7d6f142 | ||
|
f9e4998a6d | ||
|
3c617ce33c | ||
|
f6ac755cf7 | ||
|
320144ae72 | ||
|
92186898c0 | ||
|
10a9fec7fc | ||
|
6d7544458d | ||
|
d26439a0fe | ||
|
ef6b0c81c9 | ||
|
8f83d29f00 | ||
|
22bf2853e6 | ||
|
5963970be5 | ||
|
8b51eeb7ae | ||
|
5329298b52 | ||
|
e9a7fb8f91 | ||
|
1fb720b62a | ||
|
2687788236 | ||
|
0ddb952d7a | ||
|
1930a95000 | ||
|
cc38e7e18f | ||
|
55ec8bd512 | ||
|
54f57797e9 | ||
|
65f66dcf0d | ||
|
451d7a41fc | ||
|
00d6261cc0 | ||
|
745a82ce8a | ||
|
a847bc67b1 | ||
|
b100344595 | ||
|
943b3d467b | ||
|
940f7aa990 | ||
|
e5fa017172 | ||
|
c4eda46d0e | ||
|
aa067a4cf1 | ||
|
67cee43006 | ||
|
47a1650c48 | ||
|
936dfedbad | ||
|
6113f4da7f | ||
|
cc923ad031 | ||
|
df9ff44899 | ||
|
97493511f9 | ||
|
505c1f8f4a | ||
|
6744bb57c6 | ||
|
2259a88551 | ||
|
1ba050d603 | ||
|
e8717a4fce | ||
|
9b03307653 | ||
|
b735295d2b | ||
|
8d5cdedbd3 | ||
|
4f591e807a | ||
|
fb91c2550f | ||
|
0ddbd1c3a4 | ||
|
af83c82513 | ||
|
9d37b1b073 | ||
|
cf18eca86d | ||
|
ec1e6be003 | ||
|
83be2480c4 | ||
|
7affc34ab4 | ||
|
098e491a43 | ||
|
967fe76a60 | ||
|
940ed3d525 | ||
|
6f7280a690 | ||
|
20031cea92 | ||
|
3fb47372b7 | ||
|
bb160cfe37 | ||
|
a29cfa7843 | ||
|
f5fa84554f | ||
|
b88e4a1a9a | ||
|
ff411658e8 | ||
|
943c7d18cc | ||
|
ccfae82ad1 | ||
|
430b5c302a | ||
|
8fa4cfb7df | ||
|
a551f85b91 | ||
|
07052a515b | ||
|
1fa0cd7a75 | ||
|
c10739e6e3 | ||
|
9e628067fc | ||
|
99b01c5d12 | ||
|
a8ff3a452c | ||
|
dca75db127 | ||
|
a425fbebe4 | ||
|
cca227a53e | ||
|
b9c439a55e | ||
|
726d697821 | ||
|
0ccc0ace88 | ||
|
f43d4a8638 | ||
|
4c7a2faf85 | ||
|
3b66351eeb | ||
|
e58e97b0a3 | ||
|
2dd0b2af71 | ||
|
2ec2b3bfb3 | ||
|
0ec128e5ed | ||
|
083a5cf3c1 | ||
|
8f42401aa8 | ||
|
97a309b784 | ||
|
3bf6f78dad | ||
|
e4ab28b1fb | ||
|
81ad218b8b | ||
|
64c46db087 | ||
|
0920572e70 | ||
|
55ccb1a8cf | ||
|
d1638a09ba | ||
|
e3882b23d0 | ||
|
88e9e03945 | ||
|
0fb9a04526 | ||
|
44899cd548 | ||
|
cd0d049126 | ||
|
180c26ada6 | ||
|
5833abbbd1 | ||
|
514e0ff509 | ||
|
40081cb330 | ||
|
32b18179dd | ||
|
29e7dc6428 | ||
|
3c0605c68e | ||
|
d8b865366a | ||
|
3852418d24 | ||
|
c4d214c42d | ||
|
93b4478e70 | ||
|
7c7a84ff60 | ||
|
a0b2169ed6 | ||
|
ee91df62f0 | ||
|
12c1bb936d | ||
|
5f721dce36 | ||
|
d679d20029 | ||
|
7188ee4f99 | ||
|
c7315617eb | ||
|
d49a1334a8 | ||
|
2c481202ef | ||
|
6cf193e166 | ||
|
b1120ec433 | ||
|
5d4b54b012 | ||
|
b6e226c320 | ||
|
f9b52203f5 | ||
|
a3d3b4fd64 | ||
|
f3f7d3629a | ||
|
c356e42500 | ||
|
0b29caf9ab | ||
|
3dd8db83f1 | ||
|
d5689bb539 | ||
|
e5384774a8 | ||
|
f0e023bff2 | ||
|
3cec45d821 | ||
|
7f46680ab1 | ||
|
f603a22af0 | ||
|
cdac64970e | ||
|
6e0aadc585 | ||
|
2b6ff6837e | ||
|
29997ef4ba | ||
|
5e96d738e6 | ||
|
9df0f0b66c | ||
|
4093b993a2 | ||
|
08cc063e17 | ||
|
a17850e41c | ||
|
6a5c342063 | ||
|
f044e4c951 | ||
|
ce3ba798df | ||
|
0eaf3581a3 | ||
|
62ee5cc273 | ||
|
48bf32c5de | ||
|
904f9b6aee | ||
|
e5d3a71263 | ||
|
0e630e9e74 | ||
|
5f30cb7753 | ||
|
495b92fb53 | ||
|
b57086aa43 | ||
|
09581d32fd | ||
|
86e9f69a69 | ||
|
781828a56e | ||
|
0baf166d39 | ||
|
ace803948a | ||
|
01c2ff34dd | ||
|
22b1370ae5 | ||
|
f309681d4a | ||
|
ce62521883 | ||
|
e7fd0f5aec | ||
|
abfd550ee2 | ||
|
8e51a36c7f | ||
|
5c3bd8e93d | ||
|
05a5e0b4f1 | ||
|
b61d4c3636 | ||
|
e79d3cd2ef | ||
|
1822707c7e | ||
|
c3f7c9bbb5 | ||
|
ee8116ac5d | ||
|
f5db483973 | ||
|
7564b26b7d | ||
|
178a300eea | ||
|
d655a10381 | ||
|
b65773bea9 | ||
|
c4eb194033 | ||
|
6ae89940c7 | ||
|
3d28879c26 | ||
|
223dcc8bac | ||
|
6ce07ee864 | ||
|
bc299928ad | ||
|
ac658500fb | ||
|
8cced091f5 | ||
|
91299f7039 | ||
|
60308a2bb5 | ||
|
613eac4603 | ||
|
e4a26f4f1d | ||
|
57b632ead8 | ||
|
1bf63dfdcd | ||
|
e0cfbec66b | ||
|
b3a7e3109b | ||
|
45e82199fb | ||
|
4711796d38 | ||
|
0d70c44253 | ||
|
a364df4c9e | ||
|
46d990f1b6 | ||
|
5bf7b1e1fa | ||
|
97444ed7a8 | ||
|
4e41cda27e | ||
|
da86aac0f5 | ||
|
0c7a7e2d56 | ||
|
0ec6072a29 | ||
|
3ca699debf | ||
|
52c0919621 | ||
|
6fbfeefc71 | ||
|
46bf87c8d1 | ||
|
595eb89f6e | ||
|
a815b14bf1 | ||
|
3a5052a714 | ||
|
8e237b006f | ||
|
1ed925b69c | ||
|
aed529f695 | ||
|
de68e065fe | ||
|
e2426942e5 | ||
|
5c6c300abf | ||
|
6bd3397141 | ||
|
68fd32c810 | ||
|
3ddb16bd5b | ||
|
f6387536f6 | ||
|
968f6a6013 | ||
|
488efab636 | ||
|
6649255d54 | ||
|
4b00cba319 | ||
|
9e418671e1 | ||
|
d73c14751a | ||
|
6f313de952 | ||
|
2cf6e7862a | ||
|
58669fef77 | ||
|
e20aef7d53 | ||
|
b2143a98e2 | ||
|
f75f8efb1b | ||
|
be96787ed0 | ||
|
89d945aabe | ||
|
27211c71e9 | ||
|
14942bca60 | ||
|
77f2a01304 | ||
|
7b56ce6521 | ||
|
32a8caf7e7 | ||
|
caaa9b11e4 | ||
|
b1ad2d8066 | ||
|
22746b3046 | ||
|
49713fab04 | ||
|
8b86ee8bf0 | ||
|
2a052c69f3 | ||
|
2320b2241c | ||
|
8f5188269b | ||
|
00c8626863 | ||
|
0a211f29f5 | ||
|
d279d7c4c6 | ||
|
6c78b03bb7 | ||
|
f79497087b | ||
|
508bde1f61 | ||
|
e5ff19ac0f | ||
|
8579066c7a | ||
|
9232bc2c00 | ||
|
db0b764a5a | ||
|
278583b8a1 | ||
|
4414cd07e2 | ||
|
9e98fb0167 | ||
|
9856378384 | ||
|
dfa1bd0cd4 | ||
|
92df6b0dce | ||
|
71963972bf | ||
|
1bc05b1f9f | ||
|
e6cf643f5a | ||
|
94140e886e | ||
|
b248d59713 | ||
|
cbc0ff6ec0 | ||
|
6b6554adb8 | ||
|
d936eb437b | ||
|
883d01084c | ||
|
0564b46a5e | ||
|
3c9716acfd | ||
|
581f6659f8 | ||
|
e72ae6b25f | ||
|
9e35656244 | ||
|
e87758529e | ||
|
eb97d949aa | ||
|
e74efd87e5 | ||
|
4dbdb556fe | ||
|
5ee4b19691 | ||
|
d35e70a8c6 | ||
|
c35ed8363f | ||
|
d505b33665 | ||
|
118be4dea0 | ||
|
73b9756b8d | ||
|
8b9e385943 | ||
|
e01da1fd7a | ||
|
7a8c013edc | ||
|
518399a95b | ||
|
155d44016d | ||
|
13f90bb87a | ||
|
c67b257e51 | ||
|
8237d7e1a4 | ||
|
85da1a17d8 | ||
|
9609b04ff9 | ||
|
04421063af | ||
|
43e1415e71 | ||
|
e1448732b3 | ||
|
7c4c402bd7 | ||
|
6179b17903 | ||
|
05b48d48d9 | ||
|
07a21fdfa9 | ||
|
0f594732b0 | ||
|
312411fc70 | ||
|
70add904c4 | ||
|
5ca4823128 | ||
|
0500213086 | ||
|
b0fca6eaf0 | ||
|
4988e00b1d | ||
|
0fad7a0bb0 | ||
|
727f1b54cd | ||
|
c80457be02 | ||
|
4a42c5ed20 | ||
|
bd6d6e7f33 | ||
|
027140b731 | ||
|
ea10592ad3 | ||
|
9b54342baa | ||
|
8f9887b0c9 | ||
|
fa39df4731 | ||
|
f7249bd331 | ||
|
6934e7aa2b | ||
|
8bbeee2041 | ||
|
7a24e564f4 | ||
|
4b5b8a7630 | ||
|
5b1375141b | ||
|
4af9410dc2 | ||
|
a6315b0af4 | ||
|
cac59fefec | ||
|
1ac2fc3f7e | ||
|
cf6a1716ae | ||
|
10d7219807 | ||
|
838ed87d6f | ||
|
76b82fdde7 | ||
|
c5fd577181 | ||
|
fbd6354393 | ||
|
fd8d8e122e | ||
|
1c9d56998d | ||
|
242e06b242 | ||
|
25e72949a1 | ||
|
259dcd838e | ||
|
ef33198e8f | ||
|
604eb21a7e | ||
|
92a0dd164e | ||
|
b9b8e6220f | ||
|
a95df6b57e | ||
|
9642311ac2 | ||
|
98e99cd03d | ||
|
8210a1d7ac | ||
|
d105c7403c | ||
|
00ee1cf98e | ||
|
7dd0f76e5a | ||
|
17ed4fc04c | ||
|
6a8824253c | ||
|
eb42adc4c0 | ||
|
09dbcabcc7 | ||
|
72c7818ae6 | ||
|
1ea47950f4 | ||
|
8d6c18076f | ||
|
9c5a37a797 | ||
|
ca85455a8e | ||
|
28f6c2df59 | ||
|
83ab3ae0af | ||
|
b672118f92 | ||
|
aac90d9279 |
101
.clang-tidy
Normal file
@@ -0,0 +1,101 @@
|
||||
WarningsAsErrors: '*'
|
||||
HeaderFilterRegex: '.*\.hpp'
|
||||
FormatStyle: file
|
||||
Checks: >
|
||||
-*,
|
||||
bugprone-*,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-forward-declararion-namespace,
|
||||
-bugprone-forward-declararion-namespace,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-branch-clone,
|
||||
-bugprone-assignment-in-if-condition,
|
||||
concurrency-*,
|
||||
-concurrency-mt-unsafe,
|
||||
cppcoreguidelines-*,
|
||||
-cppcoreguidelines-owning-memory,
|
||||
-cppcoreguidelines-avoid-magic-numbers,
|
||||
-cppcoreguidelines-pro-bounds-constant-array-index,
|
||||
-cppcoreguidelines-avoid-const-or-ref-data-members,
|
||||
-cppcoreguidelines-non-private-member-variables-in-classes,
|
||||
-cppcoreguidelines-avoid-goto,
|
||||
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
-cppcoreguidelines-avoid-do-while,
|
||||
-cppcoreguidelines-avoid-non-const-global-variables,
|
||||
-cppcoreguidelines-special-member-functions,
|
||||
-cppcoreguidelines-explicit-virtual-functions,
|
||||
-cppcoreguidelines-avoid-c-arrays,
|
||||
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
||||
-cppcoreguidelines-narrowing-conversions,
|
||||
-cppcoreguidelines-pro-type-union-access,
|
||||
-cppcoreguidelines-pro-type-member-init,
|
||||
-cppcoreguidelines-macro-usage,
|
||||
-cppcoreguidelines-macro-to-enum,
|
||||
-cppcoreguidelines-init-variables,
|
||||
-cppcoreguidelines-pro-type-cstyle-cast,
|
||||
-cppcoreguidelines-pro-type-vararg,
|
||||
-cppcoreguidelines-pro-type-reinterpret-cast,
|
||||
google-global-names-in-headers,
|
||||
-google-readability-casting,
|
||||
google-runtime-operator,
|
||||
misc-*,
|
||||
-misc-unused-parameters,
|
||||
-misc-no-recursion,
|
||||
-misc-non-private-member-variables-in-classes,
|
||||
-misc-include-cleaner,
|
||||
-misc-use-anonymous-namespace,
|
||||
-misc-const-correctness,
|
||||
modernize-*,
|
||||
-modernize-return-braced-init-list,
|
||||
-modernize-use-trailing-return-type,
|
||||
-modernize-use-using,
|
||||
-modernize-use-override,
|
||||
-modernize-avoid-c-arrays,
|
||||
-modernize-macro-to-enum,
|
||||
-modernize-loop-convert,
|
||||
-modernize-use-nodiscard,
|
||||
-modernize-pass-by-value,
|
||||
-modernize-use-auto,
|
||||
performance-*,
|
||||
-performance-avoid-endl,
|
||||
-performance-unnecessary-value-param,
|
||||
portability-std-allocator-const,
|
||||
readability-*,
|
||||
-readability-function-cognitive-complexity,
|
||||
-readability-function-size,
|
||||
-readability-identifier-length,
|
||||
-readability-magic-numbers,
|
||||
-readability-uppercase-literal-suffix,
|
||||
-readability-braces-around-statements,
|
||||
-readability-redundant-access-specifiers,
|
||||
-readability-else-after-return,
|
||||
-readability-container-data-pointer,
|
||||
-readability-implicit-bool-conversion,
|
||||
-readability-avoid-nested-conditional-operator,
|
||||
-readability-redundant-member-init,
|
||||
-readability-redundant-string-init,
|
||||
-readability-avoid-const-params-in-decls,
|
||||
-readability-named-parameter,
|
||||
-readability-convert-member-functions-to-static,
|
||||
-readability-qualified-auto,
|
||||
-readability-make-member-function-const,
|
||||
-readability-isolate-declaration,
|
||||
-readability-inconsistent-declaration-parameter-name,
|
||||
-clang-diagnostic-error,
|
||||
|
||||
CheckOptions:
|
||||
performance-for-range-copy.WarnOnAllAutoCopies: true
|
||||
performance-inefficient-string-concatenation.StrictMode: true
|
||||
readability-braces-around-statements.ShortStatementLines: 0
|
||||
readability-identifier-naming.ClassCase: CamelCase
|
||||
readability-identifier-naming.ClassIgnoredRegexp: I.*
|
||||
readability-identifier-naming.ClassPrefix: C # We can't use regex here?!?!?!?
|
||||
readability-identifier-naming.EnumCase: CamelCase
|
||||
readability-identifier-naming.EnumPrefix: e
|
||||
readability-identifier-naming.EnumConstantCase: UPPER_CASE
|
||||
readability-identifier-naming.FunctionCase: camelBack
|
||||
readability-identifier-naming.NamespaceCase: CamelCase
|
||||
readability-identifier-naming.NamespacePrefix: N
|
||||
readability-identifier-naming.StructPrefix: S
|
||||
readability-identifier-naming.StructCase: CamelCase
|
83
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -2,12 +2,13 @@ name: Bug Report
|
||||
description: Something is not working right
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
value: |
|
||||
## Before opening a new issue, please take a moment to search through the current open and closed issues to check if it already exists.
|
||||
|
||||
---
|
||||
label: Already reported ? *
|
||||
description: Before opening a new bug report, please take a moment to search through the current open issues. If the same bug is already reported, don't open new issue - instead go upvote/comment on an existing one.
|
||||
options:
|
||||
- label: I have searched the existing open and closed issues.
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: type
|
||||
@@ -18,27 +19,28 @@ body:
|
||||
**BEFORE CONTINUING**, please check if this bug is a regression or not, and if it is, we need you to bisect with the help of the wiki: https://wiki.hyprland.org/Crashes-and-Bugs/#bisecting-an-issue
|
||||
multiple: true
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
- "Definitely a regression - something broke after update (requires bisect)"
|
||||
- "Probably not a regression / I don't remember it happening before"
|
||||
- "Not a regression - it's bug regarding new feature"
|
||||
- "Not a regression - it's an old bug"
|
||||
- "I don't know, I started using Hyprland only recently"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: ver
|
||||
attributes:
|
||||
label: System Info and Version
|
||||
label: System Info and Hyprland Version
|
||||
description: |
|
||||
Paste the output of `hyprctl systeminfo -c` here (If you are on a
|
||||
version that shows you help menu, omit the `-c` and attach config files
|
||||
to the issue). If you have configs outside of the main config shown
|
||||
here, please attach.
|
||||
Paste the output of `hyprctl systeminfo` here. If you can't
|
||||
launch Hyprland, paste the output of `Hyprland --systeminfo`.
|
||||
value: "<details>
|
||||
<summary>System/Version info</summary>
|
||||
|
||||
|
||||
```sh
|
||||
|
||||
<Paste the output of the command here>
|
||||
```
|
||||
|
||||
<Paste the output of the command here, without removing any formatting around this>
|
||||
|
||||
```
|
||||
|
||||
@@ -60,15 +62,56 @@ body:
|
||||
attributes:
|
||||
label: How to reproduce
|
||||
description: "How can someone else reproduce the issue?"
|
||||
placeholder: |
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Additional info section
|
||||
|
||||
In the section below you will be asked to upload some files.
|
||||
|
||||
When including text files (such as logs or config), please **always ATTACH** them, and not paste them directly.
|
||||
|
||||
This is important to avoid clutter, spam, and make the issues more readable.
|
||||
Thanks for your understanding.
|
||||
|
||||
# The main reason to disallow pasting directly or in a dropdown, is to not clutter
|
||||
# the issue with unnecessary keywords, making the github issue search useless.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Attach not paste
|
||||
options:
|
||||
- label: I understand that all text files must be *attached*, and not pasted directly. If not respected, this issue will likely get closed as spam
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >-
|
||||
Please be sure to upload the following files below if they are relevant to the issue:
|
||||
|
||||
- Logs can be found in $XDG_RUNTIME_DIR/hypr (sort by date to grab the latest)
|
||||
- Crash reports are stored in ~/.cache/hyprland or $XDG_CACHE_HOME/hyprland
|
||||
- Hyprland config files - `hyprctl systeminfo -c > /tmp/hyprland_config_dump.txt` use this command to dump full configuration to a single file.
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist of files to include below
|
||||
options:
|
||||
- label: Hyprland config - `hyprctl systeminfo -c` (always include)
|
||||
- label: Crash report (always include in case of crash)
|
||||
- label: Video (always include in case of a visual bug)
|
||||
- label: Logs (might contain useful info such as errors)
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Crash reports, logs, images, videos
|
||||
label: Additional info & File uploads
|
||||
description: |
|
||||
Anything that can help. Please always ATTACH and not paste them.
|
||||
Logs can be found in $XDG_RUNTIME_DIR/hypr
|
||||
Crash reports are stored in ~/.cache/hyprland or $XDG_CACHE_HOME/hyprland
|
||||
|
||||
Tip: You can attach files by clicking this area to highlight it and then dragging files in.
|
||||
|
19
.github/actions/setup_base/action.yml
vendored
@@ -33,7 +33,9 @@ runs:
|
||||
libfontenc \
|
||||
libglvnd \
|
||||
libinput \
|
||||
libjxl \
|
||||
libliftoff \
|
||||
libwebp \
|
||||
libxcursor \
|
||||
libxcvt \
|
||||
libxfont2 \
|
||||
@@ -58,7 +60,17 @@ runs:
|
||||
xcb-util \
|
||||
xcb-util-image \
|
||||
libzip \
|
||||
librsvg
|
||||
librsvg \
|
||||
re2
|
||||
|
||||
- name: Get glaze
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/stephenberry/glaze.git
|
||||
cd glaze
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
cmake --install build
|
||||
|
||||
- name: Get hyprwayland-scanner-git
|
||||
shell: bash
|
||||
@@ -69,6 +81,11 @@ runs:
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
cmake --install build
|
||||
|
||||
- name: Get hyprgraphics-git
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/hyprwm/hyprgraphics && cd hyprgraphics && cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -B build && cmake --build build --target hyprgraphics && cmake --install build
|
||||
|
||||
- name: Get hyprutils-git
|
||||
shell: bash
|
||||
run: |
|
||||
|
6
.github/pull_request_template.md
vendored
@@ -1,3 +1,9 @@
|
||||
<!--
|
||||
BEFORE you submit your PR, please check out the PR guidelines
|
||||
on our wiki: https://wiki.hyprland.org/Contributing-and-Debugging/PR-Guidelines/
|
||||
-->
|
||||
|
||||
|
||||
#### Describe your PR, what does it fix/add?
|
||||
|
||||
|
||||
|
27
.github/workflows/ci.yaml
vendored
@@ -39,7 +39,7 @@ jobs:
|
||||
tar -cvf Hyprland.tar.xz hyprland
|
||||
|
||||
- name: Release
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Build archive
|
||||
path: Hyprland.tar.xz
|
||||
@@ -107,6 +107,7 @@ jobs:
|
||||
run: make release
|
||||
|
||||
clang-format:
|
||||
permissions: read-all
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
||||
name: "Code Style (Arch)"
|
||||
runs-on: ubuntu-latest
|
||||
@@ -126,3 +127,27 @@ jobs:
|
||||
|
||||
- name: clang-format check
|
||||
run: ninja -C build clang-format-check
|
||||
|
||||
- name: clang-format apply
|
||||
if: ${{ failure() && github.event_name == 'pull_request' }}
|
||||
run: ninja -C build clang-format
|
||||
|
||||
- name: Create patch
|
||||
if: ${{ failure() && github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
echo 'Please fix the formatting issues by running [`clang-format`](https://wiki.hyprland.org/Contributing-and-Debugging/PR-Guidelines/#code-style), or directly apply this patch:' > clang-format.patch
|
||||
echo '<details>' >> clang-format.patch
|
||||
echo '<summary>clang-format.patch</summary>' >> clang-format.patch
|
||||
echo >> clang-format.patch
|
||||
echo '```diff' >> clang-format.patch
|
||||
git diff >> clang-format.patch
|
||||
echo '```' >> clang-format.patch
|
||||
echo >> clang-format.patch
|
||||
echo '</details>' >> clang-format.patch
|
||||
|
||||
- name: Comment patch
|
||||
if: ${{ failure() && github.event_name == 'pull_request' }}
|
||||
uses: mshick/add-pr-comment@v2
|
||||
with:
|
||||
message-path: |
|
||||
clang-format.patch
|
||||
|
4
.github/workflows/man-update.yaml
vendored
@@ -17,14 +17,14 @@ jobs:
|
||||
run: sudo apt install pandoc
|
||||
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.PAT }}
|
||||
|
||||
- name: Build man pages
|
||||
run: make man
|
||||
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
||||
name: Commit
|
||||
with:
|
||||
commit_message: "[gha] build man pages"
|
||||
|
17
.github/workflows/nix-build.yml
vendored
@@ -1,3 +1,5 @@
|
||||
name: Nix (Build)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
secrets:
|
||||
@@ -10,21 +12,18 @@ jobs:
|
||||
matrix:
|
||||
package:
|
||||
- hyprland
|
||||
# - hyprland-cross # cross compiling fails due to qt
|
||||
# failure chain: hyprland-qtutils -> qt6.qtsvg -> qt6.qtbase -> psqlodbc & qt6.qttranslations
|
||||
- xdg-desktop-portal-hyprland
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
submodules: recursive
|
||||
|
||||
- uses: cachix/install-nix-action@v27
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
|
||||
- uses: cachix/cachix-action@v15
|
||||
with:
|
||||
name: hyprland
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
|
||||
- run: nix build '.?submodules=1#${{ matrix.package }}' -L --extra-substituters "https://hyprland.cachix.org"
|
||||
- run: nix build 'github:hyprwm/Hyprland?ref=${{ github.ref }}#${{ matrix.package }}' -L --extra-substituters "https://hyprland.cachix.org"
|
||||
|
7
.github/workflows/nix-ci.yml
vendored
@@ -1,15 +1,14 @@
|
||||
name: Nix
|
||||
name: Nix (CI)
|
||||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
update-inputs:
|
||||
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
||||
uses: ./.github/workflows/nix-update-inputs.yml
|
||||
secrets: inherit
|
||||
|
||||
build:
|
||||
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork) && !contains(needs.*.result, 'failure')
|
||||
needs: update-inputs
|
||||
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork)
|
||||
uses: ./.github/workflows/nix-build.yml
|
||||
secrets: inherit
|
||||
|
7
.github/workflows/nix-update-inputs.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Nix
|
||||
name: Nix (Update Inputs)
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
@@ -8,11 +8,12 @@ on:
|
||||
|
||||
jobs:
|
||||
update:
|
||||
if: github.repository == 'hyprwm/Hyprland'
|
||||
name: inputs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.PAT }}
|
||||
|
||||
@@ -21,6 +22,6 @@ jobs:
|
||||
run: nix/update-inputs.sh
|
||||
|
||||
- name: Commit
|
||||
uses: stefanzweifel/git-auto-commit-action@v4
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "[gha] Nix: update inputs"
|
||||
|
3
.github/workflows/release.yaml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout Hyprland
|
||||
id: checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -20,7 +20,6 @@ jobs:
|
||||
run: |
|
||||
git fetch --unshallow || echo "failed unshallowing"
|
||||
bash -c scripts/generateVersion.sh
|
||||
mv scripts/generateVersion.sh scripts/generateVersion.sh.bak
|
||||
|
||||
- name: Create tarball with submodules
|
||||
id: tar
|
||||
|
2
.github/workflows/security-checks.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Scan with Flawfinder
|
||||
uses: david-a-wheeler/flawfinder@8e4a779ad59dbfaee5da586aa9210853b701959c
|
||||
|
18
.github/workflows/stale.yml
vendored
@@ -7,22 +7,22 @@ name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '7 */4 * * *'
|
||||
- cron: "7 */4 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
if: github.repository == 'hyprwm/Hyprland'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.STALEBOT_PAT }}
|
||||
stale-issue-label: 'stale'
|
||||
stale-pr-label: 'stale'
|
||||
operations-per-run: 40
|
||||
days-before-close: -1
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
repo-token: ${{ secrets.STALEBOT_PAT }}
|
||||
stale-issue-label: "stale"
|
||||
stale-pr-label: "stale"
|
||||
operations-per-run: 40
|
||||
days-before-close: -1
|
||||
|
4
.gitignore
vendored
@@ -14,6 +14,7 @@ _deps
|
||||
|
||||
build/
|
||||
result*
|
||||
/.pre-commit-config.yaml
|
||||
/.vscode/
|
||||
/.idea/
|
||||
.envrc
|
||||
@@ -39,3 +40,6 @@ PKGBUILD
|
||||
src/version.h
|
||||
hyprpm/Makefile
|
||||
hyprctl/Makefile
|
||||
|
||||
**/.#*.*
|
||||
**/#*.*#
|
||||
|
130
CMakeLists.txt
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.27)
|
||||
cmake_minimum_required(VERSION 3.30)
|
||||
|
||||
# Get version
|
||||
file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW)
|
||||
@@ -15,6 +15,7 @@ include(GNUInstallDirs)
|
||||
set(HYPRLAND_VERSION ${VER})
|
||||
set(PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||
set(INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
set(BINDIR ${CMAKE_INSTALL_BINDIR})
|
||||
configure_file(hyprland.pc.in hyprland.pc @ONLY)
|
||||
|
||||
set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
|
||||
@@ -25,8 +26,18 @@ message(STATUS "Gathering git info")
|
||||
execute_process(COMMAND ./scripts/generateVersion.sh
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# udis
|
||||
add_subdirectory("subprojects/udis86")
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
# Try to find canihavesomecoffee's udis86 using pkgconfig vmd/udis86 does not
|
||||
# provide a .pc file and won't be detected this way
|
||||
pkg_check_modules(udis_dep IMPORTED_TARGET udis86>=1.7.2)
|
||||
|
||||
# Fallback to subproject
|
||||
if(NOT udis_dep_FOUND)
|
||||
add_subdirectory("subprojects/udis86")
|
||||
include_directories("subprojects/udis86")
|
||||
message(STATUS "udis86 dependency not found, falling back to subproject")
|
||||
endif()
|
||||
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} BUILDTYPE_LOWER)
|
||||
@@ -47,8 +58,6 @@ else()
|
||||
set(BUILDTYPE_LOWER "release")
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
||||
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
||||
pkg_get_variable(WAYLAND_SCANNER_PKGDATA_DIR wayland-scanner pkgdatadir)
|
||||
@@ -63,7 +72,10 @@ else()
|
||||
message(STATUS "Configuring Hyprland in Release with CMake")
|
||||
endif()
|
||||
|
||||
include_directories(. "src/" "subprojects/udis86/" "protocols/")
|
||||
add_compile_definitions(HYPRLAND_VERSION="${HYPRLAND_VERSION}")
|
||||
|
||||
include_directories(. "src/" "protocols/")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 26)
|
||||
add_compile_options(
|
||||
-Wall
|
||||
@@ -89,18 +101,25 @@ else()
|
||||
endif()
|
||||
find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
||||
|
||||
pkg_check_modules(hyprctl_deps REQUIRED IMPORTED_TARGET hyprutils>=0.2.1)
|
||||
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.5)
|
||||
pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2)
|
||||
pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7)
|
||||
pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.4.0)
|
||||
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1)
|
||||
|
||||
add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}")
|
||||
add_compile_definitions(HYPRLANG_VERSION="${hyprlang_dep_VERSION}")
|
||||
add_compile_definitions(HYPRUTILS_VERSION="${hyprutils_dep_VERSION}")
|
||||
add_compile_definitions(HYPRCURSOR_VERSION="${hyprcursor_dep_VERSION}")
|
||||
add_compile_definitions(HYPRGRAPHICS_VERSION="${hyprgraphics_dep_VERSION}")
|
||||
|
||||
pkg_check_modules(
|
||||
deps
|
||||
REQUIRED
|
||||
IMPORTED_TARGET
|
||||
aquamarine
|
||||
xkbcommon
|
||||
uuid
|
||||
wayland-server
|
||||
wayland-client
|
||||
wayland-cursor
|
||||
wayland-server>=1.22.90
|
||||
wayland-protocols
|
||||
cairo
|
||||
pango
|
||||
@@ -109,16 +128,9 @@ pkg_check_modules(
|
||||
xcursor
|
||||
libdrm
|
||||
libinput
|
||||
hwdata
|
||||
libseat
|
||||
libdisplay-info
|
||||
libliftoff
|
||||
libudev
|
||||
gbm
|
||||
gio-2.0
|
||||
hyprlang>=0.3.2
|
||||
hyprcursor>=0.1.7
|
||||
hyprutils>=0.2.1)
|
||||
re2)
|
||||
|
||||
find_package(hyprwayland-scanner 0.3.10 REQUIRED)
|
||||
|
||||
@@ -200,14 +212,11 @@ else()
|
||||
REQUIRED
|
||||
IMPORTED_TARGET
|
||||
xcb
|
||||
xwayland
|
||||
xcb-util
|
||||
xcb-render
|
||||
xcb-xfixes
|
||||
xcb-icccm
|
||||
xcb-composite
|
||||
xcb-res
|
||||
xcb-ewmh
|
||||
xcb-errors)
|
||||
target_link_libraries(Hyprland PkgConfig::xdeps)
|
||||
endif()
|
||||
@@ -217,6 +226,15 @@ if(NO_SYSTEMD)
|
||||
else()
|
||||
message(STATUS "SYSTEMD support is requested (NO_SYSTEMD not defined)...")
|
||||
add_compile_definitions(USES_SYSTEMD)
|
||||
|
||||
# session file -uwsm
|
||||
if(NO_UWSM)
|
||||
message(STATUS "UWSM support is disabled...")
|
||||
else()
|
||||
message(STATUS "UWSM support is enabled (NO_UWSM not defined)...")
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/systemd/hyprland-uwsm.desktop
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
@@ -230,14 +248,27 @@ target_precompile_headers(Hyprland PRIVATE
|
||||
|
||||
message(STATUS "Setting link libraries")
|
||||
|
||||
target_link_libraries(Hyprland rt PkgConfig::deps)
|
||||
target_link_libraries(
|
||||
Hyprland
|
||||
rt
|
||||
PkgConfig::aquamarine_dep
|
||||
PkgConfig::hyprlang_dep
|
||||
PkgConfig::hyprutils_dep
|
||||
PkgConfig::hyprcursor_dep
|
||||
PkgConfig::hyprgraphics_dep
|
||||
PkgConfig::deps)
|
||||
if(udis_dep_FOUND)
|
||||
target_link_libraries(Hyprland PkgConfig::udis_dep)
|
||||
else()
|
||||
target_link_libraries(Hyprland libudis86)
|
||||
endif()
|
||||
|
||||
# used by `make installheaders`, to ensure the headers are generated
|
||||
add_custom_target(generate-protocol-headers)
|
||||
|
||||
function(protocolnew protoPath protoName external)
|
||||
if(external)
|
||||
set(path ${CMAKE_SOURCE_DIR}/${protoPath})
|
||||
set(path ${protoPath})
|
||||
else()
|
||||
set(path ${WAYLAND_PROTOCOLS_DIR}/${protoPath})
|
||||
endif()
|
||||
@@ -265,14 +296,22 @@ function(protocolWayland)
|
||||
PRIVATE ${CMAKE_SOURCE_DIR}/protocols/wayland.hpp)
|
||||
endfunction()
|
||||
|
||||
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads
|
||||
libudis86 uuid)
|
||||
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads)
|
||||
|
||||
protocolnew("subprojects/hyprland-protocols/protocols"
|
||||
"hyprland-global-shortcuts-v1" true)
|
||||
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.6.0)
|
||||
if(hyprland_protocols_dep_FOUND)
|
||||
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
|
||||
message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}")
|
||||
else()
|
||||
set(HYPRLAND_PROTOCOLS "subprojects/hyprland-protocols")
|
||||
message(STATUS "hyprland-protocols subproject set to ${HYPRLAND_PROTOCOLS}")
|
||||
endif()
|
||||
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-global-shortcuts-v1"
|
||||
true)
|
||||
protocolnew("unstable/text-input" "text-input-unstable-v1" false)
|
||||
protocolnew("subprojects/hyprland-protocols/protocols"
|
||||
"hyprland-toplevel-export-v1" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-toplevel-export-v1"
|
||||
true)
|
||||
protocolnew("protocols" "wlr-screencopy-unstable-v1" true)
|
||||
protocolnew("protocols" "wlr-gamma-control-unstable-v1" true)
|
||||
protocolnew("protocols" "wlr-foreign-toplevel-management-unstable-v1" true)
|
||||
@@ -283,10 +322,15 @@ protocolnew("protocols" "input-method-unstable-v2" true)
|
||||
protocolnew("protocols" "wlr-output-management-unstable-v1" true)
|
||||
protocolnew("protocols" "kde-server-decoration" true)
|
||||
protocolnew("protocols" "wlr-data-control-unstable-v1" true)
|
||||
protocolnew("subprojects/hyprland-protocols/protocols" "hyprland-focus-grab-v1"
|
||||
true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-focus-grab-v1" true)
|
||||
protocolnew("protocols" "wlr-layer-shell-unstable-v1" true)
|
||||
protocolnew("protocols" "xx-color-management-v4" true)
|
||||
protocolnew("protocols" "frog-color-management-v1" true)
|
||||
protocolnew("protocols" "wayland-drm" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-ctm-control-v1" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-surface-v1" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-lock-notify-v1" true)
|
||||
|
||||
protocolnew("staging/tearing-control" "tearing-control-v1" false)
|
||||
protocolnew("staging/fractional-scale" "fractional-scale-v1" false)
|
||||
protocolnew("unstable/xdg-output" "xdg-output-unstable-v1" false)
|
||||
@@ -315,12 +359,21 @@ protocolnew("stable/viewporter" "viewporter" false)
|
||||
protocolnew("stable/linux-dmabuf" "linux-dmabuf-v1" false)
|
||||
protocolnew("staging/drm-lease" "drm-lease-v1" false)
|
||||
protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false)
|
||||
protocolnew("staging/xdg-dialog" "xdg-dialog-v1" false)
|
||||
protocolnew("staging/single-pixel-buffer" "single-pixel-buffer-v1" false)
|
||||
protocolnew("staging/security-context" "security-context-v1" false)
|
||||
|
||||
protocolwayland()
|
||||
|
||||
# tools
|
||||
add_subdirectory(hyprctl)
|
||||
add_subdirectory(hyprpm)
|
||||
|
||||
if(NO_HYPRPM)
|
||||
message(STATUS "hyprpm is disabled")
|
||||
else()
|
||||
add_subdirectory(hyprpm)
|
||||
message(STATUS "hyprpm is enabled (NO_HYPRPM not defined)")
|
||||
endif()
|
||||
|
||||
# binary and symlink
|
||||
install(TARGETS Hyprland)
|
||||
@@ -331,17 +384,18 @@ install(
|
||||
${CMAKE_INSTALL_FULL_BINDIR}/Hyprland \
|
||||
\"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/hyprland\" \
|
||||
)")
|
||||
|
||||
# session file
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.desktop
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
||||
|
||||
# allow Hyprland to find wallpapers
|
||||
# allow Hyprland to find assets
|
||||
add_compile_definitions(DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}")
|
||||
|
||||
# wallpapers
|
||||
file(GLOB_RECURSE WALLPAPERS "assets/wall*")
|
||||
install(FILES ${WALLPAPERS} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hypr)
|
||||
# installable assets
|
||||
file(GLOB_RECURSE INSTALLABLE_ASSETS "assets/install/*")
|
||||
list(FILTER INSTALLABLE_ASSETS EXCLUDE REGEX "meson.build")
|
||||
install(FILES ${INSTALLABLE_ASSETS}
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hypr)
|
||||
|
||||
# default config
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.conf
|
||||
|
27
Makefile
@@ -1,28 +1,27 @@
|
||||
PREFIX = /usr/local
|
||||
|
||||
stub:
|
||||
@echo "Do not run $(MAKE) directly without any arguments. Please refer to the wiki on how to compile Hyprland."
|
||||
|
||||
legacyrenderer:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build -G Ninja
|
||||
cmake --build ./build --config Release --target all
|
||||
chmod -R 777 ./build
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
legacyrendererdebug:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build -G Ninja
|
||||
cmake --build ./build --config Release --target all
|
||||
chmod -R 777 ./build
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
||||
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
release:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build -G Ninja
|
||||
cmake --build ./build --config Release --target all
|
||||
chmod -R 777 ./build
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
debug:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build -G Ninja
|
||||
cmake --build ./build --config Debug --target all
|
||||
chmod -R 777 ./build
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build
|
||||
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
nopch:
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -S . -B ./build -G Ninja
|
||||
cmake --build ./build --config Release --target all
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
|
||||
clear:
|
||||
rm -rf build
|
||||
|
@@ -100,7 +100,7 @@ easy IPC, much more QoL stuff than other compositors and more...
|
||||
|
||||
<!----------------------------------------------------------------------------->
|
||||
|
||||
[Configure]: https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||
[Configure]: https://wiki.hyprland.org/Configuring/
|
||||
[Stars]: https://starchart.cc/hyprwm/Hyprland
|
||||
[Hypr]: https://github.com/hyprwm/Hypr
|
||||
|
||||
|
BIN
assets/install/lockdead.png
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
assets/install/lockdead2.png
Normal file
After Width: | Height: | Size: 48 KiB |
10
assets/install/meson.build
Normal file
@@ -0,0 +1,10 @@
|
||||
globber = run_command('sh', '-c', 'find . -type f -not -name "*.build"', check: true)
|
||||
files = globber.stdout().strip().split('\n')
|
||||
|
||||
foreach file : files
|
||||
install_data(
|
||||
file,
|
||||
install_dir: join_paths(get_option('datadir'), 'hypr'),
|
||||
install_tag: 'runtime',
|
||||
)
|
||||
endforeach
|
Before Width: | Height: | Size: 14 MiB After Width: | Height: | Size: 14 MiB |
Before Width: | Height: | Size: 5.9 MiB After Width: | Height: | Size: 5.9 MiB |
Before Width: | Height: | Size: 27 MiB After Width: | Height: | Size: 27 MiB |
@@ -1,7 +1,7 @@
|
||||
wallpapers = ['0', '1', '2']
|
||||
install_data(
|
||||
'hyprland-portals.conf',
|
||||
install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'),
|
||||
install_tag: 'runtime',
|
||||
)
|
||||
|
||||
foreach type : wallpapers
|
||||
install_data(f'wall@type@.png', install_dir: join_paths(get_option('datadir'), 'hypr'), install_tag: 'runtime')
|
||||
endforeach
|
||||
|
||||
install_data('hyprland-portals.conf', install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'), install_tag: 'runtime')
|
||||
subdir('install')
|
||||
|
@@ -10,8 +10,8 @@ Hyprland - Dynamic tiling Wayland compositor
|
||||
\f[B]Hyprland\f[R] [\f[I]arg [...]\f[R]].
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\f[B]Hyprland\f[R] is a dynamic tiling Wayland compositor based on
|
||||
wlroots that doesn\[aq]t sacrifice on its looks.
|
||||
\f[B]Hyprland\f[R] is an independent, highly customizable, dynamic
|
||||
tiling Wayland compositor that doesn\[aq]t sacrifice on its looks.
|
||||
.PP
|
||||
You can launch Hyprland by either going into a TTY and executing
|
||||
\f[B]Hyprland\f[R], or with a login manager.
|
||||
|
@@ -14,8 +14,8 @@ SYNOPSIS
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
**Hyprland** is a dynamic tiling Wayland compositor based on
|
||||
wlroots that doesn't sacrifice on its looks.
|
||||
**Hyprland** is an independent, highly customizable,
|
||||
dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
|
||||
|
||||
You can launch Hyprland by either going into a TTY and
|
||||
executing **Hyprland**, or with a login manager.
|
||||
|
@@ -3,7 +3,7 @@
|
||||
First of all, please remember to:
|
||||
- Check that your issue is not a duplicate
|
||||
- Read the [FAQ](https://wiki.hyprland.org/FAQ/)
|
||||
- Read the [Configuring Page](https://wiki.hyprland.org/Configuring/Configuring-Hyprland)
|
||||
- Read the [Configuring Page](https://wiki.hyprland.org/Configuring/)
|
||||
|
||||
<br/>
|
||||
|
||||
|
@@ -1,2 +1,2 @@
|
||||
install_man ('Hyprland.1')
|
||||
install_man ('hyprctl.1')
|
||||
install_man('Hyprland.1')
|
||||
install_man('hyprctl.1')
|
||||
|
@@ -1,14 +0,0 @@
|
||||
[Unit]
|
||||
Description=Hyprland - Tiling compositor with the looks
|
||||
Documentation=man:Hyprland(1)
|
||||
BindsTo=graphical-session.target
|
||||
Before=graphical-session.target
|
||||
Wants=graphical-session-pre.target
|
||||
After=graphical-session-pre.target
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=/usr/bin/Hyprland
|
||||
ExecStop=/usr/bin/hyprctl dispatch exit
|
||||
Restart=on-failure
|
||||
Slice=session.slice
|
@@ -1,6 +1,6 @@
|
||||
# This is an example Hyprland config file.
|
||||
# Refer to the wiki for more information.
|
||||
# https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||
# https://wiki.hyprland.org/Configuring/
|
||||
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki
|
||||
@@ -59,7 +59,7 @@ env = HYPRCURSOR_SIZE,24
|
||||
# Refer to https://wiki.hyprland.org/Configuring/Variables/
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#general
|
||||
general {
|
||||
general {
|
||||
gaps_in = 5
|
||||
gaps_out = 20
|
||||
|
||||
@@ -70,7 +70,7 @@ general {
|
||||
col.inactive_border = rgba(595959aa)
|
||||
|
||||
# Set to true enable resizing windows by clicking and dragging on borders and gaps
|
||||
resize_on_border = false
|
||||
resize_on_border = false
|
||||
|
||||
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
|
||||
allow_tearing = false
|
||||
@@ -81,42 +81,69 @@ general {
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||
decoration {
|
||||
rounding = 10
|
||||
rounding_power = 2
|
||||
|
||||
# Change transparency of focused and unfocused windows
|
||||
active_opacity = 1.0
|
||||
inactive_opacity = 1.0
|
||||
|
||||
drop_shadow = true
|
||||
shadow_range = 4
|
||||
shadow_render_power = 3
|
||||
col.shadow = rgba(1a1a1aee)
|
||||
shadow {
|
||||
enabled = true
|
||||
range = 4
|
||||
render_power = 3
|
||||
color = rgba(1a1a1aee)
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
||||
blur {
|
||||
enabled = true
|
||||
size = 3
|
||||
passes = 1
|
||||
|
||||
|
||||
vibrancy = 0.1696
|
||||
}
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
||||
animations {
|
||||
enabled = true
|
||||
enabled = yes, please :)
|
||||
|
||||
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||
|
||||
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
||||
bezier = easeOutQuint,0.23,1,0.32,1
|
||||
bezier = easeInOutCubic,0.65,0.05,0.36,1
|
||||
bezier = linear,0,0,1,1
|
||||
bezier = almostLinear,0.5,0.5,0.75,1.0
|
||||
bezier = quick,0.15,0,0.1,1
|
||||
|
||||
animation = windows, 1, 7, myBezier
|
||||
animation = windowsOut, 1, 7, default, popin 80%
|
||||
animation = border, 1, 10, default
|
||||
animation = borderangle, 1, 8, default
|
||||
animation = fade, 1, 7, default
|
||||
animation = workspaces, 1, 6, default
|
||||
animation = global, 1, 10, default
|
||||
animation = border, 1, 5.39, easeOutQuint
|
||||
animation = windows, 1, 4.79, easeOutQuint
|
||||
animation = windowsIn, 1, 4.1, easeOutQuint, popin 87%
|
||||
animation = windowsOut, 1, 1.49, linear, popin 87%
|
||||
animation = fadeIn, 1, 1.73, almostLinear
|
||||
animation = fadeOut, 1, 1.46, almostLinear
|
||||
animation = fade, 1, 3.03, quick
|
||||
animation = layers, 1, 3.81, easeOutQuint
|
||||
animation = layersIn, 1, 4, easeOutQuint, fade
|
||||
animation = layersOut, 1, 1.5, linear, fade
|
||||
animation = fadeLayersIn, 1, 1.79, almostLinear
|
||||
animation = fadeLayersOut, 1, 1.39, almostLinear
|
||||
animation = workspaces, 1, 1.94, almostLinear, fade
|
||||
animation = workspacesIn, 1, 1.21, almostLinear, fade
|
||||
animation = workspacesOut, 1, 1.94, almostLinear, fade
|
||||
}
|
||||
|
||||
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
||||
# "Smart gaps" / "No gaps when only"
|
||||
# uncomment all if you wish to use that.
|
||||
# workspace = w[tv1], gapsout:0, gapsin:0
|
||||
# workspace = f[1], gapsout:0, gapsin:0
|
||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tv1]
|
||||
# windowrulev2 = rounding 0, floating:0, onworkspace:w[tv1]
|
||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:f[1]
|
||||
# windowrulev2 = rounding 0, floating:0, onworkspace:f[1]
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||
dwindle {
|
||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||
@@ -129,7 +156,7 @@ master {
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#misc
|
||||
misc {
|
||||
misc {
|
||||
force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
|
||||
disable_hyprland_logo = false # If true disables the random hyprland logo / anime girl background. :(
|
||||
}
|
||||
@@ -228,6 +255,19 @@ bind = $mainMod, mouse_up, workspace, e-1
|
||||
bindm = $mainMod, mouse:272, movewindow
|
||||
bindm = $mainMod, mouse:273, resizewindow
|
||||
|
||||
# Laptop multimedia keys for volume and LCD brightness
|
||||
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+
|
||||
bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||
bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||
bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||
bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+
|
||||
bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%-
|
||||
|
||||
# Requires playerctl
|
||||
bindl = , XF86AudioNext, exec, playerctl next
|
||||
bindl = , XF86AudioPause, exec, playerctl play-pause
|
||||
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
||||
bindl = , XF86AudioPrev, exec, playerctl previous
|
||||
|
||||
##############################
|
||||
### WINDOWS AND WORKSPACES ###
|
||||
@@ -242,4 +282,8 @@ bindm = $mainMod, mouse:273, resizewindow
|
||||
# Example windowrule v2
|
||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||
|
||||
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
|
||||
# Ignore maximize requests from apps. You'll probably like this.
|
||||
windowrulev2 = suppressevent maximize, class:.*
|
||||
|
||||
# Fix some dragging issues with XWayland
|
||||
windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
|
||||
|
@@ -2,4 +2,6 @@
|
||||
Name=Hyprland
|
||||
Comment=An intelligent dynamic tiling Wayland compositor
|
||||
Exec=Hyprland
|
||||
Type=Application
|
||||
Type=Application
|
||||
DesktopNames=Hyprland
|
||||
Keywords=tiling;wayland;compositor;
|
||||
|
@@ -22,5 +22,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
]
|
||||
}
|
@@ -1,2 +1,10 @@
|
||||
install_data('hyprland.conf', install_dir: join_paths(get_option('datadir'), 'hypr'), install_tag: 'runtime')
|
||||
install_data('hyprland.desktop', install_dir: join_paths(get_option('datadir'), 'wayland-sessions'), install_tag: 'runtime')
|
||||
install_data(
|
||||
'hyprland.conf',
|
||||
install_dir: join_paths(get_option('datadir'), 'hypr'),
|
||||
install_tag: 'runtime',
|
||||
)
|
||||
install_data(
|
||||
'hyprland.desktop',
|
||||
install_dir: join_paths(get_option('datadir'), 'wayland-sessions'),
|
||||
install_tag: 'runtime',
|
||||
)
|
||||
|
305
flake.lock
generated
@@ -16,11 +16,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1724273991,
|
||||
"narHash": "sha256-+aUSOXKGpS5CRm1oTitgNAr05ThQNbKIXalZHl3nC6Y=",
|
||||
"lastModified": 1737636397,
|
||||
"narHash": "sha256-F5MbBj3QVorycVSFE9qjuOTLtIQBqt2VWbXa0uwzm98=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "aquamarine",
|
||||
"rev": "9a3161ad4c78dc420d1cbb3aae638222608c7de4",
|
||||
"rev": "7fe006981fae53e931f513026fc754e322f13145",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -29,6 +29,43 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprcursor": {
|
||||
"inputs": {
|
||||
"hyprlang": [
|
||||
@@ -42,11 +79,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722623071,
|
||||
"narHash": "sha256-sLADpVgebpCBFXkA1FlCXtvEPu1tdEsTfqK1hfeHySE=",
|
||||
"lastModified": 1737634937,
|
||||
"narHash": "sha256-Ffw4ujFpi++6pPHe+gCBOfDgAoNlzVPZN6MReC1beu8=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprcursor",
|
||||
"rev": "912d56025f03d41b1ad29510c423757b4379eb1c",
|
||||
"rev": "9c5dd1f7c825ee47f72727ad0a4e16ca46a2688e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -55,32 +92,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-protocols": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"xdph",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"xdph",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1721326555,
|
||||
"narHash": "sha256-zCu4R0CSHEactW9JqYki26gy8h9f6rHmSwj4XJmlHgg=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"rev": "5a11232266bf1a1f5952d5b179c3f4b2facaaa84",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprlang": {
|
||||
"hyprgraphics": {
|
||||
"inputs": {
|
||||
"hyprutils": [
|
||||
"hyprutils"
|
||||
@@ -93,11 +105,141 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1724174162,
|
||||
"narHash": "sha256-fOOBLwil6M9QWMCiSULwjMQzrXhHXUnEqmjHX5ZHeVI=",
|
||||
"lastModified": 1737634889,
|
||||
"narHash": "sha256-9JZE3KxcXOqZH9zs3UeadngDiK/yIACTiAR8HSA/TNI=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprgraphics",
|
||||
"rev": "0d77b4895ad5f1bb3b0ee43103a5246c58b65591",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprgraphics",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-protocols": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737556638,
|
||||
"narHash": "sha256-laKgI3mr2qz6tas/q3tuGPxMdsGhBi/w+HO+hO2f1AY=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"rev": "4c75dd5c015c8a0e5a34c6d02a018a650f57feb5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-protocols",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-qt-support": {
|
||||
"inputs": {
|
||||
"hyprlang": "hyprlang",
|
||||
"nixpkgs": [
|
||||
"hyprland-qtutils",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland-qtutils",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634706,
|
||||
"narHash": "sha256-nGCibkfsXz7ARx5R+SnisRtMq21IQIhazp6viBU8I/A=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qt-support",
|
||||
"rev": "8810df502cdee755993cb803eba7b23f189db795",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qt-support",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprland-qtutils": {
|
||||
"inputs": {
|
||||
"hyprland-qt-support": "hyprland-qt-support",
|
||||
"hyprutils": [
|
||||
"hyprutils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737811848,
|
||||
"narHash": "sha256-WZ7LeiKHk5Y94MU5gHIWn0r8asWxYOvie4LqfCjVIZU=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qtutils",
|
||||
"rev": "9c0831ff98856c0f312fcb8b57553fbe3dd34d5b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-qtutils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprlang": {
|
||||
"inputs": {
|
||||
"hyprutils": "hyprutils",
|
||||
"nixpkgs": [
|
||||
"hyprland-qtutils",
|
||||
"hyprland-qt-support",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland-qtutils",
|
||||
"hyprland-qt-support",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634606,
|
||||
"narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"rev": "16e5c9465f04477d8a3dd48a0a26bf437986336c",
|
||||
"rev": "f41271d35cc0f370d300413d756c2677f386af9d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprlang_2": {
|
||||
"inputs": {
|
||||
"hyprutils": [
|
||||
"hyprutils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737634606,
|
||||
"narHash": "sha256-W7W87Cv6wqZ9PHegI6rH1+ve3zJPiyevMFf0/HwdbCQ=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"rev": "f41271d35cc0f370d300413d756c2677f386af9d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -107,6 +249,35 @@
|
||||
}
|
||||
},
|
||||
"hyprutils": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"hyprland-qtutils",
|
||||
"hyprland-qt-support",
|
||||
"hyprlang",
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"hyprland-qtutils",
|
||||
"hyprland-qt-support",
|
||||
"hyprlang",
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737632363,
|
||||
"narHash": "sha256-X9I8POSlHxBVjD0fiX1O2j7U9Zi1+4rIkrsyHP0uHXY=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "006620eb29d54ea9086538891404c78563d1bae1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprutils_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
@@ -116,11 +287,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722869141,
|
||||
"narHash": "sha256-0KU4qhyMp441qfwbirNg3+wbm489KnEjXOz2I/RbeFs=",
|
||||
"lastModified": 1737725508,
|
||||
"narHash": "sha256-jGmcPc6y/prg/4A8KGYqJ27nSPaProCMiFadaxNAKvA=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "0252fd13e78e60fb0da512a212e56007515a49f7",
|
||||
"rev": "fb0c2d1de3d1ef7396d19c18ac09e12bd956929e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -139,11 +310,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1721324119,
|
||||
"narHash": "sha256-SOOqIT27/X792+vsLSeFdrNTF+OSRp5qXv6Te+fb2Qg=",
|
||||
"lastModified": 1735493474,
|
||||
"narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwayland-scanner",
|
||||
"rev": "a048a6cb015340bd82f97c1f40a4b595ca85cc30",
|
||||
"rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -154,11 +325,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1724224976,
|
||||
"narHash": "sha256-Z/ELQhrSd7bMzTO8r7NZgi9g5emh+aRKoCdaAv5fiO0=",
|
||||
"lastModified": 1737632463,
|
||||
"narHash": "sha256-38J9QfeGSej341ouwzqf77WIHAScihAKCt8PQJ+NH28=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c374d94f1536013ca8e92341b540eba4c22f9c62",
|
||||
"rev": "0aa475546ed21629c4f5bbf90e38c846a99ec9e9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -168,14 +339,40 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1737465171,
|
||||
"narHash": "sha256-R10v2hoJRLq8jcL4syVFag7nIGE7m13qO48wRIukWNg=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"aquamarine": "aquamarine",
|
||||
"hyprcursor": "hyprcursor",
|
||||
"hyprlang": "hyprlang",
|
||||
"hyprutils": "hyprutils",
|
||||
"hyprgraphics": "hyprgraphics",
|
||||
"hyprland-protocols": "hyprland-protocols",
|
||||
"hyprland-qtutils": "hyprland-qtutils",
|
||||
"hyprlang": "hyprlang_2",
|
||||
"hyprutils": "hyprutils_2",
|
||||
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks",
|
||||
"systems": "systems",
|
||||
"xdph": "xdph"
|
||||
}
|
||||
@@ -197,10 +394,18 @@
|
||||
},
|
||||
"xdph": {
|
||||
"inputs": {
|
||||
"hyprland-protocols": "hyprland-protocols",
|
||||
"hyprland-protocols": [
|
||||
"hyprland-protocols"
|
||||
],
|
||||
"hyprlang": [
|
||||
"hyprlang"
|
||||
],
|
||||
"hyprutils": [
|
||||
"hyprutils"
|
||||
],
|
||||
"hyprwayland-scanner": [
|
||||
"hyprwayland-scanner"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
@@ -209,11 +414,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1724073926,
|
||||
"narHash": "sha256-nWlUL43jOFHf+KW6Hqrx+W/r1XdXuDyb0wC/SrHsOu4=",
|
||||
"lastModified": 1737634991,
|
||||
"narHash": "sha256-dBAnb7Kbnier30cA7AgxVSxxARmxKZ1vHZT33THSIr8=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "xdg-desktop-portal-hyprland",
|
||||
"rev": "a08ecbbf33598924e93542f737fc6169a26b481e",
|
||||
"rev": "e09dfe2726c8008f983e45a0aa1a3b7416aaeb8a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
61
flake.nix
@@ -22,6 +22,26 @@
|
||||
inputs.hyprlang.follows = "hyprlang";
|
||||
};
|
||||
|
||||
hyprgraphics = {
|
||||
url = "github:hyprwm/hyprgraphics";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.systems.follows = "systems";
|
||||
inputs.hyprutils.follows = "hyprutils";
|
||||
};
|
||||
|
||||
hyprland-protocols = {
|
||||
url = "github:hyprwm/hyprland-protocols";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.systems.follows = "systems";
|
||||
};
|
||||
|
||||
hyprland-qtutils = {
|
||||
url = "github:hyprwm/hyprland-qtutils";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.systems.follows = "systems";
|
||||
inputs.hyprutils.follows = "hyprutils";
|
||||
};
|
||||
|
||||
hyprlang = {
|
||||
url = "github:hyprwm/hyprlang";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
@@ -45,7 +65,15 @@
|
||||
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.systems.follows = "systems";
|
||||
inputs.hyprland-protocols.follows = "hyprland-protocols";
|
||||
inputs.hyprlang.follows = "hyprlang";
|
||||
inputs.hyprutils.follows = "hyprutils";
|
||||
inputs.hyprwayland-scanner.follows = "hyprwayland-scanner";
|
||||
};
|
||||
|
||||
pre-commit-hooks = {
|
||||
url = "github:cachix/git-hooks.nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -65,6 +93,15 @@
|
||||
hyprland-extras
|
||||
];
|
||||
});
|
||||
pkgsCrossFor = eachSystem (system: crossSystem:
|
||||
import nixpkgs {
|
||||
localSystem = system;
|
||||
inherit crossSystem;
|
||||
overlays = with self.overlays; [
|
||||
hyprland-packages
|
||||
hyprland-extras
|
||||
];
|
||||
});
|
||||
in {
|
||||
overlays = import ./nix/overlays.nix {inherit self lib inputs;};
|
||||
|
||||
@@ -74,6 +111,18 @@
|
||||
self.packages.${system})
|
||||
// {
|
||||
inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
|
||||
pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
|
||||
src = ./.;
|
||||
hooks = {
|
||||
hyprland-treewide-formatter = {
|
||||
enable = true;
|
||||
entry = "${self.formatter.${system}}/bin/hyprland-treewide-formatter";
|
||||
pass_filenames = false;
|
||||
excludes = ["subprojects"];
|
||||
always_run = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
packages = eachSystem (system: {
|
||||
@@ -81,34 +130,30 @@
|
||||
inherit
|
||||
(pkgsFor.${system})
|
||||
# hyprland-packages
|
||||
|
||||
hyprland
|
||||
hyprland-debug
|
||||
hyprland-legacy-renderer
|
||||
hyprland-unwrapped
|
||||
# hyprland-extras
|
||||
|
||||
xdg-desktop-portal-hyprland
|
||||
;
|
||||
hyprland-cross = (pkgsCrossFor.${system} "aarch64-linux").hyprland;
|
||||
});
|
||||
|
||||
devShells = eachSystem (system: {
|
||||
default =
|
||||
pkgsFor.${system}.mkShell.override {
|
||||
stdenv = pkgsFor.${system}.gcc14Stdenv;
|
||||
inherit (self.packages.${system}.default) stdenv;
|
||||
} {
|
||||
name = "hyprland-shell";
|
||||
nativeBuildInputs = with pkgsFor.${system}; [
|
||||
expat
|
||||
libxml2
|
||||
];
|
||||
hardeningDisable = ["fortify"];
|
||||
inputsFrom = [pkgsFor.${system}.hyprland];
|
||||
packages = [pkgsFor.${system}.clang-tools];
|
||||
inherit (self.checks.${system}.pre-commit-check) shellHook;
|
||||
};
|
||||
});
|
||||
|
||||
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
formatter = eachSystem (system: pkgsFor.${system}.callPackage ./nix/formatter.nix {});
|
||||
|
||||
nixosModules.default = import ./nix/module.nix inputs;
|
||||
homeManagerModules.default = import ./nix/hm-module.nix self;
|
||||
|
@@ -5,7 +5,7 @@ project(
|
||||
DESCRIPTION "Control utility for Hyprland"
|
||||
)
|
||||
|
||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET hyprutils>=0.1.1)
|
||||
pkg_check_modules(hyprctl_deps REQUIRED IMPORTED_TARGET hyprutils>=0.2.4 re2)
|
||||
|
||||
add_executable(hyprctl "main.cpp")
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
const std::string_view USAGE = R"#(usage: hyprctl [flags] <command> [args...|--help]
|
||||
|
||||
commands:
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#include <re2/re2.h>
|
||||
|
||||
#include <cctype>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -17,13 +19,12 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <print>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <filesystem>
|
||||
#include <cstdarg>
|
||||
#include <regex>
|
||||
#include <sys/socket.h>
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <cstring>
|
||||
@@ -44,18 +45,24 @@ struct SInstanceData {
|
||||
bool valid = true;
|
||||
};
|
||||
|
||||
void log(std::string str) {
|
||||
void log(const std::string& str) {
|
||||
if (quiet)
|
||||
return;
|
||||
|
||||
std::cout << str << "\n";
|
||||
std::println("{}", str);
|
||||
}
|
||||
|
||||
static int getUID() {
|
||||
const auto UID = getuid();
|
||||
const auto PWUID = getpwuid(UID);
|
||||
return PWUID ? PWUID->pw_uid : UID;
|
||||
}
|
||||
|
||||
std::string getRuntimeDir() {
|
||||
const auto XDG = getenv("XDG_RUNTIME_DIR");
|
||||
|
||||
if (!XDG) {
|
||||
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
|
||||
const std::string USERID = std::to_string(getUID());
|
||||
return "/run/user/" + USERID + "/hypr";
|
||||
}
|
||||
|
||||
@@ -65,6 +72,11 @@ std::string getRuntimeDir() {
|
||||
std::vector<SInstanceData> instances() {
|
||||
std::vector<SInstanceData> result;
|
||||
|
||||
try {
|
||||
if (!std::filesystem::exists(getRuntimeDir()))
|
||||
return {};
|
||||
} catch (std::exception& e) { return {}; }
|
||||
|
||||
for (const auto& el : std::filesystem::directory_iterator(getRuntimeDir())) {
|
||||
if (!el.is_directory() || !std::filesystem::exists(el.path().string() + "/hyprland.lock"))
|
||||
continue;
|
||||
@@ -105,7 +117,7 @@ std::vector<SInstanceData> instances() {
|
||||
static volatile bool sigintReceived = false;
|
||||
void intHandler(int sig) {
|
||||
sigintReceived = true;
|
||||
std::cout << "[hyprctl] SIGINT received, closing connection" << std::endl;
|
||||
std::println("[hyprctl] SIGINT received, closing connection");
|
||||
}
|
||||
|
||||
int rollingRead(const int socket) {
|
||||
@@ -115,12 +127,12 @@ int rollingRead(const int socket) {
|
||||
constexpr size_t BUFFER_SIZE = 8192;
|
||||
std::array<char, BUFFER_SIZE> buffer = {0};
|
||||
long sizeWritten = 0;
|
||||
std::cout << "[hyprctl] reading from socket following up log:" << std::endl;
|
||||
std::println("[hyprctl] reading from socket following up log:");
|
||||
while (!sigintReceived) {
|
||||
sizeWritten = read(socket, buffer.data(), BUFFER_SIZE);
|
||||
if (sizeWritten < 0 && errno != EAGAIN) {
|
||||
if (errno != EINTR)
|
||||
std::cout << "Couldn't read (5) " << strerror(errno) << ":" << errno << std::endl;
|
||||
std::println("Couldn't read (5): {}: {}", strerror(errno), errno);
|
||||
close(socket);
|
||||
return 5;
|
||||
}
|
||||
@@ -129,7 +141,7 @@ int rollingRead(const int socket) {
|
||||
break;
|
||||
|
||||
if (sizeWritten > 0) {
|
||||
std::cout << std::string(buffer.data(), sizeWritten);
|
||||
std::println("{}", std::string(buffer.data(), sizeWritten));
|
||||
buffer.fill('\0');
|
||||
}
|
||||
|
||||
@@ -162,7 +174,7 @@ int request(std::string arg, int minArgs = 0, bool needRoll = false) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
|
||||
const std::string USERID = std::to_string(getUID());
|
||||
|
||||
sockaddr_un serverAddress = {0};
|
||||
serverAddress.sun_family = AF_UNIX;
|
||||
@@ -232,7 +244,7 @@ int requestHyprpaper(std::string arg) {
|
||||
sockaddr_un serverAddress = {0};
|
||||
serverAddress.sun_family = AF_UNIX;
|
||||
|
||||
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
|
||||
const std::string USERID = std::to_string(getUID());
|
||||
|
||||
std::string socketPath = getRuntimeDir() + "/" + instanceSignature + "/.hyprpaper.sock";
|
||||
|
||||
@@ -270,10 +282,11 @@ int requestHyprpaper(std::string arg) {
|
||||
}
|
||||
|
||||
void batchRequest(std::string arg, bool json) {
|
||||
std::string commands = arg.substr(arg.find_first_of(" ") + 1);
|
||||
std::string commands = arg.substr(arg.find_first_of(' ') + 1);
|
||||
|
||||
if (json) {
|
||||
commands = "j/" + std::regex_replace(commands, std::regex(";\\s*"), ";j/");
|
||||
RE2::GlobalReplace(&commands, ";\\s*", ";j/");
|
||||
commands.insert(0, "j/");
|
||||
}
|
||||
|
||||
std::string rq = "[[BATCH]]" + commands;
|
||||
@@ -287,12 +300,12 @@ void instancesRequest(bool json) {
|
||||
std::vector<SInstanceData> inst = instances();
|
||||
|
||||
if (!json) {
|
||||
for (auto& el : inst) {
|
||||
for (auto const& el : inst) {
|
||||
result += std::format("instance {}:\n\ttime: {}\n\tpid: {}\n\twl socket: {}\n\n", el.id, el.time, el.pid, el.wlSocket);
|
||||
}
|
||||
} else {
|
||||
result += '[';
|
||||
for (auto& el : inst) {
|
||||
for (auto const& el : inst) {
|
||||
result += std::format(R"#(
|
||||
{{
|
||||
"instance": "{}",
|
||||
@@ -310,11 +323,11 @@ void instancesRequest(bool json) {
|
||||
log(result + "\n");
|
||||
}
|
||||
|
||||
std::deque<std::string> splitArgs(int argc, char** argv) {
|
||||
std::deque<std::string> result;
|
||||
std::vector<std::string> splitArgs(int argc, char** argv) {
|
||||
std::vector<std::string> result;
|
||||
|
||||
for (auto i = 1 /* skip the executable */; i < argc; ++i)
|
||||
result.push_back(std::string(argv[i]));
|
||||
result.emplace_back(argv[i]);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -323,7 +336,7 @@ int main(int argc, char** argv) {
|
||||
bool parseArgs = true;
|
||||
|
||||
if (argc < 2) {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -360,7 +373,7 @@ int main(int argc, char** argv) {
|
||||
++i;
|
||||
|
||||
if (i >= ARGS.size()) {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -371,24 +384,24 @@ int main(int argc, char** argv) {
|
||||
const std::string& cmd = ARGS[0];
|
||||
|
||||
if (cmd == "hyprpaper") {
|
||||
std::cout << HYPRPAPER_HELP << std::endl;
|
||||
std::println("{}", HYPRPAPER_HELP);
|
||||
} else if (cmd == "notify") {
|
||||
std::cout << NOTIFY_HELP << std::endl;
|
||||
std::println("{}", NOTIFY_HELP);
|
||||
} else if (cmd == "output") {
|
||||
std::cout << OUTPUT_HELP << std::endl;
|
||||
std::println("{}", OUTPUT_HELP);
|
||||
} else if (cmd == "plugin") {
|
||||
std::cout << PLUGIN_HELP << std::endl;
|
||||
std::println("{}", PLUGIN_HELP);
|
||||
} else if (cmd == "setprop") {
|
||||
std::cout << SETPROP_HELP << std::endl;
|
||||
std::println("{}", SETPROP_HELP);
|
||||
} else if (cmd == "switchxkblayout") {
|
||||
std::cout << SWITCHXKBLAYOUT_HELP << std::endl;
|
||||
std::println("{}", SWITCHXKBLAYOUT_HELP);
|
||||
} else {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -399,7 +412,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
if (fullRequest.empty()) {
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -476,7 +489,7 @@ int main(int argc, char** argv) {
|
||||
else if (fullRequest.contains("/decorations"))
|
||||
exitStatus = request(fullRequest, 1);
|
||||
else if (fullRequest.contains("/--help"))
|
||||
std::cout << USAGE << std::endl;
|
||||
std::println("{}", USAGE);
|
||||
else if (fullRequest.contains("/rollinglog") && needRoll)
|
||||
exitStatus = request(fullRequest, 0, true);
|
||||
else {
|
||||
|
@@ -1,10 +1,27 @@
|
||||
executable('hyprctl', 'main.cpp',
|
||||
executable(
|
||||
'hyprctl',
|
||||
'main.cpp',
|
||||
dependencies: [
|
||||
dependency('hyprutils', version: '>= 0.1.1'),
|
||||
dependency('re2', required: true)
|
||||
],
|
||||
install: true
|
||||
install: true,
|
||||
)
|
||||
|
||||
install_data('hyprctl.bash', install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'), install_tag: 'runtime', rename: 'hyprctl')
|
||||
install_data('hyprctl.fish', install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'), install_tag: 'runtime')
|
||||
install_data('hyprctl.zsh', install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'), install_tag: 'runtime', rename: '_hyprctl')
|
||||
install_data(
|
||||
'hyprctl.bash',
|
||||
install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'),
|
||||
install_tag: 'runtime',
|
||||
rename: 'hyprctl',
|
||||
)
|
||||
install_data(
|
||||
'hyprctl.fish',
|
||||
install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'),
|
||||
install_tag: 'runtime',
|
||||
)
|
||||
install_data(
|
||||
'hyprctl.zsh',
|
||||
install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'),
|
||||
install_tag: 'runtime',
|
||||
rename: '_hyprctl',
|
||||
)
|
||||
|
@@ -9,11 +9,25 @@ file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
|
||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET tomlplusplus hyprutils>=0.1.1)
|
||||
pkg_check_modules(hyprpm_deps REQUIRED IMPORTED_TARGET tomlplusplus hyprutils>=0.2.4)
|
||||
|
||||
find_package(glaze QUIET)
|
||||
if (NOT glaze_FOUND)
|
||||
set(GLAZE_VERSION v4.2.3)
|
||||
message(STATUS "glaze dependency not found, retrieving ${GLAZE_VERSION} with FetchContent")
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
glaze
|
||||
GIT_REPOSITORY https://github.com/stephenberry/glaze.git
|
||||
GIT_TAG ${GLAZE_VERSION}
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(glaze)
|
||||
endif()
|
||||
|
||||
add_executable(hyprpm ${SRCFILES})
|
||||
|
||||
target_link_libraries(hyprpm PUBLIC PkgConfig::deps)
|
||||
target_link_libraries(hyprpm PUBLIC PkgConfig::hyprpm_deps glaze::glaze)
|
||||
|
||||
# binary
|
||||
install(TARGETS hyprpm)
|
||||
|
@@ -14,7 +14,7 @@ hyprpm [<FLAGS>]... <ARGUMENT>
|
||||
| (list) "List all installed plugins"
|
||||
| (enable <PLUGINS>) "Load a plugin"
|
||||
| (disable <PLUGINS>) "Unload a plugin"
|
||||
| (reload) "Reload all plugins"
|
||||
| (reload) "Reload plugins to match the enabled/disabled state. Use -f to force reload."
|
||||
;
|
||||
|
||||
<PLUGINS> ::= {{{ hyprpm list | awk '/Plugin/{print $4}' }}};
|
||||
|
@@ -1,14 +1,13 @@
|
||||
#include "DataState.hpp"
|
||||
#include <toml++/toml.hpp>
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include <print>
|
||||
#include <fstream>
|
||||
#include "PluginManager.hpp"
|
||||
|
||||
std::string DataState::getDataStatePath() {
|
||||
std::filesystem::path DataState::getDataStatePath() {
|
||||
const auto HOME = getenv("HOME");
|
||||
if (!HOME) {
|
||||
std::cerr << "DataState: no $HOME\n";
|
||||
std::println(stderr, "DataState: no $HOME");
|
||||
throw std::runtime_error("no $HOME");
|
||||
return "";
|
||||
}
|
||||
@@ -16,12 +15,29 @@ std::string DataState::getDataStatePath() {
|
||||
const auto XDG_DATA_HOME = getenv("XDG_DATA_HOME");
|
||||
|
||||
if (XDG_DATA_HOME)
|
||||
return std::string{XDG_DATA_HOME} + "/hyprpm";
|
||||
return std::string{HOME} + "/.local/share/hyprpm";
|
||||
return std::filesystem::path{XDG_DATA_HOME} / "hyprpm";
|
||||
return std::filesystem::path{HOME} / ".local/share/hyprpm";
|
||||
}
|
||||
|
||||
std::string DataState::getHeadersPath() {
|
||||
return getDataStatePath() + "/headersRoot";
|
||||
return getDataStatePath() / "headersRoot";
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> DataState::getPluginStates() {
|
||||
ensureStateStoreExists();
|
||||
|
||||
std::vector<std::filesystem::path> states;
|
||||
for (const auto& entry : std::filesystem::directory_iterator(getDataStatePath())) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
const auto stateFile = entry.path() / "state.toml";
|
||||
if (!std::filesystem::exists(stateFile))
|
||||
continue;
|
||||
|
||||
states.emplace_back(stateFile);
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
void DataState::ensureStateStoreExists() {
|
||||
@@ -37,7 +53,7 @@ void DataState::ensureStateStoreExists() {
|
||||
void DataState::addNewPluginRepo(const SPluginRepository& repo) {
|
||||
ensureStateStoreExists();
|
||||
|
||||
const auto PATH = getDataStatePath() + "/" + repo.name;
|
||||
const auto PATH = getDataStatePath() / repo.name;
|
||||
|
||||
std::filesystem::create_directories(PATH);
|
||||
// clang-format off
|
||||
@@ -49,20 +65,22 @@ void DataState::addNewPluginRepo(const SPluginRepository& repo) {
|
||||
{"rev", repo.rev}
|
||||
}}
|
||||
};
|
||||
for (auto& p : repo.plugins) {
|
||||
for (auto const& p : repo.plugins) {
|
||||
const auto filename = p.name + ".so";
|
||||
|
||||
// copy .so to the good place
|
||||
if (std::filesystem::exists(p.filename))
|
||||
std::filesystem::copy_file(p.filename, PATH + "/" + p.name + ".so");
|
||||
std::filesystem::copy_file(p.filename, PATH / filename);
|
||||
|
||||
DATA.emplace(p.name, toml::table{
|
||||
{"filename", p.name + ".so"},
|
||||
{"filename", filename},
|
||||
{"enabled", p.enabled},
|
||||
{"failed", p.failed}
|
||||
});
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
std::ofstream ofs(PATH + "/state.toml", std::ios::trunc);
|
||||
std::ofstream ofs(PATH / "state.toml", std::ios::trunc);
|
||||
ofs << DATA;
|
||||
ofs.close();
|
||||
}
|
||||
@@ -72,17 +90,10 @@ bool DataState::pluginRepoExists(const std::string& urlOrName) {
|
||||
|
||||
const auto PATH = getDataStatePath();
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::exists(entry.path().string() + "/state.toml"))
|
||||
continue;
|
||||
|
||||
auto STATE = toml::parse_file(entry.path().string() + "/state.toml");
|
||||
|
||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
||||
const auto URL = STATE["repository"]["url"].value_or("");
|
||||
for (const auto& stateFile : getPluginStates()) {
|
||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
||||
const auto URL = STATE["repository"]["url"].value_or("");
|
||||
|
||||
if (URL == urlOrName || NAME == urlOrName)
|
||||
return true;
|
||||
@@ -96,29 +107,22 @@ void DataState::removePluginRepo(const std::string& urlOrName) {
|
||||
|
||||
const auto PATH = getDataStatePath();
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::exists(entry.path().string() + "/state.toml"))
|
||||
continue;
|
||||
|
||||
auto STATE = toml::parse_file(entry.path().string() + "/state.toml");
|
||||
|
||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
||||
const auto URL = STATE["repository"]["url"].value_or("");
|
||||
for (const auto& stateFile : getPluginStates()) {
|
||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
||||
const auto URL = STATE["repository"]["url"].value_or("");
|
||||
|
||||
if (URL == urlOrName || NAME == urlOrName) {
|
||||
|
||||
// unload the plugins!!
|
||||
for (const auto& file : std::filesystem::directory_iterator(entry.path())) {
|
||||
for (const auto& file : std::filesystem::directory_iterator(stateFile.parent_path())) {
|
||||
if (!file.path().string().ends_with(".so"))
|
||||
continue;
|
||||
|
||||
g_pPluginManager->loadUnloadPlugin(std::filesystem::absolute(file.path()), false);
|
||||
}
|
||||
|
||||
std::filesystem::remove_all(entry.path());
|
||||
std::filesystem::remove_all(stateFile.parent_path());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -139,7 +143,7 @@ void DataState::updateGlobalState(const SGlobalState& state) {
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
std::ofstream ofs(PATH + "/state.toml", std::ios::trunc);
|
||||
std::ofstream ofs(PATH / "state.toml", std::ios::trunc);
|
||||
ofs << DATA;
|
||||
ofs.close();
|
||||
}
|
||||
@@ -147,12 +151,12 @@ void DataState::updateGlobalState(const SGlobalState& state) {
|
||||
SGlobalState DataState::getGlobalState() {
|
||||
ensureStateStoreExists();
|
||||
|
||||
const auto PATH = getDataStatePath();
|
||||
const auto stateFile = getDataStatePath() / "state.toml";
|
||||
|
||||
if (!std::filesystem::exists(PATH + "/state.toml"))
|
||||
if (!std::filesystem::exists(stateFile))
|
||||
return SGlobalState{};
|
||||
|
||||
auto DATA = toml::parse_file(PATH + "/state.toml");
|
||||
auto DATA = toml::parse_file(stateFile.c_str());
|
||||
|
||||
SGlobalState state;
|
||||
state.headersHashCompiled = DATA["state"]["hash"].value_or("");
|
||||
@@ -167,15 +171,8 @@ std::vector<SPluginRepository> DataState::getAllRepositories() {
|
||||
const auto PATH = getDataStatePath();
|
||||
|
||||
std::vector<SPluginRepository> repos;
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::exists(entry.path().string() + "/state.toml"))
|
||||
continue;
|
||||
|
||||
auto STATE = toml::parse_file(entry.path().string() + "/state.toml");
|
||||
for (const auto& stateFile : getPluginStates()) {
|
||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
||||
|
||||
const auto NAME = STATE["repository"]["name"].value_or("");
|
||||
const auto URL = STATE["repository"]["url"].value_or("");
|
||||
@@ -210,15 +207,8 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) {
|
||||
|
||||
const auto PATH = getDataStatePath();
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(PATH)) {
|
||||
if (!entry.is_directory() || entry.path().stem() == "headersRoot")
|
||||
continue;
|
||||
|
||||
if (!std::filesystem::exists(entry.path().string() + "/state.toml"))
|
||||
continue;
|
||||
|
||||
auto STATE = toml::parse_file(entry.path().string() + "/state.toml");
|
||||
|
||||
for (const auto& stateFile : getPluginStates()) {
|
||||
const auto STATE = toml::parse_file(stateFile.c_str());
|
||||
for (const auto& [key, val] : STATE) {
|
||||
if (key == "repository")
|
||||
continue;
|
||||
@@ -231,10 +221,11 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) {
|
||||
if (FAILED)
|
||||
return false;
|
||||
|
||||
(*STATE[key].as_table()).insert_or_assign("enabled", enabled);
|
||||
auto modifiedState = STATE;
|
||||
(*modifiedState[key].as_table()).insert_or_assign("enabled", enabled);
|
||||
|
||||
std::ofstream state(entry.path().string() + "/state.toml", std::ios::trunc);
|
||||
state << STATE;
|
||||
std::ofstream state(stateFile, std::ios::trunc);
|
||||
state << modifiedState;
|
||||
state.close();
|
||||
|
||||
return true;
|
||||
@@ -242,4 +233,4 @@ bool DataState::setPluginEnabled(const std::string& name, bool enabled) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Plugin.hpp"
|
||||
@@ -9,14 +10,15 @@ struct SGlobalState {
|
||||
};
|
||||
|
||||
namespace DataState {
|
||||
std::string getDataStatePath();
|
||||
std::string getHeadersPath();
|
||||
void ensureStateStoreExists();
|
||||
void addNewPluginRepo(const SPluginRepository& repo);
|
||||
void removePluginRepo(const std::string& urlOrName);
|
||||
bool pluginRepoExists(const std::string& urlOrName);
|
||||
void updateGlobalState(const SGlobalState& state);
|
||||
SGlobalState getGlobalState();
|
||||
bool setPluginEnabled(const std::string& name, bool enabled);
|
||||
std::vector<SPluginRepository> getAllRepositories();
|
||||
std::filesystem::path getDataStatePath();
|
||||
std::string getHeadersPath();
|
||||
std::vector<std::filesystem::path> getPluginStates();
|
||||
void ensureStateStoreExists();
|
||||
void addNewPluginRepo(const SPluginRepository& repo);
|
||||
void removePluginRepo(const std::string& urlOrName);
|
||||
bool pluginRepoExists(const std::string& urlOrName);
|
||||
void updateGlobalState(const SGlobalState& state);
|
||||
SGlobalState getGlobalState();
|
||||
bool setPluginEnabled(const std::string& name, bool enabled);
|
||||
std::vector<SPluginRepository> getAllRepositories();
|
||||
};
|
@@ -6,7 +6,7 @@ CManifest::CManifest(const eManifestType type, const std::string& path) {
|
||||
auto manifest = toml::parse_file(path);
|
||||
|
||||
if (type == MANIFEST_HYPRLOAD) {
|
||||
for (auto& [key, val] : manifest) {
|
||||
for (auto const& [key, val] : manifest) {
|
||||
if (key.str().ends_with(".build"))
|
||||
continue;
|
||||
|
||||
@@ -63,7 +63,7 @@ CManifest::CManifest(const eManifestType type, const std::string& path) {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& [key, val] : manifest) {
|
||||
for (auto const& [key, val] : manifest) {
|
||||
if (key.str() == "repository")
|
||||
continue;
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
enum eHeadersErrors {
|
||||
HEADERS_OK = 0,
|
||||
@@ -26,7 +27,8 @@ enum ePluginLoadStateReturn {
|
||||
LOADSTATE_OK = 0,
|
||||
LOADSTATE_FAIL,
|
||||
LOADSTATE_PARTIAL_FAIL,
|
||||
LOADSTATE_HEADERS_OUTDATED
|
||||
LOADSTATE_HEADERS_OUTDATED,
|
||||
LOADSTATE_HYPRLAND_UPDATED
|
||||
};
|
||||
|
||||
struct SHyprlandVersion {
|
||||
@@ -49,10 +51,10 @@ class CPluginManager {
|
||||
|
||||
bool enablePlugin(const std::string& name);
|
||||
bool disablePlugin(const std::string& name);
|
||||
ePluginLoadStateReturn ensurePluginsLoadState();
|
||||
ePluginLoadStateReturn ensurePluginsLoadState(bool forceReload = false);
|
||||
|
||||
bool loadUnloadPlugin(const std::string& path, bool load);
|
||||
SHyprlandVersion getHyprlandVersion();
|
||||
SHyprlandVersion getHyprlandVersion(bool running = true);
|
||||
|
||||
void notify(const eNotifyIcons icon, uint32_t color, int durationMs, const std::string& message);
|
||||
|
||||
@@ -68,7 +70,7 @@ class CPluginManager {
|
||||
std::string headerError(const eHeadersErrors err);
|
||||
std::string headerErrorShort(const eHeadersErrors err);
|
||||
|
||||
std::string m_szWorkingPluginDirectory = "";
|
||||
std::string m_szWorkingPluginDirectory;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CPluginManager> g_pPluginManager;
|
||||
|
32
hyprpm/src/helpers/StringUtils.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <format>
|
||||
#include <string>
|
||||
#include "Colors.hpp"
|
||||
|
||||
template <typename... Args>
|
||||
std::string statusString(const std::string_view emoji, const std::string_view color, const std::string_view fmt, Args&&... args) {
|
||||
std::string ret = std::format("{}{}{} ", color, emoji, Colors::RESET);
|
||||
ret += std::vformat(fmt, std::make_format_args(args...));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string successString(const std::string_view fmt, Args&&... args) {
|
||||
return statusString("✔", Colors::GREEN, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string failureString(const std::string_view fmt, Args&&... args) {
|
||||
return statusString("✖", Colors::RED, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string verboseString(const std::string_view fmt, Args&&... args) {
|
||||
return statusString("[v]", Colors::BLUE, fmt, args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string infoString(const std::string_view fmt, Args&&... args) {
|
||||
return statusString("→", Colors::RESET, fmt, args...);
|
||||
}
|
@@ -1,15 +1,16 @@
|
||||
#include "progress/CProgressBar.hpp"
|
||||
#include "helpers/Colors.hpp"
|
||||
#include "helpers/StringUtils.hpp"
|
||||
#include "core/PluginManager.hpp"
|
||||
#include "core/DataState.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <print>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||
constexpr std::string_view HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||
┃
|
||||
┣ add [url] [git rev] → Install a new plugin repository from git. Git revision
|
||||
┃ is optional, when set, commit locks are ignored.
|
||||
@@ -22,7 +23,8 @@ const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||
┃
|
||||
┣ Flags:
|
||||
┃
|
||||
┣ --notify | -n → Send a hyprland notification for important events (e.g. load fail)
|
||||
┣ --notify | -n → Send a hyprland notification for important events (including both successes and fail events)
|
||||
┣ --notify-fail | -nn → Send a hyprland notification for fail events only
|
||||
┣ --help | -h → Show this menu
|
||||
┣ --verbose | -v → Enable too much logging
|
||||
┣ --force | -f → Force an operation ignoring checks (e.g. update -f)
|
||||
@@ -30,36 +32,38 @@ const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||
┗
|
||||
)#";
|
||||
|
||||
int main(int argc, char** argv, char** envp) {
|
||||
int main(int argc, char** argv, char** envp) {
|
||||
std::vector<std::string> ARGS{argc};
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
ARGS[i] = std::string{argv[i]};
|
||||
}
|
||||
|
||||
if (ARGS.size() < 2) {
|
||||
std::cout << HELP;
|
||||
std::println(stderr, "{}", HELP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<std::string> command;
|
||||
bool notify = false, verbose = false, force = false, noShallow = false;
|
||||
bool notify = false, notifyFail = false, verbose = false, force = false, noShallow = false;
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (ARGS[i].starts_with("-")) {
|
||||
if (ARGS[i] == "--help" || ARGS[i] == "-h") {
|
||||
std::cout << HELP;
|
||||
std::println("{}", HELP);
|
||||
return 0;
|
||||
} else if (ARGS[i] == "--notify" || ARGS[i] == "-n") {
|
||||
notify = true;
|
||||
} else if (ARGS[i] == "--notify-fail" || ARGS[i] == "-nn") {
|
||||
notifyFail = notify = true;
|
||||
} else if (ARGS[i] == "--verbose" || ARGS[i] == "-v") {
|
||||
verbose = true;
|
||||
} else if (ARGS[i] == "--no-shallow" || ARGS[i] == "-s") {
|
||||
noShallow = true;
|
||||
} else if (ARGS[i] == "--force" || ARGS[i] == "-f") {
|
||||
force = true;
|
||||
std::cout << Colors::RED << "!" << Colors::RESET << " Using --force, I hope you know what you are doing.\n";
|
||||
std::println("{}", statusString("!", Colors::RED, "Using --force, I hope you know what you are doing."));
|
||||
} else {
|
||||
std::cerr << "Unrecognized option " << ARGS[i] << "\n";
|
||||
std::println(stderr, "Unrecognized option {}", ARGS[i]);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
@@ -68,8 +72,8 @@ int main(int argc, char** argv, char** envp) {
|
||||
}
|
||||
|
||||
if (command.empty()) {
|
||||
std::cout << HELP;
|
||||
return 0;
|
||||
std::println(stderr, "{}", HELP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_pPluginManager = std::make_unique<CPluginManager>();
|
||||
@@ -78,7 +82,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
|
||||
if (command[0] == "add") {
|
||||
if (command.size() < 2) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for add.\n";
|
||||
std::println(stderr, "{}", failureString("Not enough args for add."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -90,7 +94,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1;
|
||||
} else if (command[0] == "remove") {
|
||||
if (ARGS.size() < 2) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for remove.\n";
|
||||
std::println(stderr, "{}", failureString("Not enough args for remove."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -99,7 +103,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
bool headersValid = g_pPluginManager->headersValid() == HEADERS_OK;
|
||||
bool headers = g_pPluginManager->updateHeaders(force);
|
||||
if (headers) {
|
||||
const auto HLVER = g_pPluginManager->getHyprlandVersion();
|
||||
const auto HLVER = g_pPluginManager->getHyprlandVersion(false);
|
||||
auto GLOBALSTATE = DataState::getGlobalState();
|
||||
const auto COMPILEDOUTDATED = HLVER.hash != GLOBALSTATE.headersHashCompiled;
|
||||
|
||||
@@ -110,32 +114,39 @@ int main(int argc, char** argv, char** envp) {
|
||||
|
||||
auto ret2 = g_pPluginManager->ensurePluginsLoadState();
|
||||
|
||||
if (ret2 == LOADSTATE_HYPRLAND_UPDATED)
|
||||
g_pPluginManager->notify(ICON_INFO, 0, 10000, "[hyprpm] Updated plugins, but Hyprland was updated. Please restart Hyprland.");
|
||||
|
||||
if (ret2 != LOADSTATE_OK)
|
||||
return 1;
|
||||
} else if (notify)
|
||||
g_pPluginManager->notify(ICON_ERROR, 0, 10000, "[hyprpm] Couldn't update headers");
|
||||
} else if (command[0] == "enable") {
|
||||
if (ARGS.size() < 2) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for enable.\n";
|
||||
std::println(stderr, "{}", failureString("Not enough args for enable."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!g_pPluginManager->enablePlugin(command[1])) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Couldn't enable plugin (missing?)\n";
|
||||
std::println(stderr, "{}", failureString("Couldn't enable plugin (missing?)"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto ret = g_pPluginManager->ensurePluginsLoadState();
|
||||
|
||||
if (ret == LOADSTATE_HYPRLAND_UPDATED)
|
||||
g_pPluginManager->notify(ICON_INFO, 0, 10000, "[hyprpm] Enabled plugin, but Hyprland was updated. Please restart Hyprland.");
|
||||
|
||||
if (ret != LOADSTATE_OK)
|
||||
return 1;
|
||||
} else if (command[0] == "disable") {
|
||||
if (command.size() < 2) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for disable.\n";
|
||||
std::println(stderr, "{}", failureString("Not enough args for disable."));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!g_pPluginManager->disablePlugin(command[1])) {
|
||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Couldn't disable plugin (missing?)\n";
|
||||
std::println(stderr, "{}", failureString("Couldn't disable plugin (missing?)"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -143,7 +154,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
if (ret != LOADSTATE_OK)
|
||||
return 1;
|
||||
} else if (command[0] == "reload") {
|
||||
auto ret = g_pPluginManager->ensurePluginsLoadState();
|
||||
auto ret = g_pPluginManager->ensurePluginsLoadState(force);
|
||||
|
||||
if (ret != LOADSTATE_OK && notify) {
|
||||
switch (ret) {
|
||||
@@ -154,15 +165,16 @@ int main(int argc, char** argv, char** envp) {
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
} else if (notify) {
|
||||
return 1;
|
||||
} else if (notify && !notifyFail) {
|
||||
g_pPluginManager->notify(ICON_OK, 0, 4000, "[hyprpm] Loaded plugins");
|
||||
}
|
||||
} else if (command[0] == "list") {
|
||||
g_pPluginManager->listAllPlugins();
|
||||
} else {
|
||||
std::cout << HELP;
|
||||
std::println(stderr, "{}", HELP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +1,32 @@
|
||||
globber = run_command('sh', '-c', 'find . -name "*.cpp" | sort', check: true)
|
||||
src = globber.stdout().strip().split('\n')
|
||||
|
||||
executable('hyprpm', src,
|
||||
executable(
|
||||
'hyprpm',
|
||||
src,
|
||||
dependencies: [
|
||||
dependency('hyprutils', version: '>= 0.1.1'),
|
||||
dependency('threads'),
|
||||
dependency('tomlplusplus')
|
||||
dependency('tomlplusplus'),
|
||||
dependency('glaze', method: 'cmake'),
|
||||
],
|
||||
install : true
|
||||
install: true,
|
||||
)
|
||||
|
||||
install_data('../hyprpm.bash', install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'), install_tag: 'runtime', rename: 'hyprpm')
|
||||
install_data('../hyprpm.fish', install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'), install_tag: 'runtime')
|
||||
install_data('../hyprpm.zsh', install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'), install_tag: 'runtime', rename: '_hyprpm')
|
||||
install_data(
|
||||
'../hyprpm.bash',
|
||||
install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'),
|
||||
install_tag: 'runtime',
|
||||
rename: 'hyprpm',
|
||||
)
|
||||
install_data(
|
||||
'../hyprpm.fish',
|
||||
install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'),
|
||||
install_tag: 'runtime',
|
||||
)
|
||||
install_data(
|
||||
'../hyprpm.zsh',
|
||||
install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'),
|
||||
install_tag: 'runtime',
|
||||
rename: '_hyprpm',
|
||||
)
|
||||
|
@@ -1,11 +1,11 @@
|
||||
#include "CProgressBar.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/ioctl.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <format>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <print>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -16,11 +16,12 @@ void CProgressBar::printMessageAbove(const std::string& msg) {
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
|
||||
std::string spaces;
|
||||
spaces.reserve(w.ws_col);
|
||||
for (size_t i = 0; i < w.ws_col; ++i) {
|
||||
spaces += ' ';
|
||||
}
|
||||
|
||||
std::cout << "\r" << spaces << "\r" << msg << "\n";
|
||||
std::println("\r{}\r{}", spaces, msg);
|
||||
print();
|
||||
}
|
||||
|
||||
@@ -29,15 +30,16 @@ void CProgressBar::print() {
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
|
||||
if (m_bFirstPrint)
|
||||
std::cout << "\n";
|
||||
std::print("\n");
|
||||
m_bFirstPrint = false;
|
||||
|
||||
std::string spaces;
|
||||
spaces.reserve(w.ws_col);
|
||||
for (size_t i = 0; i < w.ws_col; ++i) {
|
||||
spaces += ' ';
|
||||
}
|
||||
|
||||
std::cout << "\r" << spaces << "\r";
|
||||
std::print("\r{}\r", spaces);
|
||||
|
||||
std::string message = "";
|
||||
|
||||
@@ -74,7 +76,7 @@ void CProgressBar::print() {
|
||||
message += " " + std::format("{} / {}", m_iSteps, m_iMaxSteps) + " ";
|
||||
|
||||
// draw message
|
||||
std::cout << message + " " + m_szCurrentMessage;
|
||||
std::print("{} {}", message, m_szCurrentMessage);
|
||||
|
||||
std::fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
@@ -14,4 +14,4 @@ class CProgressBar {
|
||||
|
||||
private:
|
||||
bool m_bFirstPrint = true;
|
||||
};
|
||||
};
|
||||
|
65
meson.build
@@ -1,13 +1,17 @@
|
||||
project('Hyprland', 'cpp', 'c',
|
||||
version : run_command('cat', join_paths(meson.source_root(), 'VERSION'), check: true).stdout().strip(),
|
||||
default_options : [
|
||||
project(
|
||||
'Hyprland',
|
||||
'cpp',
|
||||
'c',
|
||||
version: run_command('cat', join_paths(meson.project_source_root(), 'VERSION'), check: true).stdout().strip(),
|
||||
default_options: [
|
||||
'warning_level=2',
|
||||
'default_library=static',
|
||||
'optimization=3',
|
||||
'buildtype=release',
|
||||
'debug=false',
|
||||
'cpp_std=c++26',
|
||||
])
|
||||
],
|
||||
)
|
||||
|
||||
datarootdir = '-DDATAROOTDIR="' + get_option('prefix') / get_option('datadir') + '"'
|
||||
add_project_arguments(
|
||||
@@ -16,16 +20,28 @@ add_project_arguments(
|
||||
'-Wno-unused-value',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wno-narrowing',
|
||||
'-Wno-pointer-arith',
|
||||
datarootdir,
|
||||
'-Wno-pointer-arith', datarootdir,
|
||||
'-DHYPRLAND_VERSION="' + meson.project_version() + '"',
|
||||
],
|
||||
language: 'cpp')
|
||||
language: 'cpp',
|
||||
)
|
||||
|
||||
cpp_compiler = meson.get_compiler('cpp')
|
||||
if cpp_compiler.check_header('execinfo.h')
|
||||
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
|
||||
endif
|
||||
|
||||
aquamarine = dependency('aquamarine', version: '>=0.4.5')
|
||||
hyprcursor = dependency('hyprcursor', version: '>=0.1.7')
|
||||
hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.1')
|
||||
hyprlang = dependency('hyprlang', version: '>= 0.3.2')
|
||||
hyprutils = dependency('hyprutils', version: '>= 0.2.3')
|
||||
add_project_arguments(['-DAQUAMARINE_VERSION="@0@"'.format(aquamarine.version())], language: 'cpp')
|
||||
add_project_arguments(['-DHYPRCURSOR_VERSION="@0@"'.format(hyprcursor.version())], language: 'cpp')
|
||||
add_project_arguments(['-DHYPRGRAPHICS_VERSION="@0@"'.format(hyprgraphics.version())], language: 'cpp')
|
||||
add_project_arguments(['-DHYPRLANG_VERSION="@0@"'.format(hyprlang.version())], language: 'cpp')
|
||||
add_project_arguments(['-DHYPRUTILS_VERSION="@0@"'.format(hyprutils.version())], language: 'cpp')
|
||||
|
||||
xcb_dep = dependency('xcb', required: get_option('xwayland'))
|
||||
xcb_composite_dep = dependency('xcb-composite', required: get_option('xwayland'))
|
||||
xcb_errors_dep = dependency('xcb-errors', required: get_option('xwayland'))
|
||||
@@ -34,11 +50,7 @@ xcb_render_dep = dependency('xcb-render', required: get_option('xwayland'))
|
||||
xcb_res_dep = dependency('xcb-res', required: get_option('xwayland'))
|
||||
xcb_xfixes_dep = dependency('xcb-xfixes', required: get_option('xwayland'))
|
||||
|
||||
gio_dep = dependency('gio-2.0', required:true)
|
||||
|
||||
cmake = import('cmake')
|
||||
udis = cmake.subproject('udis86')
|
||||
udis86 = udis.dependency('libudis86')
|
||||
gio_dep = dependency('gio-2.0', required: true)
|
||||
|
||||
if not xcb_dep.found()
|
||||
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
|
||||
@@ -47,8 +59,17 @@ endif
|
||||
backtrace_dep = cpp_compiler.find_library('execinfo', required: false)
|
||||
epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs
|
||||
|
||||
if get_option('systemd').enabled()
|
||||
re2 = dependency('re2', required: true)
|
||||
|
||||
# Handle options
|
||||
systemd_option = get_option('systemd')
|
||||
systemd = dependency('systemd', required: systemd_option)
|
||||
systemd_option.enable_auto_if(systemd.found())
|
||||
|
||||
if (systemd_option.enabled())
|
||||
message('Enabling systemd integration')
|
||||
add_project_arguments('-DUSES_SYSTEMD', language: 'cpp')
|
||||
subdir('systemd')
|
||||
endif
|
||||
|
||||
if get_option('legacy_renderer').enabled()
|
||||
@@ -59,22 +80,36 @@ if get_option('buildtype') == 'debug'
|
||||
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
|
||||
endif
|
||||
|
||||
version_h = run_command('sh', '-c', 'scripts/generateVersion.sh', check: true)
|
||||
# Generate hyprland version and populate version.h
|
||||
run_command('sh', '-c', 'scripts/generateVersion.sh', check: true)
|
||||
|
||||
# Install headers
|
||||
globber = run_command('find', 'src', '-name', '*.h*', check: true)
|
||||
headers = globber.stdout().strip().split('\n')
|
||||
foreach file : headers
|
||||
install_headers(file, subdir: 'hyprland', preserve_path: true)
|
||||
endforeach
|
||||
|
||||
tracy = dependency('tracy', static: true, required: get_option('tracy_enable'))
|
||||
|
||||
if get_option('tracy_enable') and get_option('buildtype') != 'debugoptimized'
|
||||
warning('Profiling builds should set -- buildtype = debugoptimized')
|
||||
endif
|
||||
|
||||
|
||||
|
||||
subdir('protocols')
|
||||
subdir('src')
|
||||
subdir('hyprctl')
|
||||
subdir('hyprpm/src')
|
||||
subdir('assets')
|
||||
subdir('example')
|
||||
subdir('docs')
|
||||
|
||||
if get_option('hyprpm').enabled()
|
||||
subdir('hyprpm/src')
|
||||
endif
|
||||
|
||||
# Generate hyprland.pc
|
||||
pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig')
|
||||
|
||||
import('pkgconfig').generate(
|
||||
|
@@ -1,3 +1,6 @@
|
||||
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
||||
option('systemd', type: 'feature', value: 'auto', description: 'Enable systemd integration')
|
||||
option('uwsm', type: 'feature', value: 'enabled', description: 'Enable uwsm integration (only if systemd is enabled)')
|
||||
option('legacy_renderer', type: 'feature', value: 'disabled', description: 'Enable legacy renderer')
|
||||
option('hyprpm', type: 'feature', value: 'enabled', description: 'Enable hyprpm')
|
||||
option('tracy_enable', type: 'boolean', value: false , description: 'Enable profiling')
|
||||
|
272
nix/default.nix
@@ -1,43 +1,38 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
stdenvAdapters,
|
||||
pkg-config,
|
||||
pkgconf,
|
||||
makeWrapper,
|
||||
cmake,
|
||||
meson,
|
||||
ninja,
|
||||
aquamarine,
|
||||
binutils,
|
||||
cairo,
|
||||
expat,
|
||||
fribidi,
|
||||
git,
|
||||
hwdata,
|
||||
glaze,
|
||||
hyprcursor,
|
||||
hyprgraphics,
|
||||
hyprland-protocols,
|
||||
hyprland-qtutils,
|
||||
hyprlang,
|
||||
hyprutils,
|
||||
hyprwayland-scanner,
|
||||
jq,
|
||||
libGL,
|
||||
libdatrie,
|
||||
libdisplay-info,
|
||||
libdrm,
|
||||
libexecinfo,
|
||||
libinput,
|
||||
libliftoff,
|
||||
libselinux,
|
||||
libsepol,
|
||||
libthai,
|
||||
libuuid,
|
||||
libxkbcommon,
|
||||
libuuid,
|
||||
mesa,
|
||||
pango,
|
||||
pciutils,
|
||||
pcre2,
|
||||
python3,
|
||||
seatd,
|
||||
re2,
|
||||
systemd,
|
||||
tomlplusplus,
|
||||
udis86-hyprland,
|
||||
wayland,
|
||||
wayland-protocols,
|
||||
wayland-scanner,
|
||||
@@ -50,140 +45,151 @@
|
||||
wrapRuntimeDeps ? true,
|
||||
version ? "git",
|
||||
commit,
|
||||
revCount,
|
||||
date,
|
||||
# deprecated flags
|
||||
enableNvidiaPatches ? false,
|
||||
nvidiaPatches ? false,
|
||||
hidpiXWayland ? false,
|
||||
}:
|
||||
assert lib.assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
|
||||
assert lib.assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed.";
|
||||
assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland";
|
||||
stdenv.mkDerivation {
|
||||
pname = "hyprland${lib.optionalString debug "-debug"}";
|
||||
inherit version;
|
||||
}: let
|
||||
inherit (builtins) baseNameOf foldl' readFile;
|
||||
inherit (lib.asserts) assertMsg;
|
||||
inherit (lib.attrsets) mapAttrsToList;
|
||||
inherit (lib.lists) flatten concatLists optional optionals;
|
||||
inherit (lib.sources) cleanSourceWith cleanSource;
|
||||
inherit (lib.strings) hasSuffix makeBinPath optionalString mesonBool mesonEnable trim;
|
||||
|
||||
src = lib.cleanSourceWith {
|
||||
filter = name: type: let
|
||||
baseName = baseNameOf (toString name);
|
||||
in
|
||||
! (lib.hasSuffix ".nix" baseName);
|
||||
src = lib.cleanSource ../.;
|
||||
};
|
||||
adapters = flatten [
|
||||
stdenvAdapters.useMoldLinker
|
||||
(lib.optional debug stdenvAdapters.keepDebugInfo)
|
||||
];
|
||||
|
||||
patches = [
|
||||
# forces GCC to use -std=c++26
|
||||
./stdcxx.patch
|
||||
];
|
||||
customStdenv = foldl' (acc: adapter: adapter acc) stdenv adapters;
|
||||
in
|
||||
assert assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
|
||||
assert assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed.";
|
||||
assert assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland";
|
||||
customStdenv.mkDerivation (finalAttrs: {
|
||||
pname = "hyprland${optionalString debug "-debug"}";
|
||||
inherit version;
|
||||
|
||||
postPatch = ''
|
||||
# Fix hardcoded paths to /usr installation
|
||||
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
||||
src = cleanSourceWith {
|
||||
filter = name: _type: let
|
||||
baseName = baseNameOf (toString name);
|
||||
in
|
||||
! (hasSuffix ".nix" baseName);
|
||||
src = cleanSource ../.;
|
||||
};
|
||||
|
||||
# Remove extra @PREFIX@ to fix pkg-config paths
|
||||
sed -i "s#@PREFIX@/##g" hyprland.pc.in
|
||||
'';
|
||||
postPatch = ''
|
||||
# Fix hardcoded paths to /usr installation
|
||||
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
||||
|
||||
COMMITS = commit;
|
||||
DATE = date;
|
||||
DIRTY = lib.optionalString (commit == "") "dirty";
|
||||
HASH = commit;
|
||||
# Remove extra @PREFIX@ to fix pkg-config paths
|
||||
sed -i "s#@PREFIX@/##g" hyprland.pc.in
|
||||
'';
|
||||
|
||||
nativeBuildInputs = [
|
||||
hyprwayland-scanner
|
||||
jq
|
||||
makeWrapper
|
||||
cmake
|
||||
ninja
|
||||
pkg-config
|
||||
python3 # for udis86
|
||||
# re-add after https://github.com/NixOS/nixpkgs/pull/214906 hits nixos-unstable
|
||||
# wayland-scanner
|
||||
];
|
||||
COMMITS = revCount;
|
||||
DATE = date;
|
||||
DIRTY = optionalString (commit == "") "dirty";
|
||||
HASH = commit;
|
||||
TAG = "v${trim (readFile "${finalAttrs.src}/VERSION")}";
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
"man"
|
||||
"dev"
|
||||
];
|
||||
depsBuildBuild = [
|
||||
pkg-config
|
||||
];
|
||||
|
||||
buildInputs = lib.concatLists [
|
||||
[
|
||||
aquamarine
|
||||
cairo
|
||||
expat
|
||||
fribidi
|
||||
git
|
||||
hwdata
|
||||
hyprcursor
|
||||
hyprlang
|
||||
hyprutils
|
||||
libdatrie
|
||||
libdisplay-info
|
||||
libdrm
|
||||
libGL
|
||||
libinput
|
||||
libliftoff
|
||||
libselinux
|
||||
libsepol
|
||||
libthai
|
||||
libuuid
|
||||
libxkbcommon
|
||||
mesa
|
||||
pango
|
||||
pciutils
|
||||
pcre2
|
||||
seatd
|
||||
tomlplusplus
|
||||
wayland
|
||||
wayland-protocols
|
||||
xorg.libXcursor
|
||||
]
|
||||
(lib.optionals stdenv.hostPlatform.isMusl [libexecinfo])
|
||||
(lib.optionals enableXWayland [
|
||||
xorg.libxcb
|
||||
xorg.libXdmcp
|
||||
xorg.xcbutil
|
||||
xorg.xcbutilerrors
|
||||
xorg.xcbutilrenderutil
|
||||
xorg.xcbutilwm
|
||||
xwayland
|
||||
])
|
||||
(lib.optionals withSystemd [systemd])
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
hyprwayland-scanner
|
||||
makeWrapper
|
||||
meson
|
||||
ninja
|
||||
cmake # needed for glaze
|
||||
pkg-config
|
||||
];
|
||||
|
||||
cmakeBuildType =
|
||||
if debug
|
||||
then "Debug"
|
||||
else "RelWithDebInfo";
|
||||
outputs = [
|
||||
"out"
|
||||
"man"
|
||||
"dev"
|
||||
];
|
||||
|
||||
# we want as much debug info as possible
|
||||
dontStrip = debug;
|
||||
|
||||
cmakeFlags = [
|
||||
(lib.cmakeBool "NO_XWAYLAND" (!enableXWayland))
|
||||
(lib.cmakeBool "LEGACY_RENDERER" legacyRenderer)
|
||||
(lib.cmakeBool "NO_SYSTEMD" (!withSystemd))
|
||||
];
|
||||
|
||||
postInstall = ''
|
||||
${lib.optionalString wrapRuntimeDeps ''
|
||||
wrapProgram $out/bin/Hyprland \
|
||||
--suffix PATH : ${lib.makeBinPath [
|
||||
binutils
|
||||
buildInputs = concatLists [
|
||||
[
|
||||
aquamarine
|
||||
cairo
|
||||
git
|
||||
glaze
|
||||
hyprcursor
|
||||
hyprgraphics
|
||||
hyprland-protocols
|
||||
hyprlang
|
||||
hyprutils
|
||||
libdrm
|
||||
libGL
|
||||
libinput
|
||||
libuuid
|
||||
libxkbcommon
|
||||
mesa
|
||||
pango
|
||||
pciutils
|
||||
pkgconf
|
||||
]}
|
||||
''}
|
||||
'';
|
||||
re2
|
||||
tomlplusplus
|
||||
udis86-hyprland
|
||||
wayland
|
||||
wayland-protocols
|
||||
wayland-scanner
|
||||
xorg.libXcursor
|
||||
]
|
||||
(optionals customStdenv.hostPlatform.isMusl [libexecinfo])
|
||||
(optionals enableXWayland [
|
||||
xorg.libxcb
|
||||
xorg.libXdmcp
|
||||
xorg.xcbutilerrors
|
||||
xorg.xcbutilrenderutil
|
||||
xorg.xcbutilwm
|
||||
xwayland
|
||||
])
|
||||
(optional withSystemd systemd)
|
||||
];
|
||||
|
||||
passthru.providedSessions = ["hyprland"];
|
||||
mesonBuildType =
|
||||
if debug
|
||||
then "debugoptimized"
|
||||
else "release";
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/hyprwm/Hyprland";
|
||||
description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
|
||||
license = lib.licenses.bsd3;
|
||||
platforms = lib.platforms.linux;
|
||||
mainProgram = "Hyprland";
|
||||
};
|
||||
}
|
||||
mesonFlags = flatten [
|
||||
(mapAttrsToList mesonEnable {
|
||||
"xwayland" = enableXWayland;
|
||||
"legacy_renderer" = legacyRenderer;
|
||||
"uwsm" = false;
|
||||
"hyprpm" = false;
|
||||
})
|
||||
(mapAttrsToList mesonBool {
|
||||
"b_pch" = false;
|
||||
"tracy_enable" = false;
|
||||
})
|
||||
];
|
||||
|
||||
postInstall = ''
|
||||
${optionalString wrapRuntimeDeps ''
|
||||
wrapProgram $out/bin/Hyprland \
|
||||
--suffix PATH : ${makeBinPath [
|
||||
binutils
|
||||
hyprland-qtutils
|
||||
pciutils
|
||||
pkgconf
|
||||
]}
|
||||
''}
|
||||
'';
|
||||
|
||||
passthru.providedSessions = ["hyprland"];
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/hyprwm/Hyprland";
|
||||
description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
|
||||
license = lib.licenses.bsd3;
|
||||
platforms = lib.platforms.linux;
|
||||
mainProgram = "Hyprland";
|
||||
};
|
||||
})
|
||||
|
64
nix/formatter.nix
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
writeShellApplication,
|
||||
deadnix,
|
||||
statix,
|
||||
alejandra,
|
||||
llvmPackages_19,
|
||||
fd,
|
||||
}:
|
||||
writeShellApplication {
|
||||
name = "hyprland-treewide-formatter";
|
||||
runtimeInputs = [
|
||||
deadnix
|
||||
statix
|
||||
alejandra
|
||||
llvmPackages_19.clang-tools
|
||||
fd
|
||||
];
|
||||
text = ''
|
||||
# shellcheck disable=SC2148
|
||||
|
||||
# common excludes
|
||||
excludes="subprojects"
|
||||
|
||||
nix_format() {
|
||||
if [ "$*" = 0 ]; then
|
||||
fd '.*\.nix' . -E "$excludes" -x statix fix -- {} \;
|
||||
fd '.*\.nix' . -E "$excludes" -X deadnix -e -- {} \; -X alejandra {} \;
|
||||
elif [ -d "$1" ]; then
|
||||
fd '.*\.nix' "$1" -E "$excludes" -i -x statix fix -- {} \;
|
||||
fd '.*\.nix' "$1" -E "$excludes" -i -X deadnix -e -- {} \; -X alejandra {} \;
|
||||
else
|
||||
statix fix -- "$1"
|
||||
deadnix -e "$1"
|
||||
alejandra "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
cpp_format() {
|
||||
if [ "$*" = 0 ] || [ "$1" = "." ]; then
|
||||
fd '.*\.cpp' . -E "$excludes" | xargs clang-format --verbose -i
|
||||
elif [ -d "$1" ]; then
|
||||
fd '.*\.cpp' "$1" -E "$excludes" | xargs clang-format --verbose -i
|
||||
else
|
||||
clang-format --verbose -i "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
for i in "$@"; do
|
||||
case ''${i##*.} in
|
||||
"nix")
|
||||
nix_format "$i"
|
||||
;;
|
||||
"cpp")
|
||||
cpp_format "$i"
|
||||
;;
|
||||
*)
|
||||
nix_format "$i"
|
||||
cpp_format "$i"
|
||||
;;
|
||||
esac
|
||||
|
||||
done
|
||||
'';
|
||||
}
|
205
nix/module.nix
@@ -7,15 +7,206 @@ inputs: {
|
||||
inherit (pkgs.stdenv.hostPlatform) system;
|
||||
cfg = config.programs.hyprland;
|
||||
|
||||
package = inputs.self.packages.${system}.hyprland;
|
||||
portalPackage = inputs.self.packages.${system}.xdg-desktop-portal-hyprland.override {
|
||||
hyprland = cfg.finalPackage;
|
||||
};
|
||||
# basically 1:1 taken from https://github.com/nix-community/home-manager/blob/master/modules/services/window-managers/hyprland.nix
|
||||
toHyprconf = {
|
||||
attrs,
|
||||
indentLevel ? 0,
|
||||
importantPrefixes ? ["$"],
|
||||
}: let
|
||||
inherit
|
||||
(lib)
|
||||
all
|
||||
concatMapStringsSep
|
||||
concatStrings
|
||||
concatStringsSep
|
||||
filterAttrs
|
||||
foldl
|
||||
generators
|
||||
hasPrefix
|
||||
isAttrs
|
||||
isList
|
||||
mapAttrsToList
|
||||
replicate
|
||||
;
|
||||
|
||||
initialIndent = concatStrings (replicate indentLevel " ");
|
||||
|
||||
toHyprconf' = indent: attrs: let
|
||||
sections =
|
||||
filterAttrs (n: v: isAttrs v || (isList v && all isAttrs v)) attrs;
|
||||
|
||||
mkSection = n: attrs:
|
||||
if lib.isList attrs
|
||||
then (concatMapStringsSep "\n" (a: mkSection n a) attrs)
|
||||
else ''
|
||||
${indent}${n} {
|
||||
${toHyprconf' " ${indent}" attrs}${indent}}
|
||||
'';
|
||||
|
||||
mkFields = generators.toKeyValue {
|
||||
listsAsDuplicateKeys = true;
|
||||
inherit indent;
|
||||
};
|
||||
|
||||
allFields =
|
||||
filterAttrs (n: v: !(isAttrs v || (isList v && all isAttrs v)))
|
||||
attrs;
|
||||
|
||||
isImportantField = n: _:
|
||||
foldl (acc: prev:
|
||||
if hasPrefix prev n
|
||||
then true
|
||||
else acc)
|
||||
false
|
||||
importantPrefixes;
|
||||
|
||||
importantFields = filterAttrs isImportantField allFields;
|
||||
|
||||
fields =
|
||||
builtins.removeAttrs allFields
|
||||
(mapAttrsToList (n: _: n) importantFields);
|
||||
in
|
||||
mkFields importantFields
|
||||
+ concatStringsSep "\n" (mapAttrsToList mkSection sections)
|
||||
+ mkFields fields;
|
||||
in
|
||||
toHyprconf' initialIndent attrs;
|
||||
in {
|
||||
config = {
|
||||
options = {
|
||||
programs.hyprland = {
|
||||
package = lib.mkDefault package;
|
||||
portalPackage = lib.mkDefault portalPackage;
|
||||
plugins = lib.mkOption {
|
||||
type = with lib.types; listOf (either package path);
|
||||
default = [];
|
||||
description = ''
|
||||
List of Hyprland plugins to use. Can either be packages or
|
||||
absolute plugin paths.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types; let
|
||||
valueType =
|
||||
nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
path
|
||||
(attrsOf valueType)
|
||||
(listOf valueType)
|
||||
])
|
||||
// {
|
||||
description = "Hyprland configuration value";
|
||||
};
|
||||
in
|
||||
valueType;
|
||||
default = {};
|
||||
description = ''
|
||||
Hyprland configuration written in Nix. Entries with the same key
|
||||
should be written as lists. Variables' and colors' names should be
|
||||
quoted. See <https://wiki.hyprland.org> for more examples.
|
||||
|
||||
::: {.note}
|
||||
Use the [](#programs.hyprland.plugins) option to
|
||||
declare plugins.
|
||||
:::
|
||||
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
decoration = {
|
||||
shadow_offset = "0 5";
|
||||
"col.shadow" = "rgba(00000099)";
|
||||
};
|
||||
|
||||
"$mod" = "SUPER";
|
||||
|
||||
bindm = [
|
||||
# mouse movements
|
||||
"$mod, mouse:272, movewindow"
|
||||
"$mod, mouse:273, resizewindow"
|
||||
"$mod ALT, mouse:272, resizewindow"
|
||||
];
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
# window resize
|
||||
bind = $mod, S, submap, resize
|
||||
|
||||
submap = resize
|
||||
binde = , right, resizeactive, 10 0
|
||||
binde = , left, resizeactive, -10 0
|
||||
binde = , up, resizeactive, 0 -10
|
||||
binde = , down, resizeactive, 0 10
|
||||
bind = , escape, submap, reset
|
||||
submap = reset
|
||||
'';
|
||||
description = ''
|
||||
Extra configuration lines to add to `/etc/xdg/hypr/hyprland.conf`.
|
||||
'';
|
||||
};
|
||||
|
||||
sourceFirst =
|
||||
lib.mkEnableOption ''
|
||||
putting source entries at the top of the configuration
|
||||
''
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
|
||||
importantPrefixes = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = ["$" "bezier" "name"] ++ lib.optionals cfg.sourceFirst ["source"];
|
||||
example = ["$" "bezier"];
|
||||
description = ''
|
||||
List of prefix of attributes to source at the top of the config.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
config = lib.mkMerge [
|
||||
{
|
||||
programs.hyprland = {
|
||||
package = lib.mkDefault inputs.self.packages.${system}.hyprland;
|
||||
portalPackage = lib.mkDefault (inputs.self.packages.${system}.xdg-desktop-portal-hyprland.override {
|
||||
hyprland = cfg.finalPackage;
|
||||
});
|
||||
};
|
||||
}
|
||||
(lib.mkIf cfg.enable {
|
||||
environment.etc."xdg/hypr/hyprland.conf" = let
|
||||
shouldGenerate = cfg.extraConfig != "" || cfg.settings != {} || cfg.plugins != [];
|
||||
|
||||
pluginsToHyprconf = plugins:
|
||||
toHyprconf {
|
||||
attrs = {
|
||||
plugin = let
|
||||
mkEntry = entry:
|
||||
if lib.types.package.check entry
|
||||
then "${entry}/lib/lib${entry.pname}.so"
|
||||
else entry;
|
||||
in
|
||||
map mkEntry cfg.plugins;
|
||||
};
|
||||
inherit (cfg) importantPrefixes;
|
||||
};
|
||||
in
|
||||
lib.mkIf shouldGenerate {
|
||||
text =
|
||||
lib.optionalString (cfg.plugins != [])
|
||||
(pluginsToHyprconf cfg.plugins)
|
||||
+ lib.optionalString (cfg.settings != {})
|
||||
(toHyprconf {
|
||||
attrs = cfg.settings;
|
||||
inherit (cfg) importantPrefixes;
|
||||
})
|
||||
+ lib.optionalString (cfg.extraConfig != "") cfg.extraConfig;
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
@@ -22,22 +22,33 @@ in {
|
||||
# Dependencies
|
||||
inputs.aquamarine.overlays.default
|
||||
inputs.hyprcursor.overlays.default
|
||||
inputs.hyprgraphics.overlays.default
|
||||
inputs.hyprland-protocols.overlays.default
|
||||
inputs.hyprland-qtutils.overlays.default
|
||||
inputs.hyprlang.overlays.default
|
||||
inputs.hyprutils.overlays.default
|
||||
inputs.hyprwayland-scanner.overlays.default
|
||||
self.overlays.udis86
|
||||
|
||||
# Hyprland packages themselves
|
||||
(final: prev: let
|
||||
(final: _prev: let
|
||||
date = mkDate (self.lastModifiedDate or "19700101");
|
||||
in {
|
||||
hyprland = final.callPackage ./default.nix {
|
||||
stdenv = final.gcc14Stdenv;
|
||||
version = "${version}+date=${date}_${self.shortRev or "dirty"}";
|
||||
commit = self.rev or "";
|
||||
revCount = self.sourceInfo.revCount or "";
|
||||
inherit date;
|
||||
};
|
||||
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
|
||||
hyprland-debug = final.hyprland.override {debug = true;};
|
||||
|
||||
# Build major libs with debug to get as much info as possible in a stacktrace
|
||||
hyprland-debug = final.hyprland.override {
|
||||
aquamarine = final.aquamarine.override {debug = true;};
|
||||
hyprutils = final.hyprutils.override {debug = true;};
|
||||
debug = true;
|
||||
};
|
||||
hyprland-legacy-renderer = final.hyprland.override {legacyRenderer = true;};
|
||||
|
||||
# deprecated packages
|
||||
@@ -60,6 +71,22 @@ in {
|
||||
# Packages for extra software recommended for usage with Hyprland,
|
||||
# including forked or patched packages for compatibility.
|
||||
hyprland-extras = lib.composeManyExtensions [
|
||||
inputs.xdph.overlays.xdg-desktop-portal-hyprland
|
||||
inputs.xdph.overlays.default
|
||||
];
|
||||
|
||||
# udis86 from nixpkgs is too old, and also does not provide a .pc file
|
||||
# this version is the one used in the git submodule, and allows us to
|
||||
# fetch the source without '?submodules=1'
|
||||
udis86 = final: prev: {
|
||||
udis86-hyprland = prev.udis86.overrideAttrs (_self: _super: {
|
||||
src = final.fetchFromGitHub {
|
||||
owner = "canihavesomecoffee";
|
||||
repo = "udis86";
|
||||
rev = "5336633af70f3917760a6d441ff02d93477b0c86";
|
||||
hash = "sha256-HifdUQPGsKQKQprByeIznvRLONdOXeolOsU5nkwIv3g=";
|
||||
};
|
||||
|
||||
patches = [];
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@@ -1,12 +0,0 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index cfbd431f..73e8e0c2 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -64,6 +64,7 @@ endif()
|
||||
include_directories(. "src/" "subprojects/udis86/" "protocols/")
|
||||
set(CMAKE_CXX_STANDARD 26)
|
||||
add_compile_options(
|
||||
+ -std=c++26
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-unused-parameter
|
366
protocols/frog-color-management-v1.xml
Normal file
@@ -0,0 +1,366 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="frog_color_management_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2023 Joshua Ashton for Valve Software
|
||||
Copyright © 2023 Xaver Hugl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="experimental color management protocol">
|
||||
The aim of this color management extension is to get HDR games working quickly,
|
||||
and have an easy way to test implementations in the wild before the upstream
|
||||
protocol is ready to be merged.
|
||||
For that purpose it's intentionally limited and cut down and does not serve
|
||||
all uses cases.
|
||||
</description>
|
||||
|
||||
<interface name="frog_color_management_factory_v1" version="1">
|
||||
<description summary="color management factory">
|
||||
The color management factory singleton creates color managed surface objects.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor"></request>
|
||||
|
||||
<request name="get_color_managed_surface">
|
||||
<description summary="create color management interface for surface">
|
||||
</description>
|
||||
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="target surface" />
|
||||
<arg name="callback" type="new_id" interface="frog_color_managed_surface"
|
||||
summary="new color managed surface object" />
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="frog_color_managed_surface" version="1">
|
||||
<description summary="color managed surface">
|
||||
Interface for changing surface color management and HDR state.
|
||||
|
||||
An implementation must: support every part of the version
|
||||
of the frog_color_managed_surface interface it exposes.
|
||||
Including all known enums associated with a given version.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy color managed surface">
|
||||
Destroying the color managed surface resets all known color
|
||||
state for the surface back to 'undefined' implementation-specific
|
||||
values.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="transfer_function">
|
||||
<description summary="known transfer functions">
|
||||
Extended information on the transfer functions described
|
||||
here can be found in the Khronos Data Format specification:
|
||||
https://registry.khronos.org/DataFormat/specs/1.3/dataformat.1.3.html
|
||||
</description>
|
||||
<entry name="undefined" value="0"
|
||||
summary="specifies undefined, implementation-specific handling of the surface's transfer function." />
|
||||
<entry name="srgb" value="1"
|
||||
summary="specifies the sRGB non-linear EOTF. An implementation may: display this as Gamma 2.2 for the purposes of being consistent with content rendering across displays, rendering_intent and user expectations." />
|
||||
<entry name="gamma_22" value="2" summary="specifies gamma 2.2 power curve as the EOTF" />
|
||||
<entry name="st2084_pq" value="3"
|
||||
summary="specifies the SMPTE ST2084 Perceptual Quantizer (PQ) EOTF" />
|
||||
<entry name="scrgb_linear" value="4"
|
||||
summary="specifies the scRGB (extended sRGB) linear EOTF. Note: Primaries outside the gamut triangle specified can be expressed with negative values for this transfer function." />
|
||||
</enum>
|
||||
|
||||
<request name="set_known_transfer_function">
|
||||
<description summary="sets a known transfer function for a surface" />
|
||||
<arg name="transfer_function" type="uint" enum="transfer_function"
|
||||
summary="transfer function for the surface" />
|
||||
</request>
|
||||
|
||||
<enum name="primaries">
|
||||
<description summary="known primaries" />
|
||||
<entry name="undefined" value="0"
|
||||
summary="specifies undefined, implementation-specific handling" />
|
||||
<entry name="rec709" value="1" summary="specifies Rec.709/sRGB primaries with D65 white point" />
|
||||
<entry name="rec2020" value="2"
|
||||
summary="specifies Rec.2020/HDR10 primaries with D65 white point" />
|
||||
</enum>
|
||||
|
||||
<request name="set_known_container_color_volume">
|
||||
<description summary="sets the container color volume (primaries) for a surface" />
|
||||
<arg name="primaries" type="uint" enum="primaries" summary="primaries for the surface" />
|
||||
</request>
|
||||
|
||||
<enum name="render_intent">
|
||||
<description summary="known render intents">
|
||||
Extended information on render intents described
|
||||
here can be found in ICC.1:2022:
|
||||
|
||||
https://www.color.org/specification/ICC.1-2022-05.pdf
|
||||
</description>
|
||||
<entry name="perceptual" value="0" summary="perceptual" />
|
||||
</enum>
|
||||
|
||||
<request name="set_render_intent">
|
||||
<description summary="sets the render intent for a surface">
|
||||
NOTE: On a surface with "perceptual" (default) render intent, handling of the container's
|
||||
color volume
|
||||
is implementation-specific, and may differ between different transfer functions it is paired
|
||||
with:
|
||||
ie. sRGB + 709 rendering may have it's primaries widened to more of the available display's
|
||||
gamut
|
||||
to be be more pleasing for the viewer.
|
||||
Compared to scRGB Linear + 709 being treated faithfully as 709
|
||||
(including utilizing negatives out of the 709 gamut triangle)
|
||||
</description>
|
||||
<arg name="render_intent" type="uint" enum="render_intent"
|
||||
summary="render intent for the surface" />
|
||||
</request>
|
||||
|
||||
<request name="set_hdr_metadata">
|
||||
<description summary="set HDR metadata for a surface">
|
||||
Forwards HDR metadata from the client to the compositor.
|
||||
|
||||
HDR Metadata Infoframe as per CTA 861.G spec.
|
||||
|
||||
Usage of this HDR metadata is implementation specific and
|
||||
outside of the scope of this protocol.
|
||||
</description>
|
||||
<arg name="mastering_display_primary_red_x" type="uint">
|
||||
<description summary="red primary x coordinate">
|
||||
Mastering Red Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_red_y" type="uint">
|
||||
<description summary="red primary y coordinate">
|
||||
Mastering Red Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_green_x" type="uint">
|
||||
<description summary="green primary x coordinate">
|
||||
Mastering Green Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_green_y" type="uint">
|
||||
<description summary="green primary y coordinate">
|
||||
Mastering Green Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_blue_x" type="uint">
|
||||
<description summary="blue primary x coordinate">
|
||||
Mastering Blue Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_display_primary_blue_y" type="uint">
|
||||
<description summary="blue primary y coordinate">
|
||||
Mastering Blue Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_white_point_x" type="uint">
|
||||
<description summary="white point x coordinate">
|
||||
Mastering White Point X Coordinate of the Data.
|
||||
|
||||
These are coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="mastering_white_point_y" type="uint">
|
||||
<description summary="white point y coordinate">
|
||||
Mastering White Point Y Coordinate of the Data.
|
||||
|
||||
These are coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_display_mastering_luminance" type="uint">
|
||||
<description summary="max display mastering luminance">
|
||||
Max Mastering Display Luminance.
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="min_display_mastering_luminance" type="uint">
|
||||
<description summary="min display mastering luminance">
|
||||
Min Mastering Display Luminance.
|
||||
This value is coded as an unsigned 16-bit value in units of
|
||||
0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF
|
||||
represents 6.5535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_cll" type="uint">
|
||||
<description summary="max content light level">
|
||||
Max Content Light Level.
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_fall" type="uint">
|
||||
<description summary="max frame average light level">
|
||||
Max Frame Average Light Level.
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
</request>
|
||||
|
||||
<event name="preferred_metadata">
|
||||
<description summary="preferred metadata for a surface">
|
||||
Current preferred metadata for a surface.
|
||||
The application should use this information to tone-map its buffers
|
||||
to this target before committing.
|
||||
|
||||
This metadata does not necessarily correspond to any physical output, but
|
||||
rather what the compositor thinks would be best for a given surface.
|
||||
</description>
|
||||
<arg name="transfer_function" type="uint" enum="transfer_function">
|
||||
<description summary="output's current transfer function">
|
||||
Specifies a known transfer function that corresponds to the
|
||||
output the surface is targeting.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_red_x" type="uint">
|
||||
<description summary="red primary x coordinate">
|
||||
Output Red Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_red_y" type="uint">
|
||||
<description summary="red primary y coordinate">
|
||||
Output Red Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_green_x" type="uint">
|
||||
<description summary="green primary x coordinate">
|
||||
Output Green Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_green_y" type="uint">
|
||||
<description summary="green primary y coordinate">
|
||||
Output Green Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_blue_x" type="uint">
|
||||
<description summary="blue primary x coordinate">
|
||||
Output Blue Color Primary X Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_display_primary_blue_y" type="uint">
|
||||
<description summary="blue primary y coordinate">
|
||||
Output Blue Color Primary Y Coordinate of the Data.
|
||||
|
||||
Coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_white_point_x" type="uint">
|
||||
<description summary="white point x coordinate">
|
||||
Output White Point X Coordinate of the Data.
|
||||
|
||||
These are coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="output_white_point_y" type="uint">
|
||||
<description summary="white point y coordinate">
|
||||
Output White Point Y Coordinate of the Data.
|
||||
|
||||
These are coded as unsigned 16-bit values in units of
|
||||
0.00002, where 0x0000 represents zero and 0xC350
|
||||
represents 1.0000.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_luminance" type="uint">
|
||||
<description summary="maximum luminance">
|
||||
Max Output Luminance
|
||||
The max luminance in nits that the output is capable of rendering in small areas.
|
||||
Content should: not exceed this value to avoid clipping.
|
||||
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="min_luminance" type="uint">
|
||||
<description summary="minimum luminance">
|
||||
Min Output Luminance
|
||||
The min luminance that the output is capable of rendering.
|
||||
Content should: not exceed this value to avoid clipping.
|
||||
|
||||
This value is coded as an unsigned 16-bit value in units of
|
||||
0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF
|
||||
represents 6.5535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
<arg name="max_full_frame_luminance" type="uint">
|
||||
<description summary="maximum full frame luminance">
|
||||
Max Full Frame Luminance
|
||||
The max luminance in nits that the output is capable of rendering for the
|
||||
full frame sustained.
|
||||
|
||||
This value is coded as an unsigned 16-bit value in units of 1 cd/m2,
|
||||
where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2.
|
||||
</description>
|
||||
</arg>
|
||||
</event>
|
||||
</interface>
|
||||
</protocol>
|
@@ -1,76 +1,82 @@
|
||||
wayland_protos = dependency('wayland-protocols',
|
||||
wayland_protos = dependency(
|
||||
'wayland-protocols',
|
||||
version: '>=1.32',
|
||||
fallback: 'wayland-protocols',
|
||||
default_options: ['tests=false'],
|
||||
)
|
||||
|
||||
hyprland_protos = dependency('hyprland-protocols',
|
||||
version: '>=0.2',
|
||||
fallback: 'hyprland-protocols',
|
||||
hyprland_protos = dependency(
|
||||
'hyprland-protocols',
|
||||
version: '>=0.6',
|
||||
fallback: 'hyprland-protocols',
|
||||
)
|
||||
|
||||
wl_protocol_dir = wayland_protos.get_variable('pkgdatadir')
|
||||
hl_protocol_dir = hyprland_protos.get_variable('pkgdatadir')
|
||||
wayland_protocol_dir = wayland_protos.get_variable('pkgdatadir')
|
||||
hyprland_protocol_dir = hyprland_protos.get_variable('pkgdatadir')
|
||||
|
||||
hyprwayland_scanner_dep = dependency('hyprwayland-scanner', version: '>=0.3.8', native: true)
|
||||
hyprwayland_scanner_dep = dependency('hyprwayland-scanner', version: '>=0.3.10', native: true)
|
||||
hyprwayland_scanner = find_program(
|
||||
hyprwayland_scanner_dep.get_variable('hyprwayland_scanner'),
|
||||
native: true,
|
||||
)
|
||||
|
||||
new_protocols = [
|
||||
['wlr-gamma-control-unstable-v1.xml'],
|
||||
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
||||
['wlr-output-power-management-unstable-v1.xml'],
|
||||
['input-method-unstable-v2.xml'],
|
||||
['virtual-keyboard-unstable-v1.xml'],
|
||||
['wlr-virtual-pointer-unstable-v1.xml'],
|
||||
['wlr-output-management-unstable-v1.xml'],
|
||||
['kde-server-decoration.xml'],
|
||||
['wlr-layer-shell-unstable-v1.xml'],
|
||||
['wayland-drm.xml'],
|
||||
['wlr-data-control-unstable-v1.xml'],
|
||||
['wlr-screencopy-unstable-v1.xml'],
|
||||
[hl_protocol_dir, 'protocols/hyprland-global-shortcuts-v1.xml'],
|
||||
[hl_protocol_dir, 'protocols/hyprland-toplevel-export-v1.xml'],
|
||||
[hl_protocol_dir, 'protocols/hyprland-focus-grab-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/alpha-modifier/alpha-modifier-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v3.xml'],
|
||||
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/xdg-activation/xdg-activation-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/ext-idle-notify/ext-idle-notify-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/ext-session-lock/ext-session-lock-v1.xml'],
|
||||
[wl_protocol_dir, 'stable/tablet/tablet-v2.xml'],
|
||||
[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml'],
|
||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||
[wl_protocol_dir, 'unstable/primary-selection/primary-selection-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/xwayland-shell/xwayland-shell-v1.xml'],
|
||||
[wl_protocol_dir, 'stable/viewporter/viewporter.xml'],
|
||||
[wl_protocol_dir, 'stable/linux-dmabuf/linux-dmabuf-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/drm-lease/drm-lease-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml'],
|
||||
protocols = [
|
||||
'wlr-gamma-control-unstable-v1.xml',
|
||||
'wlr-foreign-toplevel-management-unstable-v1.xml',
|
||||
'wlr-output-power-management-unstable-v1.xml',
|
||||
'input-method-unstable-v2.xml',
|
||||
'virtual-keyboard-unstable-v1.xml',
|
||||
'wlr-virtual-pointer-unstable-v1.xml',
|
||||
'wlr-output-management-unstable-v1.xml',
|
||||
'kde-server-decoration.xml',
|
||||
'wlr-layer-shell-unstable-v1.xml',
|
||||
'wayland-drm.xml',
|
||||
'wlr-data-control-unstable-v1.xml',
|
||||
'wlr-screencopy-unstable-v1.xml',
|
||||
'xx-color-management-v4.xml',
|
||||
'frog-color-management-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-global-shortcuts-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-toplevel-export-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-focus-grab-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-ctm-control-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-surface-v1.xml',
|
||||
hyprland_protocol_dir / 'protocols/hyprland-lock-notify-v1.xml',
|
||||
wayland_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
|
||||
wayland_protocol_dir / 'staging/fractional-scale/fractional-scale-v1.xml',
|
||||
wayland_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
|
||||
wayland_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||
wayland_protocol_dir / 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml',
|
||||
wayland_protocol_dir / 'unstable/relative-pointer/relative-pointer-unstable-v1.xml',
|
||||
wayland_protocol_dir / 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml',
|
||||
wayland_protocol_dir / 'staging/alpha-modifier/alpha-modifier-v1.xml',
|
||||
wayland_protocol_dir / 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml',
|
||||
wayland_protocol_dir / 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml',
|
||||
wayland_protocol_dir / 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml',
|
||||
wayland_protocol_dir / 'unstable/text-input/text-input-unstable-v3.xml',
|
||||
wayland_protocol_dir / 'unstable/text-input/text-input-unstable-v1.xml',
|
||||
wayland_protocol_dir / 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml',
|
||||
wayland_protocol_dir / 'staging/xdg-activation/xdg-activation-v1.xml',
|
||||
wayland_protocol_dir / 'staging/ext-idle-notify/ext-idle-notify-v1.xml',
|
||||
wayland_protocol_dir / 'staging/ext-session-lock/ext-session-lock-v1.xml',
|
||||
wayland_protocol_dir / 'stable/tablet/tablet-v2.xml',
|
||||
wayland_protocol_dir / 'stable/presentation-time/presentation-time.xml',
|
||||
wayland_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
|
||||
wayland_protocol_dir / 'unstable/primary-selection/primary-selection-unstable-v1.xml',
|
||||
wayland_protocol_dir / 'staging/xwayland-shell/xwayland-shell-v1.xml',
|
||||
wayland_protocol_dir / 'stable/viewporter/viewporter.xml',
|
||||
wayland_protocol_dir / 'stable/linux-dmabuf/linux-dmabuf-v1.xml',
|
||||
wayland_protocol_dir / 'staging/drm-lease/drm-lease-v1.xml',
|
||||
wayland_protocol_dir / 'staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml',
|
||||
wayland_protocol_dir / 'staging/xdg-dialog/xdg-dialog-v1.xml',
|
||||
wayland_protocol_dir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml',
|
||||
wayland_protocol_dir / 'staging/security-context/security-context-v1.xml',
|
||||
]
|
||||
|
||||
wl_protos_src = []
|
||||
wl_protos_headers = []
|
||||
|
||||
new_wl_protos = []
|
||||
foreach p : new_protocols
|
||||
xml = join_paths(p)
|
||||
new_wl_protos += custom_target(
|
||||
xml.underscorify(),
|
||||
input: xml,
|
||||
wl_protocols = []
|
||||
foreach protocol : protocols
|
||||
wl_protocols += custom_target(
|
||||
protocol.underscorify(),
|
||||
input: protocol,
|
||||
install: true,
|
||||
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
||||
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
||||
@@ -78,31 +84,26 @@ foreach p : new_protocols
|
||||
)
|
||||
endforeach
|
||||
|
||||
wayland_server_dep = dependency('wayland-server', version: '>=1.20.0')
|
||||
wayland_server_dir = wayland_server_dep.get_variable('pkgdatadir')
|
||||
# wayland.xml generation
|
||||
wayland_scanner = dependency('wayland-scanner')
|
||||
wayland_scanner_datadir = wayland_scanner.get_variable('pkgdatadir')
|
||||
|
||||
wl_server_protos = [
|
||||
wayland_server_dir / 'wayland.xml'
|
||||
]
|
||||
wl_server_protos_gen = []
|
||||
foreach p : wl_server_protos
|
||||
wl_server_protos_gen += custom_target(
|
||||
p.underscorify(),
|
||||
input: p,
|
||||
install: true,
|
||||
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
||||
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
||||
command: [hyprwayland_scanner, '--wayland-enums', '@INPUT@', '@OUTDIR@'],
|
||||
)
|
||||
endforeach
|
||||
wayland_xml = wayland_scanner_datadir / 'wayland.xml'
|
||||
wayland_protocol = custom_target(
|
||||
wayland_xml.underscorify(),
|
||||
input: wayland_xml,
|
||||
install: true,
|
||||
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
||||
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
||||
command: [hyprwayland_scanner, '--wayland-enums', '@INPUT@', '@OUTDIR@'],
|
||||
)
|
||||
|
||||
lib_server_protos = static_library(
|
||||
'server_protos',
|
||||
wl_protos_src + wl_protos_headers + new_wl_protos + wl_server_protos_gen,
|
||||
dependencies: wayland_server_dep.partial_dependency(compile_args: true),
|
||||
wl_protocols + wayland_protocol,
|
||||
)
|
||||
|
||||
server_protos = declare_dependency(
|
||||
link_with: lib_server_protos,
|
||||
sources: wl_protos_headers + new_wl_protos,
|
||||
sources: wl_protocols + wayland_protocol,
|
||||
)
|
||||
|
1457
protocols/xx-color-management-v4.xml
Normal file
1309
src/Compositor.cpp
@@ -1,41 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "defines.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "events/Events.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "managers/ThreadManager.hpp"
|
||||
#include "managers/XWaylandManager.hpp"
|
||||
#include "managers/input/InputManager.hpp"
|
||||
#include "managers/LayoutManager.hpp"
|
||||
#include "managers/KeybindManager.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "managers/EventManager.hpp"
|
||||
#include "managers/ProtocolManager.hpp"
|
||||
#include "managers/SessionLockManager.hpp"
|
||||
#include "managers/HookSystemManager.hpp"
|
||||
#include "debug/HyprDebugOverlay.hpp"
|
||||
#include "debug/HyprNotificationOverlay.hpp"
|
||||
#include "helpers/Monitor.hpp"
|
||||
#include "desktop/Workspace.hpp"
|
||||
#include "desktop/Window.hpp"
|
||||
#include "render/Renderer.hpp"
|
||||
#include "render/OpenGL.hpp"
|
||||
#include "hyprerror/HyprError.hpp"
|
||||
#include "plugins/PluginSystem.hpp"
|
||||
#include "helpers/Watchdog.hpp"
|
||||
#include "protocols/types/ColorManagement.hpp"
|
||||
#include "helpers/memory/Memory.hpp"
|
||||
|
||||
#include <aquamarine/backend/Backend.hpp>
|
||||
#include <aquamarine/output/Output.hpp>
|
||||
|
||||
class CWLSurfaceResource;
|
||||
struct SWorkspaceRule;
|
||||
|
||||
enum eManagersInitStage {
|
||||
enum eManagersInitStage : uint8_t {
|
||||
STAGE_PRIORITY = 0,
|
||||
STAGE_BASICINIT,
|
||||
STAGE_LATE
|
||||
@@ -43,7 +25,7 @@ enum eManagersInitStage {
|
||||
|
||||
class CCompositor {
|
||||
public:
|
||||
CCompositor();
|
||||
CCompositor(bool onlyConfig = false);
|
||||
~CCompositor();
|
||||
|
||||
wl_display* m_sWLDisplay;
|
||||
@@ -59,8 +41,8 @@ class CCompositor {
|
||||
std::string m_szInstancePath = "";
|
||||
std::string m_szCurrentSplash = "error";
|
||||
|
||||
std::vector<SP<CMonitor>> m_vMonitors;
|
||||
std::vector<SP<CMonitor>> m_vRealMonitors; // for all monitors, even those turned off
|
||||
std::vector<PHLMONITOR> m_vMonitors;
|
||||
std::vector<PHLMONITOR> m_vRealMonitors; // for all monitors, even those turned off
|
||||
std::vector<PHLWINDOW> m_vWindows;
|
||||
std::vector<PHLLS> m_vLayers;
|
||||
std::vector<PHLWORKSPACE> m_vWorkspaces;
|
||||
@@ -80,7 +62,7 @@ class CCompositor {
|
||||
|
||||
WP<CWLSurfaceResource> m_pLastFocus;
|
||||
PHLWINDOWREF m_pLastWindow;
|
||||
WP<CMonitor> m_pLastMonitor;
|
||||
PHLMONITORREF m_pLastMonitor;
|
||||
|
||||
std::vector<PHLWINDOWREF> m_vWindowFocusHistory; // first element is the most recently focused.
|
||||
|
||||
@@ -89,72 +71,64 @@ class CCompositor {
|
||||
bool m_bDPMSStateON = true;
|
||||
bool m_bUnsafeState = false; // unsafe state is when there is no monitors.
|
||||
bool m_bNextIsUnsafe = false;
|
||||
CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state
|
||||
bool m_bIsShuttingDown = false;
|
||||
bool m_bDesktopEnvSet = false;
|
||||
PHLMONITORREF m_pUnsafeOutput; // fallback output for the unsafe state
|
||||
bool m_bIsShuttingDown = false;
|
||||
bool m_bFinalRequests = false;
|
||||
bool m_bDesktopEnvSet = false;
|
||||
bool m_bWantsXwayland = true;
|
||||
bool m_bOnlyConfigVerification = false;
|
||||
|
||||
// ------------------------------------------------- //
|
||||
|
||||
CMonitor* getMonitorFromID(const MONITORID&);
|
||||
CMonitor* getMonitorFromName(const std::string&);
|
||||
CMonitor* getMonitorFromDesc(const std::string&);
|
||||
CMonitor* getMonitorFromCursor();
|
||||
CMonitor* getMonitorFromVector(const Vector2D&);
|
||||
PHLMONITOR getMonitorFromID(const MONITORID&);
|
||||
PHLMONITOR getMonitorFromName(const std::string&);
|
||||
PHLMONITOR getMonitorFromDesc(const std::string&);
|
||||
PHLMONITOR getMonitorFromCursor();
|
||||
PHLMONITOR getMonitorFromVector(const Vector2D&);
|
||||
void removeWindowFromVectorSafe(PHLWINDOW);
|
||||
void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
|
||||
void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
|
||||
bool monitorExists(CMonitor*);
|
||||
bool monitorExists(PHLMONITOR);
|
||||
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
|
||||
SP<CWLSurfaceResource> vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*);
|
||||
SP<CWLSurfaceResource> vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*);
|
||||
SP<CWLSurfaceResource> vectorToLayerPopupSurface(const Vector2D&, PHLMONITOR monitor, Vector2D*, PHLLS*);
|
||||
SP<CWLSurfaceResource> vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl);
|
||||
Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, SP<CWLSurfaceResource>);
|
||||
CMonitor* getMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||
CMonitor* getRealMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||
PHLMONITOR getMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||
PHLMONITOR getRealMonitorFromOutput(SP<Aquamarine::IOutput>);
|
||||
PHLWINDOW getWindowFromSurface(SP<CWLSurfaceResource>);
|
||||
PHLWINDOW getWindowFromHandle(uint32_t);
|
||||
bool isWorkspaceVisible(PHLWORKSPACE);
|
||||
bool isWorkspaceVisibleNotCovered(PHLWORKSPACE);
|
||||
PHLWORKSPACE getWorkspaceByID(const WORKSPACEID&);
|
||||
PHLWORKSPACE getWorkspaceByName(const std::string&);
|
||||
PHLWORKSPACE getWorkspaceByString(const std::string&);
|
||||
void sanityCheckWorkspaces();
|
||||
void updateWorkspaceWindowDecos(const WORKSPACEID&);
|
||||
void updateWorkspaceWindowData(const WORKSPACEID&);
|
||||
int getWindowsOnWorkspace(const WORKSPACEID& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
||||
int getGroupsOnWorkspace(const WORKSPACEID& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
||||
PHLWINDOW getUrgentWindow();
|
||||
bool hasUrgentWindowOnWorkspace(const WORKSPACEID&);
|
||||
PHLWINDOW getFirstWindowOnWorkspace(const WORKSPACEID&);
|
||||
PHLWINDOW getTopLeftWindowOnWorkspace(const WORKSPACEID&);
|
||||
PHLWINDOW getFullscreenWindowOnWorkspace(const WORKSPACEID&);
|
||||
bool isWindowActive(PHLWINDOW);
|
||||
void changeWindowZOrder(PHLWINDOW, bool);
|
||||
void cleanupFadingOut(const MONITORID& monid);
|
||||
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
|
||||
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
||||
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
||||
PHLWINDOW getWindowInDirection(const CBox& box, PHLWORKSPACE pWorkspace, char dir, PHLWINDOW ignoreWindow = nullptr, bool useVectorAngles = false);
|
||||
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {}, bool visible = false);
|
||||
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {}, bool visible = false);
|
||||
WORKSPACEID getNextAvailableNamedWorkspace();
|
||||
bool isPointOnAnyMonitor(const Vector2D&);
|
||||
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
|
||||
CMonitor* getMonitorInDirection(const char&);
|
||||
CMonitor* getMonitorInDirection(CMonitor*, const char&);
|
||||
bool isPointOnReservedArea(const Vector2D& point, const PHLMONITOR monitor = nullptr);
|
||||
PHLMONITOR getMonitorInDirection(const char&);
|
||||
PHLMONITOR getMonitorInDirection(PHLMONITOR, const char&);
|
||||
void updateAllWindowsAnimatedDecorationValues();
|
||||
void updateWorkspaceWindows(const WORKSPACEID& id);
|
||||
void updateWindowAnimatedDecorationValues(PHLWINDOW);
|
||||
MONITORID getNextAvailableMonitorID(std::string const& name);
|
||||
void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
|
||||
void swapActiveWorkspaces(CMonitor*, CMonitor*);
|
||||
CMonitor* getMonitorFromString(const std::string&);
|
||||
void moveWorkspaceToMonitor(PHLWORKSPACE, PHLMONITOR, bool noWarpCursor = false);
|
||||
void swapActiveWorkspaces(PHLMONITOR, PHLMONITOR);
|
||||
PHLMONITOR getMonitorFromString(const std::string&);
|
||||
bool workspaceIDOutOfBounds(const WORKSPACEID&);
|
||||
void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||
void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||
void setWindowFullscreenState(const PHLWINDOW PWINDOW, const sFullscreenState state);
|
||||
void changeWindowFullscreenModeInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON);
|
||||
void setWindowFullscreenState(const PHLWINDOW PWINDOW, const SFullscreenState state);
|
||||
void changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON);
|
||||
void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
|
||||
PHLWINDOW getX11Parent(PHLWINDOW);
|
||||
void scheduleFrameForMonitor(CMonitor*, Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
|
||||
void scheduleFrameForMonitor(PHLMONITOR, Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
|
||||
void addToFadingOutSafe(PHLLS);
|
||||
void removeFromFadingOutSafe(PHLLS);
|
||||
void addToFadingOutSafe(PHLWINDOW);
|
||||
@@ -163,11 +137,9 @@ class CCompositor {
|
||||
PHLLS getLayerSurfaceFromSurface(SP<CWLSurfaceResource>);
|
||||
void closeWindow(PHLWINDOW);
|
||||
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
||||
void forceReportSizesToWindowsOnWorkspace(const WORKSPACEID&);
|
||||
PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "",
|
||||
bool isEmtpy = true); // will be deleted next frame if left empty and unfocused!
|
||||
void renameWorkspace(const WORKSPACEID&, const std::string& name = "");
|
||||
void setActiveMonitor(CMonitor*);
|
||||
bool isEmpty = true); // will be deleted next frame if left empty and unfocused!
|
||||
void setActiveMonitor(PHLMONITOR);
|
||||
bool isWorkspaceSpecial(const WORKSPACEID&);
|
||||
WORKSPACEID getNewSpecialID();
|
||||
void performUserChecks();
|
||||
@@ -179,8 +151,11 @@ class CCompositor {
|
||||
void setPreferredScaleForSurface(SP<CWLSurfaceResource> pSurface, double scale);
|
||||
void setPreferredTransformForSurface(SP<CWLSurfaceResource> pSurface, wl_output_transform transform);
|
||||
void updateSuspendedStates();
|
||||
PHLWINDOW windowForCPointer(CWindow*);
|
||||
void onNewMonitor(SP<Aquamarine::IOutput> output);
|
||||
void ensurePersistentWorkspacesPresent(const std::vector<SWorkspaceRule>& rules);
|
||||
|
||||
SImageDescription getPreferredImageDescription();
|
||||
bool shouldChangePreferredImageDescription();
|
||||
|
||||
std::string explicitConfigPath;
|
||||
|
||||
@@ -191,10 +166,11 @@ class CCompositor {
|
||||
void setRandomSplash();
|
||||
void initManagers(eManagersInitStage stage);
|
||||
void prepareFallbackOutput();
|
||||
bool isWindowAvailableForCycle(PHLWINDOW pWindow, PHLWINDOW w, bool focusableOnly, std::optional<bool> floating, bool anyWorkspace = false);
|
||||
|
||||
uint64_t m_iHyprlandPID = 0;
|
||||
wl_event_source* m_critSigSource = nullptr;
|
||||
rlimit m_sOriginalNofile = {0};
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CCompositor> g_pCompositor;
|
||||
inline UP<CCompositor> g_pCompositor;
|
||||
|
@@ -3,11 +3,11 @@
|
||||
#include "helpers/math/Math.hpp"
|
||||
#include <functional>
|
||||
#include <any>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <hyprutils/math/Box.hpp>
|
||||
|
||||
using namespace Hyprutils::Math;
|
||||
|
||||
enum eIcons {
|
||||
enum eIcons : uint8_t {
|
||||
ICON_WARNING = 0,
|
||||
ICON_INFO,
|
||||
ICON_HINT,
|
||||
@@ -17,7 +17,7 @@ enum eIcons {
|
||||
ICON_NONE
|
||||
};
|
||||
|
||||
enum eRenderStage {
|
||||
enum eRenderStage : uint8_t {
|
||||
RENDER_PRE = 0, /* Before binding the gl context */
|
||||
RENDER_BEGIN, /* Just when the rendering begins, nothing has been rendered yet. Damage, current render data in opengl valid. */
|
||||
RENDER_PRE_WINDOWS, /* Pre windows, post bottom and overlay layers */
|
||||
@@ -29,7 +29,7 @@ enum eRenderStage {
|
||||
RENDER_POST_WINDOW, /* After rendering a window (any pass) */
|
||||
};
|
||||
|
||||
enum eInputType {
|
||||
enum eInputType : uint8_t {
|
||||
INPUT_TYPE_AXIS = 0,
|
||||
INPUT_TYPE_BUTTON,
|
||||
INPUT_TYPE_DRAG_START,
|
||||
@@ -41,7 +41,7 @@ struct SCallbackInfo {
|
||||
bool cancelled = false; /* on cancellable events, will cancel the event. */
|
||||
};
|
||||
|
||||
enum eHyprCtlOutputFormat {
|
||||
enum eHyprCtlOutputFormat : uint8_t {
|
||||
FORMAT_NORMAL = 0,
|
||||
FORMAT_JSON
|
||||
};
|
||||
@@ -52,6 +52,12 @@ struct SHyprCtlCommand {
|
||||
std::function<std::string(eHyprCtlOutputFormat, std::string)> fn;
|
||||
};
|
||||
|
||||
struct SDispatchResult {
|
||||
bool passEvent = false;
|
||||
bool success = true;
|
||||
std::string error;
|
||||
};
|
||||
|
||||
typedef int64_t WINDOWID;
|
||||
typedef int64_t MONITORID;
|
||||
typedef int64_t WORKSPACEID;
|
||||
|
@@ -3,7 +3,7 @@
|
||||
#include "../helpers/varlist/VarList.hpp"
|
||||
#include <vector>
|
||||
|
||||
enum eConfigValueDataTypes {
|
||||
enum eConfigValueDataTypes : int8_t {
|
||||
CVD_TYPE_INVALID = -1,
|
||||
CVD_TYPE_GRADIENT = 0,
|
||||
CVD_TYPE_CSS_VALUE = 1
|
||||
@@ -20,24 +20,40 @@ class ICustomConfigValueData {
|
||||
|
||||
class CGradientValueData : public ICustomConfigValueData {
|
||||
public:
|
||||
CGradientValueData() {};
|
||||
CGradientValueData(CColor col) {
|
||||
CGradientValueData() = default;
|
||||
CGradientValueData(CHyprColor col) {
|
||||
m_vColors.push_back(col);
|
||||
updateColorsOk();
|
||||
};
|
||||
virtual ~CGradientValueData() {};
|
||||
virtual ~CGradientValueData() = default;
|
||||
|
||||
virtual eConfigValueDataTypes getDataType() {
|
||||
return CVD_TYPE_GRADIENT;
|
||||
}
|
||||
|
||||
void reset(CColor col) {
|
||||
void reset(CHyprColor col) {
|
||||
m_vColors.clear();
|
||||
m_vColors.emplace_back(col);
|
||||
m_fAngle = 0;
|
||||
updateColorsOk();
|
||||
}
|
||||
|
||||
void updateColorsOk() {
|
||||
m_vColorsOkLabA.clear();
|
||||
for (auto& c : m_vColors) {
|
||||
const auto OKLAB = c.asOkLab();
|
||||
m_vColorsOkLabA.emplace_back(OKLAB.l);
|
||||
m_vColorsOkLabA.emplace_back(OKLAB.a);
|
||||
m_vColorsOkLabA.emplace_back(OKLAB.b);
|
||||
m_vColorsOkLabA.emplace_back(c.a);
|
||||
}
|
||||
}
|
||||
|
||||
/* Vector containing the colors */
|
||||
std::vector<CColor> m_vColors;
|
||||
std::vector<CHyprColor> m_vColors;
|
||||
|
||||
/* Vector containing pure colors for shoving into opengl */
|
||||
std::vector<float> m_vColorsOkLabA;
|
||||
|
||||
/* Float corresponding to the angle (rad) */
|
||||
float m_fAngle = 0;
|
||||
|
@@ -104,6 +104,30 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{0, 0, 4},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:snap:enabled",
|
||||
.description = "enable snapping for floating windows",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:snap:window_gap",
|
||||
.description = "minimum gap in pixels between windows before snapping",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{10, 0, 100},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:snap:monitor_gap",
|
||||
.description = "minimum gap in pixels between window and monitor edges before snapping",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{10, 0, 100},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:snap:border_overlap",
|
||||
.description = "if true, windows snap such that only one border's worth of space is between them",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
|
||||
/*
|
||||
* decoration:
|
||||
@@ -115,6 +139,12 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{0, 0, 20},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:rounding_power",
|
||||
.description = "rouding power of corners (2 is a circle)",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{2, 2, 10},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:active_opacity",
|
||||
.description = "opacity of active windows. [0.0 - 1.0]",
|
||||
@@ -134,49 +164,55 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:drop_shadow",
|
||||
.value = "decoration:shadow:enabled",
|
||||
.description = "enable drop shadows on windows",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_range",
|
||||
.value = "decoration:shadow:range",
|
||||
.description = "Shadow range (size) in layout px",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{4, 0, 100},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_render_power",
|
||||
.value = "decoration:shadow:render_power",
|
||||
.description = "in what power to render the falloff (more power, the faster the falloff) [1 - 4]",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{3, 1, 4},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_ignore_window",
|
||||
.value = "decoration:shadow:sharp",
|
||||
.description = "whether the shadow should be sharp or not. Akin to an infinitely high render power.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow:ignore_window",
|
||||
.description = "if true, the shadow will not be rendered behind the window itself, only around it.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:col.shadow",
|
||||
.value = "decoration:shadow:color",
|
||||
.description = "shadow's color. Alpha dictates shadow's opacity.",
|
||||
.type = CONFIG_OPTION_COLOR,
|
||||
.data = SConfigOptionDescription::SColorData{0xee1a1a1a},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:col.shadow_inactive",
|
||||
.value = "decoration:shadow:color_inactive",
|
||||
.description = "inactive shadow color. (if not set, will fall back to col.shadow)",
|
||||
.type = CONFIG_OPTION_COLOR,
|
||||
.data = SConfigOptionDescription::SColorData{}, //##TODO UNSET?
|
||||
.data = SConfigOptionDescription::SColorData{}, //TODO: UNSET?
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_offset",
|
||||
.value = "decoration:shadow:offset",
|
||||
.description = "shadow's rendering offset.",
|
||||
.type = CONFIG_OPTION_VECTOR,
|
||||
.data = SConfigOptionDescription::SVectorData{{}, {-250, -250}, {250, 250}},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "decoration:shadow_scale",
|
||||
.value = "decoration:shadow:scale",
|
||||
.description = "shadow's scale. [0.0 - 1.0]",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
||||
@@ -238,7 +274,7 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.value = "blur:ignore_opacity",
|
||||
.description = "make the blur layer ignore the opacity of the window",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "blur:new_optimizations",
|
||||
@@ -301,6 +337,18 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{0.2, 0, 1},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "blur:input_methods",
|
||||
.description = "whether to blur input methods (e.g. fcitx5)",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "blur:input_methods_ignorealpha",
|
||||
.description = "works like ignorealpha in layer rules. If pixel opacity is below set value, will not blur. [0.0 - 1.0]",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{0.2, 0, 1},
|
||||
},
|
||||
|
||||
/*
|
||||
* animations:
|
||||
@@ -590,16 +638,22 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "input:tablet:output",
|
||||
.description = "the monitor to bind tablets. Empty means unbound..",
|
||||
.description = "the monitor to bind tablets. Can be current or a monitor name. Leave empty to map across all monitors.",
|
||||
.type = CONFIG_OPTION_STRING_SHORT,
|
||||
.data = SConfigOptionDescription::SStringData{""}, //##TODO UNSET?
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "input:tablet:region_position",
|
||||
.description = "position of the mapped region in monitor layout.",
|
||||
.description = "position of the mapped region in monitor layout relative to the top left corner of the bound monitor or all monitors.",
|
||||
.type = CONFIG_OPTION_VECTOR,
|
||||
.data = SConfigOptionDescription::SVectorData{{}, {-20000, -20000}, {20000, 20000}},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "input:tablet:absolute_region_position",
|
||||
.description = "whether to treat the region_position as an absolute position in monitor layout. Only applies when output is empty.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "input:tablet:region_size",
|
||||
.description = "size of the mapped region. When this variable is set, tablet input will be mapped to the region. [0, 0] or invalid size means unset.",
|
||||
@@ -742,6 +796,18 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:merge_groups_on_drag",
|
||||
.description = "whether window groups can be dragged into other groups",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:merge_groups_on_groupbar",
|
||||
.description = "whether one group will be merged with another when dragged into its groupbar",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "general:col.border_active",
|
||||
.description = "border color for inactive windows",
|
||||
@@ -766,6 +832,30 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_GRADIENT,
|
||||
.data = SConfigOptionDescription::SGradientData{"0x66775500"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:auto_group",
|
||||
.description = "automatically group new windows",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:drag_into_group",
|
||||
.description = "whether dragging a window into a unlocked group will merge them. Options: 0 (disabled), 1 (enabled), 2 (only when dragging into the groupbar)",
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{0, "disabled,enabled,only when dragging into the groupbar"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:merge_floated_into_tiled_on_groupbar",
|
||||
.description = "whether dragging a floating window into a tiled window groupbar will merge them",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "group:group_on_movetoworkspace",
|
||||
.description = "whether using movetoworkspace[silent] will merge the window into the workspace's solitary unlocked group",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
|
||||
/*
|
||||
* group:groupbar:
|
||||
@@ -1037,6 +1127,30 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "misc:render_unfocused_fps",
|
||||
.description = "the maximum limit for renderunfocused windows' fps in the background",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{15, 1, 120},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "misc:disable_xdg_env_checks",
|
||||
.description = "disable the warning if XDG environment is externally managed",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "misc:disable_hyprland_qtutils_check",
|
||||
.description = "disable the warning if hyprland-qtutils is missing",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "misc:lockdead_screen_delay",
|
||||
.description = "the delay in ms after the lockdead screen appears if the lock screen did not appear after a lock event occurred.",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{1000, 0, 5000},
|
||||
},
|
||||
|
||||
/*
|
||||
* binds:
|
||||
@@ -1092,6 +1206,12 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "binds:movefocus_cycles_groupfirst",
|
||||
.description = "If enabled, when in a grouped window, movefocus will cycle windows in the groups first, then at each ends of tabs, it'll move on to other windows/groups",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "binds:disable_keybind_grabbing",
|
||||
.description = "If enabled, apps that request keybinds to be disabled (e.g. VMs) will not be able to do so.",
|
||||
@@ -1104,11 +1224,23 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "binds:allow_pin_fullscreen",
|
||||
.description = "Allows fullscreen to pinned windows, and restore their pinned status afterwards",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
|
||||
/*
|
||||
* xwayland:
|
||||
*/
|
||||
|
||||
SConfigOptionDescription{
|
||||
.value = "xwayland:enabled",
|
||||
.description = "allow running applications using X11",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "xwayland:use_nearest_neighbor",
|
||||
.description = "uses the nearest neighbor filtering for xwayland apps, making them pixelated rather than blurry",
|
||||
@@ -1163,6 +1295,30 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "render:expand_undersized_textures",
|
||||
.description = "Whether to expand textures that have not yet resized to be larger, or to just stretch them instead.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "render:xp_mode",
|
||||
.description = "Disable back buffer and bottom layer rendering.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "render:ctm_animation",
|
||||
.description = "Whether to enable a fade animation for CTM changes (hyprsunset). 2 means 'auto' (Yes on everything but Nvidia).",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{2, 0, 2},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "render:allow_early_buffer_release",
|
||||
.description = "Allow early buffer release event. Fixes stuttering and missing frames for some apps. May cause graphical glitches and memory leaks in others",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
|
||||
/*
|
||||
* cursor:
|
||||
@@ -1178,8 +1334,8 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
SConfigOptionDescription{
|
||||
.value = "cursor:no_hardware_cursors",
|
||||
.description = "disables hardware cursors",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{0, "Disabled,Enabled,Auto"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "cursor:no_break_fs_vrr",
|
||||
@@ -1219,9 +1375,9 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "cursor:warp_on_change_workspace",
|
||||
.description = "If true, move the cursor to the last focused window after changing the workspace.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
.description = "Move the cursor to the last focused window after changing the workspace. Options: 0 (Disabled), 1 (Enabled), 2 (Force - ignores cursor:no_warps option)",
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{0, "Disabled,Enabled,Force"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "cursor:default_monitor",
|
||||
@@ -1260,8 +1416,8 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "cursor:allow_dumb_copy",
|
||||
.description = "Makes HW cursors work on Nvidia, at the cost of a possible hitch whenever the image changes",
|
||||
.value = "cursor:use_cpu_buffer",
|
||||
.description = "Makes HW cursors use a CPU buffer. Required on Nvidia to have HW cursors. Experimental",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
@@ -1348,4 +1504,182 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
|
||||
/*
|
||||
* dwindle:
|
||||
*/
|
||||
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:pseudotile",
|
||||
.description = "enable pseudotiling. Pseudotiled windows retain their floating size when tiled.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:force_split",
|
||||
.description = "0 -> split follows mouse, 1 -> always split to the left (new = left or top) 2 -> always split to the right (new = right or bottom)",
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{0, "follow mouse,left or top,right or bottom"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:preserve_split",
|
||||
.description = "if enabled, the split (side/top) will not change regardless of what happens to the container.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:smart_split",
|
||||
.description = "if enabled, allows a more precise control over the window split direction based on the cursor's position. The window is conceptually divided into four "
|
||||
"triangles, and cursor's triangle determines the split direction. This feature also turns on preserve_split.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:smart_resizing",
|
||||
.description =
|
||||
"if enabled, resizing direction will be determined by the mouse's position on the window (nearest to which corner). Else, it is based on the window's tiling position.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:permanent_direction_override",
|
||||
.description = "if enabled, makes the preselect direction persist until either this mode is turned off, another direction is specified, or a non-direction is specified "
|
||||
"(anything other than l,r,u/t,d/b)",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:special_scale_factor",
|
||||
.description = "specifies the scale factor of windows on the special workspace [0 - 1]",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:split_width_multiplier",
|
||||
.description = "specifies the auto-split width multiplier",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{1, 0.1, 3},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:use_active_for_splits",
|
||||
.description = "whether to prefer the active window or the mouse position for splits",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:default_split_ratio",
|
||||
.description = "the default split ratio on window open. 1 means even 50/50 split. [0.1 - 1.9]",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{1, 0.1, 1.9},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "dwindle:split_bias",
|
||||
.description = "specifies which window will receive the larger half of a split. positional - 0, current window - 1, opening window - 2 [0/1/2]",
|
||||
.type = CONFIG_OPTION_CHOICE,
|
||||
.data = SConfigOptionDescription::SChoiceData{0, "positional,current,opening"},
|
||||
},
|
||||
|
||||
/*
|
||||
* master:
|
||||
*/
|
||||
|
||||
SConfigOptionDescription{
|
||||
.value = "master:allow_small_split",
|
||||
.description = "enable adding additional master windows in a horizontal split style",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:special_scale_factor",
|
||||
.description = "the scale of the special workspace windows. [0.0 - 1.0]",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{1, 0, 1},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:mfact",
|
||||
.description =
|
||||
"the size as a percentage of the master window, for example `mfact = 0.70` would mean 70% of the screen will be the master window, and 30% the slave [0.0 - 1.0]",
|
||||
.type = CONFIG_OPTION_FLOAT,
|
||||
.data = SConfigOptionDescription::SFloatData{0.55, 0, 1},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:new_status",
|
||||
.description = "`master`: new window becomes master; `slave`: new windows are added to slave stack; `inherit`: inherit from focused window",
|
||||
.type = CONFIG_OPTION_STRING_SHORT,
|
||||
.data = SConfigOptionDescription::SStringData{"slave"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:new_on_top",
|
||||
.description = "whether a newly open window should be on the top of the stack",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:new_on_active",
|
||||
.description = "`before`, `after`: place new window relative to the focused window; `none`: place new window according to the value of `new_on_top`. ",
|
||||
.type = CONFIG_OPTION_STRING_SHORT,
|
||||
.data = SConfigOptionDescription::SStringData{"none"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:orientation",
|
||||
.description = "default placement of the master area, can be left, right, top, bottom or center",
|
||||
.type = CONFIG_OPTION_STRING_SHORT,
|
||||
.data = SConfigOptionDescription::SStringData{"left"},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:inherit_fullscreen",
|
||||
.description = "inherit fullscreen status when cycling/swapping to another window (e.g. monocle layout)",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:slave_count_for_center_master",
|
||||
.description = "when using orientation=center, make the master window centered only when at least this many slave windows are open. (Set 0 to always_center_master)",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{2, 0, 10}, //##TODO RANGE?
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:center_master_slaves_on_right",
|
||||
.description = "set if the slaves should appear on right of master when slave_count_for_center_master > 2",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:center_ignores_reserved",
|
||||
.description = "centers the master window on monitor ignoring reserved areas",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:smart_resizing",
|
||||
.description =
|
||||
"if enabled, resizing direction will be determined by the mouse's position on the window (nearest to which corner). Else, it is based on the window's tiling position.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "master:drop_at_cursor",
|
||||
.description = "when enabled, dragging and dropping windows will put them at the cursor position. Otherwise, when dropped at the stack side, they will go to the "
|
||||
"top/bottom of the stack depending on new_on_top.",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{true},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "experimental:wide_color_gamut",
|
||||
.description = "force wide color gamut for all supported outputs",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "experimental:hdr",
|
||||
.description = "force static hdr for all supported outputs",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "experimental:xx_color_management_v4",
|
||||
.description = "enable color management protocol",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
};
|
||||
|
@@ -1,33 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <hyprutils/animation/AnimationConfig.hpp>
|
||||
#define CONFIG_MANAGER_H
|
||||
|
||||
#include <map>
|
||||
#include "../debug/Log.hpp"
|
||||
#include <unordered_map>
|
||||
#include "../defines.hpp"
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
#include <xf86drmMode.h>
|
||||
#include "../helpers/WLClasses.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../helpers/varlist/VarList.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "../desktop/LayerRule.hpp"
|
||||
|
||||
#include "defaultConfig.hpp"
|
||||
#include "ConfigDataValues.hpp"
|
||||
#include "../SharedDefs.hpp"
|
||||
#include "../helpers/Color.hpp"
|
||||
#include "../desktop/DesktopTypes.hpp"
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
#include "../desktop/WindowRule.hpp"
|
||||
#include "../managers/XWaylandManager.hpp"
|
||||
|
||||
#include <hyprlang.hpp>
|
||||
|
||||
#define INITANIMCFG(name) animationConfig[name] = {}
|
||||
#define CREATEANIMCFG(name, parent) animationConfig[name] = {false, "", "", 0.f, -1, &animationConfig["global"], &animationConfig[parent]}
|
||||
|
||||
#define HANDLE void*
|
||||
|
||||
struct SWorkspaceRule {
|
||||
@@ -56,26 +53,14 @@ struct SMonitorAdditionalReservedArea {
|
||||
int right = 0;
|
||||
};
|
||||
|
||||
struct SAnimationPropertyConfig {
|
||||
bool overridden = true;
|
||||
|
||||
std::string internalBezier = "";
|
||||
std::string internalStyle = "";
|
||||
float internalSpeed = 0.f;
|
||||
int internalEnabled = -1;
|
||||
|
||||
SAnimationPropertyConfig* pValues = nullptr;
|
||||
SAnimationPropertyConfig* pParentAnimation = nullptr;
|
||||
};
|
||||
|
||||
struct SPluginKeyword {
|
||||
HANDLE handle = 0;
|
||||
HANDLE handle = nullptr;
|
||||
std::string name = "";
|
||||
Hyprlang::PCONFIGHANDLERFUNC fn = nullptr;
|
||||
};
|
||||
|
||||
struct SPluginVariable {
|
||||
HANDLE handle = 0;
|
||||
HANDLE handle = nullptr;
|
||||
std::string name = "";
|
||||
};
|
||||
|
||||
@@ -84,7 +69,7 @@ struct SExecRequestedRule {
|
||||
uint64_t iPid = 0;
|
||||
};
|
||||
|
||||
enum eConfigOptionType : uint16_t {
|
||||
enum eConfigOptionType : uint8_t {
|
||||
CONFIG_OPTION_BOOL = 0,
|
||||
CONFIG_OPTION_INT = 1, /* e.g. 0/1/2*/
|
||||
CONFIG_OPTION_FLOAT = 2,
|
||||
@@ -96,7 +81,7 @@ enum eConfigOptionType : uint16_t {
|
||||
CONFIG_OPTION_VECTOR = 8,
|
||||
};
|
||||
|
||||
enum eConfigOptionFlags : uint32_t {
|
||||
enum eConfigOptionFlags : uint8_t {
|
||||
CONFIG_OPTION_FLAG_PERCENTAGE = (1 << 0),
|
||||
};
|
||||
|
||||
@@ -119,7 +104,7 @@ struct SConfigOptionDescription {
|
||||
};
|
||||
|
||||
struct SColorData {
|
||||
CColor color;
|
||||
CHyprColor color;
|
||||
};
|
||||
|
||||
struct SChoiceData {
|
||||
@@ -148,12 +133,18 @@ struct SConfigOptionDescription {
|
||||
std::variant<SBoolData, SRangeData, SFloatData, SStringData, SColorData, SChoiceData, SGradientData, SVectorData> data;
|
||||
};
|
||||
|
||||
struct SFirstExecRequest {
|
||||
std::string exec = "";
|
||||
bool withRules = false;
|
||||
};
|
||||
|
||||
class CConfigManager {
|
||||
public:
|
||||
CConfigManager();
|
||||
|
||||
void tick();
|
||||
void init();
|
||||
void reload();
|
||||
std::string verify();
|
||||
|
||||
int getDeviceInt(const std::string&, const std::string&, const std::string& fallback = "");
|
||||
float getDeviceFloat(const std::string&, const std::string&, const std::string& fallback = "");
|
||||
@@ -165,144 +156,154 @@ class CConfigManager {
|
||||
|
||||
void* const* getConfigValuePtr(const std::string&);
|
||||
Hyprlang::CConfigValue* getHyprlangConfigValuePtr(const std::string& name, const std::string& specialCat = "");
|
||||
void onPluginLoadUnload(const std::string& name, bool load);
|
||||
static std::string getMainConfigPath();
|
||||
const std::string getConfigString();
|
||||
std::string getMainConfigPath();
|
||||
std::string getConfigString();
|
||||
|
||||
SMonitorRule getMonitorRuleFor(const CMonitor&);
|
||||
SMonitorRule getMonitorRuleFor(const PHLMONITOR);
|
||||
SWorkspaceRule getWorkspaceRuleFor(PHLWORKSPACE workspace);
|
||||
std::string getDefaultWorkspaceFor(const std::string&);
|
||||
|
||||
CMonitor* getBoundMonitorForWS(const std::string&);
|
||||
PHLMONITOR getBoundMonitorForWS(const std::string&);
|
||||
std::string getBoundMonitorStringForWS(const std::string&);
|
||||
const std::deque<SWorkspaceRule>& getAllWorkspaceRules();
|
||||
const std::vector<SWorkspaceRule>& getAllWorkspaceRules();
|
||||
|
||||
std::vector<SWindowRule> getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false);
|
||||
std::vector<SLayerRule> getMatchingRules(PHLLS);
|
||||
std::vector<SP<CWindowRule>> getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false);
|
||||
std::vector<SP<CLayerRule>> getMatchingRules(PHLLS);
|
||||
void ensurePersistentWorkspacesPresent();
|
||||
|
||||
const std::vector<SConfigOptionDescription>& getAllDescriptions();
|
||||
|
||||
std::unordered_map<std::string, SMonitorAdditionalReservedArea> m_mAdditionalReservedAreas;
|
||||
|
||||
std::unordered_map<std::string, SAnimationPropertyConfig> getAnimationConfig();
|
||||
const std::unordered_map<std::string, SP<Hyprutils::Animation::SAnimationPropertyConfig>>& getAnimationConfig();
|
||||
|
||||
void addPluginConfigVar(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value);
|
||||
void addPluginConfigVar(HANDLE handle, const std::string& name, const Hyprlang::CConfigValue& value);
|
||||
void addPluginKeyword(HANDLE handle, const std::string& name, Hyprlang::PCONFIGHANDLERFUNC fun, Hyprlang::SHandlerOptions opts = {});
|
||||
void removePluginConfig(HANDLE handle);
|
||||
|
||||
// no-op when done.
|
||||
void dispatchExecOnce();
|
||||
void dispatchExecOnce();
|
||||
void dispatchExecShutdown();
|
||||
|
||||
void performMonitorReload();
|
||||
void appendMonitorRule(const SMonitorRule&);
|
||||
bool replaceMonitorRule(const SMonitorRule&);
|
||||
void ensureMonitorStatus();
|
||||
void ensureVRR(CMonitor* pMonitor = nullptr);
|
||||
void performMonitorReload();
|
||||
void ensureMonitorStatus();
|
||||
void ensureVRR(PHLMONITOR pMonitor = nullptr);
|
||||
|
||||
std::string parseKeyword(const std::string&, const std::string&);
|
||||
bool shouldUseSoftwareCursors();
|
||||
|
||||
void addParseError(const std::string&);
|
||||
std::string parseKeyword(const std::string&, const std::string&);
|
||||
|
||||
SAnimationPropertyConfig* getAnimationPropertyConfig(const std::string&);
|
||||
void addParseError(const std::string&);
|
||||
|
||||
void addExecRule(const SExecRequestedRule&);
|
||||
SP<Hyprutils::Animation::SAnimationPropertyConfig> getAnimationPropertyConfig(const std::string&);
|
||||
|
||||
void handlePluginLoads();
|
||||
std::string getErrors();
|
||||
void addExecRule(const SExecRequestedRule&);
|
||||
|
||||
void handlePluginLoads();
|
||||
std::string getErrors();
|
||||
|
||||
// keywords
|
||||
std::optional<std::string> handleRawExec(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExecOnce(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleMonitor(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBind(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleUnbind(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleWindowRule(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleLayerRule(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleWindowRuleV2(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleWorkspaceRules(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBezier(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleAnimation(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleSource(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleSubmap(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBlurLS(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBindWS(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleEnv(const std::string&, const std::string&);
|
||||
std::optional<std::string> handlePlugin(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleRawExec(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExec(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExecOnce(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExecRawOnce(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleExecShutdown(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleMonitor(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBind(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleUnbind(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleWindowRule(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleLayerRule(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleWindowRuleV2(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleWorkspaceRules(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBezier(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleAnimation(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleSource(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleSubmap(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBlurLS(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleBindWS(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleEnv(const std::string&, const std::string&);
|
||||
std::optional<std::string> handlePlugin(const std::string&, const std::string&);
|
||||
|
||||
std::string configCurrentPath;
|
||||
std::string configCurrentPath;
|
||||
|
||||
std::unordered_map<std::string, std::function<CWindowOverridableVar<bool>*(PHLWINDOW)>> mbWindowProperties = {
|
||||
{"allowsinput", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.allowsInput; }},
|
||||
{"dimaround", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.dimAround; }},
|
||||
{"decorate", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.decorate; }},
|
||||
{"focusonactivate", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.focusOnActivate; }},
|
||||
{"keepaspectratio", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.keepAspectRatio; }},
|
||||
{"nearestneighbor", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.nearestNeighbor; }},
|
||||
{"noanim", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noAnim; }},
|
||||
{"noblur", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noBlur; }},
|
||||
{"noborder", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noBorder; }},
|
||||
{"nodim", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noDim; }},
|
||||
{"nofocus", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noFocus; }},
|
||||
{"nomaxsize", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noMaxSize; }},
|
||||
{"norounding", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noRounding; }},
|
||||
{"noshadow", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noShadow; }},
|
||||
{"noshortcutsinhibit", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.noShortcutsInhibit; }},
|
||||
{"opaque", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.opaque; }},
|
||||
{"forcergbx", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.RGBX; }},
|
||||
{"syncfullscreen", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.syncFullscreen; }},
|
||||
{"immediate", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.tearing; }},
|
||||
{"xray", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.xray; }},
|
||||
std::unordered_map<std::string, std::function<CWindowOverridableVar<bool>*(const PHLWINDOW&)>> mbWindowProperties = {
|
||||
{"allowsinput", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.allowsInput; }},
|
||||
{"dimaround", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.dimAround; }},
|
||||
{"decorate", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.decorate; }},
|
||||
{"focusonactivate", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.focusOnActivate; }},
|
||||
{"keepaspectratio", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.keepAspectRatio; }},
|
||||
{"nearestneighbor", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.nearestNeighbor; }},
|
||||
{"noanim", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noAnim; }},
|
||||
{"noblur", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noBlur; }},
|
||||
{"noborder", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noBorder; }},
|
||||
{"nodim", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noDim; }},
|
||||
{"nofocus", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noFocus; }},
|
||||
{"nomaxsize", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noMaxSize; }},
|
||||
{"norounding", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noRounding; }},
|
||||
{"noshadow", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noShadow; }},
|
||||
{"noshortcutsinhibit", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.noShortcutsInhibit; }},
|
||||
{"opaque", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.opaque; }},
|
||||
{"forcergbx", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.RGBX; }},
|
||||
{"syncfullscreen", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.syncFullscreen; }},
|
||||
{"immediate", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.tearing; }},
|
||||
{"xray", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.xray; }},
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, std::function<CWindowOverridableVar<int>*(PHLWINDOW)>> miWindowProperties = {
|
||||
{"rounding", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.rounding; }}, {"bordersize", [](PHLWINDOW pWindow) { return &pWindow->m_sWindowData.borderSize; }}};
|
||||
std::unordered_map<std::string, std::function<CWindowOverridableVar<int>*(const PHLWINDOW&)>> miWindowProperties = {
|
||||
{"rounding", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.rounding; }},
|
||||
{"bordersize", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.borderSize; }},
|
||||
};
|
||||
|
||||
bool m_bWantsMonitorReload = false;
|
||||
bool m_bForceReload = false;
|
||||
bool m_bNoMonitorReload = false;
|
||||
bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking
|
||||
std::unordered_map<std::string, std::function<CWindowOverridableVar<float>*(PHLWINDOW)>> mfWindowProperties = {
|
||||
{"roundingpower", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.roundingPower; }},
|
||||
{"scrollmouse", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollMouse; }},
|
||||
{"scrolltouchpad", [](const PHLWINDOW& pWindow) { return &pWindow->m_sWindowData.scrollTouchpad; }}};
|
||||
|
||||
bool m_bWantsMonitorReload = false;
|
||||
bool m_bNoMonitorReload = false;
|
||||
bool isLaunchingExecOnce = false; // For exec-once to skip initial ws tracking
|
||||
bool m_bLastConfigVerificationWasSuccessful = true;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Hyprlang::CConfig> m_pConfig;
|
||||
UP<Hyprlang::CConfig> m_pConfig;
|
||||
|
||||
std::deque<std::string> configPaths; // stores all the config paths
|
||||
std::unordered_map<std::string, time_t> configModifyTimes; // stores modify times
|
||||
std::vector<std::string> m_configPaths;
|
||||
|
||||
std::unordered_map<std::string, SAnimationPropertyConfig> animationConfig; // stores all the animations with their set values
|
||||
Hyprutils::Animation::CAnimationConfigTree m_AnimationTree;
|
||||
|
||||
std::string m_szCurrentSubmap = ""; // For storing the current keybind submap
|
||||
std::string m_szCurrentSubmap = ""; // For storing the current keybind submap
|
||||
|
||||
std::vector<SExecRequestedRule> execRequestedRules; // rules requested with exec, e.g. [workspace 2] kitty
|
||||
std::vector<SExecRequestedRule> execRequestedRules; // rules requested with exec, e.g. [workspace 2] kitty
|
||||
|
||||
std::vector<std::string> m_vDeclaredPlugins;
|
||||
std::vector<SPluginKeyword> pluginKeywords;
|
||||
std::vector<SPluginVariable> pluginVariables;
|
||||
std::vector<std::string> m_vDeclaredPlugins;
|
||||
std::vector<SPluginKeyword> pluginKeywords;
|
||||
std::vector<SPluginVariable> pluginVariables;
|
||||
|
||||
bool isFirstLaunch = true; // For exec-once
|
||||
bool isFirstLaunch = true; // For exec-once
|
||||
|
||||
std::deque<SMonitorRule> m_dMonitorRules;
|
||||
std::deque<SWorkspaceRule> m_dWorkspaceRules;
|
||||
std::deque<SWindowRule> m_dWindowRules;
|
||||
std::deque<SLayerRule> m_dLayerRules;
|
||||
std::deque<std::string> m_dBlurLSNamespaces;
|
||||
std::vector<SMonitorRule> m_vMonitorRules;
|
||||
std::vector<SWorkspaceRule> m_vWorkspaceRules;
|
||||
std::vector<SP<CWindowRule>> m_vWindowRules;
|
||||
std::vector<SP<CLayerRule>> m_vLayerRules;
|
||||
std::vector<std::string> m_dBlurLSNamespaces;
|
||||
|
||||
bool firstExecDispatched = false;
|
||||
bool m_bManualCrashInitiated = false;
|
||||
std::deque<std::string> firstExecRequests;
|
||||
bool firstExecDispatched = false;
|
||||
bool m_bManualCrashInitiated = false;
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins
|
||||
std::string m_szConfigErrors = "";
|
||||
std::vector<SFirstExecRequest> firstExecRequests; // bool is for if with rules
|
||||
std::vector<std::string> finalExecRequests;
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins
|
||||
std::string m_szConfigErrors = "";
|
||||
|
||||
// internal methods
|
||||
void setAnimForChildren(SAnimationPropertyConfig* const);
|
||||
void updateBlurredLS(const std::string&, const bool);
|
||||
void setDefaultAnimationVars();
|
||||
std::optional<std::string> resetHLConfig();
|
||||
static std::optional<std::string> generateConfig(std::string configPath);
|
||||
static std::optional<std::string> verifyConfigExists();
|
||||
void postConfigReload(const Hyprlang::CParseResult& result);
|
||||
void reload();
|
||||
SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&);
|
||||
void updateBlurredLS(const std::string&, const bool);
|
||||
void setDefaultAnimationVars();
|
||||
std::optional<std::string> resetHLConfig();
|
||||
std::optional<std::string> generateConfig(std::string configPath);
|
||||
std::optional<std::string> verifyConfigExists();
|
||||
void postConfigReload(const Hyprlang::CParseResult& result);
|
||||
SWorkspaceRule mergeWorkspaceRules(const SWorkspaceRule&, const SWorkspaceRule&);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
||||
inline UP<CConfigManager> g_pConfigManager;
|
||||
|
@@ -3,7 +3,6 @@
|
||||
#include <string>
|
||||
#include <typeindex>
|
||||
#include <hyprlang.hpp>
|
||||
#include "../debug/Log.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "ConfigManager.hpp"
|
||||
|
||||
@@ -13,6 +12,7 @@ class CConfigValue {
|
||||
CConfigValue(const std::string& val) {
|
||||
const auto PVHYPRLANG = g_pConfigManager->getHyprlangConfigValuePtr(val);
|
||||
|
||||
// NOLINTNEXTLINE
|
||||
p_ = PVHYPRLANG->getDataStaticPtr();
|
||||
|
||||
#ifdef HYPRLAND_DEBUG
|
||||
@@ -70,4 +70,4 @@ template <>
|
||||
inline Hyprlang::CUSTOMTYPE CConfigValue<Hyprlang::CUSTOMTYPE>::operator*() const {
|
||||
RASSERT(false, "Impossible to implement operator* of CConfigValue<Hyprlang::CUSTOMTYPE>, use ptr()");
|
||||
return *ptr();
|
||||
}
|
||||
}
|
||||
|
73
src/config/ConfigWatcher.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "ConfigWatcher.hpp"
|
||||
#include <sys/inotify.h>
|
||||
#include "../debug/Log.hpp"
|
||||
#include <ranges>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
CConfigWatcher::CConfigWatcher() : m_inotifyFd(inotify_init()) {
|
||||
if (m_inotifyFd < 0) {
|
||||
Debug::log(ERR, "CConfigWatcher couldn't open an inotify node. Config will not be automatically reloaded");
|
||||
return;
|
||||
}
|
||||
|
||||
const int FLAGS = fcntl(m_inotifyFd, F_GETFL, 0);
|
||||
if (fcntl(m_inotifyFd, F_SETFL, FLAGS | O_NONBLOCK) < 0) {
|
||||
Debug::log(ERR, "CConfigWatcher couldn't non-block inotify node. Config will not be automatically reloaded");
|
||||
close(m_inotifyFd);
|
||||
m_inotifyFd = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CConfigWatcher::~CConfigWatcher() {
|
||||
if (m_inotifyFd >= 0)
|
||||
close(m_inotifyFd);
|
||||
}
|
||||
|
||||
int CConfigWatcher::getInotifyFD() {
|
||||
return m_inotifyFd;
|
||||
}
|
||||
|
||||
void CConfigWatcher::setWatchList(const std::vector<std::string>& paths) {
|
||||
|
||||
// we clear all watches first, because whichever fired is now invalid
|
||||
// or that is at least what it seems to be.
|
||||
// since we don't know which fired,
|
||||
// plus it doesn't matter that much, these ops are done rarely and fast anyways.
|
||||
|
||||
// cleanup old paths
|
||||
for (auto& watch : m_watches) {
|
||||
inotify_rm_watch(m_inotifyFd, watch.wd);
|
||||
}
|
||||
|
||||
m_watches.clear();
|
||||
|
||||
// add new paths
|
||||
for (const auto& path : paths) {
|
||||
m_watches.emplace_back(SInotifyWatch{
|
||||
.wd = inotify_add_watch(m_inotifyFd, path.c_str(), IN_MODIFY),
|
||||
.file = path,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigWatcher::setOnChange(const std::function<void(const SConfigWatchEvent&)>& fn) {
|
||||
m_watchCallback = fn;
|
||||
}
|
||||
|
||||
void CConfigWatcher::onInotifyEvent() {
|
||||
inotify_event ev;
|
||||
while (read(m_inotifyFd, &ev, sizeof(ev)) > 0) {
|
||||
const auto WD = std::ranges::find_if(m_watches.begin(), m_watches.end(), [wd = ev.wd](const auto& e) { return e.wd == wd; });
|
||||
|
||||
if (WD == m_watches.end()) {
|
||||
Debug::log(ERR, "CConfigWatcher: got an event for wd {} which we don't have?!", ev.wd);
|
||||
return;
|
||||
}
|
||||
|
||||
m_watchCallback(SConfigWatchEvent{
|
||||
.file = WD->file,
|
||||
});
|
||||
}
|
||||
}
|
32
src/config/ConfigWatcher.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
class CConfigWatcher {
|
||||
public:
|
||||
CConfigWatcher();
|
||||
~CConfigWatcher();
|
||||
|
||||
struct SConfigWatchEvent {
|
||||
std::string file;
|
||||
};
|
||||
|
||||
int getInotifyFD();
|
||||
void setWatchList(const std::vector<std::string>& paths);
|
||||
void setOnChange(const std::function<void(const SConfigWatchEvent&)>& fn);
|
||||
void onInotifyEvent();
|
||||
|
||||
private:
|
||||
struct SInotifyWatch {
|
||||
int wd = -1;
|
||||
std::string file;
|
||||
};
|
||||
|
||||
std::function<void(const SConfigWatchEvent&)> m_watchCallback;
|
||||
std::vector<SInotifyWatch> m_watches;
|
||||
int m_inotifyFd = -1;
|
||||
};
|
||||
|
||||
inline UP<CConfigWatcher> g_pConfigWatcher = makeUnique<CConfigWatcher>();
|
@@ -4,8 +4,8 @@
|
||||
|
||||
inline const std::string AUTOCONFIG = R"#(
|
||||
# #######################################################################################
|
||||
# AUTOGENERATED HYPR CONFIG.
|
||||
# PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hypr.conf AND EDIT IT,
|
||||
# AUTOGENERATED HYPRLAND CONFIG.
|
||||
# PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hyprland.conf AND EDIT IT,
|
||||
# OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
|
||||
# #######################################################################################
|
||||
|
||||
@@ -13,7 +13,7 @@ autogenerated = 1 # remove this line to remove the warning
|
||||
|
||||
# This is an example Hyprland config file.
|
||||
# Refer to the wiki for more information.
|
||||
# https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
||||
# https://wiki.hyprland.org/Configuring/
|
||||
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki
|
||||
@@ -72,7 +72,7 @@ env = HYPRCURSOR_SIZE,24
|
||||
# Refer to https://wiki.hyprland.org/Configuring/Variables/
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#general
|
||||
general {
|
||||
general {
|
||||
gaps_in = 5
|
||||
gaps_out = 20
|
||||
|
||||
@@ -83,7 +83,7 @@ general {
|
||||
col.inactive_border = rgba(595959aa)
|
||||
|
||||
# Set to true enable resizing windows by clicking and dragging on borders and gaps
|
||||
resize_on_border = false
|
||||
resize_on_border = false
|
||||
|
||||
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
|
||||
allow_tearing = false
|
||||
@@ -94,42 +94,69 @@ general {
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||
decoration {
|
||||
rounding = 10
|
||||
rounding_power = 2
|
||||
|
||||
# Change transparency of focused and unfocused windows
|
||||
active_opacity = 1.0
|
||||
inactive_opacity = 1.0
|
||||
|
||||
drop_shadow = true
|
||||
shadow_range = 4
|
||||
shadow_render_power = 3
|
||||
col.shadow = rgba(1a1a1aee)
|
||||
shadow {
|
||||
enabled = true
|
||||
range = 4
|
||||
render_power = 3
|
||||
color = rgba(1a1a1aee)
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
||||
blur {
|
||||
enabled = true
|
||||
size = 3
|
||||
passes = 1
|
||||
|
||||
|
||||
vibrancy = 0.1696
|
||||
}
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
||||
animations {
|
||||
enabled = true
|
||||
enabled = yes, please :)
|
||||
|
||||
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||
|
||||
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
||||
bezier = easeOutQuint,0.23,1,0.32,1
|
||||
bezier = easeInOutCubic,0.65,0.05,0.36,1
|
||||
bezier = linear,0,0,1,1
|
||||
bezier = almostLinear,0.5,0.5,0.75,1.0
|
||||
bezier = quick,0.15,0,0.1,1
|
||||
|
||||
animation = windows, 1, 7, myBezier
|
||||
animation = windowsOut, 1, 7, default, popin 80%
|
||||
animation = border, 1, 10, default
|
||||
animation = borderangle, 1, 8, default
|
||||
animation = fade, 1, 7, default
|
||||
animation = workspaces, 1, 6, default
|
||||
animation = global, 1, 10, default
|
||||
animation = border, 1, 5.39, easeOutQuint
|
||||
animation = windows, 1, 4.79, easeOutQuint
|
||||
animation = windowsIn, 1, 4.1, easeOutQuint, popin 87%
|
||||
animation = windowsOut, 1, 1.49, linear, popin 87%
|
||||
animation = fadeIn, 1, 1.73, almostLinear
|
||||
animation = fadeOut, 1, 1.46, almostLinear
|
||||
animation = fade, 1, 3.03, quick
|
||||
animation = layers, 1, 3.81, easeOutQuint
|
||||
animation = layersIn, 1, 4, easeOutQuint, fade
|
||||
animation = layersOut, 1, 1.5, linear, fade
|
||||
animation = fadeLayersIn, 1, 1.79, almostLinear
|
||||
animation = fadeLayersOut, 1, 1.39, almostLinear
|
||||
animation = workspaces, 1, 1.94, almostLinear, fade
|
||||
animation = workspacesIn, 1, 1.21, almostLinear, fade
|
||||
animation = workspacesOut, 1, 1.94, almostLinear, fade
|
||||
}
|
||||
|
||||
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
||||
# "Smart gaps" / "No gaps when only"
|
||||
# uncomment all if you wish to use that.
|
||||
# workspace = w[tv1], gapsout:0, gapsin:0
|
||||
# workspace = f[1], gapsout:0, gapsin:0
|
||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tv1]
|
||||
# windowrulev2 = rounding 0, floating:0, onworkspace:w[tv1]
|
||||
# windowrulev2 = bordersize 0, floating:0, onworkspace:f[1]
|
||||
# windowrulev2 = rounding 0, floating:0, onworkspace:f[1]
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||
dwindle {
|
||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||
@@ -142,7 +169,7 @@ master {
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#misc
|
||||
misc {
|
||||
misc {
|
||||
force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
|
||||
disable_hyprland_logo = false # If true disables the random hyprland logo / anime girl background. :(
|
||||
}
|
||||
@@ -241,6 +268,19 @@ bind = $mainMod, mouse_up, workspace, e-1
|
||||
bindm = $mainMod, mouse:272, movewindow
|
||||
bindm = $mainMod, mouse:273, resizewindow
|
||||
|
||||
# Laptop multimedia keys for volume and LCD brightness
|
||||
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
|
||||
bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||
bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||
bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||
bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+
|
||||
bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%-
|
||||
|
||||
# Requires playerctl
|
||||
bindl = , XF86AudioNext, exec, playerctl next
|
||||
bindl = , XF86AudioPause, exec, playerctl play-pause
|
||||
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
||||
bindl = , XF86AudioPrev, exec, playerctl previous
|
||||
|
||||
##############################
|
||||
### WINDOWS AND WORKSPACES ###
|
||||
@@ -255,5 +295,9 @@ bindm = $mainMod, mouse:273, resizewindow
|
||||
# Example windowrule v2
|
||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||
|
||||
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
|
||||
# Ignore maximize requests from apps. You'll probably like this.
|
||||
windowrulev2 = suppressevent maximize, class:.*
|
||||
|
||||
# Fix some dragging issues with XWayland
|
||||
windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
|
||||
)#";
|
||||
|
@@ -2,10 +2,11 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <link.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <ctime>
|
||||
#include <cerrno>
|
||||
#include <sys/stat.h>
|
||||
#include <filesystem>
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
|
||||
#include "../plugins/PluginSystem.hpp"
|
||||
#include "../signal-safe.hpp"
|
||||
@@ -31,10 +32,10 @@ static char const* const MESSAGES[] = {"Sorry, didn't mean to...",
|
||||
|
||||
// <random> is not async-signal-safe, fake it with time(NULL) instead
|
||||
char const* getRandomMessage() {
|
||||
return MESSAGES[time(NULL) % (sizeof(MESSAGES) / sizeof(MESSAGES[0]))];
|
||||
return MESSAGES[time(nullptr) % (sizeof(MESSAGES) / sizeof(MESSAGES[0]))];
|
||||
}
|
||||
|
||||
[[noreturn]] inline void exit_with_error(char const* err) {
|
||||
[[noreturn]] inline void exitWithError(char const* err) {
|
||||
write(STDERR_FILENO, err, strlen(err));
|
||||
// perror() is not signal-safe, but we use it here
|
||||
// because if the crash-handler already crashed, it can't get any worse.
|
||||
@@ -42,17 +43,17 @@ char const* getRandomMessage() {
|
||||
abort();
|
||||
}
|
||||
|
||||
void CrashReporter::createAndSaveCrash(int sig) {
|
||||
int reportFd;
|
||||
void NCrashReporter::createAndSaveCrash(int sig) {
|
||||
int reportFd = -1;
|
||||
|
||||
// We're in the signal handler, so we *only* have stack memory.
|
||||
// To save as much stack memory as possible,
|
||||
// destroy things as soon as possible.
|
||||
{
|
||||
MaxLengthCString<255> reportPath;
|
||||
CMaxLengthCString<255> reportPath;
|
||||
|
||||
const auto HOME = sig_getenv("HOME");
|
||||
const auto CACHE_HOME = sig_getenv("XDG_CACHE_HOME");
|
||||
const auto HOME = sigGetenv("HOME");
|
||||
const auto CACHE_HOME = sigGetenv("XDG_CACHE_HOME");
|
||||
|
||||
if (CACHE_HOME && CACHE_HOME[0] != '\0') {
|
||||
reportPath += CACHE_HOME;
|
||||
@@ -61,24 +62,24 @@ void CrashReporter::createAndSaveCrash(int sig) {
|
||||
reportPath += HOME;
|
||||
reportPath += "/.cache/hyprland";
|
||||
} else {
|
||||
exit_with_error("$CACHE_HOME and $HOME not set, nowhere to report crash\n");
|
||||
exitWithError("$CACHE_HOME and $HOME not set, nowhere to report crash\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = mkdir(reportPath.get_str(), S_IRWXU);
|
||||
int ret = mkdir(reportPath.getStr(), S_IRWXU);
|
||||
//__asm__("int $3");
|
||||
if (ret < 0 && errno != EEXIST) {
|
||||
exit_with_error("failed to mkdir() crash report directory\n");
|
||||
exitWithError("failed to mkdir() crash report directory\n");
|
||||
}
|
||||
reportPath += "/hyprlandCrashReport";
|
||||
reportPath.write_num(getpid());
|
||||
reportPath.writeNum(getpid());
|
||||
reportPath += ".txt";
|
||||
|
||||
{
|
||||
BufFileWriter<64> stderr(2);
|
||||
CBufFileWriter<64> stderr(2);
|
||||
stderr += "Hyprland has crashed :( Consult the crash report at ";
|
||||
if (!reportPath.boundsExceeded()) {
|
||||
stderr += reportPath.get_str();
|
||||
stderr += reportPath.getStr();
|
||||
} else {
|
||||
stderr += "[ERROR: Crash report path does not fit into memory! Check if your $CACHE_HOME/$HOME is too deeply nested. Max 255 characters.]";
|
||||
}
|
||||
@@ -86,12 +87,12 @@ void CrashReporter::createAndSaveCrash(int sig) {
|
||||
stderr.flush();
|
||||
}
|
||||
|
||||
reportFd = open(reportPath.get_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
reportFd = open(reportPath.getStr(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
if (reportFd < 0) {
|
||||
exit_with_error("Failed to open crash report path for writing");
|
||||
exitWithError("Failed to open crash report path for writing");
|
||||
}
|
||||
}
|
||||
BufFileWriter<512> finalCrashReport(reportFd);
|
||||
CBufFileWriter<512> finalCrashReport(reportFd);
|
||||
|
||||
finalCrashReport += "--------------------------------------------\n Hyprland Crash Report\n--------------------------------------------\n";
|
||||
finalCrashReport += getRandomMessage();
|
||||
@@ -100,7 +101,7 @@ void CrashReporter::createAndSaveCrash(int sig) {
|
||||
finalCrashReport += "Hyprland received signal ";
|
||||
finalCrashReport.writeNum(sig);
|
||||
finalCrashReport += '(';
|
||||
finalCrashReport += sig_strsignal(sig);
|
||||
finalCrashReport += sigStrsignal(sig);
|
||||
finalCrashReport += ")\nVersion: ";
|
||||
finalCrashReport += GIT_COMMIT_HASH;
|
||||
finalCrashReport += "\nTag: ";
|
||||
@@ -111,7 +112,7 @@ void CrashReporter::createAndSaveCrash(int sig) {
|
||||
#ifdef LEGACY_RENDERER
|
||||
finalCrashReport += "legacyrenderer\n";
|
||||
#endif
|
||||
#ifndef ISDEBUG
|
||||
#if ISDEBUG
|
||||
finalCrashReport += "debug\n";
|
||||
#endif
|
||||
#ifdef NO_XWAYLAND
|
||||
@@ -122,9 +123,9 @@ void CrashReporter::createAndSaveCrash(int sig) {
|
||||
if (g_pPluginSystem && g_pPluginSystem->pluginCount() > 0) {
|
||||
finalCrashReport += "Hyprland seems to be running with plugins. This crash might not be Hyprland's fault.\nPlugins:\n";
|
||||
|
||||
size_t count = g_pPluginSystem->pluginCount();
|
||||
CPlugin* plugins[count];
|
||||
g_pPluginSystem->sig_getPlugins(plugins, count);
|
||||
const size_t count = g_pPluginSystem->pluginCount();
|
||||
std::vector<CPlugin*> plugins(count);
|
||||
g_pPluginSystem->sigGetPlugins(plugins.data(), count);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
auto p = plugins[i];
|
||||
@@ -159,9 +160,9 @@ void CrashReporter::createAndSaveCrash(int sig) {
|
||||
|
||||
finalCrashReport += "GPU:\n\t";
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
finalCrashReport.writeCmdOutput("pciconf -lv | fgrep -A4 vga");
|
||||
finalCrashReport.writeCmdOutput("pciconf -lv | grep -F -A4 vga");
|
||||
#else
|
||||
finalCrashReport.writeCmdOutput("lspci -vnn | grep VGA");
|
||||
finalCrashReport.writeCmdOutput("lspci -vnn | grep -E '(VGA|Display|3D)'");
|
||||
#endif
|
||||
|
||||
finalCrashReport += "\n\nos-release:\n";
|
||||
@@ -241,5 +242,5 @@ void CrashReporter::createAndSaveCrash(int sig) {
|
||||
|
||||
finalCrashReport += "\n\nLog tail:\n";
|
||||
|
||||
finalCrashReport += std::string_view(Debug::rollingLog).substr(Debug::rollingLog.find("\n") + 1);
|
||||
finalCrashReport += std::string_view(Debug::rollingLog).substr(Debug::rollingLog.find('\n') + 1);
|
||||
}
|
||||
|
@@ -2,6 +2,6 @@
|
||||
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace CrashReporter {
|
||||
namespace NCrashReporter {
|
||||
void createAndSaveCrash(int sig);
|
||||
};
|
@@ -1,10 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Compositor.hpp"
|
||||
#include <fstream>
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include <functional>
|
||||
|
||||
// exposed for main.cpp
|
||||
std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request);
|
||||
std::string versionRequest(eHyprCtlOutputFormat format, std::string request);
|
||||
|
||||
class CHyprCtl {
|
||||
public:
|
||||
CHyprCtl();
|
||||
@@ -34,4 +38,4 @@ class CHyprCtl {
|
||||
std::string m_socketPath;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprCtl> g_pHyprCtl;
|
||||
inline UP<CHyprCtl> g_pHyprCtl;
|
||||
|
@@ -2,13 +2,21 @@
|
||||
#include "HyprDebugOverlay.hpp"
|
||||
#include "config/ConfigValue.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../render/pass/TexPassElement.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
|
||||
CHyprDebugOverlay::CHyprDebugOverlay() {
|
||||
m_pTexture = makeShared<CTexture>();
|
||||
}
|
||||
|
||||
void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) {
|
||||
m_dLastRenderTimes.push_back(durationUs / 1000.f);
|
||||
void CHyprMonitorDebugOverlay::renderData(PHLMONITOR pMonitor, float durationUs) {
|
||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
||||
|
||||
if (!*PDEBUGOVERLAY)
|
||||
return;
|
||||
|
||||
m_dLastRenderTimes.emplace_back(durationUs / 1000.f);
|
||||
|
||||
if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate)
|
||||
m_dLastRenderTimes.pop_front();
|
||||
@@ -17,8 +25,13 @@ void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float durationUs)
|
||||
m_pMonitor = pMonitor;
|
||||
}
|
||||
|
||||
void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) {
|
||||
m_dLastRenderTimesNoOverlay.push_back(durationUs / 1000.f);
|
||||
void CHyprMonitorDebugOverlay::renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs) {
|
||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
||||
|
||||
if (!*PDEBUGOVERLAY)
|
||||
return;
|
||||
|
||||
m_dLastRenderTimesNoOverlay.emplace_back(durationUs / 1000.f);
|
||||
|
||||
if (m_dLastRenderTimesNoOverlay.size() > (long unsigned int)pMonitor->refreshRate)
|
||||
m_dLastRenderTimesNoOverlay.pop_front();
|
||||
@@ -27,8 +40,13 @@ void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float dur
|
||||
m_pMonitor = pMonitor;
|
||||
}
|
||||
|
||||
void CHyprMonitorDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||
m_dLastFrametimes.push_back(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - m_tpLastFrame).count() / 1000.f);
|
||||
void CHyprMonitorDebugOverlay::frameData(PHLMONITOR pMonitor) {
|
||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
||||
|
||||
if (!*PDEBUGOVERLAY)
|
||||
return;
|
||||
|
||||
m_dLastFrametimes.emplace_back(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - m_tpLastFrame).count() / 1000.f);
|
||||
|
||||
if (m_dLastFrametimes.size() > (long unsigned int)pMonitor->refreshRate)
|
||||
m_dLastFrametimes.pop_front();
|
||||
@@ -39,7 +57,7 @@ void CHyprMonitorDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||
m_pMonitor = pMonitor;
|
||||
|
||||
// anim data too
|
||||
const auto PMONITORFORTICKS = g_pHyprRenderer->m_pMostHzMonitor ? g_pHyprRenderer->m_pMostHzMonitor : g_pCompositor->m_pLastMonitor.get();
|
||||
const auto PMONITORFORTICKS = g_pHyprRenderer->m_pMostHzMonitor ? g_pHyprRenderer->m_pMostHzMonitor.lock() : g_pCompositor->m_pLastMonitor.lock();
|
||||
if (PMONITORFORTICKS) {
|
||||
if (m_dLastAnimationTicks.size() > (long unsigned int)PMONITORFORTICKS->refreshRate)
|
||||
m_dLastAnimationTicks.pop_front();
|
||||
@@ -57,7 +75,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||
float avgFrametime = 0;
|
||||
float maxFrametime = 0;
|
||||
float minFrametime = 9999;
|
||||
for (auto& ft : m_dLastFrametimes) {
|
||||
for (auto const& ft : m_dLastFrametimes) {
|
||||
if (ft > maxFrametime)
|
||||
maxFrametime = ft;
|
||||
if (ft < minFrametime)
|
||||
@@ -70,7 +88,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||
float avgRenderTime = 0;
|
||||
float maxRenderTime = 0;
|
||||
float minRenderTime = 9999;
|
||||
for (auto& rt : m_dLastRenderTimes) {
|
||||
for (auto const& rt : m_dLastRenderTimes) {
|
||||
if (rt > maxRenderTime)
|
||||
maxRenderTime = rt;
|
||||
if (rt < minRenderTime)
|
||||
@@ -83,7 +101,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||
float avgRenderTimeNoOverlay = 0;
|
||||
float maxRenderTimeNoOverlay = 0;
|
||||
float minRenderTimeNoOverlay = 9999;
|
||||
for (auto& rt : m_dLastRenderTimesNoOverlay) {
|
||||
for (auto const& rt : m_dLastRenderTimesNoOverlay) {
|
||||
if (rt > maxRenderTimeNoOverlay)
|
||||
maxRenderTimeNoOverlay = rt;
|
||||
if (rt < minRenderTimeNoOverlay)
|
||||
@@ -96,7 +114,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||
float avgAnimMgrTick = 0;
|
||||
float maxAnimMgrTick = 0;
|
||||
float minAnimMgrTick = 9999;
|
||||
for (auto& at : m_dLastAnimationTicks) {
|
||||
for (auto const& at : m_dLastAnimationTicks) {
|
||||
if (at > maxAnimMgrTick)
|
||||
maxAnimMgrTick = at;
|
||||
if (at < minAnimMgrTick)
|
||||
@@ -180,29 +198,44 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||
double posX = 0, posY = 0;
|
||||
cairo_get_current_point(cr, &posX, &posY);
|
||||
|
||||
g_pHyprRenderer->damageBox(&m_wbLastDrawnBox);
|
||||
g_pHyprRenderer->damageBox(m_wbLastDrawnBox);
|
||||
m_wbLastDrawnBox = {(int)g_pCompositor->m_vMonitors.front()->vecPosition.x + MARGIN_LEFT - 1, (int)g_pCompositor->m_vMonitors.front()->vecPosition.y + offset + MARGIN_TOP - 1,
|
||||
(int)maxTextW + 2, posY - offset - MARGIN_TOP + 2};
|
||||
g_pHyprRenderer->damageBox(&m_wbLastDrawnBox);
|
||||
g_pHyprRenderer->damageBox(m_wbLastDrawnBox);
|
||||
|
||||
return posY - offset;
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) {
|
||||
void CHyprDebugOverlay::renderData(PHLMONITOR pMonitor, float durationUs) {
|
||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
||||
|
||||
if (!*PDEBUGOVERLAY)
|
||||
return;
|
||||
|
||||
m_mMonitorOverlays[pMonitor].renderData(pMonitor, durationUs);
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) {
|
||||
void CHyprDebugOverlay::renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs) {
|
||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
||||
|
||||
if (!*PDEBUGOVERLAY)
|
||||
return;
|
||||
|
||||
m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, durationUs);
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||
void CHyprDebugOverlay::frameData(PHLMONITOR pMonitor) {
|
||||
static auto PDEBUGOVERLAY = CConfigValue<Hyprlang::INT>("debug:overlay");
|
||||
|
||||
if (!*PDEBUGOVERLAY)
|
||||
return;
|
||||
|
||||
m_mMonitorOverlays[pMonitor].frameData(pMonitor);
|
||||
}
|
||||
|
||||
void CHyprDebugOverlay::draw() {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front();
|
||||
|
||||
if (!m_pCairoSurface || !m_pCairo) {
|
||||
m_pCairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
@@ -217,8 +250,8 @@ void CHyprDebugOverlay::draw() {
|
||||
|
||||
// draw the things
|
||||
int offsetY = 0;
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
offsetY += m_mMonitorOverlays[m.get()].draw(offsetY);
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
offsetY += m_mMonitorOverlays[m].draw(offsetY);
|
||||
offsetY += 5; // for padding between mons
|
||||
}
|
||||
|
||||
@@ -238,6 +271,8 @@ void CHyprDebugOverlay::draw() {
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
CBox pMonBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||
g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f);
|
||||
CTexPassElement::SRenderData data;
|
||||
data.tex = m_pTexture;
|
||||
data.box = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||
g_pHyprRenderer->m_sRenderPass.add(makeShared<CTexPassElement>(data));
|
||||
}
|
||||
|
@@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../render/Texture.hpp"
|
||||
#include <deque>
|
||||
#include <cairo/cairo.h>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
class CHyprRenderer;
|
||||
|
||||
@@ -13,9 +12,9 @@ class CHyprMonitorDebugOverlay {
|
||||
public:
|
||||
int draw(int offset);
|
||||
|
||||
void renderData(CMonitor* pMonitor, float durationUs);
|
||||
void renderDataNoOverlay(CMonitor* pMonitor, float durationUs);
|
||||
void frameData(CMonitor* pMonitor);
|
||||
void renderData(PHLMONITOR pMonitor, float durationUs);
|
||||
void renderDataNoOverlay(PHLMONITOR pMonitor, float durationUs);
|
||||
void frameData(PHLMONITOR pMonitor);
|
||||
|
||||
private:
|
||||
std::deque<float> m_dLastFrametimes;
|
||||
@@ -23,7 +22,7 @@ class CHyprMonitorDebugOverlay {
|
||||
std::deque<float> m_dLastRenderTimesNoOverlay;
|
||||
std::deque<float> m_dLastAnimationTicks;
|
||||
std::chrono::high_resolution_clock::time_point m_tpLastFrame;
|
||||
CMonitor* m_pMonitor = nullptr;
|
||||
PHLMONITORREF m_pMonitor;
|
||||
CBox m_wbLastDrawnBox;
|
||||
|
||||
friend class CHyprRenderer;
|
||||
@@ -33,20 +32,20 @@ class CHyprDebugOverlay {
|
||||
public:
|
||||
CHyprDebugOverlay();
|
||||
void draw();
|
||||
void renderData(CMonitor*, float durationUs);
|
||||
void renderDataNoOverlay(CMonitor*, float durationUs);
|
||||
void frameData(CMonitor*);
|
||||
void renderData(PHLMONITOR, float durationUs);
|
||||
void renderDataNoOverlay(PHLMONITOR, float durationUs);
|
||||
void frameData(PHLMONITOR);
|
||||
|
||||
private:
|
||||
std::unordered_map<CMonitor*, CHyprMonitorDebugOverlay> m_mMonitorOverlays;
|
||||
std::map<PHLMONITORREF, CHyprMonitorDebugOverlay> m_mMonitorOverlays;
|
||||
|
||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||
cairo_t* m_pCairo = nullptr;
|
||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||
cairo_t* m_pCairo = nullptr;
|
||||
|
||||
SP<CTexture> m_pTexture;
|
||||
SP<CTexture> m_pTexture;
|
||||
|
||||
friend class CHyprMonitorDebugOverlay;
|
||||
friend class CHyprRenderer;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprDebugOverlay> g_pDebugOverlay;
|
||||
inline UP<CHyprDebugOverlay> g_pDebugOverlay;
|
||||
|
@@ -3,8 +3,13 @@
|
||||
#include "HyprNotificationOverlay.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../render/pass/TexPassElement.hpp"
|
||||
|
||||
inline auto iconBackendFromLayout(PangoLayout* layout) {
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
||||
static inline auto iconBackendFromLayout(PangoLayout* layout) {
|
||||
// preference: Nerd > FontAwesome > text
|
||||
auto eIconBackendChecks = std::array<eIconBackend, 2>{ICONS_BACKEND_NF, ICONS_BACKEND_FA};
|
||||
for (auto iconID : eIconBackendChecks) {
|
||||
@@ -18,10 +23,10 @@ inline auto iconBackendFromLayout(PangoLayout* layout) {
|
||||
|
||||
CHyprNotificationOverlay::CHyprNotificationOverlay() {
|
||||
static auto P = g_pHookSystem->hookDynamic("focusedMon", [&](void* self, SCallbackInfo& info, std::any param) {
|
||||
if (m_dNotifications.size() == 0)
|
||||
if (m_vNotifications.size() == 0)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageBox(&m_bLastDamage);
|
||||
g_pHyprRenderer->damageBox(m_bLastDamage);
|
||||
});
|
||||
|
||||
m_pTexture = makeShared<CTexture>();
|
||||
@@ -34,34 +39,34 @@ CHyprNotificationOverlay::~CHyprNotificationOverlay() {
|
||||
cairo_surface_destroy(m_pCairoSurface);
|
||||
}
|
||||
|
||||
void CHyprNotificationOverlay::addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon, const float fontSize) {
|
||||
const auto PNOTIF = m_dNotifications.emplace_back(std::make_unique<SNotification>()).get();
|
||||
void CHyprNotificationOverlay::addNotification(const std::string& text, const CHyprColor& color, const float timeMs, const eIcons icon, const float fontSize) {
|
||||
const auto PNOTIF = m_vNotifications.emplace_back(makeUnique<SNotification>()).get();
|
||||
|
||||
PNOTIF->text = text;
|
||||
PNOTIF->color = color == CColor(0) ? ICONS_COLORS[icon] : color;
|
||||
PNOTIF->text = icon != eIcons::ICON_NONE ? " " + text /* tiny bit of padding otherwise icon touches text */ : text;
|
||||
PNOTIF->color = color == CHyprColor(0) ? ICONS_COLORS[icon] : color;
|
||||
PNOTIF->started.reset();
|
||||
PNOTIF->timeMs = timeMs;
|
||||
PNOTIF->icon = icon;
|
||||
PNOTIF->fontSize = fontSize;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
g_pCompositor->scheduleFrameForMonitor(m.get());
|
||||
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||
g_pCompositor->scheduleFrameForMonitor(m);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprNotificationOverlay::dismissNotifications(const int amount) {
|
||||
if (amount == -1)
|
||||
m_dNotifications.clear();
|
||||
m_vNotifications.clear();
|
||||
else {
|
||||
const int AMT = std::min(amount, static_cast<int>(m_dNotifications.size()));
|
||||
const int AMT = std::min(amount, static_cast<int>(m_vNotifications.size()));
|
||||
|
||||
for (int i = 0; i < AMT; ++i) {
|
||||
m_dNotifications.pop_front();
|
||||
m_vNotifications.erase(m_vNotifications.begin());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
|
||||
CBox CHyprNotificationOverlay::drawNotifications(PHLMONITOR pMonitor) {
|
||||
static constexpr auto ANIM_DURATION_MS = 600.0;
|
||||
static constexpr auto ANIM_LAG_MS = 100.0;
|
||||
static constexpr auto NOTIF_LEFTBAR_SIZE = 5.0;
|
||||
@@ -87,7 +92,7 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
|
||||
const auto iconBackendID = iconBackendFromLayout(layout);
|
||||
const auto PBEZIER = g_pAnimationManager->getBezier("default");
|
||||
|
||||
for (auto& notif : m_dNotifications) {
|
||||
for (auto const& notif : m_vNotifications) {
|
||||
const auto ICONPADFORNOTIF = notif->icon == ICON_NONE ? 0 : ICON_PAD;
|
||||
const auto FONTSIZE = std::clamp((int)(notif->fontSize * ((pMonitor->vecPixelSize.x * SCALE) / 1920.f)), 8, 40);
|
||||
|
||||
@@ -182,12 +187,12 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
|
||||
g_object_unref(layout);
|
||||
|
||||
// cleanup notifs
|
||||
std::erase_if(m_dNotifications, [](const auto& notif) { return notif->started.getMillis() > notif->timeMs; });
|
||||
std::erase_if(m_vNotifications, [](const auto& notif) { return notif->started.getMillis() > notif->timeMs; });
|
||||
|
||||
return CBox{(int)(pMonitor->vecPosition.x + pMonitor->vecSize.x - maxWidth - 20), (int)pMonitor->vecPosition.y, (int)maxWidth + 20, (int)offsetY + 10};
|
||||
}
|
||||
|
||||
void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
|
||||
void CHyprNotificationOverlay::draw(PHLMONITOR pMonitor) {
|
||||
|
||||
const auto MONSIZE = pMonitor->vecTransformedSize;
|
||||
|
||||
@@ -205,7 +210,7 @@ void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
|
||||
}
|
||||
|
||||
// Draw the notifications
|
||||
if (m_dNotifications.size() == 0)
|
||||
if (m_vNotifications.size() == 0)
|
||||
return;
|
||||
|
||||
// Render to the monitor
|
||||
@@ -220,8 +225,8 @@ void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
|
||||
|
||||
CBox damage = drawNotifications(pMonitor);
|
||||
|
||||
g_pHyprRenderer->damageBox(&damage);
|
||||
g_pHyprRenderer->damageBox(&m_bLastDamage);
|
||||
g_pHyprRenderer->damageBox(damage);
|
||||
g_pHyprRenderer->damageBox(m_bLastDamage);
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(pMonitor);
|
||||
|
||||
@@ -241,10 +246,14 @@ void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MONSIZE.x, MONSIZE.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
CBox pMonBox = {0, 0, MONSIZE.x, MONSIZE.y};
|
||||
g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f);
|
||||
CTexPassElement::SRenderData data;
|
||||
data.tex = m_pTexture;
|
||||
data.box = {0, 0, MONSIZE.x, MONSIZE.y};
|
||||
data.a = 1.F;
|
||||
|
||||
g_pHyprRenderer->m_sRenderPass.add(makeShared<CTexPassElement>(data));
|
||||
}
|
||||
|
||||
bool CHyprNotificationOverlay::hasAny() {
|
||||
return !m_dNotifications.empty();
|
||||
return !m_vNotifications.empty();
|
||||
}
|
||||
|
@@ -2,15 +2,14 @@
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/Timer.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../render/Texture.hpp"
|
||||
#include "../SharedDefs.hpp"
|
||||
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
enum eIconBackend {
|
||||
enum eIconBackend : uint8_t {
|
||||
ICONS_BACKEND_NONE = 0,
|
||||
ICONS_BACKEND_NF,
|
||||
ICONS_BACKEND_FA
|
||||
@@ -19,17 +18,17 @@ enum eIconBackend {
|
||||
static const std::array<std::array<std::string, ICON_NONE + 1>, 3 /* backends */> ICONS_ARRAY = {
|
||||
std::array<std::string, ICON_NONE + 1>{"[!]", "[i]", "[Hint]", "[Err]", "[?]", "[ok]", ""},
|
||||
std::array<std::string, ICON_NONE + 1>{"", "", "", "", "", "", ""}, std::array<std::string, ICON_NONE + 1>{"", "", "", "", "", ""}};
|
||||
static const std::array<CColor, ICON_NONE + 1> ICONS_COLORS = {CColor{255.0 / 255.0, 204 / 255.0, 102 / 255.0, 1.0},
|
||||
CColor{128 / 255.0, 255 / 255.0, 255 / 255.0, 1.0},
|
||||
CColor{179 / 255.0, 255 / 255.0, 204 / 255.0, 1.0},
|
||||
CColor{255 / 255.0, 77 / 255.0, 77 / 255.0, 1.0},
|
||||
CColor{255 / 255.0, 204 / 255.0, 153 / 255.0, 1.0},
|
||||
CColor{128 / 255.0, 255 / 255.0, 128 / 255.0, 1.0},
|
||||
CColor{0, 0, 0, 1.0}};
|
||||
static const std::array<CHyprColor, ICON_NONE + 1> ICONS_COLORS = {CHyprColor{255.0 / 255.0, 204 / 255.0, 102 / 255.0, 1.0},
|
||||
CHyprColor{128 / 255.0, 255 / 255.0, 255 / 255.0, 1.0},
|
||||
CHyprColor{179 / 255.0, 255 / 255.0, 204 / 255.0, 1.0},
|
||||
CHyprColor{255 / 255.0, 77 / 255.0, 77 / 255.0, 1.0},
|
||||
CHyprColor{255 / 255.0, 204 / 255.0, 153 / 255.0, 1.0},
|
||||
CHyprColor{128 / 255.0, 255 / 255.0, 128 / 255.0, 1.0},
|
||||
CHyprColor{0, 0, 0, 1.0}};
|
||||
|
||||
struct SNotification {
|
||||
std::string text = "";
|
||||
CColor color;
|
||||
CHyprColor color;
|
||||
CTimer started;
|
||||
float timeMs = 0;
|
||||
eIcons icon = ICON_NONE;
|
||||
@@ -41,24 +40,24 @@ class CHyprNotificationOverlay {
|
||||
CHyprNotificationOverlay();
|
||||
~CHyprNotificationOverlay();
|
||||
|
||||
void draw(CMonitor* pMonitor);
|
||||
void addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon = ICON_NONE, const float fontSize = 13.f);
|
||||
void draw(PHLMONITOR pMonitor);
|
||||
void addNotification(const std::string& text, const CHyprColor& color, const float timeMs, const eIcons icon = ICON_NONE, const float fontSize = 13.f);
|
||||
void dismissNotifications(const int amount);
|
||||
bool hasAny();
|
||||
|
||||
private:
|
||||
CBox drawNotifications(CMonitor* pMonitor);
|
||||
CBox m_bLastDamage;
|
||||
CBox drawNotifications(PHLMONITOR pMonitor);
|
||||
CBox m_bLastDamage;
|
||||
|
||||
std::deque<std::unique_ptr<SNotification>> m_dNotifications;
|
||||
std::vector<UP<SNotification>> m_vNotifications;
|
||||
|
||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||
cairo_t* m_pCairo = nullptr;
|
||||
cairo_surface_t* m_pCairoSurface = nullptr;
|
||||
cairo_t* m_pCairo = nullptr;
|
||||
|
||||
CMonitor* m_pLastMonitor = nullptr;
|
||||
Vector2D m_vecLastSize = Vector2D(-1, -1);
|
||||
PHLMONITORREF m_pLastMonitor;
|
||||
Vector2D m_vecLastSize = Vector2D(-1, -1);
|
||||
|
||||
SP<CTexture> m_pTexture;
|
||||
SP<CTexture> m_pTexture;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprNotificationOverlay> g_pHyprNotificationOverlay;
|
||||
inline UP<CHyprNotificationOverlay> g_pHyprNotificationOverlay;
|
||||
|
@@ -1,10 +1,9 @@
|
||||
#include "Log.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "RollingLogFollow.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <print>
|
||||
#include <fcntl.h>
|
||||
|
||||
void Debug::init(const std::string& IS) {
|
||||
@@ -18,7 +17,7 @@ void Debug::close() {
|
||||
logOfs.close();
|
||||
}
|
||||
|
||||
void Debug::log(LogLevel level, std::string str) {
|
||||
void Debug::log(eLogLevel level, std::string str) {
|
||||
if (level == TRACE && !trace)
|
||||
return;
|
||||
|
||||
@@ -26,6 +25,7 @@ void Debug::log(LogLevel level, std::string str) {
|
||||
return;
|
||||
|
||||
std::string coloredStr = str;
|
||||
//NOLINTBEGIN
|
||||
switch (level) {
|
||||
case LOG:
|
||||
str = "[LOG] " + str;
|
||||
@@ -53,13 +53,14 @@ void Debug::log(LogLevel level, std::string str) {
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
//NOLINTEND
|
||||
|
||||
rollingLog += str + "\n";
|
||||
if (rollingLog.size() > ROLLING_LOG_SIZE)
|
||||
rollingLog = rollingLog.substr(rollingLog.size() - ROLLING_LOG_SIZE);
|
||||
|
||||
if (RollingLogFollow::Get().IsRunning())
|
||||
RollingLogFollow::Get().AddLog(str);
|
||||
if (SRollingLogFollow::get().isRunning())
|
||||
SRollingLogFollow::get().addLog(str);
|
||||
|
||||
if (!disableLogs || !**disableLogs) {
|
||||
// log to a file
|
||||
@@ -69,5 +70,5 @@ void Debug::log(LogLevel level, std::string str) {
|
||||
|
||||
// log it to the stdout too.
|
||||
if (!disableStdout)
|
||||
std::cout << ((coloredLogs && !**coloredLogs) ? str : coloredStr) << "\n";
|
||||
std::println("{}", ((coloredLogs && !**coloredLogs) ? str : coloredStr));
|
||||
}
|
||||
|
@@ -5,13 +5,11 @@
|
||||
#include <fstream>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include "../includes.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
|
||||
#define LOGMESSAGESIZE 1024
|
||||
#define ROLLING_LOG_SIZE 4096
|
||||
|
||||
enum LogLevel {
|
||||
enum eLogLevel : int8_t {
|
||||
NONE = -1,
|
||||
LOG = 0,
|
||||
WARN,
|
||||
@@ -21,6 +19,7 @@ enum LogLevel {
|
||||
TRACE
|
||||
};
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
namespace Debug {
|
||||
inline std::string logFile;
|
||||
inline std::ofstream logOfs;
|
||||
@@ -38,10 +37,11 @@ namespace Debug {
|
||||
void close();
|
||||
|
||||
//
|
||||
void log(LogLevel level, std::string str);
|
||||
void log(eLogLevel level, std::string str);
|
||||
|
||||
template <typename... Args>
|
||||
void log(LogLevel level, std::format_string<Args...> fmt, Args&&... args) {
|
||||
//NOLINTNEXTLINE
|
||||
void log(eLogLevel level, std::format_string<Args...> fmt, Args&&... args) {
|
||||
std::lock_guard<std::mutex> guard(logMutex);
|
||||
|
||||
if (level == TRACE && !trace)
|
||||
@@ -55,8 +55,9 @@ namespace Debug {
|
||||
// print date and time to the ofs
|
||||
if (disableTime && !**disableTime) {
|
||||
#ifndef _LIBCPP_VERSION
|
||||
const auto zt = std::chrono::zoned_time{std::chrono::current_zone(), std::chrono::system_clock::now()};
|
||||
const auto hms = std::chrono::hh_mm_ss{zt.get_local_time() - std::chrono::floor<std::chrono::days>(zt.get_local_time())};
|
||||
static auto current_zone = std::chrono::current_zone();
|
||||
const auto zt = std::chrono::zoned_time{current_zone, std::chrono::system_clock::now()};
|
||||
const auto hms = std::chrono::hh_mm_ss{zt.get_local_time() - std::chrono::floor<std::chrono::days>(zt.get_local_time())};
|
||||
#else
|
||||
// TODO: current clang 17 does not support `zoned_time`, remove this once clang 19 is ready
|
||||
const auto hms = std::chrono::hh_mm_ss{std::chrono::system_clock::now() - std::chrono::floor<std::chrono::days>(std::chrono::system_clock::now())};
|
||||
|
@@ -2,8 +2,9 @@
|
||||
|
||||
#include <shared_mutex>
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
namespace Debug {
|
||||
struct RollingLogFollow {
|
||||
struct SRollingLogFollow {
|
||||
std::unordered_map<int, std::string> socketToRollingLogFollowQueue;
|
||||
std::shared_mutex m;
|
||||
bool running = false;
|
||||
@@ -15,12 +16,12 @@ namespace Debug {
|
||||
return socketToRollingLogFollowQueue[socket].empty();
|
||||
}
|
||||
|
||||
std::string DebugInfo() {
|
||||
std::string debugInfo() {
|
||||
std::shared_lock<std::shared_mutex> r(m);
|
||||
return std::format("RollingLogFollow, got {} connections", socketToRollingLogFollowQueue.size());
|
||||
}
|
||||
|
||||
std::string GetLog(int socket) {
|
||||
std::string getLog(int socket) {
|
||||
std::unique_lock<std::shared_mutex> w(m);
|
||||
|
||||
const std::string ret = socketToRollingLogFollowQueue[socket];
|
||||
@@ -29,7 +30,7 @@ namespace Debug {
|
||||
return ret;
|
||||
};
|
||||
|
||||
void AddLog(std::string log) {
|
||||
void addLog(const std::string& log) {
|
||||
std::unique_lock<std::shared_mutex> w(m);
|
||||
running = true;
|
||||
std::vector<int> to_erase;
|
||||
@@ -37,26 +38,26 @@ namespace Debug {
|
||||
socketToRollingLogFollowQueue[p.first] += log + "\n";
|
||||
}
|
||||
|
||||
bool IsRunning() {
|
||||
bool isRunning() {
|
||||
std::shared_lock<std::shared_mutex> r(m);
|
||||
return running;
|
||||
}
|
||||
|
||||
void StopFor(int socket) {
|
||||
void stopFor(int socket) {
|
||||
std::unique_lock<std::shared_mutex> w(m);
|
||||
socketToRollingLogFollowQueue.erase(socket);
|
||||
if (socketToRollingLogFollowQueue.empty())
|
||||
running = false;
|
||||
}
|
||||
|
||||
void StartFor(int socket) {
|
||||
void startFor(int socket) {
|
||||
std::unique_lock<std::shared_mutex> w(m);
|
||||
socketToRollingLogFollowQueue[socket] = std::format("[LOG] Following log to socket: {} started\n", socket);
|
||||
running = true;
|
||||
}
|
||||
|
||||
static RollingLogFollow& Get() {
|
||||
static RollingLogFollow instance;
|
||||
static SRollingLogFollow& get() {
|
||||
static SRollingLogFollow instance;
|
||||
static std::mutex gm;
|
||||
std::lock_guard<std::mutex> lock(gm);
|
||||
return instance;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "includes.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "helpers/WLListener.hpp"
|
||||
#include "helpers/Color.hpp"
|
||||
#include "macros.hpp"
|
||||
#include "desktop/DesktopTypes.hpp"
|
||||
|
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
#include "../macros.hpp"
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
class CWorkspace;
|
||||
class CWindow;
|
||||
class CLayerSurface;
|
||||
class CMonitor;
|
||||
|
||||
/* Shared pointer to a workspace */
|
||||
typedef SP<CWorkspace> PHLWORKSPACE;
|
||||
@@ -18,3 +19,8 @@ typedef WP<CWindow> PHLWINDOWREF;
|
||||
typedef SP<CLayerSurface> PHLLS;
|
||||
/* Weak pointer to a layer surface */
|
||||
typedef WP<CLayerSurface> PHLLSREF;
|
||||
|
||||
/* Shared pointer to a monitor */
|
||||
typedef SP<CMonitor> PHLMONITOR;
|
||||
/* Weak pointer to a monitor */
|
||||
typedef WP<CMonitor> PHLMONITORREF;
|
||||
|
38
src/desktop/LayerRule.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <re2/re2.h>
|
||||
#include "LayerRule.hpp"
|
||||
#include <unordered_set>
|
||||
#include <algorithm>
|
||||
#include "../debug/Log.hpp"
|
||||
|
||||
static const auto RULES = std::unordered_set<std::string>{"noanim", "blur", "blurpopups", "dimaround"};
|
||||
static const auto RULES_PREFIX = std::unordered_set<std::string>{"ignorealpha", "ignorezero", "xray", "animation", "order"};
|
||||
|
||||
CLayerRule::CLayerRule(const std::string& rule_, const std::string& ns_) : targetNamespace(ns_), rule(rule_) {
|
||||
const bool VALID = RULES.contains(rule) || std::any_of(RULES_PREFIX.begin(), RULES_PREFIX.end(), [&rule_](const auto& prefix) { return rule_.starts_with(prefix); });
|
||||
|
||||
if (!VALID)
|
||||
return;
|
||||
|
||||
if (rule == "noanim")
|
||||
ruleType = RULE_NOANIM;
|
||||
else if (rule == "blur")
|
||||
ruleType = RULE_BLUR;
|
||||
else if (rule == "blurpopups")
|
||||
ruleType = RULE_BLURPOPUPS;
|
||||
else if (rule == "dimaround")
|
||||
ruleType = RULE_DIMAROUND;
|
||||
else if (rule.starts_with("ignorealpha"))
|
||||
ruleType = RULE_IGNOREALPHA;
|
||||
else if (rule.starts_with("ignorezero"))
|
||||
ruleType = RULE_IGNOREZERO;
|
||||
else if (rule.starts_with("xray"))
|
||||
ruleType = RULE_XRAY;
|
||||
else if (rule.starts_with("animation"))
|
||||
ruleType = RULE_ANIMATION;
|
||||
else if (rule.starts_with("order"))
|
||||
ruleType = RULE_ORDER;
|
||||
else {
|
||||
Debug::log(ERR, "CLayerRule: didn't match a rule that was found valid?!");
|
||||
ruleType = RULE_INVALID;
|
||||
}
|
||||
}
|
31
src/desktop/LayerRule.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include "Rule.hpp"
|
||||
|
||||
class CLayerRule {
|
||||
public:
|
||||
CLayerRule(const std::string& rule, const std::string& targetNS);
|
||||
|
||||
enum eRuleType : uint8_t {
|
||||
RULE_INVALID = 0,
|
||||
RULE_NOANIM,
|
||||
RULE_BLUR,
|
||||
RULE_BLURPOPUPS,
|
||||
RULE_DIMAROUND,
|
||||
RULE_IGNOREALPHA,
|
||||
RULE_IGNOREZERO,
|
||||
RULE_XRAY,
|
||||
RULE_ANIMATION,
|
||||
RULE_ORDER,
|
||||
RULE_ZUMBA,
|
||||
};
|
||||
|
||||
eRuleType ruleType = RULE_INVALID;
|
||||
|
||||
const std::string targetNamespace;
|
||||
const std::string rule;
|
||||
|
||||
CRuleRegexContainer targetNamespaceRegex;
|
||||
};
|
@@ -4,11 +4,18 @@
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
|
||||
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
|
||||
PHLLS pLS = SP<CLayerSurface>(new CLayerSurface(resource));
|
||||
|
||||
CMonitor* pMonitor = resource->monitor.empty() ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->getMonitorFromName(resource->monitor);
|
||||
auto pMonitor = resource->monitor.empty() ? g_pCompositor->m_pLastMonitor.lock() : g_pCompositor->getMonitorFromName(resource->monitor);
|
||||
|
||||
pLS->surface->assign(resource->surface.lock(), pLS);
|
||||
|
||||
@@ -18,29 +25,27 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
}
|
||||
|
||||
if (pMonitor->pMirrorOf)
|
||||
pMonitor = g_pCompositor->m_vMonitors.front().get();
|
||||
pMonitor = g_pCompositor->m_vMonitors.front();
|
||||
|
||||
pLS->self = pLS;
|
||||
|
||||
pLS->szNamespace = resource->layerNamespace;
|
||||
|
||||
pLS->layer = resource->current.layer;
|
||||
pLS->popupHead = std::make_unique<CPopup>(pLS);
|
||||
pLS->monitorID = pMonitor->ID;
|
||||
pLS->layer = resource->current.layer;
|
||||
pLS->popupHead = makeUnique<CPopup>(pLS);
|
||||
pLS->popupHead->m_pSelf = pLS->popupHead;
|
||||
pLS->monitor = pMonitor;
|
||||
pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS);
|
||||
|
||||
pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace);
|
||||
|
||||
pLS->alpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
pLS->realPosition.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
pLS->realSize.create(g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
pLS->alpha.registerVar();
|
||||
pLS->realPosition.registerVar();
|
||||
pLS->realSize.registerVar();
|
||||
g_pAnimationManager->createAnimation(0.f, pLS->alpha, g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pLS->realPosition, g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
g_pAnimationManager->createAnimation(Vector2D(0, 0), pLS->realSize, g_pConfigManager->getAnimationPropertyConfig("layersIn"), pLS, AVARDAMAGE_ENTIRE);
|
||||
|
||||
pLS->registerCallbacks();
|
||||
|
||||
pLS->alpha.setValueAndWarp(0.f);
|
||||
pLS->alpha->setValueAndWarp(0.f);
|
||||
|
||||
Debug::log(LOG, "LayerSurface {:x} (namespace {} layer {}) created on monitor {}", (uintptr_t)resource.get(), resource->layerNamespace, (int)pLS->layer, pMonitor->szName);
|
||||
|
||||
@@ -48,9 +53,9 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
|
||||
}
|
||||
|
||||
void CLayerSurface::registerCallbacks() {
|
||||
alpha.setUpdateCallback([this](void*) {
|
||||
alpha->setUpdateCallback([this](auto) {
|
||||
if (dimAround)
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(monitorID));
|
||||
g_pHyprRenderer->damageMonitor(monitor.lock());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -72,7 +77,7 @@ CLayerSurface::~CLayerSurface() {
|
||||
g_pHyprRenderer->makeEGLCurrent();
|
||||
std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == self.lock(); });
|
||||
|
||||
for (auto& mon : g_pCompositor->m_vRealMonitors) {
|
||||
for (auto const& mon : g_pCompositor->m_vRealMonitors) {
|
||||
for (auto& lsl : mon->m_aLayerSurfaceLayers) {
|
||||
std::erase_if(lsl, [this](auto& ls) { return ls.expired() || ls.get() == this; });
|
||||
}
|
||||
@@ -82,9 +87,9 @@ CLayerSurface::~CLayerSurface() {
|
||||
void CLayerSurface::onDestroy() {
|
||||
Debug::log(LOG, "LayerSurface {:x} destroyed", (uintptr_t)layerSurface.get());
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
const auto PMONITOR = monitor.lock();
|
||||
|
||||
if (!g_pCompositor->getMonitorFromID(monitorID))
|
||||
if (!PMONITOR)
|
||||
Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)");
|
||||
|
||||
if (!fadingOut) {
|
||||
@@ -93,7 +98,7 @@ void CLayerSurface::onDestroy() {
|
||||
onUnmap();
|
||||
} else {
|
||||
Debug::log(LOG, "Removing LayerSurface that wasn't mapped.");
|
||||
alpha.setValueAndWarp(0.f);
|
||||
alpha->setValueAndWarp(0.f);
|
||||
fadingOut = true;
|
||||
g_pCompositor->addToFadingOutSafe(self.lock());
|
||||
}
|
||||
@@ -110,7 +115,7 @@ void CLayerSurface::onDestroy() {
|
||||
|
||||
// and damage
|
||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
}
|
||||
|
||||
readyToDelete = true;
|
||||
@@ -137,7 +142,7 @@ void CLayerSurface::onMap() {
|
||||
g_pCompositor->removeFromFadingOutSafe(self.lock());
|
||||
|
||||
// fix if it changed its mon
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
const auto PMONITOR = monitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
@@ -174,9 +179,8 @@ void CLayerSurface::onMap() {
|
||||
position = Vector2D(geometry.x, geometry.y);
|
||||
|
||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
const auto WORKSPACE = PMONITOR->activeWorkspace;
|
||||
const bool FULLSCREEN = WORKSPACE->m_bHasFullscreenWindow && WORKSPACE->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
const bool FULLSCREEN = PMONITOR->activeWorkspace && PMONITOR->activeWorkspace->m_bHasFullscreenWindow && PMONITOR->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
||||
|
||||
startAnimation(!(layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS));
|
||||
readyToDelete = false;
|
||||
@@ -197,7 +201,7 @@ void CLayerSurface::onUnmap() {
|
||||
|
||||
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
|
||||
|
||||
if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) {
|
||||
if (!monitor || g_pCompositor->m_bUnsafeState) {
|
||||
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
|
||||
|
||||
g_pCompositor->addToFadingOutSafe(self.lock());
|
||||
@@ -211,7 +215,7 @@ void CLayerSurface::onUnmap() {
|
||||
}
|
||||
|
||||
// make a snapshot and start fade
|
||||
g_pHyprOpenGL->makeLayerSnapshot(self.lock());
|
||||
g_pHyprRenderer->makeLayerSnapshot(self.lock());
|
||||
|
||||
startAnimation(false);
|
||||
|
||||
@@ -221,9 +225,9 @@ void CLayerSurface::onUnmap() {
|
||||
|
||||
g_pCompositor->addToFadingOutSafe(self.lock());
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
const auto PMONITOR = monitor.lock();
|
||||
|
||||
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
|
||||
const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == surface->resource() || g_pSeatManager->state.pointerFocus == surface->resource();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
@@ -232,17 +236,17 @@ void CLayerSurface::onUnmap() {
|
||||
// vvvvvvvvvvvvv if there is a last focus and the last focus is not keyboard focusable, fallback to window
|
||||
if (WASLASTFOCUS || (g_pCompositor->m_pLastFocus && g_pCompositor->m_pLastFocus->hlSurface && !g_pCompositor->m_pLastFocus->hlSurface->keyboardFocusable()))
|
||||
g_pInputManager->refocusLastWindow(PMONITOR);
|
||||
else if (g_pCompositor->m_pLastFocus)
|
||||
else if (g_pCompositor->m_pLastFocus && g_pCompositor->m_pLastFocus != surface->resource())
|
||||
g_pSeatManager->setKeyboardFocus(g_pCompositor->m_pLastFocus.lock());
|
||||
|
||||
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
|
||||
geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.size.x,
|
||||
(int)layerSurface->surface->current.size.y};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
|
||||
g_pInputManager->sendMotionEventsToFocused();
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||
}
|
||||
@@ -256,13 +260,13 @@ void CLayerSurface::onCommit() {
|
||||
if (layerSurface->surface && !layerSurface->surface->current.texture) {
|
||||
fadingOut = false;
|
||||
geometry = {};
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(monitorID);
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(monitorID());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
const auto PMONITOR = monitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
@@ -271,7 +275,7 @@ void CLayerSurface::onCommit() {
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(PMONITOR); // so that blur is recalc'd
|
||||
|
||||
CBox geomFixed = {geometry.x, geometry.y, geometry.width, geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
|
||||
if (layerSurface->current.committed != 0) {
|
||||
if (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_LAYER) {
|
||||
@@ -308,21 +312,31 @@ void CLayerSurface::onCommit() {
|
||||
}
|
||||
}
|
||||
|
||||
if (realPosition.goal() != geometry.pos()) {
|
||||
if (realPosition.isBeingAnimated())
|
||||
realPosition = geometry.pos();
|
||||
if (realPosition->goal() != geometry.pos()) {
|
||||
if (realPosition->isBeingAnimated())
|
||||
*realPosition = geometry.pos();
|
||||
else
|
||||
realPosition.setValueAndWarp(geometry.pos());
|
||||
realPosition->setValueAndWarp(geometry.pos());
|
||||
}
|
||||
if (realSize.goal() != geometry.size()) {
|
||||
if (realSize.isBeingAnimated())
|
||||
realSize = geometry.size();
|
||||
if (realSize->goal() != geometry.size()) {
|
||||
if (realSize->isBeingAnimated())
|
||||
*realSize = geometry.size();
|
||||
else
|
||||
realSize.setValueAndWarp(geometry.size());
|
||||
realSize->setValueAndWarp(geometry.size());
|
||||
}
|
||||
|
||||
if (mapped) {
|
||||
const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
|
||||
if (mapped && (layerSurface->current.committed & CLayerShellResource::eCommittedState::STATE_INTERACTIVITY)) {
|
||||
bool WASLASTFOCUS = false;
|
||||
layerSurface->surface->breadthfirst(
|
||||
[&WASLASTFOCUS](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) { WASLASTFOCUS = WASLASTFOCUS || g_pSeatManager->state.keyboardFocus == surf; },
|
||||
nullptr);
|
||||
if (!WASLASTFOCUS && popupHead) {
|
||||
popupHead->breadthfirst(
|
||||
[&WASLASTFOCUS](WP<CPopup> popup, void* data) {
|
||||
WASLASTFOCUS = WASLASTFOCUS || (popup->m_pWLSurface && g_pSeatManager->state.keyboardFocus == popup->m_pWLSurface->resource());
|
||||
},
|
||||
nullptr);
|
||||
}
|
||||
const bool WASEXCLUSIVE = interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
||||
const bool ISEXCLUSIVE = layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE;
|
||||
|
||||
@@ -332,11 +346,13 @@ void CLayerSurface::onCommit() {
|
||||
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
|
||||
|
||||
// if the surface was focused and interactive but now isn't, refocus
|
||||
if (WASLASTFOCUS && !layerSurface->current.interactivity) {
|
||||
if (WASLASTFOCUS && layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE) {
|
||||
// moveMouseUnified won't focus non interactive layers but it won't unfocus them either,
|
||||
// so unfocus the surface here.
|
||||
g_pCompositor->focusSurface(nullptr);
|
||||
g_pInputManager->refocusLastWindow(g_pCompositor->getMonitorFromID(monitorID));
|
||||
g_pInputManager->refocusLastWindow(monitor.lock());
|
||||
} else if (WASLASTFOCUS && WASEXCLUSIVE && layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
} else if (!WASEXCLUSIVE && ISEXCLUSIVE) {
|
||||
// if now exclusive and not previously
|
||||
g_pSeatManager->setGrab(nullptr);
|
||||
@@ -366,50 +382,74 @@ void CLayerSurface::applyRules() {
|
||||
xray = -1;
|
||||
animationStyle.reset();
|
||||
|
||||
for (auto& rule : g_pConfigManager->getMatchingRules(self.lock())) {
|
||||
if (rule.rule == "noanim")
|
||||
noAnimations = true;
|
||||
else if (rule.rule == "blur")
|
||||
forceBlur = true;
|
||||
else if (rule.rule == "blurpopups")
|
||||
forceBlurPopups = true;
|
||||
else if (rule.rule.starts_with("ignorealpha") || rule.rule.starts_with("ignorezero")) {
|
||||
const auto FIRST_SPACE_POS = rule.rule.find_first_of(' ');
|
||||
std::string alphaValue = "";
|
||||
if (FIRST_SPACE_POS != std::string::npos)
|
||||
alphaValue = rule.rule.substr(FIRST_SPACE_POS + 1);
|
||||
for (auto const& rule : g_pConfigManager->getMatchingRules(self.lock())) {
|
||||
switch (rule->ruleType) {
|
||||
case CLayerRule::RULE_NOANIM: {
|
||||
noAnimations = true;
|
||||
break;
|
||||
}
|
||||
case CLayerRule::RULE_BLUR: {
|
||||
forceBlur = true;
|
||||
break;
|
||||
}
|
||||
case CLayerRule::RULE_BLURPOPUPS: {
|
||||
forceBlurPopups = true;
|
||||
break;
|
||||
}
|
||||
case CLayerRule::RULE_IGNOREALPHA:
|
||||
case CLayerRule::RULE_IGNOREZERO: {
|
||||
const auto FIRST_SPACE_POS = rule->rule.find_first_of(' ');
|
||||
std::string alphaValue = "";
|
||||
if (FIRST_SPACE_POS != std::string::npos)
|
||||
alphaValue = rule->rule.substr(FIRST_SPACE_POS + 1);
|
||||
|
||||
try {
|
||||
ignoreAlpha = true;
|
||||
if (!alphaValue.empty())
|
||||
ignoreAlphaValue = std::stof(alphaValue);
|
||||
} catch (...) { Debug::log(ERR, "Invalid value passed to ignoreAlpha"); }
|
||||
} else if (rule.rule == "dimaround") {
|
||||
dimAround = true;
|
||||
} else if (rule.rule.starts_with("xray")) {
|
||||
CVarList vars{rule.rule, 0, ' '};
|
||||
try {
|
||||
xray = configStringToInt(vars[1]);
|
||||
} catch (...) {}
|
||||
} else if (rule.rule.starts_with("animation")) {
|
||||
CVarList vars{rule.rule, 2, 's'};
|
||||
animationStyle = vars[1];
|
||||
try {
|
||||
ignoreAlpha = true;
|
||||
if (!alphaValue.empty())
|
||||
ignoreAlphaValue = std::stof(alphaValue);
|
||||
} catch (...) { Debug::log(ERR, "Invalid value passed to ignoreAlpha"); }
|
||||
break;
|
||||
}
|
||||
case CLayerRule::RULE_DIMAROUND: {
|
||||
dimAround = true;
|
||||
break;
|
||||
}
|
||||
case CLayerRule::RULE_XRAY: {
|
||||
CVarList vars{rule->rule, 0, ' '};
|
||||
try {
|
||||
xray = configStringToInt(vars[1]).value_or(false);
|
||||
} catch (...) {}
|
||||
break;
|
||||
}
|
||||
case CLayerRule::RULE_ANIMATION: {
|
||||
CVarList vars{rule->rule, 2, 's'};
|
||||
animationStyle = vars[1];
|
||||
break;
|
||||
}
|
||||
case CLayerRule::RULE_ORDER: {
|
||||
CVarList vars{rule->rule, 2, 's'};
|
||||
try {
|
||||
order = std::stoi(vars[1]);
|
||||
} catch (...) { Debug::log(ERR, "Invalid value passed to order"); }
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||
const auto ANIMSTYLE = animationStyle.value_or(realPosition.m_pConfig->pValues->internalStyle);
|
||||
if (in) {
|
||||
realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn");
|
||||
realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersIn");
|
||||
alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn");
|
||||
realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
||||
realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
||||
alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"));
|
||||
} else {
|
||||
realPosition.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut");
|
||||
realSize.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("layersOut");
|
||||
alpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut");
|
||||
realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
||||
realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
||||
alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut"));
|
||||
}
|
||||
|
||||
const auto ANIMSTYLE = animationStyle.value_or(realPosition->getStyle());
|
||||
if (ANIMSTYLE.starts_with("slide")) {
|
||||
// get closest edge
|
||||
const auto MIDDLE = geometry.middle();
|
||||
@@ -450,9 +490,9 @@ void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||
}
|
||||
}
|
||||
|
||||
realSize.setValueAndWarp(geometry.size());
|
||||
alpha.setValueAndWarp(in ? 0.f : 1.f);
|
||||
alpha = in ? 1.f : 0.f;
|
||||
realSize->setValueAndWarp(geometry.size());
|
||||
alpha->setValueAndWarp(in ? 0.f : 1.f);
|
||||
*alpha = in ? 1.f : 0.f;
|
||||
|
||||
Vector2D prePos;
|
||||
|
||||
@@ -477,11 +517,11 @@ void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||
}
|
||||
|
||||
if (in) {
|
||||
realPosition.setValueAndWarp(prePos);
|
||||
realPosition = geometry.pos();
|
||||
realPosition->setValueAndWarp(prePos);
|
||||
*realPosition = geometry.pos();
|
||||
} else {
|
||||
realPosition.setValueAndWarp(geometry.pos());
|
||||
realPosition = prePos;
|
||||
realPosition->setValueAndWarp(geometry.pos());
|
||||
*realPosition = prePos;
|
||||
}
|
||||
|
||||
} else if (ANIMSTYLE.starts_with("popin")) {
|
||||
@@ -500,25 +540,25 @@ void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||
const auto GOALSIZE = (geometry.size() * minPerc).clamp({5, 5});
|
||||
const auto GOALPOS = geometry.pos() + (geometry.size() - GOALSIZE) / 2.f;
|
||||
|
||||
alpha.setValueAndWarp(in ? 0.f : 1.f);
|
||||
alpha = in ? 1.f : 0.f;
|
||||
alpha->setValueAndWarp(in ? 0.f : 1.f);
|
||||
*alpha = in ? 1.f : 0.f;
|
||||
|
||||
if (in) {
|
||||
realSize.setValueAndWarp(GOALSIZE);
|
||||
realPosition.setValueAndWarp(GOALPOS);
|
||||
realSize = geometry.size();
|
||||
realPosition = geometry.pos();
|
||||
realSize->setValueAndWarp(GOALSIZE);
|
||||
realPosition->setValueAndWarp(GOALPOS);
|
||||
*realSize = geometry.size();
|
||||
*realPosition = geometry.pos();
|
||||
} else {
|
||||
realSize.setValueAndWarp(geometry.size());
|
||||
realPosition.setValueAndWarp(geometry.pos());
|
||||
realSize = GOALSIZE;
|
||||
realPosition = GOALPOS;
|
||||
realSize->setValueAndWarp(geometry.size());
|
||||
realPosition->setValueAndWarp(geometry.pos());
|
||||
*realSize = GOALSIZE;
|
||||
*realPosition = GOALPOS;
|
||||
}
|
||||
} else {
|
||||
// fade
|
||||
realPosition.setValueAndWarp(geometry.pos());
|
||||
realSize.setValueAndWarp(geometry.size());
|
||||
alpha = in ? 1.f : 0.f;
|
||||
realPosition->setValueAndWarp(geometry.pos());
|
||||
realSize->setValueAndWarp(geometry.size());
|
||||
*alpha = in ? 1.f : 0.f;
|
||||
}
|
||||
|
||||
if (!in)
|
||||
@@ -529,7 +569,7 @@ bool CLayerSurface::isFadedOut() {
|
||||
if (!fadingOut)
|
||||
return false;
|
||||
|
||||
return !realPosition.isBeingAnimated() && !realSize.isBeingAnimated() && !alpha.isBeingAnimated();
|
||||
return !realPosition->isBeingAnimated() && !realSize->isBeingAnimated() && !alpha->isBeingAnimated();
|
||||
}
|
||||
|
||||
int CLayerSurface::popupsCount() {
|
||||
@@ -537,6 +577,10 @@ int CLayerSurface::popupsCount() {
|
||||
return 0;
|
||||
|
||||
int no = -1; // we have one dummy
|
||||
popupHead->breadthfirst([](CPopup* p, void* data) { *(int*)data += 1; }, &no);
|
||||
popupHead->breadthfirst([](WP<CPopup> p, void* data) { *(int*)data += 1; }, &no);
|
||||
return no;
|
||||
}
|
||||
|
||||
MONITORID CLayerSurface::monitorID() {
|
||||
return monitor ? monitor->ID : MONITOR_INVALID;
|
||||
}
|
||||
|
@@ -5,11 +5,6 @@
|
||||
#include "WLSurface.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
|
||||
struct SLayerRule {
|
||||
std::string targetNamespace = "";
|
||||
std::string rule = "";
|
||||
};
|
||||
|
||||
class CLayerShellResource;
|
||||
|
||||
class CLayerSurface {
|
||||
@@ -22,17 +17,17 @@ class CLayerSurface {
|
||||
public:
|
||||
~CLayerSurface();
|
||||
|
||||
void applyRules();
|
||||
void startAnimation(bool in, bool instant = false);
|
||||
bool isFadedOut();
|
||||
int popupsCount();
|
||||
void applyRules();
|
||||
void startAnimation(bool in, bool instant = false);
|
||||
bool isFadedOut();
|
||||
int popupsCount();
|
||||
|
||||
CAnimatedVariable<Vector2D> realPosition;
|
||||
CAnimatedVariable<Vector2D> realSize;
|
||||
CAnimatedVariable<float> alpha;
|
||||
PHLANIMVAR<Vector2D> realPosition;
|
||||
PHLANIMVAR<Vector2D> realSize;
|
||||
PHLANIMVAR<float> alpha;
|
||||
|
||||
WP<CLayerShellResource> layerSurface;
|
||||
wl_list link;
|
||||
WP<CLayerShellResource> layerSurface;
|
||||
wl_list link;
|
||||
|
||||
// the header providing the enum type cannot be imported here
|
||||
int interactivity = 0;
|
||||
@@ -42,7 +37,7 @@ class CLayerSurface {
|
||||
bool mapped = false;
|
||||
uint32_t layer = 0;
|
||||
|
||||
MONITORID monitorID = -1;
|
||||
PHLMONITORREF monitor;
|
||||
|
||||
bool fadingOut = false;
|
||||
bool readyToDelete = false;
|
||||
@@ -55,6 +50,7 @@ class CLayerSurface {
|
||||
bool ignoreAlpha = false;
|
||||
float ignoreAlphaValue = 0.f;
|
||||
bool dimAround = false;
|
||||
int64_t order = 0;
|
||||
|
||||
std::optional<std::string> animationStyle;
|
||||
|
||||
@@ -63,12 +59,13 @@ class CLayerSurface {
|
||||
CBox geometry = {0, 0, 0, 0};
|
||||
Vector2D position;
|
||||
std::string szNamespace = "";
|
||||
std::unique_ptr<CPopup> popupHead;
|
||||
UP<CPopup> popupHead;
|
||||
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit();
|
||||
MONITORID monitorID();
|
||||
|
||||
private:
|
||||
struct {
|
||||
@@ -82,6 +79,6 @@ class CLayerSurface {
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CLayerSurface& rhs) const {
|
||||
return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID;
|
||||
return layerSurface == rhs.layerSurface && monitor == rhs.monitor;
|
||||
}
|
||||
};
|
||||
|
@@ -4,6 +4,12 @@
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../render/OpenGL.hpp"
|
||||
#include <ranges>
|
||||
|
||||
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) {
|
||||
@@ -14,13 +20,11 @@ CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) {
|
||||
initAllSignals();
|
||||
}
|
||||
|
||||
CPopup::CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner) : m_pParent(pOwner), m_pResource(popup) {
|
||||
CPopup::CPopup(SP<CXDGPopupResource> popup, WP<CPopup> pOwner) :
|
||||
m_pWindowOwner(pOwner->m_pWindowOwner), m_pLayerOwner(pOwner->m_pLayerOwner), m_pParent(pOwner), m_pResource(popup) {
|
||||
m_pWLSurface = CWLSurface::create();
|
||||
m_pWLSurface->assign(popup->surface->surface.lock(), this);
|
||||
|
||||
m_pLayerOwner = pOwner->m_pLayerOwner;
|
||||
m_pWindowOwner = pOwner->m_pWindowOwner;
|
||||
|
||||
m_vLastSize = popup->surface->current.geometry.size();
|
||||
reposition();
|
||||
|
||||
@@ -55,7 +59,8 @@ void CPopup::initAllSignals() {
|
||||
}
|
||||
|
||||
void CPopup::onNewPopup(SP<CXDGPopupResource> popup) {
|
||||
const auto POPUP = m_vChildren.emplace_back(makeShared<CPopup>(popup, this)).get();
|
||||
const auto& POPUP = m_vChildren.emplace_back(makeShared<CPopup>(popup, m_pSelf));
|
||||
POPUP->m_pSelf = POPUP;
|
||||
Debug::log(LOG, "New popup at {:x}", (uintptr_t)POPUP);
|
||||
}
|
||||
|
||||
@@ -80,13 +85,14 @@ void CPopup::onMap() {
|
||||
|
||||
CBox box = m_pWLSurface->resource()->extends();
|
||||
box.translate(COORDS).expand(4);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
|
||||
m_vLastPos = coordsRelativeToParent();
|
||||
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
|
||||
m_pSubsurfaceHead = std::make_unique<CSubsurface>(this);
|
||||
m_pSubsurfaceHead = makeUnique<CSubsurface>(m_pSelf);
|
||||
m_pSubsurfaceHead->m_pSelf = m_pSubsurfaceHead;
|
||||
|
||||
//unconstrain();
|
||||
sendScale();
|
||||
@@ -106,31 +112,36 @@ void CPopup::onUnmap() {
|
||||
return;
|
||||
}
|
||||
|
||||
m_bMapped = false;
|
||||
|
||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||
|
||||
const auto COORDS = coordsGlobal();
|
||||
|
||||
CBox box = m_pWLSurface->resource()->extends();
|
||||
box.translate(COORDS).expand(4);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
|
||||
m_pSubsurfaceHead.reset();
|
||||
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
|
||||
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
|
||||
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
|
||||
|
||||
// damage all children
|
||||
breadthfirst(
|
||||
[](CPopup* p, void* data) {
|
||||
[](WP<CPopup> p, void* data) {
|
||||
if (!p->m_pResource)
|
||||
return;
|
||||
|
||||
auto box = CBox{p->coordsGlobal(), p->size()};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
},
|
||||
nullptr);
|
||||
|
||||
const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == m_pWLSurface->resource() || g_pSeatManager->state.pointerFocus == m_pWLSurface->resource();
|
||||
|
||||
if (WASLASTFOCUS)
|
||||
g_pInputManager->simulateMouseMovement();
|
||||
}
|
||||
|
||||
void CPopup::onCommit(bool ignoreSiblings) {
|
||||
@@ -162,10 +173,10 @@ void CPopup::onCommit(bool ignoreSiblings) {
|
||||
|
||||
if (m_vLastSize != m_pResource->surface->surface->current.size || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
|
||||
CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
m_vLastSize = m_pResource->surface->surface->current.size;
|
||||
box = {COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
|
||||
m_vLastPos = COORDSLOCAL;
|
||||
}
|
||||
@@ -202,13 +213,20 @@ void CPopup::reposition() {
|
||||
m_pResource->applyPositioning(box, COORDS);
|
||||
}
|
||||
|
||||
SP<CWLSurface> CPopup::getT1Owner() {
|
||||
if (m_pWindowOwner)
|
||||
return m_pWindowOwner->m_pWLSurface;
|
||||
else
|
||||
return m_pLayerOwner->surface;
|
||||
}
|
||||
|
||||
Vector2D CPopup::coordsRelativeToParent() {
|
||||
Vector2D offset;
|
||||
|
||||
if (!m_pResource)
|
||||
return {};
|
||||
|
||||
CPopup* current = this;
|
||||
WP<CPopup> current = m_pSelf;
|
||||
offset -= current->m_pResource->surface->current.geometry.pos();
|
||||
|
||||
while (current->m_pParent && current->m_pResource) {
|
||||
@@ -232,16 +250,16 @@ Vector2D CPopup::localToGlobal(const Vector2D& rel) {
|
||||
|
||||
Vector2D CPopup::t1ParentCoords() {
|
||||
if (!m_pWindowOwner.expired())
|
||||
return m_pWindowOwner->m_vRealPosition.value();
|
||||
return m_pWindowOwner->m_vRealPosition->value();
|
||||
if (!m_pLayerOwner.expired())
|
||||
return m_pLayerOwner->realPosition.value();
|
||||
return m_pLayerOwner->realPosition->value();
|
||||
|
||||
ASSERT(false);
|
||||
return {};
|
||||
}
|
||||
|
||||
void CPopup::recheckTree() {
|
||||
CPopup* curr = this;
|
||||
WP<CPopup> curr = m_pSelf;
|
||||
while (curr->m_pParent) {
|
||||
curr = curr->m_pParent;
|
||||
}
|
||||
@@ -251,7 +269,7 @@ void CPopup::recheckTree() {
|
||||
|
||||
void CPopup::recheckChildrenRecursive() {
|
||||
auto cpy = m_vChildren;
|
||||
for (auto& c : cpy) {
|
||||
for (auto const& c : cpy) {
|
||||
c->onCommit(true);
|
||||
c->recheckChildrenRecursive();
|
||||
}
|
||||
@@ -281,16 +299,17 @@ bool CPopup::visible() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CPopup::bfHelper(std::vector<CPopup*> nodes, std::function<void(CPopup*, void*)> fn, void* data) {
|
||||
for (auto& n : nodes) {
|
||||
void CPopup::bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(WP<CPopup>, void*)> fn, void* data) {
|
||||
for (auto const& n : nodes) {
|
||||
fn(n, data);
|
||||
}
|
||||
|
||||
std::vector<CPopup*> nodes2;
|
||||
std::vector<WP<CPopup>> nodes2;
|
||||
nodes2.reserve(nodes.size() * 2);
|
||||
|
||||
for (auto& n : nodes) {
|
||||
for (auto& c : n->m_vChildren) {
|
||||
nodes2.push_back(c.get());
|
||||
for (auto const& n : nodes) {
|
||||
for (auto const& c : n->m_vChildren) {
|
||||
nodes2.push_back(c->m_pSelf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,18 +317,18 @@ void CPopup::bfHelper(std::vector<CPopup*> nodes, std::function<void(CPopup*, vo
|
||||
bfHelper(nodes2, fn, data);
|
||||
}
|
||||
|
||||
void CPopup::breadthfirst(std::function<void(CPopup*, void*)> fn, void* data) {
|
||||
std::vector<CPopup*> popups;
|
||||
popups.push_back(this);
|
||||
void CPopup::breadthfirst(std::function<void(WP<CPopup>, void*)> fn, void* data) {
|
||||
std::vector<WP<CPopup>> popups;
|
||||
popups.push_back(m_pSelf);
|
||||
bfHelper(popups, fn, data);
|
||||
}
|
||||
|
||||
CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||
std::vector<CPopup*> popups;
|
||||
breadthfirst([](CPopup* popup, void* data) { ((std::vector<CPopup*>*)data)->push_back(popup); }, &popups);
|
||||
WP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||
std::vector<WP<CPopup>> popups;
|
||||
breadthfirst([](WP<CPopup> popup, void* data) { ((std::vector<WP<CPopup>>*)data)->push_back(popup); }, &popups);
|
||||
|
||||
for (auto& p : popups | std::views::reverse) {
|
||||
if (!p->m_pResource)
|
||||
for (auto const& p : popups | std::views::reverse) {
|
||||
if (!p->m_pResource || !p->m_bMapped)
|
||||
continue;
|
||||
|
||||
if (!allowsInput) {
|
||||
@@ -328,5 +347,5 @@ CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "Subsurface.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
|
||||
class CXDGPopupResource;
|
||||
|
||||
@@ -14,32 +14,35 @@ class CPopup {
|
||||
CPopup(PHLLS pOwner);
|
||||
|
||||
// real nodes
|
||||
CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner);
|
||||
CPopup(SP<CXDGPopupResource> popup, WP<CPopup> pOwner);
|
||||
|
||||
~CPopup();
|
||||
|
||||
Vector2D coordsRelativeToParent();
|
||||
Vector2D coordsGlobal();
|
||||
SP<CWLSurface> getT1Owner();
|
||||
Vector2D coordsRelativeToParent();
|
||||
Vector2D coordsGlobal();
|
||||
|
||||
Vector2D size();
|
||||
Vector2D size();
|
||||
|
||||
void onNewPopup(SP<CXDGPopupResource> popup);
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit(bool ignoreSiblings = false);
|
||||
void onReposition();
|
||||
void onNewPopup(SP<CXDGPopupResource> popup);
|
||||
void onDestroy();
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit(bool ignoreSiblings = false);
|
||||
void onReposition();
|
||||
|
||||
void recheckTree();
|
||||
void recheckTree();
|
||||
|
||||
bool visible();
|
||||
bool visible();
|
||||
|
||||
// will also loop over this node
|
||||
void breadthfirst(std::function<void(CPopup*, void*)> fn, void* data);
|
||||
CPopup* at(const Vector2D& globalCoords, bool allowsInput = false);
|
||||
void breadthfirst(std::function<void(WP<CPopup>, void*)> fn, void* data);
|
||||
WP<CPopup> at(const Vector2D& globalCoords, bool allowsInput = false);
|
||||
|
||||
//
|
||||
SP<CWLSurface> m_pWLSurface;
|
||||
WP<CPopup> m_pSelf;
|
||||
bool m_bMapped = false;
|
||||
|
||||
private:
|
||||
// T1 owners, each popup has to have one of these
|
||||
@@ -47,7 +50,7 @@ class CPopup {
|
||||
PHLLSREF m_pLayerOwner;
|
||||
|
||||
// T2 owners
|
||||
CPopup* m_pParent = nullptr;
|
||||
WP<CPopup> m_pParent;
|
||||
|
||||
WP<CXDGPopupResource> m_pResource;
|
||||
|
||||
@@ -56,12 +59,11 @@ class CPopup {
|
||||
|
||||
bool m_bRequestedReposition = false;
|
||||
|
||||
bool m_bInert = false;
|
||||
bool m_bMapped = false;
|
||||
bool m_bInert = false;
|
||||
|
||||
//
|
||||
std::vector<SP<CPopup>> m_vChildren;
|
||||
std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
|
||||
std::vector<SP<CPopup>> m_vChildren;
|
||||
UP<CSubsurface> m_pSubsurfaceHead;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener newPopup;
|
||||
@@ -80,5 +82,5 @@ class CPopup {
|
||||
|
||||
Vector2D localToGlobal(const Vector2D& rel);
|
||||
Vector2D t1ParentCoords();
|
||||
static void bfHelper(std::vector<CPopup*> nodes, std::function<void(CPopup*, void*)> fn, void* data);
|
||||
static void bfHelper(std::vector<WP<CPopup>> const& nodes, std::function<void(WP<CPopup>, void*)> fn, void* data);
|
||||
};
|
||||
|
22
src/desktop/Rule.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <re2/re2.h>
|
||||
#include "../helpers/memory/Memory.hpp"
|
||||
#include "Rule.hpp"
|
||||
#include "../debug/Log.hpp"
|
||||
|
||||
CRuleRegexContainer::CRuleRegexContainer(const std::string& regex_) {
|
||||
const bool NEGATIVE = regex_.starts_with("negative:");
|
||||
|
||||
negative = NEGATIVE;
|
||||
regex = makeUnique<RE2>(NEGATIVE ? regex_.substr(9) : regex_);
|
||||
|
||||
// TODO: maybe pop an error?
|
||||
if (!regex->ok())
|
||||
Debug::log(ERR, "RuleRegexContainer: regex {} failed to parse!", regex_);
|
||||
}
|
||||
|
||||
bool CRuleRegexContainer::passes(const std::string& str) const {
|
||||
if (!regex)
|
||||
return false;
|
||||
|
||||
return RE2::FullMatch(str, *regex) != negative;
|
||||
}
|
21
src/desktop/Rule.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <hyprutils/memory/UniquePtr.hpp>
|
||||
|
||||
//NOLINTNEXTLINE
|
||||
namespace re2 {
|
||||
class RE2;
|
||||
};
|
||||
|
||||
class CRuleRegexContainer {
|
||||
public:
|
||||
CRuleRegexContainer() = default;
|
||||
|
||||
CRuleRegexContainer(const std::string& regex);
|
||||
|
||||
bool passes(const std::string& str) const;
|
||||
|
||||
private:
|
||||
Hyprutils::Memory::CUniquePointer<re2::RE2> regex;
|
||||
bool negative = false;
|
||||
};
|
@@ -4,13 +4,15 @@
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../protocols/core/Subcompositor.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
|
||||
CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) {
|
||||
initSignals();
|
||||
initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
||||
}
|
||||
|
||||
CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) {
|
||||
CSubsurface::CSubsurface(WP<CPopup> pOwner) : m_pPopupParent(pOwner) {
|
||||
initSignals();
|
||||
initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
|
||||
}
|
||||
@@ -22,7 +24,7 @@ CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner
|
||||
initExistingSubsurfaces(pSubsurface->surface.lock());
|
||||
}
|
||||
|
||||
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
|
||||
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
|
||||
m_pWLSurface = CWLSurface::create();
|
||||
m_pWLSurface->assign(pSubsurface->surface.lock(), this);
|
||||
initSignals();
|
||||
@@ -30,13 +32,7 @@ CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner)
|
||||
}
|
||||
|
||||
CSubsurface::~CSubsurface() {
|
||||
hyprListener_newSubsurface.removeCallback();
|
||||
|
||||
if (!m_pSubsurface)
|
||||
return;
|
||||
|
||||
hyprListener_commitSubsurface.removeCallback();
|
||||
hyprListener_destroySubsurface.removeCallback();
|
||||
;
|
||||
}
|
||||
|
||||
void CSubsurface::initSignals() {
|
||||
@@ -65,7 +61,7 @@ void CSubsurface::checkSiblingDamage() {
|
||||
|
||||
const double SCALE = m_pWindowParent.lock() && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
|
||||
|
||||
for (auto& n : m_pParent->m_vChildren) {
|
||||
for (auto const& n : m_pParent->m_vChildren) {
|
||||
if (n.get() == this)
|
||||
continue;
|
||||
|
||||
@@ -75,7 +71,7 @@ void CSubsurface::checkSiblingDamage() {
|
||||
}
|
||||
|
||||
void CSubsurface::recheckDamageForSubsurfaces() {
|
||||
for (auto& n : m_vChildren) {
|
||||
for (auto const& n : m_vChildren) {
|
||||
const auto COORDS = n->coordsGlobal();
|
||||
g_pHyprRenderer->damageSurface(n->m_pWLSurface->resource(), COORDS.x, COORDS.y);
|
||||
}
|
||||
@@ -105,11 +101,20 @@ void CSubsurface::onCommit() {
|
||||
checkSiblingDamage();
|
||||
|
||||
if (m_vLastSize != m_pWLSurface->resource()->current.size) {
|
||||
CBox box{COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
m_vLastSize = m_pWLSurface->resource()->current.size;
|
||||
box = {COORDS, m_vLastSize};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
// TODO: fix this
|
||||
// CBox box{COORDS, m_vLastSize};
|
||||
// g_pHyprRenderer->damageBox(box);
|
||||
// m_vLastSize = m_pWLSurface->resource()->current.size;
|
||||
// box = {COORDS, m_vLastSize};
|
||||
// g_pHyprRenderer->damageBox(box);
|
||||
|
||||
CBox box;
|
||||
if (m_pPopupParent)
|
||||
box = m_pPopupParent->m_pWLSurface->getSurfaceBoxGlobal().value_or(CBox{});
|
||||
else if (m_pWindowParent)
|
||||
box = m_pWindowParent->getWindowMainSurfaceBox();
|
||||
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,16 +132,18 @@ void CSubsurface::onDestroy() {
|
||||
}
|
||||
|
||||
void CSubsurface::onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface) {
|
||||
CSubsurface* PSUBSURFACE = nullptr;
|
||||
WP<CSubsurface> PSUBSURFACE;
|
||||
|
||||
if (!m_pWindowParent.expired())
|
||||
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent.lock())).get();
|
||||
PSUBSURFACE = m_vChildren.emplace_back(makeUnique<CSubsurface>(pSubsurface, m_pWindowParent.lock()));
|
||||
else if (m_pPopupParent)
|
||||
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get();
|
||||
PSUBSURFACE = m_vChildren.emplace_back(makeUnique<CSubsurface>(pSubsurface, m_pPopupParent));
|
||||
|
||||
PSUBSURFACE->m_pSelf = PSUBSURFACE;
|
||||
|
||||
ASSERT(PSUBSURFACE);
|
||||
|
||||
PSUBSURFACE->m_pParent = this;
|
||||
PSUBSURFACE->m_pParent = PSUBSURFACE;
|
||||
}
|
||||
|
||||
void CSubsurface::onMap() {
|
||||
@@ -145,7 +152,7 @@ void CSubsurface::onMap() {
|
||||
const auto COORDS = coordsGlobal();
|
||||
CBox box{COORDS, m_vLastSize};
|
||||
box.expand(4);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
|
||||
if (!m_pWindowParent.expired())
|
||||
m_pWindowParent->updateSurfaceScaleTransformDetails();
|
||||
@@ -155,7 +162,7 @@ void CSubsurface::onUnmap() {
|
||||
const auto COORDS = coordsGlobal();
|
||||
CBox box{COORDS, m_vLastSize};
|
||||
box.expand(4);
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
g_pHyprRenderer->damageBox(box);
|
||||
|
||||
if (m_pWLSurface->resource() == g_pCompositor->m_pLastFocus)
|
||||
g_pInputManager->releaseAllMouseButtons();
|
||||
@@ -175,7 +182,7 @@ Vector2D CSubsurface::coordsGlobal() {
|
||||
Vector2D coords = coordsRelativeToParent();
|
||||
|
||||
if (!m_pWindowParent.expired())
|
||||
coords += m_pWindowParent->m_vRealPosition.value();
|
||||
coords += m_pWindowParent->m_vRealPosition->value();
|
||||
else if (m_pPopupParent)
|
||||
coords += m_pPopupParent->coordsGlobal();
|
||||
|
||||
@@ -183,7 +190,7 @@ Vector2D CSubsurface::coordsGlobal() {
|
||||
}
|
||||
|
||||
void CSubsurface::initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface) {
|
||||
for (auto& s : pSurface->subsurfaces) {
|
||||
for (auto const& s : pSurface->subsurfaces) {
|
||||
if (!s || s->surface->hlSurface /* already assigned */)
|
||||
continue;
|
||||
onNewSubsurface(s.lock());
|
||||
|
@@ -11,34 +11,32 @@ class CSubsurface {
|
||||
public:
|
||||
// root dummy nodes
|
||||
CSubsurface(PHLWINDOW pOwner);
|
||||
CSubsurface(CPopup* pOwner);
|
||||
CSubsurface(WP<CPopup> pOwner);
|
||||
|
||||
// real nodes
|
||||
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
|
||||
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner);
|
||||
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner);
|
||||
|
||||
~CSubsurface();
|
||||
|
||||
Vector2D coordsRelativeToParent();
|
||||
Vector2D coordsGlobal();
|
||||
Vector2D coordsRelativeToParent();
|
||||
Vector2D coordsGlobal();
|
||||
|
||||
Vector2D size();
|
||||
Vector2D size();
|
||||
|
||||
void onCommit();
|
||||
void onDestroy();
|
||||
void onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface);
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
void onCommit();
|
||||
void onDestroy();
|
||||
void onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface);
|
||||
void onMap();
|
||||
void onUnmap();
|
||||
|
||||
bool visible();
|
||||
bool visible();
|
||||
|
||||
void recheckDamageForSubsurfaces();
|
||||
void recheckDamageForSubsurfaces();
|
||||
|
||||
WP<CSubsurface> m_pSelf;
|
||||
|
||||
private:
|
||||
DYNLISTENER(destroySubsurface);
|
||||
DYNLISTENER(commitSubsurface);
|
||||
DYNLISTENER(newSubsurface);
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroySubsurface;
|
||||
CHyprSignalListener commitSubsurface;
|
||||
@@ -52,16 +50,16 @@ class CSubsurface {
|
||||
Vector2D m_vLastSize = {};
|
||||
|
||||
// if nullptr, means it's a dummy node
|
||||
CSubsurface* m_pParent = nullptr;
|
||||
WP<CSubsurface> m_pParent;
|
||||
|
||||
PHLWINDOWREF m_pWindowParent;
|
||||
CPopup* m_pPopupParent = nullptr;
|
||||
PHLWINDOWREF m_pWindowParent;
|
||||
WP<CPopup> m_pPopupParent;
|
||||
|
||||
std::vector<std::unique_ptr<CSubsurface>> m_vChildren;
|
||||
std::vector<UP<CSubsurface>> m_vChildren;
|
||||
|
||||
bool m_bInert = false;
|
||||
bool m_bInert = false;
|
||||
|
||||
void initSignals();
|
||||
void initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface);
|
||||
void checkSiblingDamage();
|
||||
void initSignals();
|
||||
void initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface);
|
||||
void checkSiblingDamage();
|
||||
};
|
@@ -1,7 +1,9 @@
|
||||
#include "WLSurface.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "LayerSurface.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
||||
void CWLSurface::assign(SP<CWLSurfaceResource> pSurface) {
|
||||
m_pResource = pSurface;
|
||||
@@ -62,7 +64,7 @@ bool CWLSurface::small() const {
|
||||
|
||||
const auto O = m_pWindowOwner.lock();
|
||||
|
||||
return O->m_vReportedSize.x > m_pResource->current.bufferSize.x + 1 || O->m_vReportedSize.y > m_pResource->current.bufferSize.y + 1;
|
||||
return O->m_vReportedSize.x > m_pResource->current.size.x + 1 || O->m_vReportedSize.y > m_pResource->current.size.y + 1;
|
||||
}
|
||||
|
||||
Vector2D CWLSurface::correctSmallVec() const {
|
||||
@@ -72,7 +74,7 @@ Vector2D CWLSurface::correctSmallVec() const {
|
||||
const auto SIZE = getViewporterCorrectedSize();
|
||||
const auto O = m_pWindowOwner.lock();
|
||||
|
||||
return Vector2D{(O->m_vReportedSize.x - SIZE.x) / 2, (O->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_vRealSize.value() / O->m_vReportedSize);
|
||||
return Vector2D{(O->m_vReportedSize.x - SIZE.x) / 2, (O->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * (O->m_vRealSize->value() / O->m_vReportedSize);
|
||||
}
|
||||
|
||||
Vector2D CWLSurface::correctSmallVecBuf() const {
|
||||
|
@@ -84,7 +84,11 @@ class CWLSurface {
|
||||
static SP<CWLSurface> fromResource(SP<CWLSurfaceResource> pSurface);
|
||||
|
||||
// used by the alpha-modifier protocol
|
||||
float m_pAlphaModifier = 1.F;
|
||||
float m_fAlphaModifier = 1.F;
|
||||
|
||||
// used by the hyprland-surface protocol
|
||||
float m_fOverallOpacity = 1.F;
|
||||
CRegion m_visibleRegion;
|
||||
|
||||
struct {
|
||||
CSignal destroy;
|
||||
@@ -116,4 +120,5 @@ class CWLSurface {
|
||||
} listeners;
|
||||
|
||||
friend class CPointerConstraint;
|
||||
};
|
||||
friend class CXxColorManagerV4;
|
||||
};
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
#include "../config/ConfigDataValues.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
#include "../helpers/math/Math.hpp"
|
||||
#include "../helpers/signal/Signal.hpp"
|
||||
@@ -12,23 +12,25 @@
|
||||
#include "../macros.hpp"
|
||||
#include "../managers/XWaylandManager.hpp"
|
||||
#include "../render/decorations/IHyprWindowDecoration.hpp"
|
||||
#include "../render/Transformer.hpp"
|
||||
#include "DesktopTypes.hpp"
|
||||
#include "Popup.hpp"
|
||||
#include "Subsurface.hpp"
|
||||
#include "WLSurface.hpp"
|
||||
#include "Workspace.hpp"
|
||||
#include "WindowRule.hpp"
|
||||
|
||||
class CXDGSurfaceResource;
|
||||
class CXWaylandSurface;
|
||||
|
||||
enum eIdleInhibitMode {
|
||||
enum eIdleInhibitMode : uint8_t {
|
||||
IDLEINHIBIT_NONE = 0,
|
||||
IDLEINHIBIT_ALWAYS,
|
||||
IDLEINHIBIT_FULLSCREEN,
|
||||
IDLEINHIBIT_FOCUS
|
||||
};
|
||||
|
||||
enum eGroupRules {
|
||||
enum eGroupRules : uint8_t {
|
||||
// effective only during first map, except for _ALWAYS variant
|
||||
GROUP_NONE = 0,
|
||||
GROUP_SET = 1 << 0, // Open as new group or add to focused group
|
||||
@@ -40,7 +42,7 @@ enum eGroupRules {
|
||||
GROUP_OVERRIDE = 1 << 6, // Override other rules
|
||||
};
|
||||
|
||||
enum eGetWindowProperties {
|
||||
enum eGetWindowProperties : uint8_t {
|
||||
WINDOW_ONLY = 0,
|
||||
RESERVED_EXTENTS = 1 << 0,
|
||||
INPUT_EXTENTS = 1 << 1,
|
||||
@@ -50,12 +52,13 @@ enum eGetWindowProperties {
|
||||
USE_PROP_TILED = 1 << 5,
|
||||
};
|
||||
|
||||
enum eSuppressEvents {
|
||||
enum eSuppressEvents : uint8_t {
|
||||
SUPPRESS_NONE = 0,
|
||||
SUPPRESS_FULLSCREEN = 1 << 0,
|
||||
SUPPRESS_MAXIMIZE = 1 << 1,
|
||||
SUPPRESS_ACTIVATE = 1 << 2,
|
||||
SUPPRESS_ACTIVATE_FOCUSONLY = 1 << 3,
|
||||
SUPPRESS_FULLSCREEN_OUTPUT = 1 << 4,
|
||||
};
|
||||
|
||||
class IWindowTransformer;
|
||||
@@ -64,7 +67,7 @@ struct SAlphaValue {
|
||||
float m_fAlpha;
|
||||
bool m_bOverride;
|
||||
|
||||
float applyAlpha(float alpha) {
|
||||
float applyAlpha(float alpha) const {
|
||||
if (m_bOverride)
|
||||
return m_fAlpha;
|
||||
else
|
||||
@@ -72,8 +75,8 @@ struct SAlphaValue {
|
||||
};
|
||||
};
|
||||
|
||||
enum eOverridePriority {
|
||||
PRIORITY_LAYOUT,
|
||||
enum eOverridePriority : uint8_t {
|
||||
PRIORITY_LAYOUT = 0,
|
||||
PRIORITY_WORKSPACE_RULE,
|
||||
PRIORITY_WINDOW_RULE,
|
||||
PRIORITY_SET_PROP,
|
||||
@@ -85,9 +88,7 @@ class CWindowOverridableVar {
|
||||
CWindowOverridableVar(T const& value, eOverridePriority priority) {
|
||||
values[priority] = value;
|
||||
}
|
||||
CWindowOverridableVar(T const& value) {
|
||||
defaultValue = value;
|
||||
}
|
||||
CWindowOverridableVar(T const& value) : defaultValue{value} {}
|
||||
|
||||
CWindowOverridableVar() = default;
|
||||
~CWindowOverridableVar() = default;
|
||||
@@ -144,6 +145,13 @@ class CWindowOverridableVar {
|
||||
unset(priority);
|
||||
}
|
||||
|
||||
operator std::optional<T>() {
|
||||
if (hasValue())
|
||||
return value();
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<eOverridePriority, T> values;
|
||||
T defaultValue; // used for toggling, so required for bool
|
||||
@@ -174,10 +182,15 @@ struct SWindowData {
|
||||
CWindowOverridableVar<bool> syncFullscreen = true;
|
||||
CWindowOverridableVar<bool> tearing = false;
|
||||
CWindowOverridableVar<bool> xray = false;
|
||||
CWindowOverridableVar<bool> renderUnfocused = false;
|
||||
|
||||
CWindowOverridableVar<int> rounding;
|
||||
CWindowOverridableVar<float> roundingPower;
|
||||
CWindowOverridableVar<int> borderSize;
|
||||
|
||||
CWindowOverridableVar<float> scrollMouse;
|
||||
CWindowOverridableVar<float> scrollTouchpad;
|
||||
|
||||
CWindowOverridableVar<std::string> animationStyle;
|
||||
CWindowOverridableVar<Vector2D> maxSize;
|
||||
CWindowOverridableVar<Vector2D> minSize;
|
||||
@@ -186,32 +199,12 @@ struct SWindowData {
|
||||
CWindowOverridableVar<CGradientValueData> inactiveBorderColor;
|
||||
};
|
||||
|
||||
struct SWindowRule {
|
||||
std::string szRule;
|
||||
std::string szValue;
|
||||
|
||||
bool v2 = false;
|
||||
std::string szTitle;
|
||||
std::string szClass;
|
||||
std::string szInitialTitle;
|
||||
std::string szInitialClass;
|
||||
std::string szTag;
|
||||
int bX11 = -1; // -1 means "ANY"
|
||||
int bFloating = -1;
|
||||
int bFullscreen = -1;
|
||||
int bPinned = -1;
|
||||
int bFocus = -1;
|
||||
std::string szFullscreenState = ""; // empty means any
|
||||
std::string szOnWorkspace = ""; // empty means any
|
||||
std::string szWorkspace = ""; // empty means any
|
||||
};
|
||||
|
||||
struct SInitialWorkspaceToken {
|
||||
PHLWINDOWREF primaryOwner;
|
||||
std::string workspace;
|
||||
};
|
||||
|
||||
struct sFullscreenState {
|
||||
struct SFullscreenState {
|
||||
eFullscreenMode internal = FSMODE_NONE;
|
||||
eFullscreenMode client = FSMODE_NONE;
|
||||
};
|
||||
@@ -242,8 +235,8 @@ class CWindow {
|
||||
Vector2D m_vSize = Vector2D(0, 0);
|
||||
|
||||
// this is the real position and size used to draw the thing
|
||||
CAnimatedVariable<Vector2D> m_vRealPosition;
|
||||
CAnimatedVariable<Vector2D> m_vRealSize;
|
||||
PHLANIMVAR<Vector2D> m_vRealPosition;
|
||||
PHLANIMVAR<Vector2D> m_vRealSize;
|
||||
|
||||
// for not spamming the protocols
|
||||
Vector2D m_vReportedPosition;
|
||||
@@ -270,13 +263,13 @@ class CWindow {
|
||||
bool m_bIsFloating = false;
|
||||
bool m_bDraggingTiled = false; // for dragging around tiled windows
|
||||
bool m_bWasMaximized = false;
|
||||
sFullscreenState m_sFullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE};
|
||||
MONITORID m_iMonitorID = -1;
|
||||
SFullscreenState m_sFullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE};
|
||||
std::string m_szTitle = "";
|
||||
std::string m_szClass = "";
|
||||
std::string m_szInitialTitle = "";
|
||||
std::string m_szInitialClass = "";
|
||||
PHLWORKSPACE m_pWorkspace;
|
||||
PHLMONITORREF m_pMonitor;
|
||||
|
||||
bool m_bIsMapped = false;
|
||||
|
||||
@@ -288,8 +281,6 @@ class CWindow {
|
||||
// XWayland stuff
|
||||
bool m_bIsX11 = false;
|
||||
PHLWINDOWREF m_pX11Parent;
|
||||
uint64_t m_iX11Type = 0;
|
||||
bool m_bIsModal = false;
|
||||
bool m_bX11DoesntWantBorders = false;
|
||||
bool m_bX11ShouldntFocus = false;
|
||||
float m_fX11SurfaceScaledBy = 1.f;
|
||||
@@ -299,33 +290,37 @@ class CWindow {
|
||||
bool m_bNoInitialFocus = false;
|
||||
|
||||
// Fullscreen and Maximize
|
||||
bool m_bWantsInitialFullscreen = false;
|
||||
bool m_bWantsInitialFullscreen = false;
|
||||
MONITORID m_iWantsInitialFullscreenMonitor = MONITOR_INVALID;
|
||||
|
||||
// bitfield eSuppressEvents
|
||||
uint64_t m_eSuppressedEvents = SUPPRESS_NONE;
|
||||
|
||||
// desktop components
|
||||
std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
|
||||
std::unique_ptr<CPopup> m_pPopupHead;
|
||||
UP<CSubsurface> m_pSubsurfaceHead;
|
||||
UP<CPopup> m_pPopupHead;
|
||||
|
||||
// Animated border
|
||||
CGradientValueData m_cRealBorderColor = {0};
|
||||
CGradientValueData m_cRealBorderColorPrevious = {0};
|
||||
CAnimatedVariable<float> m_fBorderFadeAnimationProgress;
|
||||
CAnimatedVariable<float> m_fBorderAngleAnimationProgress;
|
||||
CGradientValueData m_cRealBorderColor = {0};
|
||||
CGradientValueData m_cRealBorderColorPrevious = {0};
|
||||
PHLANIMVAR<float> m_fBorderFadeAnimationProgress;
|
||||
PHLANIMVAR<float> m_fBorderAngleAnimationProgress;
|
||||
|
||||
// Fade in-out
|
||||
CAnimatedVariable<float> m_fAlpha;
|
||||
bool m_bFadingOut = false;
|
||||
bool m_bReadyToDelete = false;
|
||||
Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in
|
||||
Vector2D m_vOriginalClosedSize; // drawing the closing animations
|
||||
SBoxExtents m_eOriginalClosedExtents;
|
||||
bool m_bAnimatingIn = false;
|
||||
PHLANIMVAR<float> m_fAlpha;
|
||||
bool m_bFadingOut = false;
|
||||
bool m_bReadyToDelete = false;
|
||||
Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in
|
||||
Vector2D m_vOriginalClosedSize; // drawing the closing animations
|
||||
SBoxExtents m_eOriginalClosedExtents;
|
||||
bool m_bAnimatingIn = false;
|
||||
|
||||
// For pinned (sticky) windows
|
||||
bool m_bPinned = false;
|
||||
|
||||
// For preserving pinned state when fullscreening a pinned window
|
||||
bool m_bPinFullscreened = false;
|
||||
|
||||
// urgency hint
|
||||
bool m_bIsUrgent = false;
|
||||
|
||||
@@ -334,26 +329,32 @@ class CWindow {
|
||||
|
||||
// Window decorations
|
||||
// TODO: make this a SP.
|
||||
std::deque<std::unique_ptr<IHyprWindowDecoration>> m_dWindowDecorations;
|
||||
std::vector<IHyprWindowDecoration*> m_vDecosToRemove;
|
||||
std::vector<UP<IHyprWindowDecoration>> m_dWindowDecorations;
|
||||
std::vector<IHyprWindowDecoration*> m_vDecosToRemove;
|
||||
|
||||
// Special render data, rules, etc
|
||||
SWindowData m_sWindowData;
|
||||
|
||||
// Transformers
|
||||
std::vector<std::unique_ptr<IWindowTransformer>> m_vTransformers;
|
||||
std::vector<UP<IWindowTransformer>> m_vTransformers;
|
||||
|
||||
// for alpha
|
||||
CAnimatedVariable<float> m_fActiveInactiveAlpha;
|
||||
PHLANIMVAR<float> m_fActiveInactiveAlpha;
|
||||
PHLANIMVAR<float> m_fMovingFromWorkspaceAlpha;
|
||||
|
||||
// animated shadow color
|
||||
CAnimatedVariable<CColor> m_cRealShadowColor;
|
||||
PHLANIMVAR<CHyprColor> m_cRealShadowColor;
|
||||
|
||||
// animated tint
|
||||
CAnimatedVariable<float> m_fDimPercent;
|
||||
PHLANIMVAR<float> m_fDimPercent;
|
||||
|
||||
// animate moving to an invisible workspace
|
||||
int m_iMonitorMovedFrom = -1; // -1 means not moving
|
||||
PHLANIMVAR<float> m_fMovingToWorkspaceAlpha;
|
||||
|
||||
// swallowing
|
||||
PHLWINDOWREF m_pSwallowed;
|
||||
bool m_bGroupSwallowed = false;
|
||||
|
||||
// focus stuff
|
||||
bool m_bStayFocused = false;
|
||||
@@ -380,13 +381,13 @@ class CWindow {
|
||||
bool m_bTearingHint = false;
|
||||
|
||||
// stores the currently matched window rules
|
||||
std::vector<SWindowRule> m_vMatchedRules;
|
||||
std::vector<SP<CWindowRule>> m_vMatchedRules;
|
||||
|
||||
// window tags
|
||||
CTagKeeper m_tags;
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CWindow& rhs) {
|
||||
bool operator==(const CWindow& rhs) const {
|
||||
return m_pXDGSurface == rhs.m_pXDGSurface && m_pXWaylandSurface == rhs.m_pXWaylandSurface && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize &&
|
||||
m_bFadingOut == rhs.m_bFadingOut;
|
||||
}
|
||||
@@ -395,50 +396,49 @@ class CWindow {
|
||||
CBox getFullWindowBoundingBox();
|
||||
SBoxExtents getFullWindowExtents();
|
||||
CBox getWindowBoxUnified(uint64_t props);
|
||||
CBox getWindowMainSurfaceBox();
|
||||
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
||||
void addWindowDeco(std::unique_ptr<IHyprWindowDecoration> deco);
|
||||
void addWindowDeco(UP<IHyprWindowDecoration> deco);
|
||||
void updateWindowDecos();
|
||||
void removeWindowDeco(IHyprWindowDecoration* deco);
|
||||
void uncacheWindowDecos();
|
||||
bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {});
|
||||
pid_t getPID();
|
||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||
void removeDecorationByType(eDecorationType);
|
||||
void updateToplevel();
|
||||
void updateSurfaceScaleTransformDetails(bool force = false);
|
||||
void moveToWorkspace(PHLWORKSPACE);
|
||||
PHLWINDOW X11TransientFor();
|
||||
PHLWINDOW x11TransientFor();
|
||||
void onUnmap();
|
||||
void onMap();
|
||||
void setHidden(bool hidden);
|
||||
bool isHidden();
|
||||
void applyDynamicRule(const SWindowRule& r);
|
||||
void applyDynamicRule(const SP<CWindowRule>& r);
|
||||
void updateDynamicRules();
|
||||
SBoxExtents getFullWindowReservedArea();
|
||||
Vector2D middle();
|
||||
bool opaque();
|
||||
float rounding();
|
||||
float roundingPower();
|
||||
bool canBeTorn();
|
||||
void setSuspended(bool suspend);
|
||||
bool visibleOnMonitor(CMonitor* pMonitor);
|
||||
bool visibleOnMonitor(PHLMONITOR pMonitor);
|
||||
WORKSPACEID workspaceID();
|
||||
MONITORID monitorID();
|
||||
bool onSpecialWorkspace();
|
||||
void activate(bool force = false);
|
||||
int surfacesCount();
|
||||
|
||||
void clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize);
|
||||
bool isFullscreen();
|
||||
bool isEffectiveInternalFSMode(const eFullscreenMode);
|
||||
|
||||
int getRealBorderSize();
|
||||
float getScrollMouse();
|
||||
float getScrollTouchpad();
|
||||
void updateWindowData();
|
||||
void updateWindowData(const struct SWorkspaceRule&);
|
||||
|
||||
void onBorderAngleAnimEnd(void* ptr);
|
||||
void onBorderAngleAnimEnd(WP<Hyprutils::Animation::CBaseAnimatedVariable> pav);
|
||||
bool isInCurvedCorner(double x, double y);
|
||||
bool hasPopupAt(const Vector2D& pos);
|
||||
int popupsCount();
|
||||
|
||||
void applyGroupRules();
|
||||
void createGroup();
|
||||
void destroyGroup();
|
||||
@@ -455,15 +455,25 @@ class CWindow {
|
||||
void switchWithWindowInGroup(PHLWINDOW pWindow);
|
||||
void setAnimationsToMove();
|
||||
void onWorkspaceAnimUpdate();
|
||||
void onFocusAnimUpdate();
|
||||
void onUpdateState();
|
||||
void onUpdateMeta();
|
||||
void onX11Configure(CBox box);
|
||||
void onResourceChangeX11();
|
||||
std::string fetchTitle();
|
||||
std::string fetchClass();
|
||||
void warpCursor();
|
||||
void warpCursor(bool force = false);
|
||||
PHLWINDOW getSwallower();
|
||||
void unsetWindowData(eOverridePriority priority);
|
||||
bool isX11OverrideRedirect();
|
||||
bool isModal();
|
||||
Vector2D requestedMinSize();
|
||||
Vector2D requestedMaxSize();
|
||||
void sendWindowSize(Vector2D size, bool force = false, std::optional<Vector2D> overridePos = std::nullopt);
|
||||
|
||||
CBox getWindowMainSurfaceBox() const {
|
||||
return {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y};
|
||||
}
|
||||
|
||||
// listeners
|
||||
void onAck(uint32_t serial);
|
||||
@@ -550,7 +560,7 @@ struct std::formatter<PHLWINDOW, CharT> : std::formatter<CharT> {
|
||||
if (formatWorkspace)
|
||||
std::format_to(out, ", workspace: {}", w->m_pWorkspace ? w->workspaceID() : WORKSPACE_INVALID);
|
||||
if (formatMonitor)
|
||||
std::format_to(out, ", monitor: {}", w->m_iMonitorID);
|
||||
std::format_to(out, ", monitor: {}", w->monitorID());
|
||||
if (formatClass)
|
||||
std::format_to(out, ", class: {}", w->m_szClass);
|
||||
return std::format_to(out, "]");
|
||||
|
91
src/desktop/WindowRule.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include "WindowRule.hpp"
|
||||
#include <unordered_set>
|
||||
#include <algorithm>
|
||||
#include <re2/re2.h>
|
||||
#include "../config/ConfigManager.hpp"
|
||||
|
||||
static const auto RULES = std::unordered_set<std::string>{
|
||||
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused",
|
||||
};
|
||||
static const auto RULES_PREFIX = std::unordered_set<std::string>{
|
||||
"animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor", "move", "opacity",
|
||||
"plugin:", "prop", "pseudo", "rounding", "roundingpower", "scrollmouse", "scrolltouchpad", "size", "suppressevent", "tag", "workspace", "xray",
|
||||
};
|
||||
|
||||
CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool isV2, bool isExecRule) : szValue(value), szRule(rule), v2(isV2), execRule(isExecRule) {
|
||||
const auto VALS = CVarList(rule, 2, ' ');
|
||||
const bool VALID = RULES.contains(rule) || std::any_of(RULES_PREFIX.begin(), RULES_PREFIX.end(), [&rule](auto prefix) { return rule.starts_with(prefix); }) ||
|
||||
(g_pConfigManager->mbWindowProperties.find(VALS[0]) != g_pConfigManager->mbWindowProperties.end()) ||
|
||||
(g_pConfigManager->miWindowProperties.find(VALS[0]) != g_pConfigManager->miWindowProperties.end()) ||
|
||||
(g_pConfigManager->mfWindowProperties.find(VALS[0]) != g_pConfigManager->mfWindowProperties.end());
|
||||
|
||||
if (!VALID)
|
||||
return;
|
||||
|
||||
if (rule == "float")
|
||||
ruleType = RULE_FLOAT;
|
||||
else if (rule == "fullscreen")
|
||||
ruleType = RULE_FULLSCREEN;
|
||||
else if (rule == "maximize")
|
||||
ruleType = RULE_MAXIMIZE;
|
||||
else if (rule == "noinitialfocus")
|
||||
ruleType = RULE_NOINITIALFOCUS;
|
||||
else if (rule == "pin")
|
||||
ruleType = RULE_PIN;
|
||||
else if (rule == "stayfocused")
|
||||
ruleType = RULE_STAYFOCUSED;
|
||||
else if (rule == "tile")
|
||||
ruleType = RULE_TILE;
|
||||
else if (rule == "renderunfocused")
|
||||
ruleType = RULE_RENDERUNFOCUSED;
|
||||
else if (rule.starts_with("animation"))
|
||||
ruleType = RULE_ANIMATION;
|
||||
else if (rule.starts_with("bordercolor"))
|
||||
ruleType = RULE_BORDERCOLOR;
|
||||
else if (rule.starts_with("center"))
|
||||
ruleType = RULE_CENTER;
|
||||
else if (rule.starts_with("fullscreenstate"))
|
||||
ruleType = RULE_FULLSCREENSTATE;
|
||||
else if (rule.starts_with("group"))
|
||||
ruleType = RULE_GROUP;
|
||||
else if (rule.starts_with("idleinhibit"))
|
||||
ruleType = RULE_IDLEINHIBIT;
|
||||
else if (rule.starts_with("maxsize"))
|
||||
ruleType = RULE_MAXSIZE;
|
||||
else if (rule.starts_with("minsize"))
|
||||
ruleType = RULE_MINSIZE;
|
||||
else if (rule.starts_with("monitor"))
|
||||
ruleType = RULE_MONITOR;
|
||||
else if (rule.starts_with("move"))
|
||||
ruleType = RULE_MOVE;
|
||||
else if (rule.starts_with("opacity"))
|
||||
ruleType = RULE_OPACITY;
|
||||
else if (rule.starts_with("plugin:"))
|
||||
ruleType = RULE_PLUGIN;
|
||||
else if (rule.starts_with("pseudo"))
|
||||
ruleType = RULE_PSEUDO;
|
||||
else if (rule.starts_with("size"))
|
||||
ruleType = RULE_SIZE;
|
||||
else if (rule.starts_with("suppressevent"))
|
||||
ruleType = RULE_SUPPRESSEVENT;
|
||||
else if (rule.starts_with("tag"))
|
||||
ruleType = RULE_TAG;
|
||||
else if (rule.starts_with("workspace"))
|
||||
ruleType = RULE_WORKSPACE;
|
||||
else if (rule.starts_with("prop"))
|
||||
ruleType = RULE_PROP;
|
||||
else {
|
||||
// check if this is a prop.
|
||||
const CVarList VARS(rule, 0, 's', true);
|
||||
if (g_pConfigManager->miWindowProperties.find(VARS[0]) != g_pConfigManager->miWindowProperties.end() ||
|
||||
g_pConfigManager->mbWindowProperties.find(VARS[0]) != g_pConfigManager->mbWindowProperties.end() ||
|
||||
g_pConfigManager->mfWindowProperties.find(VARS[0]) != g_pConfigManager->mfWindowProperties.end()) {
|
||||
*const_cast<std::string*>(&szRule) = "prop " + rule;
|
||||
ruleType = RULE_PROP;
|
||||
Debug::log(LOG, "CWindowRule: direct prop rule found, rewritten {} -> {}", rule, szRule);
|
||||
} else {
|
||||
Debug::log(ERR, "CWindowRule: didn't match a rule that was found valid?!");
|
||||
ruleType = RULE_INVALID;
|
||||
}
|
||||
}
|
||||
}
|