Compare commits
1951 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bd541f2fd | ||
|
|
23d00cdd0d | ||
|
|
061241d3a2 | ||
|
|
b9df70be22 | ||
|
|
9583429eae | ||
|
|
747c38112b | ||
|
|
508e82341f | ||
|
|
ec0a38303b | ||
|
|
d0bffc4fa9 | ||
|
|
07a19e2c95 | ||
|
|
46d5b363fa | ||
|
|
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 | ||
|
|
66586c38f5 | ||
|
|
82c67e61a9 | ||
|
|
e45e606fbd | ||
|
|
688fe5c147 | ||
|
|
a3b75559b3 | ||
|
|
df4f222482 | ||
|
|
3b663f4afc | ||
|
|
f634b9e61a | ||
|
|
bdb296a83c | ||
|
|
4fa63104c9 | ||
|
|
a437e44a6a | ||
|
|
cae937c51b | ||
|
|
8162fae377 | ||
|
|
c5786be695 | ||
|
|
1b1ecf77e0 | ||
|
|
883463f9dd | ||
|
|
3e7325af57 | ||
|
|
946ed1f32a | ||
|
|
4eff224a7f | ||
|
|
c86db7bbb0 | ||
|
|
272d904870 | ||
|
|
01e3da4d51 | ||
|
|
33015546c6 | ||
|
|
83d88fa564 | ||
|
|
11dfb8397b | ||
|
|
f4045ab8d0 | ||
|
|
fa12efdd2a | ||
|
|
bf611fbbf3 | ||
|
|
5afc4dc42e | ||
|
|
50348a3ddb | ||
|
|
279ec1c291 | ||
|
|
1006663b6e | ||
|
|
b2a18aa80a | ||
|
|
d21a6b12b8 | ||
|
|
912e7ba82d | ||
|
|
92744b5b9a | ||
|
|
c5feee1e35 | ||
|
|
1840a907a8 | ||
|
|
682b30fba8 | ||
|
|
12d9901472 | ||
|
|
15f942000e | ||
|
|
520e91238f | ||
|
|
0c56be74a3 | ||
|
|
069faa4027 | ||
|
|
c30dfe92ee | ||
|
|
d85ae306c5 | ||
|
|
197f880790 | ||
|
|
3b4aabe04c | ||
|
|
c5ec079c6f | ||
|
|
4aec237ec0 | ||
|
|
39df1f4dbf | ||
|
|
77cf651825 | ||
|
|
c7b72790bd | ||
|
|
3fa6db1e7a | ||
|
|
d361fcbd85 | ||
|
|
df9d830117 | ||
|
|
118d4e1001 | ||
|
|
511eea71c6 | ||
|
|
01ff5fdf6a | ||
|
|
0bf9ceb53b | ||
|
|
4fdc0d55e4 | ||
|
|
8b37e81374 | ||
|
|
fd1d4e288e | ||
|
|
4b4971c06f | ||
|
|
83a334f97d | ||
|
|
9a09eac79b | ||
|
|
2d552fbaa2 | ||
|
|
ea72831541 | ||
|
|
a399f98c68 | ||
|
|
3e00d7dde7 | ||
|
|
d5bc3eb1fa | ||
|
|
99e9cb5107 | ||
|
|
f36c625e37 | ||
|
|
2e3dc17a7e | ||
|
|
b2717cf7fd | ||
|
|
3d82d199f0 | ||
|
|
a05da63d85 | ||
|
|
5b736a4a66 | ||
|
|
fa6ee51367 | ||
|
|
b0a70f63e3 | ||
|
|
d597ae41b9 | ||
|
|
640d161851 | ||
|
|
0e86808e59 | ||
|
|
2b520571e8 | ||
|
|
5dd2c27b63 | ||
|
|
4ae89e1f22 | ||
|
|
51ffd7fa6f | ||
|
|
ae50f8614d | ||
|
|
9f5a57ff45 | ||
|
|
4141e67550 | ||
|
|
be2dfa36ef | ||
|
|
1fa4b7d79b | ||
|
|
592b4a709c | ||
|
|
09bb5658b7 | ||
|
|
ab0a3268e0 | ||
|
|
c8873b958d | ||
|
|
60571cd5cc | ||
|
|
5edfa627b4 | ||
|
|
95959789b7 | ||
|
|
8c02b3c267 | ||
|
|
5b7057c479 | ||
|
|
37e1411e8d | ||
|
|
5489682799 | ||
|
|
e989a0bcff | ||
|
|
8a5f9bbb39 | ||
|
|
3b9b5346b8 | ||
|
|
8ec3dc4c09 | ||
|
|
cc7c117fe7 | ||
|
|
1c221240d0 | ||
|
|
c1afc82a4c | ||
|
|
f3a9f9ec45 | ||
|
|
10e631053a | ||
|
|
46c6efeab3 | ||
|
|
68ee4dda5e | ||
|
|
743e98f0c0 | ||
|
|
e673220340 | ||
|
|
9c38b0fdbe | ||
|
|
60b663e276 | ||
|
|
01560c9d7c | ||
|
|
3a1afb53fd | ||
|
|
23a8f06594 | ||
|
|
70468857da | ||
|
|
87699575e1 | ||
|
|
33e513d489 | ||
|
|
6e6c61b9e8 | ||
|
|
a9d87bd666 | ||
|
|
7df9b01d48 | ||
|
|
256db08aed | ||
|
|
73d09953e8 | ||
|
|
fcff2dcac2 | ||
|
|
3cc2028def | ||
|
|
9b6ae4f77b | ||
|
|
bc86afea7e | ||
|
|
6edfdd63a1 | ||
|
|
04b40ea2ec | ||
|
|
55ceca4cdd | ||
|
|
10e8af00d6 | ||
|
|
ad711ef421 | ||
|
|
ae638d997d | ||
|
|
141cd09bd3 | ||
|
|
0243271544 | ||
|
|
729b47d46d | ||
|
|
84227eb587 | ||
|
|
daed75219f | ||
|
|
ec672b1ab9 | ||
|
|
963816b9a6 | ||
|
|
534fdb5a37 | ||
|
|
682865632f | ||
|
|
76610d9fb0 | ||
|
|
57371b93a0 | ||
|
|
33a5c8ce32 | ||
|
|
a0d15a0b7b | ||
|
|
cd942ad12d | ||
|
|
daf5fad190 | ||
|
|
4beac91cbd | ||
|
|
391f1ae838 | ||
|
|
381cb2d833 | ||
|
|
a0be3de0e8 | ||
|
|
3e543d2ce8 | ||
|
|
735e3c6c56 | ||
|
|
b16fb9770c | ||
|
|
f2b6ebbf54 | ||
|
|
fe19754887 | ||
|
|
72bce7efd5 | ||
|
|
99088eaed8 | ||
|
|
2da3cfb422 | ||
|
|
e2efecc24e | ||
|
|
8a4548e430 | ||
|
|
a5f58a3126 | ||
|
|
077494ee85 | ||
|
|
752604cfe9 | ||
|
|
3c758db95c | ||
|
|
7c68236a51 | ||
|
|
4c3b035162 | ||
|
|
f17f8b219c | ||
|
|
e8374e0792 | ||
|
|
77b134e23b | ||
|
|
87db950189 | ||
|
|
5bae7f150b | ||
|
|
83a5395eaa | ||
|
|
d03fa94c2c | ||
|
|
511e9ccdd1 | ||
|
|
3132f0275e | ||
|
|
1797319a07 | ||
|
|
5979ceb56b | ||
|
|
672bf1f867 | ||
|
|
33e933e2a0 | ||
|
|
341fb4497f | ||
|
|
cbaac6deaf | ||
|
|
3b6bcd6ddc | ||
|
|
e6fc9873b5 | ||
|
|
db1f5cd137 | ||
|
|
928d1dd38a | ||
|
|
faa157e162 | ||
|
|
7f624d2236 | ||
|
|
f7fb7e7e49 | ||
|
|
efcbcd7297 | ||
|
|
043b859ea2 | ||
|
|
cf373d315e | ||
|
|
016da234d0 | ||
|
|
f642fb97df | ||
|
|
9b0993cc49 | ||
|
|
efccf25fcc | ||
|
|
8e15f91c24 | ||
|
|
300228b503 | ||
|
|
293e687389 | ||
|
|
da956c8a97 | ||
|
|
bd526822de | ||
|
|
f442f435d3 | ||
|
|
bc6b0880dd | ||
|
|
ed6c701144 | ||
|
|
45c4898423 | ||
|
|
a770a88e09 | ||
|
|
1f64668953 | ||
|
|
13bc7e1e14 | ||
|
|
7486576fa7 | ||
|
|
f85c6416c6 | ||
|
|
e728e56cbc | ||
|
|
9ff83f4aa9 | ||
|
|
3247d18a7c | ||
|
|
a443902abc | ||
|
|
b03f41efec | ||
|
|
648f824b9e | ||
|
|
22138ac259 | ||
|
|
19fb13e6cf | ||
|
|
ede1e63f69 | ||
|
|
cc98594c3a | ||
|
|
0502c3f62b | ||
|
|
0a6e83005f | ||
|
|
e894d5e964 | ||
|
|
8bb75a223d | ||
|
|
6247a6b537 | ||
|
|
2fa57f2dc4 | ||
|
|
e58fd3bfb0 | ||
|
|
d7ea1b7785 | ||
|
|
4d6f96f74f | ||
|
|
8ff9410d2c | ||
|
|
718afe271e | ||
|
|
1f43a5c859 | ||
|
|
9c5dd59d4b | ||
|
|
d16c6aa1db | ||
|
|
ac11771348 | ||
|
|
f2dc48d92f | ||
|
|
e4d09aa3a9 | ||
|
|
c338acbb7d | ||
|
|
95782de966 | ||
|
|
3ba3d20ad3 | ||
|
|
1d70962892 | ||
|
|
918d8340af | ||
|
|
4f7113972e | ||
|
|
8121e66f34 | ||
|
|
784c0b5ccb | ||
|
|
eef207ce0a | ||
|
|
4dd2b5902e | ||
|
|
cff0123ce6 | ||
|
|
8a68199a0c | ||
|
|
e09addf8de | ||
|
|
315f16d501 | ||
|
|
7f09646ab8 | ||
|
|
0b924f541c | ||
|
|
4778afe2e6 | ||
|
|
fa022901cf | ||
|
|
4a8b13ea4f | ||
|
|
8cf2ca1966 | ||
|
|
fabc30df52 | ||
|
|
d6de248b0d | ||
|
|
c1e21719a2 | ||
|
|
def5fcb212 | ||
|
|
65f04f265c | ||
|
|
6d21014a50 | ||
|
|
20a465f69d | ||
|
|
fb15b7aa2a | ||
|
|
6e5804b53d | ||
|
|
e0e3c4c6ae | ||
|
|
b98e0876d3 | ||
|
|
236150b3c5 | ||
|
|
d1340bd1d8 | ||
|
|
28ce0e0f80 | ||
|
|
a9c7a0830f | ||
|
|
785d062887 | ||
|
|
1360677478 | ||
|
|
14ab0ecc5e | ||
|
|
9cb3bf1cac | ||
|
|
b15be9c77d | ||
|
|
d5ef10abf4 | ||
|
|
172ee1cada | ||
|
|
738530e62e | ||
|
|
069a21a34e | ||
|
|
2031af82fa | ||
|
|
d0a6fa7aa6 | ||
|
|
648ac8a00b | ||
|
|
43c75f17eb | ||
|
|
1b5444494d | ||
|
|
3eaf35f1e2 | ||
|
|
2566d81884 | ||
|
|
1f5fd7e64a | ||
|
|
908bec1564 | ||
|
|
89f795da98 | ||
|
|
91fe58f8f2 | ||
|
|
77f44bfcab | ||
|
|
6c24dc0bb1 | ||
|
|
46ef6653be | ||
|
|
fb82f6bcd7 | ||
|
|
32aca88752 | ||
|
|
df0c014ba0 | ||
|
|
cb63398f07 | ||
|
|
2f278dc883 | ||
|
|
12ce06f39b | ||
|
|
a357fa3e0a | ||
|
|
a9d53a2252 | ||
|
|
b2590b58c5 | ||
|
|
9cd5b3587c | ||
|
|
8055b1c00a | ||
|
|
5de273a144 | ||
|
|
4842eb83b4 | ||
|
|
e6d10539af | ||
|
|
9e781040d9 | ||
|
|
a54f98c203 | ||
|
|
d677ac6f87 | ||
|
|
a9d7befc36 | ||
|
|
0e18da8467 | ||
|
|
18ee9ece9c | ||
|
|
38132ffaf5 | ||
|
|
a99f314106 | ||
|
|
9d7d5ec3c8 | ||
|
|
c7e85e26f7 | ||
|
|
1bae19ce85 | ||
|
|
f687105eff | ||
|
|
32283ed706 | ||
|
|
8412ffcc42 | ||
|
|
b6bf4afb48 | ||
|
|
e1b05f8eaf | ||
|
|
21b9e31bf4 | ||
|
|
1c388e52fb | ||
|
|
8c64a4bad7 | ||
|
|
1f46296ea0 | ||
|
|
809820921d | ||
|
|
90d0097716 | ||
|
|
b17381eb81 | ||
|
|
811429bfd4 | ||
|
|
ea2501d455 | ||
|
|
7ba2c31822 | ||
|
|
cef6aad28f | ||
|
|
89a3c90613 | ||
|
|
b16af45c4a | ||
|
|
1423707dbe | ||
|
|
121c6ac3ea | ||
|
|
722b846ac5 | ||
|
|
4168b8c17b | ||
|
|
1f71d5f5c1 | ||
|
|
bf75723f27 | ||
|
|
c62f0015ae | ||
|
|
9994b73ad0 | ||
|
|
d724556b7e | ||
|
|
7789caad39 | ||
|
|
3fb079a2a3 | ||
|
|
211353dc34 | ||
|
|
10e02076b1 | ||
|
|
5b6d54cae0 | ||
|
|
6967a31450 | ||
|
|
c31d9ef417 | ||
|
|
6b6b02c27a | ||
|
|
40ce17bbbd | ||
|
|
41e1147dfc | ||
|
|
9bc00897fc | ||
|
|
d6337146bb | ||
|
|
429cff340d | ||
|
|
af5f24929d | ||
|
|
c95845b148 | ||
|
|
82099fd1c0 | ||
|
|
155fe6f165 | ||
|
|
fefa55d406 | ||
|
|
098ac916a6 | ||
|
|
d0a224a491 | ||
|
|
5517cc506b | ||
|
|
0ac0f32671 | ||
|
|
b30c7125d7 | ||
|
|
3fd6c1b30e | ||
|
|
eaecf7db14 | ||
|
|
e08195d240 | ||
|
|
66acdfe2ad | ||
|
|
0ebb43c1a3 | ||
|
|
a54ab30160 | ||
|
|
df6ebe358b | ||
|
|
a60c7283e6 | ||
|
|
ebf258788e | ||
|
|
73b133d015 | ||
|
|
722d537a91 | ||
|
|
506d0c06e6 | ||
|
|
546a486bab | ||
|
|
db5d39a66f | ||
|
|
553232a3e4 | ||
|
|
addd3e7f1a | ||
|
|
a71207434c | ||
|
|
71c2ff3105 | ||
|
|
90f262aada | ||
|
|
2ff95bba3f | ||
|
|
ce17961aad | ||
|
|
6d67b84469 | ||
|
|
0d6eae0523 | ||
|
|
52684b7d90 | ||
|
|
4e42107d25 | ||
|
|
eea0a6a704 | ||
|
|
255272ea18 | ||
|
|
df80fbf706 | ||
|
|
25b9446949 | ||
|
|
7ad9116de8 | ||
|
|
62401d5b3f | ||
|
|
3775776a07 | ||
|
|
155ae3721c | ||
|
|
93fea89043 | ||
|
|
e419ef1873 | ||
|
|
3c907f7830 | ||
|
|
4daa5c0658 | ||
|
|
baef55da1d | ||
|
|
f8857e6072 | ||
|
|
c21a5a9340 | ||
|
|
2ead1fd221 | ||
|
|
49485ba36a | ||
|
|
fe23d2b639 | ||
|
|
9518cec833 | ||
|
|
23cd4c7998 | ||
|
|
0cb8fbe18e | ||
|
|
f21b6fe576 | ||
|
|
f91431465b | ||
|
|
a66cfe0fbe | ||
|
|
7173f0c9e7 | ||
|
|
abbe71d26d | ||
|
|
a2643e11a0 | ||
|
|
3ac0e7ead1 | ||
|
|
d693c44836 | ||
|
|
ca0833c9ed | ||
|
|
de9798fcf9 | ||
|
|
7e8c0b7f30 | ||
|
|
9eec4cb670 | ||
|
|
a8522db683 | ||
|
|
b9c58b6e75 | ||
|
|
3fe5280ce9 | ||
|
|
3381e2b55b | ||
|
|
7fbe05a250 | ||
|
|
31890026ea | ||
|
|
94c20a1863 | ||
|
|
3eeaea5be9 | ||
|
|
eed1361f39 | ||
|
|
7eeee2c94e | ||
|
|
fc72df8e58 | ||
|
|
0cfdde3d1a | ||
|
|
121d3a7213 | ||
|
|
4cdddcfe46 | ||
|
|
d0a4a0e0d8 | ||
|
|
1584679004 | ||
|
|
ba69652193 | ||
|
|
47874f09f4 | ||
|
|
60be4298e1 | ||
|
|
4c625ce673 | ||
|
|
064bdb06f1 | ||
|
|
fd35b35000 | ||
|
|
2ccd45a844 | ||
|
|
ff93820bbb | ||
|
|
071f6977df | ||
|
|
c8ae9a2e83 | ||
|
|
cee639d9df | ||
|
|
6be765b7a1 | ||
|
|
33a7b7bb6b | ||
|
|
15072831cf | ||
|
|
8562d38477 | ||
|
|
494b9415a1 | ||
|
|
b6a7fb9e91 | ||
|
|
3529fbc6d4 | ||
|
|
ed3a888fc2 | ||
|
|
a8ab1b1679 | ||
|
|
6e594e4416 | ||
|
|
19186de118 | ||
|
|
38911d6df4 | ||
|
|
37a84c5223 | ||
|
|
c19903eaf8 | ||
|
|
cc4ac52309 | ||
|
|
2549f0cc97 | ||
|
|
3374229118 | ||
|
|
2ba6bb69c4 | ||
|
|
db30ff63e6 | ||
|
|
a7e23d2f1e | ||
|
|
1753059b07 | ||
|
|
b0861b6709 | ||
|
|
7cf810b181 | ||
|
|
51b0da2c0d | ||
|
|
4f26ae70fd | ||
|
|
eeebbc0e7e | ||
|
|
635a02d83f | ||
|
|
85f7f69046 | ||
|
|
fe4737fb9d | ||
|
|
d7aed240db | ||
|
|
c98acaed62 | ||
|
|
67a5377b41 | ||
|
|
84e8d1810d | ||
|
|
ed411f53bd | ||
|
|
e4e84064f2 | ||
|
|
6a988d9276 | ||
|
|
d1ad490cda | ||
|
|
36d32973dd | ||
|
|
70b5e6df70 | ||
|
|
5e7925eaeb | ||
|
|
57a12476de | ||
|
|
601210878d | ||
|
|
22a86fd7a2 | ||
|
|
598bbd186b | ||
|
|
6ccc22194c | ||
|
|
ec092bd601 | ||
|
|
2bcc8d303f | ||
|
|
375e77e398 | ||
|
|
96365309de | ||
|
|
0acad88c3c | ||
|
|
57e76f91d9 | ||
|
|
0c446ec5f4 | ||
|
|
fa69de8ab6 | ||
|
|
05e4a3f1a8 | ||
|
|
a8a04c746b | ||
|
|
cddeec47a1 | ||
|
|
c7fbc30bfd | ||
|
|
1ed1ce9506 | ||
|
|
589f758d94 | ||
|
|
f15513309b | ||
|
|
99aa34db6e | ||
|
|
03ebad3cbf | ||
|
|
aaf35b9f1f | ||
|
|
62eadad20f | ||
|
|
0b215c5f24 | ||
|
|
a3309b51a2 | ||
|
|
cba1ade848 | ||
|
|
c77b60c910 | ||
|
|
c951c4f8a1 | ||
|
|
25964e5a2b | ||
|
|
2d40046f24 | ||
|
|
40201a760a | ||
|
|
a3b4923c42 | ||
|
|
1237732b97 | ||
|
|
1d2acbe193 | ||
|
|
1c73beaf9b | ||
|
|
8a2269272b | ||
|
|
d5bf15387a | ||
|
|
387127b12a | ||
|
|
41cf94faaa | ||
|
|
0623cfabc9 | ||
|
|
2755297670 | ||
|
|
7d49819b5e | ||
|
|
6aa2d123ae | ||
|
|
a3ca016d42 | ||
|
|
eeb78ef965 | ||
|
|
8427824719 | ||
|
|
d0229d6e1e | ||
|
|
56de72f357 | ||
|
|
02bfb2857e | ||
|
|
0237e39f74 | ||
|
|
47b087950d | ||
|
|
8bcccf9f0f | ||
|
|
4ed6b69b68 | ||
|
|
d2899a6c27 | ||
|
|
ed58cc4c31 | ||
|
|
3d09c6d526 | ||
|
|
70ebc3add3 | ||
|
|
a09103cd38 | ||
|
|
dbb8b294d6 | ||
|
|
1f6657f037 | ||
|
|
90e1411315 | ||
|
|
d7a48cf478 | ||
|
|
07e070012b | ||
|
|
801437cd54 | ||
|
|
62ae2b3f40 | ||
|
|
5edc32930d | ||
|
|
5e6f7b1cdb | ||
|
|
f2b03e9679 | ||
|
|
86133983a9 | ||
|
|
39595aaca3 | ||
|
|
a783cd8f40 | ||
|
|
33e0bb1478 | ||
|
|
a5a6480917 | ||
|
|
d20ee31210 | ||
|
|
95a5e75c26 | ||
|
|
335015fe2d | ||
|
|
f7815dab42 | ||
|
|
b164e67d8b | ||
|
|
28c8561924 | ||
|
|
82a6fba6ec | ||
|
|
2e763764bf | ||
|
|
90a53aed59 | ||
|
|
55490637aa | ||
|
|
e400a288d0 | ||
|
|
bca7804bb6 | ||
|
|
25aec3ac8c | ||
|
|
f94264928a | ||
|
|
d9ec2785cb | ||
|
|
1d40af64d3 | ||
|
|
e87227e00a | ||
|
|
faa9017043 | ||
|
|
0652a20bd3 | ||
|
|
9fc3cb5629 | ||
|
|
01df3b73d8 | ||
|
|
ecf282d331 | ||
|
|
72e31d3335 | ||
|
|
3878f806ff | ||
|
|
d86eec332f | ||
|
|
4540d8ccd5 | ||
|
|
d27b5985c1 | ||
|
|
932a0cd777 | ||
|
|
9fe409800b | ||
|
|
8aecd4f253 | ||
|
|
608eff600d | ||
|
|
81bb4eb2f6 | ||
|
|
e5fa0007a5 | ||
|
|
29b0529542 | ||
|
|
0d1bb65c75 | ||
|
|
34413d1f36 | ||
|
|
31d055f6d4 | ||
|
|
d119513749 | ||
|
|
bb4646bbdf | ||
|
|
a2366f78f0 | ||
|
|
cf3596a96d | ||
|
|
4f1214c7e9 | ||
|
|
aab1df50ab | ||
|
|
5fdd0bceac | ||
|
|
5262292abc | ||
|
|
c3ec16f494 | ||
|
|
29308b94ca | ||
|
|
7778f01194 | ||
|
|
da839f20f1 | ||
|
|
855a516596 | ||
|
|
012a2802e0 | ||
|
|
741c75d907 | ||
|
|
dafc9ed4eb | ||
|
|
e91513a5e8 | ||
|
|
450343b7b8 | ||
|
|
e1644e91ea | ||
|
|
cbed4fa5ec | ||
|
|
a4f38a07d7 | ||
|
|
019d4900cb | ||
|
|
448e3208ca | ||
|
|
8afdb8403b | ||
|
|
f041d763ae | ||
|
|
f587c3e0ba | ||
|
|
87173bd09d | ||
|
|
ed69502ff6 | ||
|
|
4954dcbbb3 | ||
|
|
55f1f3fedf | ||
|
|
75c87bde3c | ||
|
|
d9fe1d0f58 | ||
|
|
e823b5d693 | ||
|
|
e69bc5b870 | ||
|
|
f47c89d495 | ||
|
|
93e5d7ca5a | ||
|
|
1ce21fdb3e | ||
|
|
4dc07c4378 | ||
|
|
8ca28dd510 | ||
|
|
9ce9bd9b0f | ||
|
|
7c3bd4c19f | ||
|
|
30e4b404f2 | ||
|
|
a141bbbea5 | ||
|
|
a10a6fff55 | ||
|
|
4ad739ec63 | ||
|
|
1055e6bee6 | ||
|
|
84ee839ca6 | ||
|
|
a945346064 | ||
|
|
ea47e8c92a | ||
|
|
ea95449402 | ||
|
|
5c97b96278 | ||
|
|
10caa03ce5 | ||
|
|
1ebc32f5f4 | ||
|
|
b52a49b4c4 | ||
|
|
1016faea53 | ||
|
|
dd39cd7e42 | ||
|
|
4d0a635237 | ||
|
|
82222342f1 | ||
|
|
78b04c3a76 | ||
|
|
e57a2d7ec8 | ||
|
|
e8e02e81e8 | ||
|
|
fe7b748eb6 | ||
|
|
eeca50e3dc | ||
|
|
9a66514e26 | ||
|
|
32555e98dd | ||
|
|
79a139c949 | ||
|
|
c99803af15 | ||
|
|
02cbf049d2 | ||
|
|
ccbdce7c85 | ||
|
|
3dbf8e936e | ||
|
|
d1c2d524a0 | ||
|
|
2ea367839b | ||
|
|
1719905e7f | ||
|
|
ce4c36392d | ||
|
|
67f47fbdcc | ||
|
|
043a40cd7a | ||
|
|
fd7ea4f27c | ||
|
|
e93fbd7c4f | ||
|
|
83ab0f2d66 | ||
|
|
0634aaeac6 | ||
|
|
61fe47189b | ||
|
|
9e4b2efe7e | ||
|
|
d96501442f | ||
|
|
582d6233c8 | ||
|
|
34396f55a2 | ||
|
|
0c513ba91b | ||
|
|
dd6fdf49d9 | ||
|
|
ddcdb56f2c | ||
|
|
32147f5e91 | ||
|
|
d8d0d3b20b | ||
|
|
382b6d3f6b | ||
|
|
0a70ccd099 | ||
|
|
e1e11f5a87 | ||
|
|
45945a3e7d | ||
|
|
b1a9430289 | ||
|
|
e0a7cf5c30 | ||
|
|
185a3b4881 | ||
|
|
47e5b41fea | ||
|
|
ac0f3411c1 | ||
|
|
abc131ec7b | ||
|
|
558d1be7e3 | ||
|
|
0b2f7a1b2f | ||
|
|
c35fa9bacc | ||
|
|
b573c20125 | ||
|
|
303b9956b2 | ||
|
|
1343aa865d | ||
|
|
f2addfb404 | ||
|
|
fcac25bcc2 | ||
|
|
f6786f04d2 | ||
|
|
c7b87e0aed | ||
|
|
d0d1ba5918 | ||
|
|
a06272ae55 | ||
|
|
277f2bb76a | ||
|
|
0457c2e348 | ||
|
|
125a8f7e07 | ||
|
|
63e3668529 | ||
|
|
db91d949f7 | ||
|
|
785d9d9521 | ||
|
|
43b96f03b5 | ||
|
|
df1a3a978d | ||
|
|
7d989f2cf0 | ||
|
|
863c7b6072 | ||
|
|
c0d283016b | ||
|
|
20899d0df2 | ||
|
|
b50182326c | ||
|
|
89f775aec2 | ||
|
|
d657b59f70 | ||
|
|
f2a848cbcc | ||
|
|
9f1604e4b0 | ||
|
|
e80bccad51 | ||
|
|
ff114cf6f9 | ||
|
|
d846e82832 | ||
|
|
fa79aacea3 | ||
|
|
265c7924d8 | ||
|
|
3d64b0e9f0 | ||
|
|
04d067d78b | ||
|
|
1596e2d1f7 | ||
|
|
6cea710ac8 | ||
|
|
f081a4300f | ||
|
|
159444c45b | ||
|
|
f8c22916ab | ||
|
|
24734fbf1d | ||
|
|
dab149e4a6 | ||
|
|
b5b1c0137d | ||
|
|
094bce8118 | ||
|
|
4909b0f350 | ||
|
|
965a2e5b21 | ||
|
|
f815a33f64 | ||
|
|
0051b078a1 | ||
|
|
1e8f57c734 | ||
|
|
942172d2dc | ||
|
|
baad44b4ca | ||
|
|
12d75c0c26 | ||
|
|
1ae592fcd9 | ||
|
|
51b3148f09 | ||
|
|
1454c6213e | ||
|
|
ec2cc79c65 | ||
|
|
0569b9c300 | ||
|
|
cba9c5ff95 | ||
|
|
c4b660a339 | ||
|
|
4f3e90ad2d | ||
|
|
9b8ef9206d | ||
|
|
846162cce1 | ||
|
|
81766647f2 | ||
|
|
1b43cd5231 | ||
|
|
b7d71bc0e1 | ||
|
|
9cf563065a | ||
|
|
36a8ae9bda | ||
|
|
949eb42613 | ||
|
|
d605e47511 | ||
|
|
10146f5ec5 | ||
|
|
d88d589880 | ||
|
|
93915502d2 | ||
|
|
91061a2084 | ||
|
|
64964c4e3b | ||
|
|
3981f85e94 | ||
|
|
efdc1af044 | ||
|
|
347b839034 | ||
|
|
fbdaf74a82 | ||
|
|
3965faafac | ||
|
|
153c8f35ce | ||
|
|
ef23ef60c5 | ||
|
|
fc0a7af7ba | ||
|
|
05eb2d4af2 | ||
|
|
04a35891a1 | ||
|
|
2e5b146e57 | ||
|
|
af3a61a4e4 | ||
|
|
c377caee7a | ||
|
|
3875679755 | ||
|
|
db1506130b | ||
|
|
108163f1e5 | ||
|
|
7513c0cea5 | ||
|
|
800dbf71b0 | ||
|
|
416b3d6167 | ||
|
|
ef7ac53e99 | ||
|
|
9ae0c47a21 | ||
|
|
ecc1f22e05 | ||
|
|
8cb38d41d2 | ||
|
|
9e8f051896 | ||
|
|
64c8ba2fb1 | ||
|
|
4156b55cf9 | ||
|
|
e1e41e5448 | ||
|
|
16a9c16d9f | ||
|
|
1cc9a44318 | ||
|
|
5e8c25d498 | ||
|
|
1aed45f61d | ||
|
|
77f26997fd | ||
|
|
906e498144 | ||
|
|
a17d7ba87b | ||
|
|
6fb8f50205 | ||
|
|
54376d7b5f | ||
|
|
3d1bf1405e | ||
|
|
53aa184d20 | ||
|
|
fcd9d77b64 | ||
|
|
2930c5cb6f | ||
|
|
d8429eebc6 | ||
|
|
187caf4187 | ||
|
|
647d5a4ffc | ||
|
|
2571875453 | ||
|
|
c24034eb9d | ||
|
|
0869f65b0b | ||
|
|
132ab8d035 | ||
|
|
93d0511471 | ||
|
|
ae52b7f468 | ||
|
|
9b7ae25ae8 | ||
|
|
1a0b8d1263 | ||
|
|
a9d7526aae | ||
|
|
414e37996d | ||
|
|
ae17e900e7 | ||
|
|
ca17a89d86 | ||
|
|
356414639f | ||
|
|
6b28bf563e | ||
|
|
8001b96bb5 | ||
|
|
89543e8e3c | ||
|
|
03e99f93ae | ||
|
|
294ff8609f | ||
|
|
1e82d5a04d | ||
|
|
5cc4bf699c | ||
|
|
acf15e5579 | ||
|
|
86dc46ffea | ||
|
|
09e1128da2 | ||
|
|
432924b372 | ||
|
|
c7fbea3368 | ||
|
|
295128ab2a | ||
|
|
2d5fda4810 | ||
|
|
0d91f82d83 | ||
|
|
059e85ae69 | ||
|
|
0dfdb6678f | ||
|
|
9f2ed02f35 | ||
|
|
8c88689faf | ||
|
|
568b352b23 | ||
|
|
d2b42e29c6 | ||
|
|
461757e2fb | ||
|
|
397e08c16a | ||
|
|
c7c0e795d2 | ||
|
|
9bad62b85f | ||
|
|
a94b902bef | ||
|
|
997ee82bdf | ||
|
|
f1d06b773f | ||
|
|
ee00cb1dd8 | ||
|
|
4c796683c0 | ||
|
|
214ec82ba7 | ||
|
|
bfc95e992d | ||
|
|
d904f51716 | ||
|
|
361357095c | ||
|
|
9ddf1b105e | ||
|
|
95ac8a34b1 | ||
|
|
8593c45be3 | ||
|
|
f6038837bc | ||
|
|
07ab3b8cd6 | ||
|
|
05cd6d3df1 | ||
|
|
c32b2331d1 | ||
|
|
bcba3951f4 | ||
|
|
5c1097cbc1 | ||
|
|
05c84304cc | ||
|
|
7617c03dfd | ||
|
|
e6532ba024 | ||
|
|
7a31c954e5 | ||
|
|
49f5fd59ad | ||
|
|
7283dde878 | ||
|
|
4ffcdc41ff | ||
|
|
4b74123649 | ||
|
|
5eb33ff4d8 | ||
|
|
7587cadd0a | ||
|
|
c34ad12183 | ||
|
|
30c5911718 | ||
|
|
3c21f5e07b | ||
|
|
3ed3b34c4a | ||
|
|
e68c07d809 | ||
|
|
0387528c56 | ||
|
|
0e87a08e15 | ||
|
|
3162739e1b | ||
|
|
e566be7847 | ||
|
|
bd332a79e7 | ||
|
|
c5e28ebcfe | ||
|
|
c942ce6dce | ||
|
|
5e5d7e2abc | ||
|
|
19c90048d6 | ||
|
|
3f5f5f5491 | ||
|
|
2a2da6082e | ||
|
|
c4f52d1979 | ||
|
|
38576d651a | ||
|
|
72d78eff95 | ||
|
|
a958884b52 | ||
|
|
bb933dcf04 | ||
|
|
bc15a8f600 | ||
|
|
6c24cee88f | ||
|
|
d00c658405 | ||
|
|
dc44bd7113 | ||
|
|
045c3fbd85 | ||
|
|
b7b13623ba | ||
|
|
164e92f8e3 | ||
|
|
3e67ee0f5f | ||
|
|
893c55217b | ||
|
|
c58fcfbce2 | ||
|
|
7ea555da7f | ||
|
|
6c53d4d82f | ||
|
|
5da9591775 | ||
|
|
f1ec0ba467 | ||
|
|
a065b481f3 | ||
|
|
0fc9d45e4b | ||
|
|
66330281ff | ||
|
|
220144276b | ||
|
|
0a1632a79f | ||
|
|
981296f101 | ||
|
|
0c28d4e334 | ||
|
|
335506d555 | ||
|
|
b0f98a3d3e | ||
|
|
2ed032a7fd | ||
|
|
739c5bc98c | ||
|
|
26cd1bf949 | ||
|
|
18a35b1406 | ||
|
|
7e41e5146d | ||
|
|
c3882bb832 | ||
|
|
e7a5db4852 | ||
|
|
a01949dd28 | ||
|
|
fa886d8b11 | ||
|
|
3f58e77e75 | ||
|
|
300d77edd9 | ||
|
|
c9ea600baa | ||
|
|
3e930a568a | ||
|
|
024d4ddc74 | ||
|
|
717d5b3cc2 | ||
|
|
0a4ade01d3 | ||
|
|
5920c6a6b8 | ||
|
|
4c34e4aac2 | ||
|
|
d1c80c31c8 | ||
|
|
1290507ac4 | ||
|
|
e52d3fa852 | ||
|
|
ceecdd0fd5 | ||
|
|
6c4e2489a0 | ||
|
|
bf71026b8d | ||
|
|
77161fdbef | ||
|
|
ce072638e9 | ||
|
|
95769a3c54 | ||
|
|
067df84388 | ||
|
|
8e2a62e53b | ||
|
|
669ea8a373 | ||
|
|
082bf00254 | ||
|
|
d6f1b151b2 | ||
|
|
fb87e332c5 | ||
|
|
b1e2ca04a0 | ||
|
|
05dd204c5f | ||
|
|
31e1287da2 | ||
|
|
a4c1f4a03d | ||
|
|
0ee69058c4 | ||
|
|
f8a081b56d | ||
|
|
bdfa8ab856 | ||
|
|
08152477dc | ||
|
|
12985fa0d8 | ||
|
|
9c48c322d4 | ||
|
|
7a76ab01d1 | ||
|
|
f3c92e75c8 | ||
|
|
07c7235b72 | ||
|
|
12da0fc84f | ||
|
|
9d89b7109d | ||
|
|
063708df26 | ||
|
|
8ccbd272cc | ||
|
|
28272d2d74 | ||
|
|
c701767038 | ||
|
|
cc94123fa7 | ||
|
|
2a08f2ba84 | ||
|
|
689fced8b9 | ||
|
|
acf0b536a6 | ||
|
|
1762e9c6ec | ||
|
|
964f1a438d | ||
|
|
508262b7db | ||
|
|
d72ea5f2a7 | ||
|
|
328ab43165 | ||
|
|
d2289d8327 | ||
|
|
be89d6faa9 | ||
|
|
8811f4b69a | ||
|
|
52db216608 | ||
|
|
1e311c947e | ||
|
|
7ce781e87c | ||
|
|
b2c3440477 | ||
|
|
f115ba94d2 | ||
|
|
6e3a494d1d | ||
|
|
555afea73c | ||
|
|
4937352761 | ||
|
|
f590505daf | ||
|
|
f801d15947 | ||
|
|
e63b4b18aa | ||
|
|
1698d336f2 | ||
|
|
fbba8757cb | ||
|
|
6916d0a6a3 | ||
|
|
bcec082a1c | ||
|
|
2e111c8cf9 | ||
|
|
b39dcfa497 | ||
|
|
4bff762d97 | ||
|
|
b1c0f1cc01 | ||
|
|
1e7eb3a5a5 | ||
|
|
097f561e41 | ||
|
|
a31433c215 | ||
|
|
51b1b17fcb | ||
|
|
29cdd7de1f | ||
|
|
4bc669f933 | ||
|
|
f4f3aa2e50 | ||
|
|
c198d744b7 | ||
|
|
1c460e98f8 | ||
|
|
489ac40abd | ||
|
|
e3373669e5 | ||
|
|
f26d7aa58d | ||
|
|
e2c286548d | ||
|
|
60f81b8a23 | ||
|
|
98034fea3c | ||
|
|
21f7f32dc9 | ||
|
|
ffd7217243 | ||
|
|
bc3f5b94eb | ||
|
|
f7a3453487 | ||
|
|
1742605eb8 | ||
|
|
81fe2ae7f1 | ||
|
|
dfcfb92ec6 | ||
|
|
9815402074 | ||
|
|
a14f6b570f | ||
|
|
7f35bff720 | ||
|
|
54a8329936 | ||
|
|
f9cfec8abb | ||
|
|
f534ac3fc4 | ||
|
|
9103af317e | ||
|
|
5824b0f305 | ||
|
|
e9528fc214 | ||
|
|
6f83856025 | ||
|
|
d92da7959a | ||
|
|
f27054c13e | ||
|
|
bdbd8d965d | ||
|
|
bfb1e876a8 | ||
|
|
ca59bd5739 | ||
|
|
f389f77015 | ||
|
|
8c3613632a | ||
|
|
c1ef361e02 | ||
|
|
35e80a64a6 | ||
|
|
e83bf4f7b7 | ||
|
|
c353b7c4f7 | ||
|
|
d9757b61bf | ||
|
|
28410922da | ||
|
|
cfc652e17d | ||
|
|
dbccbabac5 | ||
|
|
9a6956fe67 | ||
|
|
af0c8e299b | ||
|
|
7fbe016c15 | ||
|
|
0ebee80bca | ||
|
|
c4283abb9f | ||
|
|
94aeb06d6b | ||
|
|
ea3fd13e24 | ||
|
|
dad8ffd576 | ||
|
|
fc5ca391ad | ||
|
|
e5eb1bdf01 | ||
|
|
ddf022d61c | ||
|
|
13d9854897 | ||
|
|
cd73dda16e | ||
|
|
02c9a2d769 | ||
|
|
7ea37c9dc9 | ||
|
|
86be75dd97 | ||
|
|
030ed27cc8 | ||
|
|
e793f10b8b | ||
|
|
d62e7a5125 | ||
|
|
fe9c8d8745 | ||
|
|
df82625206 | ||
|
|
1763566308 | ||
|
|
e4790e3f8e | ||
|
|
69a4f08dbe | ||
|
|
c6b1d82c70 | ||
|
|
301b48b740 | ||
|
|
fae47ef462 | ||
|
|
5fc0b772c7 | ||
|
|
13f6f0b923 | ||
|
|
7e8bcd675d | ||
|
|
683a4b07c5 | ||
|
|
5261a8df81 | ||
|
|
289d952a6e | ||
|
|
294e51a857 | ||
|
|
cdcc5aba06 | ||
|
|
e3e7e1fdda | ||
|
|
fbf5ba87ce | ||
|
|
a8dae8f5e1 | ||
|
|
a42b984f51 | ||
|
|
e5ac970d6e | ||
|
|
770956b092 | ||
|
|
3cca36e773 | ||
|
|
ef490965a2 | ||
|
|
b7ab15dc80 | ||
|
|
9c3f3b0018 | ||
|
|
8d68d6bfa5 | ||
|
|
60834a4687 | ||
|
|
7f52db806c | ||
|
|
305b1419c8 | ||
|
|
d5950f7719 | ||
|
|
0608791480 | ||
|
|
2a002f31e4 | ||
|
|
2a3429d4cf | ||
|
|
95abf1220f | ||
|
|
b500e5699b | ||
|
|
61378380ee | ||
|
|
890307532c | ||
|
|
f33d73b9cf | ||
|
|
927da86e3e | ||
|
|
cca3c64301 | ||
|
|
6e5c78bf63 | ||
|
|
e4bb5fa4af | ||
|
|
cb258c82f4 | ||
|
|
658f718fa3 | ||
|
|
334a0f03ee | ||
|
|
289d4241be | ||
|
|
a6ccd36147 | ||
|
|
3d9ca6381d | ||
|
|
f085ed4454 | ||
|
|
ded174d6e5 | ||
|
|
181f651de2 | ||
|
|
8a6e428d32 | ||
|
|
1fd82e37a7 | ||
|
|
f9202f791e | ||
|
|
84ab8d11e8 | ||
|
|
60bda7ee3d | ||
|
|
939696f97e | ||
|
|
cbadf3e3f3 | ||
|
|
1ed4f1cb25 | ||
|
|
5d4ff60f53 | ||
|
|
504ebe1b37 | ||
|
|
cf1886ca44 | ||
|
|
341e04a36c | ||
|
|
d7514412d8 | ||
|
|
7447be8220 | ||
|
|
4644de2269 | ||
|
|
3656045ad8 | ||
|
|
15316aaa31 | ||
|
|
cfd68af5b6 | ||
|
|
4f804d5f96 | ||
|
|
e6f7724ab0 | ||
|
|
e65f52bf2d | ||
|
|
c51b3fb06f | ||
|
|
3ff59e7e1d | ||
|
|
3d0d3b6343 | ||
|
|
2e3f0d5991 | ||
|
|
91e8c42843 | ||
|
|
4b4bd90b14 | ||
|
|
7009dc9184 | ||
|
|
b7840c6461 | ||
|
|
5a90911b70 | ||
|
|
0e5f14d8d2 | ||
|
|
df990c80e2 | ||
|
|
352574d862 | ||
|
|
bfcc2adbda | ||
|
|
9002657bcc | ||
|
|
3e93fdf779 | ||
|
|
bc7e488a4c | ||
|
|
8b1069b330 | ||
|
|
61fd75b55e | ||
|
|
7b3d039388 | ||
|
|
12d79d6342 | ||
|
|
08e3519747 | ||
|
|
5cd7e4587e | ||
|
|
72987dee88 | ||
|
|
754eaf5b8b | ||
|
|
df17991b1c | ||
|
|
791e1b96b3 | ||
|
|
02b4a9bded | ||
|
|
4d403dac32 | ||
|
|
f40e382fc6 | ||
|
|
b86ed02d8a | ||
|
|
17339e0ae9 | ||
|
|
5eeec8860e | ||
|
|
9f20a15955 | ||
|
|
c4365f20ed | ||
|
|
307dd8f511 | ||
|
|
8342bac697 | ||
|
|
3c964a9fdc | ||
|
|
f14c5ea5c5 | ||
|
|
dcd7a92b01 | ||
|
|
b6516bad02 | ||
|
|
13d9a637d6 | ||
|
|
4cee94b91c | ||
|
|
c4da4b026d | ||
|
|
babb9c07b0 | ||
|
|
6b92144f15 | ||
|
|
8d31c84483 | ||
|
|
d484506600 | ||
|
|
b240704bee | ||
|
|
71166ef40b | ||
|
|
252aaaecfa | ||
|
|
f92a86af53 | ||
|
|
2ba2c8aeee | ||
|
|
955009655d | ||
|
|
d7d333d162 | ||
|
|
f5b2fd2bc3 | ||
|
|
44ee9915e3 | ||
|
|
9f2bde925b | ||
|
|
7904188de9 | ||
|
|
666ee61c13 | ||
|
|
7e033e48ac | ||
|
|
d8dbdc4a01 | ||
|
|
d3acf8da3b | ||
|
|
aeeeace102 | ||
|
|
880996b053 | ||
|
|
4d6d662c67 | ||
|
|
1512b81126 | ||
|
|
4f26c4e1eb | ||
|
|
3c33d4b9dd | ||
|
|
bd3ea8dcb5 | ||
|
|
813af393f1 | ||
|
|
583b05a8c6 | ||
|
|
1607e96704 | ||
|
|
1a4f23eb2f | ||
|
|
42ab06e7c8 | ||
|
|
46753b1f22 | ||
|
|
d4e68ab602 | ||
|
|
37b76cd1ca | ||
|
|
0be36cd02d | ||
|
|
4e0e8d933e | ||
|
|
c7ba460687 | ||
|
|
3a189c265d | ||
|
|
069880e374 | ||
|
|
fa5e812304 | ||
|
|
33444e1e5e | ||
|
|
03ebbe18ed | ||
|
|
7c1ac58a4b | ||
|
|
46997a7643 | ||
|
|
b5b025a1ed | ||
|
|
94d6b2d2c1 | ||
|
|
33fe3a2e7f | ||
|
|
2ad2e1d5f5 | ||
|
|
5f8e4068e5 | ||
|
|
78f9ba9fdd | ||
|
|
9242b03317 | ||
|
|
f9c13b614c | ||
|
|
ddf8e01c1e | ||
|
|
f771c10d1a | ||
|
|
8321d6be46 | ||
|
|
cedf5f1fca | ||
|
|
9fba887cc9 | ||
|
|
4f3ee4c645 | ||
|
|
5f65946c84 | ||
|
|
6a93cee74e | ||
|
|
07132741bc | ||
|
|
e5eb11ad04 | ||
|
|
e75dafd8b2 | ||
|
|
b7e8110a30 | ||
|
|
2702814a3f | ||
|
|
f86cdcf8d5 | ||
|
|
85d375e8ab | ||
|
|
6cd82d948f | ||
|
|
1ecd173c7a | ||
|
|
7474c81958 | ||
|
|
191fa587f4 | ||
|
|
9fb50252d3 | ||
|
|
bfb4d66c81 | ||
|
|
34b0ce66b3 | ||
|
|
2c2ff4b61b | ||
|
|
4f99e805b9 | ||
|
|
e2d04ae503 | ||
|
|
b25b06430b | ||
|
|
5aab4a96e3 | ||
|
|
ff75f991a5 | ||
|
|
f013acc6ee | ||
|
|
d5811283d2 | ||
|
|
5c7e23f86b | ||
|
|
b9c1414f25 | ||
|
|
cc0516a9ae | ||
|
|
6c8e0f9863 | ||
|
|
6b6f3396cf | ||
|
|
79ef29d6e0 | ||
|
|
c416880cf9 | ||
|
|
37d2840246 | ||
|
|
7cec618fe4 | ||
|
|
bd952dcef2 | ||
|
|
bc51a91043 | ||
|
|
698f3b6576 | ||
|
|
79f3888b4b | ||
|
|
4eb42fab7b | ||
|
|
48ecb13b14 | ||
|
|
a197fe3c11 | ||
|
|
53c78ab906 | ||
|
|
b4f4bd38e8 | ||
|
|
d1b8a63a8e | ||
|
|
3771c49a94 | ||
|
|
d9b74ff96b | ||
|
|
ef445093f9 | ||
|
|
11fd37418c | ||
|
|
0c74df4f9e | ||
|
|
460a326c90 | ||
|
|
403fd7d9f6 | ||
|
|
763d5fa05f | ||
|
|
9fd928e114 | ||
|
|
bf7374011b | ||
|
|
8c9f38e405 | ||
|
|
c0d9dcc586 | ||
|
|
2a777cb71b | ||
|
|
9ca0c7d814 | ||
|
|
b1b8d732e6 | ||
|
|
4e5d9b90c0 | ||
|
|
e1ed8e11ca | ||
|
|
79d8d14fe0 | ||
|
|
395ab3ba37 | ||
|
|
36fa33f7ca | ||
|
|
f7cde9c92c | ||
|
|
01e5c59d75 | ||
|
|
b2e5a80e2f | ||
|
|
55cb565e6d | ||
|
|
4190b96718 | ||
|
|
d9bc210285 | ||
|
|
4de986072c | ||
|
|
934112af5b | ||
|
|
ba2af6f86d | ||
|
|
1950c3fc9c | ||
|
|
8f38487884 | ||
|
|
accb3d8d0b | ||
|
|
ea7569d7e0 | ||
|
|
e53134ca90 | ||
|
|
8191e635a3 | ||
|
|
0fdf909b19 | ||
|
|
50648e6bae | ||
|
|
53ce7992be | ||
|
|
167f2ed3b2 | ||
|
|
d02ba422da | ||
|
|
359baa0214 | ||
|
|
efdf07e295 | ||
|
|
0c10b8ab2d | ||
|
|
9f5b9053c6 | ||
|
|
b3dc58e104 | ||
|
|
af6aae4e12 | ||
|
|
0ebbf371ff | ||
|
|
89d8f665b5 | ||
|
|
9132660768 | ||
|
|
dd0714c22a | ||
|
|
11d1c50420 | ||
|
|
288f1863f0 | ||
|
|
6fb1b89b98 | ||
|
|
004bf94a23 | ||
|
|
aa020a2a1a | ||
|
|
d9175a0181 | ||
|
|
a794eecd6a | ||
|
|
d360550546 | ||
|
|
62a8d0be5c | ||
|
|
4a42344e97 | ||
|
|
5489f9f07a | ||
|
|
d74607e414 | ||
|
|
c4bd91ec8a | ||
|
|
03c6f4506a | ||
|
|
13b4c6de86 | ||
|
|
8bd86cf37e | ||
|
|
cfd94c5b30 | ||
|
|
ab66fa430e | ||
|
|
37d7a8c64d | ||
|
|
da863459c4 | ||
|
|
83248b6936 | ||
|
|
3bb9c7c5cf | ||
|
|
2d04cb1cc6 | ||
|
|
c6804ccaab | ||
|
|
aa46aaed04 | ||
|
|
68783d904d | ||
|
|
5d100bdcbb | ||
|
|
45d3fbb8d8 | ||
|
|
9a9528d093 | ||
|
|
e496b0f250 | ||
|
|
dc2082b00a | ||
|
|
59cb0e20de | ||
|
|
80b9b21f9f | ||
|
|
758cf90ea1 | ||
|
|
6e8b9ef7d8 | ||
|
|
9c09f2a847 | ||
|
|
8440a30231 | ||
|
|
ab40f240c3 | ||
|
|
b394c1695c | ||
|
|
0a4c4da5f0 | ||
|
|
b2f3623131 | ||
|
|
5513eed64d | ||
|
|
29970228c5 | ||
|
|
12ec549a18 | ||
|
|
9f2027be4b | ||
|
|
b9937484f4 | ||
|
|
776f944619 | ||
|
|
1fc1e4e9cb | ||
|
|
e1258707ad | ||
|
|
d2c3b23ace | ||
|
|
b80c72c7dd | ||
|
|
3caaa483d4 | ||
|
|
e2f18f8c7f | ||
|
|
99ca26d4eb | ||
|
|
e416ab740d | ||
|
|
7a0a5666d5 | ||
|
|
1778fb77e2 | ||
|
|
adeb20ea11 | ||
|
|
68e57b7ee3 | ||
|
|
408d96668d | ||
|
|
75e5799310 | ||
|
|
9e2b939024 | ||
|
|
cd96ceecc5 | ||
|
|
ad3f688648 | ||
|
|
98c7ba4782 | ||
|
|
a5f64b48ca | ||
|
|
b281d8647a | ||
|
|
15b282ee0c | ||
|
|
6f733292bf | ||
|
|
3fe6162af1 | ||
|
|
2ce4b94a22 | ||
|
|
de95e956a0 | ||
|
|
929c44e361 | ||
|
|
512a59731b | ||
|
|
a6eba91935 | ||
|
|
745b998587 | ||
|
|
1a2a2da6aa | ||
|
|
822775aa8c | ||
|
|
d79cf0afe2 | ||
|
|
334d0ae31b | ||
|
|
be3d635265 | ||
|
|
f9ba5a0551 | ||
|
|
258c83f3bb | ||
|
|
aedcade68d | ||
|
|
802ab58f8a | ||
|
|
af5d06593f | ||
|
|
2ebfd0c745 | ||
|
|
e40e486f61 | ||
|
|
e55c5a916a | ||
|
|
45ebe0df8f | ||
|
|
812a3f6d78 | ||
|
|
44accacff9 | ||
|
|
d417370bb7 | ||
|
|
4729265284 | ||
|
|
572fd554b8 | ||
|
|
7d1c8d827a | ||
|
|
6d26199e1c | ||
|
|
646f4bc638 | ||
|
|
7e0c90b92c | ||
|
|
add23a9ba2 | ||
|
|
3d89654254 | ||
|
|
6ad5f26cfe | ||
|
|
89f6457a99 | ||
|
|
8b57a1973e | ||
|
|
483302a2cd | ||
|
|
a903dba858 | ||
|
|
395985f815 | ||
|
|
51282f964f | ||
|
|
db8f13291a | ||
|
|
30ad71ff36 | ||
|
|
84bc0a73f6 | ||
|
|
1d9bfa60a1 | ||
|
|
a34e192433 | ||
|
|
4868d4dfd3 | ||
|
|
859841f4d1 | ||
|
|
28ef18a921 | ||
|
|
91d6be1f09 | ||
|
|
9e3dccca76 | ||
|
|
81598b3dbd | ||
|
|
e195e51c1b | ||
|
|
e8469f8b1b | ||
|
|
49597688e9 | ||
|
|
5edb4e4a30 | ||
|
|
4d6fa6ed0c | ||
|
|
016a7a9c9b | ||
|
|
2e26542e3b | ||
|
|
68935ba9dc | ||
|
|
ba5bc5871f | ||
|
|
824ccd957b | ||
|
|
45e86d4fdf | ||
|
|
0ba2e68704 | ||
|
|
e974d1fe98 | ||
|
|
47d46aa56c | ||
|
|
65efde32c9 | ||
|
|
69e314207d | ||
|
|
1bfd4a2bff | ||
|
|
91cbe93cf8 | ||
|
|
9afdd61ade | ||
|
|
f39a6ca17c | ||
|
|
eab2799842 | ||
|
|
6eb2abcb20 | ||
|
|
ae46fbafe5 | ||
|
|
52cf122a0a | ||
|
|
844da8db56 | ||
|
|
db82fc5b09 | ||
|
|
8180ca65a5 | ||
|
|
bea828ea45 | ||
|
|
c5d1faf72d | ||
|
|
cc04b52ce1 | ||
|
|
9b5e2e71e0 | ||
|
|
9be6fbf5ea | ||
|
|
7345b1a1ea | ||
|
|
e44d6de555 | ||
|
|
427153e86a | ||
|
|
1e6e9b66a5 | ||
|
|
92cb44ddb2 | ||
|
|
b8a615ffb8 | ||
|
|
8dd02eb5f3 | ||
|
|
14195835ef | ||
|
|
11432f69b9 | ||
|
|
da6fa9cbd2 | ||
|
|
c619e6976f |
1
.clang-format-ignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
subprojects/**/*
|
||||||
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
|
||||||
57
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -2,30 +2,49 @@ name: Bug Report
|
|||||||
description: Something is not working right
|
description: Something is not working right
|
||||||
labels: ["bug"]
|
labels: ["bug"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: checkboxes
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
label: Already reported ? *
|
||||||
Before opening a new issue, take a moment to search through the current open ones.
|
description: Before opening a new bug report, please take a moment to search through the current open and closed issues to check if it already exists.
|
||||||
|
options:
|
||||||
---
|
- label: I have searched the existing open and closed issues.
|
||||||
|
|
||||||
- type: input
|
|
||||||
id: ver
|
|
||||||
attributes:
|
|
||||||
label: Hyprland Version
|
|
||||||
description: "Paste here the output of `hyprctl version`."
|
|
||||||
placeholder: Hyprland, built from branch main at commit...
|
|
||||||
validations:
|
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: type
|
id: type
|
||||||
attributes:
|
attributes:
|
||||||
label: Bug or Regression?
|
label: Regression?
|
||||||
description: Is this a bug or a regression?
|
description: |
|
||||||
|
Regression means that something used to work but no longer does.
|
||||||
|
**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:
|
options:
|
||||||
- Bug
|
- "Yes"
|
||||||
- Regression
|
- "No"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: ver
|
||||||
|
attributes:
|
||||||
|
label: System Info and Version
|
||||||
|
description: |
|
||||||
|
Paste the output of `hyprctl systeminfo -c` here. If you can't
|
||||||
|
launch Hyprland, paste the output of `Hyprland --systeminfo`.
|
||||||
|
If `Hyprland --systeminfo` errors out (added in 0.44.0), find
|
||||||
|
and paste the Hyprland version manually.
|
||||||
|
value: "<details>
|
||||||
|
<summary>System/Version info</summary>
|
||||||
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
|
||||||
|
<Paste the output of the command here>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
</details>"
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
@@ -51,6 +70,6 @@ body:
|
|||||||
label: Crash reports, logs, images, videos
|
label: Crash reports, logs, images, videos
|
||||||
description: |
|
description: |
|
||||||
Anything that can help. Please always ATTACH and not paste them.
|
Anything that can help. Please always ATTACH and not paste them.
|
||||||
Logs can be found in /tmp/hypr
|
Logs can be found in $XDG_RUNTIME_DIR/hypr
|
||||||
Crash reports are stored in ~/.hyprland or $XDG_CACHE_HOME/hyprland
|
Crash reports are stored in ~/.cache/hyprland or $XDG_CACHE_HOME/hyprland
|
||||||
|
|
||||||
|
|||||||
110
.github/actions/setup_base/action.yml
vendored
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
name: "Setup base"
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
INSTALL_XORG_PKGS:
|
||||||
|
description: 'Install xorg dependencies'
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Get required pacman pkgs
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
||||||
|
pacman --noconfirm --noprogressbar -Syyu
|
||||||
|
pacman --noconfirm --noprogressbar -Sy \
|
||||||
|
base-devel \
|
||||||
|
cairo \
|
||||||
|
clang \
|
||||||
|
cmake \
|
||||||
|
git \
|
||||||
|
glm \
|
||||||
|
glslang \
|
||||||
|
go \
|
||||||
|
hyprlang \
|
||||||
|
hyprcursor \
|
||||||
|
jq \
|
||||||
|
libc++ \
|
||||||
|
libdisplay-info \
|
||||||
|
libdrm \
|
||||||
|
libepoxy \
|
||||||
|
libfontenc \
|
||||||
|
libglvnd \
|
||||||
|
libinput \
|
||||||
|
libjxl \
|
||||||
|
libliftoff \
|
||||||
|
libwebp \
|
||||||
|
libxcursor \
|
||||||
|
libxcvt \
|
||||||
|
libxfont2 \
|
||||||
|
libxkbcommon \
|
||||||
|
libxkbfile \
|
||||||
|
lld \
|
||||||
|
meson \
|
||||||
|
ninja \
|
||||||
|
pango \
|
||||||
|
pixman \
|
||||||
|
pkgconf \
|
||||||
|
pugixml \
|
||||||
|
scdoc \
|
||||||
|
seatd \
|
||||||
|
systemd \
|
||||||
|
tomlplusplus \
|
||||||
|
wayland \
|
||||||
|
wayland-protocols \
|
||||||
|
xcb-util-errors \
|
||||||
|
xcb-util-renderutil \
|
||||||
|
xcb-util-wm \
|
||||||
|
xcb-util \
|
||||||
|
xcb-util-image \
|
||||||
|
libzip \
|
||||||
|
librsvg \
|
||||||
|
re2
|
||||||
|
|
||||||
|
- name: Get hyprwayland-scanner-git
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/hyprwm/hyprwayland-scanner --recursive
|
||||||
|
cd hyprwayland-scanner
|
||||||
|
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 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: |
|
||||||
|
git clone https://github.com/hyprwm/hyprutils && cd hyprutils && cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -B build && cmake --build build --target hyprutils && cmake --install build
|
||||||
|
|
||||||
|
- name: Get aquamarine-git
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/hyprwm/aquamarine && cd aquamarine && cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -B build && cmake --build build --target aquamarine && cmake --install build
|
||||||
|
|
||||||
|
- name: Get Xorg pacman pkgs
|
||||||
|
shell: bash
|
||||||
|
if: inputs.INSTALL_XORG_PKGS == 'true'
|
||||||
|
run: |
|
||||||
|
pacman --noconfirm --noprogressbar -Sy \
|
||||||
|
xorg-fonts-encodings \
|
||||||
|
xorg-server-common \
|
||||||
|
xorg-setxkbmap \
|
||||||
|
xorg-xkbcomp \
|
||||||
|
xorg-xwayland
|
||||||
|
|
||||||
|
- name: Checkout Hyprland
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
# Fix an issue with actions/checkout where the checkout repo is not mark as safe
|
||||||
|
- name: Mark directory as safe for git
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory /__w/Hyprland/Hyprland
|
||||||
83
.github/labeler.yml
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
assets:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "assets/**"
|
||||||
|
|
||||||
|
docs:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "docs/**"
|
||||||
|
|
||||||
|
hyprctl:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "hyprctl/**"
|
||||||
|
|
||||||
|
hyprpm:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "hyprpm/**"
|
||||||
|
|
||||||
|
nix:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "nix/**"
|
||||||
|
|
||||||
|
protocols:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: ["protocols/**", "src/protocols/**"]
|
||||||
|
|
||||||
|
core:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/**"
|
||||||
|
|
||||||
|
config:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/config/**"
|
||||||
|
|
||||||
|
debug:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/debug/**"
|
||||||
|
|
||||||
|
desktop:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/desktop/**"
|
||||||
|
|
||||||
|
devices:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/devices/**"
|
||||||
|
|
||||||
|
events:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/events/**"
|
||||||
|
|
||||||
|
helpers:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/helpers/**"
|
||||||
|
|
||||||
|
hyprerror:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/hyprerror/**"
|
||||||
|
|
||||||
|
init:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/init/**"
|
||||||
|
|
||||||
|
layout:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/layout/**"
|
||||||
|
|
||||||
|
managers:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/managers/**"
|
||||||
|
|
||||||
|
pch:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/pch/**"
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/plugins/**"
|
||||||
|
|
||||||
|
render:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/render/**"
|
||||||
|
|
||||||
|
xwayland:
|
||||||
|
- changed-files:
|
||||||
|
- any-glob-to-any-file: "src/xwayland/**"
|
||||||
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?
|
#### Describe your PR, what does it fix/add?
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
130
.github/workflows/ci.yaml
vendored
@@ -3,34 +3,26 @@ name: Build Hyprland
|
|||||||
on: [push, pull_request, workflow_dispatch]
|
on: [push, pull_request, workflow_dispatch]
|
||||||
jobs:
|
jobs:
|
||||||
gcc:
|
gcc:
|
||||||
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
||||||
name: "Build Hyprland (Arch)"
|
name: "Build Hyprland (Arch)"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: archlinux
|
image: archlinux
|
||||||
steps:
|
steps:
|
||||||
- name: Get required pacman pkgs
|
- name: Checkout repository actions
|
||||||
run: |
|
uses: actions/checkout@v4
|
||||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
|
||||||
pacman --noconfirm --noprogressbar -Syyu
|
|
||||||
pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers xcb-util-errors xcb-util-renderutil xcb-util-wm xorg-fonts-encodings xorg-server-common xorg-setxkbmap xorg-xkbcomp xorg-xwayland git cmake go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd python libliftoff
|
|
||||||
- name: Set up user
|
|
||||||
run: |
|
|
||||||
useradd -m githubuser
|
|
||||||
echo -e "root ALL=(ALL:ALL) ALL\ngithubuser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
|
|
||||||
- name: Install libdisplay-info from the AUR
|
|
||||||
run: |
|
|
||||||
su githubuser -c "cd ~ && git clone https://aur.archlinux.org/libdisplay-info.git && cd ./libdisplay-info && makepkg -si --skippgpcheck --noconfirm --noprogressbar"
|
|
||||||
- name: Fix permissions for git
|
|
||||||
run: |
|
|
||||||
git config --global --add safe.directory /__w/Hyprland/Hyprland
|
|
||||||
- name: Checkout Hyprland
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
sparse-checkout: .github/actions
|
||||||
|
|
||||||
|
- name: Setup base
|
||||||
|
uses: ./.github/actions/setup_base
|
||||||
|
with:
|
||||||
|
INSTALL_XORG_PKGS: true
|
||||||
|
|
||||||
- name: Build Hyprland
|
- name: Build Hyprland
|
||||||
run: |
|
run: |
|
||||||
git submodule sync --recursive && git submodule update --init --force --recursive
|
|
||||||
make all
|
make all
|
||||||
|
|
||||||
- name: Compress and package artifacts
|
- name: Compress and package artifacts
|
||||||
run: |
|
run: |
|
||||||
mkdir x86_64-pc-linux-gnu
|
mkdir x86_64-pc-linux-gnu
|
||||||
@@ -40,69 +32,97 @@ jobs:
|
|||||||
cp ./LICENSE hyprland/
|
cp ./LICENSE hyprland/
|
||||||
cp build/Hyprland hyprland/
|
cp build/Hyprland hyprland/
|
||||||
cp build/hyprctl/hyprctl hyprland/
|
cp build/hyprctl/hyprctl hyprland/
|
||||||
cp subprojects/wlroots/build/libwlroots.so.12032 hyprland/
|
cp build/hyprpm/hyprpm hyprland/
|
||||||
cp build/Hyprland hyprland/
|
cp build/Hyprland hyprland/
|
||||||
cp -r example/ hyprland/
|
cp -r example/ hyprland/
|
||||||
cp -r assets/ hyprland/
|
cp -r assets/ hyprland/
|
||||||
tar -cvf Hyprland.tar.xz hyprland
|
tar -cvf Hyprland.tar.xz hyprland
|
||||||
|
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: Build archive
|
name: Build archive
|
||||||
path: Hyprland.tar.xz
|
path: Hyprland.tar.xz
|
||||||
|
|
||||||
meson:
|
meson:
|
||||||
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
||||||
name: "Build Hyprland with Meson (Arch)"
|
name: "Build Hyprland with Meson (Arch)"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: archlinux
|
image: archlinux
|
||||||
steps:
|
steps:
|
||||||
- name: Download dependencies
|
- name: Checkout repository actions
|
||||||
run: |
|
uses: actions/checkout@v4
|
||||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
|
||||||
pacman --noconfirm --noprogressbar -Syyu
|
|
||||||
pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers git go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd cmake jq python libliftoff
|
|
||||||
- name: Set up user
|
|
||||||
run: |
|
|
||||||
useradd -m githubuser
|
|
||||||
echo -e "root ALL=(ALL:ALL) ALL\ngithubuser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
|
|
||||||
- name: Install libdisplay-info from the AUR
|
|
||||||
run: |
|
|
||||||
su githubuser -c "cd ~ && git clone https://aur.archlinux.org/libdisplay-info.git && cd ./libdisplay-info && makepkg -si --skippgpcheck --noconfirm --noprogressbar"
|
|
||||||
- name: Checkout Hyprland
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
with:
|
||||||
submodules: true
|
sparse-checkout: .github/actions
|
||||||
|
|
||||||
|
- name: Setup base
|
||||||
|
uses: ./.github/actions/setup_base
|
||||||
|
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: |
|
run: meson setup build -Ddefault_library=static
|
||||||
meson obj-x86_64-pc-linux-gnu \
|
|
||||||
-Ddefault_library=static
|
|
||||||
- name: Compile
|
- name: Compile
|
||||||
run: ninja -C obj-x86_64-pc-linux-gnu
|
run: ninja -C build
|
||||||
|
|
||||||
|
no-pch:
|
||||||
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
||||||
|
name: "Build Hyprland without precompiled headers (Arch)"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: archlinux
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository actions
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
sparse-checkout: .github/actions
|
||||||
|
|
||||||
|
- name: Setup base
|
||||||
|
uses: ./.github/actions/setup_base
|
||||||
|
with:
|
||||||
|
INSTALL_XORG_PKGS: true
|
||||||
|
|
||||||
|
- name: Compile
|
||||||
|
run: make nopch
|
||||||
|
|
||||||
noxwayland:
|
noxwayland:
|
||||||
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
||||||
name: "Build Hyprland in pure Wayland (Arch)"
|
name: "Build Hyprland in pure Wayland (Arch)"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: archlinux
|
image: archlinux
|
||||||
steps:
|
steps:
|
||||||
- name: Download dependencies
|
- name: Checkout repository actions
|
||||||
run: |
|
uses: actions/checkout@v4
|
||||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
|
||||||
pacman --noconfirm --noprogressbar -Syyu
|
|
||||||
pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers git cmake go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd libliftoff
|
|
||||||
- name: Set up user
|
|
||||||
run: |
|
|
||||||
useradd -m githubuser
|
|
||||||
echo -e "root ALL=(ALL:ALL) ALL\ngithubuser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
|
|
||||||
- name: Install libdisplay-info from the AUR
|
|
||||||
run: |
|
|
||||||
su githubuser -c "cd ~ && git clone https://aur.archlinux.org/libdisplay-info.git && cd ./libdisplay-info && makepkg -si --skippgpcheck --noconfirm --noprogressbar"
|
|
||||||
- name: Checkout Hyprland
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
with:
|
||||||
submodules: true
|
sparse-checkout: .github/actions
|
||||||
|
|
||||||
|
- name: Setup base
|
||||||
|
uses: ./.github/actions/setup_base
|
||||||
|
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DNO_XWAYLAND:STRING=true -H./ -B./build -G Ninja
|
run: mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DNO_XWAYLAND:STRING=true -H./ -B./build -G Ninja
|
||||||
|
|
||||||
- name: Compile
|
- name: Compile
|
||||||
run: make release
|
run: make release
|
||||||
|
|
||||||
|
clang-format:
|
||||||
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
||||||
|
name: "Code Style (Arch)"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: archlinux
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository actions
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
sparse-checkout: .github/actions
|
||||||
|
|
||||||
|
- name: Setup base
|
||||||
|
uses: ./.github/actions/setup_base
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
run: meson setup build -Ddefault_library=static
|
||||||
|
|
||||||
|
- name: clang-format check
|
||||||
|
run: ninja -C build clang-format-check
|
||||||
|
|||||||
12
.github/workflows/labeler.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
name: "Pull Request Labeler"
|
||||||
|
on:
|
||||||
|
- pull_request_target
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
labeler:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/labeler@v5
|
||||||
4
.github/workflows/man-update.yaml
vendored
@@ -17,14 +17,14 @@ jobs:
|
|||||||
run: sudo apt install pandoc
|
run: sudo apt install pandoc
|
||||||
|
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
|
|
||||||
- name: Build man pages
|
- name: Build man pages
|
||||||
run: make man
|
run: make man
|
||||||
|
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
- uses: stefanzweifel/git-auto-commit-action@v5
|
||||||
name: Commit
|
name: Commit
|
||||||
with:
|
with:
|
||||||
commit_message: "[gha] build man pages"
|
commit_message: "[gha] build man pages"
|
||||||
|
|||||||
17
.github/workflows/nix-build.yml
vendored
@@ -1,3 +1,5 @@
|
|||||||
|
name: Nix (Build)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
secrets:
|
secrets:
|
||||||
@@ -10,21 +12,18 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
package:
|
package:
|
||||||
- hyprland
|
- hyprland
|
||||||
- hyprland-nvidia
|
# - hyprland-cross # cross compiling fails due to qt
|
||||||
|
# failure chain: hyprland-qtutils -> qt6.qtsvg -> qt6.qtbase -> psqlodbc & qt6.qttranslations
|
||||||
- xdg-desktop-portal-hyprland
|
- xdg-desktop-portal-hyprland
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
ref: ${{ github.ref }}
|
|
||||||
|
|
||||||
- uses: DeterminateSystems/nix-installer-action@main
|
- uses: DeterminateSystems/nix-installer-action@main
|
||||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||||
- uses: cachix/cachix-action@v12
|
|
||||||
|
- uses: cachix/cachix-action@v15
|
||||||
with:
|
with:
|
||||||
name: hyprland
|
name: hyprland
|
||||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
- run: nix build -L ${{ matrix.command }}
|
- run: nix build 'github:hyprwm/Hyprland?ref=${{ github.ref }}#${{ matrix.package }}' -L --extra-substituters "https://hyprland.cachix.org"
|
||||||
|
|||||||
11
.github/workflows/nix-ci.yml
vendored
@@ -1,15 +1,14 @@
|
|||||||
name: Nix
|
name: Nix (CI)
|
||||||
|
|
||||||
on: [push, pull_request, workflow_dispatch]
|
on: [push, pull_request, workflow_dispatch]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
wlroots:
|
update-inputs:
|
||||||
if: github.event_name != 'pull_request'
|
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
||||||
uses: ./.github/workflows/nix-update-wlroots.yml
|
uses: ./.github/workflows/nix-update-inputs.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
build:
|
build:
|
||||||
if: always() && !cancelled() && !contains(needs.*.result, 'failure')
|
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork)
|
||||||
needs: wlroots
|
|
||||||
uses: ./.github/workflows/nix-build.yml
|
uses: ./.github/workflows/nix-build.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|||||||
18
.github/workflows/nix-update-inputs.yml
vendored
@@ -1,16 +1,19 @@
|
|||||||
name: Nix
|
name: Nix (Update Inputs)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
workflow_call:
|
||||||
- cron: '0 0 * * *' # check daily
|
secrets:
|
||||||
|
PAT:
|
||||||
|
required: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update:
|
update:
|
||||||
|
if: github.repository == 'hyprwm/Hyprland'
|
||||||
name: inputs
|
name: inputs
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
|
|
||||||
@@ -19,11 +22,6 @@ jobs:
|
|||||||
run: nix/update-inputs.sh
|
run: nix/update-inputs.sh
|
||||||
|
|
||||||
- name: Commit
|
- name: Commit
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4
|
uses: stefanzweifel/git-auto-commit-action@v5
|
||||||
with:
|
with:
|
||||||
commit_message: "[gha] Nix: update inputs"
|
commit_message: "[gha] Nix: update inputs"
|
||||||
|
|
||||||
update-build:
|
|
||||||
needs: update
|
|
||||||
uses: ./.github/workflows/nix-build.yml
|
|
||||||
secrets: inherit
|
|
||||||
|
|||||||
26
.github/workflows/nix-update-wlroots.yml
vendored
@@ -1,26 +0,0 @@
|
|||||||
name: Nix
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_call:
|
|
||||||
secrets:
|
|
||||||
PAT:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
update:
|
|
||||||
name: wlroots
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Clone repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.PAT }}
|
|
||||||
|
|
||||||
- uses: DeterminateSystems/nix-installer-action@main
|
|
||||||
- name: Update lockfile
|
|
||||||
run: nix/update-wlroots.sh
|
|
||||||
|
|
||||||
- name: Commit
|
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4
|
|
||||||
with:
|
|
||||||
commit_message: "[gha] Nix: update wlroots"
|
|
||||||
4
.github/workflows/release.yaml
vendored
@@ -11,15 +11,15 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout Hyprland
|
- name: Checkout Hyprland
|
||||||
id: checkout
|
id: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Generate version
|
- name: Generate version
|
||||||
id: genversion
|
id: genversion
|
||||||
run: |
|
run: |
|
||||||
|
git fetch --unshallow || echo "failed unshallowing"
|
||||||
bash -c scripts/generateVersion.sh
|
bash -c scripts/generateVersion.sh
|
||||||
mv scripts/generateVersion.sh scripts/generateVersion.sh.bak
|
|
||||||
|
|
||||||
- name: Create tarball with submodules
|
- name: Create tarball with submodules
|
||||||
id: tar
|
id: tar
|
||||||
|
|||||||
53
.github/workflows/security-checks.yml
vendored
@@ -4,6 +4,7 @@ on: [push, pull_request]
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
flawfinder:
|
flawfinder:
|
||||||
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork
|
||||||
name: Flawfinder Checks
|
name: Flawfinder Checks
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
@@ -12,7 +13,7 @@ jobs:
|
|||||||
security-events: write
|
security-events: write
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Scan with Flawfinder
|
- name: Scan with Flawfinder
|
||||||
uses: david-a-wheeler/flawfinder@8e4a779ad59dbfaee5da586aa9210853b701959c
|
uses: david-a-wheeler/flawfinder@8e4a779ad59dbfaee5da586aa9210853b701959c
|
||||||
@@ -24,53 +25,3 @@ jobs:
|
|||||||
uses: github/codeql-action/upload-sarif@v2
|
uses: github/codeql-action/upload-sarif@v2
|
||||||
with:
|
with:
|
||||||
sarif_file: ${{github.workspace}}/flawfinder_results.sarif
|
sarif_file: ${{github.workspace}}/flawfinder_results.sarif
|
||||||
|
|
||||||
codeql:
|
|
||||||
name: CodeQL
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container:
|
|
||||||
image: archlinux
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
language: [ 'cpp' ]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v2
|
|
||||||
with:
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
|
|
||||||
- name: Init Hyprland build
|
|
||||||
run: |
|
|
||||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
|
||||||
pacman --noconfirm --noprogressbar -Syyu
|
|
||||||
pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers xcb-util-errors xcb-util-renderutil xcb-util-wm xorg-fonts-encodings xorg-server-common xorg-setxkbmap xorg-xkbcomp xorg-xwayland git cmake go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd python libliftoff
|
|
||||||
useradd -m githubuser
|
|
||||||
echo -e "root ALL=(ALL:ALL) ALL\ngithubuser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
|
|
||||||
su githubuser -c "cd ~ && git clone https://aur.archlinux.org/libdisplay-info.git && cd ./libdisplay-info && makepkg -si --skippgpcheck --noconfirm --noprogressbar"
|
|
||||||
git config --global --add safe.directory /__w/Hyprland/Hyprland
|
|
||||||
|
|
||||||
- name: Checkout Hyprland
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Build Hyprland
|
|
||||||
run: |
|
|
||||||
git submodule sync --recursive && git submodule update --init --force --recursive
|
|
||||||
make all
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v2
|
|
||||||
with:
|
|
||||||
category: "/language:${{matrix.language}}"
|
|
||||||
|
|||||||
28
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||||
|
#
|
||||||
|
# You can adjust the behavior by modifying this file.
|
||||||
|
# For more information, see:
|
||||||
|
# https://github.com/actions/stale
|
||||||
|
name: Mark stale issues and pull requests
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- 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@v9
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.STALEBOT_PAT }}
|
||||||
|
stale-issue-label: "stale"
|
||||||
|
stale-pr-label: "stale"
|
||||||
|
operations-per-run: 40
|
||||||
|
days-before-close: -1
|
||||||
16
.gitignore
vendored
@@ -7,18 +7,25 @@ cmake_install.cmake
|
|||||||
install_manifest.txt
|
install_manifest.txt
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
CTestTestfile.cmake
|
CTestTestfile.cmake
|
||||||
|
CPackConfig.cmake
|
||||||
|
CPackSourceConfig.cmake
|
||||||
|
hyprland.pc
|
||||||
_deps
|
_deps
|
||||||
|
|
||||||
build/
|
build/
|
||||||
result*
|
result*
|
||||||
|
/.pre-commit-config.yaml
|
||||||
/.vscode/
|
/.vscode/
|
||||||
/.idea/
|
/.idea/
|
||||||
.envrc
|
.envrc
|
||||||
.cache
|
.cache
|
||||||
|
.direnv
|
||||||
|
/.cmake/
|
||||||
|
/.worktree/
|
||||||
|
|
||||||
*.o
|
*.o
|
||||||
*-protocol.c
|
protocols/*.c*
|
||||||
*-protocol.h
|
protocols/*.h*
|
||||||
.ccls-cache
|
.ccls-cache
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
@@ -31,3 +38,8 @@ gmon.out
|
|||||||
PKGBUILD
|
PKGBUILD
|
||||||
|
|
||||||
src/version.h
|
src/version.h
|
||||||
|
hyprpm/Makefile
|
||||||
|
hyprctl/Makefile
|
||||||
|
|
||||||
|
**/.#*.*
|
||||||
|
**/#*.*#
|
||||||
|
|||||||
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
|||||||
[submodule "wlroots"]
|
|
||||||
path = subprojects/wlroots
|
|
||||||
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
|
|
||||||
[submodule "subprojects/hyprland-protocols"]
|
[submodule "subprojects/hyprland-protocols"]
|
||||||
path = subprojects/hyprland-protocols
|
path = subprojects/hyprland-protocols
|
||||||
url = https://github.com/hyprwm/hyprland-protocols
|
url = https://github.com/hyprwm/hyprland-protocols
|
||||||
|
|||||||
399
CMakeLists.txt
Executable file → Normal file
@@ -1,38 +1,43 @@
|
|||||||
cmake_minimum_required(VERSION 3.19)
|
cmake_minimum_required(VERSION 3.30)
|
||||||
include(CheckIncludeFile)
|
|
||||||
|
|
||||||
# Get version
|
# Get version
|
||||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/props.json PROPS)
|
file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW)
|
||||||
string(JSON VER GET ${PROPS} version)
|
string(STRIP ${VER_RAW} VER)
|
||||||
|
|
||||||
project(Hyprland
|
project(
|
||||||
|
Hyprland
|
||||||
DESCRIPTION "A Modern C++ Wayland Compositor"
|
DESCRIPTION "A Modern C++ Wayland Compositor"
|
||||||
VERSION ${VER}
|
VERSION ${VER})
|
||||||
)
|
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
set(HYPRLAND_VERSION ${VER})
|
set(HYPRLAND_VERSION ${VER})
|
||||||
set(PREFIX ${CMAKE_INSTALL_PREFIX})
|
set(PREFIX ${CMAKE_INSTALL_PREFIX})
|
||||||
|
set(INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
set(BINDIR ${CMAKE_INSTALL_BINDIR})
|
||||||
configure_file(hyprland.pc.in hyprland.pc @ONLY)
|
configure_file(hyprland.pc.in hyprland.pc @ONLY)
|
||||||
|
|
||||||
set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
|
set(CMAKE_MESSAGE_LOG_LEVEL "STATUS")
|
||||||
|
|
||||||
message(STATUS "Gathering git info")
|
message(STATUS "Gathering git info")
|
||||||
|
|
||||||
# Get git info
|
# Get git info hash and branch
|
||||||
# hash and branch
|
execute_process(COMMAND ./scripts/generateVersion.sh
|
||||||
execute_process(
|
|
||||||
COMMAND ./scripts/generateVersion.sh
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
# udis
|
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")
|
add_subdirectory("subprojects/udis86")
|
||||||
|
include_directories("subprojects/udis86")
|
||||||
# wlroots
|
message(STATUS "udis86 dependency not found, falling back to subproject")
|
||||||
message(STATUS "Setting up wlroots")
|
endif()
|
||||||
|
|
||||||
include(ExternalProject)
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE)
|
if(CMAKE_BUILD_TYPE)
|
||||||
string(TOLOWER ${CMAKE_BUILD_TYPE} BUILDTYPE_LOWER)
|
string(TOLOWER ${CMAKE_BUILD_TYPE} BUILDTYPE_LOWER)
|
||||||
@@ -53,27 +58,11 @@ else()
|
|||||||
set(BUILDTYPE_LOWER "release")
|
set(BUILDTYPE_LOWER "release")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
ExternalProject_Add(
|
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
||||||
wlroots
|
|
||||||
PREFIX ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
|
||||||
SOURCE_DIR ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
|
||||||
PATCH_COMMAND sed -E -i -e "s/(soversion = 12)([^032]|$$)/soversion = 12032/g" meson.build
|
|
||||||
CONFIGURE_COMMAND meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> && meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> --reconfigure
|
|
||||||
BUILD_COMMAND ninja -C build
|
|
||||||
BUILD_ALWAYS true
|
|
||||||
BUILD_IN_SOURCE true
|
|
||||||
BUILD_BYPRODUCTS ${CMAKE_SOURCE_DIR}/subprojects/wlroots/build/libwlroots.so.12032
|
|
||||||
INSTALL_COMMAND echo "wlroots: install not needed"
|
|
||||||
)
|
|
||||||
|
|
||||||
find_program(WaylandScanner NAMES wayland-scanner)
|
|
||||||
message(STATUS "Found WaylandScanner at ${WaylandScanner}")
|
|
||||||
execute_process(
|
|
||||||
COMMAND pkg-config --variable=pkgdatadir wayland-protocols
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
OUTPUT_VARIABLE WAYLAND_PROTOCOLS_DIR
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
||||||
|
pkg_get_variable(WAYLAND_SCANNER_PKGDATA_DIR wayland-scanner pkgdatadir)
|
||||||
|
message(
|
||||||
|
STATUS "Found wayland-scanner pkgdatadir at ${WAYLAND_SCANNER_PKGDATA_DIR}")
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||||
message(STATUS "Configuring Hyprland in Debug with CMake")
|
message(STATUS "Configuring Hyprland in Debug with CMake")
|
||||||
@@ -83,31 +72,79 @@ else()
|
|||||||
message(STATUS "Configuring Hyprland in Release with CMake")
|
message(STATUS "Configuring Hyprland in Release with CMake")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(
|
add_compile_definitions(HYPRLAND_VERSION="${HYPRLAND_VERSION}")
|
||||||
.
|
|
||||||
"src/"
|
include_directories(. "src/" "protocols/")
|
||||||
"subprojects/wlroots/include/"
|
|
||||||
"subprojects/wlroots/build/include/"
|
set(CMAKE_CXX_STANDARD 26)
|
||||||
"subprojects/udis86/"
|
add_compile_options(
|
||||||
"protocols/")
|
-Wall
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
-Wextra
|
||||||
add_compile_definitions(WLR_USE_UNSTABLE)
|
-Wno-unused-parameter
|
||||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing -Wno-pointer-arith)
|
-Wno-unused-value
|
||||||
add_link_options(-rdynamic)
|
-Wno-missing-field-initializers
|
||||||
set(CMAKE_ENABLE_EXPORTS TRUE)
|
-Wno-narrowing
|
||||||
|
-Wno-pointer-arith
|
||||||
|
-fmacro-prefix-map=${CMAKE_SOURCE_DIR}/=)
|
||||||
|
|
||||||
|
set(CMAKE_EXECUTABLE_ENABLE_EXPORTS TRUE)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
|
||||||
|
|
||||||
message(STATUS "Checking deps...")
|
message(STATUS "Checking deps...")
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
if(LEGACY_RENDERER)
|
||||||
find_package(OpenGL REQUIRED)
|
set(GLES_VERSION "GLES2")
|
||||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo libdrm xkbcommon libinput pango pangocairo pixman-1) # we do not check for wlroots, as we provide it ourselves
|
else()
|
||||||
|
set(GLES_VERSION "GLES3")
|
||||||
|
endif()
|
||||||
|
find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
||||||
|
|
||||||
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")
|
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.2.3)
|
||||||
|
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1)
|
||||||
|
|
||||||
add_executable(Hyprland ${SRCFILES})
|
add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}")
|
||||||
add_dependencies(Hyprland wlroots)
|
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
|
||||||
|
xkbcommon
|
||||||
|
uuid
|
||||||
|
wayland-server>=1.22.90
|
||||||
|
wayland-protocols
|
||||||
|
cairo
|
||||||
|
pango
|
||||||
|
pangocairo
|
||||||
|
pixman-1
|
||||||
|
xcursor
|
||||||
|
libdrm
|
||||||
|
libinput
|
||||||
|
gbm
|
||||||
|
gio-2.0
|
||||||
|
re2)
|
||||||
|
|
||||||
|
find_package(hyprwayland-scanner 0.3.10 REQUIRED)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE SRCFILES "src/*.cpp")
|
||||||
|
|
||||||
|
set(TRACY_CPP_FILES "")
|
||||||
|
if(USE_TRACY)
|
||||||
|
set(TRACY_CPP_FILES "subprojects/tracy/public/TracyClient.cpp")
|
||||||
|
message(STATUS "Tracy enabled, TRACY_CPP_FILES: " ${TRACY_CPP_FILES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(Hyprland ${SRCFILES} ${TRACY_CPP_FILES})
|
||||||
|
|
||||||
|
set(USE_GPROF ON)
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||||
message(STATUS "Setting debug flags")
|
message(STATUS "Setting debug flags")
|
||||||
@@ -134,8 +171,12 @@ if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_compile_options(-pg -no-pie -fno-builtin)
|
add_compile_options(-fno-pie -fno-builtin)
|
||||||
add_link_options(-pg -no-pie -fno-builtin)
|
add_link_options(-no-pie -fno-builtin)
|
||||||
|
if(USE_GPROF)
|
||||||
|
add_compile_options(-pg)
|
||||||
|
add_link_options(-pg)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
check_include_file("execinfo.h" EXECINFOH)
|
check_include_file("execinfo.h" EXECINFOH)
|
||||||
@@ -150,6 +191,12 @@ if(HAVE_LIBEXECINFO)
|
|||||||
target_link_libraries(Hyprland execinfo)
|
target_link_libraries(Hyprland execinfo)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
check_include_file("sys/timerfd.h" HAS_TIMERFD)
|
||||||
|
pkg_check_modules(epoll IMPORTED_TARGET epoll-shim)
|
||||||
|
if(NOT HAS_TIMERFD AND epoll_FOUND)
|
||||||
|
target_link_libraries(Hyprland PkgConfig::epoll)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(LEGACY_RENDERER)
|
if(LEGACY_RENDERER)
|
||||||
message(STATUS "Using the legacy GLES2 renderer!")
|
message(STATUS "Using the legacy GLES2 renderer!")
|
||||||
add_compile_definitions(LEGACY_RENDERER)
|
add_compile_definitions(LEGACY_RENDERER)
|
||||||
@@ -160,26 +207,33 @@ if(NO_XWAYLAND)
|
|||||||
add_compile_definitions(NO_XWAYLAND)
|
add_compile_definitions(NO_XWAYLAND)
|
||||||
else()
|
else()
|
||||||
message(STATUS "XWAYLAND Enabled (NO_XWAYLAND not defined) checking deps...")
|
message(STATUS "XWAYLAND Enabled (NO_XWAYLAND not defined) checking deps...")
|
||||||
pkg_check_modules(xcbdep REQUIRED IMPORTED_TARGET xcb)
|
pkg_check_modules(
|
||||||
target_link_libraries(Hyprland PkgConfig::xcbdep)
|
xdeps
|
||||||
|
REQUIRED
|
||||||
|
IMPORTED_TARGET
|
||||||
|
xcb
|
||||||
|
xcb-render
|
||||||
|
xcb-xfixes
|
||||||
|
xcb-icccm
|
||||||
|
xcb-composite
|
||||||
|
xcb-res
|
||||||
|
xcb-errors)
|
||||||
|
target_link_libraries(Hyprland PkgConfig::xdeps)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NO_SYSTEMD)
|
if(NO_SYSTEMD)
|
||||||
message(STATUS "SYSTEMD support is disabled...")
|
message(STATUS "SYSTEMD support is disabled...")
|
||||||
else()
|
else()
|
||||||
message(STATUS "SYSTEMD support is requested (NO_SYSTEMD not defined) checking deps...")
|
message(STATUS "SYSTEMD support is requested (NO_SYSTEMD not defined)...")
|
||||||
check_include_file("systemd/sd-daemon.h" SYSTEMDH)
|
|
||||||
if(SYSTEMDH)
|
|
||||||
pkg_check_modules(LIBSYSTEMD libsystemd)
|
|
||||||
if (LIBSYSTEMD_FOUND)
|
|
||||||
add_compile_definitions(USES_SYSTEMD)
|
add_compile_definitions(USES_SYSTEMD)
|
||||||
target_link_libraries(Hyprland "${LIBSYSTEMD_LIBRARIES}")
|
|
||||||
message(STATUS "Systemd found")
|
# session file -uwsm
|
||||||
|
if(NO_UWSM)
|
||||||
|
message(STATUS "UWSM support is disabled...")
|
||||||
else()
|
else()
|
||||||
message(WARNING "Systemd support requested but systemd libraries were not found")
|
message(STATUS "UWSM support is enabled (NO_UWSM not defined)...")
|
||||||
endif()
|
install(FILES ${CMAKE_SOURCE_DIR}/systemd/hyprland-uwsm.desktop
|
||||||
else()
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
||||||
message(WARNING "Systemd support requested but systemd headers were not found")
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -189,56 +243,171 @@ include(CPack)
|
|||||||
|
|
||||||
message(STATUS "Setting precompiled headers")
|
message(STATUS "Setting precompiled headers")
|
||||||
|
|
||||||
target_precompile_headers(Hyprland PRIVATE $<$<COMPILE_LANGUAGE:CXX>:src/pch/pch.hpp>)
|
target_precompile_headers(Hyprland PRIVATE
|
||||||
|
$<$<COMPILE_LANGUAGE:CXX>:src/pch/pch.hpp>)
|
||||||
|
|
||||||
message(STATUS "Setting link libraries")
|
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)
|
||||||
function(protocol protoPath protoName external)
|
target_link_libraries(Hyprland PkgConfig::udis_dep)
|
||||||
if (external)
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${WaylandScanner} server-header ${protoPath} protocols/${protoName}-protocol.h
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${WaylandScanner} private-code ${protoPath} protocols/${protoName}-protocol.c
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
target_sources(Hyprland PRIVATE protocols/${protoName}-protocol.c)
|
|
||||||
else()
|
else()
|
||||||
execute_process(
|
target_link_libraries(Hyprland libudis86)
|
||||||
COMMAND ${WaylandScanner} server-header ${WAYLAND_PROTOCOLS_DIR}/${protoPath} protocols/${protoName}-protocol.h
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${WaylandScanner} private-code ${WAYLAND_PROTOCOLS_DIR}/${protoPath} protocols/${protoName}-protocol.c
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
target_sources(Hyprland PRIVATE protocols/${protoName}-protocol.c)
|
|
||||||
endif()
|
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 ${protoPath})
|
||||||
|
else()
|
||||||
|
set(path ${WAYLAND_PROTOCOLS_DIR}/${protoPath})
|
||||||
|
endif()
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_SOURCE_DIR}/protocols/${protoName}.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/protocols/${protoName}.hpp
|
||||||
|
COMMAND hyprwayland-scanner ${path}/${protoName}.xml
|
||||||
|
${CMAKE_SOURCE_DIR}/protocols/
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
target_sources(Hyprland PRIVATE protocols/${protoName}.cpp
|
||||||
|
protocols/${protoName}.hpp)
|
||||||
|
target_sources(generate-protocol-headers
|
||||||
|
PRIVATE ${CMAKE_SOURCE_DIR}/protocols/${protoName}.hpp)
|
||||||
|
endfunction()
|
||||||
|
function(protocolWayland)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_SOURCE_DIR}/protocols/wayland.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/protocols/wayland.hpp
|
||||||
|
COMMAND
|
||||||
|
hyprwayland-scanner --wayland-enums
|
||||||
|
${WAYLAND_SCANNER_PKGDATA_DIR}/wayland.xml ${CMAKE_SOURCE_DIR}/protocols/
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
target_sources(Hyprland PRIVATE protocols/wayland.cpp protocols/wayland.hpp)
|
||||||
|
target_sources(generate-protocol-headers
|
||||||
|
PRIVATE ${CMAKE_SOURCE_DIR}/protocols/wayland.hpp)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
target_link_libraries(Hyprland
|
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads)
|
||||||
${CMAKE_SOURCE_DIR}/subprojects/wlroots/build/libwlroots.so.12032 # wlroots is provided by us
|
|
||||||
OpenGL::EGL
|
|
||||||
OpenGL::GL
|
|
||||||
Threads::Threads
|
|
||||||
libudis86
|
|
||||||
)
|
|
||||||
|
|
||||||
protocol("protocols/idle.xml" "idle" true)
|
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.4.0)
|
||||||
protocol("protocols/pointer-constraints-unstable-v1.xml" "pointer-constraints-unstable-v1" true)
|
if(hyprland_protocols_dep_FOUND)
|
||||||
protocol("protocols/tablet-unstable-v2.xml" "tablet-unstable-v2" true)
|
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
|
||||||
protocol("protocols/wlr-foreign-toplevel-management-unstable-v1.xml" "wlr-foreign-toplevel-management-unstable-v1" true)
|
message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}")
|
||||||
protocol("protocols/wlr-layer-shell-unstable-v1.xml" "wlr-layer-shell-unstable-v1" true)
|
else()
|
||||||
protocol("protocols/wlr-output-power-management-unstable-v1.xml" "wlr-output-power-management-unstable-v1" true)
|
set(HYPRLAND_PROTOCOLS "subprojects/hyprland-protocols")
|
||||||
protocol("protocols/wlr-screencopy-unstable-v1.xml" "wlr-screencopy-unstable-v1" true)
|
message(STATUS "hyprland-protocols subproject set to ${HYPRLAND_PROTOCOLS}")
|
||||||
protocol("subprojects/hyprland-protocols/protocols/hyprland-global-shortcuts-v1.xml" "hyprland-global-shortcuts-v1" true)
|
endif()
|
||||||
protocol("subprojects/hyprland-protocols/protocols/hyprland-toplevel-export-v1.xml" "hyprland-toplevel-export-v1" true)
|
|
||||||
protocol("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false)
|
|
||||||
protocol("unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "linux-dmabuf-unstable-v1" false)
|
|
||||||
protocol("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false)
|
|
||||||
protocol("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
|
||||||
protocol("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false)
|
|
||||||
protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false)
|
|
||||||
protocol("staging/cursor-shape/cursor-shape-v1.xml" "cursor-shape-v1" false)
|
|
||||||
|
|
||||||
# hyprctl
|
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-global-shortcuts-v1"
|
||||||
|
true)
|
||||||
|
protocolnew("unstable/text-input" "text-input-unstable-v1" false)
|
||||||
|
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)
|
||||||
|
protocolnew("protocols" "wlr-output-power-management-unstable-v1" true)
|
||||||
|
protocolnew("protocols" "virtual-keyboard-unstable-v1" true)
|
||||||
|
protocolnew("protocols" "wlr-virtual-pointer-unstable-v1" true)
|
||||||
|
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("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-focus-grab-v1" true)
|
||||||
|
protocolnew("protocols" "wlr-layer-shell-unstable-v1" true)
|
||||||
|
protocolnew("protocols" "wayland-drm" true)
|
||||||
|
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-ctm-control-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)
|
||||||
|
protocolnew("staging/cursor-shape" "cursor-shape-v1" false)
|
||||||
|
protocolnew("unstable/idle-inhibit" "idle-inhibit-unstable-v1" false)
|
||||||
|
protocolnew("unstable/relative-pointer" "relative-pointer-unstable-v1" false)
|
||||||
|
protocolnew("unstable/xdg-decoration" "xdg-decoration-unstable-v1" false)
|
||||||
|
protocolnew("staging/alpha-modifier" "alpha-modifier-v1" false)
|
||||||
|
protocolnew("staging/ext-foreign-toplevel-list" "ext-foreign-toplevel-list-v1"
|
||||||
|
false)
|
||||||
|
protocolnew("unstable/pointer-gestures" "pointer-gestures-unstable-v1" false)
|
||||||
|
protocolnew("unstable/keyboard-shortcuts-inhibit"
|
||||||
|
"keyboard-shortcuts-inhibit-unstable-v1" false)
|
||||||
|
protocolnew("unstable/text-input" "text-input-unstable-v3" false)
|
||||||
|
protocolnew("unstable/pointer-constraints" "pointer-constraints-unstable-v1"
|
||||||
|
false)
|
||||||
|
protocolnew("staging/xdg-activation" "xdg-activation-v1" false)
|
||||||
|
protocolnew("staging/ext-idle-notify" "ext-idle-notify-v1" false)
|
||||||
|
protocolnew("staging/ext-session-lock" "ext-session-lock-v1" false)
|
||||||
|
protocolnew("stable/tablet" "tablet-v2" false)
|
||||||
|
protocolnew("stable/presentation-time" "presentation-time" false)
|
||||||
|
protocolnew("stable/xdg-shell" "xdg-shell" false)
|
||||||
|
protocolnew("unstable/primary-selection" "primary-selection-unstable-v1" false)
|
||||||
|
protocolnew("staging/xwayland-shell" "xwayland-shell-v1" false)
|
||||||
|
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(hyprctl)
|
||||||
|
add_subdirectory(hyprpm)
|
||||||
|
|
||||||
|
# binary and symlink
|
||||||
|
install(TARGETS Hyprland)
|
||||||
|
|
||||||
|
install(
|
||||||
|
CODE "execute_process( \
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E create_symlink \
|
||||||
|
${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 assets
|
||||||
|
add_compile_definitions(DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}")
|
||||||
|
|
||||||
|
# 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
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hypr)
|
||||||
|
|
||||||
|
# portal config
|
||||||
|
install(FILES ${CMAKE_SOURCE_DIR}/assets/hyprland-portals.conf
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/xdg-desktop-portal)
|
||||||
|
|
||||||
|
# man pages
|
||||||
|
file(GLOB_RECURSE MANPAGES "docs/*.1")
|
||||||
|
install(FILES ${MANPAGES} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||||||
|
|
||||||
|
# pkgconfig entry
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/hyprland.pc
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
|
||||||
|
|
||||||
|
# protocol headers
|
||||||
|
set(HEADERS_PROTO "${CMAKE_CURRENT_SOURCE_DIR}/protocols")
|
||||||
|
install(
|
||||||
|
DIRECTORY ${HEADERS_PROTO}
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hyprland
|
||||||
|
FILES_MATCHING
|
||||||
|
PATTERN "*.h*")
|
||||||
|
|
||||||
|
# hyprland headers
|
||||||
|
set(HEADERS_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
install(
|
||||||
|
DIRECTORY ${HEADERS_SRC}
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hyprland
|
||||||
|
FILES_MATCHING
|
||||||
|
PATTERN "*.h*")
|
||||||
|
|||||||
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
BSD 3-Clause License
|
BSD 3-Clause License
|
||||||
|
|
||||||
Copyright (c) 2022-2023, vaxerski
|
Copyright (c) 2022-2024, vaxerski
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
|||||||
91
Makefile
@@ -1,84 +1,59 @@
|
|||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
|
|
||||||
|
stub:
|
||||||
|
@echo "Do not run $(MAKE) directly without any arguments. Please refer to the wiki on how to compile Hyprland."
|
||||||
|
|
||||||
legacyrenderer:
|
legacyrenderer:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DLEGACY_RENDERER:BOOL=true -S . -B ./build -G Ninja
|
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`
|
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
chmod -R 777 ./build
|
|
||||||
|
|
||||||
legacyrendererdebug:
|
legacyrendererdebug:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DLEGACY_RENDERER:BOOL=true -S . -B ./build -G Ninja
|
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 Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
chmod -R 777 ./build
|
|
||||||
|
|
||||||
release:
|
release:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -S . -B ./build -G Ninja
|
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`
|
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
chmod -R 777 ./build
|
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -S . -B ./build -G Ninja
|
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`
|
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
chmod -R 777 ./build
|
|
||||||
|
nopch:
|
||||||
|
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:
|
clear:
|
||||||
rm -rf build
|
rm -rf build
|
||||||
rm -f ./protocols/*-protocol.h ./protocols/*-protocol.c
|
rm -f ./protocols/*.h ./protocols/*.c ./protocols/*.cpp ./protocols/*.hpp
|
||||||
rm -rf ./subprojects/wlroots/build
|
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@if [[ "$EUID" = 0 ]]; then echo -en "Avoid running $(MAKE) all as sudo.\n"; fi
|
|
||||||
$(MAKE) clear
|
$(MAKE) clear
|
||||||
$(MAKE) release
|
$(MAKE) release
|
||||||
|
|
||||||
install:
|
install:
|
||||||
@if [ ! -f ./build/Hyprland ]; then echo -en "You need to run $(MAKE) all first.\n" && exit 1; fi
|
cmake --install ./build
|
||||||
@echo -en "!NOTE: Please note make install does not compile Hyprland and only installs the already built files."
|
|
||||||
|
|
||||||
mkdir -p ${PREFIX}/share/wayland-sessions
|
|
||||||
mkdir -p ${PREFIX}/bin
|
|
||||||
cp -f ./build/Hyprland ${PREFIX}/bin
|
|
||||||
cp -f ./build/hyprctl/hyprctl ${PREFIX}/bin
|
|
||||||
chmod 755 ${PREFIX}/bin/Hyprland
|
|
||||||
chmod 755 ${PREFIX}/bin/hyprctl
|
|
||||||
if [ ! -f ${PREFIX}/share/wayland-sessions/hyprland.desktop ]; then cp ./example/hyprland.desktop ${PREFIX}/share/wayland-sessions; fi
|
|
||||||
mkdir -p ${PREFIX}/share/hyprland
|
|
||||||
cp ./assets/wall_* ${PREFIX}/share/hyprland
|
|
||||||
mkdir -p ${PREFIX}/share/xdg-desktop-portal
|
|
||||||
cp ./assets/hyprland-portals.conf ${PREFIX}/share/xdg-desktop-portal
|
|
||||||
|
|
||||||
mkdir -p ${PREFIX}/share/man/man1
|
|
||||||
install -m644 ./docs/*.1 ${PREFIX}/share/man/man1
|
|
||||||
|
|
||||||
mkdir -p ${PREFIX}/lib/
|
|
||||||
cp ./subprojects/wlroots/build/libwlroots.so.12032 ${PREFIX}/lib/
|
|
||||||
|
|
||||||
$(MAKE) installheaders
|
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f ${PREFIX}/share/wayland-sessions/hyprland.desktop
|
xargs rm < ./build/install_manifest.txt
|
||||||
rm -f ${PREFIX}/bin/Hyprland
|
|
||||||
rm -f ${PREFIX}/bin/hyprctl
|
|
||||||
rm -f ${PREFIX}/lib/libwlroots.so.12032
|
|
||||||
rm -rf ${PREFIX}/share/hyprland
|
|
||||||
rm -f ${PREFIX}/share/man/man1/Hyprland.1
|
|
||||||
rm -f ${PREFIX}/share/man/man1/hyprctl.1
|
|
||||||
|
|
||||||
pluginenv:
|
pluginenv:
|
||||||
@echo -en "$(MAKE) pluginenv has been deprecated.\nPlease run $(MAKE) all && sudo $(MAKE) installheaders\n"
|
@echo -en "$(MAKE) pluginenv has been deprecated.\nPlease run $(MAKE) all && sudo $(MAKE) installheaders\n"
|
||||||
@exit 1
|
@exit 1
|
||||||
|
|
||||||
installheaders:
|
installheaders:
|
||||||
@if [ ! -f ./build/Hyprland ]; then echo -en "You need to run $(MAKE) all first.\n" && exit 1; fi
|
@if [ ! -f ./src/version.h ]; then echo -en "You need to run $(MAKE) all first.\n" && exit 1; fi
|
||||||
|
|
||||||
|
# remove previous headers from hyprpm's dir
|
||||||
|
rm -fr ${PREFIX}/include/hyprland
|
||||||
mkdir -p ${PREFIX}/include/hyprland
|
mkdir -p ${PREFIX}/include/hyprland
|
||||||
mkdir -p ${PREFIX}/include/hyprland/protocols
|
mkdir -p ${PREFIX}/include/hyprland/protocols
|
||||||
mkdir -p ${PREFIX}/include/hyprland/wlroots
|
|
||||||
mkdir -p ${PREFIX}/share/pkgconfig
|
mkdir -p ${PREFIX}/share/pkgconfig
|
||||||
|
|
||||||
|
cmake --build ./build --config Release --target generate-protocol-headers
|
||||||
|
|
||||||
find src -name '*.h*' -print0 | cpio --quiet -0dump ${PREFIX}/include/hyprland
|
find src -name '*.h*' -print0 | cpio --quiet -0dump ${PREFIX}/include/hyprland
|
||||||
cd subprojects/wlroots/include && find . -name '*.h*' -print0 | cpio --quiet -0dump ${PREFIX}/include/hyprland/wlroots && cd ../../..
|
cp ./protocols/*.h* ${PREFIX}/include/hyprland/protocols
|
||||||
cd subprojects/wlroots/build/include && find . -name '*.h*' -print0 | cpio --quiet -0dump ${PREFIX}/include/hyprland/wlroots && cd ../../../..
|
|
||||||
cp ./protocols/*-protocol.h ${PREFIX}/include/hyprland/protocols
|
|
||||||
cp ./build/hyprland.pc ${PREFIX}/share/pkgconfig
|
cp ./build/hyprland.pc ${PREFIX}/share/pkgconfig
|
||||||
if [ -d /usr/share/pkgconfig ]; then cp ./build/hyprland.pc /usr/share/pkgconfig 2>/dev/null || true; fi
|
if [ -d /usr/share/pkgconfig ]; then cp ./build/hyprland.pc /usr/share/pkgconfig 2>/dev/null || true; fi
|
||||||
|
|
||||||
@@ -101,3 +76,27 @@ man:
|
|||||||
--variable=section:1 \
|
--variable=section:1 \
|
||||||
--from rst \
|
--from rst \
|
||||||
--to man > ./docs/hyprctl.1
|
--to man > ./docs/hyprctl.1
|
||||||
|
|
||||||
|
asan:
|
||||||
|
@echo -en "!!WARNING!!\nOnly run this in the TTY.\n"
|
||||||
|
@pidof Hyprland > /dev/null && echo -ne "Refusing to run with Hyprland running.\n" || echo ""
|
||||||
|
@pidof Hyprland > /dev/null && exit 1 || echo ""
|
||||||
|
|
||||||
|
rm -rf ./wayland
|
||||||
|
#git reset --hard
|
||||||
|
|
||||||
|
@echo -en "If you want to apply a patch, input its path (leave empty for none):\n"
|
||||||
|
@read patchvar; \
|
||||||
|
if [ -n "$$patchvar" ]; then patch -p1 < "$$patchvar" || echo ""; else echo "No patch specified"; fi
|
||||||
|
|
||||||
|
git clone --recursive https://gitlab.freedesktop.org/wayland/wayland
|
||||||
|
cd wayland && patch -p1 < ../scripts/waylandStatic.diff && meson setup build --buildtype=debug -Db_sanitize=address -Ddocumentation=false && ninja -C build && cd ..
|
||||||
|
cp ./wayland/build/src/libwayland-server.a .
|
||||||
|
@echo "Wayland done"
|
||||||
|
|
||||||
|
patch -p1 < ./scripts/hyprlandStaticAsan.diff
|
||||||
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DWITH_ASAN:STRING=True -DUSE_TRACY:STRING=False -DUSE_TRACY_GPU:STRING=False -S . -B ./build -G Ninja
|
||||||
|
cmake --build ./build --config Debug --target all
|
||||||
|
@echo "Hyprland done"
|
||||||
|
|
||||||
|
ASAN_OPTIONS="detect_odr_violation=0,log_path=asan.log" HYPRLAND_NO_CRASHREPORTER=1 ./build/Hyprland -c ~/.config/hypr/hyprland.conf
|
||||||
|
|||||||
26
README.md
@@ -1,6 +1,6 @@
|
|||||||
<div align = center>
|
<div align = center>
|
||||||
|
|
||||||
<img src="https://raw.githubusercontent.com/vaxerski/Hyprland/main/assets/header.svg" width="750" height="300" alt="banner">
|
<img src="https://raw.githubusercontent.com/hyprwm/Hyprland/main/assets/header.svg" width="750" height="300" alt="banner">
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -10,14 +10,13 @@
|
|||||||
[![Badge Pull Requests]][Pull Requests]
|
[![Badge Pull Requests]][Pull Requests]
|
||||||
[![Badge Issues]][Issues]
|
[![Badge Issues]][Issues]
|
||||||
![Badge Hi Mom]<br>
|
![Badge Hi Mom]<br>
|
||||||
[![Badge Discord]][Discord]
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks.
|
Hyprland is a 100% independent, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
|
||||||
|
|
||||||
It provides the latest Wayland features, is highly customizable, has all the eyecandy, the most powerful plugins,
|
It provides the latest Wayland features, is highly customizable, has all the eyecandy, the most powerful plugins,
|
||||||
easy IPC, much more QoL stuff than other wlr-based compositors and more...
|
easy IPC, much more QoL stuff than other compositors and more...
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -38,17 +37,17 @@ easy IPC, much more QoL stuff than other wlr-based compositors and more...
|
|||||||
|
|
||||||
- All of the eyecandy: gradient borders, blur, animations, shadows and much more
|
- All of the eyecandy: gradient borders, blur, animations, shadows and much more
|
||||||
- A lot of customization
|
- A lot of customization
|
||||||
- Much more QoL stuff than other wlr-based compositors
|
- 100% independent, no wlroots, no libweston, no kwin, no mutter.
|
||||||
- Custom bezier curves for the best animations
|
- Custom bezier curves for the best animations
|
||||||
- Powerful plugin support
|
- Powerful plugin support
|
||||||
|
- Built-in plugin manager
|
||||||
- Tearing support for better gaming performance
|
- Tearing support for better gaming performance
|
||||||
- Easily expandable and readable codebase
|
- Easily expandable and readable codebase
|
||||||
- Fast and active development
|
- Fast and active development
|
||||||
- Not scared to provide bleeding-edge features
|
- Not afraid to provide bleeding-edge features
|
||||||
- Config reloaded instantly upon saving
|
- Config reloaded instantly upon saving
|
||||||
- Fully dynamic workspaces
|
- Fully dynamic workspaces
|
||||||
- Two built-in layouts and more available as plugins
|
- Two built-in layouts and more available as plugins
|
||||||
- Closely follows `wlroots-git`
|
|
||||||
- Global keybinds passed to your apps of choice
|
- Global keybinds passed to your apps of choice
|
||||||
- Tiling/pseudotiling/floating/fullscreen windows
|
- Tiling/pseudotiling/floating/fullscreen windows
|
||||||
- Special workspaces (scratchpads)
|
- Special workspaces (scratchpads)
|
||||||
@@ -86,7 +85,7 @@ easy IPC, much more QoL stuff than other wlr-based compositors and more...
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
**[wlroots]** - *For their amazing library*
|
**[wlroots]** - *For powering Hyprland in the past*
|
||||||
|
|
||||||
**[tinywl]** - *For showing how 2 do stuff*
|
**[tinywl]** - *For showing how 2 do stuff*
|
||||||
|
|
||||||
@@ -101,8 +100,7 @@ easy IPC, much more QoL stuff than other wlr-based compositors and more...
|
|||||||
|
|
||||||
<!----------------------------------------------------------------------------->
|
<!----------------------------------------------------------------------------->
|
||||||
|
|
||||||
[Configure]: https://wiki.hyprland.org/Configuring/Configuring-Hyprland/
|
[Configure]: https://wiki.hyprland.org/Configuring/
|
||||||
[Discord]: https://discord.gg/hQ9XvMUjjr
|
|
||||||
[Stars]: https://starchart.cc/hyprwm/Hyprland
|
[Stars]: https://starchart.cc/hyprwm/Hyprland
|
||||||
[Hypr]: https://github.com/hyprwm/Hypr
|
[Hypr]: https://github.com/hyprwm/Hypr
|
||||||
|
|
||||||
@@ -123,13 +121,12 @@ easy IPC, much more QoL stuff than other wlr-based compositors and more...
|
|||||||
[Wayfire]: https://github.com/WayfireWM/wayfire
|
[Wayfire]: https://github.com/WayfireWM/wayfire
|
||||||
[TinyWl]: https://gitlab.freedesktop.org/wlroots/wlroots/-/blob/master/tinywl/tinywl.c
|
[TinyWl]: https://gitlab.freedesktop.org/wlroots/wlroots/-/blob/master/tinywl/tinywl.c
|
||||||
[Sway]: https://github.com/swaywm/sway
|
[Sway]: https://github.com/swaywm/sway
|
||||||
[DWL]: https://github.com/djpohly/dwl
|
[DWL]: https://codeberg.org/dwl/dwl
|
||||||
|
|
||||||
<!----------------------------------{ Images }--------------------------------->
|
<!----------------------------------{ Images }--------------------------------->
|
||||||
|
|
||||||
[Stars Preview]: https://starchart.cc/vaxerski/Hyprland.svg
|
[Preview A]: https://i.ibb.co/C1yTb0r/falf.png
|
||||||
[Preview A]: https://cdn.discordapp.com/attachments/1091569872535814185/1107675866101723277/screenshot-summer.png
|
[Preview B]: https://linfindel.github.io/cdn/hyprland-preview-b.png
|
||||||
[Preview B]: https://i.ibb.co/SX7GbYR/winter-rice.png
|
|
||||||
[Preview C]: https://i.ibb.co/B3GJg28/20221126-20h53m26s-grim.png
|
[Preview C]: https://i.ibb.co/B3GJg28/20221126-20h53m26s-grim.png
|
||||||
|
|
||||||
|
|
||||||
@@ -137,7 +134,6 @@ easy IPC, much more QoL stuff than other wlr-based compositors and more...
|
|||||||
|
|
||||||
[Badge Workflow]: https://github.com/hyprwm/Hyprland/actions/workflows/ci.yaml/badge.svg
|
[Badge Workflow]: https://github.com/hyprwm/Hyprland/actions/workflows/ci.yaml/badge.svg
|
||||||
|
|
||||||
[Badge Discord]: https://img.shields.io/badge/Join%20the-Discord%20server-6666ff
|
|
||||||
[Badge Issues]: https://img.shields.io/github/issues/hyprwm/Hyprland
|
[Badge Issues]: https://img.shields.io/github/issues/hyprwm/Hyprland
|
||||||
[Badge Pull Requests]: https://img.shields.io/github/issues-pr/hyprwm/Hyprland
|
[Badge Pull Requests]: https://img.shields.io/github/issues-pr/hyprwm/Hyprland
|
||||||
[Badge Language]: https://img.shields.io/github/languages/top/hyprwm/Hyprland
|
[Badge Language]: https://img.shields.io/github/languages/top/hyprwm/Hyprland
|
||||||
|
|||||||
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
|
||||||
BIN
assets/install/wall0.png
Normal file
|
After Width: | Height: | Size: 14 MiB |
BIN
assets/install/wall1.png
Normal file
|
After Width: | Height: | Size: 5.9 MiB |
BIN
assets/install/wall2.png
Normal file
|
After Width: | Height: | Size: 27 MiB |
@@ -1,9 +1,7 @@
|
|||||||
wallpaper_types = ['', 'anime_', 'anime2_']
|
install_data(
|
||||||
|
'hyprland-portals.conf',
|
||||||
|
install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
)
|
||||||
|
|
||||||
foreach type : wallpaper_types
|
subdir('install')
|
||||||
foreach size : [2, 4, 8]
|
|
||||||
install_data(f'wall_@type@@size@K.png', install_dir: join_paths(get_option('datadir'), 'hyprland'), install_tag: 'runtime')
|
|
||||||
endforeach
|
|
||||||
endforeach
|
|
||||||
|
|
||||||
install_data('hyprland-portals.conf', install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'), install_tag: 'runtime')
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 511 KiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 502 KiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 1.6 MiB |
@@ -10,8 +10,8 @@ Hyprland - Dynamic tiling Wayland compositor
|
|||||||
\f[B]Hyprland\f[R] [\f[I]arg [...]\f[R]].
|
\f[B]Hyprland\f[R] [\f[I]arg [...]\f[R]].
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
\f[B]Hyprland\f[R] is a dynamic tiling Wayland compositor based on
|
\f[B]Hyprland\f[R] is an independent, highly customizable, dynamic
|
||||||
wlroots that doesn\[aq]t sacrifice on its looks.
|
tiling Wayland compositor that doesn\[aq]t sacrifice on its looks.
|
||||||
.PP
|
.PP
|
||||||
You can launch Hyprland by either going into a TTY and executing
|
You can launch Hyprland by either going into a TTY and executing
|
||||||
\f[B]Hyprland\f[R], or with a login manager.
|
\f[B]Hyprland\f[R], or with a login manager.
|
||||||
@@ -32,6 +32,12 @@ Show command usage.
|
|||||||
.TP
|
.TP
|
||||||
\f[B]-c\f[R], \f[B]--config\f[R]
|
\f[B]-c\f[R], \f[B]--config\f[R]
|
||||||
Specify config file to use.
|
Specify config file to use.
|
||||||
|
.TP
|
||||||
|
\f[B]--socket\f[R]
|
||||||
|
Sets the Wayland socket name (for Wayland socket handover)
|
||||||
|
.TP
|
||||||
|
\f[B]--wayland-fd\f[R]
|
||||||
|
Sets the Wayland socket file descriptor (for Wayland socket handover)
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
.TP
|
.TP
|
||||||
Submit bug reports and request features online at:
|
Submit bug reports and request features online at:
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ SYNOPSIS
|
|||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
===========
|
===========
|
||||||
|
|
||||||
**Hyprland** is a dynamic tiling Wayland compositor based on
|
**Hyprland** is an independent, highly customizable,
|
||||||
wlroots that doesn't sacrifice on its looks.
|
dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
|
||||||
|
|
||||||
You can launch Hyprland by either going into a TTY and
|
You can launch Hyprland by either going into a TTY and
|
||||||
executing **Hyprland**, or with a login manager.
|
executing **Hyprland**, or with a login manager.
|
||||||
@@ -41,6 +41,12 @@ OPTIONS
|
|||||||
**-c**, **--config**
|
**-c**, **--config**
|
||||||
Specify config file to use.
|
Specify config file to use.
|
||||||
|
|
||||||
|
**--socket**
|
||||||
|
Sets the Wayland socket name (for Wayland socket handover)
|
||||||
|
|
||||||
|
**--wayland-fd**
|
||||||
|
Sets the Wayland socket file descriptor (for Wayland socket handover)
|
||||||
|
|
||||||
BUGS
|
BUGS
|
||||||
====
|
====
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
First of all, please remember to:
|
First of all, please remember to:
|
||||||
- Check that your issue is not a duplicate
|
- Check that your issue is not a duplicate
|
||||||
- Read the [FAQ](https://wiki.hyprland.org/FAQ/)
|
- 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/>
|
<br/>
|
||||||
|
|
||||||
@@ -34,20 +34,20 @@ If your bug crashes Hyprland, append additionally:
|
|||||||
## Obtaining the Hyprland log
|
## Obtaining the Hyprland log
|
||||||
If you are in a TTY, and the hyprland session that crashed was the last one you launched, the log will be printed with
|
If you are in a TTY, and the hyprland session that crashed was the last one you launched, the log will be printed with
|
||||||
```
|
```
|
||||||
cat /tmp/hypr/$(ls -t /tmp/hypr/ | head -n 1)/hyprland.log
|
cat $XDG_RUNTIME_DIR/hypr/$(ls -t $XDG_RUNTIME_DIR/hypr | head -n 1)/hyprland.log
|
||||||
```
|
```
|
||||||
feel free to send it to a file, save, copy, etc.
|
feel free to send it to a file, save, copy, etc.
|
||||||
|
|
||||||
if you are in a Hyprland session, and you want the log of the last session, use
|
if you are in a Hyprland session, and you want the log of the last session, use
|
||||||
```
|
```
|
||||||
cat /tmp/hypr/$(ls -t /tmp/hypr/ | head -n 2 | tail -n 1)/hyprland.log
|
cat $XDG_RUNTIME_DIR/hypr/$(ls -t $XDG_RUNTIME_DIR/hypr | head -n 2 | tail -n 1)/hyprland.log
|
||||||
```
|
```
|
||||||
|
|
||||||
basically, directories in /tmp/hypr are your sessions.
|
basically, directories in $XDG_RUNTIME_DIR/hypr are your sessions.
|
||||||
|
|
||||||
## Obtaining the Hyprland Crash Report (v0.22.0beta and up)
|
## Obtaining the Hyprland Crash Report (v0.22.0beta and up)
|
||||||
|
|
||||||
If you have `$XDG_CACHE_HOME` set, the crash report directory is `$XDG_CACHE_HOME/hyprland`. If not, it's `~/.hyprland`
|
If you have `$XDG_CACHE_HOME` set, the crash report directory is `$XDG_CACHE_HOME/hyprland`. If not, it's `$HOME/.cache/hyprland`.
|
||||||
|
|
||||||
Go to the crash report directory and you should find a file named `hyprlandCrashReport[XXXX].txt` where `[XXXX]` is the PID of the process that crashed.
|
Go to the crash report directory and you should find a file named `hyprlandCrashReport[XXXX].txt` where `[XXXX]` is the PID of the process that crashed.
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
# compile with HYPRLAND_HEADERS=<path_to_hl> make all
|
|
||||||
# make sure that the path above is to the root hl repo directory, NOT src/
|
|
||||||
# and that you have ran `make protocols` in the hl dir.
|
|
||||||
|
|
||||||
all:
|
|
||||||
$(CXX) -shared -fPIC --no-gnu-unique main.cpp customLayout.cpp customDecoration.cpp -o examplePlugin.so -g `pkg-config --cflags pixman-1 libdrm hyprland` -std=c++2b
|
|
||||||
clean:
|
|
||||||
rm ./examplePlugin.so
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
#include "customDecoration.hpp"
|
|
||||||
#include <hyprland/src/Window.hpp>
|
|
||||||
#include <hyprland/src/Compositor.hpp>
|
|
||||||
#include "globals.hpp"
|
|
||||||
|
|
||||||
CCustomDecoration::CCustomDecoration(CWindow* pWindow) {
|
|
||||||
m_pWindow = pWindow;
|
|
||||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec();
|
|
||||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
|
||||||
}
|
|
||||||
|
|
||||||
CCustomDecoration::~CCustomDecoration() {
|
|
||||||
damageEntire();
|
|
||||||
}
|
|
||||||
|
|
||||||
SWindowDecorationExtents CCustomDecoration::getWindowDecorationExtents() {
|
|
||||||
return m_seExtents;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCustomDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
|
||||||
if (!g_pCompositor->windowValidMapped(m_pWindow))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static auto* const PCOLOR = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:example:border_color")->intValue;
|
|
||||||
static auto* const PROUNDING = &HyprlandAPI::getConfigValue(PHANDLE, "decoration:rounding")->intValue;
|
|
||||||
static auto* const PBORDERSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "general:border_size")->intValue;
|
|
||||||
|
|
||||||
const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ?
|
|
||||||
0 :
|
|
||||||
(m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying() == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying());
|
|
||||||
|
|
||||||
// draw the border
|
|
||||||
CBox fullBox = {(int)(m_vLastWindowPos.x - *PBORDERSIZE), (int)(m_vLastWindowPos.y - *PBORDERSIZE), (int)(m_vLastWindowSize.x + 2.0 * *PBORDERSIZE),
|
|
||||||
(int)(m_vLastWindowSize.y + 2.0 * *PBORDERSIZE)};
|
|
||||||
|
|
||||||
fullBox.x -= pMonitor->vecPosition.x;
|
|
||||||
fullBox.y -= pMonitor->vecPosition.y;
|
|
||||||
|
|
||||||
m_seExtents = {{m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2, m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2},
|
|
||||||
{fullBox.x + fullBox.width + pMonitor->vecPosition.x - m_vLastWindowPos.x - m_vLastWindowSize.x + 2,
|
|
||||||
fullBox.y + fullBox.height + pMonitor->vecPosition.y - m_vLastWindowPos.y - m_vLastWindowSize.y + 2}};
|
|
||||||
|
|
||||||
fullBox.x += offset.x;
|
|
||||||
fullBox.y += offset.y;
|
|
||||||
|
|
||||||
if (fullBox.width < 1 || fullBox.height < 1)
|
|
||||||
return; // don't draw invisible shadows
|
|
||||||
|
|
||||||
g_pHyprOpenGL->scissor((CBox*)nullptr);
|
|
||||||
|
|
||||||
fullBox.scale(pMonitor->scale);
|
|
||||||
g_pHyprOpenGL->renderBorder(&fullBox, CColor(*PCOLOR), *PROUNDING * pMonitor->scale + *PBORDERSIZE * 2, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
eDecorationType CCustomDecoration::getDecorationType() {
|
|
||||||
return DECORATION_CUSTOM;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCustomDecoration::updateWindow(CWindow* pWindow) {
|
|
||||||
|
|
||||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec();
|
|
||||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
|
||||||
|
|
||||||
damageEntire();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCustomDecoration::damageEntire() {
|
|
||||||
CBox dm = {(int)(m_vLastWindowPos.x - m_seExtents.topLeft.x), (int)(m_vLastWindowPos.y - m_seExtents.topLeft.y),
|
|
||||||
(int)(m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x), (int)m_seExtents.topLeft.y};
|
|
||||||
g_pHyprRenderer->damageBox(&dm);
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define WLR_USE_UNSTABLE
|
|
||||||
|
|
||||||
#include <hyprland/src/render/decorations/IHyprWindowDecoration.hpp>
|
|
||||||
|
|
||||||
class CCustomDecoration : public IHyprWindowDecoration {
|
|
||||||
public:
|
|
||||||
CCustomDecoration(CWindow*);
|
|
||||||
virtual ~CCustomDecoration();
|
|
||||||
|
|
||||||
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
|
||||||
|
|
||||||
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
|
||||||
|
|
||||||
virtual eDecorationType getDecorationType();
|
|
||||||
|
|
||||||
virtual void updateWindow(CWindow*);
|
|
||||||
|
|
||||||
virtual void damageEntire();
|
|
||||||
|
|
||||||
private:
|
|
||||||
SWindowDecorationExtents m_seExtents;
|
|
||||||
|
|
||||||
CWindow* m_pWindow = nullptr;
|
|
||||||
|
|
||||||
Vector2D m_vLastWindowPos;
|
|
||||||
Vector2D m_vLastWindowSize;
|
|
||||||
};
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
#include "customLayout.hpp"
|
|
||||||
#include <hyprland/src/Compositor.hpp>
|
|
||||||
#include "globals.hpp"
|
|
||||||
|
|
||||||
void CHyprCustomLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
|
||||||
const auto SIZE = PMONITOR->vecSize;
|
|
||||||
|
|
||||||
// these are used for focus and move calculations, and are *required* to touch for moving focus to work properly.
|
|
||||||
pWindow->m_vPosition = Vector2D{(SIZE.x / 2.0) * (m_vWindowData.size() % 2), (SIZE.y / 2.0) * (int)(m_vWindowData.size() > 1)};
|
|
||||||
pWindow->m_vSize = SIZE / 2.0;
|
|
||||||
|
|
||||||
// this is the actual pos and size of the window (where it's rendered)
|
|
||||||
pWindow->m_vRealPosition = pWindow->m_vPosition + Vector2D{10, 10};
|
|
||||||
pWindow->m_vRealSize = pWindow->m_vSize - Vector2D{20, 20};
|
|
||||||
|
|
||||||
const auto PDATA = &m_vWindowData.emplace_back();
|
|
||||||
PDATA->pWindow = pWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
|
||||||
std::erase_if(m_vWindowData, [&](const auto& other) { return other.pWindow == pWindow; });
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CHyprCustomLayout::isWindowTiled(CWindow* pWindow) {
|
|
||||||
return std::find_if(m_vWindowData.begin(), m_vWindowData.end(), [&](const auto& other) { return other.pWindow == pWindow; }) != m_vWindowData.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::recalculateMonitor(const int& eIdleInhibitMode) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::recalculateWindow(CWindow* pWindow) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::resizeActiveWindow(const Vector2D& delta, CWindow* pWindow) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreenMode mode, bool on) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any CHyprCustomLayout::layoutMessage(SLayoutMessageHeader header, std::string content) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
SWindowRenderLayoutHints CHyprCustomLayout::requestRenderHints(CWindow* pWindow) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::switchWindows(CWindow* pWindowA, CWindow* pWindowB) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::alterSplitRatio(CWindow* pWindow, float delta, bool exact) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string CHyprCustomLayout::getLayoutName() {
|
|
||||||
return "custom";
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::replaceWindowDataWith(CWindow* from, CWindow* to) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::onEnable() {
|
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
|
||||||
if (w->isHidden() || !w->m_bIsMapped || w->m_bFadingOut || w->m_bIsFloating)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
onWindowCreatedTiling(w.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::onDisable() {
|
|
||||||
m_vWindowData.clear();
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define WLR_USE_UNSTABLE
|
|
||||||
|
|
||||||
#include <hyprland/src/layout/IHyprLayout.hpp>
|
|
||||||
|
|
||||||
struct SWindowData {
|
|
||||||
CWindow* pWindow = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CHyprCustomLayout : public IHyprLayout {
|
|
||||||
public:
|
|
||||||
virtual void onWindowCreatedTiling(CWindow*);
|
|
||||||
virtual void onWindowRemovedTiling(CWindow*);
|
|
||||||
virtual bool isWindowTiled(CWindow*);
|
|
||||||
virtual void recalculateMonitor(const int&);
|
|
||||||
virtual void recalculateWindow(CWindow*);
|
|
||||||
virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr);
|
|
||||||
virtual void fullscreenRequestForWindow(CWindow*, eFullscreenMode, bool);
|
|
||||||
virtual std::any layoutMessage(SLayoutMessageHeader, std::string);
|
|
||||||
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);
|
|
||||||
virtual void switchWindows(CWindow*, CWindow*);
|
|
||||||
virtual void alterSplitRatio(CWindow*, float, bool);
|
|
||||||
virtual std::string getLayoutName();
|
|
||||||
virtual void replaceWindowDataWith(CWindow* from, CWindow* to);
|
|
||||||
|
|
||||||
virtual void onEnable();
|
|
||||||
virtual void onDisable();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<SWindowData> m_vWindowData;
|
|
||||||
};
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <hyprland/src/plugins/PluginAPI.hpp>
|
|
||||||
|
|
||||||
inline HANDLE PHANDLE = nullptr;
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
#define WLR_USE_UNSTABLE
|
|
||||||
|
|
||||||
#include "globals.hpp"
|
|
||||||
|
|
||||||
#include <hyprland/src/Window.hpp>
|
|
||||||
#include <hyprland/src/Compositor.hpp>
|
|
||||||
#include "customLayout.hpp"
|
|
||||||
#include "customDecoration.hpp"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
inline std::unique_ptr<CHyprCustomLayout> g_pCustomLayout;
|
|
||||||
inline CFunctionHook* g_pFocusHook = nullptr;
|
|
||||||
inline CFunctionHook* g_pMotionHook = nullptr;
|
|
||||||
inline CFunctionHook* g_pMouseDownHook = nullptr;
|
|
||||||
typedef void (*origFocusWindow)(void*, CWindow*, wlr_surface*);
|
|
||||||
typedef void (*origMotion)(wlr_seat*, uint32_t, double, double);
|
|
||||||
typedef void (*origMouseDownNormal)(void*, wlr_pointer_button_event*);
|
|
||||||
|
|
||||||
// Do NOT change this function.
|
|
||||||
APICALL EXPORT std::string PLUGIN_API_VERSION() {
|
|
||||||
return HYPRLAND_API_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onActiveWindowChange(void* self, std::any data) {
|
|
||||||
try {
|
|
||||||
auto* const PWINDOW = std::any_cast<CWindow*>(data);
|
|
||||||
|
|
||||||
HyprlandAPI::addNotification(PHANDLE, "[ExamplePlugin] Active window: " + (PWINDOW ? PWINDOW->m_szTitle : "None"), CColor{0.f, 0.5f, 1.f, 1.f}, 5000);
|
|
||||||
} catch (std::bad_any_cast& e) { HyprlandAPI::addNotification(PHANDLE, "[ExamplePlugin] Active window: None", CColor{0.f, 0.5f, 1.f, 1.f}, 5000); }
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onNewWindow(void* self, std::any data) {
|
|
||||||
auto* const PWINDOW = std::any_cast<CWindow*>(data);
|
|
||||||
|
|
||||||
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, new CCustomDecoration(PWINDOW));
|
|
||||||
}
|
|
||||||
|
|
||||||
void hkFocusWindow(void* thisptr, CWindow* pWindow, wlr_surface* pSurface) {
|
|
||||||
// HyprlandAPI::addNotification(PHANDLE, getFormat("FocusWindow with %lx %lx", pWindow, pSurface), CColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
|
||||||
(*(origFocusWindow)g_pFocusHook->m_pOriginal)(thisptr, pWindow, pSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hkNotifyMotion(wlr_seat* wlr_seat, uint32_t time_msec, double sx, double sy) {
|
|
||||||
// HyprlandAPI::addNotification(PHANDLE, getFormat("NotifyMotion with %lf %lf", sx, sy), CColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
|
||||||
(*(origMotion)g_pMotionHook->m_pOriginal)(wlr_seat, time_msec, sx, sy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hkProcessMouseDownNormal(void* thisptr, wlr_pointer_button_event* e) {
|
|
||||||
// HyprlandAPI::addNotification(PHANDLE, "Mouse down normal!", CColor{0.8f, 0.2f, 0.5f, 1.0f}, 5000);
|
|
||||||
(*(origMouseDownNormal)g_pMouseDownHook->m_pOriginal)(thisptr, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
|
||||||
PHANDLE = handle;
|
|
||||||
|
|
||||||
HyprlandAPI::addNotification(PHANDLE, "Hello World from an example plugin!", CColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
|
||||||
|
|
||||||
HyprlandAPI::registerCallbackDynamic(PHANDLE, "activeWindow", [&](void* self, SCallbackInfo& info, std::any data) { onActiveWindowChange(self, data); });
|
|
||||||
HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, SCallbackInfo& info, std::any data) { onNewWindow(self, data); });
|
|
||||||
|
|
||||||
g_pCustomLayout = std::make_unique<CHyprCustomLayout>();
|
|
||||||
|
|
||||||
HyprlandAPI::addLayout(PHANDLE, "custom", g_pCustomLayout.get());
|
|
||||||
|
|
||||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:example:border_color", SConfigValue{.intValue = configStringToInt("rgb(44ee44)")});
|
|
||||||
|
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "example", [](std::string arg) { HyprlandAPI::addNotification(PHANDLE, "Arg passed: " + arg, CColor{0.5f, 0.5f, 0.7f, 1.0f}, 5000); });
|
|
||||||
|
|
||||||
// Hook a public member
|
|
||||||
g_pFocusHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&CCompositor::focusWindow, (void*)&hkFocusWindow);
|
|
||||||
// Hook a public non-member
|
|
||||||
g_pMotionHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&wlr_seat_pointer_notify_motion, (void*)&hkNotifyMotion);
|
|
||||||
// Hook a private member
|
|
||||||
static const auto METHODS = HyprlandAPI::findFunctionsByName(PHANDLE, "processMouseDownNormal");
|
|
||||||
g_pMouseDownHook = HyprlandAPI::createFunctionHook(PHANDLE, METHODS[0].address, (void*)&hkProcessMouseDownNormal);
|
|
||||||
|
|
||||||
static auto* const PBORDERCOLOR = HyprlandAPI::getConfigValue(PHANDLE, "plugin:example:border_color");
|
|
||||||
|
|
||||||
// fancy notifications
|
|
||||||
HyprlandAPI::addNotificationV2(
|
|
||||||
PHANDLE,
|
|
||||||
{{"text", "Example hint, color " + std::to_string(PBORDERCOLOR->intValue)}, {"time", (uint64_t)10000}, {"color", CColor{PBORDERCOLOR->intValue}}, {"icon", ICON_HINT}});
|
|
||||||
|
|
||||||
// Enable our hooks
|
|
||||||
g_pFocusHook->hook();
|
|
||||||
g_pMotionHook->hook();
|
|
||||||
g_pMouseDownHook->hook();
|
|
||||||
|
|
||||||
HyprlandAPI::reloadConfig();
|
|
||||||
|
|
||||||
return {"ExamplePlugin", "An example plugin", "Vaxry", "1.0"};
|
|
||||||
}
|
|
||||||
|
|
||||||
APICALL EXPORT void PLUGIN_EXIT() {
|
|
||||||
HyprlandAPI::invokeHyprctlCommand("seterror", "disable");
|
|
||||||
}
|
|
||||||
@@ -1,28 +1,171 @@
|
|||||||
# This is an example Hyprland config file.
|
# This is an example Hyprland config file.
|
||||||
#
|
|
||||||
# Refer to the wiki for more information.
|
# Refer to the wiki for more information.
|
||||||
|
# https://wiki.hyprland.org/Configuring/
|
||||||
|
|
||||||
#
|
|
||||||
# Please note not all available settings / options are set here.
|
# Please note not all available settings / options are set here.
|
||||||
# For a full list, see the wiki
|
# For a full list, see the wiki
|
||||||
#
|
|
||||||
|
# You can split this configuration into multiple files
|
||||||
|
# Create your files separately and then link them to this file like this:
|
||||||
|
# source = ~/.config/hypr/myColors.conf
|
||||||
|
|
||||||
|
|
||||||
|
################
|
||||||
|
### MONITORS ###
|
||||||
|
################
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Monitors/
|
# See https://wiki.hyprland.org/Configuring/Monitors/
|
||||||
monitor=,preferred,auto,auto
|
monitor=,preferred,auto,auto
|
||||||
|
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
|
###################
|
||||||
|
### MY PROGRAMS ###
|
||||||
|
###################
|
||||||
|
|
||||||
# Execute your favorite apps at launch
|
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||||
|
|
||||||
|
# Set programs that you use
|
||||||
|
$terminal = kitty
|
||||||
|
$fileManager = dolphin
|
||||||
|
$menu = wofi --show drun
|
||||||
|
|
||||||
|
|
||||||
|
#################
|
||||||
|
### AUTOSTART ###
|
||||||
|
#################
|
||||||
|
|
||||||
|
# Autostart necessary processes (like notifications daemons, status bars, etc.)
|
||||||
|
# Or execute your favorite apps at launch like this:
|
||||||
|
|
||||||
|
# exec-once = $terminal
|
||||||
|
# exec-once = nm-applet &
|
||||||
# exec-once = waybar & hyprpaper & firefox
|
# exec-once = waybar & hyprpaper & firefox
|
||||||
|
|
||||||
# Source a file (multi-file configs)
|
|
||||||
# source = ~/.config/hypr/myColors.conf
|
|
||||||
|
|
||||||
# Some default env vars.
|
#############################
|
||||||
|
### ENVIRONMENT VARIABLES ###
|
||||||
|
#############################
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Environment-variables/
|
||||||
|
|
||||||
env = XCURSOR_SIZE,24
|
env = XCURSOR_SIZE,24
|
||||||
|
env = HYPRCURSOR_SIZE,24
|
||||||
|
|
||||||
# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
|
|
||||||
|
#####################
|
||||||
|
### LOOK AND FEEL ###
|
||||||
|
#####################
|
||||||
|
|
||||||
|
# Refer to https://wiki.hyprland.org/Configuring/Variables/
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#general
|
||||||
|
general {
|
||||||
|
gaps_in = 5
|
||||||
|
gaps_out = 20
|
||||||
|
|
||||||
|
border_size = 2
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#variable-types for info about colors
|
||||||
|
col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
|
||||||
|
col.inactive_border = rgba(595959aa)
|
||||||
|
|
||||||
|
# Set to true enable resizing windows by clicking and dragging on borders and gaps
|
||||||
|
resize_on_border = false
|
||||||
|
|
||||||
|
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
|
||||||
|
allow_tearing = false
|
||||||
|
|
||||||
|
layout = dwindle
|
||||||
|
}
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||||
|
decoration {
|
||||||
|
rounding = 10
|
||||||
|
|
||||||
|
# Change transparency of focused and unfocused windows
|
||||||
|
active_opacity = 1.0
|
||||||
|
inactive_opacity = 1.0
|
||||||
|
|
||||||
|
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 = yes, please :)
|
||||||
|
|
||||||
|
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||||
|
|
||||||
|
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 = 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
|
||||||
|
preserve_split = true # You probably want this
|
||||||
|
}
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
|
||||||
|
master {
|
||||||
|
new_status = master
|
||||||
|
}
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#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. :(
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#############
|
||||||
|
### INPUT ###
|
||||||
|
#############
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#input
|
||||||
input {
|
input {
|
||||||
kb_layout = us
|
kb_layout = us
|
||||||
kb_variant =
|
kb_variant =
|
||||||
@@ -32,106 +175,40 @@ input {
|
|||||||
|
|
||||||
follow_mouse = 1
|
follow_mouse = 1
|
||||||
|
|
||||||
|
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
|
||||||
|
|
||||||
touchpad {
|
touchpad {
|
||||||
natural_scroll = false
|
natural_scroll = false
|
||||||
}
|
}
|
||||||
|
|
||||||
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
|
|
||||||
}
|
|
||||||
|
|
||||||
general {
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
|
||||||
|
|
||||||
gaps_in = 5
|
|
||||||
gaps_out = 20
|
|
||||||
border_size = 2
|
|
||||||
col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
|
|
||||||
col.inactive_border = rgba(595959aa)
|
|
||||||
|
|
||||||
layout = dwindle
|
|
||||||
|
|
||||||
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
|
|
||||||
allow_tearing = false
|
|
||||||
}
|
|
||||||
|
|
||||||
decoration {
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
|
||||||
|
|
||||||
rounding = 10
|
|
||||||
|
|
||||||
blur {
|
|
||||||
enabled = true
|
|
||||||
size = 3
|
|
||||||
passes = 1
|
|
||||||
|
|
||||||
vibrancy = 0.1696
|
|
||||||
}
|
|
||||||
|
|
||||||
drop_shadow = true
|
|
||||||
shadow_range = 4
|
|
||||||
shadow_render_power = 3
|
|
||||||
col.shadow = rgba(1a1a1aee)
|
|
||||||
}
|
|
||||||
|
|
||||||
animations {
|
|
||||||
enabled = true
|
|
||||||
|
|
||||||
# Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
|
||||||
|
|
||||||
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
dwindle {
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
|
||||||
pseudotile = true # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
|
||||||
preserve_split = true # you probably want this
|
|
||||||
}
|
|
||||||
|
|
||||||
master {
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
|
|
||||||
new_is_master = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# https://wiki.hyprland.org/Configuring/Variables/#gestures
|
||||||
gestures {
|
gestures {
|
||||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
|
||||||
workspace_swipe = false
|
workspace_swipe = false
|
||||||
}
|
}
|
||||||
|
|
||||||
misc {
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Variables/ for more
|
|
||||||
force_default_wallpaper = -1 # Set to 0 to disable the anime mascot wallpapers
|
|
||||||
}
|
|
||||||
|
|
||||||
# Example per-device config
|
# Example per-device config
|
||||||
# See https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs for more
|
# See https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs for more
|
||||||
device:epic-mouse-v1 {
|
device {
|
||||||
|
name = epic-mouse-v1
|
||||||
sensitivity = -0.5
|
sensitivity = -0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
# Example windowrule v1
|
|
||||||
# windowrule = float, ^(kitty)$
|
|
||||||
# Example windowrule v2
|
|
||||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
|
|
||||||
|
|
||||||
|
###################
|
||||||
|
### KEYBINDINGS ###
|
||||||
|
###################
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
|
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||||
$mainMod = SUPER
|
$mainMod = SUPER # Sets "Windows" key as main modifier
|
||||||
|
|
||||||
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
|
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
|
||||||
bind = $mainMod, Q, exec, kitty
|
bind = $mainMod, Q, exec, $terminal
|
||||||
bind = $mainMod, C, killactive,
|
bind = $mainMod, C, killactive,
|
||||||
bind = $mainMod, M, exit,
|
bind = $mainMod, M, exit,
|
||||||
bind = $mainMod, E, exec, dolphin
|
bind = $mainMod, E, exec, $fileManager
|
||||||
bind = $mainMod, V, togglefloating,
|
bind = $mainMod, V, togglefloating,
|
||||||
bind = $mainMod, R, exec, wofi --show drun
|
bind = $mainMod, R, exec, $menu
|
||||||
bind = $mainMod, P, pseudo, # dwindle
|
bind = $mainMod, P, pseudo, # dwindle
|
||||||
bind = $mainMod, J, togglesplit, # dwindle
|
bind = $mainMod, J, togglesplit, # dwindle
|
||||||
|
|
||||||
@@ -176,3 +253,36 @@ bind = $mainMod, mouse_up, workspace, e-1
|
|||||||
# Move/resize windows with mainMod + LMB/RMB and dragging
|
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||||
bindm = $mainMod, mouse:272, movewindow
|
bindm = $mainMod, mouse:272, movewindow
|
||||||
bindm = $mainMod, mouse:273, resizewindow
|
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 ###
|
||||||
|
##############################
|
||||||
|
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
|
||||||
|
# See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules
|
||||||
|
|
||||||
|
# Example windowrule v1
|
||||||
|
# windowrule = float, ^(kitty)$
|
||||||
|
|
||||||
|
# Example windowrule v2
|
||||||
|
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|||||||
@@ -3,3 +3,5 @@ Name=Hyprland
|
|||||||
Comment=An intelligent dynamic tiling Wayland compositor
|
Comment=An intelligent dynamic tiling Wayland compositor
|
||||||
Exec=Hyprland
|
Exec=Hyprland
|
||||||
Type=Application
|
Type=Application
|
||||||
|
DesktopNames=Hyprland
|
||||||
|
Keywords=tiling;wayland;compositor;
|
||||||
|
|||||||
@@ -1,2 +1,10 @@
|
|||||||
install_data('hyprland.conf', install_dir: join_paths(get_option('datadir'), 'hyprland'), install_tag: 'runtime')
|
install_data(
|
||||||
install_data('hyprland.desktop', install_dir: join_paths(get_option('datadir'), 'wayland-sessions'), install_tag: 'runtime')
|
'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',
|
||||||
|
)
|
||||||
|
|||||||
310
flake.lock
generated
@@ -1,5 +1,123 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"aquamarine": {
|
||||||
|
"inputs": {
|
||||||
|
"hyprutils": [
|
||||||
|
"hyprutils"
|
||||||
|
],
|
||||||
|
"hyprwayland-scanner": [
|
||||||
|
"hyprwayland-scanner"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1734364797,
|
||||||
|
"narHash": "sha256-2h1c+P0v3l0Z/ypUSsAPhU/yiSRgFwjVFODWp0S3d/w=",
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "aquamarine",
|
||||||
|
"rev": "8e77618b403a82fde2105a8e3cd7cabe7ef00952",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "aquamarine",
|
||||||
|
"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": [
|
||||||
|
"hyprlang"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1734364709,
|
||||||
|
"narHash": "sha256-+2bZJL2u5hva7rSp65OfKJBK+k03T6GB/NCvpoS1OOo=",
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprcursor",
|
||||||
|
"rev": "f388aacd22be4a6e4d634fbaf6f75eb0713d239a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprcursor",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hyprgraphics": {
|
||||||
|
"inputs": {
|
||||||
|
"hyprutils": [
|
||||||
|
"hyprutils"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1733684019,
|
||||||
|
"narHash": "sha256-2kYREgmSmbLsmDpLEq96hxVAU3qz8aCvVhF65yCFZHY=",
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprgraphics",
|
||||||
|
"rev": "fb2c0268645a77403af3b8a4ce8fa7ba5917f15d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprgraphics",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hyprland-protocols": {
|
"hyprland-protocols": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -10,11 +128,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1691753796,
|
"lastModified": 1728345020,
|
||||||
"narHash": "sha256-zOEwiWoXk3j3+EoF3ySUJmberFewWlagvewDRuWYAso=",
|
"narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprland-protocols",
|
"repo": "hyprland-protocols",
|
||||||
"rev": "0c2ce70625cb30aef199cb388f99e19a61a6ce03",
|
"rev": "a7c183800e74f337753de186522b9017a07a8cee",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -23,13 +141,111 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"hyprland-qtutils": {
|
||||||
|
"inputs": {
|
||||||
|
"hyprutils": [
|
||||||
|
"hyprutils"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1733940128,
|
||||||
|
"narHash": "sha256-hmfXWj2GA9cj1QUkPFYtAAeohhs615zL4E3APy3FnvQ=",
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprland-qtutils",
|
||||||
|
"rev": "3833097e50473a152dd614d4b468886840b4ea78",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprland-qtutils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hyprlang": {
|
||||||
|
"inputs": {
|
||||||
|
"hyprutils": [
|
||||||
|
"hyprutils"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1734364628,
|
||||||
|
"narHash": "sha256-ii8fzJfI953n/EmIxVvq64ZAwhvwuuPHWfGd61/mJG8=",
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprlang",
|
||||||
|
"rev": "16e59c1eb13d9fb6de066f54e7555eb5e8a4aba5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprlang",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hyprutils": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1733502241,
|
||||||
|
"narHash": "sha256-KAUNC4Dgq8WQjYov5auBw/usaHixhacvb7cRDd0AG/k=",
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprutils",
|
||||||
|
"rev": "104117aed6dd68561be38b50f218190aa47f2cd8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprutils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hyprwayland-scanner": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": [
|
||||||
|
"systems"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1726874836,
|
||||||
|
"narHash": "sha256-VKR0sf0PSNCB0wPHVKSAn41mCNVCnegWmgkrneKDhHM=",
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprwayland-scanner",
|
||||||
|
"rev": "500c81a9e1a76760371049a8d99e008ea77aa59e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hyprwm",
|
||||||
|
"repo": "hyprwayland-scanner",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1698134075,
|
"lastModified": 1734119587,
|
||||||
"narHash": "sha256-foCD+nuKzfh49bIoiCBur4+Fx1nozo+4C/6k8BYk4sg=",
|
"narHash": "sha256-AKU6qqskl0yf2+JdRdD0cfxX4b9x3KKV5RqA6wijmPM=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "8efd5d1e283604f75a808a20e6cde0ef313d07d4",
|
"rev": "3566ab7246670a43abd2ffa913cc62dad9cdf7d5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -39,12 +255,58 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1730741070,
|
||||||
|
"narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-24.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pre-commit-hooks": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"gitignore": "gitignore",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"nixpkgs-stable": "nixpkgs-stable"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1734279981,
|
||||||
|
"narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"aquamarine": "aquamarine",
|
||||||
|
"hyprcursor": "hyprcursor",
|
||||||
|
"hyprgraphics": "hyprgraphics",
|
||||||
"hyprland-protocols": "hyprland-protocols",
|
"hyprland-protocols": "hyprland-protocols",
|
||||||
|
"hyprland-qtutils": "hyprland-qtutils",
|
||||||
|
"hyprlang": "hyprlang",
|
||||||
|
"hyprutils": "hyprutils",
|
||||||
|
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
"pre-commit-hooks": "pre-commit-hooks",
|
||||||
"systems": "systems",
|
"systems": "systems",
|
||||||
"wlroots": "wlroots",
|
|
||||||
"xdph": "xdph"
|
"xdph": "xdph"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -63,30 +325,20 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"wlroots": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"host": "gitlab.freedesktop.org",
|
|
||||||
"lastModified": 1697909146,
|
|
||||||
"narHash": "sha256-jU0I6FoCKnj4zIBL4daosFWh81U1fM719Z6cae8PxSY=",
|
|
||||||
"owner": "wlroots",
|
|
||||||
"repo": "wlroots",
|
|
||||||
"rev": "47bf87ade2bd32395615a385ebde1fefbcdf79a2",
|
|
||||||
"type": "gitlab"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"host": "gitlab.freedesktop.org",
|
|
||||||
"owner": "wlroots",
|
|
||||||
"repo": "wlroots",
|
|
||||||
"rev": "47bf87ade2bd32395615a385ebde1fefbcdf79a2",
|
|
||||||
"type": "gitlab"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"xdph": {
|
"xdph": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"hyprland-protocols": [
|
"hyprland-protocols": [
|
||||||
"hyprland-protocols"
|
"hyprland-protocols"
|
||||||
],
|
],
|
||||||
|
"hyprlang": [
|
||||||
|
"hyprlang"
|
||||||
|
],
|
||||||
|
"hyprutils": [
|
||||||
|
"hyprutils"
|
||||||
|
],
|
||||||
|
"hyprwayland-scanner": [
|
||||||
|
"hyprwayland-scanner"
|
||||||
|
],
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
@@ -95,11 +347,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1697981233,
|
"lastModified": 1734124279,
|
||||||
"narHash": "sha256-y8q4XUwx+gVK7i2eLjfR32lVo7TYvEslyzrmzYEaPZU=",
|
"narHash": "sha256-YNpFfiQjYt2o6LGcMN9NkjVvprC8ELrIpLHlbZbclRM=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "xdg-desktop-portal-hyprland",
|
"repo": "xdg-desktop-portal-hyprland",
|
||||||
"rev": "22e7a65ff9633e1dedfa5317fdffc49f68de2ff2",
|
"rev": "0c6861f819f6d31f6195c9864709b2556f00b5cf",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
113
flake.nix
@@ -7,13 +7,26 @@
|
|||||||
# <https://github.com/nix-systems/nix-systems>
|
# <https://github.com/nix-systems/nix-systems>
|
||||||
systems.url = "github:nix-systems/default-linux";
|
systems.url = "github:nix-systems/default-linux";
|
||||||
|
|
||||||
wlroots = {
|
aquamarine = {
|
||||||
type = "gitlab";
|
url = "github:hyprwm/aquamarine";
|
||||||
host = "gitlab.freedesktop.org";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
owner = "wlroots";
|
inputs.systems.follows = "systems";
|
||||||
repo = "wlroots";
|
inputs.hyprutils.follows = "hyprutils";
|
||||||
rev = "47bf87ade2bd32395615a385ebde1fefbcdf79a2";
|
inputs.hyprwayland-scanner.follows = "hyprwayland-scanner";
|
||||||
flake = false;
|
};
|
||||||
|
|
||||||
|
hyprcursor = {
|
||||||
|
url = "github:hyprwm/hyprcursor";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
inputs.hyprlang.follows = "hyprlang";
|
||||||
|
};
|
||||||
|
|
||||||
|
hyprgraphics = {
|
||||||
|
url = "github:hyprwm/hyprgraphics";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
inputs.hyprutils.follows = "hyprutils";
|
||||||
};
|
};
|
||||||
|
|
||||||
hyprland-protocols = {
|
hyprland-protocols = {
|
||||||
@@ -22,11 +35,45 @@
|
|||||||
inputs.systems.follows = "systems";
|
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";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
inputs.hyprutils.follows = "hyprutils";
|
||||||
|
};
|
||||||
|
|
||||||
|
hyprutils = {
|
||||||
|
url = "github:hyprwm/hyprutils";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
};
|
||||||
|
|
||||||
|
hyprwayland-scanner = {
|
||||||
|
url = "github:hyprwm/hyprwayland-scanner";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
};
|
||||||
|
|
||||||
xdph = {
|
xdph = {
|
||||||
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
inputs.systems.follows = "systems";
|
inputs.systems.follows = "systems";
|
||||||
inputs.hyprland-protocols.follows = "hyprland-protocols";
|
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";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,6 +93,15 @@
|
|||||||
hyprland-extras
|
hyprland-extras
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
pkgsCrossFor = eachSystem (system: crossSystem:
|
||||||
|
import nixpkgs {
|
||||||
|
localSystem = system;
|
||||||
|
inherit crossSystem;
|
||||||
|
overlays = with self.overlays; [
|
||||||
|
hyprland-packages
|
||||||
|
hyprland-extras
|
||||||
|
];
|
||||||
|
});
|
||||||
in {
|
in {
|
||||||
overlays = import ./nix/overlays.nix {inherit self lib inputs;};
|
overlays = import ./nix/overlays.nix {inherit self lib inputs;};
|
||||||
|
|
||||||
@@ -55,6 +111,18 @@
|
|||||||
self.packages.${system})
|
self.packages.${system})
|
||||||
// {
|
// {
|
||||||
inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
|
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: {
|
packages = eachSystem (system: {
|
||||||
@@ -63,40 +131,31 @@
|
|||||||
(pkgsFor.${system})
|
(pkgsFor.${system})
|
||||||
# hyprland-packages
|
# hyprland-packages
|
||||||
hyprland
|
hyprland
|
||||||
hyprland-unwrapped
|
|
||||||
hyprland-debug
|
hyprland-debug
|
||||||
hyprland-nvidia
|
hyprland-legacy-renderer
|
||||||
|
hyprland-unwrapped
|
||||||
# hyprland-extras
|
# hyprland-extras
|
||||||
xdg-desktop-portal-hyprland
|
xdg-desktop-portal-hyprland
|
||||||
# dependencies
|
|
||||||
hyprland-protocols
|
|
||||||
wlroots-hyprland
|
|
||||||
udis86
|
|
||||||
;
|
;
|
||||||
|
hyprland-cross = (pkgsCrossFor.${system} "aarch64-linux").hyprland;
|
||||||
});
|
});
|
||||||
|
|
||||||
devShells = eachSystem (system: {
|
devShells = eachSystem (system: {
|
||||||
default = pkgsFor.${system}.mkShell.override {
|
default =
|
||||||
stdenv = pkgsFor.${system}.gcc13Stdenv;
|
pkgsFor.${system}.mkShell.override {
|
||||||
|
inherit (self.packages.${system}.default) stdenv;
|
||||||
} {
|
} {
|
||||||
name = "hyprland-shell";
|
name = "hyprland-shell";
|
||||||
nativeBuildInputs = with pkgsFor.${system}; [cmake python3];
|
hardeningDisable = ["fortify"];
|
||||||
buildInputs = [self.packages.${system}.wlroots-hyprland];
|
inputsFrom = [pkgsFor.${system}.hyprland];
|
||||||
inputsFrom = [
|
packages = [pkgsFor.${system}.clang-tools];
|
||||||
self.packages.${system}.wlroots-hyprland
|
inherit (self.checks.${system}.pre-commit-check) shellHook;
|
||||||
self.packages.${system}.hyprland
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
formatter = eachSystem (system: pkgsFor.${system}.callPackage ./nix/formatter.nix {});
|
||||||
|
|
||||||
nixosModules.default = import ./nix/module.nix inputs;
|
nixosModules.default = import ./nix/module.nix inputs;
|
||||||
homeManagerModules.default = import ./nix/hm-module.nix self;
|
homeManagerModules.default = import ./nix/hm-module.nix self;
|
||||||
};
|
};
|
||||||
|
|
||||||
nixConfig = {
|
|
||||||
extra-substituters = ["https://hyprland.cachix.org"];
|
|
||||||
extra-trusted-public-keys = ["hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,21 @@ project(
|
|||||||
DESCRIPTION "Control utility for Hyprland"
|
DESCRIPTION "Control utility for Hyprland"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
pkg_check_modules(hyprctl_deps REQUIRED IMPORTED_TARGET hyprutils>=0.2.4 re2)
|
||||||
|
|
||||||
add_executable(hyprctl "main.cpp")
|
add_executable(hyprctl "main.cpp")
|
||||||
|
|
||||||
|
target_link_libraries(hyprctl PUBLIC PkgConfig::hyprctl_deps)
|
||||||
|
|
||||||
|
# binary
|
||||||
|
install(TARGETS hyprctl)
|
||||||
|
|
||||||
|
# shell completions
|
||||||
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/hyprctl.bash
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/bash-completion/completions
|
||||||
|
RENAME hyprctl)
|
||||||
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/hyprctl.fish
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/fish/vendor_completions.d)
|
||||||
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/hyprctl.zsh
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/zsh/site-functions
|
||||||
|
RENAME _hyprctl)
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
all:
|
|
||||||
$(CXX) -std=c++2b ./main.cpp -o ./hyprctl
|
|
||||||
clean:
|
|
||||||
rm ./hyprctl
|
|
||||||
162
hyprctl/Strings.hpp
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
const std::string_view USAGE = R"#(usage: hyprctl [flags] <command> [args...|--help]
|
||||||
|
|
||||||
|
commands:
|
||||||
|
activewindow → Gets the active window name and its properties
|
||||||
|
activeworkspace → Gets the active workspace and its properties
|
||||||
|
animations → Gets the current config'd info about animations
|
||||||
|
and beziers
|
||||||
|
binds → Lists all registered binds
|
||||||
|
clients → Lists all windows with their properties
|
||||||
|
configerrors → Lists all current config parsing errors
|
||||||
|
cursorpos → Gets the current cursor position in global layout
|
||||||
|
coordinates
|
||||||
|
decorations <window_regex> → Lists all decorations and their info
|
||||||
|
devices → Lists all connected keyboards and mice
|
||||||
|
dismissnotify [amount] → Dismisses all or up to AMOUNT notifications
|
||||||
|
dispatch <dispatcher> [args] → Issue a dispatch to call a keybind
|
||||||
|
dispatcher with arguments
|
||||||
|
getoption <option> → Gets the config option status (values)
|
||||||
|
globalshortcuts → Lists all global shortcuts
|
||||||
|
hyprpaper ... → Issue a hyprpaper request
|
||||||
|
instances → Lists all running instances of Hyprland with
|
||||||
|
their info
|
||||||
|
keyword <name> <value> → Issue a keyword to call a config keyword
|
||||||
|
dynamically
|
||||||
|
kill → Issue a kill to get into a kill mode, where you can
|
||||||
|
kill an app by clicking on it. You can exit it
|
||||||
|
with ESCAPE
|
||||||
|
layers → Lists all the surface layers
|
||||||
|
layouts → Lists all layouts available (including plugin'd ones)
|
||||||
|
monitors → Lists active outputs with their properties,
|
||||||
|
'monitors all' lists active and inactive outputs
|
||||||
|
notify ... → Sends a notification using the built-in Hyprland
|
||||||
|
notification system
|
||||||
|
output ... → Allows you to add and remove fake outputs to your
|
||||||
|
preferred backend
|
||||||
|
plugin ... → Issue a plugin request
|
||||||
|
reload [config-only] → Issue a reload to force reload the config. Pass
|
||||||
|
'config-only' to disable monitor reload
|
||||||
|
rollinglog → Prints tail of the log. Also supports -f/--follow
|
||||||
|
option
|
||||||
|
setcursor <theme> <size> → Sets the cursor theme and reloads the cursor
|
||||||
|
manager
|
||||||
|
seterror <color> <message...> → Sets the hyprctl error string. Color has
|
||||||
|
the same format as in colors in config. Will reset
|
||||||
|
when Hyprland's config is reloaded
|
||||||
|
setprop ... → Sets a window property
|
||||||
|
splash → Get the current splash
|
||||||
|
switchxkblayout ... → Sets the xkb layout index for a keyboard
|
||||||
|
systeminfo → Get system info
|
||||||
|
version → Prints the hyprland version, meaning flags, commit
|
||||||
|
and branch of build.
|
||||||
|
workspacerules → Lists all workspace rules
|
||||||
|
workspaces → Lists all workspaces with their properties
|
||||||
|
|
||||||
|
flags:
|
||||||
|
-j → Output in JSON
|
||||||
|
-r → Refresh state after issuing command (e.g. for
|
||||||
|
updating variables)
|
||||||
|
--batch → Execute a batch of commands, separated by ';'
|
||||||
|
--instance (-i) → use a specific instance. Can be either signature or
|
||||||
|
index in hyprctl instances (0, 1, etc)
|
||||||
|
--quiet (-q) → Disable the output of hyprctl
|
||||||
|
|
||||||
|
--help:
|
||||||
|
Can be used to print command's arguments that did not fit into this page
|
||||||
|
(three dots))#";
|
||||||
|
|
||||||
|
const std::string_view HYPRPAPER_HELP = R"#(usage: hyprctl [flags] hyprpaper <request>
|
||||||
|
|
||||||
|
requests:
|
||||||
|
listactive → Lists all active images
|
||||||
|
listloaded → Lists all loaded images
|
||||||
|
preload <path> → Preloads image
|
||||||
|
unload <path> → Unloads image. Pass 'all' as path to unload all images
|
||||||
|
wallpaper → Issue a wallpaper to call a config wallpaper dynamically
|
||||||
|
|
||||||
|
flags:
|
||||||
|
See 'hyprctl --help')#";
|
||||||
|
|
||||||
|
const std::string_view NOTIFY_HELP = R"#(usage: hyprctl [flags] notify <icon> <time_ms> <color> <message...>
|
||||||
|
|
||||||
|
icon:
|
||||||
|
Integer of value:
|
||||||
|
0 → Warning
|
||||||
|
1 → Info
|
||||||
|
2 → Hint
|
||||||
|
3 → Error
|
||||||
|
4 → Confused
|
||||||
|
5 → Ok
|
||||||
|
6 or -1 → No icon
|
||||||
|
|
||||||
|
time_ms:
|
||||||
|
Time to display notification in milliseconds
|
||||||
|
|
||||||
|
color:
|
||||||
|
Notification color. Format is the same as for colors in hyprland.conf. Use
|
||||||
|
0 for default color for icon
|
||||||
|
|
||||||
|
message:
|
||||||
|
Notification message
|
||||||
|
|
||||||
|
flags:
|
||||||
|
See 'hyprctl --help')#";
|
||||||
|
|
||||||
|
const std::string_view OUTPUT_HELP = R"#(usage: hyprctl [flags] output <create <backend> | remove <name>>
|
||||||
|
|
||||||
|
create <backend>:
|
||||||
|
Creates new virtual output. Possible values for backend: wayland, x11,
|
||||||
|
headless or auto.
|
||||||
|
|
||||||
|
remove <name>:
|
||||||
|
Removes virtual output. Pass the output's name, as found in
|
||||||
|
'hyprctl monitors'
|
||||||
|
|
||||||
|
flags:
|
||||||
|
See 'hyprctl --help')#";
|
||||||
|
|
||||||
|
const std::string_view PLUGIN_HELP = R"#(usage: hyprctl [flags] plugin <request>
|
||||||
|
|
||||||
|
requests:
|
||||||
|
load <path> → Loads a plugin. Path must be absolute
|
||||||
|
unload <path> → Unloads a plugin. Path must be absolute
|
||||||
|
list → Lists all loaded plugins
|
||||||
|
|
||||||
|
flags:
|
||||||
|
See 'hyprctl --help')#";
|
||||||
|
|
||||||
|
const std::string_view SETPROP_HELP = R"#(usage: hyprctl [flags] setprop <regex> <property> <value> [lock]
|
||||||
|
|
||||||
|
regex:
|
||||||
|
Regular expression by which a window will be searched
|
||||||
|
|
||||||
|
property:
|
||||||
|
See https://wiki.hyprland.org/Configuring/Using-hyprctl/#setprop for list
|
||||||
|
of properties
|
||||||
|
|
||||||
|
value:
|
||||||
|
Property value
|
||||||
|
|
||||||
|
lock:
|
||||||
|
Optional argument. If lock is not added, will be unlocked. Locking means a
|
||||||
|
dynamic windowrule cannot override this setting.
|
||||||
|
|
||||||
|
flags:
|
||||||
|
See 'hyprctl --help')#";
|
||||||
|
|
||||||
|
const std::string_view SWITCHXKBLAYOUT_HELP = R"#(usage: [flags] switchxkblayout <device> <cmd>
|
||||||
|
|
||||||
|
device:
|
||||||
|
You can find the device using 'hyprctl devices' command
|
||||||
|
|
||||||
|
cmd:
|
||||||
|
'next' for next, 'prev' for previous, or ID for a specific one. IDs are
|
||||||
|
assigned based on their order in config file (keyboard_layout),
|
||||||
|
starting from 0
|
||||||
|
|
||||||
|
flags:
|
||||||
|
See 'hyprctl --help')#";
|
||||||
128
hyprctl/hyprctl.bash
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
_hyprctl_cmd_1 () {
|
||||||
|
hyprctl monitors | awk '/Monitor/{ print $2 }'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprctl_cmd_3 () {
|
||||||
|
hyprctl clients | awk '/class/{print $2}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprctl_cmd_2 () {
|
||||||
|
hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprctl_cmd_0 () {
|
||||||
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprctl () {
|
||||||
|
if [[ $(type -t _get_comp_words_by_ref) != function ]]; then
|
||||||
|
echo _get_comp_words_by_ref: function not defined. Make sure the bash-completions system package is installed
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local words cword
|
||||||
|
_get_comp_words_by_ref -n "$COMP_WORDBREAKS" words cword
|
||||||
|
|
||||||
|
declare -a literals=(resizeactive 2 changegroupactive -r moveintogroup forceallowsinput 4 ::= systeminfo all layouts setprop animationstyle switchxkblayout create denywindowfromgroup headless activebordercolor exec setcursor wayland focusurgentorlast workspacerules movecurrentworkspacetomonitor movetoworkspacesilent hyprpaper alpha inactivebordercolor movegroupwindow movecursortocorner movewindowpixel prev movewindow globalshortcuts clients dimaround setignoregrouplock splash execr monitors 0 forcenoborder -q animations 1 nomaxsize splitratio moveactive pass swapnext devices layers rounding lockactivegroup 5 moveworkspacetomonitor -f -i --quiet forcenodim pin 0 1 forceopaque forcenoshadow setfloating minsize alphaoverride sendshortcut workspaces cyclenext alterzorder togglegroup lockgroups bordersize dpms focuscurrentorlast -1 --batch notify remove instances 1 3 moveoutofgroup killactive 2 movetoworkspace movecursor configerrors closewindow swapwindow tagwindow forcerendererreload centerwindow auto focuswindow seterror nofocus alphafullscreen binds version -h togglespecialworkspace fullscreen windowdancecompat 0 keyword toggleopaque 3 --instance togglefloating renameworkspace alphafullscreenoverride activeworkspace x11 kill forceopaqueoverriden output global dispatch reload forcenoblur -j event --help disable -1 activewindow keepaspectratio dismissnotify focusmonitor movefocus plugin exit workspace fullscreenstate getoption alphainactiveoverride alphainactive decorations settiled config-only descriptions resizewindowpixel fakefullscreen rollinglog swapactiveworkspaces submap next movewindoworgroup cursorpos forcenoanims focusworkspaceoncurrentmonitor maxsize)
|
||||||
|
declare -A literal_transitions
|
||||||
|
literal_transitions[0]="([120]=14 [43]=2 [125]=21 [81]=2 [3]=21 [51]=2 [50]=2 [128]=2 [89]=2 [58]=21 [8]=2 [10]=2 [11]=3 [130]=4 [13]=5 [97]=6 [101]=2 [102]=21 [133]=7 [100]=2 [137]=2 [22]=2 [19]=2 [140]=8 [25]=2 [143]=2 [107]=9 [146]=10 [69]=2 [33]=2 [34]=2 [78]=21 [114]=2 [37]=2 [151]=2 [116]=2 [121]=13 [123]=21 [39]=11 [42]=21 [79]=15 [118]=12)"
|
||||||
|
literal_transitions[1]="([81]=2 [51]=2 [50]=2 [128]=2 [8]=2 [89]=2 [10]=2 [11]=3 [130]=4 [13]=5 [97]=6 [101]=2 [133]=7 [100]=2 [22]=2 [19]=2 [137]=2 [140]=8 [25]=2 [143]=2 [107]=9 [146]=10 [69]=2 [33]=2 [34]=2 [114]=2 [37]=2 [151]=2 [116]=2 [39]=11 [118]=12 [121]=13 [120]=14 [79]=15 [43]=2)"
|
||||||
|
literal_transitions[3]="([139]=2 [63]=16 [64]=16 [45]=16 [105]=16 [27]=2 [26]=2 [52]=4 [5]=16 [66]=2 [67]=16 [129]=16 [113]=16 [12]=2 [74]=4 [99]=2 [35]=16 [152]=16 [98]=16 [59]=16 [117]=16 [41]=16 [17]=2 [138]=16 [154]=2 [122]=16)"
|
||||||
|
literal_transitions[6]="([126]=2)"
|
||||||
|
literal_transitions[10]="([56]=2)"
|
||||||
|
literal_transitions[11]="([9]=2)"
|
||||||
|
literal_transitions[12]="([14]=19 [80]=22)"
|
||||||
|
literal_transitions[13]="([142]=2)"
|
||||||
|
literal_transitions[14]="([0]=2 [84]=2 [2]=2 [85]=2 [4]=2 [87]=2 [88]=2 [90]=2 [91]=2 [92]=2 [93]=2 [94]=2 [96]=2 [15]=2 [18]=2 [103]=2 [21]=2 [104]=2 [23]=2 [24]=2 [28]=2 [29]=2 [30]=2 [108]=2 [111]=2 [32]=2 [112]=2 [36]=2 [38]=2 [119]=2 [124]=2 [46]=2 [47]=2 [48]=2 [49]=2 [53]=2 [55]=2 [131]=2 [132]=2 [134]=2 [135]=2 [60]=2 [136]=20 [141]=2 [65]=2 [144]=2 [145]=2 [68]=2 [147]=2 [70]=2 [71]=2 [72]=2 [73]=2 [148]=2 [75]=2 [76]=2 [150]=2 [153]=2)"
|
||||||
|
literal_transitions[15]="([86]=4 [6]=4 [109]=4 [61]=4 [77]=4 [54]=4 [62]=4)"
|
||||||
|
literal_transitions[16]="([40]=2 [44]=2)"
|
||||||
|
literal_transitions[17]="([7]=23)"
|
||||||
|
literal_transitions[18]="([31]=2 [149]=2)"
|
||||||
|
literal_transitions[19]="([95]=2 [16]=2 [115]=2 [20]=2)"
|
||||||
|
literal_transitions[20]="([106]=2 [82]=2 [127]=2 [1]=2 [83]=2)"
|
||||||
|
literal_transitions[23]="([57]=21 [110]=21)"
|
||||||
|
declare -A match_anything_transitions=([6]=17 [7]=2 [0]=1 [22]=2 [5]=18 [4]=2 [2]=17 [18]=2 [11]=17 [8]=2 [9]=2 [13]=17 [10]=17 [1]=1)
|
||||||
|
declare -A subword_transitions
|
||||||
|
|
||||||
|
local state=0
|
||||||
|
local word_index=1
|
||||||
|
while [[ $word_index -lt $cword ]]; do
|
||||||
|
local word=${words[$word_index]}
|
||||||
|
|
||||||
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
|
declare -A state_transitions
|
||||||
|
eval "state_transitions=${literal_transitions[$state]}"
|
||||||
|
|
||||||
|
local word_matched=0
|
||||||
|
for literal_id in $(seq 0 $((${#literals[@]} - 1))); do
|
||||||
|
if [[ ${literals[$literal_id]} = "$word" ]]; then
|
||||||
|
if [[ -v "state_transitions[$literal_id]" ]]; then
|
||||||
|
state=${state_transitions[$literal_id]}
|
||||||
|
word_index=$((word_index + 1))
|
||||||
|
word_matched=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ $word_matched -ne 0 ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v "match_anything_transitions[$state]" ]]; then
|
||||||
|
state=${match_anything_transitions[$state]}
|
||||||
|
word_index=$((word_index + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
local -a matches=()
|
||||||
|
|
||||||
|
local prefix="${words[$cword]}"
|
||||||
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
|
local state_transitions_initializer=${literal_transitions[$state]}
|
||||||
|
declare -A state_transitions
|
||||||
|
eval "state_transitions=$state_transitions_initializer"
|
||||||
|
|
||||||
|
for literal_id in "${!state_transitions[@]}"; do
|
||||||
|
local literal="${literals[$literal_id]}"
|
||||||
|
if [[ $literal = "${prefix}"* ]]; then
|
||||||
|
matches+=("$literal ")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
declare -A commands
|
||||||
|
commands=([7]=0 [22]=1 [8]=3 [5]=2)
|
||||||
|
if [[ -v "commands[$state]" ]]; then
|
||||||
|
local command_id=${commands[$state]}
|
||||||
|
local completions=()
|
||||||
|
readarray -t completions < <(_hyprctl_cmd_${command_id} "$prefix" | cut -f1)
|
||||||
|
for item in "${completions[@]}"; do
|
||||||
|
if [[ $item = "${prefix}"* ]]; then
|
||||||
|
matches+=("$item")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
local shortest_suffix="$prefix"
|
||||||
|
for ((i=0; i < ${#COMP_WORDBREAKS}; i++)); do
|
||||||
|
local char="${COMP_WORDBREAKS:$i:1}"
|
||||||
|
local candidate=${prefix##*$char}
|
||||||
|
if [[ ${#candidate} -lt ${#shortest_suffix} ]]; then
|
||||||
|
shortest_suffix=$candidate
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
local superfluous_prefix=""
|
||||||
|
if [[ "$shortest_suffix" != "$prefix" ]]; then
|
||||||
|
local superfluous_prefix=${prefix%$shortest_suffix}
|
||||||
|
fi
|
||||||
|
COMPREPLY=("${matches[@]#$superfluous_prefix}")
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -o nospace -F _hyprctl hyprctl
|
||||||
235
hyprctl/hyprctl.fish
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
function _hyprctl_2
|
||||||
|
set 1 $argv[1]
|
||||||
|
hyprctl monitors | awk '/Monitor/{ print $2 }'
|
||||||
|
end
|
||||||
|
|
||||||
|
function _hyprctl_4
|
||||||
|
set 1 $argv[1]
|
||||||
|
hyprctl clients | awk '/class/{print $2}'
|
||||||
|
end
|
||||||
|
|
||||||
|
function _hyprctl_3
|
||||||
|
set 1 $argv[1]
|
||||||
|
hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}'
|
||||||
|
end
|
||||||
|
|
||||||
|
function _hyprctl_1
|
||||||
|
set 1 $argv[1]
|
||||||
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
|
end
|
||||||
|
|
||||||
|
function _hyprctl
|
||||||
|
set COMP_LINE (commandline --cut-at-cursor)
|
||||||
|
|
||||||
|
set COMP_WORDS
|
||||||
|
echo $COMP_LINE | read --tokenize --array COMP_WORDS
|
||||||
|
if string match --quiet --regex '.*\s$' $COMP_LINE
|
||||||
|
set COMP_CWORD (math (count $COMP_WORDS) + 1)
|
||||||
|
else
|
||||||
|
set COMP_CWORD (count $COMP_WORDS)
|
||||||
|
end
|
||||||
|
|
||||||
|
set literals "resizeactive" "2" "changegroupactive" "-r" "moveintogroup" "forceallowsinput" "4" "::=" "systeminfo" "all" "layouts" "setprop" "animationstyle" "switchxkblayout" "create" "denywindowfromgroup" "headless" "activebordercolor" "exec" "setcursor" "wayland" "focusurgentorlast" "workspacerules" "movecurrentworkspacetomonitor" "movetoworkspacesilent" "hyprpaper" "alpha" "inactivebordercolor" "movegroupwindow" "movecursortocorner" "movewindowpixel" "prev" "movewindow" "globalshortcuts" "clients" "dimaround" "setignoregrouplock" "splash" "execr" "monitors" "0" "forcenoborder" "-q" "animations" "1" "nomaxsize" "splitratio" "moveactive" "pass" "swapnext" "devices" "layers" "rounding" "lockactivegroup" "5" "moveworkspacetomonitor" "-f" "-i" "--quiet" "forcenodim" "pin" "0" "1" "forceopaque" "forcenoshadow" "setfloating" "minsize" "alphaoverride" "sendshortcut" "workspaces" "cyclenext" "alterzorder" "togglegroup" "lockgroups" "bordersize" "dpms" "focuscurrentorlast" "-1" "--batch" "notify" "remove" "instances" "1" "3" "moveoutofgroup" "killactive" "2" "movetoworkspace" "movecursor" "configerrors" "closewindow" "swapwindow" "tagwindow" "forcerendererreload" "centerwindow" "auto" "focuswindow" "seterror" "nofocus" "alphafullscreen" "binds" "version" "-h" "togglespecialworkspace" "fullscreen" "windowdancecompat" "0" "keyword" "toggleopaque" "3" "--instance" "togglefloating" "renameworkspace" "alphafullscreenoverride" "activeworkspace" "x11" "kill" "forceopaqueoverriden" "output" "global" "dispatch" "reload" "forcenoblur" "-j" "event" "--help" "disable" "-1" "activewindow" "keepaspectratio" "dismissnotify" "focusmonitor" "movefocus" "plugin" "exit" "workspace" "fullscreenstate" "getoption" "alphainactiveoverride" "alphainactive" "decorations" "settiled" "config-only" "descriptions" "resizewindowpixel" "fakefullscreen" "rollinglog" "swapactiveworkspaces" "submap" "next" "movewindoworgroup" "cursorpos" "forcenoanims" "focusworkspaceoncurrentmonitor" "maxsize"
|
||||||
|
|
||||||
|
set descriptions
|
||||||
|
set descriptions[1] "Resize the active window"
|
||||||
|
set descriptions[2] "Fullscreen"
|
||||||
|
set descriptions[3] "Switch to the next window in a group"
|
||||||
|
set descriptions[4] "Refresh state after issuing the command"
|
||||||
|
set descriptions[5] "Move the active window into a group"
|
||||||
|
set descriptions[7] "CONFUSED"
|
||||||
|
set descriptions[9] "Print system info"
|
||||||
|
set descriptions[11] "List all layouts available (including plugin ones)"
|
||||||
|
set descriptions[12] "Set a property of a window"
|
||||||
|
set descriptions[14] "Set the xkb layout index for a keyboard"
|
||||||
|
set descriptions[16] "Prohibit the active window from becoming or being inserted into group"
|
||||||
|
set descriptions[19] "Execute a shell command"
|
||||||
|
set descriptions[20] "Set the cursor theme and reloads the cursor manager"
|
||||||
|
set descriptions[22] "Focus the urgent window or the last window"
|
||||||
|
set descriptions[23] "Get the list of defined workspace rules"
|
||||||
|
set descriptions[24] "Move the active workspace to a monitor"
|
||||||
|
set descriptions[25] "Move window doesnt switch to the workspace"
|
||||||
|
set descriptions[26] "Interact with hyprpaper if present"
|
||||||
|
set descriptions[29] "Swap the active window with the next or previous in a group"
|
||||||
|
set descriptions[30] "Move the cursor to the corner of the active window"
|
||||||
|
set descriptions[31] "Move a selected window"
|
||||||
|
set descriptions[33] "Move the active window in a direction or to a monitor"
|
||||||
|
set descriptions[34] "Lists all global shortcuts"
|
||||||
|
set descriptions[35] "List all windows with their properties"
|
||||||
|
set descriptions[37] "Temporarily enable or disable binds:ignore_group_lock"
|
||||||
|
set descriptions[38] "Print the current random splash"
|
||||||
|
set descriptions[39] "Execute a raw shell command"
|
||||||
|
set descriptions[40] "List active outputs with their properties"
|
||||||
|
set descriptions[43] "Disable output"
|
||||||
|
set descriptions[44] "Gets the current config info about animations and beziers"
|
||||||
|
set descriptions[47] "Change the split ratio"
|
||||||
|
set descriptions[48] "Move the active window"
|
||||||
|
set descriptions[49] "Pass the key to a specified window"
|
||||||
|
set descriptions[50] "Swap the focused window with the next window"
|
||||||
|
set descriptions[51] "List all connected keyboards and mice"
|
||||||
|
set descriptions[52] "List the layers"
|
||||||
|
set descriptions[54] "Lock the focused group"
|
||||||
|
set descriptions[55] "OK"
|
||||||
|
set descriptions[56] "Move a workspace to a monitor"
|
||||||
|
set descriptions[58] "Specify the Hyprland instance"
|
||||||
|
set descriptions[59] "Disable output"
|
||||||
|
set descriptions[61] "Pin a window"
|
||||||
|
set descriptions[62] "WARNING"
|
||||||
|
set descriptions[63] "INFO"
|
||||||
|
set descriptions[66] "Set the current window's floating state to true"
|
||||||
|
set descriptions[69] "On shortcut X sends shortcut Y to a specified window"
|
||||||
|
set descriptions[70] "List all workspaces with their properties"
|
||||||
|
set descriptions[71] "Focus the next window on a workspace"
|
||||||
|
set descriptions[72] "Modify the window stack order of the active or specified window"
|
||||||
|
set descriptions[73] "Toggle the current active window into a group"
|
||||||
|
set descriptions[74] "Lock the groups"
|
||||||
|
set descriptions[76] "Set all monitors' DPMS status"
|
||||||
|
set descriptions[77] "Switch focus from current to previously focused window"
|
||||||
|
set descriptions[78] "No Icon"
|
||||||
|
set descriptions[79] "Execute a batch of commands separated by ;"
|
||||||
|
set descriptions[80] "Send a notification using the built-in Hyprland notification system"
|
||||||
|
set descriptions[82] "List all running Hyprland instances and their info"
|
||||||
|
set descriptions[83] "Maximize no fullscreen"
|
||||||
|
set descriptions[84] "Maximize and fullscreen"
|
||||||
|
set descriptions[85] "Move the active window out of a group"
|
||||||
|
set descriptions[86] "Close the active window"
|
||||||
|
set descriptions[87] "HINT"
|
||||||
|
set descriptions[88] "Move the focused window to a workspace"
|
||||||
|
set descriptions[89] "Move the cursor to a specified position"
|
||||||
|
set descriptions[90] "List all current config parsing errors"
|
||||||
|
set descriptions[91] "Close a specified window"
|
||||||
|
set descriptions[92] "Swap the active window with another window"
|
||||||
|
set descriptions[93] "Apply a tag to the window"
|
||||||
|
set descriptions[94] "Force the renderer to reload all resources and outputs"
|
||||||
|
set descriptions[95] "Center the active window"
|
||||||
|
set descriptions[97] "Focus the first window matching"
|
||||||
|
set descriptions[98] "Set the hyprctl error string"
|
||||||
|
set descriptions[101] "List all registered binds"
|
||||||
|
set descriptions[102] "Print the Hyprland version: flags, commit and branch of build"
|
||||||
|
set descriptions[103] "Prints the help message"
|
||||||
|
set descriptions[104] "Toggle a special workspace on/off"
|
||||||
|
set descriptions[105] "Toggle the focused window's fullscreen state"
|
||||||
|
set descriptions[107] "None"
|
||||||
|
set descriptions[108] "Issue a keyword to call a config keyword dynamically"
|
||||||
|
set descriptions[109] "Toggle the current window to always be opaque"
|
||||||
|
set descriptions[110] "ERROR"
|
||||||
|
set descriptions[111] "Specify the Hyprland instance"
|
||||||
|
set descriptions[112] "Toggle the current window's floating state"
|
||||||
|
set descriptions[113] "Rename a workspace"
|
||||||
|
set descriptions[115] "Get the active workspace name and its properties"
|
||||||
|
set descriptions[117] "Get into a kill mode, where you can kill an app by clicking on it"
|
||||||
|
set descriptions[119] "Allows adding/removing fake outputs to a specific backend"
|
||||||
|
set descriptions[120] "Execute a Global Shortcut using the GlobalShortcuts portal"
|
||||||
|
set descriptions[121] "Issue a dispatch to call a keybind dispatcher with an arg"
|
||||||
|
set descriptions[122] "Force reload the config"
|
||||||
|
set descriptions[124] "Output in JSON format"
|
||||||
|
set descriptions[125] "Emits a custom event to socket2"
|
||||||
|
set descriptions[126] "Prints the help message"
|
||||||
|
set descriptions[128] "Current"
|
||||||
|
set descriptions[129] "Get the active window name and its properties"
|
||||||
|
set descriptions[131] "Dismiss all or up to amount of notifications"
|
||||||
|
set descriptions[132] "Focus a monitor"
|
||||||
|
set descriptions[133] "Move the focus in a direction"
|
||||||
|
set descriptions[134] "Interact with a plugin"
|
||||||
|
set descriptions[135] "Exit the compositor with no questions asked"
|
||||||
|
set descriptions[136] "Change the workspace"
|
||||||
|
set descriptions[137] "Sets the focused window’s fullscreen mode and the one sent to the client"
|
||||||
|
set descriptions[138] "Get the config option status (values)"
|
||||||
|
set descriptions[141] "List all decorations and their info"
|
||||||
|
set descriptions[142] "Set the current window's floating state to false"
|
||||||
|
set descriptions[144] "Return a parsable JSON with all the config options, descriptions, value types and ranges"
|
||||||
|
set descriptions[145] "Resize a selected window"
|
||||||
|
set descriptions[146] "Toggle the focused window's internal fullscreen state"
|
||||||
|
set descriptions[147] "Print tail of the log"
|
||||||
|
set descriptions[148] "Swap the active workspaces between two monitors"
|
||||||
|
set descriptions[149] "Change the current mapping group"
|
||||||
|
set descriptions[151] "Behave as moveintogroup"
|
||||||
|
set descriptions[152] "Get the current cursor pos in global layout coordinates"
|
||||||
|
set descriptions[154] "Focus the requested workspace"
|
||||||
|
|
||||||
|
set literal_transitions
|
||||||
|
set literal_transitions[1] "set inputs 121 44 126 82 4 52 51 129 90 59 9 11 12 131 14 98 102 103 134 101 138 23 20 141 26 144 108 147 70 34 35 79 115 38 152 117 122 124 40 43 80 119; set tos 15 3 22 3 22 3 3 3 3 22 3 3 4 5 6 7 3 22 8 3 3 3 3 9 3 3 10 11 3 3 3 22 3 3 3 3 14 22 12 22 16 13"
|
||||||
|
set literal_transitions[2] "set inputs 82 52 51 129 9 90 11 12 131 14 98 102 134 101 23 20 138 141 26 144 108 147 70 34 35 115 38 152 117 40 119 122 121 80 44; set tos 3 3 3 3 3 3 3 4 5 6 7 3 8 3 3 3 3 9 3 3 10 11 3 3 3 3 3 3 3 12 13 14 15 16 3"
|
||||||
|
set literal_transitions[4] "set inputs 140 64 65 46 106 28 27 53 6 67 68 130 114 13 75 100 36 153 99 60 118 42 18 139 155 123; set tos 3 17 17 17 17 3 3 5 17 3 17 17 17 3 5 3 17 17 17 17 17 17 3 17 3 17"
|
||||||
|
set literal_transitions[7] "set inputs 127; set tos 3"
|
||||||
|
set literal_transitions[11] "set inputs 57; set tos 3"
|
||||||
|
set literal_transitions[12] "set inputs 10; set tos 3"
|
||||||
|
set literal_transitions[13] "set inputs 15 81; set tos 20 23"
|
||||||
|
set literal_transitions[14] "set inputs 143; set tos 3"
|
||||||
|
set literal_transitions[15] "set inputs 1 85 3 86 5 88 89 91 92 93 94 95 97 16 19 104 22 105 24 25 29 30 31 109 112 33 113 37 39 120 125 47 48 49 50 54 56 132 133 135 136 61 137 142 66 145 146 69 148 71 72 73 74 149 76 77 151 154; set tos 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 21 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"
|
||||||
|
set literal_transitions[16] "set inputs 87 7 110 62 78 55 63; set tos 5 5 5 5 5 5 5"
|
||||||
|
set literal_transitions[17] "set inputs 41 45; set tos 3 3"
|
||||||
|
set literal_transitions[18] "set inputs 8; set tos 24"
|
||||||
|
set literal_transitions[19] "set inputs 32 150; set tos 3 3"
|
||||||
|
set literal_transitions[20] "set inputs 96 17 116 21; set tos 3 3 3 3"
|
||||||
|
set literal_transitions[21] "set inputs 107 83 128 2 84; set tos 3 3 3 3 3"
|
||||||
|
set literal_transitions[24] "set inputs 58 111; set tos 22 22"
|
||||||
|
|
||||||
|
set match_anything_transitions_from 7 8 1 23 6 5 3 19 12 9 10 14 11 2
|
||||||
|
set match_anything_transitions_to 18 3 2 3 19 3 18 3 18 3 3 18 18 2
|
||||||
|
|
||||||
|
set state 1
|
||||||
|
set word_index 2
|
||||||
|
while test $word_index -lt $COMP_CWORD
|
||||||
|
set -- word $COMP_WORDS[$word_index]
|
||||||
|
|
||||||
|
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
||||||
|
set --erase inputs
|
||||||
|
set --erase tos
|
||||||
|
eval $literal_transitions[$state]
|
||||||
|
|
||||||
|
if contains -- $word $literals
|
||||||
|
set literal_matched 0
|
||||||
|
for literal_id in (seq 1 (count $literals))
|
||||||
|
if test $literals[$literal_id] = $word
|
||||||
|
set index (contains --index -- $literal_id $inputs)
|
||||||
|
set state $tos[$index]
|
||||||
|
set word_index (math $word_index + 1)
|
||||||
|
set literal_matched 1
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if test $literal_matched -ne 0
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if set --query match_anything_transitions_from[$state] && test -n $match_anything_transitions_from[$state]
|
||||||
|
set index (contains --index -- $state $match_anything_transitions_from)
|
||||||
|
set state $match_anything_transitions_to[$index]
|
||||||
|
set word_index (math $word_index + 1)
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
||||||
|
set --erase inputs
|
||||||
|
set --erase tos
|
||||||
|
eval $literal_transitions[$state]
|
||||||
|
for literal_id in $inputs
|
||||||
|
if test -n $descriptions[$literal_id]
|
||||||
|
printf '%s\t%s\n' $literals[$literal_id] $descriptions[$literal_id]
|
||||||
|
else
|
||||||
|
printf '%s\n' $literals[$literal_id]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
set command_states 8 23 9 6
|
||||||
|
set command_ids 1 2 4 3
|
||||||
|
if contains $state $command_states
|
||||||
|
set index (contains --index $state $command_states)
|
||||||
|
set function_id $command_ids[$index]
|
||||||
|
set function_name _hyprctl_$function_id
|
||||||
|
set --erase inputs
|
||||||
|
set --erase tos
|
||||||
|
$function_name "$COMP_WORDS[$COMP_CWORD]"
|
||||||
|
end
|
||||||
|
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
complete --command hyprctl --no-files --arguments "(_hyprctl)"
|
||||||
163
hyprctl/hyprctl.usage
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
# This is a file feeded to complgen to generate bash/fish/zsh completions
|
||||||
|
# Repo: https://github.com/adaszko/complgen
|
||||||
|
# Generate completion scripts: "complgen aot --bash-script hyprctl.bash --fish-script hyprctl.fish --zsh-script hyprctl.zsh ./hyprctl.usage"
|
||||||
|
|
||||||
|
hyprctl [<OPTIONS>]... <ARGUMENTS>
|
||||||
|
|
||||||
|
<OPTIONS> ::= (-i | --instance) "Specify the Hyprland instance"
|
||||||
|
| (-j) "Output in JSON format"
|
||||||
|
| (-r) "Refresh state after issuing the command"
|
||||||
|
| (--batch) "Execute a batch of commands separated by ;"
|
||||||
|
| (-q | --quiet) "Disable output"
|
||||||
|
| (-h | --help) "Prints the help message"
|
||||||
|
;
|
||||||
|
|
||||||
|
<WINDOWS> ::= {{{ hyprctl clients | awk '/class/{print $2}' }}};
|
||||||
|
|
||||||
|
<AVAILABLE_PLUGINS> ::= {{{ hyprpm list | awk '/Plugin/{print $4}' }}};
|
||||||
|
|
||||||
|
<MONITORS> ::= {{{ hyprctl monitors | awk '/Monitor/{ print $2 }' }}};
|
||||||
|
|
||||||
|
<KEYBOARDS> ::= {{{ hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}' }}};
|
||||||
|
|
||||||
|
<NOTIFICATION_TYPES> ::= (0) "WARNING"
|
||||||
|
| (1) "INFO"
|
||||||
|
| (2) "HINT"
|
||||||
|
| (3) "ERROR"
|
||||||
|
| (4) "CONFUSED"
|
||||||
|
| (5) "OK"
|
||||||
|
| (-1) "No Icon"
|
||||||
|
;
|
||||||
|
|
||||||
|
<PROPS> ::= (animationstyle)
|
||||||
|
| (rounding <NUM>)
|
||||||
|
| (bordersize <NUM>)
|
||||||
|
| (forcenoblur (0 | 1))
|
||||||
|
| (forceopaque (0 | 1))
|
||||||
|
| (forceopaqueoverriden (0 | 1))
|
||||||
|
| (forceallowsinput (0 | 1))
|
||||||
|
| (forcenoanims (0 | 1))
|
||||||
|
| (forcenoborder (0 | 1))
|
||||||
|
| (forcenodim (0 | 1))
|
||||||
|
| (forcenoshadow (0 | 1))
|
||||||
|
| (nofocus (0 | 1))
|
||||||
|
| (windowdancecompat (0 | 1))
|
||||||
|
| (nomaxsize (0 | 1))
|
||||||
|
| (minsize)
|
||||||
|
| (maxsize)
|
||||||
|
| (dimaround (0 | 1))
|
||||||
|
| (keepaspectratio (0 | 1))
|
||||||
|
| (alphaoverride (0 | 1))
|
||||||
|
| (alpha)
|
||||||
|
| (alphainactiveoverride (0 | 1))
|
||||||
|
| (alphainactive)
|
||||||
|
| (alphafullscreenoverride (0 | 1))
|
||||||
|
| (alphafullscreen)
|
||||||
|
| (activebordercolor)
|
||||||
|
| (inactivebordercolor)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
<ARGUMENTS> ::= (activewindow) "Get the active window name and its properties"
|
||||||
|
| (activeworkspace) "Get the active workspace name and its properties"
|
||||||
|
| (animations) "Gets the current config info about animations and beziers"
|
||||||
|
| (binds) "List all registered binds"
|
||||||
|
| (clients) "List all windows with their properties"
|
||||||
|
| (configerrors) "List all current config parsing errors"
|
||||||
|
| (cursorpos) "Get the current cursor pos in global layout coordinates"
|
||||||
|
| (decorations <WINDOWS>) "List all decorations and their info"
|
||||||
|
| (descriptions) "Return a parsable JSON with all the config options, descriptions, value types and ranges"
|
||||||
|
| (devices) "List all connected keyboards and mice"
|
||||||
|
| (dismissnotify <NUM>) "Dismiss all or up to amount of notifications"
|
||||||
|
| (dispatch <DISPATCHERS>) "Issue a dispatch to call a keybind dispatcher with an arg"
|
||||||
|
| (getoption) "Get the config option status (values)"
|
||||||
|
| (globalshortcuts) "Lists all global shortcuts"
|
||||||
|
| (hyprpaper) "Interact with hyprpaper if present"
|
||||||
|
| (instances) "List all running Hyprland instances and their info"
|
||||||
|
| (keyword <KEYWORDS>) "Issue a keyword to call a config keyword dynamically"
|
||||||
|
| (kill) "Get into a kill mode, where you can kill an app by clicking on it"
|
||||||
|
| (layers) "List the layers"
|
||||||
|
| (layouts) "List all layouts available (including plugin ones)"
|
||||||
|
| (monitors [all]) "List active outputs with their properties"
|
||||||
|
| (notify <NOTIFICATION_TYPES> <NUM>) "Send a notification using the built-in Hyprland notification system"
|
||||||
|
| (output (create (wayland | x11 | headless | auto) | remove <MONITORS>)) "Allows adding/removing fake outputs to a specific backend"
|
||||||
|
| (plugin <AVAILABLE_PLUGINS>) "Interact with a plugin"
|
||||||
|
| (reload [config-only]) "Force reload the config"
|
||||||
|
| (rollinglog [-f]) "Print tail of the log"
|
||||||
|
| (setcursor) "Set the cursor theme and reloads the cursor manager"
|
||||||
|
| (seterror [disable]) "Set the hyprctl error string"
|
||||||
|
| (setprop <PROPS>) "Set a property of a window"
|
||||||
|
| (splash) "Print the current random splash"
|
||||||
|
| (switchxkblayout <KEYBOARDS> (next | prev | <NUM>)) "Set the xkb layout index for a keyboard"
|
||||||
|
| (systeminfo) "Print system info"
|
||||||
|
| (version) "Print the Hyprland version: flags, commit and branch of build"
|
||||||
|
| (workspacerules) "Get the list of defined workspace rules"
|
||||||
|
| (workspaces) "List all workspaces with their properties"
|
||||||
|
;
|
||||||
|
|
||||||
|
<WINDOW_STATE> ::= (-1) "Current"
|
||||||
|
| (0) "None"
|
||||||
|
| (1) "Maximize no fullscreen"
|
||||||
|
| (2) "Fullscreen"
|
||||||
|
| (3) "Maximize and fullscreen"
|
||||||
|
;
|
||||||
|
|
||||||
|
<DISPATCHERS> ::= (exec) "Execute a shell command"
|
||||||
|
| (execr) "Execute a raw shell command"
|
||||||
|
| (pass) "Pass the key to a specified window"
|
||||||
|
| (sendshortcut) "On shortcut X sends shortcut Y to a specified window"
|
||||||
|
| (killactive) "Close the active window"
|
||||||
|
| (closewindow) "Close a specified window"
|
||||||
|
| (workspace) "Change the workspace"
|
||||||
|
| (movetoworkspace) "Move the focused window to a workspace"
|
||||||
|
| (movetoworkspacesilent) "Move window doesnt switch to the workspace"
|
||||||
|
| (togglefloating) "Toggle the current window's floating state"
|
||||||
|
| (setfloating) "Set the current window's floating state to true"
|
||||||
|
| (settiled) "Set the current window's floating state to false"
|
||||||
|
| (fullscreen) "Toggle the focused window's fullscreen state"
|
||||||
|
| (fakefullscreen) "Toggle the focused window's internal fullscreen state"
|
||||||
|
| (fullscreenstate <WINDOW_STATE>) "Sets the focused window’s fullscreen mode and the one sent to the client"
|
||||||
|
| (dpms) "Set all monitors' DPMS status"
|
||||||
|
| (pin) "Pin a window"
|
||||||
|
| (movefocus) "Move the focus in a direction"
|
||||||
|
| (movewindow) "Move the active window in a direction or to a monitor"
|
||||||
|
| (swapwindow) "Swap the active window with another window"
|
||||||
|
| (centerwindow) "Center the active window"
|
||||||
|
| (resizeactive) "Resize the active window"
|
||||||
|
| (moveactive) "Move the active window"
|
||||||
|
| (resizewindowpixel) "Resize a selected window"
|
||||||
|
| (movewindowpixel) "Move a selected window"
|
||||||
|
| (cyclenext) "Focus the next window on a workspace"
|
||||||
|
| (swapnext) "Swap the focused window with the next window"
|
||||||
|
| (tagwindow) "Apply a tag to the window"
|
||||||
|
| (focuswindow) "Focus the first window matching"
|
||||||
|
| (focusmonitor) "Focus a monitor"
|
||||||
|
| (splitratio) "Change the split ratio"
|
||||||
|
| (toggleopaque) "Toggle the current window to always be opaque"
|
||||||
|
| (movecursortocorner) "Move the cursor to the corner of the active window"
|
||||||
|
| (movecursor) "Move the cursor to a specified position"
|
||||||
|
| (renameworkspace) "Rename a workspace"
|
||||||
|
| (exit) "Exit the compositor with no questions asked"
|
||||||
|
| (forcerendererreload) "Force the renderer to reload all resources and outputs"
|
||||||
|
| (movecurrentworkspacetomonitor) "Move the active workspace to a monitor"
|
||||||
|
| (focusworkspaceoncurrentmonitor) "Focus the requested workspace"
|
||||||
|
| (moveworkspacetomonitor) "Move a workspace to a monitor"
|
||||||
|
| (swapactiveworkspaces) "Swap the active workspaces between two monitors"
|
||||||
|
| (alterzorder) "Modify the window stack order of the active or specified window"
|
||||||
|
| (togglespecialworkspace) "Toggle a special workspace on/off"
|
||||||
|
| (focusurgentorlast) "Focus the urgent window or the last window"
|
||||||
|
| (togglegroup) "Toggle the current active window into a group"
|
||||||
|
| (changegroupactive) "Switch to the next window in a group"
|
||||||
|
| (focuscurrentorlast) "Switch focus from current to previously focused window"
|
||||||
|
| (lockgroups) "Lock the groups"
|
||||||
|
| (lockactivegroup) "Lock the focused group"
|
||||||
|
| (moveintogroup) "Move the active window into a group"
|
||||||
|
| (moveoutofgroup) "Move the active window out of a group"
|
||||||
|
| (movewindoworgroup) "Behave as moveintogroup"
|
||||||
|
| (movegroupwindow) "Swap the active window with the next or previous in a group"
|
||||||
|
| (denywindowfromgroup) "Prohibit the active window from becoming or being inserted into group"
|
||||||
|
| (setignoregrouplock) "Temporarily enable or disable binds:ignore_group_lock"
|
||||||
|
| (global) "Execute a Global Shortcut using the GlobalShortcuts portal"
|
||||||
|
| (submap) "Change the current mapping group"
|
||||||
|
| (event) "Emits a custom event to socket2"
|
||||||
|
;
|
||||||
274
hyprctl/hyprctl.zsh
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
#compdef hyprctl
|
||||||
|
|
||||||
|
_hyprctl_cmd_1 () {
|
||||||
|
hyprctl monitors | awk '/Monitor/{ print $2 }'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprctl_cmd_3 () {
|
||||||
|
hyprctl clients | awk '/class/{print $2}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprctl_cmd_2 () {
|
||||||
|
hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprctl_cmd_0 () {
|
||||||
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprctl () {
|
||||||
|
local -a literals=("resizeactive" "2" "changegroupactive" "-r" "moveintogroup" "forceallowsinput" "4" "::=" "systeminfo" "all" "layouts" "setprop" "animationstyle" "switchxkblayout" "create" "denywindowfromgroup" "headless" "activebordercolor" "exec" "setcursor" "wayland" "focusurgentorlast" "workspacerules" "movecurrentworkspacetomonitor" "movetoworkspacesilent" "hyprpaper" "alpha" "inactivebordercolor" "movegroupwindow" "movecursortocorner" "movewindowpixel" "prev" "movewindow" "globalshortcuts" "clients" "dimaround" "setignoregrouplock" "splash" "execr" "monitors" "0" "forcenoborder" "-q" "animations" "1" "nomaxsize" "splitratio" "moveactive" "pass" "swapnext" "devices" "layers" "rounding" "lockactivegroup" "5" "moveworkspacetomonitor" "-f" "-i" "--quiet" "forcenodim" "pin" "0" "1" "forceopaque" "forcenoshadow" "setfloating" "minsize" "alphaoverride" "sendshortcut" "workspaces" "cyclenext" "alterzorder" "togglegroup" "lockgroups" "bordersize" "dpms" "focuscurrentorlast" "-1" "--batch" "notify" "remove" "instances" "1" "3" "moveoutofgroup" "killactive" "2" "movetoworkspace" "movecursor" "configerrors" "closewindow" "swapwindow" "tagwindow" "forcerendererreload" "centerwindow" "auto" "focuswindow" "seterror" "nofocus" "alphafullscreen" "binds" "version" "-h" "togglespecialworkspace" "fullscreen" "windowdancecompat" "0" "keyword" "toggleopaque" "3" "--instance" "togglefloating" "renameworkspace" "alphafullscreenoverride" "activeworkspace" "x11" "kill" "forceopaqueoverriden" "output" "global" "dispatch" "reload" "forcenoblur" "-j" "event" "--help" "disable" "-1" "activewindow" "keepaspectratio" "dismissnotify" "focusmonitor" "movefocus" "plugin" "exit" "workspace" "fullscreenstate" "getoption" "alphainactiveoverride" "alphainactive" "decorations" "settiled" "config-only" "descriptions" "resizewindowpixel" "fakefullscreen" "rollinglog" "swapactiveworkspaces" "submap" "next" "movewindoworgroup" "cursorpos" "forcenoanims" "focusworkspaceoncurrentmonitor" "maxsize")
|
||||||
|
|
||||||
|
local -A descriptions
|
||||||
|
descriptions[1]="Resize the active window"
|
||||||
|
descriptions[2]="Fullscreen"
|
||||||
|
descriptions[3]="Switch to the next window in a group"
|
||||||
|
descriptions[4]="Refresh state after issuing the command"
|
||||||
|
descriptions[5]="Move the active window into a group"
|
||||||
|
descriptions[7]="CONFUSED"
|
||||||
|
descriptions[9]="Print system info"
|
||||||
|
descriptions[11]="List all layouts available (including plugin ones)"
|
||||||
|
descriptions[12]="Set a property of a window"
|
||||||
|
descriptions[14]="Set the xkb layout index for a keyboard"
|
||||||
|
descriptions[16]="Prohibit the active window from becoming or being inserted into group"
|
||||||
|
descriptions[19]="Execute a shell command"
|
||||||
|
descriptions[20]="Set the cursor theme and reloads the cursor manager"
|
||||||
|
descriptions[22]="Focus the urgent window or the last window"
|
||||||
|
descriptions[23]="Get the list of defined workspace rules"
|
||||||
|
descriptions[24]="Move the active workspace to a monitor"
|
||||||
|
descriptions[25]="Move window doesnt switch to the workspace"
|
||||||
|
descriptions[26]="Interact with hyprpaper if present"
|
||||||
|
descriptions[29]="Swap the active window with the next or previous in a group"
|
||||||
|
descriptions[30]="Move the cursor to the corner of the active window"
|
||||||
|
descriptions[31]="Move a selected window"
|
||||||
|
descriptions[33]="Move the active window in a direction or to a monitor"
|
||||||
|
descriptions[34]="Lists all global shortcuts"
|
||||||
|
descriptions[35]="List all windows with their properties"
|
||||||
|
descriptions[37]="Temporarily enable or disable binds:ignore_group_lock"
|
||||||
|
descriptions[38]="Print the current random splash"
|
||||||
|
descriptions[39]="Execute a raw shell command"
|
||||||
|
descriptions[40]="List active outputs with their properties"
|
||||||
|
descriptions[43]="Disable output"
|
||||||
|
descriptions[44]="Gets the current config info about animations and beziers"
|
||||||
|
descriptions[47]="Change the split ratio"
|
||||||
|
descriptions[48]="Move the active window"
|
||||||
|
descriptions[49]="Pass the key to a specified window"
|
||||||
|
descriptions[50]="Swap the focused window with the next window"
|
||||||
|
descriptions[51]="List all connected keyboards and mice"
|
||||||
|
descriptions[52]="List the layers"
|
||||||
|
descriptions[54]="Lock the focused group"
|
||||||
|
descriptions[55]="OK"
|
||||||
|
descriptions[56]="Move a workspace to a monitor"
|
||||||
|
descriptions[58]="Specify the Hyprland instance"
|
||||||
|
descriptions[59]="Disable output"
|
||||||
|
descriptions[61]="Pin a window"
|
||||||
|
descriptions[62]="WARNING"
|
||||||
|
descriptions[63]="INFO"
|
||||||
|
descriptions[66]="Set the current window's floating state to true"
|
||||||
|
descriptions[69]="On shortcut X sends shortcut Y to a specified window"
|
||||||
|
descriptions[70]="List all workspaces with their properties"
|
||||||
|
descriptions[71]="Focus the next window on a workspace"
|
||||||
|
descriptions[72]="Modify the window stack order of the active or specified window"
|
||||||
|
descriptions[73]="Toggle the current active window into a group"
|
||||||
|
descriptions[74]="Lock the groups"
|
||||||
|
descriptions[76]="Set all monitors' DPMS status"
|
||||||
|
descriptions[77]="Switch focus from current to previously focused window"
|
||||||
|
descriptions[78]="No Icon"
|
||||||
|
descriptions[79]="Execute a batch of commands separated by ;"
|
||||||
|
descriptions[80]="Send a notification using the built-in Hyprland notification system"
|
||||||
|
descriptions[82]="List all running Hyprland instances and their info"
|
||||||
|
descriptions[83]="Maximize no fullscreen"
|
||||||
|
descriptions[84]="Maximize and fullscreen"
|
||||||
|
descriptions[85]="Move the active window out of a group"
|
||||||
|
descriptions[86]="Close the active window"
|
||||||
|
descriptions[87]="HINT"
|
||||||
|
descriptions[88]="Move the focused window to a workspace"
|
||||||
|
descriptions[89]="Move the cursor to a specified position"
|
||||||
|
descriptions[90]="List all current config parsing errors"
|
||||||
|
descriptions[91]="Close a specified window"
|
||||||
|
descriptions[92]="Swap the active window with another window"
|
||||||
|
descriptions[93]="Apply a tag to the window"
|
||||||
|
descriptions[94]="Force the renderer to reload all resources and outputs"
|
||||||
|
descriptions[95]="Center the active window"
|
||||||
|
descriptions[97]="Focus the first window matching"
|
||||||
|
descriptions[98]="Set the hyprctl error string"
|
||||||
|
descriptions[101]="List all registered binds"
|
||||||
|
descriptions[102]="Print the Hyprland version: flags, commit and branch of build"
|
||||||
|
descriptions[103]="Prints the help message"
|
||||||
|
descriptions[104]="Toggle a special workspace on/off"
|
||||||
|
descriptions[105]="Toggle the focused window's fullscreen state"
|
||||||
|
descriptions[107]="None"
|
||||||
|
descriptions[108]="Issue a keyword to call a config keyword dynamically"
|
||||||
|
descriptions[109]="Toggle the current window to always be opaque"
|
||||||
|
descriptions[110]="ERROR"
|
||||||
|
descriptions[111]="Specify the Hyprland instance"
|
||||||
|
descriptions[112]="Toggle the current window's floating state"
|
||||||
|
descriptions[113]="Rename a workspace"
|
||||||
|
descriptions[115]="Get the active workspace name and its properties"
|
||||||
|
descriptions[117]="Get into a kill mode, where you can kill an app by clicking on it"
|
||||||
|
descriptions[119]="Allows adding/removing fake outputs to a specific backend"
|
||||||
|
descriptions[120]="Execute a Global Shortcut using the GlobalShortcuts portal"
|
||||||
|
descriptions[121]="Issue a dispatch to call a keybind dispatcher with an arg"
|
||||||
|
descriptions[122]="Force reload the config"
|
||||||
|
descriptions[124]="Output in JSON format"
|
||||||
|
descriptions[125]="Emits a custom event to socket2"
|
||||||
|
descriptions[126]="Prints the help message"
|
||||||
|
descriptions[128]="Current"
|
||||||
|
descriptions[129]="Get the active window name and its properties"
|
||||||
|
descriptions[131]="Dismiss all or up to amount of notifications"
|
||||||
|
descriptions[132]="Focus a monitor"
|
||||||
|
descriptions[133]="Move the focus in a direction"
|
||||||
|
descriptions[134]="Interact with a plugin"
|
||||||
|
descriptions[135]="Exit the compositor with no questions asked"
|
||||||
|
descriptions[136]="Change the workspace"
|
||||||
|
descriptions[137]="Sets the focused window’s fullscreen mode and the one sent to the client"
|
||||||
|
descriptions[138]="Get the config option status (values)"
|
||||||
|
descriptions[141]="List all decorations and their info"
|
||||||
|
descriptions[142]="Set the current window's floating state to false"
|
||||||
|
descriptions[144]="Return a parsable JSON with all the config options, descriptions, value types and ranges"
|
||||||
|
descriptions[145]="Resize a selected window"
|
||||||
|
descriptions[146]="Toggle the focused window's internal fullscreen state"
|
||||||
|
descriptions[147]="Print tail of the log"
|
||||||
|
descriptions[148]="Swap the active workspaces between two monitors"
|
||||||
|
descriptions[149]="Change the current mapping group"
|
||||||
|
descriptions[151]="Behave as moveintogroup"
|
||||||
|
descriptions[152]="Get the current cursor pos in global layout coordinates"
|
||||||
|
descriptions[154]="Focus the requested workspace"
|
||||||
|
|
||||||
|
local -A literal_transitions
|
||||||
|
literal_transitions[1]="([121]=15 [44]=3 [126]=22 [82]=3 [4]=22 [52]=3 [51]=3 [129]=3 [90]=3 [59]=22 [9]=3 [11]=3 [12]=4 [131]=5 [14]=6 [98]=7 [102]=3 [103]=22 [134]=8 [101]=3 [138]=3 [23]=3 [20]=3 [141]=9 [26]=3 [144]=3 [108]=10 [147]=11 [70]=3 [34]=3 [35]=3 [79]=22 [115]=3 [38]=3 [152]=3 [117]=3 [122]=14 [124]=22 [40]=12 [43]=22 [80]=16 [119]=13)"
|
||||||
|
literal_transitions[2]="([82]=3 [52]=3 [51]=3 [129]=3 [9]=3 [90]=3 [11]=3 [12]=4 [131]=5 [14]=6 [98]=7 [102]=3 [134]=8 [101]=3 [23]=3 [20]=3 [138]=3 [141]=9 [26]=3 [144]=3 [108]=10 [147]=11 [70]=3 [34]=3 [35]=3 [115]=3 [38]=3 [152]=3 [117]=3 [40]=12 [119]=13 [122]=14 [121]=15 [80]=16 [44]=3)"
|
||||||
|
literal_transitions[4]="([140]=3 [64]=17 [65]=17 [46]=17 [106]=17 [28]=3 [27]=3 [53]=5 [6]=17 [67]=3 [68]=17 [130]=17 [114]=17 [13]=3 [75]=5 [100]=3 [36]=17 [153]=17 [99]=17 [60]=17 [118]=17 [42]=17 [18]=3 [139]=17 [155]=3 [123]=17)"
|
||||||
|
literal_transitions[7]="([127]=3)"
|
||||||
|
literal_transitions[11]="([57]=3)"
|
||||||
|
literal_transitions[12]="([10]=3)"
|
||||||
|
literal_transitions[13]="([15]=20 [81]=23)"
|
||||||
|
literal_transitions[14]="([143]=3)"
|
||||||
|
literal_transitions[15]="([1]=3 [85]=3 [3]=3 [86]=3 [5]=3 [88]=3 [89]=3 [91]=3 [92]=3 [93]=3 [94]=3 [95]=3 [97]=3 [16]=3 [19]=3 [104]=3 [22]=3 [105]=3 [24]=3 [25]=3 [29]=3 [30]=3 [31]=3 [109]=3 [112]=3 [33]=3 [113]=3 [37]=3 [39]=3 [120]=3 [125]=3 [47]=3 [48]=3 [49]=3 [50]=3 [54]=3 [56]=3 [132]=3 [133]=3 [135]=3 [136]=3 [61]=3 [137]=21 [142]=3 [66]=3 [145]=3 [146]=3 [69]=3 [148]=3 [71]=3 [72]=3 [73]=3 [74]=3 [149]=3 [76]=3 [77]=3 [151]=3 [154]=3)"
|
||||||
|
literal_transitions[16]="([87]=5 [7]=5 [110]=5 [62]=5 [78]=5 [55]=5 [63]=5)"
|
||||||
|
literal_transitions[17]="([41]=3 [45]=3)"
|
||||||
|
literal_transitions[18]="([8]=24)"
|
||||||
|
literal_transitions[19]="([32]=3 [150]=3)"
|
||||||
|
literal_transitions[20]="([96]=3 [17]=3 [116]=3 [21]=3)"
|
||||||
|
literal_transitions[21]="([107]=3 [83]=3 [128]=3 [2]=3 [84]=3)"
|
||||||
|
literal_transitions[24]="([58]=22 [111]=22)"
|
||||||
|
|
||||||
|
local -A match_anything_transitions
|
||||||
|
match_anything_transitions=([7]=18 [8]=3 [1]=2 [23]=3 [6]=19 [5]=3 [3]=18 [19]=3 [12]=18 [9]=3 [10]=3 [14]=18 [11]=18 [2]=2)
|
||||||
|
|
||||||
|
declare -A subword_transitions
|
||||||
|
|
||||||
|
local state=1
|
||||||
|
local word_index=2
|
||||||
|
while [[ $word_index -lt $CURRENT ]]; do
|
||||||
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
|
local -A state_transitions
|
||||||
|
eval "state_transitions=${literal_transitions[$state]}"
|
||||||
|
|
||||||
|
local word=${words[$word_index]}
|
||||||
|
local word_matched=0
|
||||||
|
for ((literal_id = 1; literal_id <= $#literals; literal_id++)); do
|
||||||
|
if [[ ${literals[$literal_id]} = "$word" ]]; then
|
||||||
|
if [[ -v "state_transitions[$literal_id]" ]]; then
|
||||||
|
state=${state_transitions[$literal_id]}
|
||||||
|
word_index=$((word_index + 1))
|
||||||
|
word_matched=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ $word_matched -ne 0 ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v "match_anything_transitions[$state]" ]]; then
|
||||||
|
state=${match_anything_transitions[$state]}
|
||||||
|
word_index=$((word_index + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
done
|
||||||
|
|
||||||
|
completions_no_description_trailing_space=()
|
||||||
|
completions_no_description_no_trailing_space=()
|
||||||
|
completions_trailing_space=()
|
||||||
|
suffixes_trailing_space=()
|
||||||
|
descriptions_trailing_space=()
|
||||||
|
completions_no_trailing_space=()
|
||||||
|
suffixes_no_trailing_space=()
|
||||||
|
descriptions_no_trailing_space=()
|
||||||
|
|
||||||
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
|
local -A state_transitions
|
||||||
|
eval "state_transitions=${literal_transitions[$state]}"
|
||||||
|
|
||||||
|
for literal_id in ${(k)state_transitions}; do
|
||||||
|
if [[ -v "descriptions[$literal_id]" ]]; then
|
||||||
|
completions_trailing_space+=("${literals[$literal_id]}")
|
||||||
|
suffixes_trailing_space+=("${literals[$literal_id]}")
|
||||||
|
descriptions_trailing_space+=("${descriptions[$literal_id]}")
|
||||||
|
else
|
||||||
|
completions_no_description_trailing_space+=("${literals[$literal_id]}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
local -A commands=([8]=0 [23]=1 [9]=3 [6]=2)
|
||||||
|
|
||||||
|
if [[ -v "commands[$state]" ]]; then
|
||||||
|
local command_id=${commands[$state]}
|
||||||
|
local output=$(_hyprctl_cmd_${command_id} "${words[$CURRENT]}")
|
||||||
|
local -a command_completions=("${(@f)output}")
|
||||||
|
for line in ${command_completions[@]}; do
|
||||||
|
local parts=(${(@s: :)line})
|
||||||
|
if [[ -v "parts[2]" ]]; then
|
||||||
|
completions_trailing_space+=("${parts[1]}")
|
||||||
|
suffixes_trailing_space+=("${parts[1]}")
|
||||||
|
descriptions_trailing_space+=("${parts[2]}")
|
||||||
|
else
|
||||||
|
completions_no_description_trailing_space+=("${parts[1]}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
local maxlen=0
|
||||||
|
for suffix in ${suffixes_trailing_space[@]}; do
|
||||||
|
if [[ ${#suffix} -gt $maxlen ]]; then
|
||||||
|
maxlen=${#suffix}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
for suffix in ${suffixes_no_trailing_space[@]}; do
|
||||||
|
if [[ ${#suffix} -gt $maxlen ]]; then
|
||||||
|
maxlen=${#suffix}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for ((i = 1; i <= $#suffixes_trailing_space; i++)); do
|
||||||
|
if [[ -z ${descriptions_trailing_space[$i]} ]]; then
|
||||||
|
descriptions_trailing_space[$i]="${(r($maxlen)( ))${suffixes_trailing_space[$i]}}"
|
||||||
|
else
|
||||||
|
descriptions_trailing_space[$i]="${(r($maxlen)( ))${suffixes_trailing_space[$i]}} -- ${descriptions_trailing_space[$i]}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for ((i = 1; i <= $#suffixes_no_trailing_space; i++)); do
|
||||||
|
if [[ -z ${descriptions_no_trailing_space[$i]} ]]; then
|
||||||
|
descriptions_no_trailing_space[$i]="${(r($maxlen)( ))${suffixes_no_trailing_space[$i]}}"
|
||||||
|
else
|
||||||
|
descriptions_no_trailing_space[$i]="${(r($maxlen)( ))${suffixes_no_trailing_space[$i]}} -- ${descriptions_no_trailing_space[$i]}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
compadd -Q -a completions_no_description_trailing_space
|
||||||
|
compadd -Q -S ' ' -a completions_no_description_no_trailing_space
|
||||||
|
compadd -l -Q -a -d descriptions_trailing_space completions_trailing_space
|
||||||
|
compadd -l -Q -S '' -a -d descriptions_no_trailing_space completions_no_trailing_space
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $ZSH_EVAL_CONTEXT =~ :file$ ]]; then
|
||||||
|
compdef _hyprctl hyprctl
|
||||||
|
else
|
||||||
|
_hyprctl
|
||||||
|
fi
|
||||||
394
hyprctl/main.cpp
@@ -1,67 +1,41 @@
|
|||||||
#include <ctype.h>
|
#include <re2/re2.h>
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <pwd.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <signal.h>
|
#include <csignal>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <print>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <stdarg.h>
|
#include <cstdarg>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <hyprutils/string/String.hpp>
|
||||||
|
#include <cstring>
|
||||||
|
using namespace Hyprutils::String;
|
||||||
|
|
||||||
const std::string USAGE = R"#(usage: hyprctl [(opt)flags] [command] [(opt)args]
|
#include "Strings.hpp"
|
||||||
|
|
||||||
commands:
|
|
||||||
monitors
|
|
||||||
workspaces
|
|
||||||
activeworkspace
|
|
||||||
workspacerules
|
|
||||||
clients
|
|
||||||
activewindow
|
|
||||||
layers
|
|
||||||
devices
|
|
||||||
binds
|
|
||||||
dispatch
|
|
||||||
keyword
|
|
||||||
version
|
|
||||||
kill
|
|
||||||
splash
|
|
||||||
hyprpaper
|
|
||||||
reload
|
|
||||||
setcursor
|
|
||||||
getoption
|
|
||||||
cursorpos
|
|
||||||
switchxkblayout
|
|
||||||
seterror
|
|
||||||
setprop
|
|
||||||
plugin
|
|
||||||
notify
|
|
||||||
globalshortcuts
|
|
||||||
instances
|
|
||||||
|
|
||||||
flags:
|
|
||||||
-j -> output in JSON
|
|
||||||
--batch -> execute a batch of commands, separated by ';'
|
|
||||||
--instance (-i) -> use a specific instance. Can be either signature or index in hyprctl instances (0, 1, etc)
|
|
||||||
)#";
|
|
||||||
|
|
||||||
#define PAD
|
#define PAD
|
||||||
|
|
||||||
std::string instanceSignature;
|
std::string instanceSignature;
|
||||||
|
bool quiet = false;
|
||||||
|
|
||||||
struct SInstanceData {
|
struct SInstanceData {
|
||||||
std::string id;
|
std::string id;
|
||||||
@@ -71,27 +45,59 @@ struct SInstanceData {
|
|||||||
bool valid = true;
|
bool valid = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void log(const std::string& str) {
|
||||||
|
if (quiet)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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(getUID());
|
||||||
|
return "/run/user/" + USERID + "/hypr";
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string{XDG} + "/hypr";
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<SInstanceData> instances() {
|
std::vector<SInstanceData> instances() {
|
||||||
std::vector<SInstanceData> result;
|
std::vector<SInstanceData> result;
|
||||||
|
|
||||||
for (const auto& el : std::filesystem::directory_iterator("/tmp/hypr")) {
|
try {
|
||||||
if (el.is_directory())
|
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;
|
continue;
|
||||||
|
|
||||||
// read lock
|
// read lock
|
||||||
SInstanceData* data = &result.emplace_back();
|
SInstanceData* data = &result.emplace_back();
|
||||||
data->id = el.path().string();
|
data->id = el.path().filename().string();
|
||||||
data->id = data->id.substr(data->id.find_last_of('/') + 1, data->id.find(".lock") - data->id.find_last_of('/') - 1);
|
|
||||||
|
|
||||||
data->time = std::stoull(data->id.substr(data->id.find_first_of('_') + 1));
|
try {
|
||||||
|
data->time = std::stoull(data->id.substr(data->id.find_first_of('_') + 1, data->id.find_last_of('_') - (data->id.find_first_of('_') + 1)));
|
||||||
|
} catch (std::exception& e) { continue; }
|
||||||
|
|
||||||
// read file
|
// read file
|
||||||
std::ifstream ifs(el.path().string());
|
std::ifstream ifs(el.path().string() + "/hyprland.lock");
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (std::string line; std::getline(ifs, line); ++i) {
|
for (std::string line; std::getline(ifs, line); ++i) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
|
try {
|
||||||
data->pid = std::stoull(line);
|
data->pid = std::stoull(line);
|
||||||
|
} catch (std::exception& e) { continue; }
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
data->wlSocket = line;
|
data->wlSocket = line;
|
||||||
} else
|
} else
|
||||||
@@ -108,53 +114,100 @@ std::vector<SInstanceData> instances() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void request(std::string arg, int minArgs = 0) {
|
static volatile bool sigintReceived = false;
|
||||||
|
void intHandler(int sig) {
|
||||||
|
sigintReceived = true;
|
||||||
|
std::println("[hyprctl] SIGINT received, closing connection");
|
||||||
|
}
|
||||||
|
|
||||||
|
int rollingRead(const int socket) {
|
||||||
|
sigintReceived = false;
|
||||||
|
signal(SIGINT, intHandler);
|
||||||
|
|
||||||
|
constexpr size_t BUFFER_SIZE = 8192;
|
||||||
|
std::array<char, BUFFER_SIZE> buffer = {0};
|
||||||
|
long sizeWritten = 0;
|
||||||
|
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::println("Couldn't read (5): {}: {}", strerror(errno), errno);
|
||||||
|
close(socket);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeWritten == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (sizeWritten > 0) {
|
||||||
|
std::println("{}", std::string(buffer.data(), sizeWritten));
|
||||||
|
buffer.fill('\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(100000);
|
||||||
|
}
|
||||||
|
close(socket);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int request(std::string arg, int minArgs = 0, bool needRoll = false) {
|
||||||
const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
auto t = timeval{.tv_sec = 5, .tv_usec = 0};
|
||||||
|
setsockopt(SERVERSOCKET, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(struct timeval));
|
||||||
|
|
||||||
const auto ARGS = std::count(arg.begin(), arg.end(), ' ');
|
const auto ARGS = std::count(arg.begin(), arg.end(), ' ');
|
||||||
|
|
||||||
if (ARGS < minArgs) {
|
if (ARGS < minArgs) {
|
||||||
std::cout << "Not enough arguments, expected at least " << minArgs;
|
log(std::format("Not enough arguments in '{}', expected at least {}", arg, minArgs));
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SERVERSOCKET < 0) {
|
if (SERVERSOCKET < 0) {
|
||||||
std::cout << "Couldn't open a socket (1)";
|
log("Couldn't open a socket (1)");
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceSignature.empty()) {
|
if (instanceSignature.empty()) {
|
||||||
std::cout << "HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)";
|
log("HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)");
|
||||||
return;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string USERID = std::to_string(getUID());
|
||||||
|
|
||||||
sockaddr_un serverAddress = {0};
|
sockaddr_un serverAddress = {0};
|
||||||
serverAddress.sun_family = AF_UNIX;
|
serverAddress.sun_family = AF_UNIX;
|
||||||
|
|
||||||
std::string socketPath = "/tmp/hypr/" + instanceSignature + "/.socket.sock";
|
std::string socketPath = getRuntimeDir() + "/" + instanceSignature + "/.socket.sock";
|
||||||
|
|
||||||
strncpy(serverAddress.sun_path, socketPath.c_str(), sizeof(serverAddress.sun_path) - 1);
|
strncpy(serverAddress.sun_path, socketPath.c_str(), sizeof(serverAddress.sun_path) - 1);
|
||||||
|
|
||||||
if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) {
|
if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) {
|
||||||
std::cout << "Couldn't connect to " << socketPath << ". (3)";
|
log("Couldn't connect to " + socketPath + ". (3)");
|
||||||
return;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sizeWritten = write(SERVERSOCKET, arg.c_str(), arg.length());
|
auto sizeWritten = write(SERVERSOCKET, arg.c_str(), arg.length());
|
||||||
|
|
||||||
if (sizeWritten < 0) {
|
if (sizeWritten < 0) {
|
||||||
std::cout << "Couldn't write (4)";
|
log("Couldn't write (4)");
|
||||||
return;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needRoll)
|
||||||
|
return rollingRead(SERVERSOCKET);
|
||||||
|
|
||||||
std::string reply = "";
|
std::string reply = "";
|
||||||
char buffer[8192] = {0};
|
char buffer[8192] = {0};
|
||||||
|
|
||||||
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
||||||
|
|
||||||
if (sizeWritten < 0) {
|
if (sizeWritten < 0) {
|
||||||
std::cout << "Couldn't read (5)";
|
if (errno == EWOULDBLOCK)
|
||||||
return;
|
log("Hyprland IPC didn't respond in time\n");
|
||||||
|
log("Couldn't read (5)");
|
||||||
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
reply += std::string(buffer, sizeWritten);
|
reply += std::string(buffer, sizeWritten);
|
||||||
@@ -162,40 +215,44 @@ void request(std::string arg, int minArgs = 0) {
|
|||||||
while (sizeWritten == 8192) {
|
while (sizeWritten == 8192) {
|
||||||
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
||||||
if (sizeWritten < 0) {
|
if (sizeWritten < 0) {
|
||||||
std::cout << "Couldn't read (5)";
|
log("Couldn't read (5)");
|
||||||
return;
|
return 5;
|
||||||
}
|
}
|
||||||
reply += std::string(buffer, sizeWritten);
|
reply += std::string(buffer, sizeWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(SERVERSOCKET);
|
close(SERVERSOCKET);
|
||||||
|
|
||||||
std::cout << reply;
|
log(reply);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void requestHyprpaper(std::string arg) {
|
int requestHyprpaper(std::string arg) {
|
||||||
const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
if (SERVERSOCKET < 0) {
|
if (SERVERSOCKET < 0) {
|
||||||
std::cout << "Couldn't open a socket (1)";
|
log("Couldn't open a socket (1)");
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceSignature.empty()) {
|
if (instanceSignature.empty()) {
|
||||||
std::cout << "HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)";
|
log("HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)");
|
||||||
return;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_un serverAddress = {0};
|
sockaddr_un serverAddress = {0};
|
||||||
serverAddress.sun_family = AF_UNIX;
|
serverAddress.sun_family = AF_UNIX;
|
||||||
|
|
||||||
std::string socketPath = "/tmp/hypr/" + instanceSignature + "/.hyprpaper.sock";
|
const std::string USERID = std::to_string(getUID());
|
||||||
|
|
||||||
|
std::string socketPath = getRuntimeDir() + "/" + instanceSignature + "/.hyprpaper.sock";
|
||||||
|
|
||||||
strncpy(serverAddress.sun_path, socketPath.c_str(), sizeof(serverAddress.sun_path) - 1);
|
strncpy(serverAddress.sun_path, socketPath.c_str(), sizeof(serverAddress.sun_path) - 1);
|
||||||
|
|
||||||
if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) {
|
if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) {
|
||||||
std::cout << "Couldn't connect to " << socketPath << ". (3)";
|
log("Couldn't connect to " + socketPath + ". (3)");
|
||||||
return;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = arg.substr(arg.find_first_of('/') + 1); // strip flags
|
arg = arg.substr(arg.find_first_of('/') + 1); // strip flags
|
||||||
@@ -204,8 +261,8 @@ void requestHyprpaper(std::string arg) {
|
|||||||
auto sizeWritten = write(SERVERSOCKET, arg.c_str(), arg.length());
|
auto sizeWritten = write(SERVERSOCKET, arg.c_str(), arg.length());
|
||||||
|
|
||||||
if (sizeWritten < 0) {
|
if (sizeWritten < 0) {
|
||||||
std::cout << "Couldn't write (4)";
|
log("Couldn't write (4)");
|
||||||
return;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[8192] = {0};
|
char buffer[8192] = {0};
|
||||||
@@ -213,18 +270,26 @@ void requestHyprpaper(std::string arg) {
|
|||||||
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
||||||
|
|
||||||
if (sizeWritten < 0) {
|
if (sizeWritten < 0) {
|
||||||
std::cout << "Couldn't read (5)";
|
log("Couldn't read (5)");
|
||||||
return;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(SERVERSOCKET);
|
close(SERVERSOCKET);
|
||||||
|
|
||||||
std::cout << std::string(buffer);
|
log(std::string(buffer));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void batchRequest(std::string arg) {
|
void batchRequest(std::string arg, bool json) {
|
||||||
std::string rq = "[[BATCH]]" + arg.substr(arg.find_first_of(" ") + 1);
|
std::string commands = arg.substr(arg.find_first_of(' ') + 1);
|
||||||
|
|
||||||
|
if (json) {
|
||||||
|
RE2::GlobalReplace(&commands, ";\\s*", ";j/");
|
||||||
|
commands.insert(0, "j/");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string rq = "[[BATCH]]" + commands;
|
||||||
request(rq);
|
request(rq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,12 +300,12 @@ void instancesRequest(bool json) {
|
|||||||
std::vector<SInstanceData> inst = instances();
|
std::vector<SInstanceData> inst = instances();
|
||||||
|
|
||||||
if (!json) {
|
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);
|
result += std::format("instance {}:\n\ttime: {}\n\tpid: {}\n\twl socket: {}\n\n", el.id, el.time, el.pid, el.wlSocket);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result += '[';
|
result += '[';
|
||||||
for (auto& el : inst) {
|
for (auto const& el : inst) {
|
||||||
result += std::format(R"#(
|
result += std::format(R"#(
|
||||||
{{
|
{{
|
||||||
"instance": "{}",
|
"instance": "{}",
|
||||||
@@ -255,30 +320,23 @@ void instancesRequest(bool json) {
|
|||||||
result += "\n]";
|
result += "\n]";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << result << "\n";
|
log(result + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::deque<std::string> splitArgs(int argc, char** argv) {
|
std::vector<std::string> splitArgs(int argc, char** argv) {
|
||||||
std::deque<std::string> result;
|
std::vector<std::string> result;
|
||||||
|
|
||||||
for (auto i = 1 /* skip the executable */; i < argc; ++i)
|
for (auto i = 1 /* skip the executable */; i < argc; ++i)
|
||||||
result.push_back(std::string(argv[i]));
|
result.emplace_back(argv[i]);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNumber(const std::string& str, bool allowfloat) {
|
|
||||||
if (str.empty())
|
|
||||||
return false;
|
|
||||||
return std::ranges::all_of(str.begin(), str.end(), [&](char c) { return isdigit(c) != 0 || c == '-' || (allowfloat && c == '.'); });
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
int bflag = 0, sflag = 0, index, c;
|
|
||||||
bool parseArgs = true;
|
bool parseArgs = true;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf("%s\n", USAGE.c_str());
|
std::println("{}", USAGE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,9 +344,10 @@ int main(int argc, char** argv) {
|
|||||||
std::string fullArgs = "";
|
std::string fullArgs = "";
|
||||||
const auto ARGS = splitArgs(argc, argv);
|
const auto ARGS = splitArgs(argc, argv);
|
||||||
bool json = false;
|
bool json = false;
|
||||||
|
bool needRoll = false;
|
||||||
std::string overrideInstance = "";
|
std::string overrideInstance = "";
|
||||||
|
|
||||||
for (auto i = 0; i < ARGS.size(); ++i) {
|
for (std::size_t i = 0; i < ARGS.size(); ++i) {
|
||||||
if (ARGS[i] == "--") {
|
if (ARGS[i] == "--") {
|
||||||
// Stop parsing arguments after --
|
// Stop parsing arguments after --
|
||||||
parseArgs = false;
|
parseArgs = false;
|
||||||
@@ -299,19 +358,50 @@ int main(int argc, char** argv) {
|
|||||||
if (ARGS[i] == "-j" && !fullArgs.contains("j")) {
|
if (ARGS[i] == "-j" && !fullArgs.contains("j")) {
|
||||||
fullArgs += "j";
|
fullArgs += "j";
|
||||||
json = true;
|
json = true;
|
||||||
|
} else if (ARGS[i] == "-r" && !fullArgs.contains("r")) {
|
||||||
|
fullArgs += "r";
|
||||||
|
} else if (ARGS[i] == "-a" && !fullArgs.contains("a")) {
|
||||||
|
fullArgs += "a";
|
||||||
|
} else if ((ARGS[i] == "-c" || ARGS[i] == "--config") && !fullArgs.contains("c")) {
|
||||||
|
fullArgs += "c";
|
||||||
|
} else if ((ARGS[i] == "-f" || ARGS[i] == "--follow") && !fullArgs.contains("f")) {
|
||||||
|
fullArgs += "f";
|
||||||
|
needRoll = true;
|
||||||
} else if (ARGS[i] == "--batch") {
|
} else if (ARGS[i] == "--batch") {
|
||||||
fullRequest = "--batch ";
|
fullRequest = "--batch ";
|
||||||
} else if (ARGS[i] == "--instance" || ARGS[i] == "-i") {
|
} else if (ARGS[i] == "--instance" || ARGS[i] == "-i") {
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
if (i >= ARGS.size()) {
|
if (i >= ARGS.size()) {
|
||||||
printf("%s\n", USAGE.c_str());
|
std::println("{}", USAGE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
overrideInstance = ARGS[i];
|
overrideInstance = ARGS[i];
|
||||||
|
} else if (ARGS[i] == "-q" || ARGS[i] == "--quiet") {
|
||||||
|
quiet = true;
|
||||||
|
} else if (ARGS[i] == "--help") {
|
||||||
|
const std::string& cmd = ARGS[0];
|
||||||
|
|
||||||
|
if (cmd == "hyprpaper") {
|
||||||
|
std::println("{}", HYPRPAPER_HELP);
|
||||||
|
} else if (cmd == "notify") {
|
||||||
|
std::println("{}", NOTIFY_HELP);
|
||||||
|
} else if (cmd == "output") {
|
||||||
|
std::println("{}", OUTPUT_HELP);
|
||||||
|
} else if (cmd == "plugin") {
|
||||||
|
std::println("{}", PLUGIN_HELP);
|
||||||
|
} else if (cmd == "setprop") {
|
||||||
|
std::println("{}", SETPROP_HELP);
|
||||||
|
} else if (cmd == "switchxkblayout") {
|
||||||
|
std::println("{}", SWITCHXKBLAYOUT_HELP);
|
||||||
} else {
|
} else {
|
||||||
printf("%s\n", USAGE.c_str());
|
std::println("{}", USAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
std::println("{}", USAGE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +412,7 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fullRequest.empty()) {
|
if (fullRequest.empty()) {
|
||||||
printf("%s\n", USAGE.c_str());
|
std::println("{}", USAGE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,11 +420,22 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
fullRequest = fullArgs + "/" + fullRequest;
|
fullRequest = fullArgs + "/" + fullRequest;
|
||||||
|
|
||||||
|
// instances is HIS-independent
|
||||||
|
if (fullRequest.contains("/instances")) {
|
||||||
|
instancesRequest(json);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needRoll && !fullRequest.contains("/rollinglog")) {
|
||||||
|
log("only 'rollinglog' command supports '--follow' option");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (overrideInstance.contains("_"))
|
if (overrideInstance.contains("_"))
|
||||||
instanceSignature = overrideInstance;
|
instanceSignature = overrideInstance;
|
||||||
else if (!overrideInstance.empty()) {
|
else if (!overrideInstance.empty()) {
|
||||||
if (!isNumber(overrideInstance, false)) {
|
if (!isNumber(overrideInstance, false)) {
|
||||||
std::cout << "instance invalid\n";
|
log("instance invalid\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,8 +443,8 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
const auto INSTANCES = instances();
|
const auto INSTANCES = instances();
|
||||||
|
|
||||||
if (INSTANCENO < 0 || INSTANCENO >= INSTANCES.size()) {
|
if (INSTANCENO < 0 || static_cast<std::size_t>(INSTANCENO) >= INSTANCES.size()) {
|
||||||
std::cout << "no such instance\n";
|
log("no such instance\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +453,7 @@ int main(int argc, char** argv) {
|
|||||||
const auto ISIG = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
const auto ISIG = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||||
|
|
||||||
if (!ISIG) {
|
if (!ISIG) {
|
||||||
std::cout << "HYPRLAND_INSTANCE_SIGNATURE not set! (is hyprland running?)";
|
log("HYPRLAND_INSTANCE_SIGNATURE not set! (is hyprland running?)\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,70 +463,39 @@ int main(int argc, char** argv) {
|
|||||||
int exitStatus = 0;
|
int exitStatus = 0;
|
||||||
|
|
||||||
if (fullRequest.contains("/--batch"))
|
if (fullRequest.contains("/--batch"))
|
||||||
batchRequest(fullRequest);
|
batchRequest(fullRequest, json);
|
||||||
else if (fullRequest.contains("/monitors"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/clients"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/workspaces"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/activeworkspace"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/workspacerules"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/activewindow"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/layers"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/version"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/kill"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/splash"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/devices"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/reload"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/getoption"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/binds"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/cursorpos"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/animations"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/globalshortcuts"))
|
|
||||||
request(fullRequest);
|
|
||||||
else if (fullRequest.contains("/instances"))
|
|
||||||
instancesRequest(json);
|
|
||||||
else if (fullRequest.contains("/switchxkblayout"))
|
|
||||||
request(fullRequest, 2);
|
|
||||||
else if (fullRequest.contains("/seterror"))
|
|
||||||
request(fullRequest, 1);
|
|
||||||
else if (fullRequest.contains("/setprop"))
|
|
||||||
request(fullRequest, 3);
|
|
||||||
else if (fullRequest.contains("/plugin"))
|
|
||||||
request(fullRequest, 1);
|
|
||||||
else if (fullRequest.contains("/notify"))
|
|
||||||
request(fullRequest, 2);
|
|
||||||
else if (fullRequest.contains("/output"))
|
|
||||||
request(fullRequest, 2);
|
|
||||||
else if (fullRequest.contains("/setcursor"))
|
|
||||||
request(fullRequest, 1);
|
|
||||||
else if (fullRequest.contains("/dispatch"))
|
|
||||||
request(fullRequest, 1);
|
|
||||||
else if (fullRequest.contains("/keyword"))
|
|
||||||
request(fullRequest, 2);
|
|
||||||
else if (fullRequest.contains("/hyprpaper"))
|
else if (fullRequest.contains("/hyprpaper"))
|
||||||
requestHyprpaper(fullRequest);
|
exitStatus = requestHyprpaper(fullRequest);
|
||||||
|
else if (fullRequest.contains("/switchxkblayout"))
|
||||||
|
exitStatus = request(fullRequest, 2);
|
||||||
|
else if (fullRequest.contains("/seterror"))
|
||||||
|
exitStatus = request(fullRequest, 1);
|
||||||
|
else if (fullRequest.contains("/setprop"))
|
||||||
|
exitStatus = request(fullRequest, 3);
|
||||||
|
else if (fullRequest.contains("/plugin"))
|
||||||
|
exitStatus = request(fullRequest, 1);
|
||||||
|
else if (fullRequest.contains("/dismissnotify"))
|
||||||
|
exitStatus = request(fullRequest, 0);
|
||||||
|
else if (fullRequest.contains("/notify"))
|
||||||
|
exitStatus = request(fullRequest, 2);
|
||||||
|
else if (fullRequest.contains("/output"))
|
||||||
|
exitStatus = request(fullRequest, 2);
|
||||||
|
else if (fullRequest.contains("/setcursor"))
|
||||||
|
exitStatus = request(fullRequest, 1);
|
||||||
|
else if (fullRequest.contains("/dispatch"))
|
||||||
|
exitStatus = request(fullRequest, 1);
|
||||||
|
else if (fullRequest.contains("/keyword"))
|
||||||
|
exitStatus = request(fullRequest, 2);
|
||||||
|
else if (fullRequest.contains("/decorations"))
|
||||||
|
exitStatus = request(fullRequest, 1);
|
||||||
else if (fullRequest.contains("/--help"))
|
else if (fullRequest.contains("/--help"))
|
||||||
printf("%s", USAGE.c_str());
|
std::println("{}", USAGE);
|
||||||
|
else if (fullRequest.contains("/rollinglog") && needRoll)
|
||||||
|
exitStatus = request(fullRequest, 0, true);
|
||||||
else {
|
else {
|
||||||
printf("%s\n", USAGE.c_str());
|
exitStatus = request(fullRequest);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
std::cout << std::flush;
|
||||||
return exitStatus;
|
return exitStatus;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,27 @@
|
|||||||
executable('hyprctl', 'main.cpp',
|
executable(
|
||||||
install: true
|
'hyprctl',
|
||||||
|
'main.cpp',
|
||||||
|
dependencies: [
|
||||||
|
dependency('hyprutils', version: '>= 0.1.1'),
|
||||||
|
dependency('re2', required: 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',
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
prefix="@PREFIX@"
|
prefix=@PREFIX@/@INCLUDEDIR@
|
||||||
includedir="${prefix}/include"
|
|
||||||
|
|
||||||
Name: Hyprland
|
Name: Hyprland
|
||||||
URL: https://github.com/hyprwm/Hyprland
|
URL: https://github.com/hyprwm/Hyprland
|
||||||
Description: Hyprland header files
|
Description: Hyprland header files
|
||||||
Version: @HYPRLAND_VERSION@
|
Version: @HYPRLAND_VERSION@
|
||||||
Cflags: -I"${includedir}/hyprland/protocols" -I"${includedir}/hyprland/wlroots" -I"${includedir}"
|
Cflags: -I${prefix} -I${prefix}/hyprland/protocols -I${prefix}/hyprland
|
||||||
|
|||||||
29
hyprpm/CMakeLists.txt
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.19)
|
||||||
|
|
||||||
|
project(
|
||||||
|
hyprpm
|
||||||
|
DESCRIPTION "A Hyprland Plugin Manager"
|
||||||
|
)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
|
pkg_check_modules(hyprpm_deps REQUIRED IMPORTED_TARGET tomlplusplus hyprutils>=0.2.4)
|
||||||
|
|
||||||
|
add_executable(hyprpm ${SRCFILES})
|
||||||
|
|
||||||
|
target_link_libraries(hyprpm PUBLIC PkgConfig::hyprpm_deps)
|
||||||
|
|
||||||
|
# binary
|
||||||
|
install(TARGETS hyprpm)
|
||||||
|
|
||||||
|
# shell completions
|
||||||
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/hyprpm.bash
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/bash-completion/completions
|
||||||
|
RENAME hyprpm)
|
||||||
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/hyprpm.fish
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/fish/vendor_completions.d)
|
||||||
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/hyprpm.zsh
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/zsh/site-functions
|
||||||
|
RENAME _hyprpm)
|
||||||
108
hyprpm/hyprpm.bash
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
_hyprpm_cmd_0 () {
|
||||||
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprpm_cmd_1 () {
|
||||||
|
hyprpm list | awk '/Repository/{print $4}' | sed 's/:$//'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprpm () {
|
||||||
|
if [[ $(type -t _get_comp_words_by_ref) != function ]]; then
|
||||||
|
echo _get_comp_words_by_ref: function not defined. Make sure the bash-completions system package is installed
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local words cword
|
||||||
|
_get_comp_words_by_ref -n "$COMP_WORDBREAKS" words cword
|
||||||
|
|
||||||
|
declare -a literals=(--no-shallow -n ::= disable list --help update add --verbose -v --force -s remove enable --notify -h reload -f)
|
||||||
|
declare -A literal_transitions
|
||||||
|
literal_transitions[0]="([0]=7 [3]=3 [4]=4 [8]=7 [9]=7 [6]=4 [7]=4 [11]=7 [5]=7 [10]=7 [12]=2 [13]=3 [15]=7 [16]=4 [17]=7)"
|
||||||
|
literal_transitions[1]="([12]=2 [13]=3 [3]=3 [4]=4 [16]=4 [6]=4 [7]=4)"
|
||||||
|
literal_transitions[5]="([2]=6)"
|
||||||
|
literal_transitions[6]="([1]=7 [14]=7)"
|
||||||
|
declare -A match_anything_transitions=([1]=1 [4]=5 [3]=4 [2]=4 [0]=1)
|
||||||
|
declare -A subword_transitions
|
||||||
|
|
||||||
|
local state=0
|
||||||
|
local word_index=1
|
||||||
|
while [[ $word_index -lt $cword ]]; do
|
||||||
|
local word=${words[$word_index]}
|
||||||
|
|
||||||
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
|
declare -A state_transitions
|
||||||
|
eval "state_transitions=${literal_transitions[$state]}"
|
||||||
|
|
||||||
|
local word_matched=0
|
||||||
|
for literal_id in $(seq 0 $((${#literals[@]} - 1))); do
|
||||||
|
if [[ ${literals[$literal_id]} = "$word" ]]; then
|
||||||
|
if [[ -v "state_transitions[$literal_id]" ]]; then
|
||||||
|
state=${state_transitions[$literal_id]}
|
||||||
|
word_index=$((word_index + 1))
|
||||||
|
word_matched=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ $word_matched -ne 0 ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v "match_anything_transitions[$state]" ]]; then
|
||||||
|
state=${match_anything_transitions[$state]}
|
||||||
|
word_index=$((word_index + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
local -a matches=()
|
||||||
|
|
||||||
|
local prefix="${words[$cword]}"
|
||||||
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
|
local state_transitions_initializer=${literal_transitions[$state]}
|
||||||
|
declare -A state_transitions
|
||||||
|
eval "state_transitions=$state_transitions_initializer"
|
||||||
|
|
||||||
|
for literal_id in "${!state_transitions[@]}"; do
|
||||||
|
local literal="${literals[$literal_id]}"
|
||||||
|
if [[ $literal = "${prefix}"* ]]; then
|
||||||
|
matches+=("$literal ")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
declare -A commands
|
||||||
|
commands=([3]=0 [2]=1)
|
||||||
|
if [[ -v "commands[$state]" ]]; then
|
||||||
|
local command_id=${commands[$state]}
|
||||||
|
local completions=()
|
||||||
|
readarray -t completions < <(_hyprpm_cmd_${command_id} "$prefix" | cut -f1)
|
||||||
|
for item in "${completions[@]}"; do
|
||||||
|
if [[ $item = "${prefix}"* ]]; then
|
||||||
|
matches+=("$item")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
local shortest_suffix="$prefix"
|
||||||
|
for ((i=0; i < ${#COMP_WORDBREAKS}; i++)); do
|
||||||
|
local char="${COMP_WORDBREAKS:$i:1}"
|
||||||
|
local candidate=${prefix##*$char}
|
||||||
|
if [[ ${#candidate} -lt ${#shortest_suffix} ]]; then
|
||||||
|
shortest_suffix=$candidate
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
local superfluous_prefix=""
|
||||||
|
if [[ "$shortest_suffix" != "$prefix" ]]; then
|
||||||
|
local superfluous_prefix=${prefix%$shortest_suffix}
|
||||||
|
fi
|
||||||
|
COMPREPLY=("${matches[@]#$superfluous_prefix}")
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -o nospace -F _hyprpm hyprpm
|
||||||
116
hyprpm/hyprpm.fish
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
function _hyprpm_1
|
||||||
|
set 1 $argv[1]
|
||||||
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
|
end
|
||||||
|
|
||||||
|
function _hyprpm_2
|
||||||
|
set 1 $argv[1]
|
||||||
|
hyprpm list | awk '/Repository/{print $4}' | sed 's/:$//'
|
||||||
|
end
|
||||||
|
|
||||||
|
function _hyprpm
|
||||||
|
set COMP_LINE (commandline --cut-at-cursor)
|
||||||
|
|
||||||
|
set COMP_WORDS
|
||||||
|
echo $COMP_LINE | read --tokenize --array COMP_WORDS
|
||||||
|
if string match --quiet --regex '.*\s$' $COMP_LINE
|
||||||
|
set COMP_CWORD (math (count $COMP_WORDS) + 1)
|
||||||
|
else
|
||||||
|
set COMP_CWORD (count $COMP_WORDS)
|
||||||
|
end
|
||||||
|
|
||||||
|
set literals "--no-shallow" "-n" "::=" "disable" "list" "--help" "update" "add" "--verbose" "-v" "--force" "-s" "remove" "enable" "--notify" "-h" "reload" "-f"
|
||||||
|
|
||||||
|
set descriptions
|
||||||
|
set descriptions[1] "Disable shallow cloning of Hyprland sources"
|
||||||
|
set descriptions[2] "Send a hyprland notification for important events (e.g. load fail)"
|
||||||
|
set descriptions[4] "Unload a plugin"
|
||||||
|
set descriptions[5] "List all installed plugins"
|
||||||
|
set descriptions[6] "Show help menu"
|
||||||
|
set descriptions[7] "Check and update all plugins if needed"
|
||||||
|
set descriptions[8] "Install a new plugin repository from git"
|
||||||
|
set descriptions[9] "Enable too much loggin"
|
||||||
|
set descriptions[10] "Enable too much loggin"
|
||||||
|
set descriptions[11] "Force an operation ignoring checks (e.g. update -f)"
|
||||||
|
set descriptions[12] "Disable shallow cloning of Hyprland sources"
|
||||||
|
set descriptions[13] "Remove a plugin repository"
|
||||||
|
set descriptions[14] "Load a plugin"
|
||||||
|
set descriptions[15] "Send a hyprland notification for important events (e.g. load fail)"
|
||||||
|
set descriptions[16] "Show help menu"
|
||||||
|
set descriptions[17] "Reload all plugins"
|
||||||
|
set descriptions[18] "Force an operation ignoring checks (e.g. update -f)"
|
||||||
|
|
||||||
|
set literal_transitions
|
||||||
|
set literal_transitions[1] "set inputs 1 4 5 9 10 7 8 12 6 11 13 14 16 17 18; set tos 8 4 5 8 8 5 5 8 8 8 3 4 8 5 8"
|
||||||
|
set literal_transitions[2] "set inputs 13 14 4 5 17 7 8; set tos 3 4 4 5 5 5 5"
|
||||||
|
set literal_transitions[6] "set inputs 3; set tos 7"
|
||||||
|
set literal_transitions[7] "set inputs 2 15; set tos 8 8"
|
||||||
|
|
||||||
|
set match_anything_transitions_from 2 5 4 3 1
|
||||||
|
set match_anything_transitions_to 2 6 5 5 2
|
||||||
|
|
||||||
|
set state 1
|
||||||
|
set word_index 2
|
||||||
|
while test $word_index -lt $COMP_CWORD
|
||||||
|
set -- word $COMP_WORDS[$word_index]
|
||||||
|
|
||||||
|
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
||||||
|
set --erase inputs
|
||||||
|
set --erase tos
|
||||||
|
eval $literal_transitions[$state]
|
||||||
|
|
||||||
|
if contains -- $word $literals
|
||||||
|
set literal_matched 0
|
||||||
|
for literal_id in (seq 1 (count $literals))
|
||||||
|
if test $literals[$literal_id] = $word
|
||||||
|
set index (contains --index -- $literal_id $inputs)
|
||||||
|
set state $tos[$index]
|
||||||
|
set word_index (math $word_index + 1)
|
||||||
|
set literal_matched 1
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if test $literal_matched -ne 0
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if set --query match_anything_transitions_from[$state] && test -n $match_anything_transitions_from[$state]
|
||||||
|
set index (contains --index -- $state $match_anything_transitions_from)
|
||||||
|
set state $match_anything_transitions_to[$index]
|
||||||
|
set word_index (math $word_index + 1)
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
||||||
|
set --erase inputs
|
||||||
|
set --erase tos
|
||||||
|
eval $literal_transitions[$state]
|
||||||
|
for literal_id in $inputs
|
||||||
|
if test -n $descriptions[$literal_id]
|
||||||
|
printf '%s\t%s\n' $literals[$literal_id] $descriptions[$literal_id]
|
||||||
|
else
|
||||||
|
printf '%s\n' $literals[$literal_id]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
set command_states 4 3
|
||||||
|
set command_ids 1 2
|
||||||
|
if contains $state $command_states
|
||||||
|
set index (contains --index $state $command_states)
|
||||||
|
set function_id $command_ids[$index]
|
||||||
|
set function_name _hyprpm_$function_id
|
||||||
|
set --erase inputs
|
||||||
|
set --erase tos
|
||||||
|
$function_name "$COMP_WORDS[$COMP_CWORD]"
|
||||||
|
end
|
||||||
|
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
complete --command hyprpm --no-files --arguments "(_hyprpm)"
|
||||||
21
hyprpm/hyprpm.usage
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
hyprpm [<FLAGS>]... <ARGUMENT>
|
||||||
|
|
||||||
|
|
||||||
|
<FLAGS> ::= (--notify | -n) "Send a hyprland notification for important events (e.g. load fail)"
|
||||||
|
| (--help | -h) "Show help menu"
|
||||||
|
| (--verbose | -v) "Enable too much loggin"
|
||||||
|
| (--force | -f) "Force an operation ignoring checks (e.g. update -f)"
|
||||||
|
| (--no-shallow | -s) "Disable shallow cloning of Hyprland sources"
|
||||||
|
;
|
||||||
|
|
||||||
|
<ARGUMENT> ::= (add) "Install a new plugin repository from git"
|
||||||
|
| (remove <PLUGIN_REPOS>) "Remove a plugin repository"
|
||||||
|
| (update) "Check and update all plugins if needed"
|
||||||
|
| (list) "List all installed plugins"
|
||||||
|
| (enable <PLUGINS>) "Load a plugin"
|
||||||
|
| (disable <PLUGINS>) "Unload a plugin"
|
||||||
|
| (reload) "Reload all plugins"
|
||||||
|
;
|
||||||
|
|
||||||
|
<PLUGINS> ::= {{{ hyprpm list | awk '/Plugin/{print $4}' }}};
|
||||||
|
<PLUGIN_REPOS> ::= {{{ hyprpm list | awk '/Repository/{print $4}' | sed 's/:$//' }}};
|
||||||
157
hyprpm/hyprpm.zsh
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#compdef hyprpm
|
||||||
|
|
||||||
|
_hyprpm_cmd_0 () {
|
||||||
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprpm_cmd_1 () {
|
||||||
|
hyprpm list | awk '/Repository/{print $4}' | sed 's/:$//'
|
||||||
|
}
|
||||||
|
|
||||||
|
_hyprpm () {
|
||||||
|
local -a literals=("--no-shallow" "-n" "::=" "disable" "list" "--help" "update" "add" "--verbose" "-v" "--force" "-s" "remove" "enable" "--notify" "-h" "reload" "-f")
|
||||||
|
|
||||||
|
local -A descriptions
|
||||||
|
descriptions[1]="Disable shallow cloning of Hyprland sources"
|
||||||
|
descriptions[2]="Send a hyprland notification for important events (e.g. load fail)"
|
||||||
|
descriptions[4]="Unload a plugin"
|
||||||
|
descriptions[5]="List all installed plugins"
|
||||||
|
descriptions[6]="Show help menu"
|
||||||
|
descriptions[7]="Check and update all plugins if needed"
|
||||||
|
descriptions[8]="Install a new plugin repository from git"
|
||||||
|
descriptions[9]="Enable too much loggin"
|
||||||
|
descriptions[10]="Enable too much loggin"
|
||||||
|
descriptions[11]="Force an operation ignoring checks (e.g. update -f)"
|
||||||
|
descriptions[12]="Disable shallow cloning of Hyprland sources"
|
||||||
|
descriptions[13]="Remove a plugin repository"
|
||||||
|
descriptions[14]="Load a plugin"
|
||||||
|
descriptions[15]="Send a hyprland notification for important events (e.g. load fail)"
|
||||||
|
descriptions[16]="Show help menu"
|
||||||
|
descriptions[17]="Reload all plugins"
|
||||||
|
descriptions[18]="Force an operation ignoring checks (e.g. update -f)"
|
||||||
|
|
||||||
|
local -A literal_transitions
|
||||||
|
literal_transitions[1]="([1]=8 [4]=4 [5]=5 [9]=8 [10]=8 [7]=5 [8]=5 [12]=8 [6]=8 [11]=8 [13]=3 [14]=4 [16]=8 [17]=5 [18]=8)"
|
||||||
|
literal_transitions[2]="([13]=3 [14]=4 [4]=4 [5]=5 [17]=5 [7]=5 [8]=5)"
|
||||||
|
literal_transitions[6]="([3]=7)"
|
||||||
|
literal_transitions[7]="([2]=8 [15]=8)"
|
||||||
|
|
||||||
|
local -A match_anything_transitions
|
||||||
|
match_anything_transitions=([2]=2 [5]=6 [4]=5 [3]=5 [1]=2)
|
||||||
|
|
||||||
|
declare -A subword_transitions
|
||||||
|
|
||||||
|
local state=1
|
||||||
|
local word_index=2
|
||||||
|
while [[ $word_index -lt $CURRENT ]]; do
|
||||||
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
|
local -A state_transitions
|
||||||
|
eval "state_transitions=${literal_transitions[$state]}"
|
||||||
|
|
||||||
|
local word=${words[$word_index]}
|
||||||
|
local word_matched=0
|
||||||
|
for ((literal_id = 1; literal_id <= $#literals; literal_id++)); do
|
||||||
|
if [[ ${literals[$literal_id]} = "$word" ]]; then
|
||||||
|
if [[ -v "state_transitions[$literal_id]" ]]; then
|
||||||
|
state=${state_transitions[$literal_id]}
|
||||||
|
word_index=$((word_index + 1))
|
||||||
|
word_matched=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ $word_matched -ne 0 ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v "match_anything_transitions[$state]" ]]; then
|
||||||
|
state=${match_anything_transitions[$state]}
|
||||||
|
word_index=$((word_index + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
done
|
||||||
|
|
||||||
|
completions_no_description_trailing_space=()
|
||||||
|
completions_no_description_no_trailing_space=()
|
||||||
|
completions_trailing_space=()
|
||||||
|
suffixes_trailing_space=()
|
||||||
|
descriptions_trailing_space=()
|
||||||
|
completions_no_trailing_space=()
|
||||||
|
suffixes_no_trailing_space=()
|
||||||
|
descriptions_no_trailing_space=()
|
||||||
|
|
||||||
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
|
local -A state_transitions
|
||||||
|
eval "state_transitions=${literal_transitions[$state]}"
|
||||||
|
|
||||||
|
for literal_id in ${(k)state_transitions}; do
|
||||||
|
if [[ -v "descriptions[$literal_id]" ]]; then
|
||||||
|
completions_trailing_space+=("${literals[$literal_id]}")
|
||||||
|
suffixes_trailing_space+=("${literals[$literal_id]}")
|
||||||
|
descriptions_trailing_space+=("${descriptions[$literal_id]}")
|
||||||
|
else
|
||||||
|
completions_no_description_trailing_space+=("${literals[$literal_id]}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
local -A commands=([4]=0 [3]=1)
|
||||||
|
|
||||||
|
if [[ -v "commands[$state]" ]]; then
|
||||||
|
local command_id=${commands[$state]}
|
||||||
|
local output=$(_hyprpm_cmd_${command_id} "${words[$CURRENT]}")
|
||||||
|
local -a command_completions=("${(@f)output}")
|
||||||
|
for line in ${command_completions[@]}; do
|
||||||
|
local parts=(${(@s: :)line})
|
||||||
|
if [[ -v "parts[2]" ]]; then
|
||||||
|
completions_trailing_space+=("${parts[1]}")
|
||||||
|
suffixes_trailing_space+=("${parts[1]}")
|
||||||
|
descriptions_trailing_space+=("${parts[2]}")
|
||||||
|
else
|
||||||
|
completions_no_description_trailing_space+=("${parts[1]}")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
local maxlen=0
|
||||||
|
for suffix in ${suffixes_trailing_space[@]}; do
|
||||||
|
if [[ ${#suffix} -gt $maxlen ]]; then
|
||||||
|
maxlen=${#suffix}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
for suffix in ${suffixes_no_trailing_space[@]}; do
|
||||||
|
if [[ ${#suffix} -gt $maxlen ]]; then
|
||||||
|
maxlen=${#suffix}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for ((i = 1; i <= $#suffixes_trailing_space; i++)); do
|
||||||
|
if [[ -z ${descriptions_trailing_space[$i]} ]]; then
|
||||||
|
descriptions_trailing_space[$i]="${(r($maxlen)( ))${suffixes_trailing_space[$i]}}"
|
||||||
|
else
|
||||||
|
descriptions_trailing_space[$i]="${(r($maxlen)( ))${suffixes_trailing_space[$i]}} -- ${descriptions_trailing_space[$i]}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for ((i = 1; i <= $#suffixes_no_trailing_space; i++)); do
|
||||||
|
if [[ -z ${descriptions_no_trailing_space[$i]} ]]; then
|
||||||
|
descriptions_no_trailing_space[$i]="${(r($maxlen)( ))${suffixes_no_trailing_space[$i]}}"
|
||||||
|
else
|
||||||
|
descriptions_no_trailing_space[$i]="${(r($maxlen)( ))${suffixes_no_trailing_space[$i]}} -- ${descriptions_no_trailing_space[$i]}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
compadd -Q -a completions_no_description_trailing_space
|
||||||
|
compadd -Q -S ' ' -a completions_no_description_no_trailing_space
|
||||||
|
compadd -l -Q -a -d descriptions_trailing_space completions_trailing_space
|
||||||
|
compadd -l -Q -S '' -a -d descriptions_no_trailing_space completions_no_trailing_space
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $ZSH_EVAL_CONTEXT =~ :file$ ]]; then
|
||||||
|
compdef _hyprpm hyprpm
|
||||||
|
else
|
||||||
|
_hyprpm
|
||||||
|
fi
|
||||||
245
hyprpm/src/core/DataState.cpp
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
#include "DataState.hpp"
|
||||||
|
#include <toml++/toml.hpp>
|
||||||
|
#include <print>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include "PluginManager.hpp"
|
||||||
|
|
||||||
|
std::string DataState::getDataStatePath() {
|
||||||
|
const auto HOME = getenv("HOME");
|
||||||
|
if (!HOME) {
|
||||||
|
std::println(stderr, "DataState: no $HOME");
|
||||||
|
throw std::runtime_error("no $HOME");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DataState::getHeadersPath() {
|
||||||
|
return getDataStatePath() + "/headersRoot";
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataState::ensureStateStoreExists() {
|
||||||
|
const auto PATH = getDataStatePath();
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(PATH))
|
||||||
|
std::filesystem::create_directories(PATH);
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(getHeadersPath()))
|
||||||
|
std::filesystem::create_directories(getHeadersPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataState::addNewPluginRepo(const SPluginRepository& repo) {
|
||||||
|
ensureStateStoreExists();
|
||||||
|
|
||||||
|
const auto PATH = getDataStatePath() + "/" + repo.name;
|
||||||
|
|
||||||
|
std::filesystem::create_directories(PATH);
|
||||||
|
// clang-format off
|
||||||
|
auto DATA = toml::table{
|
||||||
|
{"repository", toml::table{
|
||||||
|
{"name", repo.name},
|
||||||
|
{"hash", repo.hash},
|
||||||
|
{"url", repo.url},
|
||||||
|
{"rev", repo.rev}
|
||||||
|
}}
|
||||||
|
};
|
||||||
|
for (auto const& p : repo.plugins) {
|
||||||
|
// copy .so to the good place
|
||||||
|
if (std::filesystem::exists(p.filename))
|
||||||
|
std::filesystem::copy_file(p.filename, PATH + "/" + p.name + ".so");
|
||||||
|
|
||||||
|
DATA.emplace(p.name, toml::table{
|
||||||
|
{"filename", p.name + ".so"},
|
||||||
|
{"enabled", p.enabled},
|
||||||
|
{"failed", p.failed}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
std::ofstream ofs(PATH + "/state.toml", std::ios::trunc);
|
||||||
|
ofs << DATA;
|
||||||
|
ofs.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataState::pluginRepoExists(const std::string& urlOrName) {
|
||||||
|
ensureStateStoreExists();
|
||||||
|
|
||||||
|
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("");
|
||||||
|
|
||||||
|
if (URL == urlOrName || NAME == urlOrName)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataState::removePluginRepo(const std::string& urlOrName) {
|
||||||
|
ensureStateStoreExists();
|
||||||
|
|
||||||
|
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("");
|
||||||
|
|
||||||
|
if (URL == urlOrName || NAME == urlOrName) {
|
||||||
|
|
||||||
|
// unload the plugins!!
|
||||||
|
for (const auto& file : std::filesystem::directory_iterator(entry.path())) {
|
||||||
|
if (!file.path().string().ends_with(".so"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
g_pPluginManager->loadUnloadPlugin(std::filesystem::absolute(file.path()), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::remove_all(entry.path());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataState::updateGlobalState(const SGlobalState& state) {
|
||||||
|
ensureStateStoreExists();
|
||||||
|
|
||||||
|
const auto PATH = getDataStatePath();
|
||||||
|
|
||||||
|
std::filesystem::create_directories(PATH);
|
||||||
|
// clang-format off
|
||||||
|
auto DATA = toml::table{
|
||||||
|
{"state", toml::table{
|
||||||
|
{"hash", state.headersHashCompiled},
|
||||||
|
{"dont_warn_install", state.dontWarnInstall}
|
||||||
|
}}
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
std::ofstream ofs(PATH + "/state.toml", std::ios::trunc);
|
||||||
|
ofs << DATA;
|
||||||
|
ofs.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
SGlobalState DataState::getGlobalState() {
|
||||||
|
ensureStateStoreExists();
|
||||||
|
|
||||||
|
const auto PATH = getDataStatePath();
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(PATH + "/state.toml"))
|
||||||
|
return SGlobalState{};
|
||||||
|
|
||||||
|
auto DATA = toml::parse_file(PATH + "/state.toml");
|
||||||
|
|
||||||
|
SGlobalState state;
|
||||||
|
state.headersHashCompiled = DATA["state"]["hash"].value_or("");
|
||||||
|
state.dontWarnInstall = DATA["state"]["dont_warn_install"].value_or(false);
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SPluginRepository> DataState::getAllRepositories() {
|
||||||
|
ensureStateStoreExists();
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
const auto NAME = STATE["repository"]["name"].value_or("");
|
||||||
|
const auto URL = STATE["repository"]["url"].value_or("");
|
||||||
|
const auto REV = STATE["repository"]["rev"].value_or("");
|
||||||
|
const auto HASH = STATE["repository"]["hash"].value_or("");
|
||||||
|
|
||||||
|
SPluginRepository repo;
|
||||||
|
repo.hash = HASH;
|
||||||
|
repo.name = NAME;
|
||||||
|
repo.url = URL;
|
||||||
|
repo.rev = REV;
|
||||||
|
|
||||||
|
for (const auto& [key, val] : STATE) {
|
||||||
|
if (key == "repository")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto ENABLED = STATE[key]["enabled"].value_or(false);
|
||||||
|
const auto FAILED = STATE[key]["failed"].value_or(false);
|
||||||
|
const auto FILENAME = STATE[key]["filename"].value_or("");
|
||||||
|
|
||||||
|
repo.plugins.push_back(SPlugin{std::string{key.str()}, FILENAME, ENABLED, FAILED});
|
||||||
|
}
|
||||||
|
|
||||||
|
repos.push_back(repo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return repos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataState::setPluginEnabled(const std::string& name, bool enabled) {
|
||||||
|
ensureStateStoreExists();
|
||||||
|
|
||||||
|
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& [key, val] : STATE) {
|
||||||
|
if (key == "repository")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (key.str() != name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto FAILED = STATE[key]["failed"].value_or(false);
|
||||||
|
|
||||||
|
if (FAILED)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
(*STATE[key].as_table()).insert_or_assign("enabled", enabled);
|
||||||
|
|
||||||
|
std::ofstream state(entry.path().string() + "/state.toml", std::ios::trunc);
|
||||||
|
state << STATE;
|
||||||
|
state.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
22
hyprpm/src/core/DataState.hpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "Plugin.hpp"
|
||||||
|
|
||||||
|
struct SGlobalState {
|
||||||
|
std::string headersHashCompiled = "";
|
||||||
|
bool dontWarnInstall = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
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();
|
||||||
|
};
|
||||||
105
hyprpm/src/core/Manifest.cpp
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#include "Manifest.hpp"
|
||||||
|
#include <toml++/toml.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
CManifest::CManifest(const eManifestType type, const std::string& path) {
|
||||||
|
auto manifest = toml::parse_file(path);
|
||||||
|
|
||||||
|
if (type == MANIFEST_HYPRLOAD) {
|
||||||
|
for (auto const& [key, val] : manifest) {
|
||||||
|
if (key.str().ends_with(".build"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CManifest::SManifestPlugin plugin;
|
||||||
|
plugin.name = key;
|
||||||
|
m_vPlugins.push_back(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& plugin : m_vPlugins) {
|
||||||
|
plugin.description = manifest[plugin.name]["description"].value_or("?");
|
||||||
|
plugin.version = manifest[plugin.name]["version"].value_or("?");
|
||||||
|
plugin.output = manifest[plugin.name]["build"]["output"].value_or("?");
|
||||||
|
auto authors = manifest[plugin.name]["authors"].as_array();
|
||||||
|
if (authors) {
|
||||||
|
for (auto&& a : *authors) {
|
||||||
|
plugin.authors.push_back(a.as_string()->value_or("?"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto author = manifest[plugin.name]["author"].value_or("");
|
||||||
|
if (!std::string{author}.empty())
|
||||||
|
plugin.authors.push_back(author);
|
||||||
|
}
|
||||||
|
auto buildSteps = manifest[plugin.name]["build"]["steps"].as_array();
|
||||||
|
if (buildSteps) {
|
||||||
|
for (auto&& s : *buildSteps) {
|
||||||
|
plugin.buildSteps.push_back(s.as_string()->value_or("?"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.output.empty() || plugin.buildSteps.empty()) {
|
||||||
|
m_bGood = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type == MANIFEST_HYPRPM) {
|
||||||
|
m_sRepository.name = manifest["repository"]["name"].value_or("");
|
||||||
|
auto authors = manifest["repository"]["authors"].as_array();
|
||||||
|
if (authors) {
|
||||||
|
for (auto&& a : *authors) {
|
||||||
|
m_sRepository.authors.push_back(a.as_string()->value_or("?"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto author = manifest["repository"]["author"].value_or("");
|
||||||
|
if (!std::string{author}.empty())
|
||||||
|
m_sRepository.authors.push_back(author);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pins = manifest["repository"]["commit_pins"].as_array();
|
||||||
|
if (pins) {
|
||||||
|
for (auto&& pin : *pins) {
|
||||||
|
auto pinArr = pin.as_array();
|
||||||
|
if (pinArr && pinArr->get(1))
|
||||||
|
m_sRepository.commitPins.push_back(std::make_pair<>(pinArr->get(0)->as_string()->get(), pinArr->get(1)->as_string()->get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& [key, val] : manifest) {
|
||||||
|
if (key.str() == "repository")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CManifest::SManifestPlugin plugin;
|
||||||
|
plugin.name = key;
|
||||||
|
m_vPlugins.push_back(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& plugin : m_vPlugins) {
|
||||||
|
plugin.description = manifest[plugin.name]["description"].value_or("?");
|
||||||
|
plugin.output = manifest[plugin.name]["output"].value_or("?");
|
||||||
|
plugin.since = manifest[plugin.name]["since_hyprland"].value_or(0);
|
||||||
|
auto authors = manifest[plugin.name]["authors"].as_array();
|
||||||
|
if (authors) {
|
||||||
|
for (auto&& a : *authors) {
|
||||||
|
plugin.authors.push_back(a.as_string()->value_or("?"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto author = manifest[plugin.name]["author"].value_or("");
|
||||||
|
if (!std::string{author}.empty())
|
||||||
|
plugin.authors.push_back(author);
|
||||||
|
}
|
||||||
|
auto buildSteps = manifest[plugin.name]["build"].as_array();
|
||||||
|
if (buildSteps) {
|
||||||
|
for (auto&& s : *buildSteps) {
|
||||||
|
plugin.buildSteps.push_back(s.as_string()->value_or("?"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.output.empty() || plugin.buildSteps.empty()) {
|
||||||
|
m_bGood = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ???
|
||||||
|
m_bGood = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
hyprpm/src/core/Manifest.hpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
enum eManifestType {
|
||||||
|
MANIFEST_HYPRLOAD,
|
||||||
|
MANIFEST_HYPRPM
|
||||||
|
};
|
||||||
|
|
||||||
|
class CManifest {
|
||||||
|
public:
|
||||||
|
CManifest(const eManifestType type, const std::string& path);
|
||||||
|
|
||||||
|
struct SManifestPlugin {
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
std::string version;
|
||||||
|
std::vector<std::string> authors;
|
||||||
|
std::vector<std::string> buildSteps;
|
||||||
|
std::string output;
|
||||||
|
int since = 0;
|
||||||
|
bool failed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::string> authors;
|
||||||
|
std::vector<std::pair<std::string, std::string>> commitPins;
|
||||||
|
} m_sRepository;
|
||||||
|
|
||||||
|
std::vector<SManifestPlugin> m_vPlugins;
|
||||||
|
bool m_bGood = true;
|
||||||
|
};
|
||||||
19
hyprpm/src/core/Plugin.hpp
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct SPlugin {
|
||||||
|
std::string name;
|
||||||
|
std::string filename;
|
||||||
|
bool enabled = false;
|
||||||
|
bool failed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SPluginRepository {
|
||||||
|
std::string url;
|
||||||
|
std::string rev;
|
||||||
|
std::string name;
|
||||||
|
std::vector<SPlugin> plugins;
|
||||||
|
std::string hash;
|
||||||
|
};
|
||||||
963
hyprpm/src/core/PluginManager.cpp
Normal file
@@ -0,0 +1,963 @@
|
|||||||
|
#include "PluginManager.hpp"
|
||||||
|
#include "../helpers/Colors.hpp"
|
||||||
|
#include "../helpers/StringUtils.hpp"
|
||||||
|
#include "../progress/CProgressBar.hpp"
|
||||||
|
#include "Manifest.hpp"
|
||||||
|
#include "DataState.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <iostream>
|
||||||
|
#include <array>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <print>
|
||||||
|
#include <thread>
|
||||||
|
#include <fstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <toml++/toml.hpp>
|
||||||
|
|
||||||
|
#include <hyprutils/string/String.hpp>
|
||||||
|
#include <hyprutils/os/Process.hpp>
|
||||||
|
using namespace Hyprutils::String;
|
||||||
|
using namespace Hyprutils::OS;
|
||||||
|
|
||||||
|
static std::string execAndGet(std::string cmd) {
|
||||||
|
cmd += " 2>&1";
|
||||||
|
|
||||||
|
CProcess proc("/bin/sh", {"-c", cmd});
|
||||||
|
|
||||||
|
if (!proc.runSync())
|
||||||
|
return "error";
|
||||||
|
|
||||||
|
return proc.stdOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getTempRoot() {
|
||||||
|
static auto ENV = getenv("XDG_RUNTIME_DIR");
|
||||||
|
if (!ENV) {
|
||||||
|
std::cerr << "\nERROR: XDG_RUNTIME_DIR not set!\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto STR = ENV + std::string{"/hyprpm/"};
|
||||||
|
|
||||||
|
return STR;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHyprlandVersion CPluginManager::getHyprlandVersion(bool running) {
|
||||||
|
static bool onceRunning = false;
|
||||||
|
static bool onceInstalled = false;
|
||||||
|
static SHyprlandVersion verRunning;
|
||||||
|
static SHyprlandVersion verInstalled;
|
||||||
|
|
||||||
|
if (onceRunning && running)
|
||||||
|
return verRunning;
|
||||||
|
|
||||||
|
if (onceInstalled && !running)
|
||||||
|
return verInstalled;
|
||||||
|
|
||||||
|
if (running)
|
||||||
|
onceRunning = true;
|
||||||
|
else
|
||||||
|
onceInstalled = true;
|
||||||
|
|
||||||
|
const auto HLVERCALL = running ? execAndGet("hyprctl version") : execAndGet("Hyprland --version");
|
||||||
|
if (m_bVerbose)
|
||||||
|
std::println("{}", verboseString("{} version returned: {}", running ? "running" : "installed", HLVERCALL));
|
||||||
|
|
||||||
|
if (!HLVERCALL.contains("Tag:")) {
|
||||||
|
std::println(stderr, "\n{}", failureString("You don't seem to be running Hyprland."));
|
||||||
|
return SHyprlandVersion{};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string hlcommit = HLVERCALL.substr(HLVERCALL.find("at commit") + 10);
|
||||||
|
hlcommit = hlcommit.substr(0, hlcommit.find_first_of(' '));
|
||||||
|
|
||||||
|
std::string hlbranch = HLVERCALL.substr(HLVERCALL.find("from branch") + 12);
|
||||||
|
hlbranch = hlbranch.substr(0, hlbranch.find(" at commit "));
|
||||||
|
|
||||||
|
std::string hldate = HLVERCALL.substr(HLVERCALL.find("Date: ") + 6);
|
||||||
|
hldate = hldate.substr(0, hldate.find("\n"));
|
||||||
|
|
||||||
|
std::string hlcommits;
|
||||||
|
|
||||||
|
if (HLVERCALL.contains("commits:")) {
|
||||||
|
hlcommits = HLVERCALL.substr(HLVERCALL.find("commits:") + 9);
|
||||||
|
hlcommits = hlcommits.substr(0, hlcommits.find(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
int commits = 0;
|
||||||
|
try {
|
||||||
|
commits = std::stoi(hlcommits);
|
||||||
|
} catch (...) { ; }
|
||||||
|
|
||||||
|
if (m_bVerbose)
|
||||||
|
std::println("{}", verboseString("parsed commit {} at branch {} on {}, commits {}", hlcommit, hlbranch, hldate, commits));
|
||||||
|
|
||||||
|
auto ver = SHyprlandVersion{hlbranch, hlcommit, hldate, commits};
|
||||||
|
|
||||||
|
if (running)
|
||||||
|
verRunning = ver;
|
||||||
|
else
|
||||||
|
verInstalled = ver;
|
||||||
|
|
||||||
|
return ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::createSafeDirectory(const std::string& path) {
|
||||||
|
if (path.empty() || !path.starts_with(getTempRoot()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (std::filesystem::exists(path))
|
||||||
|
std::filesystem::remove_all(path);
|
||||||
|
|
||||||
|
if (std::filesystem::exists(path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mkdir(path.c_str(), S_IRWXU) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string& rev) {
|
||||||
|
const auto HLVER = getHyprlandVersion();
|
||||||
|
|
||||||
|
if (!hasDeps()) {
|
||||||
|
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio, pkg-config"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DataState::pluginRepoExists(url)) {
|
||||||
|
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. Repository already installed."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto GLOBALSTATE = DataState::getGlobalState();
|
||||||
|
if (!GLOBALSTATE.dontWarnInstall) {
|
||||||
|
std::println("{}!{} Disclaimer: {}", Colors::YELLOW, Colors::RED, Colors::RESET);
|
||||||
|
std::println("plugins, especially not official, have no guarantee of stability, availablity or security.\n"
|
||||||
|
"Run them at your own risk.\n"
|
||||||
|
"This message will not appear again.");
|
||||||
|
GLOBALSTATE.dontWarnInstall = true;
|
||||||
|
DataState::updateGlobalState(GLOBALSTATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << Colors::GREEN << "✔" << Colors::RESET << Colors::RED << " adding a new plugin repository " << Colors::RESET << "from " << url << "\n " << Colors::RED
|
||||||
|
<< "MAKE SURE" << Colors::RESET << " that you trust the authors. " << Colors::RED << "DO NOT" << Colors::RESET
|
||||||
|
<< " install random plugins without verifying the code and author.\n "
|
||||||
|
<< "Are you sure? [Y/n] ";
|
||||||
|
std::fflush(stdout);
|
||||||
|
std::string input;
|
||||||
|
std::getline(std::cin, input);
|
||||||
|
|
||||||
|
if (input.size() > 0 && input[0] != 'Y' && input[0] != 'y') {
|
||||||
|
std::println(stderr, "Aborting.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CProgressBar progress;
|
||||||
|
progress.m_iMaxSteps = 5;
|
||||||
|
progress.m_iSteps = 0;
|
||||||
|
progress.m_szCurrentMessage = "Cloning the plugin repository";
|
||||||
|
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(getTempRoot())) {
|
||||||
|
std::filesystem::create_directory(getTempRoot());
|
||||||
|
std::filesystem::permissions(getTempRoot(), std::filesystem::perms::owner_all, std::filesystem::perm_options::replace);
|
||||||
|
} else if (!std::filesystem::is_directory(getTempRoot())) {
|
||||||
|
std::println(stderr, "\n{}", failureString("Could not prepare working dir for hyprpm"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string USERNAME = getpwuid(getuid())->pw_name;
|
||||||
|
|
||||||
|
m_szWorkingPluginDirectory = getTempRoot() + USERNAME;
|
||||||
|
|
||||||
|
if (!createSafeDirectory(m_szWorkingPluginDirectory)) {
|
||||||
|
std::println(stderr, "\n{}", failureString("Could not prepare working dir for repo"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.printMessageAbove(infoString("Cloning {}", url));
|
||||||
|
|
||||||
|
std::string ret = execAndGet(std::format("cd {} && git clone --recursive {} {}", getTempRoot(), url, USERNAME));
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
|
||||||
|
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. shell returned:\n{}", ret));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rev.empty()) {
|
||||||
|
std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " reset --hard --recurse-submodules " + rev);
|
||||||
|
if (ret.compare(0, 6, "fatal:") == 0) {
|
||||||
|
std::println(stderr, "\n{}", failureString("Could not check out revision {}. shell returned:\n{}", rev, ret));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
|
||||||
|
if (m_bVerbose)
|
||||||
|
std::println("{}", verboseString("git submodule update --init returned: {}", ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.m_iSteps = 1;
|
||||||
|
progress.printMessageAbove(successString("cloned"));
|
||||||
|
progress.m_szCurrentMessage = "Reading the manifest";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
std::unique_ptr<CManifest> pManifest;
|
||||||
|
|
||||||
|
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
|
||||||
|
progress.printMessageAbove(successString("found hyprpm manifest"));
|
||||||
|
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
|
||||||
|
} else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
|
||||||
|
progress.printMessageAbove(successString("found hyprload manifest"));
|
||||||
|
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pManifest) {
|
||||||
|
std::println(stderr, "\n{}", failureString("The provided plugin repository does not have a valid manifest"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pManifest->m_bGood) {
|
||||||
|
std::println(stderr, "\n{}", failureString("The provided plugin repository has a corrupted manifest"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.m_iSteps = 2;
|
||||||
|
progress.printMessageAbove(successString("parsed manifest, found " + std::to_string(pManifest->m_vPlugins.size()) + " plugins:"));
|
||||||
|
for (auto const& pl : pManifest->m_vPlugins) {
|
||||||
|
std::string message = "→ " + pl.name + " by ";
|
||||||
|
for (auto const& a : pl.authors) {
|
||||||
|
message += a + ", ";
|
||||||
|
}
|
||||||
|
if (pl.authors.size() > 0) {
|
||||||
|
message.pop_back();
|
||||||
|
message.pop_back();
|
||||||
|
}
|
||||||
|
message += " version " + pl.version;
|
||||||
|
progress.printMessageAbove(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pManifest->m_sRepository.commitPins.empty()) {
|
||||||
|
// check commit pins
|
||||||
|
|
||||||
|
progress.printMessageAbove(infoString("Manifest has {} pins, checking", pManifest->m_sRepository.commitPins.size()));
|
||||||
|
|
||||||
|
for (auto const& [hl, plugin] : pManifest->m_sRepository.commitPins) {
|
||||||
|
if (hl != HLVER.hash)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("commit pin {} matched hl, resetting", plugin));
|
||||||
|
|
||||||
|
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
|
||||||
|
|
||||||
|
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
|
||||||
|
if (m_bVerbose)
|
||||||
|
std::println("{}", verboseString("git submodule update --init returned: {}", ret));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.m_szCurrentMessage = "Verifying headers";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
const auto HEADERSSTATUS = headersValid();
|
||||||
|
|
||||||
|
if (HEADERSSTATUS != HEADERS_OK) {
|
||||||
|
std::println("\n{}", headerError(HEADERSSTATUS));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.m_iSteps = 3;
|
||||||
|
progress.printMessageAbove(successString("Hyprland headers OK"));
|
||||||
|
progress.m_szCurrentMessage = "Building plugin(s)";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
for (auto& p : pManifest->m_vPlugins) {
|
||||||
|
std::string out;
|
||||||
|
|
||||||
|
if (p.since > HLVER.commits && HLVER.commits >= 1 /* for --depth 1 clones, we can't check this. */) {
|
||||||
|
progress.printMessageAbove(failureString("Not building {}: your Hyprland version is too old.\n", p.name));
|
||||||
|
p.failed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.printMessageAbove(infoString("Building {}", p.name));
|
||||||
|
|
||||||
|
for (auto const& bs : p.buildSteps) {
|
||||||
|
const std::string& cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
||||||
|
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_bVerbose)
|
||||||
|
std::println("{}", verboseString("shell returned: {}", out));
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
|
||||||
|
progress.printMessageAbove(failureString("Plugin {} failed to build.\n"
|
||||||
|
" This likely means that the plugin is either outdated, not yet available for your version, or broken.\n"
|
||||||
|
" If you are on -git, update first\n"
|
||||||
|
" Try re-running with -v to see more verbose output.\n",
|
||||||
|
p.name));
|
||||||
|
|
||||||
|
p.failed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("built {} into {}", p.name, p.output));
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("all plugins built"));
|
||||||
|
progress.m_iSteps = 4;
|
||||||
|
progress.m_szCurrentMessage = "Installing repository";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
// add repo toml to DataState
|
||||||
|
SPluginRepository repo;
|
||||||
|
std::string repohash = execAndGet("cd " + m_szWorkingPluginDirectory + " && git rev-parse HEAD");
|
||||||
|
if (repohash.length() > 0)
|
||||||
|
repohash.pop_back();
|
||||||
|
repo.name = pManifest->m_sRepository.name.empty() ? url.substr(url.find_last_of('/') + 1) : pManifest->m_sRepository.name;
|
||||||
|
repo.url = url;
|
||||||
|
repo.rev = rev;
|
||||||
|
repo.hash = repohash;
|
||||||
|
for (auto const& p : pManifest->m_vPlugins) {
|
||||||
|
repo.plugins.push_back(SPlugin{p.name, m_szWorkingPluginDirectory + "/" + p.output, false, p.failed});
|
||||||
|
}
|
||||||
|
DataState::addNewPluginRepo(repo);
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("installed repository"));
|
||||||
|
progress.printMessageAbove(successString("you can now enable the plugin(s) with hyprpm enable"));
|
||||||
|
progress.m_iSteps = 5;
|
||||||
|
progress.m_szCurrentMessage = "Done!";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
std::print("\n");
|
||||||
|
|
||||||
|
// remove build files
|
||||||
|
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::removePluginRepo(const std::string& urlOrName) {
|
||||||
|
if (!DataState::pluginRepoExists(urlOrName)) {
|
||||||
|
std::println(stderr, "\n{}", failureString("Could not remove the repository. Repository is not installed."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << Colors::YELLOW << "!" << Colors::RESET << Colors::RED << " removing a plugin repository: " << Colors::RESET << urlOrName << "\n "
|
||||||
|
<< "Are you sure? [Y/n] ";
|
||||||
|
std::fflush(stdout);
|
||||||
|
std::string input;
|
||||||
|
std::getline(std::cin, input);
|
||||||
|
|
||||||
|
if (input.size() > 0 && input[0] != 'Y' && input[0] != 'y') {
|
||||||
|
std::println("Aborting.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataState::removePluginRepo(urlOrName);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
eHeadersErrors CPluginManager::headersValid() {
|
||||||
|
const auto HLVER = getHyprlandVersion(false);
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(DataState::getHeadersPath() + "/share/pkgconfig/hyprland.pc"))
|
||||||
|
return HEADERS_MISSING;
|
||||||
|
|
||||||
|
// find headers commit
|
||||||
|
const std::string& cmd = std::format("PKG_CONFIG_PATH=\"{}/share/pkgconfig\" pkgconf --cflags --keep-system-cflags hyprland", DataState::getHeadersPath());
|
||||||
|
auto headers = execAndGet(cmd.c_str());
|
||||||
|
|
||||||
|
if (!headers.contains("-I/"))
|
||||||
|
return HEADERS_MISSING;
|
||||||
|
|
||||||
|
headers.pop_back(); // pop newline
|
||||||
|
|
||||||
|
std::string verHeader;
|
||||||
|
|
||||||
|
while (!headers.empty()) {
|
||||||
|
const auto PATH = headers.substr(0, headers.find(" -I/", 3));
|
||||||
|
|
||||||
|
if (headers.find(" -I/", 3) != std::string::npos)
|
||||||
|
headers = headers.substr(headers.find("-I/", 3));
|
||||||
|
else
|
||||||
|
headers = "";
|
||||||
|
|
||||||
|
if (PATH.ends_with("protocols"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
verHeader = trim(PATH.substr(2)) + "/hyprland/src/version.h";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verHeader.empty())
|
||||||
|
return HEADERS_CORRUPTED;
|
||||||
|
|
||||||
|
// read header
|
||||||
|
std::ifstream ifs(verHeader);
|
||||||
|
if (!ifs.good())
|
||||||
|
return HEADERS_CORRUPTED;
|
||||||
|
|
||||||
|
std::string verHeaderContent((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
||||||
|
ifs.close();
|
||||||
|
|
||||||
|
const auto HASHPOS = verHeaderContent.find("#define GIT_COMMIT_HASH");
|
||||||
|
|
||||||
|
if (HASHPOS == std::string::npos || HASHPOS + 23 >= verHeaderContent.length())
|
||||||
|
return HEADERS_CORRUPTED;
|
||||||
|
|
||||||
|
std::string hash = verHeaderContent.substr(HASHPOS + 23);
|
||||||
|
hash = hash.substr(0, hash.find_first_of('\n'));
|
||||||
|
hash = hash.substr(hash.find_first_of('"') + 1);
|
||||||
|
hash = hash.substr(0, hash.find_first_of('"'));
|
||||||
|
|
||||||
|
if (hash != HLVER.hash)
|
||||||
|
return HEADERS_MISMATCHED;
|
||||||
|
|
||||||
|
return HEADERS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::updateHeaders(bool force) {
|
||||||
|
|
||||||
|
DataState::ensureStateStoreExists();
|
||||||
|
|
||||||
|
const auto HLVER = getHyprlandVersion(false);
|
||||||
|
|
||||||
|
if (!hasDeps()) {
|
||||||
|
std::println("\n{}", failureString("Could not update. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio, pkg-config"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(getTempRoot())) {
|
||||||
|
std::filesystem::create_directory(getTempRoot());
|
||||||
|
std::filesystem::permissions(getTempRoot(), std::filesystem::perms::owner_all, std::filesystem::perm_options::replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!force && headersValid() == HEADERS_OK) {
|
||||||
|
std::println("\n{}", successString("Headers up to date."));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CProgressBar progress;
|
||||||
|
progress.m_iMaxSteps = 5;
|
||||||
|
progress.m_iSteps = 0;
|
||||||
|
progress.m_szCurrentMessage = "Cloning the hyprland repository";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
const std::string USERNAME = getpwuid(getuid())->pw_name;
|
||||||
|
const auto WORKINGDIR = getTempRoot() + "hyprland-" + USERNAME;
|
||||||
|
|
||||||
|
if (!createSafeDirectory(WORKINGDIR)) {
|
||||||
|
std::println("\n{}", failureString("Could not prepare working dir for hl"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.printMessageAbove(statusString("!", Colors::YELLOW, "Cloning https://github.com/hyprwm/Hyprland, this might take a moment."));
|
||||||
|
|
||||||
|
const bool bShallow = (HLVER.branch == "main") && !m_bNoShallow;
|
||||||
|
|
||||||
|
// let us give a bit of leg-room for shallowing
|
||||||
|
// due to timezones, etc.
|
||||||
|
const std::string SHALLOW_DATE = trim(HLVER.date).empty() ? "" : execAndGet("LC_TIME=\"en_US.UTF-8\" date --date='" + HLVER.date + " - 1 weeks' '+%a %b %d %H:%M:%S %Y'");
|
||||||
|
|
||||||
|
if (m_bVerbose && bShallow)
|
||||||
|
progress.printMessageAbove(verboseString("will shallow since: {}", SHALLOW_DATE));
|
||||||
|
|
||||||
|
std::string ret = execAndGet(std::format("cd {} && git clone --recursive https://github.com/hyprwm/Hyprland hyprland-{}{}", getTempRoot(), USERNAME,
|
||||||
|
(bShallow ? " --shallow-since='" + SHALLOW_DATE + "'" : "")));
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(WORKINGDIR)) {
|
||||||
|
progress.printMessageAbove(failureString("Clone failed. Retrying without shallow."));
|
||||||
|
ret = execAndGet(std::format("cd {} && git clone --recursive https://github.com/hyprwm/hyprland hyprland-{}", getTempRoot(), USERNAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(WORKINGDIR + "/.git")) {
|
||||||
|
std::println(stderr, "\n{}", failureString("Could not clone the Hyprland repository. shell returned:\n{}", ret));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("Hyprland cloned"));
|
||||||
|
progress.m_iSteps = 2;
|
||||||
|
progress.m_szCurrentMessage = "Checking out sources";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
if (m_bVerbose)
|
||||||
|
progress.printMessageAbove(verboseString("will run: cd {} && git checkout {} 2>&1", WORKINGDIR, HLVER.hash));
|
||||||
|
|
||||||
|
ret = execAndGet("cd " + WORKINGDIR + " && git checkout " + HLVER.hash + " 2>&1");
|
||||||
|
|
||||||
|
if (ret.contains("fatal: unable to read tree")) {
|
||||||
|
std::println(stderr, "\n{}",
|
||||||
|
failureString("Could not checkout the running Hyprland commit. If you are on -git, try updating.\n"
|
||||||
|
"You can also try re-running hyprpm update with --no-shallow."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_bVerbose)
|
||||||
|
progress.printMessageAbove(verboseString("git returned (co): {}", ret));
|
||||||
|
|
||||||
|
ret = execAndGet("cd " + WORKINGDIR + " ; git rm subprojects/tracy ; git submodule update --init 2>&1 ; git reset --hard --recurse-submodules " + HLVER.hash);
|
||||||
|
|
||||||
|
if (m_bVerbose)
|
||||||
|
progress.printMessageAbove(verboseString("git returned (rs): {}", ret));
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("checked out to running ver"));
|
||||||
|
progress.m_iSteps = 3;
|
||||||
|
progress.m_szCurrentMessage = "Building Hyprland";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
progress.printMessageAbove(statusString("!", Colors::YELLOW, "configuring Hyprland"));
|
||||||
|
|
||||||
|
if (m_bVerbose)
|
||||||
|
progress.printMessageAbove(verboseString("setting PREFIX for cmake to {}", DataState::getHeadersPath()));
|
||||||
|
|
||||||
|
ret = execAndGet(std::format("cd {} && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=\"{}\" -S . -B ./build -G Ninja", WORKINGDIR,
|
||||||
|
DataState::getHeadersPath()));
|
||||||
|
if (m_bVerbose)
|
||||||
|
progress.printMessageAbove(verboseString("cmake returned: {}", ret));
|
||||||
|
|
||||||
|
if (ret.contains("CMake Error at")) {
|
||||||
|
// missing deps, let the user know.
|
||||||
|
std::string missing = ret.substr(ret.find("CMake Error at"));
|
||||||
|
missing = ret.substr(ret.find_first_of('\n') + 1);
|
||||||
|
missing = missing.substr(0, missing.find("-- Configuring incomplete"));
|
||||||
|
missing = missing.substr(0, missing.find_last_of('\n'));
|
||||||
|
|
||||||
|
std::println(stderr, "\n{}",
|
||||||
|
failureString("Could not configure the hyprland source, cmake complained:\n{}\n\n"
|
||||||
|
"This likely means that you are missing the above dependencies or they are out of date.",
|
||||||
|
missing));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("configured Hyprland"));
|
||||||
|
progress.m_iSteps = 4;
|
||||||
|
progress.m_szCurrentMessage = "Installing sources";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
const std::string& cmd =
|
||||||
|
std::format("sed -i -e \"s#PREFIX = /usr/local#PREFIX = {}#\" {}/Makefile && cd {} && make installheaders", DataState::getHeadersPath(), WORKINGDIR, WORKINGDIR);
|
||||||
|
if (m_bVerbose)
|
||||||
|
progress.printMessageAbove(verboseString("installation will run: {}", cmd));
|
||||||
|
|
||||||
|
ret = execAndGet(cmd);
|
||||||
|
|
||||||
|
if (m_bVerbose)
|
||||||
|
std::println("{}", verboseString("installer returned: {}", ret));
|
||||||
|
|
||||||
|
// remove build files
|
||||||
|
std::filesystem::remove_all(WORKINGDIR);
|
||||||
|
|
||||||
|
auto HEADERSVALID = headersValid();
|
||||||
|
if (HEADERSVALID == HEADERS_OK) {
|
||||||
|
progress.printMessageAbove(successString("installed headers"));
|
||||||
|
progress.m_iSteps = 5;
|
||||||
|
progress.m_szCurrentMessage = "Done!";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
std::print("\n");
|
||||||
|
} else {
|
||||||
|
progress.printMessageAbove(failureString("failed to install headers with error code {} ({})", (int)HEADERSVALID, headerErrorShort(HEADERSVALID)));
|
||||||
|
progress.m_iSteps = 5;
|
||||||
|
progress.m_szCurrentMessage = "Failed";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
std::print(stderr, "\n\n{}", headerError(HEADERSVALID));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
|
if (headersValid() != HEADERS_OK) {
|
||||||
|
std::println("{}", failureString("headers are not up-to-date, please run hyprpm update."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto REPOS = DataState::getAllRepositories();
|
||||||
|
|
||||||
|
if (REPOS.size() < 1) {
|
||||||
|
std::println("{}", failureString("No repos to update."));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto HLVER = getHyprlandVersion(false);
|
||||||
|
|
||||||
|
CProgressBar progress;
|
||||||
|
progress.m_iMaxSteps = REPOS.size() * 2 + 2;
|
||||||
|
progress.m_iSteps = 0;
|
||||||
|
progress.m_szCurrentMessage = "Updating repositories";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
const std::string USERNAME = getpwuid(getuid())->pw_name;
|
||||||
|
m_szWorkingPluginDirectory = getTempRoot() + USERNAME;
|
||||||
|
|
||||||
|
for (auto const& repo : REPOS) {
|
||||||
|
bool update = forceUpdateAll;
|
||||||
|
|
||||||
|
progress.m_iSteps++;
|
||||||
|
progress.m_szCurrentMessage = "Updating " + repo.name;
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
progress.printMessageAbove(infoString("checking for updates for {}", repo.name));
|
||||||
|
|
||||||
|
createSafeDirectory(m_szWorkingPluginDirectory);
|
||||||
|
|
||||||
|
progress.printMessageAbove(infoString("Cloning {}", repo.url));
|
||||||
|
|
||||||
|
std::string ret = execAndGet(std::format("cd {} && git clone --recursive {} {}", getTempRoot(), repo.url, USERNAME));
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
|
||||||
|
std::println("{}", failureString("could not clone repo: shell returned: {}", ret));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!repo.rev.empty()) {
|
||||||
|
progress.printMessageAbove(infoString("Plugin has revision set, resetting: {}", repo.rev));
|
||||||
|
|
||||||
|
std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " reset --hard --recurse-submodules " + repo.rev);
|
||||||
|
if (ret.compare(0, 6, "fatal:") == 0) {
|
||||||
|
std::println(stderr, "\n{}", failureString("could not check out revision {}: shell returned:\n{}", repo.rev, ret));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!update) {
|
||||||
|
// check if git has updates
|
||||||
|
std::string hash = execAndGet("cd " + m_szWorkingPluginDirectory + " && git rev-parse HEAD");
|
||||||
|
if (!hash.empty())
|
||||||
|
hash.pop_back();
|
||||||
|
|
||||||
|
update = update || hash != repo.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!update) {
|
||||||
|
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
||||||
|
progress.printMessageAbove(successString("repository {} is up-to-date.", repo.name));
|
||||||
|
progress.m_iSteps++;
|
||||||
|
progress.print();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need to update
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("repository {} has updates.", repo.name));
|
||||||
|
progress.printMessageAbove(infoString("Building {}", repo.name));
|
||||||
|
progress.m_iSteps++;
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
std::unique_ptr<CManifest> pManifest;
|
||||||
|
|
||||||
|
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
|
||||||
|
progress.printMessageAbove(successString("found hyprpm manifest"));
|
||||||
|
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
|
||||||
|
} else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
|
||||||
|
progress.printMessageAbove(successString("found hyprload manifest"));
|
||||||
|
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pManifest) {
|
||||||
|
std::println(stderr, "\n{}", failureString("The provided plugin repository does not have a valid manifest"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pManifest->m_bGood) {
|
||||||
|
std::println(stderr, "\n{}", failureString("The provided plugin repository has a corrupted manifest"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (repo.rev.empty() && !pManifest->m_sRepository.commitPins.empty()) {
|
||||||
|
// check commit pins unless a revision is specified
|
||||||
|
|
||||||
|
progress.printMessageAbove(infoString("Manifest has {} pins, checking", pManifest->m_sRepository.commitPins.size()));
|
||||||
|
|
||||||
|
for (auto const& [hl, plugin] : pManifest->m_sRepository.commitPins) {
|
||||||
|
if (hl != HLVER.hash)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("commit pin {} matched hl, resetting", plugin));
|
||||||
|
|
||||||
|
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& p : pManifest->m_vPlugins) {
|
||||||
|
std::string out;
|
||||||
|
|
||||||
|
if (p.since > HLVER.commits && HLVER.commits >= 1000 /* for shallow clones, we can't check this. 1000 is an arbitrary number I chose. */) {
|
||||||
|
progress.printMessageAbove(failureString("Not building {}: your Hyprland version is too old.\n", p.name));
|
||||||
|
p.failed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.printMessageAbove(infoString("Building {}", p.name));
|
||||||
|
|
||||||
|
for (auto const& bs : p.buildSteps) {
|
||||||
|
const std::string& cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
||||||
|
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_bVerbose)
|
||||||
|
std::println("{}", verboseString("shell returned: {}", out));
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
|
||||||
|
std::println(stderr,
|
||||||
|
"\n{}\n"
|
||||||
|
" This likely means that the plugin is either outdated, not yet available for your version, or broken.\n"
|
||||||
|
"If you are on -git, update first.\n"
|
||||||
|
"Try re-running with -v to see more verbose output.",
|
||||||
|
failureString("Plugin {} failed to build.", p.name));
|
||||||
|
p.failed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("built {} into {}", p.name, p.output));
|
||||||
|
}
|
||||||
|
|
||||||
|
// add repo toml to DataState
|
||||||
|
SPluginRepository newrepo = repo;
|
||||||
|
newrepo.plugins.clear();
|
||||||
|
execAndGet("cd " + m_szWorkingPluginDirectory +
|
||||||
|
" && git pull --recurse-submodules && git reset --hard --recurse-submodules"); // repo hash in the state.toml has to match head and not any pin
|
||||||
|
std::string repohash = execAndGet("cd " + m_szWorkingPluginDirectory + " && git rev-parse HEAD");
|
||||||
|
if (repohash.length() > 0)
|
||||||
|
repohash.pop_back();
|
||||||
|
newrepo.hash = repohash;
|
||||||
|
for (auto const& p : pManifest->m_vPlugins) {
|
||||||
|
const auto OLDPLUGINIT = std::find_if(repo.plugins.begin(), repo.plugins.end(), [&](const auto& other) { return other.name == p.name; });
|
||||||
|
newrepo.plugins.push_back(SPlugin{p.name, m_szWorkingPluginDirectory + "/" + p.output, OLDPLUGINIT != repo.plugins.end() ? OLDPLUGINIT->enabled : false});
|
||||||
|
}
|
||||||
|
DataState::removePluginRepo(newrepo.name);
|
||||||
|
DataState::addNewPluginRepo(newrepo);
|
||||||
|
|
||||||
|
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
||||||
|
|
||||||
|
progress.printMessageAbove(successString("updated {}", repo.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.m_iSteps++;
|
||||||
|
progress.m_szCurrentMessage = "Updating global state...";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
auto GLOBALSTATE = DataState::getGlobalState();
|
||||||
|
GLOBALSTATE.headersHashCompiled = HLVER.hash;
|
||||||
|
DataState::updateGlobalState(GLOBALSTATE);
|
||||||
|
|
||||||
|
progress.m_iSteps++;
|
||||||
|
progress.m_szCurrentMessage = "Done!";
|
||||||
|
progress.print();
|
||||||
|
|
||||||
|
std::print("\n");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::enablePlugin(const std::string& name) {
|
||||||
|
bool ret = DataState::setPluginEnabled(name, true);
|
||||||
|
if (ret)
|
||||||
|
std::println("{}", successString("Enabled {}", name));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::disablePlugin(const std::string& name) {
|
||||||
|
bool ret = DataState::setPluginEnabled(name, false);
|
||||||
|
if (ret)
|
||||||
|
std::println("{}", successString("Disabled {}", name));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||||
|
if (headersValid() != HEADERS_OK) {
|
||||||
|
std::println(stderr, "\n{}", failureString("headers are not up-to-date, please run hyprpm update."));
|
||||||
|
return LOADSTATE_HEADERS_OUTDATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto HOME = getenv("HOME");
|
||||||
|
const auto HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||||
|
if (!HOME || !HIS) {
|
||||||
|
std::println(stderr, "PluginManager: no $HOME or HIS");
|
||||||
|
return LOADSTATE_FAIL;
|
||||||
|
}
|
||||||
|
const auto HYPRPMPATH = DataState::getDataStatePath() + "/";
|
||||||
|
|
||||||
|
auto pluginLines = execAndGet("hyprctl plugins list | grep Plugin");
|
||||||
|
|
||||||
|
std::vector<std::string> loadedPlugins;
|
||||||
|
|
||||||
|
std::println("{}", successString("Ensuring plugin load state"));
|
||||||
|
|
||||||
|
// iterate line by line
|
||||||
|
while (!pluginLines.empty()) {
|
||||||
|
auto plLine = pluginLines.substr(0, pluginLines.find('\n'));
|
||||||
|
|
||||||
|
if (pluginLines.find('\n') != std::string::npos)
|
||||||
|
pluginLines = pluginLines.substr(pluginLines.find('\n') + 1);
|
||||||
|
else
|
||||||
|
pluginLines = "";
|
||||||
|
|
||||||
|
if (plLine.back() != ':')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
plLine = plLine.substr(7);
|
||||||
|
plLine = plLine.substr(0, plLine.find(" by "));
|
||||||
|
|
||||||
|
loadedPlugins.push_back(plLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get state
|
||||||
|
const auto REPOS = DataState::getAllRepositories();
|
||||||
|
|
||||||
|
auto enabled = [REPOS](const std::string& plugin) -> bool {
|
||||||
|
for (auto const& r : REPOS) {
|
||||||
|
for (auto const& p : r.plugins) {
|
||||||
|
if (p.name == plugin && p.enabled)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto repoForName = [REPOS](const std::string& name) -> std::string {
|
||||||
|
for (auto const& r : REPOS) {
|
||||||
|
for (auto const& p : r.plugins) {
|
||||||
|
if (p.name == name)
|
||||||
|
return r.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
// if any of the loadUnloadPlugin calls return false, this is true
|
||||||
|
// bcs that means the header version doesn't match the running version
|
||||||
|
// (and Hyprland needs to restart)
|
||||||
|
bool hyprlandVersionMismatch = false;
|
||||||
|
|
||||||
|
// unload disabled plugins
|
||||||
|
for (auto const& p : loadedPlugins) {
|
||||||
|
if (!enabled(p)) {
|
||||||
|
// unload
|
||||||
|
if (!loadUnloadPlugin(HYPRPMPATH + repoForName(p) + "/" + p + ".so", false)) {
|
||||||
|
std::println("{}", infoString("{} will be unloaded after restarting Hyprland", p));
|
||||||
|
hyprlandVersionMismatch = true;
|
||||||
|
} else
|
||||||
|
std::println("{}", successString("Unloaded {}", p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load enabled plugins
|
||||||
|
for (auto const& r : REPOS) {
|
||||||
|
for (auto const& p : r.plugins) {
|
||||||
|
if (!p.enabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (std::find_if(loadedPlugins.begin(), loadedPlugins.end(), [&](const auto& other) { return other == p.name; }) != loadedPlugins.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!loadUnloadPlugin(HYPRPMPATH + repoForName(p.name) + "/" + p.filename, true)) {
|
||||||
|
std::println("{}", infoString("{} will be loaded after restarting Hyprland", p.name));
|
||||||
|
hyprlandVersionMismatch = true;
|
||||||
|
} else
|
||||||
|
std::println("{}", successString("Loaded {}", p.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::println("{}", successString("Plugin load state ensured"));
|
||||||
|
|
||||||
|
return hyprlandVersionMismatch ? LOADSTATE_HYPRLAND_UPDATED : LOADSTATE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::loadUnloadPlugin(const std::string& path, bool load) {
|
||||||
|
auto state = DataState::getGlobalState();
|
||||||
|
auto HLVER = getHyprlandVersion(true);
|
||||||
|
|
||||||
|
if (state.headersHashCompiled != HLVER.hash) {
|
||||||
|
std::println("{}", infoString("Running Hyprland version differs from plugin state, please restart Hyprland."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (load)
|
||||||
|
execAndGet("hyprctl plugin load " + path);
|
||||||
|
else
|
||||||
|
execAndGet("hyprctl plugin unload " + path);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPluginManager::listAllPlugins() {
|
||||||
|
const auto REPOS = DataState::getAllRepositories();
|
||||||
|
|
||||||
|
for (auto const& r : REPOS) {
|
||||||
|
std::println("{}", infoString("Repository {}:", r.name));
|
||||||
|
|
||||||
|
for (auto const& p : r.plugins) {
|
||||||
|
std::println(" │ Plugin {}", p.name);
|
||||||
|
|
||||||
|
if (!p.failed)
|
||||||
|
std::println(" └─ enabled: {}", (p.enabled ? std::string{Colors::GREEN} + "true" : std::string{Colors::RED} + "false"));
|
||||||
|
else
|
||||||
|
std::println(" └─ enabled: {}Plugin failed to build", Colors::RED);
|
||||||
|
|
||||||
|
std::println("{}", Colors::RESET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPluginManager::notify(const eNotifyIcons icon, uint32_t color, int durationMs, const std::string& message) {
|
||||||
|
execAndGet("hyprctl notify " + std::to_string((int)icon) + " " + std::to_string(durationMs) + " " + std::to_string(color) + " " + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CPluginManager::headerError(const eHeadersErrors err) {
|
||||||
|
switch (err) {
|
||||||
|
case HEADERS_CORRUPTED: return failureString("Headers corrupted. Please run hyprpm update to fix those.\n");
|
||||||
|
case HEADERS_MISMATCHED: return failureString("Headers version mismatch. Please run hyprpm update to fix those.\n");
|
||||||
|
case HEADERS_NOT_HYPRLAND: return failureString("It doesn't seem you are running on hyprland.\n");
|
||||||
|
case HEADERS_MISSING: return failureString("Headers missing. Please run hyprpm update to fix those.\n");
|
||||||
|
case HEADERS_DUPLICATED: {
|
||||||
|
return failureString("Headers duplicated!!! This is a very bad sign.\n"
|
||||||
|
"This could be due to e.g. installing hyprland manually while a system package of hyprland is also installed.\n"
|
||||||
|
"If the above doesn't apply, check your /usr/include and /usr/local/include directories\n and remove all the hyprland headers.\n");
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return failureString("Unknown header error. Please run hyprpm update to fix those.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CPluginManager::headerErrorShort(const eHeadersErrors err) {
|
||||||
|
switch (err) {
|
||||||
|
case HEADERS_CORRUPTED: return "Headers corrupted";
|
||||||
|
case HEADERS_MISMATCHED: return "Headers version mismatched";
|
||||||
|
case HEADERS_NOT_HYPRLAND: return "Not running on Hyprland";
|
||||||
|
case HEADERS_MISSING: return "Headers missing";
|
||||||
|
case HEADERS_DUPLICATED: return "Headers duplicated";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return "?";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPluginManager::hasDeps() {
|
||||||
|
std::vector<std::string> deps = {"meson", "cpio", "cmake", "pkg-config"};
|
||||||
|
for (auto const& d : deps) {
|
||||||
|
if (!execAndGet("command -v " + d).contains("/"))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
76
hyprpm/src/core/PluginManager.hpp
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
enum eHeadersErrors {
|
||||||
|
HEADERS_OK = 0,
|
||||||
|
HEADERS_NOT_HYPRLAND,
|
||||||
|
HEADERS_MISSING,
|
||||||
|
HEADERS_CORRUPTED,
|
||||||
|
HEADERS_MISMATCHED,
|
||||||
|
HEADERS_DUPLICATED
|
||||||
|
};
|
||||||
|
|
||||||
|
enum eNotifyIcons {
|
||||||
|
ICON_WARNING = 0,
|
||||||
|
ICON_INFO,
|
||||||
|
ICON_HINT,
|
||||||
|
ICON_ERROR,
|
||||||
|
ICON_CONFUSED,
|
||||||
|
ICON_OK,
|
||||||
|
ICON_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ePluginLoadStateReturn {
|
||||||
|
LOADSTATE_OK = 0,
|
||||||
|
LOADSTATE_FAIL,
|
||||||
|
LOADSTATE_PARTIAL_FAIL,
|
||||||
|
LOADSTATE_HEADERS_OUTDATED,
|
||||||
|
LOADSTATE_HYPRLAND_UPDATED
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHyprlandVersion {
|
||||||
|
std::string branch;
|
||||||
|
std::string hash;
|
||||||
|
std::string date;
|
||||||
|
int commits = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPluginManager {
|
||||||
|
public:
|
||||||
|
bool addNewPluginRepo(const std::string& url, const std::string& rev);
|
||||||
|
bool removePluginRepo(const std::string& urlOrName);
|
||||||
|
|
||||||
|
eHeadersErrors headersValid();
|
||||||
|
bool updateHeaders(bool force = false);
|
||||||
|
bool updatePlugins(bool forceUpdateAll);
|
||||||
|
|
||||||
|
void listAllPlugins();
|
||||||
|
|
||||||
|
bool enablePlugin(const std::string& name);
|
||||||
|
bool disablePlugin(const std::string& name);
|
||||||
|
ePluginLoadStateReturn ensurePluginsLoadState();
|
||||||
|
|
||||||
|
bool loadUnloadPlugin(const std::string& path, bool load);
|
||||||
|
SHyprlandVersion getHyprlandVersion(bool running = true);
|
||||||
|
|
||||||
|
void notify(const eNotifyIcons icon, uint32_t color, int durationMs, const std::string& message);
|
||||||
|
|
||||||
|
bool hasDeps();
|
||||||
|
|
||||||
|
bool m_bVerbose = false;
|
||||||
|
bool m_bNoShallow = false;
|
||||||
|
|
||||||
|
// will delete recursively if exists!!
|
||||||
|
bool createSafeDirectory(const std::string& path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string headerError(const eHeadersErrors err);
|
||||||
|
std::string headerErrorShort(const eHeadersErrors err);
|
||||||
|
|
||||||
|
std::string m_szWorkingPluginDirectory;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::unique_ptr<CPluginManager> g_pPluginManager;
|
||||||
11
hyprpm/src/helpers/Colors.hpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Colors {
|
||||||
|
constexpr const char* RED = "\x1b[31m";
|
||||||
|
constexpr const char* GREEN = "\x1b[32m";
|
||||||
|
constexpr const char* YELLOW = "\x1b[33m";
|
||||||
|
constexpr const char* BLUE = "\x1b[34m";
|
||||||
|
constexpr const char* MAGENTA = "\x1b[35m";
|
||||||
|
constexpr const char* CYAN = "\x1b[36m";
|
||||||
|
constexpr const char* RESET = "\x1b[0m";
|
||||||
|
};
|
||||||
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...);
|
||||||
|
}
|
||||||
180
hyprpm/src/main.cpp
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
#include "helpers/Colors.hpp"
|
||||||
|
#include "helpers/StringUtils.hpp"
|
||||||
|
#include "core/PluginManager.hpp"
|
||||||
|
#include "core/DataState.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <print>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
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.
|
||||||
|
┣ remove [url/name] → Remove an installed plugin repository
|
||||||
|
┣ enable [name] → Enable a plugin
|
||||||
|
┣ disable [name] → Disable a plugin
|
||||||
|
┣ update → Check and update all plugins if needed
|
||||||
|
┣ reload → Reload hyprpm state. Ensure all enabled plugins are loaded.
|
||||||
|
┣ list → List all installed plugins
|
||||||
|
┃
|
||||||
|
┣ Flags:
|
||||||
|
┃
|
||||||
|
┣ --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)
|
||||||
|
┣ --no-shallow | -s → Disable shallow cloning of Hyprland sources
|
||||||
|
┗
|
||||||
|
)#";
|
||||||
|
|
||||||
|
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::println(stderr, "{}", HELP);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> command;
|
||||||
|
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::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::println("{}", statusString("!", Colors::RED, "Using --force, I hope you know what you are doing."));
|
||||||
|
} else {
|
||||||
|
std::println(stderr, "Unrecognized option {}", ARGS[i]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
command.push_back(ARGS[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.empty()) {
|
||||||
|
std::println(stderr, "{}", HELP);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pPluginManager = std::make_unique<CPluginManager>();
|
||||||
|
g_pPluginManager->m_bVerbose = verbose;
|
||||||
|
g_pPluginManager->m_bNoShallow = noShallow;
|
||||||
|
|
||||||
|
if (command[0] == "add") {
|
||||||
|
if (command.size() < 2) {
|
||||||
|
std::println(stderr, "{}", failureString("Not enough args for add."));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string rev = "";
|
||||||
|
if (command.size() >= 3) {
|
||||||
|
rev = command[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1;
|
||||||
|
} else if (command[0] == "remove") {
|
||||||
|
if (ARGS.size() < 2) {
|
||||||
|
std::println(stderr, "{}", failureString("Not enough args for remove."));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_pPluginManager->removePluginRepo(command[1]) ? 0 : 1;
|
||||||
|
} else if (command[0] == "update") {
|
||||||
|
bool headersValid = g_pPluginManager->headersValid() == HEADERS_OK;
|
||||||
|
bool headers = g_pPluginManager->updateHeaders(force);
|
||||||
|
if (headers) {
|
||||||
|
const auto HLVER = g_pPluginManager->getHyprlandVersion(false);
|
||||||
|
auto GLOBALSTATE = DataState::getGlobalState();
|
||||||
|
const auto COMPILEDOUTDATED = HLVER.hash != GLOBALSTATE.headersHashCompiled;
|
||||||
|
|
||||||
|
bool ret1 = g_pPluginManager->updatePlugins(!headersValid || force || COMPILEDOUTDATED);
|
||||||
|
|
||||||
|
if (!ret1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
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::println(stderr, "{}", failureString("Not enough args for enable."));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_pPluginManager->enablePlugin(command[1])) {
|
||||||
|
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::println(stderr, "{}", failureString("Not enough args for disable."));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_pPluginManager->disablePlugin(command[1])) {
|
||||||
|
std::println(stderr, "{}", failureString("Couldn't disable plugin (missing?)"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ret = g_pPluginManager->ensurePluginsLoadState();
|
||||||
|
if (ret != LOADSTATE_OK)
|
||||||
|
return 1;
|
||||||
|
} else if (command[0] == "reload") {
|
||||||
|
auto ret = g_pPluginManager->ensurePluginsLoadState();
|
||||||
|
|
||||||
|
if (ret != LOADSTATE_OK && notify) {
|
||||||
|
switch (ret) {
|
||||||
|
case LOADSTATE_FAIL:
|
||||||
|
case LOADSTATE_PARTIAL_FAIL: g_pPluginManager->notify(ICON_ERROR, 0, 10000, "[hyprpm] Failed to load plugins"); break;
|
||||||
|
case LOADSTATE_HEADERS_OUTDATED:
|
||||||
|
g_pPluginManager->notify(ICON_ERROR, 0, 10000, "[hyprpm] Failed to load plugins: Outdated headers. Please run hyprpm update manually.");
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
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::println(stderr, "{}", HELP);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
31
hyprpm/src/meson.build
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
globber = run_command('sh', '-c', 'find . -name "*.cpp" | sort', check: true)
|
||||||
|
src = globber.stdout().strip().split('\n')
|
||||||
|
|
||||||
|
executable(
|
||||||
|
'hyprpm',
|
||||||
|
src,
|
||||||
|
dependencies: [
|
||||||
|
dependency('hyprutils', version: '>= 0.1.1'),
|
||||||
|
dependency('threads'),
|
||||||
|
dependency('tomlplusplus'),
|
||||||
|
],
|
||||||
|
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',
|
||||||
|
)
|
||||||
82
hyprpm/src/progress/CProgressBar.cpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#include "CProgressBar.hpp"
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
#include <print>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "../helpers/Colors.hpp"
|
||||||
|
|
||||||
|
void CProgressBar::printMessageAbove(const std::string& msg) {
|
||||||
|
struct winsize w;
|
||||||
|
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::println("\r{}\r{}", spaces, msg);
|
||||||
|
print();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CProgressBar::print() {
|
||||||
|
struct winsize w;
|
||||||
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
|
||||||
|
if (m_bFirstPrint)
|
||||||
|
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::print("\r{}\r", spaces);
|
||||||
|
|
||||||
|
std::string message = "";
|
||||||
|
|
||||||
|
float percentDone = 0;
|
||||||
|
if (m_fPercentage >= 0)
|
||||||
|
percentDone = m_fPercentage;
|
||||||
|
else
|
||||||
|
percentDone = (float)m_iSteps / (float)m_iMaxSteps;
|
||||||
|
|
||||||
|
const auto BARWIDTH = std::clamp(w.ws_col - static_cast<unsigned long>(m_szCurrentMessage.length()) - 2, 0UL, 50UL);
|
||||||
|
|
||||||
|
// draw bar
|
||||||
|
message += std::string{" "} + Colors::GREEN;
|
||||||
|
size_t i = 0;
|
||||||
|
for (; i < std::floor(percentDone * BARWIDTH); ++i) {
|
||||||
|
message += "━";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < BARWIDTH) {
|
||||||
|
i++;
|
||||||
|
|
||||||
|
message += std::string{"╍"} + Colors::RESET;
|
||||||
|
|
||||||
|
for (; i < BARWIDTH; ++i) {
|
||||||
|
message += "━";
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
message += Colors::RESET;
|
||||||
|
|
||||||
|
// draw progress
|
||||||
|
if (m_fPercentage >= 0)
|
||||||
|
message += " " + std::format("{}%", static_cast<int>(percentDone * 100.0)) + " ";
|
||||||
|
else
|
||||||
|
message += " " + std::format("{} / {}", m_iSteps, m_iMaxSteps) + " ";
|
||||||
|
|
||||||
|
// draw message
|
||||||
|
std::print("{} {}", message, m_szCurrentMessage);
|
||||||
|
|
||||||
|
std::fflush(stdout);
|
||||||
|
}
|
||||||
17
hyprpm/src/progress/CProgressBar.hpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class CProgressBar {
|
||||||
|
public:
|
||||||
|
void print();
|
||||||
|
void printMessageAbove(const std::string& msg);
|
||||||
|
|
||||||
|
std::string m_szCurrentMessage = "";
|
||||||
|
size_t m_iSteps = 0;
|
||||||
|
size_t m_iMaxSteps = 0;
|
||||||
|
float m_fPercentage = -1; // if != -1, use percentage
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_bFirstPrint = true;
|
||||||
|
};
|
||||||
95
meson.build
@@ -1,64 +1,75 @@
|
|||||||
project('Hyprland', 'cpp', 'c',
|
project(
|
||||||
version : run_command('jq', '-r', '.version', join_paths(meson.source_root(), 'props.json'), check: true).stdout().strip(),
|
'Hyprland',
|
||||||
|
'cpp',
|
||||||
|
'c',
|
||||||
|
version: run_command('cat', join_paths(meson.project_source_root(), 'VERSION'), check: true).stdout().strip(),
|
||||||
default_options: [
|
default_options: [
|
||||||
'warning_level=2',
|
'warning_level=2',
|
||||||
'default_library=static',
|
'default_library=static',
|
||||||
'optimization=3',
|
'optimization=3',
|
||||||
'buildtype=release',
|
'buildtype=release',
|
||||||
'debug=false'
|
'debug=false',
|
||||||
# 'cpp_std=c++23' # not yet supported by meson, as of version 0.63.0
|
'cpp_std=c++26',
|
||||||
])
|
],
|
||||||
|
)
|
||||||
# clang v14.0.6 uses C++2b instead of C++23, so we've gotta account for that
|
|
||||||
# replace the following with a project default option once meson gets support for C++23
|
|
||||||
cpp_compiler = meson.get_compiler('cpp')
|
|
||||||
if cpp_compiler.has_argument('-std=c++23')
|
|
||||||
add_global_arguments('-std=c++23', language: 'cpp')
|
|
||||||
elif cpp_compiler.has_argument('-std=c++2b')
|
|
||||||
add_global_arguments('-std=c++2b', language: 'cpp')
|
|
||||||
else
|
|
||||||
error('Could not configure current C++ compiler (' + cpp_compiler.get_id() + ' ' + cpp_compiler.version() + ') with required C++ standard (C++23)')
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
datarootdir = '-DDATAROOTDIR="' + get_option('prefix') / get_option('datadir') + '"'
|
||||||
add_project_arguments(
|
add_project_arguments(
|
||||||
[
|
[
|
||||||
'-Wno-unused-parameter',
|
'-Wno-unused-parameter',
|
||||||
'-Wno-unused-value',
|
'-Wno-unused-value',
|
||||||
'-Wno-missing-field-initializers',
|
'-Wno-missing-field-initializers',
|
||||||
'-Wno-narrowing',
|
'-Wno-narrowing',
|
||||||
|
'-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')
|
if cpp_compiler.check_header('execinfo.h')
|
||||||
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
|
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
wlroots = subproject('wlroots', default_options: ['examples=false', 'renderers=gles2'])
|
aquamarine = dependency('aquamarine', version: '>=0.4.5')
|
||||||
have_xwlr = wlroots.get_variable('features').get('xwayland')
|
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_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'))
|
||||||
|
xcb_icccm_dep = dependency('xcb-icccm', required: get_option('xwayland'))
|
||||||
|
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'))
|
||||||
|
|
||||||
cmake = import('cmake')
|
gio_dep = dependency('gio-2.0', required: true)
|
||||||
udis = cmake.subproject('udis86')
|
|
||||||
udis86 = udis.dependency('libudis86')
|
|
||||||
|
|
||||||
if get_option('xwayland').enabled() and not have_xwlr
|
if not xcb_dep.found()
|
||||||
error('Cannot enable Xwayland in Hyprland: wlroots has been built without Xwayland support')
|
|
||||||
endif
|
|
||||||
have_xwayland = xcb_dep.found() and have_xwlr
|
|
||||||
|
|
||||||
if not have_xwayland
|
|
||||||
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
|
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
backtrace_dep = cpp_compiler.find_library('execinfo', required: false)
|
backtrace_dep = cpp_compiler.find_library('execinfo', required: false)
|
||||||
systemd_dep = dependency('libsystemd', required: get_option('systemd'))
|
epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs
|
||||||
|
|
||||||
if get_option('systemd').enabled()
|
re2 = dependency('re2', required: true)
|
||||||
if systemd_dep.found()
|
|
||||||
|
# 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')
|
add_project_arguments('-DUSES_SYSTEMD', language: 'cpp')
|
||||||
else
|
subdir('systemd')
|
||||||
error('Cannot enable systemd in Hyprland: libsystemd was not found')
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if get_option('legacy_renderer').enabled()
|
if get_option('legacy_renderer').enabled()
|
||||||
@@ -69,21 +80,33 @@ if get_option('buildtype') == 'debug'
|
|||||||
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
|
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
version_h = run_command('sh', '-c', 'scripts/generateVersion.sh')
|
# 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)
|
globber = run_command('find', 'src', '-name', '*.h*', check: true)
|
||||||
headers = globber.stdout().strip().split('\n')
|
headers = globber.stdout().strip().split('\n')
|
||||||
foreach file : headers
|
foreach file : headers
|
||||||
install_headers(file, subdir: 'hyprland', preserve_path: true)
|
install_headers(file, subdir: 'hyprland', preserve_path: true)
|
||||||
endforeach
|
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('protocols')
|
||||||
subdir('src')
|
subdir('src')
|
||||||
subdir('hyprctl')
|
subdir('hyprctl')
|
||||||
|
subdir('hyprpm/src')
|
||||||
subdir('assets')
|
subdir('assets')
|
||||||
subdir('example')
|
subdir('example')
|
||||||
subdir('docs')
|
subdir('docs')
|
||||||
|
|
||||||
|
# Generate hyprland.pc
|
||||||
pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig')
|
pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig')
|
||||||
|
|
||||||
import('pkgconfig').generate(
|
import('pkgconfig').generate(
|
||||||
@@ -92,5 +115,5 @@ import('pkgconfig').generate(
|
|||||||
url: 'https://github.com/hyprwm/Hyprland',
|
url: 'https://github.com/hyprwm/Hyprland',
|
||||||
description: 'Hyprland header files',
|
description: 'Hyprland header files',
|
||||||
install_dir: pkg_install_dir,
|
install_dir: pkg_install_dir,
|
||||||
subdirs: ['', 'hyprland/protocols', 'hyprland/wlroots'],
|
subdirs: ['', 'hyprland/protocols', 'hyprland'],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
||||||
option('systemd', type: 'feature', value: 'auto', description: 'Enable systemd integration')
|
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('legacy_renderer', type: 'feature', value: 'disabled', description: 'Enable legacy renderer')
|
||||||
|
option('tracy_enable', type: 'boolean', value: false , description: 'Enable profiling')
|
||||||
|
|||||||
177
nix/default.nix
@@ -1,63 +1,108 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
stdenv,
|
stdenv,
|
||||||
|
stdenvAdapters,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
|
pkgconf,
|
||||||
makeWrapper,
|
makeWrapper,
|
||||||
meson,
|
meson,
|
||||||
ninja,
|
ninja,
|
||||||
|
aquamarine,
|
||||||
binutils,
|
binutils,
|
||||||
cairo,
|
cairo,
|
||||||
git,
|
git,
|
||||||
|
hyprcursor,
|
||||||
|
hyprgraphics,
|
||||||
hyprland-protocols,
|
hyprland-protocols,
|
||||||
jq,
|
hyprland-qtutils,
|
||||||
|
hyprlang,
|
||||||
|
hyprutils,
|
||||||
|
hyprwayland-scanner,
|
||||||
|
libGL,
|
||||||
libdrm,
|
libdrm,
|
||||||
|
libexecinfo,
|
||||||
libinput,
|
libinput,
|
||||||
libxcb,
|
|
||||||
libxkbcommon,
|
libxkbcommon,
|
||||||
|
libuuid,
|
||||||
mesa,
|
mesa,
|
||||||
pango,
|
pango,
|
||||||
pciutils,
|
pciutils,
|
||||||
|
re2,
|
||||||
systemd,
|
systemd,
|
||||||
udis86,
|
tomlplusplus,
|
||||||
|
udis86-hyprland,
|
||||||
wayland,
|
wayland,
|
||||||
wayland-protocols,
|
wayland-protocols,
|
||||||
wayland-scanner,
|
wayland-scanner,
|
||||||
wlroots,
|
xorg,
|
||||||
xcbutilwm,
|
|
||||||
xwayland,
|
xwayland,
|
||||||
debug ? false,
|
debug ? false,
|
||||||
enableNvidiaPatches ? false,
|
|
||||||
enableXWayland ? true,
|
enableXWayland ? true,
|
||||||
legacyRenderer ? false,
|
legacyRenderer ? false,
|
||||||
withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd,
|
withSystemd ? lib.meta.availableOn stdenv.hostPlatform systemd,
|
||||||
wrapRuntimeDeps ? true,
|
wrapRuntimeDeps ? true,
|
||||||
version ? "git",
|
version ? "git",
|
||||||
commit,
|
commit,
|
||||||
|
revCount,
|
||||||
|
date,
|
||||||
# deprecated flags
|
# deprecated flags
|
||||||
|
enableNvidiaPatches ? false,
|
||||||
nvidiaPatches ? false,
|
nvidiaPatches ? false,
|
||||||
hidpiXWayland ? false,
|
hidpiXWayland ? false,
|
||||||
}:
|
}: let
|
||||||
assert lib.assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been renamed `enableNvidiaPatches`";
|
inherit (builtins) baseNameOf foldl';
|
||||||
assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland";
|
inherit (lib.asserts) assertMsg;
|
||||||
stdenv.mkDerivation {
|
inherit (lib.attrsets) mapAttrsToList;
|
||||||
pname = "hyprland${lib.optionalString enableNvidiaPatches "-nvidia"}${lib.optionalString debug "-debug"}";
|
inherit (lib.lists) flatten concatLists optional optionals;
|
||||||
|
inherit (lib.sources) cleanSourceWith cleanSource;
|
||||||
|
inherit (lib.strings) hasSuffix makeBinPath optionalString mesonBool mesonEnable;
|
||||||
|
|
||||||
|
adapters = flatten [
|
||||||
|
stdenvAdapters.useMoldLinker
|
||||||
|
(lib.optional debug stdenvAdapters.keepDebugInfo)
|
||||||
|
];
|
||||||
|
|
||||||
|
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;
|
inherit version;
|
||||||
|
|
||||||
src = lib.cleanSourceWith {
|
src = cleanSourceWith {
|
||||||
filter = name: type: let
|
filter = name: _type: let
|
||||||
baseName = baseNameOf (toString name);
|
baseName = baseNameOf (toString name);
|
||||||
in
|
in
|
||||||
! (lib.hasSuffix ".nix" baseName);
|
! (hasSuffix ".nix" baseName);
|
||||||
src = lib.cleanSource ../.;
|
src = cleanSource ../.;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
# Fix hardcoded paths to /usr installation
|
||||||
|
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
||||||
|
|
||||||
|
# Remove extra @PREFIX@ to fix pkg-config paths
|
||||||
|
sed -i "s#@PREFIX@/##g" hyprland.pc.in
|
||||||
|
'';
|
||||||
|
|
||||||
|
COMMITS = revCount;
|
||||||
|
DATE = date;
|
||||||
|
DIRTY = optionalString (commit == "") "dirty";
|
||||||
|
HASH = commit;
|
||||||
|
TAG = "v${builtins.readFile "${finalAttrs.src}/VERSION"}";
|
||||||
|
|
||||||
|
depsBuildBuild = [
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
jq
|
hyprwayland-scanner
|
||||||
|
makeWrapper
|
||||||
meson
|
meson
|
||||||
ninja
|
ninja
|
||||||
pkg-config
|
pkg-config
|
||||||
makeWrapper
|
|
||||||
wayland-scanner
|
|
||||||
];
|
];
|
||||||
|
|
||||||
outputs = [
|
outputs = [
|
||||||
@@ -66,76 +111,80 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov
|
|||||||
"dev"
|
"dev"
|
||||||
];
|
];
|
||||||
|
|
||||||
buildInputs =
|
buildInputs = concatLists [
|
||||||
[
|
[
|
||||||
git
|
aquamarine
|
||||||
cairo
|
cairo
|
||||||
|
git
|
||||||
|
hyprcursor
|
||||||
|
hyprgraphics
|
||||||
hyprland-protocols
|
hyprland-protocols
|
||||||
|
hyprlang
|
||||||
|
hyprutils
|
||||||
libdrm
|
libdrm
|
||||||
|
libGL
|
||||||
libinput
|
libinput
|
||||||
|
libuuid
|
||||||
libxkbcommon
|
libxkbcommon
|
||||||
mesa
|
mesa
|
||||||
pango
|
pango
|
||||||
udis86
|
pciutils
|
||||||
|
re2
|
||||||
|
tomlplusplus
|
||||||
|
udis86-hyprland
|
||||||
wayland
|
wayland
|
||||||
wayland-protocols
|
wayland-protocols
|
||||||
pciutils
|
wayland-scanner
|
||||||
(wlroots.override {inherit enableNvidiaPatches;})
|
xorg.libXcursor
|
||||||
]
|
]
|
||||||
++ lib.optionals enableXWayland [libxcb xcbutilwm xwayland]
|
(optionals customStdenv.hostPlatform.isMusl [libexecinfo])
|
||||||
++ lib.optionals withSystemd [systemd];
|
(optionals enableXWayland [
|
||||||
|
xorg.libxcb
|
||||||
|
xorg.libXdmcp
|
||||||
|
xorg.xcbutilerrors
|
||||||
|
xorg.xcbutilrenderutil
|
||||||
|
xorg.xcbutilwm
|
||||||
|
xwayland
|
||||||
|
])
|
||||||
|
(optional withSystemd systemd)
|
||||||
|
];
|
||||||
|
|
||||||
mesonBuildType =
|
mesonBuildType =
|
||||||
if debug
|
if debug
|
||||||
then "debug"
|
then "debugoptimized"
|
||||||
else "release";
|
else "release";
|
||||||
|
|
||||||
mesonAutoFeatures = "disabled";
|
mesonFlags = flatten [
|
||||||
|
(mapAttrsToList mesonEnable {
|
||||||
mesonFlags = builtins.concatLists [
|
"xwayland" = enableXWayland;
|
||||||
(lib.optional enableXWayland "-Dxwayland=enabled")
|
"legacy_renderer" = legacyRenderer;
|
||||||
(lib.optional legacyRenderer "-Dlegacy_renderer=enabled")
|
"uwsm" = false;
|
||||||
(lib.optional withSystemd "-Dsystemd=enabled")
|
})
|
||||||
|
(mapAttrsToList mesonBool {
|
||||||
|
"b_pch" = false;
|
||||||
|
"tracy_enable" = false;
|
||||||
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
patches = [
|
|
||||||
# make meson use the provided wlroots instead of the git submodule
|
|
||||||
./patches/meson-build.patch
|
|
||||||
];
|
|
||||||
|
|
||||||
postPatch = ''
|
|
||||||
# Fix hardcoded paths to /usr installation
|
|
||||||
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
|
||||||
|
|
||||||
# Generate version.h
|
|
||||||
cp src/version.h.in src/version.h
|
|
||||||
substituteInPlace src/version.h \
|
|
||||||
--replace "@HASH@" '${commit}' \
|
|
||||||
--replace "@BRANCH@" "" \
|
|
||||||
--replace "@MESSAGE@" "" \
|
|
||||||
--replace "@TAG@" "" \
|
|
||||||
--replace "@DIRTY@" '${
|
|
||||||
if commit == ""
|
|
||||||
then "dirty"
|
|
||||||
else ""
|
|
||||||
}'
|
|
||||||
'';
|
|
||||||
|
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
ln -s ${wlroots}/include/wlr $dev/include/hyprland/wlroots
|
${optionalString wrapRuntimeDeps ''
|
||||||
${lib.optionalString wrapRuntimeDeps ''
|
|
||||||
wrapProgram $out/bin/Hyprland \
|
wrapProgram $out/bin/Hyprland \
|
||||||
--suffix PATH : ${lib.makeBinPath [binutils pciutils]}
|
--suffix PATH : ${makeBinPath [
|
||||||
|
binutils
|
||||||
|
hyprland-qtutils
|
||||||
|
pciutils
|
||||||
|
pkgconf
|
||||||
|
]}
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
passthru.providedSessions = ["hyprland"];
|
passthru.providedSessions = ["hyprland"];
|
||||||
|
|
||||||
meta = with lib; {
|
meta = {
|
||||||
homepage = "https://github.com/vaxerski/Hyprland";
|
homepage = "https://github.com/hyprwm/Hyprland";
|
||||||
description = "A dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
|
description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
|
||||||
license = licenses.bsd3;
|
license = lib.licenses.bsd3;
|
||||||
platforms = platforms.linux;
|
platforms = lib.platforms.linux;
|
||||||
mainProgram = "Hyprland";
|
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
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -4,174 +4,11 @@ self: {
|
|||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
cfg = config.wayland.windowManager.hyprland;
|
inherit (pkgs.stdenv.hostPlatform) system;
|
||||||
defaultHyprlandPackage = self.packages.${pkgs.stdenv.hostPlatform.system}.default.override {
|
|
||||||
enableXWayland = cfg.xwayland.enable;
|
package = self.packages.${system}.default;
|
||||||
inherit (cfg) enableNvidiaPatches;
|
|
||||||
};
|
|
||||||
in {
|
in {
|
||||||
disabledModules = ["services/window-managers/hyprland.nix"];
|
config = {
|
||||||
|
wayland.windowManager.hyprland.package = lib.mkDefault package;
|
||||||
meta.maintainers = [lib.maintainers.fufexan];
|
|
||||||
|
|
||||||
options.wayland.windowManager.hyprland = {
|
|
||||||
enable =
|
|
||||||
lib.mkEnableOption null
|
|
||||||
// {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Whether to enable Hyprland, the dynamic tiling Wayland compositor
|
|
||||||
that doesn't sacrifice on its looks.
|
|
||||||
|
|
||||||
You can manually launch Hyprland by executing {command}`Hyprland` on
|
|
||||||
a TTY.
|
|
||||||
|
|
||||||
See <https://wiki.hyprland.org> for more information.
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
package = lib.mkOption {
|
|
||||||
type = with lib.types; nullOr package;
|
|
||||||
default = defaultHyprlandPackage;
|
|
||||||
defaultText = lib.literalExpression ''
|
|
||||||
hyprland.packages.''${pkgs.stdenv.hostPlatform.system}.default.override {
|
|
||||||
enableXWayland = config.wayland.windowManager.hyprland.xwayland.enable;
|
|
||||||
inherit (config.wayland.windowManager.hyprland) enableNvidiaPatches;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Hyprland package to use. Will override the 'xwayland' and
|
|
||||||
'enableNvidiaPatches' options.
|
|
||||||
|
|
||||||
Defaults to the one provided by the flake. Set it to
|
|
||||||
{package}`pkgs.hyprland` to use the one provided by nixpkgs or
|
|
||||||
if you have an overlay.
|
|
||||||
|
|
||||||
Set to null to not add any Hyprland package to your path. This should
|
|
||||||
be done if you want to use the NixOS module to install Hyprland.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
plugins = lib.mkOption {
|
|
||||||
type = with lib.types; listOf (either package path);
|
|
||||||
default = [];
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
List of Hyprland plugins to use. Can either be packages or
|
|
||||||
absolute plugin paths.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
systemdIntegration = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = pkgs.stdenv.isLinux;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Whether to enable {file}`hyprland-session.target` on
|
|
||||||
Hyprland startup. This links to {file}`graphical-session.target`.
|
|
||||||
Some important environment variables will be imported to systemd
|
|
||||||
and dbus user environment before reaching the target, including
|
|
||||||
- {env}`DISPLAY`
|
|
||||||
- {env}`HYPRLAND_INSTANCE_SIGNATURE`
|
|
||||||
- {env}`WAYLAND_DISPLAY`
|
|
||||||
- {env}`XDG_CURRENT_DESKTOP`
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
disableAutoreload =
|
|
||||||
lib.mkEnableOption null
|
|
||||||
// {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Whether to disable automatically reloading Hyprland's configuration when
|
|
||||||
rebuilding the Home Manager profile.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
xwayland.enable = lib.mkEnableOption (lib.mdDoc "XWayland") // {default = true;};
|
|
||||||
|
|
||||||
enableNvidiaPatches = lib.mkEnableOption (lib.mdDoc "patching wlroots for better Nvidia support.");
|
|
||||||
|
|
||||||
extraConfig = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.lines;
|
|
||||||
default = "";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Extra configuration lines to add to {file}`~/.config/hypr/hyprland.conf`.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
recommendedEnvironment =
|
|
||||||
lib.mkEnableOption null
|
|
||||||
// {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Whether to set the recommended environment variables.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
warnings =
|
|
||||||
if (cfg.systemdIntegration || cfg.plugins != []) && cfg.extraConfig == null
|
|
||||||
then [
|
|
||||||
''
|
|
||||||
You have enabled hyprland.systemdIntegration or listed plugins in hyprland.plugins.
|
|
||||||
Your Hyprland config will be linked by home manager.
|
|
||||||
Set hyprland.extraConfig or unset hyprland.systemdIntegration and hyprland.plugins to remove this warning.
|
|
||||||
''
|
|
||||||
]
|
|
||||||
else [];
|
|
||||||
|
|
||||||
home.packages =
|
|
||||||
lib.optional (cfg.package != null) cfg.package
|
|
||||||
++ lib.optional cfg.xwayland.enable pkgs.xwayland;
|
|
||||||
|
|
||||||
home.sessionVariables =
|
|
||||||
lib.mkIf cfg.recommendedEnvironment {NIXOS_OZONE_WL = "1";};
|
|
||||||
|
|
||||||
xdg.configFile."hypr/hyprland.conf" = lib.mkIf (cfg.systemdIntegration || cfg.extraConfig != null || cfg.plugins != []) {
|
|
||||||
text =
|
|
||||||
(lib.optionalString cfg.systemdIntegration ''
|
|
||||||
exec-once=${pkgs.dbus}/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP && systemctl --user start hyprland-session.target
|
|
||||||
'')
|
|
||||||
+ lib.concatStrings (builtins.map (entry: let
|
|
||||||
plugin =
|
|
||||||
if lib.types.package.check entry
|
|
||||||
then "${entry}/lib/lib${entry.pname}.so"
|
|
||||||
else entry;
|
|
||||||
in "plugin = ${plugin}\n")
|
|
||||||
cfg.plugins)
|
|
||||||
+ (
|
|
||||||
if cfg.extraConfig != null
|
|
||||||
then cfg.extraConfig
|
|
||||||
else ""
|
|
||||||
);
|
|
||||||
|
|
||||||
onChange = let
|
|
||||||
hyprlandPackage =
|
|
||||||
if cfg.package == null
|
|
||||||
then defaultHyprlandPackage
|
|
||||||
else cfg.package;
|
|
||||||
in
|
|
||||||
lib.mkIf (!cfg.disableAutoreload) ''
|
|
||||||
( # execute in subshell so that `shopt` won't affect other scripts
|
|
||||||
shopt -s nullglob # so that nothing is done if /tmp/hypr/ does not exist or is empty
|
|
||||||
for instance in /tmp/hypr/*; do
|
|
||||||
HYPRLAND_INSTANCE_SIGNATURE=''${instance##*/} ${hyprlandPackage}/bin/hyprctl reload config-only \
|
|
||||||
|| true # ignore dead instance(s)
|
|
||||||
done
|
|
||||||
)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.user.targets.hyprland-session = lib.mkIf cfg.systemdIntegration {
|
|
||||||
Unit = {
|
|
||||||
Description = "Hyprland compositor session";
|
|
||||||
Documentation = ["man:systemd.special(7)"];
|
|
||||||
BindsTo = ["graphical-session.target"];
|
|
||||||
Wants = ["graphical-session-pre.target"];
|
|
||||||
After = ["graphical-session-pre.target"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
(lib.mkRemovedOptionModule ["wayland" "windowManager" "hyprland" "xwayland" "hidpi"]
|
|
||||||
"Support for this option has been removed. Refer to https://wiki.hyprland.org/Configuring/XWayland for more info")
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,98 +2,20 @@ inputs: {
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
options,
|
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
with lib; let
|
|
||||||
cfg = config.programs.hyprland;
|
|
||||||
inherit (pkgs.stdenv.hostPlatform) system;
|
inherit (pkgs.stdenv.hostPlatform) system;
|
||||||
|
cfg = config.programs.hyprland;
|
||||||
|
|
||||||
finalPortalPackage = cfg.portalPackage.override {
|
package = inputs.self.packages.${system}.hyprland;
|
||||||
|
portalPackage = inputs.self.packages.${system}.xdg-desktop-portal-hyprland.override {
|
||||||
hyprland = cfg.finalPackage;
|
hyprland = cfg.finalPackage;
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
# disables Nixpkgs Hyprland module to avoid conflicts
|
config = {
|
||||||
disabledModules = ["programs/hyprland.nix"];
|
programs.hyprland = {
|
||||||
|
package = lib.mkDefault package;
|
||||||
options.programs.hyprland = {
|
portalPackage = lib.mkDefault portalPackage;
|
||||||
enable =
|
|
||||||
mkEnableOption null
|
|
||||||
// {
|
|
||||||
description = mdDoc ''
|
|
||||||
Hyprland, the dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
|
|
||||||
|
|
||||||
You can manually launch Hyprland by executing {command}`Hyprland` on a TTY.
|
|
||||||
|
|
||||||
A configuration file will be generated in {file}`~/.config/hypr/hyprland.conf`.
|
|
||||||
See <https://wiki.hyprland.org> for more information.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
package = mkPackageOptionMD inputs.self.packages.${system} "hyprland" { };
|
|
||||||
|
|
||||||
finalPackage = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
readOnly = true;
|
|
||||||
default = cfg.package.override {
|
|
||||||
enableXWayland = cfg.xwayland.enable;
|
|
||||||
enableNvidiaPatches = cfg.enableNvidiaPatches;
|
|
||||||
};
|
|
||||||
defaultText =
|
|
||||||
literalExpression
|
|
||||||
"`programs.hyprland.package` with applied configuration";
|
|
||||||
description = mdDoc ''
|
|
||||||
The Hyprland package after applying configuration.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
portalPackage = mkPackageOptionMD inputs.xdph.packages.${system} "xdg-desktop-portal-hyprland" {};
|
|
||||||
|
|
||||||
xwayland.enable = mkEnableOption (mdDoc "support for XWayland") // {default = true;};
|
|
||||||
|
|
||||||
enableNvidiaPatches =
|
|
||||||
mkEnableOption null
|
|
||||||
// {
|
|
||||||
description = mdDoc "Whether to apply patches to wlroots for better Nvidia support.";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
environment.systemPackages = [cfg.finalPackage];
|
|
||||||
|
|
||||||
# NixOS changed the name of this attribute between NixOS 23.05 and
|
|
||||||
# 23.11
|
|
||||||
fonts = if builtins.hasAttr "enableDefaultPackages" options.fonts
|
|
||||||
then {enableDefaultPackages = mkDefault true;}
|
|
||||||
else {enableDefaultFonts = mkDefault true;};
|
|
||||||
|
|
||||||
hardware.opengl.enable = mkDefault true;
|
|
||||||
|
|
||||||
programs = {
|
|
||||||
dconf.enable = mkDefault true;
|
|
||||||
xwayland.enable = mkDefault cfg.xwayland.enable;
|
|
||||||
};
|
|
||||||
|
|
||||||
security.polkit.enable = true;
|
|
||||||
|
|
||||||
services.xserver.displayManager.sessionPackages = [cfg.finalPackage];
|
|
||||||
|
|
||||||
xdg.portal = {
|
|
||||||
enable = mkDefault true;
|
|
||||||
extraPortals = [finalPortalPackage];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
imports = with lib; [
|
|
||||||
(
|
|
||||||
mkRemovedOptionModule
|
|
||||||
["programs" "hyprland" "xwayland" "hidpi"]
|
|
||||||
"XWayland patches are deprecated. Refer to https://wiki.hyprland.org/Configuring/XWayland"
|
|
||||||
)
|
|
||||||
(
|
|
||||||
mkRenamedOptionModule
|
|
||||||
["programs" "hyprland" "nvidiaPatches"]
|
|
||||||
["programs" "hyprland" "enableNvidiaPatches"]
|
|
||||||
)
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,42 +3,62 @@
|
|||||||
lib,
|
lib,
|
||||||
inputs,
|
inputs,
|
||||||
}: let
|
}: let
|
||||||
props = builtins.fromJSON (builtins.readFile ../props.json);
|
|
||||||
|
|
||||||
mkDate = longDate: (lib.concatStringsSep "-" [
|
mkDate = longDate: (lib.concatStringsSep "-" [
|
||||||
(builtins.substring 0 4 longDate)
|
(builtins.substring 0 4 longDate)
|
||||||
(builtins.substring 4 2 longDate)
|
(builtins.substring 4 2 longDate)
|
||||||
(builtins.substring 6 2 longDate)
|
(builtins.substring 6 2 longDate)
|
||||||
]);
|
]);
|
||||||
|
version = lib.removeSuffix "\n" (builtins.readFile ../VERSION);
|
||||||
mkJoinedOverlays = overlays: final: prev:
|
|
||||||
lib.foldl' (attrs: overlay: attrs // (overlay final prev)) {} overlays;
|
|
||||||
in {
|
in {
|
||||||
# Contains what a user is most likely to care about:
|
# Contains what a user is most likely to care about:
|
||||||
# Hyprland itself, XDPH and the Share Picker.
|
# Hyprland itself, XDPH and the Share Picker.
|
||||||
default = mkJoinedOverlays (with self.overlays; [
|
default = lib.composeManyExtensions (with self.overlays; [
|
||||||
hyprland-packages
|
hyprland-packages
|
||||||
hyprland-extras
|
hyprland-extras
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# Packages for variations of Hyprland, dependencies included.
|
# Packages for variations of Hyprland, dependencies included.
|
||||||
hyprland-packages = mkJoinedOverlays [
|
hyprland-packages = lib.composeManyExtensions [
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
inputs.aquamarine.overlays.default
|
||||||
|
inputs.hyprcursor.overlays.default
|
||||||
|
inputs.hyprgraphics.overlays.default
|
||||||
inputs.hyprland-protocols.overlays.default
|
inputs.hyprland-protocols.overlays.default
|
||||||
self.overlays.wlroots-hyprland
|
inputs.hyprland-qtutils.overlays.default
|
||||||
|
inputs.hyprlang.overlays.default
|
||||||
|
inputs.hyprutils.overlays.default
|
||||||
|
inputs.hyprwayland-scanner.overlays.default
|
||||||
self.overlays.udis86
|
self.overlays.udis86
|
||||||
|
|
||||||
# Hyprland packages themselves
|
# Hyprland packages themselves
|
||||||
(final: prev: {
|
(final: _prev: let
|
||||||
|
date = mkDate (self.lastModifiedDate or "19700101");
|
||||||
|
in {
|
||||||
hyprland = final.callPackage ./default.nix {
|
hyprland = final.callPackage ./default.nix {
|
||||||
stdenv = final.gcc13Stdenv;
|
stdenv = final.gcc14Stdenv;
|
||||||
version = "${props.version}+date=${mkDate (self.lastModifiedDate or "19700101")}_${self.shortRev or "dirty"}";
|
version = "${version}+date=${date}_${self.shortRev or "dirty"}";
|
||||||
wlroots = final.wlroots-hyprland;
|
|
||||||
commit = self.rev or "";
|
commit = self.rev or "";
|
||||||
inherit (final) udis86 hyprland-protocols;
|
revCount = self.sourceInfo.revCount or "";
|
||||||
|
inherit date;
|
||||||
};
|
};
|
||||||
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
|
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
|
||||||
hyprland-debug = final.hyprland.override {debug = true;};
|
|
||||||
hyprland-nvidia = final.hyprland.override {enableNvidiaPatches = 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
|
||||||
|
hyprland-nvidia =
|
||||||
|
builtins.trace ''
|
||||||
|
hyprland-nvidia was removed. Please use the hyprland package.
|
||||||
|
Nvidia patches are no longer needed.
|
||||||
|
''
|
||||||
|
final.hyprland;
|
||||||
|
|
||||||
hyprland-hidpi =
|
hyprland-hidpi =
|
||||||
builtins.trace ''
|
builtins.trace ''
|
||||||
hyprland-hidpi was removed. Please use the hyprland package.
|
hyprland-hidpi was removed. Please use the hyprland package.
|
||||||
@@ -50,45 +70,23 @@ in {
|
|||||||
|
|
||||||
# Packages for extra software recommended for usage with Hyprland,
|
# Packages for extra software recommended for usage with Hyprland,
|
||||||
# including forked or patched packages for compatibility.
|
# including forked or patched packages for compatibility.
|
||||||
hyprland-extras = mkJoinedOverlays [
|
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 = final: prev: {
|
||||||
udis86 = final.callPackage ./udis86.nix {};
|
udis86-hyprland = prev.udis86.overrideAttrs (_self: _super: {
|
||||||
|
src = final.fetchFromGitHub {
|
||||||
|
owner = "canihavesomecoffee";
|
||||||
|
repo = "udis86";
|
||||||
|
rev = "5336633af70f3917760a6d441ff02d93477b0c86";
|
||||||
|
hash = "sha256-HifdUQPGsKQKQprByeIznvRLONdOXeolOsU5nkwIv3g=";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Patched version of wlroots for Hyprland.
|
patches = [];
|
||||||
# It is under a new package name so as to not conflict with
|
|
||||||
# the standard version in nixpkgs.
|
|
||||||
wlroots-hyprland = final: prev: {
|
|
||||||
wlroots-hyprland = final.callPackage ./wlroots.nix {
|
|
||||||
version = "${mkDate (inputs.wlroots.lastModifiedDate or "19700101")}_${inputs.wlroots.shortRev or "dirty"}";
|
|
||||||
src = inputs.wlroots;
|
|
||||||
|
|
||||||
libdisplay-info = prev.libdisplay-info.overrideAttrs (old: {
|
|
||||||
version = "0.1.1+date=2023-03-02";
|
|
||||||
src = final.fetchFromGitLab {
|
|
||||||
domain = "gitlab.freedesktop.org";
|
|
||||||
owner = "emersion";
|
|
||||||
repo = old.pname;
|
|
||||||
rev = "147d6611a64a6ab04611b923e30efacaca6fc678";
|
|
||||||
sha256 = "sha256-/q79o13Zvu7x02SBGu0W5yQznQ+p7ltZ9L6cMW5t/o4=";
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
libliftoff = prev.libliftoff.overrideAttrs (old: {
|
|
||||||
version = "0.5.0-dev";
|
|
||||||
src = final.fetchFromGitLab {
|
|
||||||
domain = "gitlab.freedesktop.org";
|
|
||||||
owner = "emersion";
|
|
||||||
repo = old.pname;
|
|
||||||
rev = "d98ae243280074b0ba44bff92215ae8d785658c0";
|
|
||||||
sha256 = "sha256-DjwlS8rXE7srs7A8+tHqXyUsFGtucYSeq6X0T/pVOc8=";
|
|
||||||
};
|
|
||||||
|
|
||||||
NIX_CFLAGS_COMPILE = toString ["-Wno-error=sign-conversion"];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
diff --git a/meson.build b/meson.build
|
|
||||||
index 1d2c7f9f..c5ef4e67 100644
|
|
||||||
--- a/meson.build
|
|
||||||
+++ b/meson.build
|
|
||||||
@@ -33,20 +33,7 @@ if cpp_compiler.check_header('execinfo.h')
|
|
||||||
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
|
|
||||||
endif
|
|
||||||
|
|
||||||
-wlroots = subproject('wlroots', default_options: ['examples=false', 'renderers=gles2'])
|
|
||||||
-have_xwlr = wlroots.get_variable('features').get('xwayland')
|
|
||||||
-xcb_dep = dependency('xcb', required: get_option('xwayland'))
|
|
||||||
-
|
|
||||||
-cmake = import('cmake')
|
|
||||||
-udis = cmake.subproject('udis86')
|
|
||||||
-udis86 = udis.dependency('libudis86')
|
|
||||||
-
|
|
||||||
-if get_option('xwayland').enabled() and not have_xwlr
|
|
||||||
- error('Cannot enable Xwayland in Hyprland: wlroots has been built without Xwayland support')
|
|
||||||
-endif
|
|
||||||
-have_xwayland = xcb_dep.found() and have_xwlr
|
|
||||||
-
|
|
||||||
-if not have_xwayland
|
|
||||||
+if get_option('xwayland').disabled()
|
|
||||||
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
|
|
||||||
endif
|
|
||||||
|
|
||||||
@@ -69,8 +56,6 @@ if get_option('buildtype') == 'debug'
|
|
||||||
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
|
|
||||||
endif
|
|
||||||
|
|
||||||
-version_h = run_command('sh', '-c', 'scripts/generateVersion.sh')
|
|
||||||
-
|
|
||||||
globber = run_command('find', 'src', '-name', '*.h*', check: true)
|
|
||||||
headers = globber.stdout().strip().split('\n')
|
|
||||||
foreach file : headers
|
|
||||||
diff --git a/src/meson.build b/src/meson.build
|
|
||||||
index 0af864b9..38723b8c 100644
|
|
||||||
--- a/src/meson.build
|
|
||||||
+++ b/src/meson.build
|
|
||||||
@@ -9,16 +9,16 @@ executable('Hyprland', src,
|
|
||||||
server_protos,
|
|
||||||
dependency('wayland-server'),
|
|
||||||
dependency('wayland-client'),
|
|
||||||
- wlroots.get_variable('wlroots'),
|
|
||||||
+ dependency('wlroots'),
|
|
||||||
dependency('cairo'),
|
|
||||||
dependency('libdrm'),
|
|
||||||
dependency('egl'),
|
|
||||||
dependency('xkbcommon'),
|
|
||||||
dependency('libinput'),
|
|
||||||
- xcb_dep,
|
|
||||||
+ dependency('xcb', required: get_option('xwayland')),
|
|
||||||
backtrace_dep,
|
|
||||||
systemd_dep,
|
|
||||||
- udis86,
|
|
||||||
+ dependency('udis86'),
|
|
||||||
|
|
||||||
dependency('pixman-1'),
|
|
||||||
dependency('gl', 'opengl'),
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c
|
|
||||||
index 9fe934f7..9662d4ee 100644
|
|
||||||
--- a/render/gles2/renderer.c
|
|
||||||
+++ b/render/gles2/renderer.c
|
|
||||||
@@ -176,7 +176,7 @@ static bool gles2_bind_buffer(struct wlr_renderer *wlr_renderer,
|
|
||||||
assert(wlr_egl_is_current(renderer->egl));
|
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
|
||||||
- glFlush();
|
|
||||||
+ glFinish();
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
pop_gles2_debug(renderer);
|
|
||||||
|
|
||||||
diff --git a/types/output/render.c b/types/output/render.c
|
|
||||||
index 2e38919a..97f78608 100644
|
|
||||||
--- a/types/output/render.c
|
|
||||||
+++ b/types/output/render.c
|
|
||||||
@@ -240,22 +240,7 @@ bool output_pick_format(struct wlr_output *output,
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t wlr_output_preferred_read_format(struct wlr_output *output) {
|
|
||||||
- struct wlr_renderer *renderer = output->renderer;
|
|
||||||
- assert(renderer != NULL);
|
|
||||||
-
|
|
||||||
- if (!renderer->impl->preferred_read_format || !renderer->impl->read_pixels) {
|
|
||||||
- return DRM_FORMAT_INVALID;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (!wlr_output_attach_render(output, NULL)) {
|
|
||||||
- return false;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- uint32_t fmt = renderer->impl->preferred_read_format(renderer);
|
|
||||||
-
|
|
||||||
- output_clear_back_buffer(output);
|
|
||||||
-
|
|
||||||
- return fmt;
|
|
||||||
+ return DRM_FORMAT_XRGB8888;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_render_pass *wlr_output_begin_render_pass(struct wlr_output *output,
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
stdenv,
|
|
||||||
fetchFromGitHub,
|
|
||||||
autoreconfHook,
|
|
||||||
python3,
|
|
||||||
}:
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
pname = "udis86";
|
|
||||||
version = "unstable-2022-10-13";
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "canihavesomecoffee";
|
|
||||||
repo = "udis86";
|
|
||||||
rev = "5336633af70f3917760a6d441ff02d93477b0c86";
|
|
||||||
hash = "sha256-HifdUQPGsKQKQprByeIznvRLONdOXeolOsU5nkwIv3g=";
|
|
||||||
};
|
|
||||||
|
|
||||||
nativeBuildInputs = [autoreconfHook python3];
|
|
||||||
|
|
||||||
configureFlags = ["--enable-shared"];
|
|
||||||
|
|
||||||
outputs = ["bin" "out" "dev" "lib"];
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
homepage = "https://udis86.sourceforge.net";
|
|
||||||
license = licenses.bsd2;
|
|
||||||
mainProgram = "udcli";
|
|
||||||
description = "Easy-to-use, minimalistic x86 disassembler library (libudis86)";
|
|
||||||
platforms = platforms.all;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#!/usr/bin/env -S nix shell nixpkgs#gawk nixpkgs#git nixpkgs#gnused nixpkgs#ripgrep -c bash
|
|
||||||
|
|
||||||
# get wlroots revision from submodule
|
|
||||||
SUB_REV=$(git submodule status | rg wlroots | awk '{ print substr($1,2) }')
|
|
||||||
# and from lockfile
|
|
||||||
CRT_REV=$(rg rev flake.nix | awk '{ print substr($3, 2, 40) }')
|
|
||||||
|
|
||||||
if [ "$SUB_REV" != "$CRT_REV" ]; then
|
|
||||||
echo "Updating wlroots..."
|
|
||||||
# update wlroots to submodule revision
|
|
||||||
sed -Ei "s/\w{40}/$SUB_REV/g" flake.nix subprojects/wlroots.wrap
|
|
||||||
nix flake lock
|
|
||||||
|
|
||||||
echo "wlroots: $CRT_REV -> $SUB_REV"
|
|
||||||
else
|
|
||||||
echo "wlroots is up to date!"
|
|
||||||
fi
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
version,
|
|
||||||
src,
|
|
||||||
wlroots,
|
|
||||||
hwdata,
|
|
||||||
libdisplay-info,
|
|
||||||
libliftoff,
|
|
||||||
enableXWayland ? true,
|
|
||||||
enableNvidiaPatches ? false,
|
|
||||||
}:
|
|
||||||
wlroots.overrideAttrs (old: {
|
|
||||||
inherit version src enableXWayland;
|
|
||||||
|
|
||||||
pname = "${old.pname}-hyprland${lib.optionalString enableNvidiaPatches "-nvidia"}";
|
|
||||||
|
|
||||||
patches =
|
|
||||||
(old.patches or [])
|
|
||||||
++ (lib.optionals enableNvidiaPatches [
|
|
||||||
./patches/wlroots-nvidia.patch
|
|
||||||
]);
|
|
||||||
|
|
||||||
buildInputs = old.buildInputs ++ [hwdata libliftoff libdisplay-info];
|
|
||||||
|
|
||||||
NIX_CFLAGS_COMPILE = toString [
|
|
||||||
"-Wno-error=maybe-uninitialized"
|
|
||||||
];
|
|
||||||
})
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.32.0"
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<protocol name="idle">
|
|
||||||
<copyright><![CDATA[
|
|
||||||
Copyright (C) 2015 Martin Gräßlin
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2.1 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
]]></copyright>
|
|
||||||
<interface name="org_kde_kwin_idle" version="1">
|
|
||||||
<description summary="User idle time manager">
|
|
||||||
This interface allows to monitor user idle time on a given seat. The interface
|
|
||||||
allows to register timers which trigger after no user activity was registered
|
|
||||||
on the seat for a given interval. It notifies when user activity resumes.
|
|
||||||
|
|
||||||
This is useful for applications wanting to perform actions when the user is not
|
|
||||||
interacting with the system, e.g. chat applications setting the user as away, power
|
|
||||||
management features to dim screen, etc..
|
|
||||||
</description>
|
|
||||||
<request name="get_idle_timeout">
|
|
||||||
<arg name="id" type="new_id" interface="org_kde_kwin_idle_timeout"/>
|
|
||||||
<arg name="seat" type="object" interface="wl_seat"/>
|
|
||||||
<arg name="timeout" type="uint" summary="The idle timeout in msec"/>
|
|
||||||
</request>
|
|
||||||
</interface>
|
|
||||||
<interface name="org_kde_kwin_idle_timeout" version="1">
|
|
||||||
<request name="release" type="destructor">
|
|
||||||
<description summary="release the timeout object"/>
|
|
||||||
</request>
|
|
||||||
<request name="simulate_user_activity">
|
|
||||||
<description summary="Simulates user activity for this timeout, behaves just like real user activity on the seat"/>
|
|
||||||
</request>
|
|
||||||
<event name="idle">
|
|
||||||
<description summary="Triggered when there has not been any user activity in the requested idle time interval"/>
|
|
||||||
</event>
|
|
||||||
<event name="resumed">
|
|
||||||
<description summary="Triggered on the first user activity after an idle event"/>
|
|
||||||
</event>
|
|
||||||
</interface>
|
|
||||||
</protocol>
|
|
||||||
494
protocols/input-method-unstable-v2.xml
Normal file
@@ -0,0 +1,494 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="input_method_unstable_v2">
|
||||||
|
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2008-2011 Kristian Høgsberg
|
||||||
|
Copyright © 2010-2011 Intel Corporation
|
||||||
|
Copyright © 2012-2013 Collabora, Ltd.
|
||||||
|
Copyright © 2012, 2013 Intel Corporation
|
||||||
|
Copyright © 2015, 2016 Jan Arne Petersen
|
||||||
|
Copyright © 2017, 2018 Red Hat, Inc.
|
||||||
|
Copyright © 2018 Purism SPC
|
||||||
|
|
||||||
|
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="Protocol for creating input methods">
|
||||||
|
This protocol allows applications to act as input methods for compositors.
|
||||||
|
|
||||||
|
An input method context is used to manage the state of the input method.
|
||||||
|
|
||||||
|
Text strings are UTF-8 encoded, their indices and lengths are in bytes.
|
||||||
|
|
||||||
|
This document adheres to the RFC 2119 when using words like "must",
|
||||||
|
"should", "may", etc.
|
||||||
|
|
||||||
|
Warning! The protocol described in this file is experimental and
|
||||||
|
backward incompatible changes may be made. Backward compatible changes
|
||||||
|
may be added together with the corresponding interface version bump.
|
||||||
|
Backward incompatible changes are done by bumping the version number in
|
||||||
|
the protocol and interface names and resetting the interface version.
|
||||||
|
Once the protocol is to be declared stable, the 'z' prefix and the
|
||||||
|
version number in the protocol and interface names are removed and the
|
||||||
|
interface version number is reset.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<interface name="zwp_input_method_v2" version="1">
|
||||||
|
<description summary="input method">
|
||||||
|
An input method object allows for clients to compose text.
|
||||||
|
|
||||||
|
The objects connects the client to a text input in an application, and
|
||||||
|
lets the client to serve as an input method for a seat.
|
||||||
|
|
||||||
|
The zwp_input_method_v2 object can occupy two distinct states: active and
|
||||||
|
inactive. In the active state, the object is associated to and
|
||||||
|
communicates with a text input. In the inactive state, there is no
|
||||||
|
associated text input, and the only communication is with the compositor.
|
||||||
|
Initially, the input method is in the inactive state.
|
||||||
|
|
||||||
|
Requests issued in the inactive state must be accepted by the compositor.
|
||||||
|
Because of the serial mechanism, and the state reset on activate event,
|
||||||
|
they will not have any effect on the state of the next text input.
|
||||||
|
|
||||||
|
There must be no more than one input method object per seat.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="role" value="0" summary="wl_surface has another role"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<event name="activate">
|
||||||
|
<description summary="input method has been requested">
|
||||||
|
Notification that a text input focused on this seat requested the input
|
||||||
|
method to be activated.
|
||||||
|
|
||||||
|
This event serves the purpose of providing the compositor with an
|
||||||
|
active input method.
|
||||||
|
|
||||||
|
This event resets all state associated with previous enable, disable,
|
||||||
|
surrounding_text, text_change_cause, and content_type events, as well
|
||||||
|
as the state associated with set_preedit_string, commit_string, and
|
||||||
|
delete_surrounding_text requests. In addition, it marks the
|
||||||
|
zwp_input_method_v2 object as active, and makes any existing
|
||||||
|
zwp_input_popup_surface_v2 objects visible.
|
||||||
|
|
||||||
|
The surrounding_text, and content_type events must follow before the
|
||||||
|
next done event if the text input supports the respective
|
||||||
|
functionality.
|
||||||
|
|
||||||
|
State set with this event is double-buffered. It will get applied on
|
||||||
|
the next zwp_input_method_v2.done event, and stay valid until changed.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="deactivate">
|
||||||
|
<description summary="deactivate event">
|
||||||
|
Notification that no focused text input currently needs an active
|
||||||
|
input method on this seat.
|
||||||
|
|
||||||
|
This event marks the zwp_input_method_v2 object as inactive. The
|
||||||
|
compositor must make all existing zwp_input_popup_surface_v2 objects
|
||||||
|
invisible until the next activate event.
|
||||||
|
|
||||||
|
State set with this event is double-buffered. It will get applied on
|
||||||
|
the next zwp_input_method_v2.done event, and stay valid until changed.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="surrounding_text">
|
||||||
|
<description summary="surrounding text event">
|
||||||
|
Updates the surrounding plain text around the cursor, excluding the
|
||||||
|
preedit text.
|
||||||
|
|
||||||
|
If any preedit text is present, it is replaced with the cursor for the
|
||||||
|
purpose of this event.
|
||||||
|
|
||||||
|
The argument text is a buffer containing the preedit string, and must
|
||||||
|
include the cursor position, and the complete selection. It should
|
||||||
|
contain additional characters before and after these. There is a
|
||||||
|
maximum length of wayland messages, so text can not be longer than 4000
|
||||||
|
bytes.
|
||||||
|
|
||||||
|
cursor is the byte offset of the cursor within the text buffer.
|
||||||
|
|
||||||
|
anchor is the byte offset of the selection anchor within the text
|
||||||
|
buffer. If there is no selected text, anchor must be the same as
|
||||||
|
cursor.
|
||||||
|
|
||||||
|
If this event does not arrive before the first done event, the input
|
||||||
|
method may assume that the text input does not support this
|
||||||
|
functionality and ignore following surrounding_text events.
|
||||||
|
|
||||||
|
Values set with this event are double-buffered. They will get applied
|
||||||
|
and set to initial values on the next zwp_input_method_v2.done
|
||||||
|
event.
|
||||||
|
|
||||||
|
The initial state for affected fields is empty, meaning that the text
|
||||||
|
input does not support sending surrounding text. If the empty values
|
||||||
|
get applied, subsequent attempts to change them may have no effect.
|
||||||
|
</description>
|
||||||
|
<arg name="text" type="string"/>
|
||||||
|
<arg name="cursor" type="uint"/>
|
||||||
|
<arg name="anchor" type="uint"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="text_change_cause">
|
||||||
|
<description summary="indicates the cause of surrounding text change">
|
||||||
|
Tells the input method why the text surrounding the cursor changed.
|
||||||
|
|
||||||
|
Whenever the client detects an external change in text, cursor, or
|
||||||
|
anchor position, it must issue this request to the compositor. This
|
||||||
|
request is intended to give the input method a chance to update the
|
||||||
|
preedit text in an appropriate way, e.g. by removing it when the user
|
||||||
|
starts typing with a keyboard.
|
||||||
|
|
||||||
|
cause describes the source of the change.
|
||||||
|
|
||||||
|
The value set with this event is double-buffered. It will get applied
|
||||||
|
and set to its initial value on the next zwp_input_method_v2.done
|
||||||
|
event.
|
||||||
|
|
||||||
|
The initial value of cause is input_method.
|
||||||
|
</description>
|
||||||
|
<arg name="cause" type="uint" enum="zwp_text_input_v3.change_cause"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="content_type">
|
||||||
|
<description summary="content purpose and hint">
|
||||||
|
Indicates the content type and hint for the current
|
||||||
|
zwp_input_method_v2 instance.
|
||||||
|
|
||||||
|
Values set with this event are double-buffered. They will get applied
|
||||||
|
on the next zwp_input_method_v2.done event.
|
||||||
|
|
||||||
|
The initial value for hint is none, and the initial value for purpose
|
||||||
|
is normal.
|
||||||
|
</description>
|
||||||
|
<arg name="hint" type="uint" enum="zwp_text_input_v3.content_hint"/>
|
||||||
|
<arg name="purpose" type="uint" enum="zwp_text_input_v3.content_purpose"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="done">
|
||||||
|
<description summary="apply state">
|
||||||
|
Atomically applies state changes recently sent to the client.
|
||||||
|
|
||||||
|
The done event establishes and updates the state of the client, and
|
||||||
|
must be issued after any changes to apply them.
|
||||||
|
|
||||||
|
Text input state (content purpose, content hint, surrounding text, and
|
||||||
|
change cause) is conceptually double-buffered within an input method
|
||||||
|
context.
|
||||||
|
|
||||||
|
Events modify the pending state, as opposed to the current state in use
|
||||||
|
by the input method. A done event atomically applies all pending state,
|
||||||
|
replacing the current state. After done, the new pending state is as
|
||||||
|
documented for each related request.
|
||||||
|
|
||||||
|
Events must be applied in the order of arrival.
|
||||||
|
|
||||||
|
Neither current nor pending state are modified unless noted otherwise.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="commit_string">
|
||||||
|
<description summary="commit string">
|
||||||
|
Send the commit string text for insertion to the application.
|
||||||
|
|
||||||
|
Inserts a string at current cursor position (see commit event
|
||||||
|
sequence). The string to commit could be either just a single character
|
||||||
|
after a key press or the result of some composing.
|
||||||
|
|
||||||
|
The argument text is a buffer containing the string to insert. There is
|
||||||
|
a maximum length of wayland messages, so text can not be longer than
|
||||||
|
4000 bytes.
|
||||||
|
|
||||||
|
Values set with this event are double-buffered. They must be applied
|
||||||
|
and reset to initial on the next zwp_text_input_v3.commit request.
|
||||||
|
|
||||||
|
The initial value of text is an empty string.
|
||||||
|
</description>
|
||||||
|
<arg name="text" type="string"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_preedit_string">
|
||||||
|
<description summary="pre-edit string">
|
||||||
|
Send the pre-edit string text to the application text input.
|
||||||
|
|
||||||
|
Place a new composing text (pre-edit) at the current cursor position.
|
||||||
|
Any previously set composing text must be removed. Any previously
|
||||||
|
existing selected text must be removed. The cursor is moved to a new
|
||||||
|
position within the preedit string.
|
||||||
|
|
||||||
|
The argument text is a buffer containing the preedit string. There is
|
||||||
|
a maximum length of wayland messages, so text can not be longer than
|
||||||
|
4000 bytes.
|
||||||
|
|
||||||
|
The arguments cursor_begin and cursor_end are counted in bytes relative
|
||||||
|
to the beginning of the submitted string buffer. Cursor should be
|
||||||
|
hidden by the text input when both are equal to -1.
|
||||||
|
|
||||||
|
cursor_begin indicates the beginning of the cursor. cursor_end
|
||||||
|
indicates the end of the cursor. It may be equal or different than
|
||||||
|
cursor_begin.
|
||||||
|
|
||||||
|
Values set with this event are double-buffered. They must be applied on
|
||||||
|
the next zwp_input_method_v2.commit event.
|
||||||
|
|
||||||
|
The initial value of text is an empty string. The initial value of
|
||||||
|
cursor_begin, and cursor_end are both 0.
|
||||||
|
</description>
|
||||||
|
<arg name="text" type="string"/>
|
||||||
|
<arg name="cursor_begin" type="int"/>
|
||||||
|
<arg name="cursor_end" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="delete_surrounding_text">
|
||||||
|
<description summary="delete text">
|
||||||
|
Remove the surrounding text.
|
||||||
|
|
||||||
|
before_length and after_length are the number of bytes before and after
|
||||||
|
the current cursor index (excluding the preedit text) to delete.
|
||||||
|
|
||||||
|
If any preedit text is present, it is replaced with the cursor for the
|
||||||
|
purpose of this event. In effect before_length is counted from the
|
||||||
|
beginning of preedit text, and after_length from its end (see commit
|
||||||
|
event sequence).
|
||||||
|
|
||||||
|
Values set with this event are double-buffered. They must be applied
|
||||||
|
and reset to initial on the next zwp_input_method_v2.commit request.
|
||||||
|
|
||||||
|
The initial values of both before_length and after_length are 0.
|
||||||
|
</description>
|
||||||
|
<arg name="before_length" type="uint"/>
|
||||||
|
<arg name="after_length" type="uint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="commit">
|
||||||
|
<description summary="apply state">
|
||||||
|
Apply state changes from commit_string, set_preedit_string and
|
||||||
|
delete_surrounding_text requests.
|
||||||
|
|
||||||
|
The state relating to these events is double-buffered, and each one
|
||||||
|
modifies the pending state. This request replaces the current state
|
||||||
|
with the pending state.
|
||||||
|
|
||||||
|
The connected text input is expected to proceed by evaluating the
|
||||||
|
changes in the following order:
|
||||||
|
|
||||||
|
1. Replace existing preedit string with the cursor.
|
||||||
|
2. Delete requested surrounding text.
|
||||||
|
3. Insert commit string with the cursor at its end.
|
||||||
|
4. Calculate surrounding text to send.
|
||||||
|
5. Insert new preedit text in cursor position.
|
||||||
|
6. Place cursor inside preedit text.
|
||||||
|
|
||||||
|
The serial number reflects the last state of the zwp_input_method_v2
|
||||||
|
object known to the client. The value of the serial argument must be
|
||||||
|
equal to the number of done events already issued by that object. When
|
||||||
|
the compositor receives a commit request with a serial different than
|
||||||
|
the number of past done events, it must proceed as normal, except it
|
||||||
|
should not change the current state of the zwp_input_method_v2 object.
|
||||||
|
</description>
|
||||||
|
<arg name="serial" type="uint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_input_popup_surface">
|
||||||
|
<description summary="create popup surface">
|
||||||
|
Creates a new zwp_input_popup_surface_v2 object wrapping a given
|
||||||
|
surface.
|
||||||
|
|
||||||
|
The surface gets assigned the "input_popup" role. If the surface
|
||||||
|
already has an assigned role, the compositor must issue a protocol
|
||||||
|
error.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="zwp_input_popup_surface_v2"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="grab_keyboard">
|
||||||
|
<description summary="grab hardware keyboard">
|
||||||
|
Allow an input method to receive hardware keyboard input and process
|
||||||
|
key events to generate text events (with pre-edit) over the wire. This
|
||||||
|
allows input methods which compose multiple key events for inputting
|
||||||
|
text like it is done for CJK languages.
|
||||||
|
|
||||||
|
The compositor should send all keyboard events on the seat to the grab
|
||||||
|
holder via the returned wl_keyboard object. Nevertheless, the
|
||||||
|
compositor may decide not to forward any particular event. The
|
||||||
|
compositor must not further process any event after it has been
|
||||||
|
forwarded to the grab holder.
|
||||||
|
|
||||||
|
Releasing the resulting wl_keyboard object releases the grab.
|
||||||
|
</description>
|
||||||
|
<arg name="keyboard" type="new_id"
|
||||||
|
interface="zwp_input_method_keyboard_grab_v2"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="unavailable">
|
||||||
|
<description summary="input method unavailable">
|
||||||
|
The input method ceased to be available.
|
||||||
|
|
||||||
|
The compositor must issue this event as the only event on the object if
|
||||||
|
there was another input_method object associated with the same seat at
|
||||||
|
the time of its creation.
|
||||||
|
|
||||||
|
The compositor must issue this request when the object is no longer
|
||||||
|
usable, e.g. due to seat removal.
|
||||||
|
|
||||||
|
The input method context becomes inert and should be destroyed after
|
||||||
|
deactivation is handled. Any further requests and events except for the
|
||||||
|
destroy request must be ignored.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the text input">
|
||||||
|
Destroys the zwp_text_input_v2 object and any associated child
|
||||||
|
objects, i.e. zwp_input_popup_surface_v2 and
|
||||||
|
zwp_input_method_keyboard_grab_v2.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zwp_input_popup_surface_v2" version="1">
|
||||||
|
<description summary="popup surface">
|
||||||
|
This interface marks a surface as a popup for interacting with an input
|
||||||
|
method.
|
||||||
|
|
||||||
|
The compositor should place it near the active text input area. It must
|
||||||
|
be visible if and only if the input method is in the active state.
|
||||||
|
|
||||||
|
The client must not destroy the underlying wl_surface while the
|
||||||
|
zwp_input_popup_surface_v2 object exists.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<event name="text_input_rectangle">
|
||||||
|
<description summary="set text input area position">
|
||||||
|
Notify about the position of the area of the text input expressed as a
|
||||||
|
rectangle in surface local coordinates.
|
||||||
|
|
||||||
|
This is a hint to the input method telling it the relative position of
|
||||||
|
the text being entered.
|
||||||
|
</description>
|
||||||
|
<arg name="x" type="int"/>
|
||||||
|
<arg name="y" type="int"/>
|
||||||
|
<arg name="width" type="int"/>
|
||||||
|
<arg name="height" type="int"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor"/>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zwp_input_method_keyboard_grab_v2" version="1">
|
||||||
|
<!-- Closely follows wl_keyboard version 6 -->
|
||||||
|
<description summary="keyboard grab">
|
||||||
|
The zwp_input_method_keyboard_grab_v2 interface represents an exclusive
|
||||||
|
grab of the wl_keyboard interface associated with the seat.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<event name="keymap">
|
||||||
|
<description summary="keyboard mapping">
|
||||||
|
This event provides a file descriptor to the client which can be
|
||||||
|
memory-mapped to provide a keyboard mapping description.
|
||||||
|
</description>
|
||||||
|
<arg name="format" type="uint" enum="wl_keyboard.keymap_format"
|
||||||
|
summary="keymap format"/>
|
||||||
|
<arg name="fd" type="fd" summary="keymap file descriptor"/>
|
||||||
|
<arg name="size" type="uint" summary="keymap size, in bytes"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="key">
|
||||||
|
<description summary="key event">
|
||||||
|
A key was pressed or released.
|
||||||
|
The time argument is a timestamp with millisecond granularity, with an
|
||||||
|
undefined base.
|
||||||
|
</description>
|
||||||
|
<arg name="serial" type="uint" summary="serial number of the key event"/>
|
||||||
|
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||||
|
<arg name="key" type="uint" summary="key that produced the event"/>
|
||||||
|
<arg name="state" type="uint" enum="wl_keyboard.key_state"
|
||||||
|
summary="physical state of the key"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="modifiers">
|
||||||
|
<description summary="modifier and group state">
|
||||||
|
Notifies clients that the modifier and/or group state has changed, and
|
||||||
|
it should update its local state.
|
||||||
|
</description>
|
||||||
|
<arg name="serial" type="uint" summary="serial number of the modifiers event"/>
|
||||||
|
<arg name="mods_depressed" type="uint" summary="depressed modifiers"/>
|
||||||
|
<arg name="mods_latched" type="uint" summary="latched modifiers"/>
|
||||||
|
<arg name="mods_locked" type="uint" summary="locked modifiers"/>
|
||||||
|
<arg name="group" type="uint" summary="keyboard layout"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="release" type="destructor">
|
||||||
|
<description summary="release the grab object"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="repeat_info">
|
||||||
|
<description summary="repeat rate and delay">
|
||||||
|
Informs the client about the keyboard's repeat rate and delay.
|
||||||
|
|
||||||
|
This event is sent as soon as the zwp_input_method_keyboard_grab_v2
|
||||||
|
object has been created, and is guaranteed to be received by the
|
||||||
|
client before any key press event.
|
||||||
|
|
||||||
|
Negative values for either rate or delay are illegal. A rate of zero
|
||||||
|
will disable any repeating (regardless of the value of delay).
|
||||||
|
|
||||||
|
This event can be sent later on as well with a new value if necessary,
|
||||||
|
so clients should continue listening for the event past the creation
|
||||||
|
of zwp_input_method_keyboard_grab_v2.
|
||||||
|
</description>
|
||||||
|
<arg name="rate" type="int"
|
||||||
|
summary="the rate of repeating keys in characters per second"/>
|
||||||
|
<arg name="delay" type="int"
|
||||||
|
summary="delay in milliseconds since key down until repeating starts"/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zwp_input_method_manager_v2" version="1">
|
||||||
|
<description summary="input method manager">
|
||||||
|
The input method manager allows the client to become the input method on
|
||||||
|
a chosen seat.
|
||||||
|
|
||||||
|
No more than one input method must be associated with any seat at any
|
||||||
|
given time.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="get_input_method">
|
||||||
|
<description summary="request an input method object">
|
||||||
|
Request a new input zwp_input_method_v2 object associated with a given
|
||||||
|
seat.
|
||||||
|
</description>
|
||||||
|
<arg name="seat" type="object" interface="wl_seat"/>
|
||||||
|
<arg name="input_method" type="new_id" interface="zwp_input_method_v2"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the input method manager">
|
||||||
|
Destroys the zwp_input_method_manager_v2 object.
|
||||||
|
|
||||||
|
The zwp_input_method_v2 objects originating from it remain valid.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
||||||
85
protocols/kde-server-decoration.xml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="server_decoration">
|
||||||
|
<copyright><![CDATA[
|
||||||
|
SPDX-FileCopyrightText: 2015 Martin Gräßlin
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
]]></copyright>
|
||||||
|
<interface name="org_kde_kwin_server_decoration_manager" version="1">
|
||||||
|
<description summary="Server side window decoration manager">
|
||||||
|
This interface allows to coordinate whether the server should create
|
||||||
|
a server-side window decoration around a wl_surface representing a
|
||||||
|
shell surface (wl_shell_surface or similar). By announcing support
|
||||||
|
for this interface the server indicates that it supports server
|
||||||
|
side decorations.
|
||||||
|
|
||||||
|
Use in conjunction with zxdg_decoration_manager_v1 is undefined.
|
||||||
|
</description>
|
||||||
|
<request name="create">
|
||||||
|
<description summary="Create a server-side decoration object for a given surface">
|
||||||
|
When a client creates a server-side decoration object it indicates
|
||||||
|
that it supports the protocol. The client is supposed to tell the
|
||||||
|
server whether it wants server-side decorations or will provide
|
||||||
|
client-side decorations.
|
||||||
|
|
||||||
|
If the client does not create a server-side decoration object for
|
||||||
|
a surface the server interprets this as lack of support for this
|
||||||
|
protocol and considers it as client-side decorated. Nevertheless a
|
||||||
|
client-side decorated surface should use this protocol to indicate
|
||||||
|
to the server that it does not want a server-side deco.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="org_kde_kwin_server_decoration"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
</request>
|
||||||
|
<enum name="mode">
|
||||||
|
<description summary="Possible values to use in request_mode and the event mode."/>
|
||||||
|
<entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/>
|
||||||
|
<entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/>
|
||||||
|
<entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/>
|
||||||
|
</enum>
|
||||||
|
<event name="default_mode">
|
||||||
|
<description summary="The default mode used on the server">
|
||||||
|
This event is emitted directly after binding the interface. It contains
|
||||||
|
the default mode for the decoration. When a new server decoration object
|
||||||
|
is created this new object will be in the default mode until the first
|
||||||
|
request_mode is requested.
|
||||||
|
|
||||||
|
The server may change the default mode at any time.
|
||||||
|
</description>
|
||||||
|
<arg name="mode" type="uint" summary="The default decoration mode applied to newly created server decorations."/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
<interface name="org_kde_kwin_server_decoration" version="1">
|
||||||
|
<request name="release" type="destructor">
|
||||||
|
<description summary="release the server decoration object"/>
|
||||||
|
</request>
|
||||||
|
<enum name="mode">
|
||||||
|
<description summary="Possible values to use in request_mode and the event mode."/>
|
||||||
|
<entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/>
|
||||||
|
<entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/>
|
||||||
|
<entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/>
|
||||||
|
</enum>
|
||||||
|
<request name="request_mode">
|
||||||
|
<description summary="The decoration mode the surface wants to use."/>
|
||||||
|
<arg name="mode" type="uint" summary="The mode this surface wants to use."/>
|
||||||
|
</request>
|
||||||
|
<event name="mode">
|
||||||
|
<description summary="The new decoration mode applied by the server">
|
||||||
|
This event is emitted directly after the decoration is created and
|
||||||
|
represents the base decoration policy by the server. E.g. a server
|
||||||
|
which wants all surfaces to be client-side decorated will send Client,
|
||||||
|
a server which wants server-side decoration will send Server.
|
||||||
|
|
||||||
|
The client can request a different mode through the decoration request.
|
||||||
|
The server will acknowledge this by another event with the same mode. So
|
||||||
|
even if a server prefers server-side decoration it's possible to force a
|
||||||
|
client-side decoration.
|
||||||
|
|
||||||
|
The server may emit this event at any time. In this case the client can
|
||||||
|
again request a different mode. It's the responsibility of the server to
|
||||||
|
prevent a feedback loop.
|
||||||
|
</description>
|
||||||
|
<arg name="mode" type="uint" summary="The decoration mode applied to the surface by the server."/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
||||||
@@ -1,70 +1,105 @@
|
|||||||
wayland_protos = dependency('wayland-protocols',
|
wayland_protos = dependency(
|
||||||
version: '>=1.25',
|
'wayland-protocols',
|
||||||
|
version: '>=1.32',
|
||||||
fallback: 'wayland-protocols',
|
fallback: 'wayland-protocols',
|
||||||
default_options: ['tests=false'],
|
default_options: ['tests=false'],
|
||||||
)
|
)
|
||||||
|
|
||||||
hyprland_protos = dependency('hyprland-protocols',
|
hyprland_protos = dependency(
|
||||||
version: '>=0.2',
|
'hyprland-protocols',
|
||||||
|
version: '>=0.4',
|
||||||
fallback: 'hyprland-protocols',
|
fallback: 'hyprland-protocols',
|
||||||
)
|
)
|
||||||
|
|
||||||
wl_protocol_dir = wayland_protos.get_variable('pkgdatadir')
|
wayland_protocol_dir = wayland_protos.get_variable('pkgdatadir')
|
||||||
hl_protocol_dir = hyprland_protos.get_variable('pkgdatadir')
|
hyprland_protocol_dir = hyprland_protos.get_variable('pkgdatadir')
|
||||||
|
|
||||||
wayland_scanner_dep = dependency('wayland-scanner', native: true)
|
hyprwayland_scanner_dep = dependency('hyprwayland-scanner', version: '>=0.3.10', native: true)
|
||||||
wayland_scanner = find_program(
|
hyprwayland_scanner = find_program(
|
||||||
wayland_scanner_dep.get_variable('wayland_scanner'),
|
hyprwayland_scanner_dep.get_variable('hyprwayland_scanner'),
|
||||||
native: true,
|
native: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
protocols = [
|
protocols = [
|
||||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
'wlr-gamma-control-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
'wlr-foreign-toplevel-management-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
|
'wlr-output-power-management-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
'input-method-unstable-v2.xml',
|
||||||
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
'virtual-keyboard-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'],
|
'wlr-virtual-pointer-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
'wlr-output-management-unstable-v1.xml',
|
||||||
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
'kde-server-decoration.xml',
|
||||||
['wlr-layer-shell-unstable-v1.xml'],
|
'wlr-layer-shell-unstable-v1.xml',
|
||||||
['wlr-output-power-management-unstable-v1.xml'],
|
'wayland-drm.xml',
|
||||||
['wlr-screencopy-unstable-v1.xml'],
|
'wlr-data-control-unstable-v1.xml',
|
||||||
['pointer-constraints-unstable-v1.xml'],
|
'wlr-screencopy-unstable-v1.xml',
|
||||||
['tablet-unstable-v2.xml'],
|
hyprland_protocol_dir / 'protocols/hyprland-global-shortcuts-v1.xml',
|
||||||
['idle.xml'],
|
hyprland_protocol_dir / 'protocols/hyprland-toplevel-export-v1.xml',
|
||||||
[hl_protocol_dir, 'protocols/hyprland-toplevel-export-v1.xml'],
|
hyprland_protocol_dir / 'protocols/hyprland-focus-grab-v1.xml',
|
||||||
[hl_protocol_dir, 'protocols/hyprland-global-shortcuts-v1.xml']
|
hyprland_protocol_dir / 'protocols/hyprland-ctm-control-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 = []
|
wl_protocols = []
|
||||||
foreach p : protocols
|
foreach protocol : protocols
|
||||||
xml = join_paths(p)
|
wl_protocols += custom_target(
|
||||||
wl_protos_src += custom_target(
|
protocol.underscorify(),
|
||||||
xml.underscorify() + '_server_c',
|
input: protocol,
|
||||||
input: xml,
|
|
||||||
output: '@BASENAME@-protocol.c',
|
|
||||||
command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'],
|
|
||||||
)
|
|
||||||
wl_protos_headers += custom_target(
|
|
||||||
xml.underscorify() + '_server_h',
|
|
||||||
input: xml,
|
|
||||||
install: true,
|
install: true,
|
||||||
install_dir: join_paths(get_option('includedir'), 'hyprland/protocols'),
|
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
||||||
output: '@BASENAME@-protocol.h',
|
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
||||||
command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@'],
|
command: [hyprwayland_scanner, '@INPUT@', '@OUTDIR@'],
|
||||||
)
|
)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
wayland_server = dependency('wayland-server', version: '>=1.20.0')
|
# wayland.xml generation
|
||||||
|
wayland_scanner = dependency('wayland-scanner')
|
||||||
|
wayland_scanner_datadir = wayland_scanner.get_variable('pkgdatadir')
|
||||||
|
|
||||||
|
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(
|
lib_server_protos = static_library(
|
||||||
'server_protos',
|
'server_protos',
|
||||||
wl_protos_src + wl_protos_headers,
|
wl_protocols + wayland_protocol,
|
||||||
dependencies: wayland_server.partial_dependency(compile_args: true),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
server_protos = declare_dependency(
|
server_protos = declare_dependency(
|
||||||
link_with: lib_server_protos,
|
link_with: lib_server_protos,
|
||||||
sources: wl_protos_headers,
|
sources: wl_protocols + wayland_protocol,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,339 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<protocol name="pointer_constraints_unstable_v1">
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
Copyright © 2014 Jonas Ådahl
|
|
||||||
Copyright © 2015 Red Hat Inc.
|
|
||||||
|
|
||||||
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="protocol for constraining pointer motions">
|
|
||||||
This protocol specifies a set of interfaces used for adding constraints to
|
|
||||||
the motion of a pointer. Possible constraints include confining pointer
|
|
||||||
motions to a given region, or locking it to its current position.
|
|
||||||
|
|
||||||
In order to constrain the pointer, a client must first bind the global
|
|
||||||
interface "wp_pointer_constraints" which, if a compositor supports pointer
|
|
||||||
constraints, is exposed by the registry. Using the bound global object, the
|
|
||||||
client uses the request that corresponds to the type of constraint it wants
|
|
||||||
to make. See wp_pointer_constraints for more details.
|
|
||||||
|
|
||||||
Warning! The protocol described in this file is experimental and backward
|
|
||||||
incompatible changes may be made. Backward compatible changes may be added
|
|
||||||
together with the corresponding interface version bump. Backward
|
|
||||||
incompatible changes are done by bumping the version number in the protocol
|
|
||||||
and interface names and resetting the interface version. Once the protocol
|
|
||||||
is to be declared stable, the 'z' prefix and the version number in the
|
|
||||||
protocol and interface names are removed and the interface version number is
|
|
||||||
reset.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<interface name="zwp_pointer_constraints_v1" version="1">
|
|
||||||
<description summary="constrain the movement of a pointer">
|
|
||||||
The global interface exposing pointer constraining functionality. It
|
|
||||||
exposes two requests: lock_pointer for locking the pointer to its
|
|
||||||
position, and confine_pointer for locking the pointer to a region.
|
|
||||||
|
|
||||||
The lock_pointer and confine_pointer requests create the objects
|
|
||||||
wp_locked_pointer and wp_confined_pointer respectively, and the client can
|
|
||||||
use these objects to interact with the lock.
|
|
||||||
|
|
||||||
For any surface, only one lock or confinement may be active across all
|
|
||||||
wl_pointer objects of the same seat. If a lock or confinement is requested
|
|
||||||
when another lock or confinement is active or requested on the same surface
|
|
||||||
and with any of the wl_pointer objects of the same seat, an
|
|
||||||
'already_constrained' error will be raised.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<enum name="error">
|
|
||||||
<description summary="wp_pointer_constraints error values">
|
|
||||||
These errors can be emitted in response to wp_pointer_constraints
|
|
||||||
requests.
|
|
||||||
</description>
|
|
||||||
<entry name="already_constrained" value="1"
|
|
||||||
summary="pointer constraint already requested on that surface"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<enum name="lifetime">
|
|
||||||
<description summary="constraint lifetime">
|
|
||||||
These values represent different lifetime semantics. They are passed
|
|
||||||
as arguments to the factory requests to specify how the constraint
|
|
||||||
lifetimes should be managed.
|
|
||||||
</description>
|
|
||||||
<entry name="oneshot" value="1">
|
|
||||||
<description summary="the pointer constraint is defunct once deactivated">
|
|
||||||
A oneshot pointer constraint will never reactivate once it has been
|
|
||||||
deactivated. See the corresponding deactivation event
|
|
||||||
(wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for
|
|
||||||
details.
|
|
||||||
</description>
|
|
||||||
</entry>
|
|
||||||
<entry name="persistent" value="2">
|
|
||||||
<description summary="the pointer constraint may reactivate">
|
|
||||||
A persistent pointer constraint may again reactivate once it has
|
|
||||||
been deactivated. See the corresponding deactivation event
|
|
||||||
(wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for
|
|
||||||
details.
|
|
||||||
</description>
|
|
||||||
</entry>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="destroy the pointer constraints manager object">
|
|
||||||
Used by the client to notify the server that it will no longer use this
|
|
||||||
pointer constraints object.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="lock_pointer">
|
|
||||||
<description summary="lock pointer to a position">
|
|
||||||
The lock_pointer request lets the client request to disable movements of
|
|
||||||
the virtual pointer (i.e. the cursor), effectively locking the pointer
|
|
||||||
to a position. This request may not take effect immediately; in the
|
|
||||||
future, when the compositor deems implementation-specific constraints
|
|
||||||
are satisfied, the pointer lock will be activated and the compositor
|
|
||||||
sends a locked event.
|
|
||||||
|
|
||||||
The protocol provides no guarantee that the constraints are ever
|
|
||||||
satisfied, and does not require the compositor to send an error if the
|
|
||||||
constraints cannot ever be satisfied. It is thus possible to request a
|
|
||||||
lock that will never activate.
|
|
||||||
|
|
||||||
There may not be another pointer constraint of any kind requested or
|
|
||||||
active on the surface for any of the wl_pointer objects of the seat of
|
|
||||||
the passed pointer when requesting a lock. If there is, an error will be
|
|
||||||
raised. See general pointer lock documentation for more details.
|
|
||||||
|
|
||||||
The intersection of the region passed with this request and the input
|
|
||||||
region of the surface is used to determine where the pointer must be
|
|
||||||
in order for the lock to activate. It is up to the compositor whether to
|
|
||||||
warp the pointer or require some kind of user interaction for the lock
|
|
||||||
to activate. If the region is null the surface input region is used.
|
|
||||||
|
|
||||||
A surface may receive pointer focus without the lock being activated.
|
|
||||||
|
|
||||||
The request creates a new object wp_locked_pointer which is used to
|
|
||||||
interact with the lock as well as receive updates about its state. See
|
|
||||||
the the description of wp_locked_pointer for further information.
|
|
||||||
|
|
||||||
Note that while a pointer is locked, the wl_pointer objects of the
|
|
||||||
corresponding seat will not emit any wl_pointer.motion events, but
|
|
||||||
relative motion events will still be emitted via wp_relative_pointer
|
|
||||||
objects of the same seat. wl_pointer.axis and wl_pointer.button events
|
|
||||||
are unaffected.
|
|
||||||
</description>
|
|
||||||
<arg name="id" type="new_id" interface="zwp_locked_pointer_v1"/>
|
|
||||||
<arg name="surface" type="object" interface="wl_surface"
|
|
||||||
summary="surface to lock pointer to"/>
|
|
||||||
<arg name="pointer" type="object" interface="wl_pointer"
|
|
||||||
summary="the pointer that should be locked"/>
|
|
||||||
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
|
||||||
summary="region of surface"/>
|
|
||||||
<arg name="lifetime" type="uint" enum="lifetime" summary="lock lifetime"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="confine_pointer">
|
|
||||||
<description summary="confine pointer to a region">
|
|
||||||
The confine_pointer request lets the client request to confine the
|
|
||||||
pointer cursor to a given region. This request may not take effect
|
|
||||||
immediately; in the future, when the compositor deems implementation-
|
|
||||||
specific constraints are satisfied, the pointer confinement will be
|
|
||||||
activated and the compositor sends a confined event.
|
|
||||||
|
|
||||||
The intersection of the region passed with this request and the input
|
|
||||||
region of the surface is used to determine where the pointer must be
|
|
||||||
in order for the confinement to activate. It is up to the compositor
|
|
||||||
whether to warp the pointer or require some kind of user interaction for
|
|
||||||
the confinement to activate. If the region is null the surface input
|
|
||||||
region is used.
|
|
||||||
|
|
||||||
The request will create a new object wp_confined_pointer which is used
|
|
||||||
to interact with the confinement as well as receive updates about its
|
|
||||||
state. See the the description of wp_confined_pointer for further
|
|
||||||
information.
|
|
||||||
</description>
|
|
||||||
<arg name="id" type="new_id" interface="zwp_confined_pointer_v1"/>
|
|
||||||
<arg name="surface" type="object" interface="wl_surface"
|
|
||||||
summary="surface to lock pointer to"/>
|
|
||||||
<arg name="pointer" type="object" interface="wl_pointer"
|
|
||||||
summary="the pointer that should be confined"/>
|
|
||||||
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
|
||||||
summary="region of surface"/>
|
|
||||||
<arg name="lifetime" type="uint" enum="lifetime" summary="confinement lifetime"/>
|
|
||||||
</request>
|
|
||||||
</interface>
|
|
||||||
|
|
||||||
<interface name="zwp_locked_pointer_v1" version="1">
|
|
||||||
<description summary="receive relative pointer motion events">
|
|
||||||
The wp_locked_pointer interface represents a locked pointer state.
|
|
||||||
|
|
||||||
While the lock of this object is active, the wl_pointer objects of the
|
|
||||||
associated seat will not emit any wl_pointer.motion events.
|
|
||||||
|
|
||||||
This object will send the event 'locked' when the lock is activated.
|
|
||||||
Whenever the lock is activated, it is guaranteed that the locked surface
|
|
||||||
will already have received pointer focus and that the pointer will be
|
|
||||||
within the region passed to the request creating this object.
|
|
||||||
|
|
||||||
To unlock the pointer, send the destroy request. This will also destroy
|
|
||||||
the wp_locked_pointer object.
|
|
||||||
|
|
||||||
If the compositor decides to unlock the pointer the unlocked event is
|
|
||||||
sent. See wp_locked_pointer.unlock for details.
|
|
||||||
|
|
||||||
When unlocking, the compositor may warp the cursor position to the set
|
|
||||||
cursor position hint. If it does, it will not result in any relative
|
|
||||||
motion events emitted via wp_relative_pointer.
|
|
||||||
|
|
||||||
If the surface the lock was requested on is destroyed and the lock is not
|
|
||||||
yet activated, the wp_locked_pointer object is now defunct and must be
|
|
||||||
destroyed.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="destroy the locked pointer object">
|
|
||||||
Destroy the locked pointer object. If applicable, the compositor will
|
|
||||||
unlock the pointer.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="set_cursor_position_hint">
|
|
||||||
<description summary="set the pointer cursor position hint">
|
|
||||||
Set the cursor position hint relative to the top left corner of the
|
|
||||||
surface.
|
|
||||||
|
|
||||||
If the client is drawing its own cursor, it should update the position
|
|
||||||
hint to the position of its own cursor. A compositor may use this
|
|
||||||
information to warp the pointer upon unlock in order to avoid pointer
|
|
||||||
jumps.
|
|
||||||
|
|
||||||
The cursor position hint is double buffered. The new hint will only take
|
|
||||||
effect when the associated surface gets it pending state applied. See
|
|
||||||
wl_surface.commit for details.
|
|
||||||
</description>
|
|
||||||
<arg name="surface_x" type="fixed"
|
|
||||||
summary="surface-local x coordinate"/>
|
|
||||||
<arg name="surface_y" type="fixed"
|
|
||||||
summary="surface-local y coordinate"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="set_region">
|
|
||||||
<description summary="set a new lock region">
|
|
||||||
Set a new region used to lock the pointer.
|
|
||||||
|
|
||||||
The new lock region is double-buffered. The new lock region will
|
|
||||||
only take effect when the associated surface gets its pending state
|
|
||||||
applied. See wl_surface.commit for details.
|
|
||||||
|
|
||||||
For details about the lock region, see wp_locked_pointer.
|
|
||||||
</description>
|
|
||||||
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
|
||||||
summary="region of surface"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<event name="locked">
|
|
||||||
<description summary="lock activation event">
|
|
||||||
Notification that the pointer lock of the seat's pointer is activated.
|
|
||||||
</description>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="unlocked">
|
|
||||||
<description summary="lock deactivation event">
|
|
||||||
Notification that the pointer lock of the seat's pointer is no longer
|
|
||||||
active. If this is a oneshot pointer lock (see
|
|
||||||
wp_pointer_constraints.lifetime) this object is now defunct and should
|
|
||||||
be destroyed. If this is a persistent pointer lock (see
|
|
||||||
wp_pointer_constraints.lifetime) this pointer lock may again
|
|
||||||
reactivate in the future.
|
|
||||||
</description>
|
|
||||||
</event>
|
|
||||||
</interface>
|
|
||||||
|
|
||||||
<interface name="zwp_confined_pointer_v1" version="1">
|
|
||||||
<description summary="confined pointer object">
|
|
||||||
The wp_confined_pointer interface represents a confined pointer state.
|
|
||||||
|
|
||||||
This object will send the event 'confined' when the confinement is
|
|
||||||
activated. Whenever the confinement is activated, it is guaranteed that
|
|
||||||
the surface the pointer is confined to will already have received pointer
|
|
||||||
focus and that the pointer will be within the region passed to the request
|
|
||||||
creating this object. It is up to the compositor to decide whether this
|
|
||||||
requires some user interaction and if the pointer will warp to within the
|
|
||||||
passed region if outside.
|
|
||||||
|
|
||||||
To unconfine the pointer, send the destroy request. This will also destroy
|
|
||||||
the wp_confined_pointer object.
|
|
||||||
|
|
||||||
If the compositor decides to unconfine the pointer the unconfined event is
|
|
||||||
sent. The wp_confined_pointer object is at this point defunct and should
|
|
||||||
be destroyed.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="destroy the confined pointer object">
|
|
||||||
Destroy the confined pointer object. If applicable, the compositor will
|
|
||||||
unconfine the pointer.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="set_region">
|
|
||||||
<description summary="set a new confine region">
|
|
||||||
Set a new region used to confine the pointer.
|
|
||||||
|
|
||||||
The new confine region is double-buffered. The new confine region will
|
|
||||||
only take effect when the associated surface gets its pending state
|
|
||||||
applied. See wl_surface.commit for details.
|
|
||||||
|
|
||||||
If the confinement is active when the new confinement region is applied
|
|
||||||
and the pointer ends up outside of newly applied region, the pointer may
|
|
||||||
warped to a position within the new confinement region. If warped, a
|
|
||||||
wl_pointer.motion event will be emitted, but no
|
|
||||||
wp_relative_pointer.relative_motion event.
|
|
||||||
|
|
||||||
The compositor may also, instead of using the new region, unconfine the
|
|
||||||
pointer.
|
|
||||||
|
|
||||||
For details about the confine region, see wp_confined_pointer.
|
|
||||||
</description>
|
|
||||||
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
|
||||||
summary="region of surface"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<event name="confined">
|
|
||||||
<description summary="pointer confined">
|
|
||||||
Notification that the pointer confinement of the seat's pointer is
|
|
||||||
activated.
|
|
||||||
</description>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="unconfined">
|
|
||||||
<description summary="pointer unconfined">
|
|
||||||
Notification that the pointer confinement of the seat's pointer is no
|
|
||||||
longer active. If this is a oneshot pointer confinement (see
|
|
||||||
wp_pointer_constraints.lifetime) this object is now defunct and should
|
|
||||||
be destroyed. If this is a persistent pointer confinement (see
|
|
||||||
wp_pointer_constraints.lifetime) this pointer confinement may again
|
|
||||||
reactivate in the future.
|
|
||||||
</description>
|
|
||||||
</event>
|
|
||||||
</interface>
|
|
||||||
|
|
||||||
</protocol>
|
|
||||||