mirror of
git://git.suckless.org/dwm
synced 2025-04-20 03:24:46 +01:00
Compare commits
1656 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
cfb8627a80 | ||
|
fcb2476b69 | ||
|
8933ebcf50 | ||
|
5687f46964 | ||
|
061e9fe9a7 | ||
|
9f8855343c | ||
|
e81f17d4c1 | ||
|
348f6559ab | ||
|
712d6639ff | ||
|
89f9905714 | ||
|
ba56fe9fea | ||
|
50ad171eea | ||
|
970f376973 | ||
|
c2b748e793 | ||
|
84d7322113 | ||
|
5799dd1fca | ||
|
44adafe006 | ||
|
a859676ead | ||
|
e0dee91145 | ||
|
5e76e7e21d | ||
|
5b2e5e7a40 | ||
|
786f6e2a6f | ||
|
e03248a4d5 | ||
|
6613d9f9a1 | ||
|
9bffa845fa | ||
|
d3f93c7c1a | ||
|
cd0773cee9 | ||
|
8b48e30973 | ||
|
a83dc20310 | ||
|
a4771de5ba | ||
|
d93ff48803 | ||
|
8806b6e237 | ||
|
bece862a0f | ||
|
60e9a14998 | ||
|
d39e2f3441 | ||
|
8657affa2a | ||
|
a786211d6c | ||
|
716233534b | ||
|
138b405f0c | ||
|
67d76bdc68 | ||
|
61bb8b2241 | ||
|
bb2e7222ba | ||
|
f04cac6d6e | ||
|
f09418bbb6 | ||
|
ed3ab6b4fc | ||
|
f087d20e6e | ||
|
a8e9513783 | ||
|
c82db690cc | ||
|
cb3f58ad06 | ||
|
b69c870a30 | ||
|
e78b4a9207 | ||
|
3cd4023fb3 | ||
|
f40f86fa87 | ||
|
c3a2e016bb | ||
|
c8e9479186 | ||
|
10dfa65860 | ||
|
3bd8466e93 | ||
|
76c8c16d79 | ||
|
3cb34830eb | ||
|
db2236001c | ||
|
3756f7f6b8 | ||
|
99f78fa553 | ||
|
a9b6a312a7 | ||
|
6aa8e37efe | ||
|
ceac8c91ff | ||
|
5b238c8dab | ||
|
022d076054 | ||
|
2952b68db8 | ||
|
bb3bd6fec3 | ||
|
e63bf22948 | ||
|
5376947571 | ||
|
975c898376 | ||
|
a137a86a23 | ||
|
839c7f6939 | ||
|
7a59cd1457 | ||
|
24849acada | ||
|
ab9571bbc5 | ||
|
56a31dc4a7 | ||
|
7af4d439bd | ||
|
cd2d7549b3 | ||
|
3465bed290 | ||
|
4ec3a673ff | ||
|
5ed9c48196 | ||
|
3c91283ede | ||
|
e941181f46 | ||
|
43e82adf0d | ||
|
42cf1c7d8f | ||
|
dce4fb3737 | ||
|
646b351cc7 | ||
|
e3b7e1d620 | ||
|
04db03a4e6 | ||
|
4a4817b3aa | ||
|
7e1182ce55 | ||
|
40529e1469 | ||
|
14343e69cc | ||
|
35db6d8afc | ||
|
3d1090ba89 | ||
|
18248ebf4b | ||
|
b468873b2b | ||
|
cdec9782a1 | ||
|
6af273771c | ||
|
4fb31e0896 | ||
|
b800a1d136 | ||
|
33a74489f0 | ||
|
5364697914 | ||
|
7edc596311 | ||
|
68b400e95d | ||
|
656882d76f | ||
|
1479e76f01 | ||
|
f2544a3318 | ||
|
aafeaf7317 | ||
|
f21d46ea7d | ||
|
c0ba635c50 | ||
|
0a673ad7a3 | ||
|
3aabc08ede | ||
|
d456617f0e | ||
|
61fe833a06 | ||
|
917e281634 | ||
|
31451c3ad3 | ||
|
344f35f9f5 | ||
|
87adcd263b | ||
|
fd3c19bd55 | ||
|
1bdb393f81 | ||
|
940feed314 | ||
|
606b44179d | ||
|
20f6917910 | ||
|
820cbb3545 | ||
|
90f3238301 | ||
|
3bfc43c3d0 | ||
|
c1128417a9 | ||
|
1b62f8fa58 | ||
|
54c3044dec | ||
|
51336aa4a3 | ||
|
c4b6ac812e | ||
|
873bcb97a9 | ||
|
907db0a851 | ||
|
4e7c469862 | ||
|
26445a0dc9 | ||
|
b5068e32e9 | ||
|
f099d2d5b5 | ||
|
80a9da555e | ||
|
d21026f0a1 | ||
|
e5a1e77351 | ||
|
8262d9e663 | ||
|
90af1ced3c | ||
|
5ccd42f807 | ||
|
1586b7a02d | ||
|
2420071f4c | ||
|
04c26574b8 | ||
|
b1a28ae1da | ||
|
f68a01cd76 | ||
|
2b625eb73e | ||
|
0f1f30daca | ||
|
dec4850d05 | ||
|
0de4197cc5 | ||
|
a372248b80 | ||
|
69e7d7dfd3 | ||
|
c99fe7dd7d | ||
|
d6670a800d | ||
|
6288c44697 | ||
|
d5c5c52b30 | ||
|
d0b4575bf4 | ||
|
03518ce49e | ||
|
cd8bb06af5 | ||
|
3150a8a1be | ||
|
b3c5f5435a | ||
|
a692bdcf2b | ||
|
d83454f6b7 | ||
|
27b0142203 | ||
|
867ba36030 | ||
|
e83f36db10 | ||
|
212f417e44 | ||
|
3a392b8558 | ||
|
92fe06b501 | ||
|
6cf29bff33 | ||
|
60c06a7cb4 | ||
|
1147546122 | ||
|
d384cee751 | ||
|
5c710cf89c | ||
|
8a111c181e | ||
|
2255bf46a0 | ||
|
04797343db | ||
|
e7d41cc188 | ||
|
22d8818850 | ||
|
6784429c3c | ||
|
37fea84de8 | ||
|
c14d293e51 | ||
|
79b1657a19 | ||
|
d24837f1ad | ||
|
3c2d303c0e | ||
|
1e20a0f78a | ||
|
96f9855248 | ||
|
3c48858ffa | ||
|
dd46d5b588 | ||
|
0bc4e41ebd | ||
|
703c4dd253 | ||
|
b68528d85d | ||
|
a644baf674 | ||
|
c1f8688bfa | ||
|
bea4dd2490 | ||
|
83d10be1c1 | ||
|
1529058f27 | ||
|
36311d88af | ||
|
f1a2a3c850 | ||
|
ee734fae6b | ||
|
62d3caa999 | ||
|
4c9b397ff9 | ||
|
5c6545adf5 | ||
|
a704b1ee34 | ||
|
f83d61dfe8 | ||
|
c6180949a7 | ||
|
1973ab0643 | ||
|
427053f8d1 | ||
|
a88e0373ef | ||
|
aa9f2be24e | ||
|
c53b29e60b | ||
|
d6bdd03d91 | ||
|
1144e98394 | ||
|
7671d03a90 | ||
|
bc554d45d8 | ||
|
ac4caea921 | ||
|
161f2d921b | ||
|
210378f198 | ||
|
7879616a75 | ||
|
9e8dd3479d | ||
|
0b72be924d | ||
|
91e902f7fe | ||
|
30fed9a211 | ||
|
c45d46ad9a | ||
|
6f55de8310 | ||
|
07ad298133 | ||
|
f0a4845e7d | ||
|
82ec7a7ed4 | ||
|
e7300e0f6f | ||
|
c3feffa1e2 | ||
|
956a430054 | ||
|
01056b6636 | ||
|
eb260b1a41 | ||
|
7fe81359d4 | ||
|
a3a859b4e9 | ||
|
9c066c24b3 | ||
|
0a668922a4 | ||
|
5762964232 | ||
|
cba6b211c2 | ||
|
42750a621b | ||
|
8ef465d592 | ||
|
33fe200b52 | ||
|
91fffb3f7d | ||
|
1fa31efebf | ||
|
244addb3f4 | ||
|
c13be8d620 | ||
|
dc39ae8568 | ||
|
966d76a428 | ||
|
7151bf8329 | ||
|
dfecd46190 | ||
|
5bc4db0f76 | ||
|
999d6e795f | ||
|
636075297c | ||
|
6877a00033 | ||
|
0927d635bc | ||
|
450b08dde2 | ||
|
da80487c07 | ||
|
d9779c06fc | ||
|
20996c6c5a | ||
|
8dc9fcf1b9 | ||
|
fc21dd4b7e | ||
|
758b100d12 | ||
|
8420fb1ced | ||
|
f6128a16f9 | ||
|
87526be6f0 | ||
|
565050ac51 | ||
|
5e408d8ff6 | ||
|
1724f7fa43 | ||
|
3e6fe6b541 | ||
|
6620615ab9 | ||
|
61c3095f2f | ||
|
a72dc2fec2 | ||
|
8b17f5517b | ||
|
cd96232f7e | ||
|
a9e145fe6d | ||
|
5dd92c7655 | ||
|
52bd69c2a4 | ||
|
ca376970db | ||
|
8352f2b3a8 | ||
|
d4bfde79f3 | ||
|
7ac8c1d4e1 | ||
|
16e1ef5d40 | ||
|
1d729384d1 | ||
|
25c1eb28f9 | ||
|
d719cc9a0e | ||
|
9cde6570cc | ||
|
e408ca97d8 | ||
|
183dc670a3 | ||
|
25947bcfdb | ||
|
1ddfc571ae | ||
|
21cd59a630 | ||
|
6cbe47d481 | ||
|
029655bb22 | ||
|
27db9d4448 | ||
|
176408afa8 | ||
|
64674c395b | ||
|
b9dee2c6f1 | ||
|
a73ff905b0 | ||
|
e3f0445df1 | ||
|
ab06f7444b | ||
|
a2a3590979 | ||
|
e8aafb8e91 | ||
|
18b1312449 | ||
|
80ee95473b | ||
|
454a04acdf | ||
|
891831fe62 | ||
|
cdb8e27453 | ||
|
5c4913e983 | ||
|
fa5ae54bbb | ||
|
7de534192c | ||
|
54dc0d542c | ||
|
913333f518 | ||
|
d702f39274 | ||
|
0d8671a5ad | ||
|
38e9b67026 | ||
|
a3bbdb1b7b | ||
|
d53ceee682 | ||
|
78f56672b5 | ||
|
c2fff604a7 | ||
|
6644a6aa2e | ||
|
3da2453997 | ||
|
2ce37bc69e | ||
|
f27ccc5c60 | ||
|
2dbfda72f0 | ||
|
7df39f3fc7 | ||
|
0b45199cec | ||
|
3632d7132f | ||
|
565697087b | ||
|
ea0008cba2 | ||
|
af508c2e82 | ||
|
f0d1d5206f | ||
|
1c80c05587 | ||
|
1e350be229 | ||
|
1a26389e2b | ||
|
bf9da23f07 | ||
|
2373940215 | ||
|
90687482ad | ||
|
5ab627c06c | ||
|
76d7e80fc4 | ||
|
af8049bce8 | ||
|
2bb51b3246 | ||
|
b16d8282be | ||
|
fef4614772 | ||
|
be39dddcc5 | ||
|
6d209b9b29 | ||
|
57a0788bd8 | ||
|
3ad906eede | ||
|
0be9fb8797 | ||
|
62a491e36d | ||
|
0b5dcf229f | ||
|
fda92f46aa | ||
|
a62ea4062f | ||
|
7dc28d130f | ||
|
fbce733532 | ||
|
e7572804fa | ||
|
ed1bef1241 | ||
|
2b047e460b | ||
|
5f74dc5e78 | ||
|
ea8a4ca46a | ||
|
4883a06221 | ||
|
4dea5324c0 | ||
|
53cac17692 | ||
|
83abfc05eb | ||
|
862b0d541d | ||
|
c1c6fdc5d8 | ||
|
9a4d07d9de | ||
|
30410108eb | ||
|
753e0e048e | ||
|
d15d4ba45a | ||
|
815f9c054d | ||
|
addc52c948 | ||
|
26f41c9055 | ||
|
73ec124ae9 | ||
|
ec11a3470c | ||
|
4b3b597da3 | ||
|
288cf78b18 | ||
|
6411aa921b | ||
|
db5db8806f | ||
|
258c338030 | ||
|
85da537856 | ||
|
2b4157eccd | ||
|
0f26de991f | ||
|
840f937a98 | ||
|
6975a7e31a | ||
|
47f63dce55 | ||
|
02a8ca95cf | ||
|
2ce50a9cad | ||
|
bfa5869da1 | ||
|
087a55f8d3 | ||
|
6d7285fd6e | ||
|
69c7b4b0ba | ||
|
97699e5b1b | ||
|
2dc7f42fd7 | ||
|
9f3a5cb754 | ||
|
b48fa3f101 | ||
|
051a404b66 | ||
|
d8d733c34f | ||
|
bb01e5a16f | ||
|
06f7eed103 | ||
|
0ffa6d1393 | ||
|
15ce143620 | ||
|
63d7190231 | ||
|
b279cef670 | ||
|
6254ef9dc7 | ||
|
4a2902efe4 | ||
|
6fad4c49f1 | ||
|
78f0f8595f | ||
|
7ecadcee39 | ||
|
c86ed46a1b | ||
|
9086f98068 | ||
|
9aa4a9043d | ||
|
d5893f55be | ||
|
f529d41ca1 | ||
|
45768ee04b | ||
|
a6d23fb61c | ||
|
bf76cefe47 | ||
|
9bb0f20515 | ||
|
2431ae7df7 | ||
|
829b6b57e7 | ||
|
7b4c512e62 | ||
|
7f7c3140a9 | ||
|
277155cf77 | ||
|
0c38ec7cd6 | ||
|
deef4c9bfd | ||
|
b86c818599 | ||
|
c2a916bf30 | ||
|
2bd46d1ce6 | ||
|
6e0ce46365 | ||
|
c853d5e9bb | ||
|
31da0b7525 | ||
|
12ea925076 | ||
|
79ecbeca7e | ||
|
cf98ea2a9c | ||
|
d8fad9bf7a | ||
|
f25cc5678f | ||
|
5a92420fce | ||
|
ae1d865ac0 | ||
|
1ce173402f | ||
|
a06b9193c7 | ||
|
43bb77a569 | ||
|
e3da222c1e | ||
|
66608a60fe | ||
|
b6aa84e51b | ||
|
9ff5143acb | ||
|
1edf6a7866 | ||
|
4db2f44277 | ||
|
1f1a132784 | ||
|
512541bfbd | ||
|
709da0b858 | ||
|
5cd65f8cd8 | ||
|
e3838e8585 | ||
|
016dca4f69 | ||
|
8f052596b2 | ||
|
9463d5354b | ||
|
d662f98d89 | ||
|
e5a965a274 | ||
|
5d422bb1ce | ||
|
38a43c2dcc | ||
|
c56533615f | ||
|
a8e0772c4d | ||
|
98e7950be8 | ||
|
88e6eb4a3a | ||
|
0840c1367c | ||
|
077d3e435b | ||
|
d26b60b43e | ||
|
32f36ab2d5 | ||
|
08bcf721b4 | ||
|
fc578c57e4 | ||
|
c8eaab21b6 | ||
|
c26e22ccee | ||
|
c2784e4a38 | ||
|
6e9387793b | ||
|
92f3c181c3 | ||
|
d589f7679a | ||
|
75690c808d | ||
|
fde58d5e63 | ||
|
e1002745fa | ||
|
940a4cc6c6 | ||
|
64243ab05b | ||
|
32c5046635 | ||
|
6c8618f502 | ||
|
9189f7a12d | ||
|
2d4faae522 | ||
|
5d2385b636 | ||
|
0fe2e783e9 | ||
|
cd3d83f571 | ||
|
0a9ef560c0 | ||
|
0528a37c79 | ||
|
56b2fece9e | ||
|
9f569fac74 | ||
|
48d0c56eac | ||
|
825d6cb93a | ||
|
f852504014 | ||
|
c3fa9e879f | ||
|
8e05f6c592 | ||
|
39d1ecd5b0 | ||
|
103fb58a44 | ||
|
5f55af40ae | ||
|
f806a17692 | ||
|
822101dd5b | ||
|
6bdef73a4f | ||
|
234b12eb73 | ||
|
bd4deaebfc | ||
|
499315c22c | ||
|
f22d047d41 | ||
|
4a5c8d84db | ||
|
71365a524f | ||
|
3afca3e6a1 | ||
|
bdc80bdad6 | ||
|
64707da963 | ||
|
549726869b | ||
|
42cb2bd3be | ||
|
585294ce0f | ||
|
a864a82b34 | ||
|
bd67a82fb5 | ||
|
14d8d828ab | ||
|
4246affc15 | ||
|
42c4b31003 | ||
|
a785a0d712 | ||
|
489ac07e83 | ||
|
349d768b57 | ||
|
6dfa7cac56 | ||
|
71681c21a5 | ||
|
704781875c | ||
|
d7cc0f6416 | ||
|
6b79f3f326 | ||
|
446fa8c671 | ||
|
fa244aa7fb | ||
|
7ac4f8a4af | ||
|
7eb26288fc | ||
|
93a4fe1052 | ||
|
5602f44b29 | ||
|
b848f4bda8 | ||
|
86c4797f2c | ||
|
c094ed2473 | ||
|
bfd6079a15 | ||
|
7f70d90219 | ||
|
858251de46 | ||
|
d26c28c1e7 | ||
|
b6335776e4 | ||
|
c059625128 | ||
|
874837f653 | ||
|
5fa559dbfc | ||
|
146ff227fe | ||
|
bb0a328978 | ||
|
721b208478 | ||
|
6229ed20c2 | ||
|
940240e5e6 | ||
|
08c596ed10 | ||
|
9ce6abb95c | ||
|
0e21794e02 | ||
|
d477fb6927 | ||
|
3d6630b7d2 | ||
|
c982bb1389 | ||
|
6cf73e706a | ||
|
a520ba3c0b | ||
|
0c71b16b92 | ||
|
00c28a7ef2 | ||
|
5a3a2d6b63 | ||
|
a355782a77 | ||
|
20cd336087 | ||
|
a6a216f28c | ||
|
2c2063bc75 | ||
|
e6ede461a9 | ||
|
6877205e9d | ||
|
fb5f99d935 | ||
|
7ebab7533a | ||
|
9fa5ca3538 | ||
|
fe6b0c0fc1 | ||
|
aa2395b6a8 | ||
|
dba22848c7 | ||
|
33b1960220 | ||
|
e237b2a76f | ||
|
dd9ee6d248 | ||
|
1380569133 | ||
|
831428b00c | ||
|
69439715c0 | ||
|
f2e98f48fb | ||
|
c19d4b2930 | ||
|
f77a3d0a62 | ||
|
8aa1533879 | ||
|
2fc9cffdeb | ||
|
3c5b6f03ba | ||
|
02673538bc | ||
|
95eae7b9d2 | ||
|
59107755c8 | ||
|
d05d09b205 | ||
|
47b1974446 | ||
|
247ba66c08 | ||
|
d7b074fcce | ||
|
c9170189bf | ||
|
f7a45ff28b | ||
|
add7df6e9b | ||
|
3a79b82721 | ||
|
b31b430592 | ||
|
88c8ead3e8 | ||
|
2e95837220 | ||
|
5d9ae3f3b7 | ||
|
2e38296edd | ||
|
59aa02a075 | ||
|
e3c2d327f6 | ||
|
295ad21092 | ||
|
39af3c2607 | ||
|
96ee9d888c | ||
|
a82cba2759 | ||
|
f7c097e802 | ||
|
da1b3fa437 | ||
|
ad0a2fa042 | ||
|
9804726c82 | ||
|
7bc272a4e4 | ||
|
f1719ac2de | ||
|
d99ec61482 | ||
|
2f70a14ee1 | ||
|
00ca643bd7 | ||
|
0271ac0ed7 | ||
|
d5178292ed | ||
|
2bfd3fffbf | ||
|
a3d8c05a95 | ||
|
fd01413fae | ||
|
d6e24f7116 | ||
|
c43d7b7587 | ||
|
de5b294edc | ||
|
8e0f8ffcc6 | ||
|
dd21823536 | ||
|
9cb9c32ee7 | ||
|
4076e2ff60 | ||
|
55edd2d6ec | ||
|
2e8e5509d9 | ||
|
4426032450 | ||
|
e0f0397896 | ||
|
ca3e847e45 | ||
|
c2737b7b93 | ||
|
191cb9ce28 | ||
|
6ab163c695 | ||
|
e8244395e4 | ||
|
954db46bac | ||
|
508922b90d | ||
|
4adfdc9d95 | ||
|
c619363d15 | ||
|
012710a3ce | ||
|
c2c54cc0fa | ||
|
a62630ae92 | ||
|
62b18fb9d4 | ||
|
e0d6451086 | ||
|
7a496e9777 | ||
|
308f95ae5a | ||
|
40a734bca9 | ||
|
985e330524 | ||
|
5f19423c7b | ||
|
d66ad1457e | ||
|
8497f9f781 | ||
|
91bb749e97 | ||
|
68ff133857 | ||
|
4380db468a | ||
|
123a565bb9 | ||
|
d0e0505301 | ||
|
762b66ae7c | ||
|
cb4951dd54 | ||
|
667da18b31 | ||
|
e9a0733506 | ||
|
198502f41d | ||
|
35efafe8ac | ||
|
951d022dfc | ||
|
54bde0f9d7 | ||
|
260a55ef62 | ||
|
0e98090d65 | ||
|
af4667a85a | ||
|
a98b5e5935 | ||
|
b8985dc7bb | ||
|
6f60b2e1cd | ||
|
3033d45d1c | ||
|
34e7872c89 | ||
|
c36f7c3c5e | ||
|
3fd39feb41 | ||
|
93eee247ca | ||
|
d5e8edcbcb | ||
|
13577b15e5 | ||
|
5473e763f6 | ||
|
cdd6c3e820 | ||
|
29f2b15ddc | ||
|
7b65b763bc | ||
|
e94774dd69 | ||
|
af0034f3a5 | ||
|
cd7ebaad25 | ||
|
8dc03d6e6b | ||
|
1dcb18c124 | ||
|
206eb344e2 | ||
|
04de5720e6 | ||
|
5a04edecb1 | ||
|
24c125cc8a | ||
|
0453c1d180 | ||
|
0b5c14cf59 | ||
|
a73de0cff4 | ||
|
eeea4ef583 | ||
|
883e09b2eb | ||
|
7e25897f11 | ||
|
95091dcad4 | ||
|
57676994ea | ||
|
60adbab726 | ||
|
c3eca4d14f | ||
|
d1f4fbb469 | ||
|
635b64384d | ||
|
bedbe59aaa | ||
|
3f3086f8b8 | ||
|
f92a4e45c4 | ||
|
2fc8a13588 | ||
|
63725004f5 | ||
|
e9348dcaca | ||
|
fa857b2896 | ||
|
c77663fcb4 | ||
|
17d39ee014 | ||
|
8d1810c85b | ||
|
60444daa70 | ||
|
b0477c3017 | ||
|
24dae7d7e3 | ||
|
fa1ce22bc4 | ||
|
1fafcb1820 | ||
|
08c2d92480 | ||
|
fe2775a15b | ||
|
01022b95d6 | ||
|
b2f276b0f9 | ||
|
d1ce3eac33 | ||
|
9449ea3e00 | ||
|
49197fe4bf | ||
|
11cfff2dae | ||
|
a026617c65 | ||
|
a6df995b5d | ||
|
e041ff70b0 | ||
|
2d7bb8d7c9 | ||
|
0235a84ef2 | ||
|
2091200c95 | ||
|
7e476fb86b | ||
|
9800518ae3 | ||
|
5d831eaa94 | ||
|
e0a6dee30d | ||
|
73e2aba341 | ||
|
9f88fd093c | ||
|
0e515a06c8 | ||
|
c4b3c0d979 | ||
|
f3a5116248 | ||
|
ae760f3f38 | ||
|
169d96ae8f | ||
|
f651435061 | ||
|
a92cf496c1 | ||
|
cc7970010b | ||
|
67a1141f44 | ||
|
8be3f3ec9e | ||
|
5762e92994 | ||
|
36672d0401 | ||
|
b18e684015 | ||
|
fc109ea8f7 | ||
|
b975c47280 | ||
|
47765f7286 | ||
|
96d7fe16ea | ||
|
78d1a22d4e | ||
|
0c60620410 | ||
|
50be6c8b67 | ||
|
7d156dee1e | ||
|
55d8dda9f4 | ||
|
86953bd682 | ||
|
a923298d35 | ||
|
04dec4c943 | ||
|
e40448fd63 | ||
|
10bc0ce912 | ||
|
e8792d95a1 | ||
|
feec92df84 | ||
|
10d13f01ff | ||
|
8fcc4ff0ae | ||
|
f2512243f4 | ||
|
b32cd4454b | ||
|
9e56e1ded6 | ||
|
e4ad320599 | ||
|
a200c39635 | ||
|
77044e8765 | ||
|
2feb3afe78 | ||
|
0937cc78bf | ||
|
f6e41b0bc3 | ||
|
2c6087e3d2 | ||
|
2d81b78b85 | ||
|
b5eea45a31 | ||
|
aa53e39ec0 | ||
|
4216bf801f | ||
|
2cd1609770 | ||
|
85c9ebf2fc | ||
|
796925089c | ||
|
da91dfc948 | ||
|
4135e34dfa | ||
|
846128a498 | ||
|
e461e60997 | ||
|
28c10330bd | ||
|
0d40590c2c | ||
|
8fda28be35 | ||
|
a54cf2ecef | ||
|
4b9337a01e | ||
|
154497541d | ||
|
e0cfe07648 | ||
|
82be289985 | ||
|
f2190c8fc2 | ||
|
c31648d15d | ||
|
52250e7c1e | ||
|
51a94a2f14 | ||
|
c95bf3db9d | ||
|
4bf3b01953 | ||
|
ff957d1eac | ||
|
83aa110c6f | ||
|
5a1a2edf0e | ||
|
b3419f49a3 | ||
|
141beb2704 | ||
|
4e49d5a0ad | ||
|
2c6be7239f | ||
|
d934296476 | ||
|
39ae286861 | ||
|
59e65d1709 | ||
|
9fdd2cd1a9 | ||
|
e1deda9e04 | ||
|
199a601611 | ||
|
492c6f10fc | ||
|
caa7ab5362 | ||
|
f3e672efd8 | ||
|
02d5dddc00 | ||
|
c789941bba | ||
|
e45b3ced67 | ||
|
5a9af492ae | ||
|
32563abe86 | ||
|
70c7b432ea | ||
|
69dfcaa317 | ||
|
6ee8e3e93b | ||
|
8439369db9 | ||
|
81658eaab3 | ||
|
81aebf8cae | ||
|
fa32f02a43 | ||
|
598e22907e | ||
|
1e826ddd3e | ||
|
a967d7f664 | ||
|
ce450c5bf1 | ||
|
8f5f7a5b5a | ||
|
5ad2828c57 | ||
|
b896b58d6d | ||
|
fef6c5c66b | ||
|
37e062b0ed | ||
|
cf58091736 | ||
|
2aef8b9b4c | ||
|
d96307cbe4 | ||
|
124866e269 | ||
|
ab3d6a7dfe | ||
|
c67dbb28e4 | ||
|
b8bccb4ac5 | ||
|
b6b2f584ec | ||
|
f7bdb39d9e | ||
|
ecd9c3e222 | ||
|
216099d072 | ||
|
fc2e3eae20 | ||
|
f9e7a33019 | ||
|
7c9fa2566f | ||
|
22399a3bc0 | ||
|
ad2508f957 | ||
|
b078599833 | ||
|
1e80207876 | ||
|
464fc2cd18 | ||
|
be8d6d40f6 | ||
|
f0c2353393 | ||
|
a730213c3b | ||
|
399993c6b5 | ||
|
4d318060a2 | ||
|
540d5eed46 | ||
|
7d071ce2bd | ||
|
93aeaa53c9 | ||
|
06f9f346e6 | ||
|
5c48012ad2 | ||
|
a686c9ccd2 | ||
|
9ca5c3b108 | ||
|
bab5b1178d | ||
|
ee8fb0c6e4 | ||
|
0d9d3e79e9 | ||
|
12280f0253 | ||
|
a58731e835 | ||
|
1df45593ed | ||
|
2122e39ce1 | ||
|
e70139428a | ||
|
3d1d75a224 | ||
|
35f08f4231 | ||
|
0ea0343a63 | ||
|
338c083858 | ||
|
671442e89d | ||
|
8d111632f5 | ||
|
fe5acb939a | ||
|
cac492b0e9 | ||
|
ef9b3e173c | ||
|
5a13632afb | ||
|
587100873a | ||
|
27b0595af7 | ||
|
12d5a26fd2 | ||
|
89b7f1503e | ||
|
5711609203 | ||
|
825b7c3eb1 | ||
|
ba96131af0 | ||
|
2c477cf661 | ||
|
986ca73074 | ||
|
288098893c | ||
|
cb9607c284 | ||
|
4bd4f421d3 | ||
|
84432e6b36 | ||
|
1a25414ace | ||
|
3171371498 | ||
|
92105e7862 | ||
|
6ee9f13457 | ||
|
352cae4380 | ||
|
b3b58c08e4 | ||
|
204f0a340d | ||
|
78666b99b8 | ||
|
0bdcf75e25 | ||
|
f1009285d8 | ||
|
f76b3a4685 | ||
|
84ae6e12eb | ||
|
784659565a | ||
|
7ae0c198b3 | ||
|
dc6623728d | ||
|
7541f1ad49 | ||
|
74cbbe5f35 | ||
|
52f0b9e2e3 | ||
|
29c26b88e7 | ||
|
f196b71e4d | ||
|
ab83872134 | ||
|
ad4962c7eb | ||
|
d180ba418c | ||
|
138b7fbd05 | ||
|
e7508783e8 | ||
|
f4d15b1fec | ||
|
355beb53f0 | ||
|
8012fcf333 | ||
|
6bc4556ebd | ||
|
879241c05c | ||
|
3794c62945 | ||
|
5a03daf47f | ||
|
6d5f67a092 | ||
|
cee56d3863 | ||
|
7c4da24465 | ||
|
cdbc84b9a8 | ||
|
b2f895166a | ||
|
ebe68f650a | ||
|
df9fd28f9a | ||
|
e9c49ddd7a | ||
|
f8415019d4 | ||
|
238dd5d2b1 | ||
|
64871a7045 | ||
|
2e95bc0413 | ||
|
4cdbd523e5 | ||
|
b3d7e07f18 | ||
|
30af19d442 | ||
|
5d9146ff37 | ||
|
5cc27f1b3c | ||
|
39ed54a468 | ||
|
b61f91361c | ||
|
3167373512 | ||
|
4cff744438 | ||
|
c3527bea57 | ||
|
de6695792a | ||
|
6e22ccf7b1 | ||
|
8a5f002c41 | ||
|
3ce8c9f338 | ||
|
0d095ae2ff | ||
|
2d7f59424c | ||
|
e256afe31e | ||
|
64cfebc5e7 | ||
|
7a095d0ce2 | ||
|
5052c538d9 | ||
|
22d8c6fd18 | ||
|
71857b87ee | ||
|
6ba400ee0f | ||
|
35e65ea640 | ||
|
d0d986dd0e | ||
|
9685e7dbc2 | ||
|
37f39afb8e | ||
|
dc9f62f393 | ||
|
7055315725 | ||
|
fd995dac78 | ||
|
e5765cdd84 | ||
|
8d0e58f80b | ||
|
8fcd1bfda8 | ||
|
e39e697998 | ||
|
d2dd58eabd | ||
|
c6fc6b173d | ||
|
4590d7877c | ||
|
f577fe4e27 | ||
|
9ed5de00b6 | ||
|
28ffff801b | ||
|
44ef3f5a07 | ||
|
dafbd0dcb0 | ||
|
2ddc78720a | ||
|
7ece30ebc0 | ||
|
3d48f33025 | ||
|
19fd903d40 | ||
|
5732e471ae | ||
|
042297b27b | ||
|
a5cb80b86c | ||
|
7e98db251e | ||
|
bced9077f9 | ||
|
82fed986f9 | ||
|
2c1db7ed35 | ||
|
ea4827a578 | ||
|
55be4d6137 | ||
|
1f18466409 | ||
|
b65a1e3379 | ||
|
87836d79ef | ||
|
c8a12a0852 | ||
|
71b84c2114 | ||
|
edb2660a2e | ||
|
17ec726b49 | ||
|
373b11de11 | ||
|
04a2b74529 | ||
|
fcd98308ba | ||
|
b233089815 | ||
|
201c56f6d3 | ||
|
1e051d71f5 | ||
|
ddc79603f9 | ||
|
dee5ea2335 | ||
|
b1c9f5f144 | ||
|
a542bdf658 | ||
|
96e1b25c8c | ||
|
caf5a16271 | ||
|
936e11fd54 | ||
|
9715ba82aa | ||
|
3c35b90dd3 | ||
|
1d63030665 | ||
|
6a5b41203e | ||
|
fbd310972d | ||
|
3059c9c507 | ||
|
3b18f17d4d | ||
|
72faa1919e | ||
|
f8181f64e2 | ||
|
0045ad87df | ||
|
ceea528eff | ||
|
6c5dc7017c | ||
|
ae0b4fdd92 | ||
|
b3cea4d388 | ||
|
d296081321 | ||
|
177ed7e5de | ||
|
f679125206 | ||
|
58beead14d | ||
|
e1811c37ca | ||
|
a24a6701c8 | ||
|
d108cfa7fc | ||
|
92cb5ebb7c | ||
|
653826572d | ||
|
5a5851bac2 | ||
|
1d4a24dae0 | ||
|
a768ea93fd | ||
|
c95fe6e24b | ||
|
c75168186b | ||
|
3a96c9a8d5 | ||
|
1617b95598 | ||
|
726ae5bf6d | ||
|
3e11b38349 | ||
|
16ed879524 | ||
|
20d7b5d058 | ||
|
11a08b9cfc | ||
|
c2b753d917 | ||
|
6c767072a3 | ||
|
e9cfae7aba | ||
|
7ac0de8350 | ||
|
0b7c0f10ee | ||
|
51f6405b0d | ||
|
6096f8a113 | ||
|
d939f301fa | ||
|
8c4623da80 | ||
|
0faaba04a5 | ||
|
ec7a5ffff1 | ||
|
98afb7b9d0 | ||
|
06bae9dfb7 | ||
|
0b80d1842d | ||
|
d7ec23a5db | ||
|
2cf8ef9520 | ||
|
184471b4bb | ||
|
21898c6049 | ||
|
6a9300e815 | ||
|
ac24f132db | ||
|
cb4aa5bc35 | ||
|
beac539f31 | ||
|
b5d297f02f | ||
|
9056d7ea88 | ||
|
ebd17e4827 | ||
|
7e59c89250 | ||
|
9e4e4d9022 | ||
|
71fd06f843 | ||
|
58e6866d86 | ||
|
c7da124149 | ||
|
21bd90d7d3 | ||
|
c8f96b5b4c | ||
|
ded60365d4 | ||
|
629647dfee | ||
|
4ca3d861f0 | ||
|
069e7a6e24 | ||
|
ac6e34ea06 | ||
|
a308b7507a | ||
|
630e7ff26f | ||
|
3764ab471b | ||
|
a3319c6f8e | ||
|
66c699a701 | ||
|
aaf1e44da9 | ||
|
1ef2307ec4 | ||
|
d42c3ba2dc | ||
|
4b06155873 | ||
|
857d825eeb | ||
|
6b345353e3 | ||
|
ab3b3a8f61 | ||
|
71b82fb1f6 | ||
|
9bd9ea423e | ||
|
99964398e7 | ||
|
7009ebfa69 | ||
|
760e23dd3a | ||
|
c53d9d516a | ||
|
7739e6b466 | ||
|
4881857458 | ||
|
c73d5cb7b6 | ||
|
6458803d21 | ||
|
6e72d781f7 | ||
|
4e926a9ef2 | ||
|
4ba3cfaee9 | ||
|
e655e8a7d5 | ||
|
c34e4e4b39 | ||
|
a678ee6365 | ||
|
49f0ee329d | ||
|
0c9d9a3d94 | ||
|
89e1acb0bb | ||
|
c2ed26b711 | ||
|
42fd392e05 | ||
|
e06447ee88 | ||
|
683dabe5e6 | ||
|
3aff96177c | ||
|
0a915eba8f | ||
|
19dcbc5717 | ||
|
d2a4952956 | ||
|
0c97b21b61 | ||
|
19390b1a91 | ||
|
8dc86051df | ||
|
46d5f9d1bf | ||
|
35e96b8deb | ||
|
2210ea7e3b | ||
|
61a1910f91 | ||
|
27ef73507b | ||
|
2b35fb643e | ||
|
478f6f95f1 | ||
|
44411d2d48 | ||
|
a2175cf71a | ||
|
4606d218c3 | ||
|
d37d0f24e6 | ||
|
321e8d51ed | ||
|
78f4b51757 | ||
|
7d168a2621 | ||
|
931e712eac | ||
|
4ec04209e0 | ||
|
82ddba88a2 | ||
|
52a8cc8d46 | ||
|
d175df8aa3 | ||
|
b003a35fde | ||
|
df1a0f9445 | ||
|
5b07b85838 | ||
|
f320cd203b | ||
|
f78c16f8c6 | ||
|
0c5f47e720 | ||
|
4b5b3d90af | ||
|
2cce4b95cd | ||
|
8e6eb52196 | ||
|
04b633ddf3 | ||
|
b76561a212 | ||
|
51c7589c87 | ||
|
99785382ae | ||
|
dc1690ce0f | ||
|
b6614261ea | ||
|
91e569ca37 | ||
|
0f395c1b11 | ||
|
2b13e7466f | ||
|
0982e47408 | ||
|
b93ebcf42f | ||
|
a08d83ba62 | ||
|
2b7c275ce8 | ||
|
040d0f48a0 | ||
|
724f35a664 | ||
|
6f3872edbd | ||
|
87324e680c | ||
|
c2b908f603 | ||
|
d7734f996f | ||
|
8b68890650 | ||
|
b60406cb9b | ||
|
ce9a9934ec | ||
|
720b2abe17 | ||
|
5983c00b95 | ||
|
6651dd7fd9 | ||
|
acdea31916 | ||
|
10885d349a | ||
|
1c1d09f3e9 | ||
|
0384faeee5 | ||
|
6cca3999c8 | ||
|
69408d384d | ||
|
4aea423f06 | ||
|
6fc8a63041 | ||
|
2583a7c0d1 | ||
|
0ef6e3103c | ||
|
7c052b37c8 | ||
|
d9c475d7f4 | ||
|
c8e57332d1 | ||
|
c045459917 | ||
|
e0f64e63db | ||
|
dddd58a8cd | ||
|
010fd21b20 | ||
|
1802fad2f9 | ||
|
f833d109d1 | ||
|
7225c99903 | ||
|
36178933ed | ||
|
ad0da9a571 | ||
|
6646468125 | ||
|
fee8df6ccf | ||
|
8fa47ac679 | ||
|
b427a2c6cb | ||
|
14d05e7c72 | ||
|
a118a57fe3 | ||
|
02cea3b47e | ||
|
1c2d673ded | ||
|
c34df2c1b6 | ||
|
6092aa977e | ||
|
c9cc2b385a | ||
|
b39d0c521a | ||
|
e87bed6df2 | ||
|
4ee05b3294 | ||
|
e81eb46a78 | ||
|
f315832f75 | ||
|
97ced11e53 | ||
|
4d6c4d36ce | ||
|
b4d53bf194 | ||
|
67bc08d1b9 | ||
|
bcb07de750 | ||
|
7d7cde0fd6 | ||
|
6b25d06d7d | ||
|
cff951c650 | ||
|
114cc3ec02 | ||
|
3c4b7672a8 | ||
|
6de149eb22 | ||
|
da909dd1e8 | ||
|
67986e81ee | ||
|
346bdea946 | ||
|
05c10c5776 | ||
|
b2cb925d99 | ||
|
9fb6502b3b | ||
|
9eb226ff78 | ||
|
e34c4eaf61 | ||
|
9e75bcfc75 | ||
|
d800ec05ff | ||
|
bda53ac6ad | ||
|
4230932563 | ||
|
f17e898bd1 | ||
|
886b2088f1 | ||
|
551d6bb23d | ||
|
d504005e91 | ||
|
2511b5c675 | ||
|
28aba061ec | ||
|
8e37c78ce3 | ||
|
ca68975ff8 | ||
|
529be52fea | ||
|
ca65478c89 | ||
|
a1e9362d38 | ||
|
cbfc69e310 | ||
|
1d7674bb22 | ||
|
e6cc22396a | ||
|
868159fd0a | ||
|
b597fa4637 | ||
|
d2d394eccf | ||
|
438beeabde | ||
|
281f0981a6 | ||
|
6ff346bed9 | ||
|
0925dd588c | ||
|
6f20315dff | ||
|
2e68f22118 | ||
|
8aa860d270 | ||
|
15abade272 | ||
|
7ab8c87281 | ||
|
4ff8f71643 | ||
|
d22abeee86 | ||
|
a33150eb4b | ||
|
fd00b3a186 | ||
|
e8389a4cc0 | ||
|
6078d756bc | ||
|
57c49fe867 | ||
|
c60de1acd4 | ||
|
69b738c097 | ||
|
da0b2a2f31 | ||
|
2378a558a2 | ||
|
f18ed615ae | ||
|
f6656fffb4 | ||
|
aaad7bfd15 | ||
|
0915da8842 | ||
|
0d0e8bde13 | ||
|
838a1ff950 | ||
|
e1315fd40c | ||
|
52a3ab1042 | ||
|
a82e7b765e | ||
|
0ed0fa4d5b | ||
|
ec85fddb9a | ||
|
3a1343a245 | ||
|
9066ee2eb4 | ||
|
40bd21ce63 | ||
|
4633fbec61 | ||
|
25060031a5 | ||
|
c7ae6334b7 | ||
|
eac04882b4 | ||
|
6499fc4f93 | ||
|
04f27a5438 | ||
|
1b3903d6e9 | ||
|
cc05093b0d | ||
|
6436dd4438 | ||
|
26c50c780e | ||
|
01d13b0c49 | ||
|
f15f45a9f8 | ||
|
1b2e149cb4 | ||
|
6136640ec9 | ||
|
95d8423823 | ||
|
de6411c338 | ||
|
e316cf53f6 | ||
|
c107db57db | ||
|
d39d00057c | ||
|
26157e6973 | ||
|
6d22782e8f | ||
|
1836b6740d | ||
|
924a088812 | ||
|
bab575c868 | ||
|
daae3bba50 | ||
|
05fbbbd8dc | ||
|
4c368bcd24 | ||
|
9927b9e642 | ||
|
1b492dffc8 | ||
|
140be1b4b3 | ||
|
79259acc12 | ||
|
5a3bea2d69 | ||
|
30d928591d | ||
|
70a3e62257 | ||
|
6828fba7a0 | ||
|
aa1bda8164 | ||
|
157ea539a2 | ||
|
c3c94c0e0a | ||
|
9d73909075 | ||
|
016c54196e | ||
|
5056bb952d | ||
|
8a6679b3b4 | ||
|
7b6d5ff298 | ||
|
846850914d | ||
|
4e6c513ac2 | ||
|
db9cda6a7d | ||
|
a50b15a9e9 | ||
|
0a25fe9188 | ||
|
2dd5212a79 | ||
|
00e95e1f38 | ||
|
0a0759132c | ||
|
5cf362c7d0 | ||
|
413be1112a | ||
|
8233dc8568 | ||
|
afa8b3bcd9 | ||
|
c518345f40 | ||
|
afe6ac9923 | ||
|
e995c1b532 | ||
|
e36929292e | ||
|
03128f78df | ||
|
7d4a5e654c | ||
|
41ba7a7984 | ||
|
aa471f2d65 | ||
|
d37dfa1bed | ||
|
9f35cc52fe | ||
|
f1fe19bc2b | ||
|
b55bd709ee | ||
|
9833610356 | ||
|
de7fc0011e | ||
|
2e0c767d74 | ||
|
a5379e901c | ||
|
a039d51d5f | ||
|
60b3dceccf | ||
|
c2ac851b90 | ||
|
c976bc6c2c | ||
|
2e834e941f | ||
|
77e5f3167c | ||
|
7e597ae204 | ||
|
c39df91ab9 | ||
|
af1158d105 | ||
|
b739721d9e | ||
|
7711ab6707 | ||
|
d370c32f69 | ||
|
d6a6eca71d | ||
|
39ffc18635 | ||
|
3e972ec84d | ||
|
b5159dfd2f | ||
|
07c2659806 | ||
|
dc83b9e988 | ||
|
8b4bc8270a | ||
|
0ff80653d3 | ||
|
352e1b4c81 | ||
|
aa13727067 | ||
|
595028614b | ||
|
6a3ae5e26a | ||
|
8c334ee078 | ||
|
f60fe2a4f9 | ||
|
b112257bf2 | ||
|
eb88adcd8a | ||
|
950a1ab5af | ||
|
1b9fe55025 | ||
|
2272df9d31 | ||
|
08d85d6d66 | ||
|
b43989207a | ||
|
2eebebf262 | ||
|
8c1fffe106 | ||
|
5e9acbc952 | ||
|
a420ceab50 | ||
|
0e1c649dca | ||
|
67c2124fa9 | ||
|
a635743c6d | ||
|
b5c2412d84 | ||
|
ad2e77d635 | ||
|
a20b10d01f | ||
|
4cc0551948 | ||
|
56130c3689 | ||
|
14f7380308 | ||
|
727449d1e7 | ||
|
80bf2aa559 | ||
|
b9cd0c4331 | ||
|
f77a87137c | ||
|
65dfe8fdce | ||
|
e3bb595d77 | ||
|
a1682b8927 | ||
|
24d91e3b8a | ||
|
ce04a66528 | ||
|
df74b26e5d | ||
|
b6ad663f87 | ||
|
ee31e38dc7 | ||
|
442334641e | ||
|
dfa5ea6360 | ||
|
3e06edeb5d | ||
|
78b050c13c | ||
|
4ad20ffc2c | ||
|
57e6e3bb80 | ||
|
19da197f58 | ||
|
666fae97e6 | ||
|
823fb1118a | ||
|
db1d62e184 | ||
|
d26ffc7fa3 | ||
|
0f3acce042 | ||
|
9eef9f7b02 | ||
|
aff4c787f4 | ||
|
fe3dfbbe90 | ||
|
2ffdc1936c | ||
|
0fe52c63ea | ||
|
28a52197c4 | ||
|
2c0d1cc87b | ||
|
375a251d16 | ||
|
d4b7a9a373 | ||
|
4d67199a4b | ||
|
95766d6241 | ||
|
4cb78a170c | ||
|
2c66b422e7 | ||
|
e571de83e9 | ||
|
4bb89e2cb1 | ||
|
349cadacf6 | ||
|
292ccc4c43 | ||
|
d7413ffd2d | ||
|
50729a2e73 | ||
|
a3e3f0b9ed | ||
|
45aea23355 | ||
|
975b459c17 | ||
|
2b35faee06 | ||
|
84818bdbb5 | ||
|
895902b57a | ||
|
7d4184dc5c | ||
|
8278f0a6be | ||
|
d3969634ac | ||
|
735ca9ccd6 | ||
|
4ee661d908 | ||
|
9fce8215b7 | ||
|
6521c2dd41 | ||
|
9ee9ce7e14 | ||
|
9d39da6452 | ||
|
0228dcd58f | ||
|
3d35ea99bb | ||
|
0680c76a6f | ||
|
c3e5f5cc9a | ||
|
1c620d27d8 | ||
|
fde45ebed8 | ||
|
4bd0d33f57 | ||
|
00255728aa | ||
|
4b0328f209 | ||
|
30561a0161 | ||
|
a4c4998c8b | ||
|
8e053b6476 | ||
|
b79b5facb1 | ||
|
c53f0fca91 | ||
|
c225e1afc2 | ||
|
92e55c7c53 | ||
|
c86f131681 | ||
|
e943234d09 | ||
|
9fc24e371b | ||
|
cac467d52c | ||
|
04f17d2669 | ||
|
dff15a02f7 | ||
|
42277b1110 | ||
|
095f9e143e | ||
|
9fbb2ebb90 | ||
|
dbcf87ce76 | ||
|
4250c26e9b | ||
|
e48de30516 | ||
|
1f0060caa3 | ||
|
c732cc90ab | ||
|
4e2c5b5f25 | ||
|
d9386a0c07 | ||
|
66e16c92d3 | ||
|
6a8e176df1 | ||
|
632c7f3410 | ||
|
045f1840e0 | ||
|
45d16d090b | ||
|
525c5ff4d8 | ||
|
5952157c3b | ||
|
f777d21899 | ||
|
82064af2d7 | ||
|
d54444cfd7 | ||
|
525ef3c178 | ||
|
5ef6ef1bac | ||
|
f4208e7cac | ||
|
ecc95c903b | ||
|
a207949b65 | ||
|
86d12249dd | ||
|
b098c94ed4 | ||
|
6a39a496d0 | ||
|
3d73084b5e | ||
|
12b1d439e4 | ||
|
1076161bf3 | ||
|
e21d93b7bd | ||
|
f504aea132 | ||
|
9955ddc978 | ||
|
0dfe729f90 | ||
|
8f698bd4cc | ||
|
99b126d0af | ||
|
a2d56f6dce | ||
|
db876f9fb0 | ||
|
05a618b06e | ||
|
72608f0d5a | ||
|
bba044de4f | ||
|
4d55eee754 | ||
|
d41b232b52 | ||
|
b35575574b | ||
|
666b4563a0 | ||
|
7315bb08ad | ||
|
f80688f1c7 | ||
|
dc5c070c44 | ||
|
8cc7f3bace | ||
|
5d3fd3707b | ||
|
1bf0c4a8e7 | ||
|
863656d2bc | ||
|
f1a34ae1e4 | ||
|
3000cad507 | ||
|
0f8249f262 | ||
|
b515765216 | ||
|
85e6d59956 | ||
|
95e8d12b71 | ||
|
a55f0e12fe | ||
|
0cf3ba0eab | ||
|
1d85225952 | ||
|
3af6434085 | ||
|
57871415c1 | ||
|
52021851d1 | ||
|
080a38d62d | ||
|
ab7a11c0c7 | ||
|
d8675f6f30 | ||
|
eff4478c2d | ||
|
81683351f0 | ||
|
b38905b004 | ||
|
d9a6a3b5d2 | ||
|
7c2e3bb67d | ||
|
b01a51a844 | ||
|
77f8c075c4 | ||
|
33b4821cd6 | ||
|
a73a882806 | ||
|
57416beefe | ||
|
1b63f832c5 | ||
|
7b5638f61d | ||
|
937cabfa0a | ||
|
deba5069e5 | ||
|
956113b295 | ||
|
db98a7d60f | ||
|
0464e42231 | ||
|
4970ef938e | ||
|
f85b163899 | ||
|
2b66f7afb1 | ||
|
67b3083dfd | ||
|
0c7bcc24cb | ||
|
98c6a92eb5 | ||
|
ba59bc8b9f | ||
|
cd8d8e1208 | ||
|
04eb016e78 | ||
|
0a4342098b | ||
|
72707c2fae | ||
|
06dc514bc7 | ||
|
2b5553b1eb | ||
|
4688ad181d | ||
|
dc5d967ee6 | ||
|
fe3756c8e1 | ||
|
01b151f5f8 | ||
|
8bb4a93f2b | ||
|
5ec04b7726 | ||
|
3657eaedf3 | ||
|
9291283a18 | ||
|
eccd02def2 | ||
|
11737233a7 | ||
|
bcaf6a7a0f | ||
|
f95eed34b4 | ||
|
1eaffa372f | ||
|
b1697e8d5f | ||
|
801d11c7e7 | ||
|
1b855fccd7 | ||
|
d34b4c7b9a | ||
|
1f9614f82e | ||
|
4491bdda69 | ||
|
8af1d97332 | ||
|
79cd408844 | ||
|
18be893b66 | ||
|
0fb1842fd0 | ||
|
f522930a99 | ||
|
aebd745f72 | ||
|
c53980cddc | ||
|
95e56ffc0d | ||
|
f1294353f2 | ||
|
6649dcce6d | ||
|
58f2fe3f6a | ||
|
0aaa9a21f3 | ||
|
4f8b08d330 | ||
|
849e631510 | ||
|
789717d109 | ||
|
605630c145 | ||
|
1e7e57dad3 | ||
|
eb184e02ea | ||
|
ed41473634 | ||
|
ee5ba14431 | ||
|
b706893e0a | ||
|
bf35794507 | ||
|
e743836541 | ||
|
0c3544d42f | ||
|
94f7c2707b | ||
|
901b3ed9b7 | ||
|
e6cbe9c11e | ||
|
f60c597d65 | ||
|
c09bf8da07 | ||
|
adaa28a6e6 | ||
|
dba23062ba | ||
|
c0705eeb65 | ||
|
29355bd382 | ||
|
91a1f6926e | ||
|
54775e0b3e | ||
|
59b4a5e4ca | ||
|
82384e385e |
19
LICENSE
19
LICENSE
@ -1,6 +1,23 @@
|
|||||||
MIT/X Consortium License
|
MIT/X Consortium License
|
||||||
|
|
||||||
(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
|
||||||
|
© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
|
||||||
|
© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
|
||||||
|
© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
|
||||||
|
© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
|
||||||
|
© 2007-2009 Christof Musik <christof at sendfax dot de>
|
||||||
|
© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
|
||||||
|
© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
|
||||||
|
© 2008 Martin Hurton <martin dot hurton at gmail dot com>
|
||||||
|
© 2008 Neale Pickett <neale dot woozle dot org>
|
||||||
|
© 2009 Mate Nagy <mnagy at port70 dot net>
|
||||||
|
© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
|
||||||
|
© 2010-2012 Connor Lane Smith <cls@lubutu.com>
|
||||||
|
© 2011 Christoph Lohmann <20h@r-36.net>
|
||||||
|
© 2015-2016 Quentin Rameau <quinq@fifth.space>
|
||||||
|
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
|
||||||
|
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
|
||||||
|
© 2020-2022 Chris Down <chris@chrisdown.name>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
54
Makefile
54
Makefile
@ -1,55 +1,45 @@
|
|||||||
# dwm - dynamic window manager
|
# dwm - dynamic window manager
|
||||||
# (C)opyright MMVI Anselm R. Garbe
|
# See LICENSE file for copyright and license details.
|
||||||
|
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
SRC = bar.c client.c dev.c draw.c event.c main.c util.c
|
SRC = drw.c dwm.c util.c
|
||||||
OBJ = ${SRC:.c=.o}
|
OBJ = ${SRC:.c=.o}
|
||||||
MAN1 = dwm.1
|
|
||||||
BIN = dwm
|
|
||||||
|
|
||||||
all: config dwm
|
all: dwm
|
||||||
@echo finished
|
|
||||||
|
|
||||||
config:
|
|
||||||
@echo dwm build options:
|
|
||||||
@echo "LIBS = ${LIBS}"
|
|
||||||
@echo "CFLAGS = ${CFLAGS}"
|
|
||||||
@echo "LDFLAGS = ${LDFLAGS}"
|
|
||||||
@echo "CC = ${CC}"
|
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
@echo CC $<
|
${CC} -c ${CFLAGS} $<
|
||||||
@${CC} -c ${CFLAGS} $<
|
|
||||||
|
|
||||||
${OBJ}: dwm.h
|
${OBJ}: config.h config.mk
|
||||||
|
|
||||||
|
config.h:
|
||||||
|
cp config.def.h $@
|
||||||
|
|
||||||
dwm: ${OBJ}
|
dwm: ${OBJ}
|
||||||
@echo LD $@
|
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||||
@${CC} -o $@ ${OBJ} ${LDFLAGS}
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f dwm *.o core
|
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
|
||||||
|
|
||||||
dist: clean
|
dist: clean
|
||||||
mkdir -p dwm-${VERSION}
|
mkdir -p dwm-${VERSION}
|
||||||
cp -R Makefile README LICENSE config.mk *.h *.c ${MAN1} dwm-${VERSION}
|
cp -R LICENSE Makefile README config.def.h config.mk\
|
||||||
|
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
|
||||||
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
|
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
|
||||||
gzip dwm-${VERSION}.tar
|
gzip dwm-${VERSION}.tar
|
||||||
rm -rf dwm-${VERSION}
|
rm -rf dwm-${VERSION}
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
@mkdir -p ${DESTDIR}${PREFIX}/bin
|
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||||
@cp -f ${BIN} ${DESTDIR}${PREFIX}/bin
|
cp -f dwm ${DESTDIR}${PREFIX}/bin
|
||||||
@echo installed executable files to ${DESTDIR}${PREFIX}/bin
|
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
|
||||||
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||||
@cp -f ${MAN1} ${DESTDIR}${MANPREFIX}/man1
|
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||||
@echo installed manual pages to ${DESTDIR}${MANPREFIX}/man1
|
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
for i in ${BIN}; do \
|
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
|
||||||
rm -f ${DESTDIR}${PREFIX}/bin/`basename $$i`; \
|
${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||||
done
|
|
||||||
for i in ${MAN1}; do \
|
.PHONY: all clean dist install uninstall
|
||||||
rm -f ${DESTDIR}${MANPREFIX}/man1/`basename $$i`; \
|
|
||||||
done
|
|
||||||
|
24
README
24
README
@ -1,7 +1,6 @@
|
|||||||
dwm - dynamic window manager
|
dwm - dynamic window manager
|
||||||
----------------------------
|
============================
|
||||||
|
dwm is an extremely fast, small, and dynamic window manager for X.
|
||||||
dwm is an extremly fast, small, and dynamic X11 window manager.
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
@ -11,8 +10,8 @@ In order to build dwm you need the Xlib header files.
|
|||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
Edit config.mk to match your local setup. dwm is installed into
|
Edit config.mk to match your local setup (dwm is installed into
|
||||||
the /usr/local namespace by default.
|
the /usr/local namespace by default).
|
||||||
|
|
||||||
Afterwards enter the following command to build and install dwm (if
|
Afterwards enter the following command to build and install dwm (if
|
||||||
necessary as root):
|
necessary as root):
|
||||||
@ -31,10 +30,19 @@ the DISPLAY environment variable is set correctly, e.g.:
|
|||||||
|
|
||||||
DISPLAY=foo.bar:1 exec dwm
|
DISPLAY=foo.bar:1 exec dwm
|
||||||
|
|
||||||
This will start dwm on display :1 of the host foo.bar.
|
(This will start dwm on display :1 of the host foo.bar.)
|
||||||
|
|
||||||
|
In order to display status info in the bar, you can do something
|
||||||
|
like this in your .xinitrc:
|
||||||
|
|
||||||
|
while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
done &
|
||||||
|
exec dwm
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
The configuration of dwm is done by customizing the wm.h source file. To
|
The configuration of dwm is done by creating a custom config.h
|
||||||
customize the key bindings edit dev.c.
|
and (re)compiling the source code.
|
||||||
|
1
TODO
1
TODO
@ -1 +0,0 @@
|
|||||||
- improve mouse based resizals with quadrant approach (then I think we have feature completeness already)
|
|
46
bar.c
46
bar.c
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
|
||||||
* See LICENSE file for license details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dwm.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
barclick(XButtonPressedEvent *e)
|
|
||||||
{
|
|
||||||
int x = 0;
|
|
||||||
Arg a;
|
|
||||||
for(a.i = 0; a.i < TLast; a.i++) {
|
|
||||||
x += textw(tags[a.i]) + dc.font.height;
|
|
||||||
if(e->x < x) {
|
|
||||||
view(&a);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
draw_bar()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
dc.x = dc.y = 0;
|
|
||||||
dc.w = bw;
|
|
||||||
drawtext(NULL, False, False);
|
|
||||||
|
|
||||||
dc.w = 0;
|
|
||||||
for(i = 0; i < TLast; i++) {
|
|
||||||
dc.x += dc.w;
|
|
||||||
dc.w = textw(tags[i]) + dc.font.height;
|
|
||||||
drawtext(tags[i], i == tsel, True);
|
|
||||||
}
|
|
||||||
if(sel) {
|
|
||||||
dc.x += dc.w;
|
|
||||||
dc.w = textw(sel->name) + dc.font.height;
|
|
||||||
drawtext(sel->name, True, True);
|
|
||||||
}
|
|
||||||
dc.w = textw(stext) + dc.font.height;
|
|
||||||
dc.x = bx + bw - dc.w;
|
|
||||||
drawtext(stext, False, False);
|
|
||||||
XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
|
|
||||||
XFlush(dpy);
|
|
||||||
}
|
|
616
client.c
616
client.c
@ -1,616 +0,0 @@
|
|||||||
/*
|
|
||||||
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
|
||||||
* See LICENSE file for license details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <X11/Xatom.h>
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
|
|
||||||
#include "dwm.h"
|
|
||||||
|
|
||||||
void (*arrange)(Arg *) = tiling;
|
|
||||||
|
|
||||||
static Rule rule[] = {
|
|
||||||
/* class instance tags floating */
|
|
||||||
{ "Firefox-bin", "Gecko", { [Twww] = "www" }, False },
|
|
||||||
};
|
|
||||||
|
|
||||||
static Client *
|
|
||||||
next(Client *c)
|
|
||||||
{
|
|
||||||
for(; c && !c->tags[tsel]; c = c->next);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
zoom(Arg *arg)
|
|
||||||
{
|
|
||||||
Client **l, *c;
|
|
||||||
|
|
||||||
if(!sel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(sel == next(clients) && sel->next) {
|
|
||||||
if((c = next(sel->next)))
|
|
||||||
sel = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(l = &clients; *l && *l != sel; l = &(*l)->next);
|
|
||||||
*l = sel->next;
|
|
||||||
|
|
||||||
sel->next = clients; /* pop */
|
|
||||||
clients = sel;
|
|
||||||
arrange(NULL);
|
|
||||||
focus(sel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
max(Arg *arg)
|
|
||||||
{
|
|
||||||
if(!sel)
|
|
||||||
return;
|
|
||||||
sel->x = sx;
|
|
||||||
sel->y = sy + bh;
|
|
||||||
sel->w = sw - 2 * sel->border;
|
|
||||||
sel->h = sh - 2 * sel->border - bh;
|
|
||||||
craise(sel);
|
|
||||||
resize(sel, False);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
view(Arg *arg)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
tsel = arg->i;
|
|
||||||
arrange(NULL);
|
|
||||||
|
|
||||||
for(c = clients; c; c = next(c->next))
|
|
||||||
draw_client(c);
|
|
||||||
draw_bar();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
tappend(Arg *arg)
|
|
||||||
{
|
|
||||||
if(!sel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sel->tags[arg->i] = tags[arg->i];
|
|
||||||
arrange(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ttrunc(Arg *arg)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if(!sel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(i = 0; i < TLast; i++)
|
|
||||||
sel->tags[i] = NULL;
|
|
||||||
tappend(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ban_client(Client *c)
|
|
||||||
{
|
|
||||||
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
|
|
||||||
XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
floating(Arg *arg)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
arrange = floating;
|
|
||||||
for(c = clients; c; c = c->next) {
|
|
||||||
if(c->tags[tsel])
|
|
||||||
resize(c, True);
|
|
||||||
else
|
|
||||||
ban_client(c);
|
|
||||||
}
|
|
||||||
if(sel && !sel->tags[tsel]) {
|
|
||||||
if((sel = next(clients))) {
|
|
||||||
craise(sel);
|
|
||||||
focus(sel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
tiling(Arg *arg)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
int n, i, w, h;
|
|
||||||
|
|
||||||
w = sw - mw;
|
|
||||||
arrange = tiling;
|
|
||||||
for(n = 0, c = clients; c; c = c->next)
|
|
||||||
if(c->tags[tsel] && !c->floating)
|
|
||||||
n++;
|
|
||||||
|
|
||||||
if(n > 1)
|
|
||||||
h = (sh - bh) / (n - 1);
|
|
||||||
else
|
|
||||||
h = sh - bh;
|
|
||||||
|
|
||||||
for(i = 0, c = clients; c; c = c->next) {
|
|
||||||
if(c->tags[tsel]) {
|
|
||||||
if(c->floating) {
|
|
||||||
craise(c);
|
|
||||||
resize(c, True);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(n == 1) {
|
|
||||||
c->x = sx;
|
|
||||||
c->y = sy + bh;
|
|
||||||
c->w = sw - 2 * c->border;
|
|
||||||
c->h = sh - 2 * c->border - bh;
|
|
||||||
}
|
|
||||||
else if(i == 0) {
|
|
||||||
c->x = sx;
|
|
||||||
c->y = sy + bh;
|
|
||||||
c->w = mw - 2 * c->border;
|
|
||||||
c->h = sh - 2 * c->border - bh;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c->x = sx + mw;
|
|
||||||
c->y = sy + (i - 1) * h + bh;
|
|
||||||
c->w = w - 2 * c->border;
|
|
||||||
c->h = h - 2 * c->border;
|
|
||||||
}
|
|
||||||
resize(c, False);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ban_client(c);
|
|
||||||
}
|
|
||||||
if(!sel || (sel && !sel->tags[tsel])) {
|
|
||||||
if((sel = next(clients))) {
|
|
||||||
craise(sel);
|
|
||||||
focus(sel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
prevc(Arg *arg)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
if(!sel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
|
|
||||||
craise(c);
|
|
||||||
focus(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nextc(Arg *arg)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
if(!sel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!(c = next(sel->next)))
|
|
||||||
c = next(clients);
|
|
||||||
if(c) {
|
|
||||||
craise(c);
|
|
||||||
c->revert = sel;
|
|
||||||
focus(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ckill(Arg *arg)
|
|
||||||
{
|
|
||||||
if(!sel)
|
|
||||||
return;
|
|
||||||
if(sel->proto & WM_PROTOCOL_DELWIN)
|
|
||||||
send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
|
|
||||||
else
|
|
||||||
XKillClient(dpy, sel->win);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
resize_title(Client *c)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
c->tw = 0;
|
|
||||||
for(i = 0; i < TLast; i++)
|
|
||||||
if(c->tags[i])
|
|
||||||
c->tw += textw(c->tags[i]) + dc.font.height;
|
|
||||||
c->tw += textw(c->name) + dc.font.height;
|
|
||||||
if(c->tw > c->w)
|
|
||||||
c->tw = c->w + 2;
|
|
||||||
c->tx = c->x + c->w - c->tw + 2;
|
|
||||||
c->ty = c->y;
|
|
||||||
XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
update_name(Client *c)
|
|
||||||
{
|
|
||||||
XTextProperty name;
|
|
||||||
int n;
|
|
||||||
char **list = NULL;
|
|
||||||
|
|
||||||
name.nitems = 0;
|
|
||||||
c->name[0] = 0;
|
|
||||||
XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]);
|
|
||||||
if(!name.nitems)
|
|
||||||
XGetWMName(dpy, c->win, &name);
|
|
||||||
if(!name.nitems)
|
|
||||||
return;
|
|
||||||
if(name.encoding == XA_STRING)
|
|
||||||
strncpy(c->name, (char *)name.value, sizeof(c->name));
|
|
||||||
else {
|
|
||||||
if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
|
|
||||||
&& n > 0 && *list)
|
|
||||||
{
|
|
||||||
strncpy(c->name, *list, sizeof(c->name));
|
|
||||||
XFreeStringList(list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
XFree(name.value);
|
|
||||||
resize_title(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
update_size(Client *c)
|
|
||||||
{
|
|
||||||
XSizeHints size;
|
|
||||||
long msize;
|
|
||||||
if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags)
|
|
||||||
size.flags = PSize;
|
|
||||||
c->flags = size.flags;
|
|
||||||
if(c->flags & PBaseSize) {
|
|
||||||
c->basew = size.base_width;
|
|
||||||
c->baseh = size.base_height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c->basew = c->baseh = 0;
|
|
||||||
if(c->flags & PResizeInc) {
|
|
||||||
c->incw = size.width_inc;
|
|
||||||
c->inch = size.height_inc;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c->incw = c->inch = 0;
|
|
||||||
if(c->flags & PMaxSize) {
|
|
||||||
c->maxw = size.max_width;
|
|
||||||
c->maxh = size.max_height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c->maxw = c->maxh = 0;
|
|
||||||
if(c->flags & PMinSize) {
|
|
||||||
c->minw = size.min_width;
|
|
||||||
c->minh = size.min_height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c->minw = c->minh = 0;
|
|
||||||
if(c->flags & PWinGravity)
|
|
||||||
c->grav = size.win_gravity;
|
|
||||||
else
|
|
||||||
c->grav = NorthWestGravity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
craise(Client *c)
|
|
||||||
{
|
|
||||||
XRaiseWindow(dpy, c->win);
|
|
||||||
XRaiseWindow(dpy, c->title);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
lower(Client *c)
|
|
||||||
{
|
|
||||||
XLowerWindow(dpy, c->title);
|
|
||||||
XLowerWindow(dpy, c->win);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
focus(Client *c)
|
|
||||||
{
|
|
||||||
Client *old = sel;
|
|
||||||
XEvent ev;
|
|
||||||
|
|
||||||
XFlush(dpy);
|
|
||||||
sel = c;
|
|
||||||
if(old && old != c)
|
|
||||||
draw_client(old);
|
|
||||||
draw_client(c);
|
|
||||||
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
|
|
||||||
XFlush(dpy);
|
|
||||||
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
init_tags(Client *c)
|
|
||||||
{
|
|
||||||
XClassHint ch;
|
|
||||||
static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
|
|
||||||
unsigned int i, j;
|
|
||||||
Bool matched = False;
|
|
||||||
|
|
||||||
if(!len) {
|
|
||||||
c->tags[tsel] = tags[tsel];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(XGetClassHint(dpy, c->win, &ch)) {
|
|
||||||
if(ch.res_class && ch.res_name) {
|
|
||||||
for(i = 0; i < len; i++)
|
|
||||||
if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
|
|
||||||
&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
|
|
||||||
{
|
|
||||||
for(j = 0; j < TLast; j++)
|
|
||||||
c->tags[j] = rule[i].tags[j];
|
|
||||||
c->floating = rule[i].floating;
|
|
||||||
matched = True;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(ch.res_class)
|
|
||||||
XFree(ch.res_class);
|
|
||||||
if(ch.res_name)
|
|
||||||
XFree(ch.res_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!matched)
|
|
||||||
c->tags[tsel] = tags[tsel];
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
manage(Window w, XWindowAttributes *wa)
|
|
||||||
{
|
|
||||||
Client *c, **l;
|
|
||||||
XSetWindowAttributes twa;
|
|
||||||
Window trans;
|
|
||||||
|
|
||||||
c = emallocz(sizeof(Client));
|
|
||||||
c->win = w;
|
|
||||||
c->tx = c->x = wa->x;
|
|
||||||
c->ty = c->y = wa->y;
|
|
||||||
if(c->y < bh)
|
|
||||||
c->ty = c->y += bh;
|
|
||||||
c->tw = c->w = wa->width;
|
|
||||||
c->h = wa->height;
|
|
||||||
c->th = bh;
|
|
||||||
c->border = 1;
|
|
||||||
c->proto = win_proto(c->win);
|
|
||||||
update_size(c);
|
|
||||||
XSelectInput(dpy, c->win,
|
|
||||||
StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
|
|
||||||
XGetTransientForHint(dpy, c->win, &trans);
|
|
||||||
twa.override_redirect = 1;
|
|
||||||
twa.background_pixmap = ParentRelative;
|
|
||||||
twa.event_mask = ExposureMask;
|
|
||||||
|
|
||||||
c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
|
|
||||||
0, DefaultDepth(dpy, screen), CopyFromParent,
|
|
||||||
DefaultVisual(dpy, screen),
|
|
||||||
CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
|
|
||||||
|
|
||||||
update_name(c);
|
|
||||||
init_tags(c);
|
|
||||||
|
|
||||||
for(l = &clients; *l; l = &(*l)->next);
|
|
||||||
c->next = *l; /* *l == nil */
|
|
||||||
*l = c;
|
|
||||||
|
|
||||||
XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
|
|
||||||
GrabModeAsync, GrabModeSync, None, None);
|
|
||||||
XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask,
|
|
||||||
GrabModeAsync, GrabModeSync, None, None);
|
|
||||||
XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
|
|
||||||
GrabModeAsync, GrabModeSync, None, None);
|
|
||||||
|
|
||||||
if(!c->floating)
|
|
||||||
c->floating = trans
|
|
||||||
|| ((c->maxw == c->minw) && (c->maxh == c->minh));
|
|
||||||
|
|
||||||
arrange(NULL);
|
|
||||||
/* mapping the window now prevents flicker */
|
|
||||||
if(c->tags[tsel]) {
|
|
||||||
XMapRaised(dpy, c->win);
|
|
||||||
XMapRaised(dpy, c->title);
|
|
||||||
focus(c);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ban_client(c);
|
|
||||||
XMapRaised(dpy, c->win);
|
|
||||||
XMapRaised(dpy, c->title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gravitate(Client *c, Bool invert)
|
|
||||||
{
|
|
||||||
int dx = 0, dy = 0;
|
|
||||||
|
|
||||||
switch(c->grav) {
|
|
||||||
case StaticGravity:
|
|
||||||
case NorthWestGravity:
|
|
||||||
case NorthGravity:
|
|
||||||
case NorthEastGravity:
|
|
||||||
dy = c->border;
|
|
||||||
break;
|
|
||||||
case EastGravity:
|
|
||||||
case CenterGravity:
|
|
||||||
case WestGravity:
|
|
||||||
dy = -(c->h / 2) + c->border;
|
|
||||||
break;
|
|
||||||
case SouthEastGravity:
|
|
||||||
case SouthGravity:
|
|
||||||
case SouthWestGravity:
|
|
||||||
dy = -c->h;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (c->grav) {
|
|
||||||
case StaticGravity:
|
|
||||||
case NorthWestGravity:
|
|
||||||
case WestGravity:
|
|
||||||
case SouthWestGravity:
|
|
||||||
dx = c->border;
|
|
||||||
break;
|
|
||||||
case NorthGravity:
|
|
||||||
case CenterGravity:
|
|
||||||
case SouthGravity:
|
|
||||||
dx = -(c->w / 2) + c->border;
|
|
||||||
break;
|
|
||||||
case NorthEastGravity:
|
|
||||||
case EastGravity:
|
|
||||||
case SouthEastGravity:
|
|
||||||
dx = -(c->w + c->border);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(invert) {
|
|
||||||
dx = -dx;
|
|
||||||
dy = -dy;
|
|
||||||
}
|
|
||||||
c->x += dx;
|
|
||||||
c->y += dy;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
resize(Client *c, Bool inc)
|
|
||||||
{
|
|
||||||
XConfigureEvent e;
|
|
||||||
|
|
||||||
if(inc) {
|
|
||||||
if(c->incw)
|
|
||||||
c->w -= (c->w - c->basew) % c->incw;
|
|
||||||
if(c->inch)
|
|
||||||
c->h -= (c->h - c->baseh) % c->inch;
|
|
||||||
}
|
|
||||||
if(c->x > sw) /* might happen on restart */
|
|
||||||
c->x = sw - c->w;
|
|
||||||
if(c->y > sh)
|
|
||||||
c->ty = c->y = sh - c->h;
|
|
||||||
if(c->minw && c->w < c->minw)
|
|
||||||
c->w = c->minw;
|
|
||||||
if(c->minh && c->h < c->minh)
|
|
||||||
c->h = c->minh;
|
|
||||||
if(c->maxw && c->w > c->maxw)
|
|
||||||
c->w = c->maxw;
|
|
||||||
if(c->maxh && c->h > c->maxh)
|
|
||||||
c->h = c->maxh;
|
|
||||||
resize_title(c);
|
|
||||||
XSetWindowBorderWidth(dpy, c->win, 1);
|
|
||||||
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
|
|
||||||
e.type = ConfigureNotify;
|
|
||||||
e.event = c->win;
|
|
||||||
e.window = c->win;
|
|
||||||
e.x = c->x;
|
|
||||||
e.y = c->y;
|
|
||||||
e.width = c->w;
|
|
||||||
e.height = c->h;
|
|
||||||
e.border_width = c->border;
|
|
||||||
e.above = None;
|
|
||||||
e.override_redirect = False;
|
|
||||||
XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e);
|
|
||||||
XFlush(dpy);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
dummy_error_handler(Display *dsply, XErrorEvent *err)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
unmanage(Client *c)
|
|
||||||
{
|
|
||||||
Client **l;
|
|
||||||
|
|
||||||
XGrabServer(dpy);
|
|
||||||
XSetErrorHandler(dummy_error_handler);
|
|
||||||
|
|
||||||
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
|
|
||||||
XDestroyWindow(dpy, c->title);
|
|
||||||
|
|
||||||
for(l = &clients; *l && *l != c; l = &(*l)->next);
|
|
||||||
*l = c->next;
|
|
||||||
for(l = &clients; *l; l = &(*l)->next)
|
|
||||||
if((*l)->revert == c)
|
|
||||||
(*l)->revert = NULL;
|
|
||||||
if(sel == c)
|
|
||||||
sel = sel->revert ? sel->revert : clients;
|
|
||||||
|
|
||||||
free(c);
|
|
||||||
|
|
||||||
XFlush(dpy);
|
|
||||||
XSetErrorHandler(error_handler);
|
|
||||||
XUngrabServer(dpy);
|
|
||||||
arrange(NULL);
|
|
||||||
if(sel)
|
|
||||||
focus(sel);
|
|
||||||
}
|
|
||||||
|
|
||||||
Client *
|
|
||||||
gettitle(Window w)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
for(c = clients; c; c = c->next)
|
|
||||||
if(c->title == w)
|
|
||||||
return c;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Client *
|
|
||||||
getclient(Window w)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
for(c = clients; c; c = c->next)
|
|
||||||
if(c->win == w)
|
|
||||||
return c;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
draw_client(Client *c)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if(c == sel) {
|
|
||||||
draw_bar();
|
|
||||||
XUnmapWindow(dpy, c->title);
|
|
||||||
XSetWindowBorder(dpy, c->win, dc.fg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
XSetWindowBorder(dpy, c->win, dc.bg);
|
|
||||||
XMapWindow(dpy, c->title);
|
|
||||||
|
|
||||||
dc.x = dc.y = 0;
|
|
||||||
|
|
||||||
dc.w = 0;
|
|
||||||
for(i = 0; i < TLast; i++) {
|
|
||||||
if(c->tags[i]) {
|
|
||||||
dc.x += dc.w;
|
|
||||||
dc.w = textw(c->tags[i]) + dc.font.height;
|
|
||||||
drawtext(c->tags[i], False, True);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dc.x += dc.w;
|
|
||||||
dc.w = textw(c->name) + dc.font.height;
|
|
||||||
drawtext(c->name, False, True);
|
|
||||||
XCopyArea(dpy, dc.drawable, c->title, dc.gc,
|
|
||||||
0, 0, c->tw, c->th, 0, 0);
|
|
||||||
XFlush(dpy);
|
|
||||||
}
|
|
116
config.def.h
Normal file
116
config.def.h
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
|
/* appearance */
|
||||||
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
|
static const unsigned int snap = 32; /* snap pixel */
|
||||||
|
static const int showbar = 1; /* 0 means no bar */
|
||||||
|
static const int topbar = 1; /* 0 means bottom bar */
|
||||||
|
static const char *fonts[] = { "monospace:size=10" };
|
||||||
|
static const char dmenufont[] = "monospace:size=10";
|
||||||
|
static const char col_gray1[] = "#222222";
|
||||||
|
static const char col_gray2[] = "#444444";
|
||||||
|
static const char col_gray3[] = "#bbbbbb";
|
||||||
|
static const char col_gray4[] = "#eeeeee";
|
||||||
|
static const char col_cyan[] = "#005577";
|
||||||
|
static const char *colors[][3] = {
|
||||||
|
/* fg bg border */
|
||||||
|
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||||
|
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* tagging */
|
||||||
|
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||||
|
|
||||||
|
static const Rule rules[] = {
|
||||||
|
/* xprop(1):
|
||||||
|
* WM_CLASS(STRING) = instance, class
|
||||||
|
* WM_NAME(STRING) = title
|
||||||
|
*/
|
||||||
|
/* class instance title tags mask isfloating monitor */
|
||||||
|
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
||||||
|
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* layout(s) */
|
||||||
|
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
||||||
|
static const int nmaster = 1; /* number of clients in master area */
|
||||||
|
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||||
|
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
||||||
|
|
||||||
|
static const Layout layouts[] = {
|
||||||
|
/* symbol arrange function */
|
||||||
|
{ "[]=", tile }, /* first entry is default */
|
||||||
|
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||||
|
{ "[M]", monocle },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* key definitions */
|
||||||
|
#define MODKEY Mod1Mask
|
||||||
|
#define TAGKEYS(KEY,TAG) \
|
||||||
|
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
||||||
|
|
||||||
|
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||||
|
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||||
|
|
||||||
|
/* commands */
|
||||||
|
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||||
|
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
|
||||||
|
static const char *termcmd[] = { "st", NULL };
|
||||||
|
|
||||||
|
static const Key keys[] = {
|
||||||
|
/* modifier key function argument */
|
||||||
|
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||||
|
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
||||||
|
{ MODKEY, XK_b, togglebar, {0} },
|
||||||
|
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||||
|
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||||
|
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
||||||
|
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
|
||||||
|
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
||||||
|
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
||||||
|
{ MODKEY, XK_Return, zoom, {0} },
|
||||||
|
{ MODKEY, XK_Tab, view, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
||||||
|
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||||
|
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
||||||
|
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
||||||
|
{ MODKEY, XK_space, setlayout, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
||||||
|
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
|
||||||
|
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
|
||||||
|
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
||||||
|
TAGKEYS( XK_1, 0)
|
||||||
|
TAGKEYS( XK_2, 1)
|
||||||
|
TAGKEYS( XK_3, 2)
|
||||||
|
TAGKEYS( XK_4, 3)
|
||||||
|
TAGKEYS( XK_5, 4)
|
||||||
|
TAGKEYS( XK_6, 5)
|
||||||
|
TAGKEYS( XK_7, 6)
|
||||||
|
TAGKEYS( XK_8, 7)
|
||||||
|
TAGKEYS( XK_9, 8)
|
||||||
|
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* button definitions */
|
||||||
|
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
|
||||||
|
static const Button buttons[] = {
|
||||||
|
/* click event mask button function argument */
|
||||||
|
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
|
||||||
|
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
|
||||||
|
{ ClkWinTitle, 0, Button2, zoom, {0} },
|
||||||
|
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
|
||||||
|
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
||||||
|
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
|
||||||
|
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
|
||||||
|
{ ClkTagBar, 0, Button1, view, {0} },
|
||||||
|
{ ClkTagBar, 0, Button3, toggleview, {0} },
|
||||||
|
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
||||||
|
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
||||||
|
};
|
||||||
|
|
38
config.mk
38
config.mk
@ -1,31 +1,39 @@
|
|||||||
# Customize to fit your system
|
# dwm version
|
||||||
|
VERSION = 6.5
|
||||||
|
|
||||||
|
# Customize below to fit your system
|
||||||
|
|
||||||
# paths
|
# paths
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
CONFPREFIX = ${PREFIX}/etc
|
|
||||||
MANPREFIX = ${PREFIX}/share/man
|
MANPREFIX = ${PREFIX}/share/man
|
||||||
|
|
||||||
X11INC = /usr/X11R6/include
|
X11INC = /usr/X11R6/include
|
||||||
X11LIB = /usr/X11R6/lib
|
X11LIB = /usr/X11R6/lib
|
||||||
|
|
||||||
VERSION = 0.1
|
# Xinerama, comment if you don't want it
|
||||||
|
XINERAMALIBS = -lXinerama
|
||||||
|
XINERAMAFLAGS = -DXINERAMA
|
||||||
|
|
||||||
|
# freetype
|
||||||
|
FREETYPELIBS = -lfontconfig -lXft
|
||||||
|
FREETYPEINC = /usr/include/freetype2
|
||||||
|
# OpenBSD (uncomment)
|
||||||
|
#FREETYPEINC = ${X11INC}/freetype2
|
||||||
|
#MANPREFIX = ${PREFIX}/man
|
||||||
|
|
||||||
# includes and libs
|
# includes and libs
|
||||||
LIBS = -L${PREFIX}/lib -L/usr/lib -lc -L${X11LIB} -lX11
|
INCS = -I${X11INC} -I${FREETYPEINC}
|
||||||
|
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
|
||||||
|
|
||||||
# Linux/BSD
|
# flags
|
||||||
CFLAGS = -Os -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \
|
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||||
-DVERSION=\"${VERSION}\"
|
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
|
||||||
|
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
|
||||||
LDFLAGS = ${LIBS}
|
LDFLAGS = ${LIBS}
|
||||||
#CFLAGS = -g -Wall -O2 -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \
|
|
||||||
# -DVERSION=\"${VERSION}\"
|
|
||||||
#LDFLAGS = -g ${LIBS}
|
|
||||||
|
|
||||||
|
|
||||||
# Solaris
|
# Solaris
|
||||||
#CFLAGS = -fast -xtarget=ultra ${INCLUDES} -DVERSION=\"${VERSION}\"
|
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
|
||||||
#LIBS += -lnsl -lsocket
|
#LDFLAGS = ${LIBS}
|
||||||
|
|
||||||
AR = ar cr
|
# compiler and linker
|
||||||
CC = cc
|
CC = cc
|
||||||
RANLIB = ranlib
|
|
||||||
|
151
dev.c
151
dev.c
@ -1,151 +0,0 @@
|
|||||||
/*
|
|
||||||
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
|
||||||
* See LICENSE file for license details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dwm.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <X11/keysym.h>
|
|
||||||
|
|
||||||
/********** CUSTOMIZE **********/
|
|
||||||
|
|
||||||
const char *term[] = {
|
|
||||||
"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
|
|
||||||
"-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
|
|
||||||
};
|
|
||||||
const char *browse[] = { "firefox", NULL };
|
|
||||||
const char *xlock[] = { "xlock", NULL };
|
|
||||||
|
|
||||||
static Key key[] = {
|
|
||||||
/* modifier key function arguments */
|
|
||||||
{ Mod1Mask, XK_Return, zoom, { 0 } },
|
|
||||||
{ Mod1Mask, XK_k, prevc, { 0 } },
|
|
||||||
{ Mod1Mask, XK_j, nextc, { 0 } },
|
|
||||||
{ Mod1Mask, XK_m, max, { 0 } },
|
|
||||||
{ Mod1Mask, XK_0, view, { .i = Tscratch } },
|
|
||||||
{ Mod1Mask, XK_1, view, { .i = Tdev } },
|
|
||||||
{ Mod1Mask, XK_2, view, { .i = Twww } },
|
|
||||||
{ Mod1Mask, XK_3, view, { .i = Twork } },
|
|
||||||
{ Mod1Mask, XK_space, tiling, { 0 } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_space, floating, { 0 } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_0, ttrunc, { .i = Tscratch } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_1, ttrunc, { .i = Tdev } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_2, ttrunc, { .i = Twww } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_3, ttrunc, { .i = Twork } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_c, ckill, { 0 } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_q, quit, { 0 } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_Return, spawn, { .argv = term } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_w, spawn, { .argv = browse } },
|
|
||||||
{ Mod1Mask|ShiftMask, XK_l, spawn, { .argv = xlock } },
|
|
||||||
{ ControlMask, XK_0, tappend, { .i = Tscratch } },
|
|
||||||
{ ControlMask, XK_1, tappend, { .i = Tdev } },
|
|
||||||
{ ControlMask, XK_2, tappend, { .i = Twww } },
|
|
||||||
{ ControlMask, XK_3, tappend, { .i = Twork } },
|
|
||||||
};
|
|
||||||
|
|
||||||
/********** CUSTOMIZE **********/
|
|
||||||
|
|
||||||
void
|
|
||||||
update_keys(void)
|
|
||||||
{
|
|
||||||
static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
|
|
||||||
unsigned int i;
|
|
||||||
KeyCode code;
|
|
||||||
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
code = XKeysymToKeycode(dpy, key[i].keysym);
|
|
||||||
XUngrabKey(dpy, code, key[i].mod, root);
|
|
||||||
XGrabKey(dpy, code, key[i].mod, root, True, GrabModeAsync, GrabModeAsync);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
keypress(XEvent *e)
|
|
||||||
{
|
|
||||||
XKeyEvent *ev = &e->xkey;
|
|
||||||
static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
|
|
||||||
unsigned int i;
|
|
||||||
KeySym keysym;
|
|
||||||
|
|
||||||
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
|
|
||||||
for(i = 0; i < len; i++)
|
|
||||||
if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
|
|
||||||
if(key[i].func)
|
|
||||||
key[i].func(&key[i].arg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ButtonMask (ButtonPressMask | ButtonReleaseMask)
|
|
||||||
#define MouseMask (ButtonMask | PointerMotionMask)
|
|
||||||
|
|
||||||
void
|
|
||||||
mresize(Client *c)
|
|
||||||
{
|
|
||||||
XEvent ev;
|
|
||||||
int ocx, ocy;
|
|
||||||
|
|
||||||
ocx = c->x;
|
|
||||||
ocy = c->y;
|
|
||||||
if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
|
|
||||||
None, cursor[CurResize], CurrentTime) != GrabSuccess)
|
|
||||||
return;
|
|
||||||
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
|
|
||||||
for(;;) {
|
|
||||||
XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
|
|
||||||
switch(ev.type) {
|
|
||||||
default: break;
|
|
||||||
case Expose:
|
|
||||||
handler[Expose](&ev);
|
|
||||||
break;
|
|
||||||
case MotionNotify:
|
|
||||||
XFlush(dpy);
|
|
||||||
c->w = abs(ocx - ev.xmotion.x);
|
|
||||||
c->h = abs(ocy - ev.xmotion.y);
|
|
||||||
c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
|
|
||||||
c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
|
|
||||||
resize(c, True);
|
|
||||||
break;
|
|
||||||
case ButtonRelease:
|
|
||||||
XUngrabPointer(dpy, CurrentTime);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mmove(Client *c)
|
|
||||||
{
|
|
||||||
XEvent ev;
|
|
||||||
int x1, y1, ocx, ocy, di;
|
|
||||||
unsigned int dui;
|
|
||||||
Window dummy;
|
|
||||||
|
|
||||||
ocx = c->x;
|
|
||||||
ocy = c->y;
|
|
||||||
if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
|
|
||||||
None, cursor[CurMove], CurrentTime) != GrabSuccess)
|
|
||||||
return;
|
|
||||||
XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
|
|
||||||
for(;;) {
|
|
||||||
XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
|
|
||||||
switch (ev.type) {
|
|
||||||
default: break;
|
|
||||||
case Expose:
|
|
||||||
handler[Expose](&ev);
|
|
||||||
break;
|
|
||||||
case MotionNotify:
|
|
||||||
XFlush(dpy);
|
|
||||||
c->x = ocx + (ev.xmotion.x - x1);
|
|
||||||
c->y = ocy + (ev.xmotion.y - y1);
|
|
||||||
resize(c, False);
|
|
||||||
break;
|
|
||||||
case ButtonRelease:
|
|
||||||
XUngrabPointer(dpy, CurrentTime);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
158
draw.c
158
draw.c
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
|
||||||
* See LICENSE file for license details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <X11/Xlocale.h>
|
|
||||||
|
|
||||||
#include "dwm.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
drawborder(void)
|
|
||||||
{
|
|
||||||
XPoint points[5];
|
|
||||||
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
|
|
||||||
XSetForeground(dpy, dc.gc, dc.border);
|
|
||||||
points[0].x = dc.x;
|
|
||||||
points[0].y = dc.y;
|
|
||||||
points[1].x = dc.w - 1;
|
|
||||||
points[1].y = 0;
|
|
||||||
points[2].x = 0;
|
|
||||||
points[2].y = dc.h - 1;
|
|
||||||
points[3].x = -(dc.w - 1);
|
|
||||||
points[3].y = 0;
|
|
||||||
points[4].x = 0;
|
|
||||||
points[4].y = -(dc.h - 1);
|
|
||||||
XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
drawtext(const char *text, Bool invert, Bool border)
|
|
||||||
{
|
|
||||||
int x, y, w, h;
|
|
||||||
unsigned int len;
|
|
||||||
static char buf[256];
|
|
||||||
XGCValues gcv;
|
|
||||||
XRectangle r = { dc.x, dc.y, dc.w, dc.h };
|
|
||||||
|
|
||||||
XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg);
|
|
||||||
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
|
|
||||||
|
|
||||||
w = 0;
|
|
||||||
if(border)
|
|
||||||
drawborder();
|
|
||||||
|
|
||||||
if(!text)
|
|
||||||
return;
|
|
||||||
|
|
||||||
len = strlen(text);
|
|
||||||
if(len >= sizeof(buf))
|
|
||||||
len = sizeof(buf) - 1;
|
|
||||||
memcpy(buf, text, len);
|
|
||||||
buf[len] = 0;
|
|
||||||
|
|
||||||
h = dc.font.ascent + dc.font.descent;
|
|
||||||
y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
|
|
||||||
x = dc.x + (h / 2);
|
|
||||||
|
|
||||||
/* shorten text if necessary */
|
|
||||||
while(len && (w = textnw(buf, len)) > dc.w - h)
|
|
||||||
buf[--len] = 0;
|
|
||||||
|
|
||||||
if(w > dc.w)
|
|
||||||
return; /* too long */
|
|
||||||
|
|
||||||
gcv.foreground = invert ? dc.bg : dc.fg;
|
|
||||||
gcv.background = invert ? dc.fg : dc.bg;
|
|
||||||
if(dc.font.set) {
|
|
||||||
XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv);
|
|
||||||
XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc,
|
|
||||||
x, y, buf, len);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
gcv.font = dc.font.xfont->fid;
|
|
||||||
XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv);
|
|
||||||
XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long
|
|
||||||
initcolor(const char *colstr)
|
|
||||||
{
|
|
||||||
XColor color;
|
|
||||||
Colormap cmap = DefaultColormap(dpy, screen);
|
|
||||||
|
|
||||||
XAllocNamedColor(dpy, cmap, colstr, &color, &color);
|
|
||||||
return color.pixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
textnw(char *text, unsigned int len)
|
|
||||||
{
|
|
||||||
XRectangle r;
|
|
||||||
if(dc.font.set) {
|
|
||||||
XmbTextExtents(dc.font.set, text, len, NULL, &r);
|
|
||||||
return r.width;
|
|
||||||
}
|
|
||||||
return XTextWidth(dc.font.xfont, text, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
textw(char *text)
|
|
||||||
{
|
|
||||||
return textnw(text, strlen(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
initfont(const char *fontstr)
|
|
||||||
{
|
|
||||||
char **missing, *def;
|
|
||||||
int i, n;
|
|
||||||
|
|
||||||
missing = NULL;
|
|
||||||
setlocale(LC_ALL, "");
|
|
||||||
if(dc.font.set)
|
|
||||||
XFreeFontSet(dpy, dc.font.set);
|
|
||||||
dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
|
|
||||||
if(missing) {
|
|
||||||
while(n--)
|
|
||||||
fprintf(stderr, "missing fontset: %s\n", missing[n]);
|
|
||||||
XFreeStringList(missing);
|
|
||||||
if(dc.font.set) {
|
|
||||||
XFreeFontSet(dpy, dc.font.set);
|
|
||||||
dc.font.set = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(dc.font.set) {
|
|
||||||
XFontSetExtents *font_extents;
|
|
||||||
XFontStruct **xfonts;
|
|
||||||
char **font_names;
|
|
||||||
|
|
||||||
dc.font.ascent = dc.font.descent = 0;
|
|
||||||
font_extents = XExtentsOfFontSet(dc.font.set);
|
|
||||||
n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
|
|
||||||
for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
|
|
||||||
if(dc.font.ascent < (*xfonts)->ascent)
|
|
||||||
dc.font.ascent = (*xfonts)->ascent;
|
|
||||||
if(dc.font.descent < (*xfonts)->descent)
|
|
||||||
dc.font.descent = (*xfonts)->descent;
|
|
||||||
xfonts++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(dc.font.xfont)
|
|
||||||
XFreeFont(dpy, dc.font.xfont);
|
|
||||||
dc.font.xfont = NULL;
|
|
||||||
dc.font.xfont = XLoadQueryFont(dpy, fontstr);
|
|
||||||
if (!dc.font.xfont)
|
|
||||||
dc.font.xfont = XLoadQueryFont(dpy, "fixed");
|
|
||||||
if (!dc.font.xfont)
|
|
||||||
error("error, cannot init 'fixed' font\n");
|
|
||||||
dc.font.ascent = dc.font.xfont->ascent;
|
|
||||||
dc.font.descent = dc.font.xfont->descent;
|
|
||||||
}
|
|
||||||
dc.font.height = dc.font.ascent + dc.font.descent;
|
|
||||||
}
|
|
448
drw.c
Normal file
448
drw.c
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
|
||||||
|
#include "drw.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#define UTF_INVALID 0xFFFD
|
||||||
|
|
||||||
|
static int
|
||||||
|
utf8decode(const char *s_in, long *u, int *err)
|
||||||
|
{
|
||||||
|
static const unsigned char lens[] = {
|
||||||
|
/* 0XXXX */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
/* 10XXX */ 0, 0, 0, 0, 0, 0, 0, 0, /* invalid */
|
||||||
|
/* 110XX */ 2, 2, 2, 2,
|
||||||
|
/* 1110X */ 3, 3,
|
||||||
|
/* 11110 */ 4,
|
||||||
|
/* 11111 */ 0, /* invalid */
|
||||||
|
};
|
||||||
|
static const unsigned char leading_mask[] = { 0x7F, 0x1F, 0x0F, 0x07 };
|
||||||
|
static const unsigned int overlong[] = { 0x0, 0x80, 0x0800, 0x10000 };
|
||||||
|
|
||||||
|
const unsigned char *s = (const unsigned char *)s_in;
|
||||||
|
int len = lens[*s >> 3];
|
||||||
|
*u = UTF_INVALID;
|
||||||
|
*err = 1;
|
||||||
|
if (len == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
long cp = s[0] & leading_mask[len - 1];
|
||||||
|
for (int i = 1; i < len; ++i) {
|
||||||
|
if (s[i] == '\0' || (s[i] & 0xC0) != 0x80)
|
||||||
|
return i;
|
||||||
|
cp = (cp << 6) | (s[i] & 0x3F);
|
||||||
|
}
|
||||||
|
/* out of range, surrogate, overlong encoding */
|
||||||
|
if (cp > 0x10FFFF || (cp >> 11) == 0x1B || cp < overlong[len - 1])
|
||||||
|
return len;
|
||||||
|
|
||||||
|
*err = 0;
|
||||||
|
*u = cp;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
Drw *
|
||||||
|
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
|
||||||
|
{
|
||||||
|
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||||
|
|
||||||
|
drw->dpy = dpy;
|
||||||
|
drw->screen = screen;
|
||||||
|
drw->root = root;
|
||||||
|
drw->w = w;
|
||||||
|
drw->h = h;
|
||||||
|
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
|
||||||
|
drw->gc = XCreateGC(dpy, root, 0, NULL);
|
||||||
|
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||||
|
|
||||||
|
return drw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
||||||
|
{
|
||||||
|
if (!drw)
|
||||||
|
return;
|
||||||
|
|
||||||
|
drw->w = w;
|
||||||
|
drw->h = h;
|
||||||
|
if (drw->drawable)
|
||||||
|
XFreePixmap(drw->dpy, drw->drawable);
|
||||||
|
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_free(Drw *drw)
|
||||||
|
{
|
||||||
|
XFreePixmap(drw->dpy, drw->drawable);
|
||||||
|
XFreeGC(drw->dpy, drw->gc);
|
||||||
|
drw_fontset_free(drw->fonts);
|
||||||
|
free(drw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is an implementation detail. Library users should use
|
||||||
|
* drw_fontset_create instead.
|
||||||
|
*/
|
||||||
|
static Fnt *
|
||||||
|
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
|
||||||
|
{
|
||||||
|
Fnt *font;
|
||||||
|
XftFont *xfont = NULL;
|
||||||
|
FcPattern *pattern = NULL;
|
||||||
|
|
||||||
|
if (fontname) {
|
||||||
|
/* Using the pattern found at font->xfont->pattern does not yield the
|
||||||
|
* same substitution results as using the pattern returned by
|
||||||
|
* FcNameParse; using the latter results in the desired fallback
|
||||||
|
* behaviour whereas the former just results in missing-character
|
||||||
|
* rectangles being drawn, at least with some fonts. */
|
||||||
|
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
|
||||||
|
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
|
||||||
|
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
|
||||||
|
XftFontClose(drw->dpy, xfont);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else if (fontpattern) {
|
||||||
|
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
|
||||||
|
fprintf(stderr, "error, cannot load font from pattern.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
die("no font specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
font = ecalloc(1, sizeof(Fnt));
|
||||||
|
font->xfont = xfont;
|
||||||
|
font->pattern = pattern;
|
||||||
|
font->h = xfont->ascent + xfont->descent;
|
||||||
|
font->dpy = drw->dpy;
|
||||||
|
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xfont_free(Fnt *font)
|
||||||
|
{
|
||||||
|
if (!font)
|
||||||
|
return;
|
||||||
|
if (font->pattern)
|
||||||
|
FcPatternDestroy(font->pattern);
|
||||||
|
XftFontClose(font->dpy, font->xfont);
|
||||||
|
free(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
Fnt*
|
||||||
|
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
|
||||||
|
{
|
||||||
|
Fnt *cur, *ret = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!drw || !fonts)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 1; i <= fontcount; i++) {
|
||||||
|
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
|
||||||
|
cur->next = ret;
|
||||||
|
ret = cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (drw->fonts = ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_fontset_free(Fnt *font)
|
||||||
|
{
|
||||||
|
if (font) {
|
||||||
|
drw_fontset_free(font->next);
|
||||||
|
xfont_free(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||||
|
{
|
||||||
|
if (!drw || !dest || !clrname)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
|
||||||
|
DefaultColormap(drw->dpy, drw->screen),
|
||||||
|
clrname, dest))
|
||||||
|
die("error, cannot allocate color '%s'", clrname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||||
|
* returned color scheme when done using it. */
|
||||||
|
Clr *
|
||||||
|
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
Clr *ret;
|
||||||
|
|
||||||
|
/* need at least two colors for a scheme */
|
||||||
|
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < clrcount; i++)
|
||||||
|
drw_clr_create(drw, &ret[i], clrnames[i]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_setfontset(Drw *drw, Fnt *set)
|
||||||
|
{
|
||||||
|
if (drw)
|
||||||
|
drw->fonts = set;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_setscheme(Drw *drw, Clr *scm)
|
||||||
|
{
|
||||||
|
if (drw)
|
||||||
|
drw->scheme = scm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
|
||||||
|
{
|
||||||
|
if (!drw || !drw->scheme)
|
||||||
|
return;
|
||||||
|
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
|
||||||
|
if (filled)
|
||||||
|
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||||
|
else
|
||||||
|
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
|
||||||
|
{
|
||||||
|
int ty, ellipsis_x = 0;
|
||||||
|
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1;
|
||||||
|
XftDraw *d = NULL;
|
||||||
|
Fnt *usedfont, *curfont, *nextfont;
|
||||||
|
int utf8strlen, utf8charlen, utf8err, render = x || y || w || h;
|
||||||
|
long utf8codepoint = 0;
|
||||||
|
const char *utf8str;
|
||||||
|
FcCharSet *fccharset;
|
||||||
|
FcPattern *fcpattern;
|
||||||
|
FcPattern *match;
|
||||||
|
XftResult result;
|
||||||
|
int charexists = 0, overflow = 0;
|
||||||
|
/* keep track of a couple codepoints for which we have no match. */
|
||||||
|
static unsigned int nomatches[128], ellipsis_width, invalid_width;
|
||||||
|
static const char invalid[] = "<EFBFBD>";
|
||||||
|
|
||||||
|
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!render) {
|
||||||
|
w = invert ? invert : ~invert;
|
||||||
|
} else {
|
||||||
|
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||||
|
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||||
|
if (w < lpad)
|
||||||
|
return x + w;
|
||||||
|
d = XftDrawCreate(drw->dpy, drw->drawable,
|
||||||
|
DefaultVisual(drw->dpy, drw->screen),
|
||||||
|
DefaultColormap(drw->dpy, drw->screen));
|
||||||
|
x += lpad;
|
||||||
|
w -= lpad;
|
||||||
|
}
|
||||||
|
|
||||||
|
usedfont = drw->fonts;
|
||||||
|
if (!ellipsis_width && render)
|
||||||
|
ellipsis_width = drw_fontset_getwidth(drw, "...");
|
||||||
|
if (!invalid_width && render)
|
||||||
|
invalid_width = drw_fontset_getwidth(drw, invalid);
|
||||||
|
while (1) {
|
||||||
|
ew = ellipsis_len = utf8err = utf8charlen = utf8strlen = 0;
|
||||||
|
utf8str = text;
|
||||||
|
nextfont = NULL;
|
||||||
|
while (*text) {
|
||||||
|
utf8charlen = utf8decode(text, &utf8codepoint, &utf8err);
|
||||||
|
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
||||||
|
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
||||||
|
if (charexists) {
|
||||||
|
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
|
||||||
|
if (ew + ellipsis_width <= w) {
|
||||||
|
/* keep track where the ellipsis still fits */
|
||||||
|
ellipsis_x = x + ew;
|
||||||
|
ellipsis_w = w - ew;
|
||||||
|
ellipsis_len = utf8strlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ew + tmpw > w) {
|
||||||
|
overflow = 1;
|
||||||
|
/* called from drw_fontset_getwidth_clamp():
|
||||||
|
* it wants the width AFTER the overflow
|
||||||
|
*/
|
||||||
|
if (!render)
|
||||||
|
x += tmpw;
|
||||||
|
else
|
||||||
|
utf8strlen = ellipsis_len;
|
||||||
|
} else if (curfont == usedfont) {
|
||||||
|
text += utf8charlen;
|
||||||
|
utf8strlen += utf8err ? 0 : utf8charlen;
|
||||||
|
ew += utf8err ? 0 : tmpw;
|
||||||
|
} else {
|
||||||
|
nextfont = curfont;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overflow || !charexists || nextfont || utf8err)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
charexists = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utf8strlen) {
|
||||||
|
if (render) {
|
||||||
|
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
||||||
|
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
||||||
|
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
|
||||||
|
}
|
||||||
|
x += ew;
|
||||||
|
w -= ew;
|
||||||
|
}
|
||||||
|
if (utf8err && (!render || invalid_width < w)) {
|
||||||
|
if (render)
|
||||||
|
drw_text(drw, x, y, w, h, 0, invalid, invert);
|
||||||
|
x += invalid_width;
|
||||||
|
w -= invalid_width;
|
||||||
|
}
|
||||||
|
if (render && overflow)
|
||||||
|
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
|
||||||
|
|
||||||
|
if (!*text || overflow) {
|
||||||
|
break;
|
||||||
|
} else if (nextfont) {
|
||||||
|
charexists = 0;
|
||||||
|
usedfont = nextfont;
|
||||||
|
} else {
|
||||||
|
/* Regardless of whether or not a fallback font is found, the
|
||||||
|
* character must be drawn. */
|
||||||
|
charexists = 1;
|
||||||
|
|
||||||
|
hash = (unsigned int)utf8codepoint;
|
||||||
|
hash = ((hash >> 16) ^ hash) * 0x21F0AAAD;
|
||||||
|
hash = ((hash >> 15) ^ hash) * 0xD35A2D97;
|
||||||
|
h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches);
|
||||||
|
h1 = (hash >> 17) % LENGTH(nomatches);
|
||||||
|
/* avoid expensive XftFontMatch call when we know we won't find a match */
|
||||||
|
if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint)
|
||||||
|
goto no_match;
|
||||||
|
|
||||||
|
fccharset = FcCharSetCreate();
|
||||||
|
FcCharSetAddChar(fccharset, utf8codepoint);
|
||||||
|
|
||||||
|
if (!drw->fonts->pattern) {
|
||||||
|
/* Refer to the comment in xfont_create for more information. */
|
||||||
|
die("the first font in the cache must be loaded from a font string.");
|
||||||
|
}
|
||||||
|
|
||||||
|
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
|
||||||
|
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
|
||||||
|
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
|
||||||
|
|
||||||
|
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
|
||||||
|
FcDefaultSubstitute(fcpattern);
|
||||||
|
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
|
||||||
|
|
||||||
|
FcCharSetDestroy(fccharset);
|
||||||
|
FcPatternDestroy(fcpattern);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
usedfont = xfont_create(drw, NULL, match);
|
||||||
|
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
|
||||||
|
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
|
||||||
|
; /* NOP */
|
||||||
|
curfont->next = usedfont;
|
||||||
|
} else {
|
||||||
|
xfont_free(usedfont);
|
||||||
|
nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint;
|
||||||
|
no_match:
|
||||||
|
usedfont = drw->fonts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (d)
|
||||||
|
XftDrawDestroy(d);
|
||||||
|
|
||||||
|
return x + (render ? w : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
|
||||||
|
{
|
||||||
|
if (!drw)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
|
||||||
|
XSync(drw->dpy, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
drw_fontset_getwidth(Drw *drw, const char *text)
|
||||||
|
{
|
||||||
|
if (!drw || !drw->fonts || !text)
|
||||||
|
return 0;
|
||||||
|
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
|
||||||
|
{
|
||||||
|
unsigned int tmp = 0;
|
||||||
|
if (drw && drw->fonts && text && n)
|
||||||
|
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
|
||||||
|
return MIN(n, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
|
||||||
|
{
|
||||||
|
XGlyphInfo ext;
|
||||||
|
|
||||||
|
if (!font || !text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
|
||||||
|
if (w)
|
||||||
|
*w = ext.xOff;
|
||||||
|
if (h)
|
||||||
|
*h = font->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cur *
|
||||||
|
drw_cur_create(Drw *drw, int shape)
|
||||||
|
{
|
||||||
|
Cur *cur;
|
||||||
|
|
||||||
|
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cur->cursor = XCreateFontCursor(drw->dpy, shape);
|
||||||
|
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drw_cur_free(Drw *drw, Cur *cursor)
|
||||||
|
{
|
||||||
|
if (!cursor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XFreeCursor(drw->dpy, cursor->cursor);
|
||||||
|
free(cursor);
|
||||||
|
}
|
58
drw.h
Normal file
58
drw.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Cursor cursor;
|
||||||
|
} Cur;
|
||||||
|
|
||||||
|
typedef struct Fnt {
|
||||||
|
Display *dpy;
|
||||||
|
unsigned int h;
|
||||||
|
XftFont *xfont;
|
||||||
|
FcPattern *pattern;
|
||||||
|
struct Fnt *next;
|
||||||
|
} Fnt;
|
||||||
|
|
||||||
|
enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
|
||||||
|
typedef XftColor Clr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int w, h;
|
||||||
|
Display *dpy;
|
||||||
|
int screen;
|
||||||
|
Window root;
|
||||||
|
Drawable drawable;
|
||||||
|
GC gc;
|
||||||
|
Clr *scheme;
|
||||||
|
Fnt *fonts;
|
||||||
|
} Drw;
|
||||||
|
|
||||||
|
/* Drawable abstraction */
|
||||||
|
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
|
||||||
|
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||||
|
void drw_free(Drw *drw);
|
||||||
|
|
||||||
|
/* Fnt abstraction */
|
||||||
|
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
|
||||||
|
void drw_fontset_free(Fnt* set);
|
||||||
|
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
||||||
|
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
|
||||||
|
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||||
|
|
||||||
|
/* Colorscheme abstraction */
|
||||||
|
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||||
|
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||||
|
|
||||||
|
/* Cursor abstraction */
|
||||||
|
Cur *drw_cur_create(Drw *drw, int shape);
|
||||||
|
void drw_cur_free(Drw *drw, Cur *cursor);
|
||||||
|
|
||||||
|
/* Drawing context manipulation */
|
||||||
|
void drw_setfontset(Drw *drw, Fnt *set);
|
||||||
|
void drw_setscheme(Drw *drw, Clr *scm);
|
||||||
|
|
||||||
|
/* Drawing functions */
|
||||||
|
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
|
||||||
|
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
|
||||||
|
|
||||||
|
/* Map functions */
|
||||||
|
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
|
232
dwm.1
232
dwm.1
@ -1,98 +1,176 @@
|
|||||||
.TH DWM 1 dwm-0.1
|
.TH DWM 1 dwm\-VERSION
|
||||||
.SH NAME
|
.SH NAME
|
||||||
dwm \- dynamic window manager
|
dwm \- dynamic window manager
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B dwm
|
.B dwm
|
||||||
.RB [ \-v ]
|
.RB [ \-v ]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.SS Overview
|
dwm is a dynamic window manager for X. It manages windows in tiled, monocle
|
||||||
.B dwm
|
and floating layouts. Either layout can be applied dynamically, optimising the
|
||||||
is a dynamic window manager for X11.
|
environment for the application in use and the task performed.
|
||||||
.SS Options
|
.P
|
||||||
|
In tiled layouts windows are managed in a master and stacking area. The master
|
||||||
|
area on the left contains one window by default, and the stacking area on the
|
||||||
|
right contains all other windows. The number of master area windows can be
|
||||||
|
adjusted from zero to an arbitrary number. In monocle layout all windows are
|
||||||
|
maximised to the screen size. In floating layout windows can be resized and
|
||||||
|
moved freely. Dialog windows are always managed floating, regardless of the
|
||||||
|
layout applied.
|
||||||
|
.P
|
||||||
|
Windows are grouped by tags. Each window can be tagged with one or multiple
|
||||||
|
tags. Selecting certain tags displays all windows with these tags.
|
||||||
|
.P
|
||||||
|
Each screen contains a small status bar which displays all available tags, the
|
||||||
|
layout, the title of the focused window, and the text read from the root window
|
||||||
|
name property, if the screen is focused. A floating window is indicated with an
|
||||||
|
empty square and a maximised floating window is indicated with a filled square
|
||||||
|
before the windows title. The selected tags are indicated with a different
|
||||||
|
color. The tags of the focused window are indicated with a filled square in the
|
||||||
|
top left corner. The tags which are applied to one or more windows are
|
||||||
|
indicated with an empty square in the top left corner.
|
||||||
|
.P
|
||||||
|
dwm draws a small border around windows to indicate the focus state.
|
||||||
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B \-v
|
.B \-v
|
||||||
prints version information to stdout, then exits.
|
prints version information to stderr, then exits.
|
||||||
.SS Status text
|
.SH USAGE
|
||||||
.B dwm
|
.SS Status bar
|
||||||
reads from stdin to display status text if provided.
|
|
||||||
.SS Default Key Bindings
|
|
||||||
.TP 16
|
|
||||||
.I Key
|
|
||||||
.I Action
|
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-Return
|
.B X root window name
|
||||||
Zoom
|
is read and displayed in the status text area. It can be set with the
|
||||||
.B window
|
.BR xsetroot (1)
|
||||||
to the
|
command.
|
||||||
.B master
|
|
||||||
track
|
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-k
|
.B Button1
|
||||||
Focus previous
|
click on a tag label to display all windows with that tag, click on the layout
|
||||||
.B window
|
label toggles between tiled and floating layout.
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-j
|
.B Button3
|
||||||
Focus next
|
click on a tag label adds/removes all windows with that tag to/from the view.
|
||||||
.B window
|
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-m
|
.B Mod1\-Button1
|
||||||
Maximize current
|
click on a tag label applies that tag to the focused window.
|
||||||
.B window
|
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-[0..n]
|
.B Mod1\-Button3
|
||||||
Focus
|
click on a tag label adds/removes that tag to/from the focused window.
|
||||||
.B nth
|
.SS Keyboard commands
|
||||||
tag
|
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-space
|
.B Mod1\-Shift\-Return
|
||||||
(Re-)arrange
|
|
||||||
.B all
|
|
||||||
windows tiled
|
|
||||||
.TP
|
|
||||||
.B Mod1-Shift-space
|
|
||||||
(Re-)arrange
|
|
||||||
.B all
|
|
||||||
windows floating
|
|
||||||
.TP
|
|
||||||
.B Mod1-Shift-[0..n]
|
|
||||||
Apply
|
|
||||||
.B nth
|
|
||||||
tag to current
|
|
||||||
.B window
|
|
||||||
.TP
|
|
||||||
.B Mod1-Shift-q
|
|
||||||
Quit
|
|
||||||
.B dwm
|
|
||||||
.TP
|
|
||||||
.B Mod1-Shift-Return
|
|
||||||
Start
|
Start
|
||||||
.B terminal
|
.BR st(1).
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-Shift-w
|
.B Mod1\-p
|
||||||
Start
|
Spawn
|
||||||
.B web browser
|
.BR dmenu(1)
|
||||||
|
for launching other programs.
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-Shift-l
|
.B Mod1\-,
|
||||||
Lock
|
Focus previous screen, if any.
|
||||||
.B screen
|
|
||||||
.TP
|
.TP
|
||||||
.B Control-[0..n]
|
.B Mod1\-.
|
||||||
Append
|
Focus next screen, if any.
|
||||||
.B nth
|
|
||||||
tag to cureent
|
|
||||||
.B window
|
|
||||||
.SS Default Mouse Bindings
|
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-Button1
|
.B Mod1\-Shift\-,
|
||||||
Moves current
|
Send focused window to previous screen, if any.
|
||||||
.B window
|
|
||||||
while dragging
|
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-Button2
|
.B Mod1\-Shift\-.
|
||||||
Lowers current
|
Send focused window to next screen, if any.
|
||||||
.B window
|
|
||||||
.TP
|
.TP
|
||||||
.B Mod1-Button3
|
.B Mod1\-b
|
||||||
Resizes current
|
Toggles bar on and off.
|
||||||
.B window
|
.TP
|
||||||
while dragging
|
.B Mod1\-t
|
||||||
|
Sets tiled layout.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-f
|
||||||
|
Sets floating layout.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-m
|
||||||
|
Sets monocle layout.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-space
|
||||||
|
Toggles between current and previous layout.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-j
|
||||||
|
Focus next window.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-k
|
||||||
|
Focus previous window.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-i
|
||||||
|
Increase number of windows in master area.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-d
|
||||||
|
Decrease number of windows in master area.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-l
|
||||||
|
Increase master area size.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-h
|
||||||
|
Decrease master area size.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Return
|
||||||
|
Zooms/cycles focused window to/from master area (tiled layouts only).
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Shift\-c
|
||||||
|
Close focused window.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Shift\-space
|
||||||
|
Toggle focused window between tiled and floating state.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Tab
|
||||||
|
Toggles to the previously selected tags.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Shift\-[1..n]
|
||||||
|
Apply nth tag to focused window.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Shift\-0
|
||||||
|
Apply all tags to focused window.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Control\-Shift\-[1..n]
|
||||||
|
Add/remove nth tag to/from focused window.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-[1..n]
|
||||||
|
View all windows with nth tag.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-0
|
||||||
|
View all windows with any tag.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Control\-[1..n]
|
||||||
|
Add/remove all windows with nth tag to/from the view.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Shift\-q
|
||||||
|
Quit dwm.
|
||||||
|
.SS Mouse commands
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Button1
|
||||||
|
Move focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Button2
|
||||||
|
Toggles focused window between floating and tiled state.
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Button3
|
||||||
|
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||||
|
.SH CUSTOMIZATION
|
||||||
|
dwm is customized by creating a custom config.h and (re)compiling the source
|
||||||
|
code. This keeps it fast, secure and simple.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR dmenu (1),
|
||||||
|
.BR st (1)
|
||||||
|
.SH ISSUES
|
||||||
|
Java applications which use the XToolkit/XAWT backend may draw grey windows
|
||||||
|
only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
|
||||||
|
JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds
|
||||||
|
are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the
|
||||||
|
environment variable
|
||||||
|
.BR AWT_TOOLKIT=MToolkit
|
||||||
|
(to use the older Motif backend instead) or running
|
||||||
|
.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D
|
||||||
|
or
|
||||||
|
.B wmname LG3D
|
||||||
|
(to pretend that a non-reparenting window manager is running that the
|
||||||
|
XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable
|
||||||
|
.BR _JAVA_AWT_WM_NONREPARENTING=1 .
|
||||||
|
.SH BUGS
|
||||||
|
Send all bug reports with a patch to hackers@suckless.org.
|
||||||
|
155
dwm.h
155
dwm.h
@ -1,155 +0,0 @@
|
|||||||
/*
|
|
||||||
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
|
||||||
* See LICENSE file for license details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
|
|
||||||
/********** CUSTOMIZE **********/
|
|
||||||
|
|
||||||
#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*"
|
|
||||||
#define BGCOLOR "#666699"
|
|
||||||
#define FGCOLOR "#eeeeee"
|
|
||||||
#define BORDERCOLOR "#9999CC"
|
|
||||||
#define MASTERW 52 /* percent */
|
|
||||||
#define WM_PROTOCOL_DELWIN 1
|
|
||||||
|
|
||||||
/* tags */
|
|
||||||
enum { Tscratch, Tdev, Twww, Twork, TLast };
|
|
||||||
|
|
||||||
/********** CUSTOMIZE **********/
|
|
||||||
|
|
||||||
typedef union Arg Arg;
|
|
||||||
typedef struct DC DC;
|
|
||||||
typedef struct Client Client;
|
|
||||||
typedef struct Fnt Fnt;
|
|
||||||
typedef struct Key Key;
|
|
||||||
typedef struct Rule Rule;
|
|
||||||
|
|
||||||
union Arg {
|
|
||||||
const char **argv;
|
|
||||||
int i;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* atoms */
|
|
||||||
enum { WMProtocols, WMDelete, WMLast };
|
|
||||||
enum { NetSupported, NetWMName, NetLast };
|
|
||||||
|
|
||||||
/* cursor */
|
|
||||||
enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
|
|
||||||
|
|
||||||
struct Fnt {
|
|
||||||
XFontStruct *xfont;
|
|
||||||
XFontSet set;
|
|
||||||
int ascent;
|
|
||||||
int descent;
|
|
||||||
int height;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DC { /* draw context */
|
|
||||||
GC gc;
|
|
||||||
Drawable drawable;
|
|
||||||
int x, y, w, h;
|
|
||||||
Fnt font;
|
|
||||||
unsigned long bg;
|
|
||||||
unsigned long fg;
|
|
||||||
unsigned long border;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Client {
|
|
||||||
char name[256];
|
|
||||||
char *tags[TLast];
|
|
||||||
int proto;
|
|
||||||
int x, y, w, h;
|
|
||||||
int tx, ty, tw, th;
|
|
||||||
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
|
|
||||||
int grav;
|
|
||||||
unsigned int border;
|
|
||||||
long flags;
|
|
||||||
Bool floating;
|
|
||||||
Window win;
|
|
||||||
Window title;
|
|
||||||
Client *next;
|
|
||||||
Client *revert;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Rule {
|
|
||||||
const char *class;
|
|
||||||
const char *instance;
|
|
||||||
char *tags[TLast];
|
|
||||||
Bool floating;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Key {
|
|
||||||
unsigned long mod;
|
|
||||||
KeySym keysym;
|
|
||||||
void (*func)(Arg *arg);
|
|
||||||
Arg arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Display *dpy;
|
|
||||||
extern Window root, barwin;
|
|
||||||
extern Atom wm_atom[WMLast], net_atom[NetLast];
|
|
||||||
extern Cursor cursor[CurLast];
|
|
||||||
extern Bool running, issel;
|
|
||||||
extern void (*handler[LASTEvent])(XEvent *);
|
|
||||||
extern void (*arrange)(Arg *);
|
|
||||||
|
|
||||||
extern int tsel, screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
|
|
||||||
extern char *tags[TLast], stext[1024];
|
|
||||||
|
|
||||||
extern DC dc;
|
|
||||||
extern Client *clients, *sel;
|
|
||||||
|
|
||||||
/* bar.c */
|
|
||||||
extern void draw_bar();
|
|
||||||
extern void barclick(XButtonPressedEvent *e);
|
|
||||||
|
|
||||||
/* client.c */
|
|
||||||
extern void manage(Window w, XWindowAttributes *wa);
|
|
||||||
extern void unmanage(Client *c);
|
|
||||||
extern Client *getclient(Window w);
|
|
||||||
extern void focus(Client *c);
|
|
||||||
extern void update_name(Client *c);
|
|
||||||
extern void draw_client(Client *c);
|
|
||||||
extern void resize(Client *c, Bool inc);
|
|
||||||
extern void update_size(Client *c);
|
|
||||||
extern Client *gettitle(Window w);
|
|
||||||
extern void craise(Client *c);
|
|
||||||
extern void lower(Client *c);
|
|
||||||
extern void ckill(Arg *arg);
|
|
||||||
extern void nextc(Arg *arg);
|
|
||||||
extern void prevc(Arg *arg);
|
|
||||||
extern void max(Arg *arg);
|
|
||||||
extern void floating(Arg *arg);
|
|
||||||
extern void tiling(Arg *arg);
|
|
||||||
extern void ttrunc(Arg *arg);
|
|
||||||
extern void tappend(Arg *arg);
|
|
||||||
extern void view(Arg *arg);
|
|
||||||
extern void zoom(Arg *arg);
|
|
||||||
extern void gravitate(Client *c, Bool invert);
|
|
||||||
|
|
||||||
/* draw.c */
|
|
||||||
extern void drawtext(const char *text, Bool invert, Bool border);
|
|
||||||
extern unsigned long initcolor(const char *colstr);
|
|
||||||
extern void initfont(const char *fontstr);
|
|
||||||
extern unsigned int textnw(char *text, unsigned int len);
|
|
||||||
extern unsigned int textw(char *text);
|
|
||||||
extern unsigned int texth(void);
|
|
||||||
|
|
||||||
/* dev.c */
|
|
||||||
extern void update_keys(void);
|
|
||||||
extern void keypress(XEvent *e);
|
|
||||||
extern void mresize(Client *c);
|
|
||||||
extern void mmove(Client *c);
|
|
||||||
|
|
||||||
/* main.c */
|
|
||||||
extern int error_handler(Display *dsply, XErrorEvent *e);
|
|
||||||
extern void send_message(Window w, Atom a, long value);
|
|
||||||
extern int win_proto(Window w);
|
|
||||||
extern void quit(Arg *arg);
|
|
||||||
|
|
||||||
/* util.c */
|
|
||||||
extern void error(const char *errstr, ...);
|
|
||||||
extern void *emallocz(unsigned int size);
|
|
||||||
extern void spawn(Arg *arg);
|
|
106
dwm.html
106
dwm.html
@ -1,106 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>dwm - dynamic window manager</title>
|
|
||||||
<meta name="author" content="Anselm R. Garbe">
|
|
||||||
<meta name="generator" content="ed">
|
|
||||||
<meta name="copyright" content="(C)opyright 2006 by Anselm R. Garbe">
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
color: #000000;
|
|
||||||
font-family: sans-serif;
|
|
||||||
margin: 20px 20px 20px 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<center>
|
|
||||||
<img src="dwm.png"/><br />
|
|
||||||
<h3>dynamic window manager</h3>
|
|
||||||
</center>
|
|
||||||
<h3>Description</h3>
|
|
||||||
<p>
|
|
||||||
dwm is a dynamic window manager for X11.
|
|
||||||
</p>
|
|
||||||
<h3>Philosophy</h3>
|
|
||||||
<p>
|
|
||||||
As founder and main developer of wmii I came to the conclusion that
|
|
||||||
wmii is too clunky for my needs. I don't need so many funky features
|
|
||||||
and all this hype about remote control through a 9P service, I only
|
|
||||||
want to manage my windows in a simple, but dynamic way. wmii never got
|
|
||||||
finished because I listened to users, who proposed arbitrary ideas I
|
|
||||||
considered useful. This resulted in an extreme <a href="http://www.jwz.org/doc/cadt.html">CADT</a>
|
|
||||||
development model, which was a mistake. Thus the philosophy of
|
|
||||||
dwm is simply <i>to fit my needs</i> (maybe yours as well). That's it.
|
|
||||||
</p>
|
|
||||||
<h3>Differences to wmii</h3
|
|
||||||
<p>
|
|
||||||
In contrast to wmii, dwm is only a window manager, and nothing else.
|
|
||||||
Hence, it is much smaller, faster and simpler.
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
dwm has no 9P support, no menu, no editable tagbars,
|
|
||||||
no shell-based configuration and remote control and comes without
|
|
||||||
any additional tools like printing the selection or warping the
|
|
||||||
mouse.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
dwm is only a single binary, it's source code is intended to never
|
|
||||||
exceed 2000 SLOC.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
dwm is customized through editing its source code, that makes it
|
|
||||||
extremely fast and secure - it does not process any input data which
|
|
||||||
hasn't been known at compile time, except window title names.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
dwm is based on tagging and dynamic window management (however simpler
|
|
||||||
than wmii or larswm).
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
dwm don't distinguishes between layers, there is no floating or
|
|
||||||
managed layer. Wether the clients of currently selected tag are
|
|
||||||
managed or not, you can re-arrange all clients on the fly. Popup-
|
|
||||||
and fixed-size windows are treated unmanaged.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
dwm uses 1-pixel borders to provide the maximum of screen real
|
|
||||||
estate to clients. Small titlebars are only drawn in front of unfocused
|
|
||||||
clients.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
dwm reads from <b>stdin</b> to print arbitrary status text (like the
|
|
||||||
date, load, battery charge). That's much simpler than larsremote,
|
|
||||||
wmiir and what not...
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
garbeam <b>does not</b> want any feedback to dwm. If you ask for support,
|
|
||||||
feature requests, or if you report bugs, they will be <b>ignored</b>
|
|
||||||
with a high chance. dwm is only intended to fit garbeams needs.
|
|
||||||
However you are free to download and distribute/relicense it, with the
|
|
||||||
conditions of the <a href="http://wmii.de/cgi-bin/hgwebdir.cgi/dwm?f=f10eb1139362;file=LICENSE;style=raw">MIT/X Consortium license</a>.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h3>Screenshot</h3>
|
|
||||||
<p>
|
|
||||||
<a href="http://wmii.de/shots/dwm-20060714.png">Click here for a screenshot</a> (20060714)
|
|
||||||
</p>
|
|
||||||
<h3>Development</h3>
|
|
||||||
<p>
|
|
||||||
dwm is actively developed in parallel to wmii. You can <a href="http://wmii.de/cgi-bin/hgwebdir.cgi/dwm">browse</a> its source code repository or get a copy using <a href="http://www.selenic.com/mercurial/">Mercurial</a> with following command:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<code>hg clone http://wmii.de/cgi-bin/hgwebdir.cgi/dwm</code>
|
|
||||||
</p>
|
|
||||||
<h3>Download</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="http://wmii.de/download/dwm-0.1.tar.gz">dwm 0.1</a> (12kb) (20060714)</li>
|
|
||||||
</ul>
|
|
||||||
<h3>Miscellaneous</h3>
|
|
||||||
<p>
|
|
||||||
You can purchase this <a href="https://www.spreadshirt.net/shop.php?op=article&article_id=3298632&view=403">tricot</a>
|
|
||||||
if you like dwm and the dwm logo, which has been designed by garbeam.
|
|
||||||
</p>
|
|
||||||
<p><small>--Anselm (20060714)</small></p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
BIN
dwm.png
BIN
dwm.png
Binary file not shown.
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 373 B |
216
event.c
216
event.c
@ -1,216 +0,0 @@
|
|||||||
/*
|
|
||||||
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
|
||||||
* See LICENSE file for license details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <X11/keysym.h>
|
|
||||||
#include <X11/Xatom.h>
|
|
||||||
|
|
||||||
#include "dwm.h"
|
|
||||||
|
|
||||||
/* local functions */
|
|
||||||
static void buttonpress(XEvent *e);
|
|
||||||
static void configurerequest(XEvent *e);
|
|
||||||
static void destroynotify(XEvent *e);
|
|
||||||
static void enternotify(XEvent *e);
|
|
||||||
static void leavenotify(XEvent *e);
|
|
||||||
static void expose(XEvent *e);
|
|
||||||
static void keymapnotify(XEvent *e);
|
|
||||||
static void maprequest(XEvent *e);
|
|
||||||
static void propertynotify(XEvent *e);
|
|
||||||
static void unmapnotify(XEvent *e);
|
|
||||||
|
|
||||||
void (*handler[LASTEvent]) (XEvent *) = {
|
|
||||||
[ButtonPress] = buttonpress,
|
|
||||||
[ConfigureRequest] = configurerequest,
|
|
||||||
[DestroyNotify] = destroynotify,
|
|
||||||
[EnterNotify] = enternotify,
|
|
||||||
[LeaveNotify] = leavenotify,
|
|
||||||
[Expose] = expose,
|
|
||||||
[KeyPress] = keypress,
|
|
||||||
[KeymapNotify] = keymapnotify,
|
|
||||||
[MapRequest] = maprequest,
|
|
||||||
[PropertyNotify] = propertynotify,
|
|
||||||
[UnmapNotify] = unmapnotify
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
buttonpress(XEvent *e)
|
|
||||||
{
|
|
||||||
XButtonPressedEvent *ev = &e->xbutton;
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
if(barwin == ev->window)
|
|
||||||
barclick(ev);
|
|
||||||
else if((c = getclient(ev->window))) {
|
|
||||||
craise(c);
|
|
||||||
switch(ev->button) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
case Button1:
|
|
||||||
mmove(c);
|
|
||||||
break;
|
|
||||||
case Button2:
|
|
||||||
lower(c);
|
|
||||||
break;
|
|
||||||
case Button3:
|
|
||||||
mresize(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
configurerequest(XEvent *e)
|
|
||||||
{
|
|
||||||
XConfigureRequestEvent *ev = &e->xconfigurerequest;
|
|
||||||
XWindowChanges wc;
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
ev->value_mask &= ~CWSibling;
|
|
||||||
if((c = getclient(ev->window))) {
|
|
||||||
gravitate(c, True);
|
|
||||||
if(ev->value_mask & CWX)
|
|
||||||
c->x = ev->x;
|
|
||||||
if(ev->value_mask & CWY)
|
|
||||||
c->y = ev->y;
|
|
||||||
if(ev->value_mask & CWWidth)
|
|
||||||
c->w = ev->width;
|
|
||||||
if(ev->value_mask & CWHeight)
|
|
||||||
c->h = ev->height;
|
|
||||||
if(ev->value_mask & CWBorderWidth)
|
|
||||||
c->border = 1;
|
|
||||||
gravitate(c, False);
|
|
||||||
resize(c, True);
|
|
||||||
}
|
|
||||||
|
|
||||||
wc.x = ev->x;
|
|
||||||
wc.y = ev->y;
|
|
||||||
wc.width = ev->width;
|
|
||||||
wc.height = ev->height;
|
|
||||||
wc.border_width = 1;
|
|
||||||
wc.sibling = None;
|
|
||||||
wc.stack_mode = Above;
|
|
||||||
ev->value_mask &= ~CWStackMode;
|
|
||||||
ev->value_mask |= CWBorderWidth;
|
|
||||||
XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
|
|
||||||
XFlush(dpy);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
destroynotify(XEvent *e)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
|
||||||
|
|
||||||
if((c = getclient(ev->window)))
|
|
||||||
unmanage(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
enternotify(XEvent *e)
|
|
||||||
{
|
|
||||||
XCrossingEvent *ev = &e->xcrossing;
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if((c = getclient(ev->window)))
|
|
||||||
focus(c);
|
|
||||||
else if(ev->window == root)
|
|
||||||
issel = True;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
leavenotify(XEvent *e)
|
|
||||||
{
|
|
||||||
XCrossingEvent *ev = &e->xcrossing;
|
|
||||||
|
|
||||||
if((ev->window == root) && !ev->same_screen)
|
|
||||||
issel = True;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
expose(XEvent *e)
|
|
||||||
{
|
|
||||||
XExposeEvent *ev = &e->xexpose;
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
if(ev->count == 0) {
|
|
||||||
if((c = gettitle(ev->window)))
|
|
||||||
draw_client(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
keymapnotify(XEvent *e)
|
|
||||||
{
|
|
||||||
update_keys();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
maprequest(XEvent *e)
|
|
||||||
{
|
|
||||||
XMapRequestEvent *ev = &e->xmaprequest;
|
|
||||||
static XWindowAttributes wa;
|
|
||||||
|
|
||||||
if(!XGetWindowAttributes(dpy, ev->window, &wa))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(wa.override_redirect) {
|
|
||||||
XSelectInput(dpy, ev->window,
|
|
||||||
(StructureNotifyMask | PropertyChangeMask));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!getclient(ev->window))
|
|
||||||
manage(ev->window, &wa);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
propertynotify(XEvent *e)
|
|
||||||
{
|
|
||||||
XPropertyEvent *ev = &e->xproperty;
|
|
||||||
Window trans;
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
if(ev->state == PropertyDelete)
|
|
||||||
return; /* ignore */
|
|
||||||
|
|
||||||
if((c = getclient(ev->window))) {
|
|
||||||
if(ev->atom == wm_atom[WMProtocols]) {
|
|
||||||
c->proto = win_proto(c->win);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (ev->atom) {
|
|
||||||
default: break;
|
|
||||||
case XA_WM_TRANSIENT_FOR:
|
|
||||||
XGetTransientForHint(dpy, c->win, &trans);
|
|
||||||
if(!c->floating && (c->floating = (trans != 0)))
|
|
||||||
arrange(NULL);
|
|
||||||
break;
|
|
||||||
case XA_WM_NORMAL_HINTS:
|
|
||||||
update_size(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(ev->atom == XA_WM_NAME || ev->atom == net_atom[NetWMName]) {
|
|
||||||
update_name(c);
|
|
||||||
draw_client(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
unmapnotify(XEvent *e)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
XUnmapEvent *ev = &e->xunmap;
|
|
||||||
|
|
||||||
if((c = getclient(ev->window)))
|
|
||||||
unmanage(c);
|
|
||||||
}
|
|
327
main.c
327
main.c
@ -1,327 +0,0 @@
|
|||||||
/*
|
|
||||||
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
|
||||||
* See LICENSE file for license details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <X11/cursorfont.h>
|
|
||||||
#include <X11/Xatom.h>
|
|
||||||
#include <X11/Xproto.h>
|
|
||||||
|
|
||||||
#include "dwm.h"
|
|
||||||
|
|
||||||
/********** CUSTOMIZE **********/
|
|
||||||
|
|
||||||
char *tags[TLast] = {
|
|
||||||
[Tscratch] = "scratch",
|
|
||||||
[Tdev] = "dev",
|
|
||||||
[Twww] = "www",
|
|
||||||
[Twork] = "work",
|
|
||||||
};
|
|
||||||
|
|
||||||
/********** CUSTOMIZE **********/
|
|
||||||
|
|
||||||
/* X structs */
|
|
||||||
Display *dpy;
|
|
||||||
Window root, barwin;
|
|
||||||
Atom wm_atom[WMLast], net_atom[NetLast];
|
|
||||||
Cursor cursor[CurLast];
|
|
||||||
Bool running = True;
|
|
||||||
Bool issel;
|
|
||||||
|
|
||||||
int tsel = Tdev; /* default tag */
|
|
||||||
int screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
|
|
||||||
char stext[1024];
|
|
||||||
|
|
||||||
DC dc = {0};
|
|
||||||
Client *clients = NULL;
|
|
||||||
Client *sel = NULL;
|
|
||||||
|
|
||||||
static Bool other_wm_running;
|
|
||||||
static const char version[] =
|
|
||||||
"dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
|
|
||||||
static int (*x_error_handler) (Display *, XErrorEvent *);
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage() { error("usage: dwm [-v]\n"); }
|
|
||||||
|
|
||||||
static void
|
|
||||||
scan_wins()
|
|
||||||
{
|
|
||||||
unsigned int i, num;
|
|
||||||
Window *wins;
|
|
||||||
XWindowAttributes wa;
|
|
||||||
Window d1, d2;
|
|
||||||
|
|
||||||
if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
|
|
||||||
for(i = 0; i < num; i++) {
|
|
||||||
if(!XGetWindowAttributes(dpy, wins[i], &wa))
|
|
||||||
continue;
|
|
||||||
if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
|
|
||||||
continue;
|
|
||||||
if(wa.map_state == IsViewable)
|
|
||||||
manage(wins[i], &wa);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(wins)
|
|
||||||
XFree(wins);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
|
|
||||||
{
|
|
||||||
Atom real;
|
|
||||||
int format;
|
|
||||||
unsigned long res, extra;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format,
|
|
||||||
&res, &extra, prop);
|
|
||||||
|
|
||||||
if(status != Success || *prop == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(res == 0) {
|
|
||||||
free((void *) *prop);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
win_proto(Window w)
|
|
||||||
{
|
|
||||||
unsigned char *protocols;
|
|
||||||
long res;
|
|
||||||
int protos = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L, &protocols);
|
|
||||||
if(res <= 0) {
|
|
||||||
return protos;
|
|
||||||
}
|
|
||||||
for(i = 0; i < res; i++) {
|
|
||||||
if(protocols[i] == wm_atom[WMDelete])
|
|
||||||
protos |= WM_PROTOCOL_DELWIN;
|
|
||||||
}
|
|
||||||
free((char *) protocols);
|
|
||||||
return protos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
send_message(Window w, Atom a, long value)
|
|
||||||
{
|
|
||||||
XEvent e;
|
|
||||||
|
|
||||||
e.type = ClientMessage;
|
|
||||||
e.xclient.window = w;
|
|
||||||
e.xclient.message_type = a;
|
|
||||||
e.xclient.format = 32;
|
|
||||||
e.xclient.data.l[0] = value;
|
|
||||||
e.xclient.data.l[1] = CurrentTime;
|
|
||||||
XSendEvent(dpy, w, False, NoEventMask, &e);
|
|
||||||
XFlush(dpy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There's no way to check accesses to destroyed windows, thus
|
|
||||||
* those cases are ignored (especially on UnmapNotify's).
|
|
||||||
* Other types of errors call Xlib's default error handler, which
|
|
||||||
* calls exit().
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
error_handler(Display *dpy, XErrorEvent *error)
|
|
||||||
{
|
|
||||||
if(error->error_code == BadWindow
|
|
||||||
|| (error->request_code == X_SetInputFocus
|
|
||||||
&& error->error_code == BadMatch)
|
|
||||||
|| (error->request_code == X_PolyText8
|
|
||||||
&& error->error_code == BadDrawable)
|
|
||||||
|| (error->request_code == X_PolyFillRectangle
|
|
||||||
&& error->error_code == BadDrawable)
|
|
||||||
|| (error->request_code == X_PolySegment
|
|
||||||
&& error->error_code == BadDrawable)
|
|
||||||
|| (error->request_code == X_ConfigureWindow
|
|
||||||
&& error->error_code == BadMatch)
|
|
||||||
|| (error->request_code == X_GrabKey
|
|
||||||
&& error->error_code == BadAccess))
|
|
||||||
return 0;
|
|
||||||
fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
|
|
||||||
error->request_code, error->error_code);
|
|
||||||
return x_error_handler(dpy, error); /* may call exit() */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Startup Error handler to check if another window manager
|
|
||||||
* is already running.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
startup_error_handler(Display *dpy, XErrorEvent *error)
|
|
||||||
{
|
|
||||||
other_wm_running = True;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cleanup()
|
|
||||||
{
|
|
||||||
while(sel) {
|
|
||||||
resize(sel, True);
|
|
||||||
unmanage(sel);
|
|
||||||
}
|
|
||||||
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
quit(Arg *arg)
|
|
||||||
{
|
|
||||||
running = False;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int i, n;
|
|
||||||
fd_set rd;
|
|
||||||
XSetWindowAttributes wa;
|
|
||||||
unsigned int mask;
|
|
||||||
Bool readstdin = True;
|
|
||||||
Window w;
|
|
||||||
XEvent ev;
|
|
||||||
|
|
||||||
for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
|
|
||||||
switch (argv[i][1]) {
|
|
||||||
case 'v':
|
|
||||||
fprintf(stdout, "%s", version);
|
|
||||||
exit(0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dpy = XOpenDisplay(0);
|
|
||||||
if(!dpy)
|
|
||||||
error("dwm: cannot connect X server\n");
|
|
||||||
|
|
||||||
screen = DefaultScreen(dpy);
|
|
||||||
root = RootWindow(dpy, screen);
|
|
||||||
|
|
||||||
/* check if another WM is already running */
|
|
||||||
other_wm_running = False;
|
|
||||||
XSetErrorHandler(startup_error_handler);
|
|
||||||
/* this causes an error if some other WM is running */
|
|
||||||
XSelectInput(dpy, root, SubstructureRedirectMask);
|
|
||||||
XFlush(dpy);
|
|
||||||
|
|
||||||
if(other_wm_running)
|
|
||||||
error("dwm: another window manager is already running\n");
|
|
||||||
|
|
||||||
XSetErrorHandler(0);
|
|
||||||
x_error_handler = XSetErrorHandler(error_handler);
|
|
||||||
|
|
||||||
/* init atoms */
|
|
||||||
wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
|
|
||||||
wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
|
|
||||||
net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
|
|
||||||
net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
|
|
||||||
XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32,
|
|
||||||
PropModeReplace, (unsigned char *) net_atom, NetLast);
|
|
||||||
|
|
||||||
/* init cursors */
|
|
||||||
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
|
|
||||||
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
|
|
||||||
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
|
|
||||||
|
|
||||||
update_keys();
|
|
||||||
|
|
||||||
/* style */
|
|
||||||
dc.bg = initcolor(BGCOLOR);
|
|
||||||
dc.fg = initcolor(FGCOLOR);
|
|
||||||
dc.border = initcolor(BORDERCOLOR);
|
|
||||||
initfont(FONT);
|
|
||||||
|
|
||||||
sx = sy = 0;
|
|
||||||
sw = DisplayWidth(dpy, screen);
|
|
||||||
sh = DisplayHeight(dpy, screen);
|
|
||||||
mw = (sw * MASTERW) / 100;
|
|
||||||
|
|
||||||
wa.override_redirect = 1;
|
|
||||||
wa.background_pixmap = ParentRelative;
|
|
||||||
wa.event_mask = ButtonPressMask | ExposureMask;
|
|
||||||
|
|
||||||
bx = by = 0;
|
|
||||||
bw = sw;
|
|
||||||
dc.h = bh = dc.font.height + 4;
|
|
||||||
barwin = XCreateWindow(dpy, root, bx, by, bw, bh, 0, DefaultDepth(dpy, screen),
|
|
||||||
CopyFromParent, DefaultVisual(dpy, screen),
|
|
||||||
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
|
|
||||||
XDefineCursor(dpy, barwin, cursor[CurNormal]);
|
|
||||||
XMapRaised(dpy, barwin);
|
|
||||||
|
|
||||||
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
|
|
||||||
dc.gc = XCreateGC(dpy, root, 0, 0);
|
|
||||||
draw_bar();
|
|
||||||
|
|
||||||
issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
|
|
||||||
|
|
||||||
wa.event_mask = SubstructureRedirectMask | EnterWindowMask \
|
|
||||||
| LeaveWindowMask;
|
|
||||||
wa.cursor = cursor[CurNormal];
|
|
||||||
|
|
||||||
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
|
|
||||||
|
|
||||||
strcpy(stext, "dwm-"VERSION);
|
|
||||||
scan_wins();
|
|
||||||
|
|
||||||
/* main event loop, reads status text from stdin as well */
|
|
||||||
Mainloop:
|
|
||||||
while(running) {
|
|
||||||
FD_ZERO(&rd);
|
|
||||||
if(readstdin)
|
|
||||||
FD_SET(STDIN_FILENO, &rd);
|
|
||||||
FD_SET(ConnectionNumber(dpy), &rd);
|
|
||||||
|
|
||||||
i = select(ConnectionNumber(dpy) + 1, &rd, 0, 0, 0);
|
|
||||||
if(i == -1 && errno == EINTR)
|
|
||||||
continue;
|
|
||||||
if(i < 0)
|
|
||||||
error("select failed\n");
|
|
||||||
else if(i > 0) {
|
|
||||||
if(FD_ISSET(ConnectionNumber(dpy), &rd)) {
|
|
||||||
while(XPending(dpy)) {
|
|
||||||
XNextEvent(dpy, &ev);
|
|
||||||
if(handler[ev.type])
|
|
||||||
(handler[ev.type])(&ev); /* call handler */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(readstdin && FD_ISSET(STDIN_FILENO, &rd)) {
|
|
||||||
i = n = 0;
|
|
||||||
for(;;) {
|
|
||||||
if((i = getchar()) == EOF) {
|
|
||||||
/* broken pipe/end of producer */
|
|
||||||
readstdin = False;
|
|
||||||
strcpy(stext, "broken pipe");
|
|
||||||
goto Mainloop;
|
|
||||||
}
|
|
||||||
if(i == '\n' || n >= sizeof(stext) - 1)
|
|
||||||
break;
|
|
||||||
stext[n++] = i;
|
|
||||||
}
|
|
||||||
stext[n] = 0;
|
|
||||||
draw_bar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup();
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
42
transient.c
Normal file
42
transient.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* cc transient.c -o transient -lX11 */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
Display *d;
|
||||||
|
Window r, f, t = None;
|
||||||
|
XSizeHints h;
|
||||||
|
XEvent e;
|
||||||
|
|
||||||
|
d = XOpenDisplay(NULL);
|
||||||
|
if (!d)
|
||||||
|
exit(1);
|
||||||
|
r = DefaultRootWindow(d);
|
||||||
|
|
||||||
|
f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
|
||||||
|
h.min_width = h.max_width = h.min_height = h.max_height = 400;
|
||||||
|
h.flags = PMinSize | PMaxSize;
|
||||||
|
XSetWMNormalHints(d, f, &h);
|
||||||
|
XStoreName(d, f, "floating");
|
||||||
|
XMapWindow(d, f);
|
||||||
|
|
||||||
|
XSelectInput(d, f, ExposureMask);
|
||||||
|
while (1) {
|
||||||
|
XNextEvent(d, &e);
|
||||||
|
|
||||||
|
if (t == None) {
|
||||||
|
sleep(5);
|
||||||
|
t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
|
||||||
|
XSetTransientForHint(d, t, f);
|
||||||
|
XStoreName(d, t, "transient");
|
||||||
|
XMapWindow(d, t);
|
||||||
|
XSelectInput(d, t, ExposureMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XCloseDisplay(d);
|
||||||
|
exit(0);
|
||||||
|
}
|
68
util.c
68
util.c
@ -1,59 +1,37 @@
|
|||||||
/*
|
/* See LICENSE file for copyright and license details. */
|
||||||
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
#include <errno.h>
|
||||||
* See LICENSE file for license details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <string.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "dwm.h"
|
#include "util.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
error(const char *errstr, ...) {
|
die(const char *fmt, ...)
|
||||||
va_list ap;
|
|
||||||
va_start(ap, errstr);
|
|
||||||
vfprintf(stderr, errstr, ap);
|
|
||||||
va_end(ap);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bad_malloc(unsigned int size)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "fatal: could not malloc() %d bytes\n",
|
va_list ap;
|
||||||
(int) size);
|
int saved_errno;
|
||||||
|
|
||||||
|
saved_errno = errno;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (fmt[0] && fmt[strlen(fmt)-1] == ':')
|
||||||
|
fprintf(stderr, " %s", strerror(saved_errno));
|
||||||
|
fputc('\n', stderr);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
emallocz(unsigned int size)
|
ecalloc(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
void *res = calloc(1, size);
|
void *p;
|
||||||
if(!res)
|
|
||||||
bad_malloc(size);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
if (!(p = calloc(nmemb, size)))
|
||||||
spawn(Arg *arg)
|
die("calloc:");
|
||||||
{
|
return p;
|
||||||
char **argv = (char **)arg->argv;
|
|
||||||
if(!argv || !argv[0])
|
|
||||||
return;
|
|
||||||
if(fork() == 0) {
|
|
||||||
if(fork() == 0) {
|
|
||||||
if(dpy)
|
|
||||||
close(ConnectionNumber(dpy));
|
|
||||||
setsid();
|
|
||||||
execvp(argv[0], argv);
|
|
||||||
fprintf(stderr, "dwm: execvp %s", argv[0]);
|
|
||||||
perror(" failed");
|
|
||||||
}
|
|
||||||
exit (0);
|
|
||||||
}
|
|
||||||
wait(0);
|
|
||||||
}
|
}
|
||||||
|
9
util.h
Normal file
9
util.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
|
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
|
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
|
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
|
||||||
|
#define LENGTH(X) (sizeof (X) / sizeof (X)[0])
|
||||||
|
|
||||||
|
void die(const char *fmt, ...);
|
||||||
|
void *ecalloc(size_t nmemb, size_t size);
|
Loading…
x
Reference in New Issue
Block a user