Compare commits
552 Commits
METACITY_2
...
METACITY_2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a70fc3259f | ||
![]() |
094df1295c | ||
![]() |
8db78742c3 | ||
![]() |
9c337d0a8f | ||
![]() |
e0c8b245ef | ||
![]() |
8d314aead8 | ||
![]() |
15d28dfd97 | ||
![]() |
48b00403b6 | ||
![]() |
d78fab02eb | ||
![]() |
d275e4bbc2 | ||
![]() |
d26ad2c490 | ||
![]() |
cef58f676d | ||
![]() |
214bcceaea | ||
![]() |
5e1439f89e | ||
![]() |
eb40c5c2cf | ||
![]() |
ba3cf950ba | ||
![]() |
d26eb15bff | ||
![]() |
aed65de051 | ||
![]() |
bf767e8420 | ||
![]() |
ad65fda1a8 | ||
![]() |
170d3ed121 | ||
![]() |
7f1dfffab3 | ||
![]() |
40e3058408 | ||
![]() |
3e05c7c6c6 | ||
![]() |
fd135d0869 | ||
![]() |
5452a0ecac | ||
![]() |
6557627d8f | ||
![]() |
cfa2e165ba | ||
![]() |
e9999aa93c | ||
![]() |
b8788e9c0d | ||
![]() |
60293ee189 | ||
![]() |
2541da1d83 | ||
![]() |
bd537dcfc6 | ||
![]() |
b95dd0574c | ||
![]() |
49dca9e5b1 | ||
![]() |
02a8fb4a37 | ||
![]() |
1a5b861dff | ||
![]() |
0970829146 | ||
![]() |
3ee131245c | ||
![]() |
80a1a8d26b | ||
![]() |
d1aaf6a9b1 | ||
![]() |
5590e8878b | ||
![]() |
de703edfd7 | ||
![]() |
772bbb8d91 | ||
![]() |
b17b88595e | ||
![]() |
e64d1bf881 | ||
![]() |
40696052ca | ||
![]() |
b567879eac | ||
![]() |
0163c58ee1 | ||
![]() |
bc3b64f922 | ||
![]() |
765cb51df3 | ||
![]() |
b56824f650 | ||
![]() |
c613fed9ef | ||
![]() |
6c18374142 | ||
![]() |
a64b868dbd | ||
![]() |
cfd2d87fea | ||
![]() |
77349f6878 | ||
![]() |
5efd276a22 | ||
![]() |
373f6de13e | ||
![]() |
e0a4c2a1df | ||
![]() |
9feebc05c7 | ||
![]() |
d7917c02fe | ||
![]() |
1d0b5ef660 | ||
![]() |
ee84fbb81f | ||
![]() |
6a1abc7482 | ||
![]() |
7f36a8c7d1 | ||
![]() |
d1d7767033 | ||
![]() |
18973c23b3 | ||
![]() |
93289dc950 | ||
![]() |
817c357335 | ||
![]() |
f5bf830754 | ||
![]() |
b3a1122b2a | ||
![]() |
c7d9042e5d | ||
![]() |
4512f8317a | ||
![]() |
effec94613 | ||
![]() |
c9c67387ce | ||
![]() |
81089c2d8c | ||
![]() |
04c9c3e058 | ||
![]() |
4d5cc9d0bb | ||
![]() |
0d88e93787 | ||
![]() |
5a8af8c2fb | ||
![]() |
e8097a6f8f | ||
![]() |
cb27f0c4be | ||
![]() |
c3a5c4c169 | ||
![]() |
bc46b2f0e0 | ||
![]() |
ce657d7807 | ||
![]() |
9702903343 | ||
![]() |
15a05467bd | ||
![]() |
0041f49d3f | ||
![]() |
0cfb05a661 | ||
![]() |
c6b475b251 | ||
![]() |
37a1e6f57b | ||
![]() |
0c5cacf7cc | ||
![]() |
95e5a13131 | ||
![]() |
c1a88f5457 | ||
![]() |
70b6a57003 | ||
![]() |
915c2db3b9 | ||
![]() |
eb647577c3 | ||
![]() |
1094410ff8 | ||
![]() |
6e90c238e8 | ||
![]() |
44a63a9911 | ||
![]() |
149e8d12cd | ||
![]() |
9888f0434d | ||
![]() |
370982b812 | ||
![]() |
5c5de1c6b3 | ||
![]() |
5ba2fa893f | ||
![]() |
4eb8a93c83 | ||
![]() |
3da0b1c7d9 | ||
![]() |
aa62466091 | ||
![]() |
337812d51d | ||
![]() |
17ac646f70 | ||
![]() |
e3cfa163d0 | ||
![]() |
9657b6cebe | ||
![]() |
90b8a5a20b | ||
![]() |
54c50e96e7 | ||
![]() |
8c2e8ddf5c | ||
![]() |
9740b3f1df | ||
![]() |
0c57ebca70 | ||
![]() |
ae577d7724 | ||
![]() |
82e5cb578c | ||
![]() |
4ba0ce89c4 | ||
![]() |
0df65b9f9f | ||
![]() |
30e3cf5050 | ||
![]() |
25ca0e21db | ||
![]() |
f08337d939 | ||
![]() |
372dc090fd | ||
![]() |
81b6316081 | ||
![]() |
fc4a0aef0d | ||
![]() |
a1bb0e0015 | ||
![]() |
b8e5a4d707 | ||
![]() |
979392efa5 | ||
![]() |
9de7b59e93 | ||
![]() |
0388149904 | ||
![]() |
7b0cd87838 | ||
![]() |
7641c6f952 | ||
![]() |
261c9a74ef | ||
![]() |
a544f68ac9 | ||
![]() |
ba9d2d1a71 | ||
![]() |
f4920a9249 | ||
![]() |
94b6dde6bb | ||
![]() |
791ab07bd4 | ||
![]() |
437093dee0 | ||
![]() |
407ec7b495 | ||
![]() |
3407dffed0 | ||
![]() |
e802acf413 | ||
![]() |
f001625e5b | ||
![]() |
43a726efe7 | ||
![]() |
f37245ace2 | ||
![]() |
08ddfbb884 | ||
![]() |
e96e7ffc89 | ||
![]() |
2926f0a501 | ||
![]() |
6c325e9070 | ||
![]() |
efc82ee1b9 | ||
![]() |
5ae85e9c07 | ||
![]() |
74b3bca93d | ||
![]() |
e7e41b045d | ||
![]() |
47f67eb270 | ||
![]() |
e608366a8e | ||
![]() |
03a3183b1c | ||
![]() |
e64a42732f | ||
![]() |
45a2c2e905 | ||
![]() |
f5f20efe0d | ||
![]() |
49a9e74900 | ||
![]() |
207eef305e | ||
![]() |
4694ded7cd | ||
![]() |
d027c27ca1 | ||
![]() |
ee26de98de | ||
![]() |
94e75ba53c | ||
![]() |
f4e602a791 | ||
![]() |
6ab198ac22 | ||
![]() |
a030448cde | ||
![]() |
5da8c8f708 | ||
![]() |
09cc9e5d93 | ||
![]() |
195d136faa | ||
![]() |
d2cd398594 | ||
![]() |
8232b8ba6d | ||
![]() |
cfa98e02fc | ||
![]() |
efa3a05a35 | ||
![]() |
34fdccd3fb | ||
![]() |
b9db62bc43 | ||
![]() |
9ae52f1e46 | ||
![]() |
419b29f5b4 | ||
![]() |
0134973907 | ||
![]() |
fcb791d5a0 | ||
![]() |
175565eb71 | ||
![]() |
aa91d9f78b | ||
![]() |
730715228a | ||
![]() |
e151a2f153 | ||
![]() |
1a04ec9f33 | ||
![]() |
3d47456f56 | ||
![]() |
3bdf5ea05e | ||
![]() |
4b91c5aa03 | ||
![]() |
0932b98c34 | ||
![]() |
cbb0b8e66c | ||
![]() |
a6a7407faa | ||
![]() |
a5c4eaa55c | ||
![]() |
44cbcaa387 | ||
![]() |
a5237524b2 | ||
![]() |
9e062cd7a8 | ||
![]() |
5eddcaef89 | ||
![]() |
95bddff99d | ||
![]() |
34ea09264a | ||
![]() |
20c5761bcd | ||
![]() |
900de3c304 | ||
![]() |
8b7447b282 | ||
![]() |
66f03613b7 | ||
![]() |
f1b58398b0 | ||
![]() |
cbb4a91113 | ||
![]() |
b9002db37f | ||
![]() |
7e29e47e4b | ||
![]() |
0f9bdb18f5 | ||
![]() |
29d17da1ba | ||
![]() |
ce78866002 | ||
![]() |
0ac412da0f | ||
![]() |
2ba63f3462 | ||
![]() |
590c2d72ab | ||
![]() |
db3fe54006 | ||
![]() |
b23b32f84d | ||
![]() |
c39a03ad59 | ||
![]() |
0ac034ad4c | ||
![]() |
8d36bbd7ab | ||
![]() |
e74969bd17 | ||
![]() |
b5a99f049c | ||
![]() |
f86c3e6253 | ||
![]() |
964e69127c | ||
![]() |
f3a4631395 | ||
![]() |
1afc7df221 | ||
![]() |
51521d147d | ||
![]() |
c3b9b816f7 | ||
![]() |
f881cdaae6 | ||
![]() |
600501924f | ||
![]() |
80d64e6418 | ||
![]() |
c36a344387 | ||
![]() |
2581654922 | ||
![]() |
d86c90a162 | ||
![]() |
9ed1636ffe | ||
![]() |
bb9cc21d8e | ||
![]() |
b9529231b4 | ||
![]() |
689bcd14aa | ||
![]() |
42440b17e8 | ||
![]() |
27e35b8bcd | ||
![]() |
501264647e | ||
![]() |
fb09ca1868 | ||
![]() |
8a847ee7dc | ||
![]() |
2c41717e30 | ||
![]() |
2fb121b1c9 | ||
![]() |
c17e916978 | ||
![]() |
75109ac211 | ||
![]() |
02bcf06809 | ||
![]() |
c540438b91 | ||
![]() |
154e38e71e | ||
![]() |
7179d77d0c | ||
![]() |
4c3a20c3f2 | ||
![]() |
b78ad2e12d | ||
![]() |
f36d236a55 | ||
![]() |
9a72bf1858 | ||
![]() |
79857803de | ||
![]() |
4fcc9f052e | ||
![]() |
8c5369d522 | ||
![]() |
311052d555 | ||
![]() |
d299fbd8da | ||
![]() |
8a5cce91bf | ||
![]() |
7a598e5567 | ||
![]() |
ceb771aeb6 | ||
![]() |
ebae7a654e | ||
![]() |
1e0d6c3346 | ||
![]() |
ff652ff407 | ||
![]() |
f6853d0947 | ||
![]() |
6ec56406cf | ||
![]() |
00dcef82e3 | ||
![]() |
f15e959634 | ||
![]() |
43c7a44e1d | ||
![]() |
9cdd64b58f | ||
![]() |
1cd4938224 | ||
![]() |
f3446fad9a | ||
![]() |
d81fdce482 | ||
![]() |
585e362526 | ||
![]() |
8984fd358b | ||
![]() |
583596178f | ||
![]() |
ae148bc89f | ||
![]() |
dc5a81ac77 | ||
![]() |
b51e6bdaa4 | ||
![]() |
95e4c6ac2a | ||
![]() |
9e86812928 | ||
![]() |
43dd208874 | ||
![]() |
e8a9a6063b | ||
![]() |
e22eea105f | ||
![]() |
319f590e1a | ||
![]() |
69090f0bf0 | ||
![]() |
f289b64030 | ||
![]() |
cb57ebd470 | ||
![]() |
509495e224 | ||
![]() |
96f64031d4 | ||
![]() |
9abae5b0a2 | ||
![]() |
98c3b06ffd | ||
![]() |
1af2020151 | ||
![]() |
88a0d1ff03 | ||
![]() |
28958e51ef | ||
![]() |
78a2866980 | ||
![]() |
6f6e533380 | ||
![]() |
f7b55bfdcc | ||
![]() |
5975c80270 | ||
![]() |
7e0b4d4a78 | ||
![]() |
f51eed31d8 | ||
![]() |
197c81178c | ||
![]() |
dc73aaeb39 | ||
![]() |
9c08499787 | ||
![]() |
8e2d576805 | ||
![]() |
26ea31107f | ||
![]() |
a6620b663b | ||
![]() |
dccd7a9b99 | ||
![]() |
badb397bce | ||
![]() |
812f783084 | ||
![]() |
826a0c4e10 | ||
![]() |
ebb788140a | ||
![]() |
637d35a74b | ||
![]() |
2be93847ce | ||
![]() |
f0a74e2e95 | ||
![]() |
b30802e35f | ||
![]() |
086f74fb29 | ||
![]() |
b908e45208 | ||
![]() |
23cefa0bb5 | ||
![]() |
42639fc9fb | ||
![]() |
a38c16e57e | ||
![]() |
a535ef6117 | ||
![]() |
eb42281fd4 | ||
![]() |
93902aabfd | ||
![]() |
7d068e6909 | ||
![]() |
7593c6fdee | ||
![]() |
4e66c5dc6c | ||
![]() |
a62b3c8b29 | ||
![]() |
8c3437fd27 | ||
![]() |
efeedae712 | ||
![]() |
b392d206d7 | ||
![]() |
d826e620a9 | ||
![]() |
1db28d3b3f | ||
![]() |
b6177f74a7 | ||
![]() |
086f3d807e | ||
![]() |
6b72d622a5 | ||
![]() |
f0a811421f | ||
![]() |
b3a72a61fd | ||
![]() |
f94a3d08e0 | ||
![]() |
d910267364 | ||
![]() |
d7b4eec74a | ||
![]() |
86b34a45b1 | ||
![]() |
34c04823ff | ||
![]() |
7cff2734d1 | ||
![]() |
e5dc1b01ac | ||
![]() |
6e577c12c1 | ||
![]() |
97b629ad5b | ||
![]() |
5eca441b1c | ||
![]() |
8a8171ebc7 | ||
![]() |
0243071f15 | ||
![]() |
de42a62f4e | ||
![]() |
854e58fd82 | ||
![]() |
fb49dabcc2 | ||
![]() |
b0d3660c91 | ||
![]() |
dbcacfa5ba | ||
![]() |
e51e7ab77a | ||
![]() |
6cda7d0b11 | ||
![]() |
c7a72aeed3 | ||
![]() |
e354442c93 | ||
![]() |
3e3bbe0eb5 | ||
![]() |
82a6ba0238 | ||
![]() |
82a43d88f5 | ||
![]() |
c3b63c96d7 | ||
![]() |
899b6347b1 | ||
![]() |
213846a685 | ||
![]() |
346a8b5aaf | ||
![]() |
5faeb552b7 | ||
![]() |
b44845ad66 | ||
![]() |
f1097bfbe1 | ||
![]() |
47353f88c7 | ||
![]() |
7ff56e67e9 | ||
![]() |
d7cac40332 | ||
![]() |
e0e6dab50f | ||
![]() |
00e572800c | ||
![]() |
702eab3a6c | ||
![]() |
3ed032bf8b | ||
![]() |
b3f3014058 | ||
![]() |
39f2c804a3 | ||
![]() |
4dfc8d16be | ||
![]() |
bab3f73370 | ||
![]() |
dc9d951255 | ||
![]() |
fecaa42962 | ||
![]() |
8057a2f68a | ||
![]() |
9bad861649 | ||
![]() |
deed8016ed | ||
![]() |
b168954ed3 | ||
![]() |
fb5a3a8998 | ||
![]() |
459d8f9c9d | ||
![]() |
1efd5432ef | ||
![]() |
31b211550f | ||
![]() |
538a06fd55 | ||
![]() |
be44a1d9a5 | ||
![]() |
e694f07144 | ||
![]() |
2b780e5486 | ||
![]() |
9e8800561e | ||
![]() |
5fba648e85 | ||
![]() |
019b5cacc3 | ||
![]() |
81e52735a2 | ||
![]() |
9bcdc8be00 | ||
![]() |
a7c8cea1b5 | ||
![]() |
47f0557175 | ||
![]() |
24c91c3a37 | ||
![]() |
89b00f25a7 | ||
![]() |
8ebadbce28 | ||
![]() |
875e6dc0f9 | ||
![]() |
7df9ce1731 | ||
![]() |
8d07496c75 | ||
![]() |
c776871d52 | ||
![]() |
7fea250304 | ||
![]() |
6617781f4f | ||
![]() |
ac31a7f143 | ||
![]() |
fffb277250 | ||
![]() |
966c399154 | ||
![]() |
fb448b2f31 | ||
![]() |
85815f8188 | ||
![]() |
22bbeb0ae0 | ||
![]() |
3e4253f23e | ||
![]() |
400e82daa3 | ||
![]() |
0a513b0678 | ||
![]() |
b4743ee236 | ||
![]() |
dd8acae43c | ||
![]() |
e28902b102 | ||
![]() |
d5bcea27e3 | ||
![]() |
d0e109f96c | ||
![]() |
9d68b98bc9 | ||
![]() |
a242f622ea | ||
![]() |
4e2d5154fe | ||
![]() |
d5e31129d5 | ||
![]() |
b7f1a5fae7 | ||
![]() |
fe20139722 | ||
![]() |
c6b3408398 | ||
![]() |
d4b91dc654 | ||
![]() |
8da3b943a9 | ||
![]() |
3a745537f0 | ||
![]() |
3d62f360fe | ||
![]() |
bfd67fadef | ||
![]() |
2f74af1c04 | ||
![]() |
49f9ba96cc | ||
![]() |
90ff51acdb | ||
![]() |
f7c2b446f2 | ||
![]() |
619e2c36b5 | ||
![]() |
737d3cbbf5 | ||
![]() |
6aaf2738c9 | ||
![]() |
31ba0b1f95 | ||
![]() |
68eb780c75 | ||
![]() |
03498549b2 | ||
![]() |
6077c26cdf | ||
![]() |
0498d55314 | ||
![]() |
4b5eda0b0a | ||
![]() |
0cf10075e1 | ||
![]() |
ceb2f700f5 | ||
![]() |
2e19e3c9f7 | ||
![]() |
aad6035c57 | ||
![]() |
2eeb984e4e | ||
![]() |
a1c5f93ef0 | ||
![]() |
b0af92b1d8 | ||
![]() |
068c16b162 | ||
![]() |
91bf299f16 | ||
![]() |
f24be6ccc3 | ||
![]() |
0cbf47ca30 | ||
![]() |
a40a9eccf4 | ||
![]() |
e19d4c048a | ||
![]() |
35bdbec054 | ||
![]() |
af845f4de7 | ||
![]() |
d466c615ed | ||
![]() |
cc3c995d80 | ||
![]() |
a4fe1ad960 | ||
![]() |
750cb70f69 | ||
![]() |
4f70698493 | ||
![]() |
30ff4540d0 | ||
![]() |
71552fb08d | ||
![]() |
2536b82084 | ||
![]() |
d70e08039c | ||
![]() |
49fe8f0399 | ||
![]() |
4e9ac83b15 | ||
![]() |
0f1f2283e7 | ||
![]() |
2567ee81b8 | ||
![]() |
b29a41fa43 | ||
![]() |
1b8dd23884 | ||
![]() |
860a1298b5 | ||
![]() |
7366527aa7 | ||
![]() |
6e7669e4d7 | ||
![]() |
691c6f802d | ||
![]() |
009a439259 | ||
![]() |
82b064ed7d | ||
![]() |
bb35f88925 | ||
![]() |
9b39feab95 | ||
![]() |
74cf783be3 | ||
![]() |
6c38f577fe | ||
![]() |
5f65ca07d7 | ||
![]() |
2c73ab41ed | ||
![]() |
53bddf9ceb | ||
![]() |
5151c5102d | ||
![]() |
973662d5c3 | ||
![]() |
b94beb3289 | ||
![]() |
af83598ad3 | ||
![]() |
41e99288b5 | ||
![]() |
a3460b8ac8 | ||
![]() |
9598affa03 | ||
![]() |
2679d3cf00 | ||
![]() |
487c6cfaaa | ||
![]() |
052a794427 | ||
![]() |
6fe940afc7 | ||
![]() |
912afb6e6b | ||
![]() |
6d2c558bd8 | ||
![]() |
8f5c12d76d | ||
![]() |
0494b044d5 | ||
![]() |
3f7203a3a4 | ||
![]() |
9138b9aa3c | ||
![]() |
de41777c69 | ||
![]() |
7b9877258f | ||
![]() |
41120f2a79 | ||
![]() |
6f8a7f1870 | ||
![]() |
7fbbd0200f | ||
![]() |
cf4ef8cab2 | ||
![]() |
011a7f77a6 | ||
![]() |
80fb12a0b9 | ||
![]() |
80c4897ced | ||
![]() |
c56914dd5d | ||
![]() |
559f6e8f19 | ||
![]() |
718b077b82 | ||
![]() |
14dccacfde | ||
![]() |
82ceb7c837 | ||
![]() |
03481ae2d0 | ||
![]() |
17b4eab4d4 | ||
![]() |
cb1b7deefa | ||
![]() |
cd40cc9edb | ||
![]() |
e8267b20fe | ||
![]() |
c64ada94a5 | ||
![]() |
a32503a75a | ||
![]() |
53268f985f | ||
![]() |
e4e200a1dc | ||
![]() |
e9053f1f52 | ||
![]() |
e3156b007d | ||
![]() |
e691b664e3 | ||
![]() |
4ee70f0780 | ||
![]() |
995e8da006 | ||
![]() |
5fd4fb96f7 | ||
![]() |
1d818b7b7c | ||
![]() |
8183c509d9 | ||
![]() |
115c086eb9 | ||
![]() |
6603ee6084 | ||
![]() |
f5c10f387b | ||
![]() |
458e125c09 | ||
![]() |
b98ae68f39 | ||
![]() |
d23fa8c870 | ||
![]() |
ebc69e1127 | ||
![]() |
4c64e88631 | ||
![]() |
dd56688cd8 |
@@ -25,3 +25,6 @@ INSTALL
|
||||
intl
|
||||
ABOUT-NLS
|
||||
COPYING
|
||||
intltool-*
|
||||
metacity.spec
|
||||
autom4te.cache
|
||||
|
@@ -1,4 +1,5 @@
|
||||
|
||||
SUBDIRS=src po
|
||||
SUBDIRS=src po doc
|
||||
|
||||
EXTRA_DIST=HACKING theme-format.txt metacity.spec
|
||||
EXTRA_DIST=HACKING metacity.spec.in metacity.spec \
|
||||
intltool-extract.in intltool-merge.in intltool-update.in
|
||||
|
373
README
373
README
@@ -9,19 +9,63 @@ your petty hangups about version numbers.
|
||||
COMPILING METACITY
|
||||
===
|
||||
|
||||
You need GTK+ 2.0, ideally the latest in the 2.0.x series.
|
||||
You need GTK+ 2.0, ideally the latest in the 2.0.x series. For
|
||||
multihead/Xinerama support to work, you need GTK+ 2.1.x or 2.2. For
|
||||
startup notification to work you need libstartup-notification at
|
||||
http://www.freedesktop.org/software/startup-notification/ or on the
|
||||
GNOME ftp site. You also need GConf 1.2 (unless building a funky
|
||||
extra-small embedded metacity with --disable-gconf).
|
||||
|
||||
REPORTING BUGS AND SUBMITTING PATCHES
|
||||
===
|
||||
|
||||
Report new bugs on http://bugzilla.gnome.org.
|
||||
Report new bugs on http://bugzilla.gnome.org. Please check for
|
||||
duplicates, *especially* if you are reporting a feature request.
|
||||
|
||||
Feel free to send patches too; Metacity is really small and simple, so
|
||||
if you find a bug or want to add a feature it should be pretty easy.
|
||||
Send me mail, or put the patch in bugzilla.
|
||||
Please do *not* add "me too!" or "yes I really want this!" comments to
|
||||
feature requests in bugzilla. Please read
|
||||
http://pobox.com/~hp/features.html prior to adding any kind of flame
|
||||
about missing features or misfeatures.
|
||||
|
||||
Feel free to send patches too; Metacity is relatively small and
|
||||
simple, so if you find a bug or want to add a feature it should be
|
||||
pretty easy. Send me mail, or put the patch in bugzilla.
|
||||
|
||||
See the HACKING file for some notes on hacking Metacity.
|
||||
|
||||
SHRINKING METACITY
|
||||
===
|
||||
|
||||
Not that metacity is huge (<400K binary last I checked), but about
|
||||
half of that is in the preferences handling, in static strings that
|
||||
aren't essential, and in the theme engine.
|
||||
|
||||
You can strip about 70K from the metacity binary by compiling with
|
||||
options such as:
|
||||
|
||||
--disable-gconf
|
||||
--disable-sm
|
||||
--disable-verbose
|
||||
--disable-startup-notification
|
||||
|
||||
However the result is no good for desktop use, all prefs have to be
|
||||
hardcoded in the binary, for example. If you wanted to make a really
|
||||
small metacity, here's some additional stuff you might consider
|
||||
implementing:
|
||||
|
||||
- add --disable-themes, which would replace theme.c and theme-parser.c
|
||||
with a hardcoded implementation of the interface in theme.h,
|
||||
should save about 80K. This should be fairly easy.
|
||||
|
||||
- add --disable-gtk, which would implement the interface in ui.h
|
||||
without using GTK. This one is easier than you think because the
|
||||
main part of the window manager doesn't use GTK directly, but is
|
||||
still fairly hard to do. You would probably have to give up some
|
||||
of the features, such as window menus, as menus are pretty complex
|
||||
to implement well. So time may be better spent adding a GTK
|
||||
configure script feature to build GTK with only a small core set of
|
||||
functionality.
|
||||
|
||||
METACITY FEATURES
|
||||
===
|
||||
|
||||
@@ -31,8 +75,22 @@ METACITY FEATURES
|
||||
- Uses GTK+ 2.0 for drawing window frames. This means colors, fonts,
|
||||
etc. come from GTK+ theme.
|
||||
|
||||
- Does not expose the concept of "window manager" to the user. Some
|
||||
of the features in the GNOME control panel and other parts of the
|
||||
desktop happen to be implemented in metacity, such as changing your
|
||||
window border theme, or changing your window navigation shorcuts,
|
||||
but the user doesn't need to know this.
|
||||
|
||||
- Includes only the window manager; does not try to be a desktop
|
||||
environment. The pager, configuration, etc. are all separate and
|
||||
modular. The "libwnck" library (which I also wrote) is available
|
||||
for writing metacity extensions, pagers, and so on. (But libwnck
|
||||
isn't metacity specific, or GNOME-dependent; it requires only GTK,
|
||||
and should work with KWin, fvwm2, and other EWMH-compliant WMs.)
|
||||
|
||||
- Has a simple theme system and a couple of extra themes come with it.
|
||||
Change themes via gconf-editor or gconftool:
|
||||
Change themes via gconf-editor or gconftool or GNOME themes control
|
||||
panel:
|
||||
gconftool-2 --type=string --set /apps/metacity/general/theme Crux
|
||||
gconftool-2 --type=string --set /apps/metacity/general/theme Gorilla
|
||||
gconftool-2 --type=string --set /apps/metacity/general/theme Atlanta
|
||||
@@ -51,19 +109,28 @@ METACITY FEATURES
|
||||
gconftool-2 --type=string --set /apps/metacity/general/focus_mode sloppy
|
||||
gconftool-2 --type=string --set /apps/metacity/general/focus_mode click
|
||||
|
||||
- Global keybindings:
|
||||
Alt-F1 to Alt-F6 switch workspaces
|
||||
Alt-1 to Alt-6 switch workspaces
|
||||
- Global keybinding defaults include:
|
||||
|
||||
Alt-Tab forward cycle window focus
|
||||
Alt-Shift-Tab backward cycle focus
|
||||
Alt-Ctrl-Tab forward cycle focus among panels
|
||||
Alt-Ctrl-Shift-Tab backward cycle focus among panels
|
||||
Alt-Escape focus previous window
|
||||
Alt-Escape cycle window focus without a popup thingy
|
||||
Ctrl-Alt-Left Arrow previous workspace
|
||||
Ctrl-Alt-Right Arrow next workspace
|
||||
Ctrl-Alt-D minimize/unminimize all, to show desktop
|
||||
|
||||
Change keybindings for example:
|
||||
|
||||
unst gconftool-2 --type=string --set /apps/metacity/global_keybindings/switch_to_workspace_1 '<Alt>F1'
|
||||
|
||||
Also try the GNOME keyboard shortcuts control panel, or
|
||||
gconf-editor.
|
||||
|
||||
See metacity.schemas for all available bindings.
|
||||
|
||||
- Window keybindings:
|
||||
|
||||
Alt-space window menu
|
||||
|
||||
Mnemonics work in the menu. That is, Alt-space then underlined
|
||||
@@ -77,6 +144,10 @@ METACITY FEATURES
|
||||
Choose Resize from menu, and nothing happens yet, but
|
||||
eventually I might implement something.
|
||||
|
||||
Keybindings for things like maximize window, vertical maximize,
|
||||
etc. can be bound, but may not all exist by default. See
|
||||
metacity.schemas.
|
||||
|
||||
- Window mouse bindings:
|
||||
|
||||
Clicking anywhere on frame with button 1 will raise/focus window
|
||||
@@ -90,11 +161,15 @@ METACITY FEATURES
|
||||
If you click and drag the titlebar with button 1 it moves the
|
||||
window.
|
||||
|
||||
If you click anywhere on the frame with button 2 it lowers the
|
||||
window.
|
||||
|
||||
If you click anywhere on the frame with button 3 it shows the
|
||||
window menu.
|
||||
|
||||
If you hold down Alt and click inside a window, it will move the
|
||||
window (buttons 1 and 2) or show menu (button 3).
|
||||
If you hold down Super (windows key) and click inside a window, it
|
||||
will move the window (buttons 1 and 2) or show menu (button 3).
|
||||
Or you can configure a different modifier for this.
|
||||
|
||||
If you pick up a window with button 1 and then switch workspaces
|
||||
the window will come with you to the new workspace, this is
|
||||
@@ -110,9 +185,10 @@ METACITY FEATURES
|
||||
for session-aware applications.
|
||||
|
||||
- Metacity implements much of the new window manager spec from
|
||||
freedesktop.org, and much of the ICCCM. But then there are
|
||||
parts of each that it doesn't implement, just because I haven't
|
||||
yet.
|
||||
freedesktop.org
|
||||
(http://www.freedesktop.org/standards/wm-spec.html), and much of
|
||||
the ICCCM. But then there are parts of each that it doesn't
|
||||
implement, just because I haven't yet.
|
||||
|
||||
- Uses Pango to render text, so has cool i18n capabilities.
|
||||
Supports UTF-8 window titles and such.
|
||||
@@ -127,139 +203,77 @@ METACITY FEATURES
|
||||
- considers the panel when placing windows and maximizing
|
||||
them.
|
||||
|
||||
- handles the window manager selection from the ICCCM. Will exit if
|
||||
another WM claims it, and can claim it from another WM if you pass
|
||||
the --replace argument. So if you're running another
|
||||
ICCCM-compliant WM, you can run "metacity --replace" to replace it
|
||||
with Metacity.
|
||||
|
||||
- does basic colormap handling
|
||||
|
||||
- and much more! well, maybe not a lot more.
|
||||
|
||||
METACITY BUGS, NON-FEATURES, AND CAVEATS
|
||||
===
|
||||
|
||||
- If you want keybindings which are not the ones mentioned above
|
||||
as features, you have to edit keybindings.c and recompile.
|
||||
|
||||
- Some of the default keybindings (notable Alt+number) are total
|
||||
crackrock. This is just because I like those keybindings and
|
||||
things aren't configurable yet. Once bindings are configurable
|
||||
the dumb defaults will go away.
|
||||
|
||||
- You need an EWMH-spec compliant pager/tasklist to be able
|
||||
to navigate graphically; this does NOT include GNOME 1.x,
|
||||
but should include GNOME 2 and KDE 3.
|
||||
|
||||
- Metacity turns off its keybindings for Emacs, because I use
|
||||
Alt-space in Emacs, and getting a window menu annoys me.
|
||||
This is a broken feature that will go away when keybindings are
|
||||
configurable.
|
||||
|
||||
- I haven't even read the ICCCM section about colormaps. So if you
|
||||
have an 8-bit display you are probably screwed.
|
||||
|
||||
- Metacity doesn't properly claim the window manager selection
|
||||
as described in the ICCCM. But then, most other window managers
|
||||
don't handle this correctly either.
|
||||
|
||||
- There are probably other ICCCM-compliance issues.
|
||||
|
||||
- Window placement is always cascade for now; I want to implement
|
||||
"first fit, falling back to cascade if no fit."
|
||||
(Configurable placement algorithms are stupid though, don't
|
||||
send me patches for any bogus ones. Let's just pick a good one.)
|
||||
|
||||
- Should Metacity support flipping in right-to-left locales?
|
||||
I don't know what window managers look like in a right-to-left
|
||||
locale. I assume the window titles should be right-justified;
|
||||
should the window controls also be flipped?
|
||||
|
||||
- Resize menu item doesn't do anything. It's intended to enter
|
||||
resize-with-the-keyboard mode, similar to Move menu item.
|
||||
|
||||
- In GNOME 1.x, if you switch from sawfish to metacity without
|
||||
restarting X, the panel often ends up buried behind the Nautilus
|
||||
desktop window.
|
||||
|
||||
What happens is that the panel detects Sawfish has gone away, and
|
||||
turns on override redirect mode because no GNOME-aware WM is
|
||||
running (i.e. it goes into "ignore the window manager" mode). But
|
||||
the panel doesn't notice that Metacity has appeared and is
|
||||
(partially) GNOME-compliant. So Metacity doesn't see the override
|
||||
redirect panel, and leaves it behind the Nautilus desktop. I'm not
|
||||
sure whether Metacity or the panel is to blame for this.
|
||||
|
||||
(To debug - use "xwininfo" on the panel, if override redirect is
|
||||
"Yes" then Metacity won't have any awareness of a window and can't
|
||||
properly stack it above the desktop. If override redirect is "No"
|
||||
then Metacity can see the panel and handle it properly. Look at
|
||||
xstuff.c:xstuff_is_compliant_wm() in the panel to get started on
|
||||
how the panel deals with this.)
|
||||
|
||||
- In GNOME 1.x, If you have "put panel below other windows" turned on
|
||||
in panel Global Preferences, Miscellaneous tab, you need to change
|
||||
this to "Put panel on top of other windows." That's because
|
||||
Metacity uses semantic categories, not the legacy layer system in
|
||||
the GNOME spec. It treats things in the legacy "dock" layer as
|
||||
semantic type dock, but if you have the panel set to be in another
|
||||
layer, Metacity will think it's a normal window.
|
||||
|
||||
You can diagnose this problem because Metacity will put panels in
|
||||
the wrong place, and Alt+rightclick will let you perform operations
|
||||
like minimize/maximize, and Alt+leftclick will let you move the panel.
|
||||
If Metacity has detected that the panel is a panel, then none of
|
||||
this will be enabled.
|
||||
|
||||
I put a patch in the CVS version of the panel to fix this by
|
||||
setting the new non-legacy type hint, but a panel with that
|
||||
patch hasn't been released yet.
|
||||
See bugzilla: http://bugzilla.gnome.org/query.cgi
|
||||
|
||||
FAQ
|
||||
===
|
||||
|
||||
Q: Will you add my feature?
|
||||
|
||||
A: If it makes sense to turn on unconditionally,
|
||||
or is genuinely a harmless preference that I would not
|
||||
be embarrassed to put in a simple, uncluttered, user-friendly
|
||||
configuration dialog.
|
||||
A: If it makes sense to turn on unconditionally, or is genuinely a
|
||||
harmless preference that I would not be embarrassed to put in a
|
||||
simple, uncluttered, user-friendly configuration dialog.
|
||||
|
||||
If the only rationale for your feature is that other window
|
||||
managers have it, or that you are personally used to it, or something
|
||||
like that, then I will not be impressed. Metacity is firmly in the
|
||||
"choose good defaults" camp rather than the "offer 6 equally broken
|
||||
ways to do it, and let the user pick one" camp.
|
||||
managers have it, or that you are personally used to it, or
|
||||
something like that, then I will not be impressed. Metacity is
|
||||
firmly in the "choose good defaults" camp rather than the "offer 6
|
||||
equally broken ways to do it, and let the user pick one" camp.
|
||||
|
||||
This is part of a "no crackrock" policy, despite some exceptions
|
||||
I'm mildly embarrassed about. For example, multiple workspaces
|
||||
probably constitute crackrock, they confuse most users
|
||||
and really are not that useful if you have a decent tasklist and
|
||||
so on. But I am too used to them to turn them off.
|
||||
Or alternatively iconification/tasklist is crack, and workspaces/pager
|
||||
are good. But having both is certainly a bit wrong.
|
||||
Sloppy focus is probably crackrock too. Oh, and my Alt-1 thru Alt-6
|
||||
keybindings are definitely on crack.
|
||||
probably constitute crackrock, they confuse most users and really
|
||||
are not that useful if you have a decent tasklist and so on. But I
|
||||
am too used to them to turn them off. Or alternatively
|
||||
iconification/tasklist is crack, and workspaces/pager are good. But
|
||||
having both is certainly a bit wrong. Sloppy focus is probably
|
||||
crackrock too.
|
||||
|
||||
But don't think unlimited crack is OK just because I slipped up a
|
||||
little. No slippery slope here.
|
||||
little. No slippery slope here.
|
||||
|
||||
Don't let this discourage patches and fixes - I love those. ;-)
|
||||
Just be prepared to hear the above objections if your patch
|
||||
adds some crack-ridden configuration option.
|
||||
Just be prepared to hear the above objections if your patch adds
|
||||
some crack-ridden configuration option.
|
||||
|
||||
http://pobox.com/~hp/free-software-ui.html
|
||||
http://pobox.com/~hp/features.html
|
||||
|
||||
Q: Will Metacity be part of GNOME?
|
||||
|
||||
A: Many people are now asking for this, though it was not the original
|
||||
plan - Metacity started out as sort of an experiment.
|
||||
|
||||
A decision hasn't really been made but the issue will probably
|
||||
be raised shortly after the GNOME 2 release.
|
||||
A: It is officially part of GNOME as of GNOME 2.2. Prior to that,
|
||||
it was unofficially shipped as the default GNOME WM by several
|
||||
OS vendors.
|
||||
|
||||
Q: Is Metacity a Red Hat project?
|
||||
|
||||
A: Metacity is in no way funded, endorsed, or encouraged by Red Hat,
|
||||
Inc. - I'm guessing Red Hat would not consider "insufficient number
|
||||
of window managers for Linux" an urgent problem. Just a wild guess
|
||||
though.
|
||||
A: Metacity's original creation was in no way funded, endorsed, or
|
||||
encouraged by Red Hat, Inc. - I'm guessing Red Hat would not
|
||||
consider "insufficient number of window managers for Linux" an
|
||||
urgent problem. Just a wild guess though.
|
||||
|
||||
Now that metacity is the default WM however, Red Hat supports some
|
||||
bugfixing and other work.
|
||||
|
||||
Q: Why does Metacity remember the workspace/position of some apps
|
||||
but not others?
|
||||
but not others across logout/login?
|
||||
|
||||
A: Metacity only stores sizes/positions for apps that are session
|
||||
managed. As far as I can determine, there is no way to attempt
|
||||
to remember workspace/position for non-session-aware apps without
|
||||
A: Metacity only stores sizes/positions for apps that are session
|
||||
managed. As far as I can determine, there is no way to attempt to
|
||||
remember workspace/position for non-session-aware apps without
|
||||
causing a lot of weird effects.
|
||||
|
||||
The reason is that you don't know which non-SM-aware apps were
|
||||
@@ -312,14 +326,125 @@ A: I could conceivably be convinced to use viewports _instead_ of
|
||||
features traditionally associated with either kind if those
|
||||
features make sense.
|
||||
|
||||
Q: Why is the panel always on top?
|
||||
|
||||
A: Because it's a better user interface, and until we made this not
|
||||
configurable a bunch of apps were not getting fixed (the app
|
||||
authors were just saying "put your panel on the bottom" instead of
|
||||
properly supporting fullscreen mode, and such).
|
||||
|
||||
rationales.txt has the bugzilla URL for some flamefesting on this,
|
||||
if you want to go back and relive the glory.
|
||||
Read these and the bugzilla stuff before asking/commenting:
|
||||
http://pobox.com/~hp/free-software-ui.html
|
||||
http://pobox.com/~hp/features.html
|
||||
|
||||
Q: Why is there no edge flipping?
|
||||
|
||||
A: This one is also in rationales.txt. Because "ouija board" UI, where
|
||||
you just move the mouse around and the computer guesses what you
|
||||
mean, has a lot of issues. This includes mouse focus, shade-hover
|
||||
mode, edge flipping, autoraise, etc. Metacity has mouse focus and
|
||||
autoraise as a compromise, but these features are all confusing for
|
||||
many users, and cause problems with accessibility, fitt's law, and
|
||||
so on.
|
||||
|
||||
Read these and the bugzilla stuff before asking/commenting:
|
||||
http://pobox.com/~hp/free-software-ui.html
|
||||
http://pobox.com/~hp/features.html
|
||||
|
||||
Q: Why no wireframe move/resize?
|
||||
|
||||
A: Also in rationales.txt. Because it has low usability, and is a pain
|
||||
to implement, and there's no reason opaque move/resize should be a
|
||||
problem on any setup that can run a modern desktop worth a darn to
|
||||
begin with.
|
||||
|
||||
Read these and the bugzilla stuff before asking/commenting:
|
||||
http://pobox.com/~hp/free-software-ui.html
|
||||
http://pobox.com/~hp/features.html
|
||||
|
||||
Q: Why no XYZ?
|
||||
|
||||
A: You are probably getting the idea by now - check rationales.txt,
|
||||
query/search bugzilla, and read http://pobox.com/~hp/features.html
|
||||
and http://pobox.com/~hp/free-software-ui.html
|
||||
|
||||
Then sit down and answer the question for yourself. Is the feature
|
||||
good? What's the rationale for it? Answer "why" not just "why not."
|
||||
Justify in terms of users as a whole, not just users like
|
||||
yourself. How else can you solve the same problem? etc. If that
|
||||
leads you to a strong opinion, then please, post the rationale for
|
||||
discussion to an appropriate bugzilla bug, or to
|
||||
usability@gnome.org.
|
||||
|
||||
Please don't just "me too!" on bugzilla bugs, please don't think
|
||||
flames will get you anywhere, and please don't repeat rationale
|
||||
that's already been offered.
|
||||
|
||||
Q: Your dumb web pages you made me read talk about solving problems in
|
||||
fundamental ways instead of adding preferences or workarounds.
|
||||
What are some examples where metacity has done this?
|
||||
|
||||
A: There are quite a few, though many opportunities remain. Sometimes
|
||||
the real fix involves application changes. The metacity approach is
|
||||
that it's OK to require apps to change, though there are also
|
||||
plenty of workarounds in metacity for battles considered too hard
|
||||
to fight.
|
||||
|
||||
Here are some examples:
|
||||
|
||||
- fullscreen mode was introduced to allow position constraints,
|
||||
panel-on-top, and other such things to apply to normal windows
|
||||
while still allowing video players etc. to "just work"
|
||||
|
||||
- "whether to include minimized windows in Alt+Tab" was solved
|
||||
by putting minimized windows at the *end* of the tab order.
|
||||
|
||||
- Whether to pop up a feedback display during Alt+Tab was solved by
|
||||
having both Alt+Tab and Alt+Esc
|
||||
|
||||
- Whether to have a "kill" feature was solved by automatically
|
||||
detecting and offering to kill stuck apps. Better, metacity
|
||||
actually does "kill -9" on the process, it doesn't just
|
||||
disconnect the process from the X server. You'll appreciate this
|
||||
if you ever did a "kill" on Netscape 4, and watched it keep
|
||||
eating 100% CPU even though the X server had booted it.
|
||||
|
||||
- The workspaces vs. viewports mess was avoided by adding
|
||||
directional navigation and such to workspaces, see discussion
|
||||
earlier in this file.
|
||||
|
||||
- Instead of configurable placement algorithms, there's just one
|
||||
that works fairly well most of the time.
|
||||
|
||||
- To avoid excess CPU use during opaque move/resize, we rate limit
|
||||
the updates to the application window's size.
|
||||
|
||||
- Instead of configurable "show size of window while resizing,"
|
||||
it's only shown for windows where it matters, such as terminals.
|
||||
(Only use-case given for all windows is for web designers
|
||||
choosing their web browser size, but there are web sites and
|
||||
desktop backgrounds that do this for you.)
|
||||
|
||||
- Using startup notification, applications open on the workspace
|
||||
where you launched them, not the active workspace when their
|
||||
window is opened.
|
||||
|
||||
- and much more.
|
||||
|
||||
Q: I think metacity sucks.
|
||||
|
||||
A: Feel free to use any WM you like. The reason metacity follows the
|
||||
ICCCM and EWMH specifications is that it makes metacity a modular,
|
||||
interchangeable part in the desktop. libwnck-based apps such as the
|
||||
GNOME window list will work just fine with any EWMH-compliant WM.
|
||||
|
||||
Q: Did you spend a lot of time on this?
|
||||
|
||||
A: Originally the answer was no. Sadly the answer is now yes.
|
||||
Still, it's only 12,000 lines of code.
|
||||
|
||||
Q: How can you claim that you are anti-crack, while still
|
||||
writing a window manager?
|
||||
|
||||
A: I have no comment on that.
|
||||
|
||||
|
||||
|
12
acconfig.h
12
acconfig.h
@@ -1,12 +0,0 @@
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
#undef HAVE_CATGETS
|
||||
#undef HAVE_GETTEXT
|
||||
#undef HAVE_LC_MESSAGES
|
||||
#undef HAVE_STPCPY
|
||||
#undef ENABLE_NLS
|
||||
#undef HAVE_PTHREAD_H
|
||||
#undef GETTEXT_PACKAGE
|
||||
#undef HAVE_SHAPE_EXT
|
||||
#undef HAVE_XFT
|
||||
#undef HAVE_SM
|
59
autogen.sh
59
autogen.sh
@@ -12,6 +12,14 @@ FILE=src/display.c
|
||||
|
||||
DIE=0
|
||||
|
||||
AUTOMAKE=automake-1.4
|
||||
ACLOCAL=aclocal-1.4
|
||||
|
||||
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
|
||||
AUTOMAKE=automake
|
||||
ACLOCAL=aclocal
|
||||
}
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have autoconf installed to compile $PROJECT."
|
||||
@@ -20,7 +28,7 @@ DIE=0
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
||||
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "You must have automake installed to compile $PROJECT."
|
||||
echo "Get ftp://sourceware.cygnus.com/pub/automake/automake-1.4.tar.gz"
|
||||
@@ -38,16 +46,29 @@ DIE=0
|
||||
}
|
||||
}
|
||||
|
||||
grep "^AM_GLIB_GNU_GETTEXT" configure.in >/dev/null && {
|
||||
grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \
|
||||
(gettext --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`gettext' installed to compile $PROJECT."
|
||||
echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
}
|
||||
}
|
||||
CONFIGURE=configure.in
|
||||
if grep "^AM_[A-Z0-9_]\{1,\}_GETTEXT" "$CONFIGURE" >/dev/null; then
|
||||
if grep "sed.*POTFILES" "$CONFIGURE" >/dev/null; then
|
||||
GETTEXTIZE=""
|
||||
else
|
||||
if grep "^AM_GLIB_GNU_GETTEXT" "$CONFIGURE" >/dev/null; then
|
||||
GETTEXTIZE="glib-gettextize"
|
||||
GETTEXTIZE_URL="ftp://ftp.gtk.org/pub/gtk/v2.0/glib-2.0.0.tar.gz"
|
||||
else
|
||||
GETTEXTIZE="gettextize"
|
||||
GETTEXTIZE_URL="ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
|
||||
fi
|
||||
|
||||
$GETTEXTIZE --version < /dev/null > /dev/null 2>&1
|
||||
if test $? -ne 0; then
|
||||
echo
|
||||
echo "**Error**: You must have \`$GETTEXTIZE' installed to compile $PKG_NAME."
|
||||
echo "Get $GETTEXTIZE_URL"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
@@ -96,18 +117,26 @@ do
|
||||
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
|
||||
fi
|
||||
fi
|
||||
if grep "^AC_PROG_INTLTOOL" configure.in >/dev/null; then
|
||||
echo "Running intltoolize..."
|
||||
intltoolize --force --copy --automake
|
||||
fi
|
||||
if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
|
||||
echo "Running libtoolize..."
|
||||
libtoolize --force --copy
|
||||
fi
|
||||
echo "Running aclocal $aclocalinclude ..."
|
||||
aclocal $aclocalinclude
|
||||
|
||||
echo "Running $ACLOCAL $aclocalinclude ..."
|
||||
$ACLOCAL $aclocalinclude
|
||||
|
||||
if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
|
||||
echo "Running autoheader..."
|
||||
autoheader
|
||||
fi
|
||||
echo "Running automake --gnu $am_opt ..."
|
||||
automake --add-missing --gnu $am_opt
|
||||
|
||||
echo "Running $AUTOMAKE --gnu $am_opt ..."
|
||||
$AUTOMAKE --add-missing --gnu $am_opt
|
||||
|
||||
echo "Running autoconf ..."
|
||||
autoconf
|
||||
)
|
||||
|
237
configure.in
237
configure.in
@@ -1,23 +1,24 @@
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(src/display.c)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987
|
||||
AM_INIT_AUTOMAKE(metacity, 2.3.89)
|
||||
AM_INIT_AUTOMAKE(metacity, 2.4.8)
|
||||
|
||||
# Honor aclocal flags
|
||||
ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
|
||||
|
||||
GETTEXT_PACKAGE=metacity
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE")
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Name of default gettext domain])
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_PROG_INTLTOOL([0.21])
|
||||
AC_PROG_CC
|
||||
AC_ISC_POSIX
|
||||
AC_HEADER_STDC
|
||||
AC_ARG_PROGRAM
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
changequote(,)dnl
|
||||
@@ -27,10 +28,10 @@ if test "x$GCC" = "xyes"; then
|
||||
*) CFLAGS="$CFLAGS -Wall" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wshadow[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wshadow" ;;
|
||||
esac
|
||||
# case " $CFLAGS " in
|
||||
# *[\ \ ]-Wshadow[\ \ ]*) ;;
|
||||
# *) CFLAGS="$CFLAGS -Wshadow" ;;
|
||||
# esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
|
||||
@@ -81,38 +82,189 @@ if test "x$GCC" = "xyes"; then
|
||||
fi
|
||||
changequote([,])dnl
|
||||
|
||||
ALL_LINGUAS="da es gl lv ms no pl pt ru sk sv tr uk"
|
||||
METACITY_PC_MODULES='gtk+-2.0 >= 2.0.0'
|
||||
|
||||
AC_ARG_ENABLE(config-dialog, [ --enable-config-dialog enable the config dialog that you need with GNOME 2.0 (obsolete with GNOME 2.2)],enable_config_dialog=yes,enable_config_dialog=no)
|
||||
|
||||
AM_CONDITIONAL(BUILD_CONFIG_DIALOG, test x$enable_config_dialog = xyes)
|
||||
if test x$enable_config_dialog = xyes; then
|
||||
AC_DEFINE(BUILD_CONFIG_DIALOG,1,[Build configuration dialog])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(gconf, [ --disable-gconf disable gconf usage, for embedded/size-sensitive non-GNOME builds],enable_gconf=no,enable_gconf=yes)
|
||||
|
||||
if test x$enable_gconf = xyes; then
|
||||
AC_DEFINE(HAVE_GCONF,1,[Build with gconf support])
|
||||
METACITY_PC_MODULES="$METACITY_PC_MODULES gconf-2.0 >= 1.2.0"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(verbose-mode, [ --disable-verbose disable metacity's ability to do verbose logging, for embedded/size-sensitive custom builds],enable_verbose_mode=no,enable_verbose_mode=yes)
|
||||
|
||||
if test x$enable_verbose_mode = xyes; then
|
||||
AC_DEFINE(WITH_VERBOSE_MODE,1,[Build with verbose mode support])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(sm, [ --disable-sm disable metacity's session management support, for embedded/size-sensitive custom non-GNOME builds],enable_sm=no,enable_sm=auto)
|
||||
|
||||
AC_ARG_ENABLE(startup-notification, [ --disable-startup-notification disable metacity's startup notification support, for embedded/size-sensitive custom non-GNOME builds],enable_startup_notification=no,enable_startup_notification=auto)
|
||||
|
||||
## try definining HAVE_BACKTRACE
|
||||
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
|
||||
|
||||
ALL_LINGUAS="az ca cs da de el es fr gl hu it ja ko lv ms no pl pt pt_BR ro ru sk sv tr uk vi zh_CN zh_TW"
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
## here we get the flags we'll actually use
|
||||
PKG_CHECK_MODULES(METACITY, gtk+-2.0 >= 2.0.0 gconf-2.0 >= 1.1.9)
|
||||
PKG_CHECK_MODULES(METACITY_MESSAGE, gtk+-2.0 >= 2.0.0)
|
||||
PKG_CHECK_MODULES(METACITY_WINDOW_DEMO, gtk+-2.0 >= 2.0.0)
|
||||
|
||||
if test x$enable_config_dialog = xyes; then
|
||||
PKG_CHECK_MODULES(METACITY_PROPS, gtk+-2.0 >= 2.0.0 gconf-2.0 >= 1.1.9 libglade-2.0)
|
||||
fi
|
||||
|
||||
STARTUP_NOTIFICATION_VERSION=0.4
|
||||
AC_MSG_CHECKING([Startup notification library >= $STARTUP_NOTIFICATION_VERSION])
|
||||
if $PKG_CONFIG --atleast-version $STARTUP_NOTIFICATION_VERSION libstartup-notification-1.0; then
|
||||
have_startup_notification=yes
|
||||
else
|
||||
have_startup_notification=no
|
||||
fi
|
||||
AC_MSG_RESULT($have_startup_notification)
|
||||
|
||||
if test x$enable_startup_notification = xyes; then
|
||||
have_startup_notification=yes
|
||||
echo "startup-notification support forced on"
|
||||
elif test x$enable_startup_notification = xauto; then
|
||||
true
|
||||
else
|
||||
have_startup_notification=no
|
||||
fi
|
||||
|
||||
if test x$have_startup_notification = xyes; then
|
||||
echo "Building with libstartup-notification"
|
||||
METACITY_PC_MODULES="$METACITY_PC_MODULES libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_VERSION"
|
||||
AC_DEFINE(HAVE_STARTUP_NOTIFICATION, , [Building with startup notification support])
|
||||
else
|
||||
echo "Building without libstartup-notification"
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(METACITY, $METACITY_PC_MODULES)
|
||||
|
||||
if $PKG_CONFIG --atleast-version 2.1.0 gtk+-2.0; then
|
||||
AC_DEFINE(HAVE_GTK_MULTIHEAD,,[gtk+ with multihead support found])
|
||||
with_multihead=yes
|
||||
else
|
||||
with_multihead=no
|
||||
fi
|
||||
|
||||
AC_PATH_XTRA
|
||||
|
||||
CFLAGS="$METACITY_CFLAGS $CFLAGS $X_CFLAGS"
|
||||
ALL_X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||
|
||||
METACITY_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_LIBS"
|
||||
# Check for Xinerama extension (Solaris impl or Xfree impl)
|
||||
metacity_save_cppflags="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
|
||||
|
||||
found_sm=false
|
||||
use_solaris_xinerama=no
|
||||
use_xfree_xinerama=no
|
||||
case "$host" in
|
||||
*-*-solaris*)
|
||||
# Check for solaris
|
||||
use_solaris_xinerama=yes
|
||||
AC_CHECK_LIB(Xext, XineramaGetInfo,
|
||||
use_solaris_xinerama=yes, use_solaris_xinerama=no,
|
||||
$ALL_X_LIBS)
|
||||
if test "x$use_solaris_xinerama" = "xyes"; then
|
||||
AC_CHECK_HEADER(X11/extensions/xinerama.h,
|
||||
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
|
||||
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
|
||||
fi
|
||||
AC_DEFINE(HAVE_SOLARIS_XINERAMA, , [Have Solaris-style Xinerama])
|
||||
AC_DEFINE(HAVE_XINERAMA, , [Have some version of Xinerama]),
|
||||
use_solaris_xinerama=no,
|
||||
[#include <X11/Xlib.h>])
|
||||
fi
|
||||
AC_MSG_CHECKING(for Xinerama support on Solaris)
|
||||
AC_MSG_RESULT($use_solaris_xinerama);
|
||||
;;
|
||||
*)
|
||||
# Check for XFree
|
||||
use_xfree_xinerama=yes
|
||||
AC_CHECK_LIB(Xinerama, XineramaQueryExtension,
|
||||
[AC_CHECK_HEADER(X11/extensions/Xinerama.h,
|
||||
X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
|
||||
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
|
||||
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
|
||||
fi
|
||||
AC_DEFINE(HAVE_XFREE_XINERAMA, , [Have XFree86-style Xinerama])
|
||||
AC_DEFINE(HAVE_XINERAMA,, [Have some version of Xinerama]),
|
||||
use_xfree_xinerama=no,
|
||||
[#include <X11/Xlib.h>])],
|
||||
use_xfree_xinerama=no, -lXext $ALL_X_LIBS)
|
||||
AC_MSG_CHECKING(for Xinerama support on XFree86)
|
||||
AC_MSG_RESULT($use_xfree_xinerama);
|
||||
;;
|
||||
esac
|
||||
|
||||
CPPFLAGS="$metacity_save_cppflags"
|
||||
|
||||
SHAPE_LIBS=
|
||||
found_shape=no
|
||||
AC_CHECK_LIB(Xext, XShapeQueryExtension,
|
||||
[AC_CHECK_HEADER(X11/extensions/shape.h,
|
||||
SHAPE_LIBS=-lXext found_shape=yes)],
|
||||
, $ALL_X_LIBS)
|
||||
|
||||
if test "x$found_shape" = "xyes"; then
|
||||
AC_DEFINE(HAVE_SHAPE, , [Have the shape extension library])
|
||||
fi
|
||||
|
||||
RANDR_LIBS=
|
||||
found_randr=no
|
||||
AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration,
|
||||
[AC_CHECK_HEADER(X11/extensions/Xrandr.h,
|
||||
RANDR_LIBS=-lXrandr found_randr=yes,,
|
||||
[#include <X11/Xlib.h>])],
|
||||
, -lXrender $ALL_X_LIBS)
|
||||
|
||||
if test "x$found_randr" = "xyes"; then
|
||||
AC_DEFINE(HAVE_RANDR, , [Have the Xrandr extension library])
|
||||
fi
|
||||
|
||||
METACITY_LIBS="$RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_LIBS"
|
||||
METACITY_MESSAGE_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_MESSAGE_LIBS"
|
||||
METACITY_WINDOW_DEMO_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_WINDOW_DEMO_LIBS"
|
||||
METACITY_PROPS_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $METACITY_PROPS_LIBS"
|
||||
|
||||
found_sm=no
|
||||
case "$METACITY_LIBS" in
|
||||
*-lSM*)
|
||||
found_sm=true
|
||||
found_sm=yes
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_LIB(SM, SmcSaveYourselfDone,
|
||||
[AC_CHECK_HEADERS(X11/SM/SMlib.h,
|
||||
METACITY_LIBS="-lSM -lICE $METACITY_LIBS" found_sm=true)],
|
||||
METACITY_LIBS="-lSM -lICE $METACITY_LIBS" found_sm=no)],
|
||||
, $METACITY_LIBS)
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$found_sm" = "true"; then
|
||||
AC_DEFINE(HAVE_SM)
|
||||
if test x$enable_sm = xno; then
|
||||
found_sm=no
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "true")
|
||||
if test x$enable_sm = xyes; then
|
||||
if test "$found_sm" = "no"; then
|
||||
AC_MSG_ERROR([--enable-sm forced and -lSM not found])
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$found_sm" = "yes"; then
|
||||
AC_DEFINE(HAVE_SM, , [Building with SM support])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "yes")
|
||||
|
||||
HOST_ALIAS=$host_alias
|
||||
AC_SUBST(HOST_ALIAS)
|
||||
@@ -131,19 +283,60 @@ LDFLAGS="$METACITY_LIBS $LDFLAGS"
|
||||
AC_CHECK_FUNCS(gdk_pixbuf_new_from_stream)
|
||||
LDFLAGS=$save_LDFLAGS
|
||||
|
||||
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
|
||||
if test x$enable_gconf = xyes; then
|
||||
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
|
||||
if test x"$GCONFTOOL" = xno; then
|
||||
AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
|
||||
fi
|
||||
|
||||
if test x"$GCONFTOOL" = xno; then
|
||||
AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
|
||||
AM_GCONF_SOURCE_2
|
||||
fi
|
||||
|
||||
AM_GCONF_SOURCE_2
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
doc/Makefile
|
||||
src/Makefile
|
||||
src/wm-tester/Makefile
|
||||
src/libmetacity-private.pc
|
||||
src/tools/Makefile
|
||||
src/themes/Makefile
|
||||
po/Makefile.in
|
||||
metacity.spec
|
||||
])
|
||||
|
||||
if test x$enable_gconf = xno; then
|
||||
echo "*** WARNING WARNING WARNING WARNING WARNING"
|
||||
echo "*** Building without GConf"
|
||||
echo "*** This means there's no way to change prefs except"
|
||||
echo "*** hacking source code, at least for now."
|
||||
echo "*** Also, some prefs may have broken defaults."
|
||||
echo "*** Patches needed for a simple no-gconf config file."
|
||||
echo "*** This is intended for embedded systems etc., not for normal use."
|
||||
fi
|
||||
|
||||
if test x$enable_verbose_mode = xno; then
|
||||
echo "*** WARNING WARNING WARNING WARNING WARNING"
|
||||
echo "*** Building without verbose mode"
|
||||
echo "*** This means there's no way to debug metacity problems."
|
||||
echo "*** Please build normal desktop versions of metacity"
|
||||
echo "*** with verbose mode enabled so users can use it when they report bugs."
|
||||
fi
|
||||
|
||||
dnl ==========================================================================
|
||||
echo "
|
||||
metacity-$VERSION:
|
||||
|
||||
prefix: ${prefix}
|
||||
source code location: ${srcdir}
|
||||
compiler: ${CC}
|
||||
|
||||
GConf: ${enable_gconf}
|
||||
XFree86 Xinerama: ${use_xfree_xinerama}
|
||||
Solaris Xinerama: ${use_solaris_xinerama}
|
||||
Multihead: ${with_multihead}
|
||||
Startup notification: ${have_startup_notification}
|
||||
Session management: ${found_sm}
|
||||
Shape extension: ${found_shape}
|
||||
Resize-and-rotate: ${found_randr}
|
||||
Deprecated config dialog: ${enable_config_dialog}
|
||||
"
|
||||
|
2
doc/.cvsignore
Normal file
2
doc/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
2
doc/Makefile.am
Normal file
2
doc/Makefile.am
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
EXTRA_DIST=theme-format.txt metacity-theme.dtd
|
273
doc/metacity-theme.dtd
Normal file
273
doc/metacity-theme.dtd
Normal file
@@ -0,0 +1,273 @@
|
||||
<!--
|
||||
DTD for Metacity themes, as of Metacity 2.4.1
|
||||
Author: Ross Burton <ross@burtonini.com>
|
||||
Copyright (C) 2002 Ross Burton
|
||||
Licensed under the GPL, version 2
|
||||
-->
|
||||
|
||||
<!-- Top-level element -->
|
||||
<!ELEMENT metacity_theme (info,(window|frame_style_set|frame_style|frame_geometry|constant|draw_ops|menu_icon)+)>
|
||||
|
||||
<!-- Theme metadata -->
|
||||
<!ELEMENT info (name?|author?|copyright?|date?|description?)*>
|
||||
<!ELEMENT name (#PCDATA)>
|
||||
<!ELEMENT author (#PCDATA)>
|
||||
<!ELEMENT copyright (#PCDATA)>
|
||||
<!ELEMENT date (#PCDATA)>
|
||||
<!ELEMENT description (#PCDATA)>
|
||||
|
||||
<!ENTITY % xyrequired "
|
||||
x CDATA #REQUIRED
|
||||
y CDATA #REQUIRED
|
||||
">
|
||||
|
||||
<!ENTITY % xyimplied "
|
||||
x CDATA #IMPLIED
|
||||
y CDATA #IMPLIED
|
||||
">
|
||||
|
||||
<!ENTITY % widthheightrequired "
|
||||
width CDATA #REQUIRED
|
||||
height CDATA #REQUIRED
|
||||
">
|
||||
|
||||
<!ENTITY % widthheightimplied "
|
||||
width CDATA #IMPLIED
|
||||
height CDATA #IMPLIED
|
||||
">
|
||||
|
||||
<!ENTITY % boolean "(true|false)">
|
||||
|
||||
<!ENTITY % piece_positions "
|
||||
(entire_background|titlebar|titlebar_middle|left_titlebar_edge|right_titlebar_edge|top_titlebar_edge|bottom_titlebar_edge|title|left_edge|right_edge|bottom_edge|overlay)
|
||||
">
|
||||
|
||||
<!ENTITY % gtk-state "
|
||||
state (normal|prelight|active|selected|insensitive) #REQUIRED
|
||||
">
|
||||
|
||||
<!ENTITY % gtk-shadow "
|
||||
shadow (none|in|out|etched_in|etched_out) #REQUIRED
|
||||
">
|
||||
|
||||
|
||||
<!-- The actual theme -->
|
||||
|
||||
<!ELEMENT window EMPTY>
|
||||
<!ATTLIST window
|
||||
type (normal|dialog|modal_dialog|menu|utility|border) #REQUIRED
|
||||
style_set CDATA #REQUIRED
|
||||
>
|
||||
|
||||
|
||||
<!ELEMENT frame_style_set (frame+)>
|
||||
<!ATTLIST frame_style_set
|
||||
name CDATA #REQUIRED
|
||||
parent CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT frame EMPTY>
|
||||
<!ATTLIST frame
|
||||
focus (yes|no) #REQUIRED
|
||||
state (normal|maximized|shaded|maximized_and_shaded) #REQUIRED
|
||||
resize (both|horizontal|vertical|none) #REQUIRED
|
||||
style CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT frame_style (piece|button)*>
|
||||
<!ATTLIST frame_style
|
||||
name CDATA #REQUIRED
|
||||
geometry CDATA #REQUIRED
|
||||
parent CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT piece (draw_ops?)>
|
||||
<!ATTLIST piece
|
||||
position %piece_positions; #REQUIRED
|
||||
draw_ops CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT button (draw_ops?)>
|
||||
<!ATTLIST button
|
||||
function (menu|minimize|maximize|close|left_left_background|left_middle_background|left_right_background|right_left_background|right_middle_background|right_right_background) #REQUIRED
|
||||
state (normal|prelight|pressed) #REQUIRED
|
||||
draw_ops CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT frame_geometry (border|(aspect_ratio|distance))+>
|
||||
<!ATTLIST frame_geometry
|
||||
name CDATA #REQUIRED
|
||||
parent CDATA #IMPLIED
|
||||
title_scale (xx-small|x-small|small|medium|large|x-large|xx-large) #IMPLIED
|
||||
has_title (true|false) 'true'
|
||||
rounded_top_left %boolean; #IMPLIED
|
||||
rounded_top_right %boolean; #IMPLIED
|
||||
rounded_bottom_left %boolean; #IMPLIED
|
||||
rounded_bottom_right %boolean; #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT distance EMPTY>
|
||||
<!ATTLIST distance
|
||||
name (left_width|right_width|bottom_height|title_vertical_pad|right_titlebar_edge|left_titlebar_edge|button_width|button_height) #REQUIRED
|
||||
value CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT border EMPTY>
|
||||
<!ATTLIST border
|
||||
name CDATA #REQUIRED
|
||||
top CDATA #REQUIRED
|
||||
bottom CDATA #REQUIRED
|
||||
left CDATA #REQUIRED
|
||||
right CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT aspect_ratio EMPTY>
|
||||
<!ATTLIST aspect_ratio
|
||||
name CDATA #REQUIRED
|
||||
value CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT draw_ops (line|rectangle|arc|tint|gradient|image|gtk_arrow|gtk_box|gtk_vline|icon|title|clip|include|tile)*>
|
||||
<!-- not sure about this.. maybe it should be removed. see #3478 in theme-parser.c -->
|
||||
<!ATTLIST draw_ops
|
||||
name CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT line EMPTY>
|
||||
<!ATTLIST line
|
||||
color CDATA #REQUIRED
|
||||
x1 CDATA #REQUIRED
|
||||
y1 CDATA #REQUIRED
|
||||
x2 CDATA #REQUIRED
|
||||
y2 CDATA #REQUIRED
|
||||
width CDATA #IMPLIED
|
||||
dash_on_length CDATA #IMPLIED
|
||||
dash_off_length CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT rectangle EMPTY>
|
||||
<!ATTLIST rectangle
|
||||
color CDATA #REQUIRED
|
||||
%xyrequired;
|
||||
%widthheightrequired;
|
||||
filled %boolean; 'false'
|
||||
>
|
||||
|
||||
<!ELEMENT arc EMTPY>
|
||||
<!ATTLIST arc
|
||||
color CDATA #REQUIRED
|
||||
%xyrequired;
|
||||
%widthheightrequired;
|
||||
start_angle CDATA #REQUIRED
|
||||
extent_angle CDATA #REQUIRED
|
||||
filled %boolean; 'false'
|
||||
>
|
||||
|
||||
<!ELEMENT icon EMPTY>
|
||||
<!ATTLIST icon
|
||||
%xyrequired;
|
||||
width CDATA #REQUIRED
|
||||
height CDATA #REQUIRED
|
||||
alpha CDATA #IMPLIED
|
||||
fill_type (tile|scale) 'scale'
|
||||
>
|
||||
|
||||
<!ELEMENT image EMPTY>
|
||||
<!ATTLIST image
|
||||
filename CDATA #REQUIRED
|
||||
colorize CDATA #IMPLIED
|
||||
%xyrequired;
|
||||
%widthheightrequired;
|
||||
alpha CDATA #IMPLIED
|
||||
fill_type (tile|scale) 'scale'
|
||||
>
|
||||
|
||||
<!ELEMENT tile EMPTY>
|
||||
<!ATTLIST tile
|
||||
name CDATA #REQUIRED
|
||||
%xyrequired;
|
||||
%widthheightrequired;
|
||||
tile_xoffset CDATA #IMPLIED
|
||||
tile_yoffset CDATA #IMPLIED
|
||||
tile_width CDATA #REQUIRED
|
||||
tile_height CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT clip EMPTY>
|
||||
<!ATTLIST clip
|
||||
%xyrequired;
|
||||
%widthheightrequired;
|
||||
>
|
||||
|
||||
<!ELEMENT title EMPTY>
|
||||
<!ATTLIST title
|
||||
color CDATA #REQUIRED
|
||||
%xyrequired;
|
||||
>
|
||||
|
||||
<!ELEMENT tint EMPTY>
|
||||
<!ATTLIST tint
|
||||
color CDATA #REQUIRED
|
||||
%xyrequired;
|
||||
%widthheightrequired;
|
||||
alpha CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT gtk_box EMPTY>
|
||||
<!ATTLIST gtk_box
|
||||
%gtk-state;
|
||||
%gtk-shadow;
|
||||
%xyrequired;
|
||||
%widthheightrequired;
|
||||
>
|
||||
|
||||
<!ELEMENT gtk_arrow EMPTY>
|
||||
<!ATTLIST gtk_arrow
|
||||
%gtk-state;
|
||||
%gtk-shadow;
|
||||
arrow (up|down|left|right) #REQUIRED
|
||||
%xyrequired;
|
||||
%widthheightrequired;
|
||||
filed CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT gtk_vline EMPTY>
|
||||
<!ATTLIST gtk_vline
|
||||
%gtk-state;
|
||||
x CDATA #REQUIRED
|
||||
y1 CDATA #REQUIRED
|
||||
y2 CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT gradient (color)+>
|
||||
<!ATTLIST gradient
|
||||
type (vertical|horizontal|diagonal) #REQUIRED
|
||||
%xyrequired;
|
||||
%widthheightrequired;
|
||||
alpha CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT color EMPTY>
|
||||
<!ATTLIST color
|
||||
value CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT include EMPTY>
|
||||
<!ATTLIST include
|
||||
name CDATA #REQUIRED
|
||||
%xyimplied;
|
||||
%widthheightimplied;
|
||||
>
|
||||
|
||||
<!ELEMENT constant EMPTY>
|
||||
<!ATTLIST constant
|
||||
name CDATA #REQUIRED
|
||||
value CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT menu_icon (draw_ops?)>
|
||||
<!ATTLIST menu_icon
|
||||
function (close|maximize|minimize|unmaximize) #REQUIRED
|
||||
%gtk-state;
|
||||
draw_ops CDATA #IMPLIED
|
||||
>
|
@@ -18,8 +18,15 @@ Themes are in a simple XML-subset format.
|
||||
determines whether the title text height is included in the
|
||||
height calculation. if not specified, defaults to true.
|
||||
It also has an optional text_size="medium" attribute
|
||||
(same sizes as with Pango markup, xx-small thru medium thru xx-large) -->
|
||||
<frame_geometry name="normal" has_title="true" title_size="medium">
|
||||
(same sizes as with Pango markup, xx-small thru medium thru
|
||||
xx-large)
|
||||
|
||||
Finally it has optional args rounded_top_left=true,
|
||||
rounded_top_right=true, rounded_bottom_left=true,
|
||||
rounded_bottom_right=true.
|
||||
|
||||
-->
|
||||
<frame_geometry name="normal" has_title="true" title_scale="medium">
|
||||
<distance name="left_width" value="6"/>
|
||||
<distance name="right_width" value="6"/>
|
||||
<distance name="bottom_height" value="7"/>
|
||||
@@ -27,6 +34,8 @@ Themes are in a simple XML-subset format.
|
||||
<distance name="right_titlebar_edge" value="6"/>
|
||||
<distance name="button_width" value="17"/>
|
||||
<distance name="button_height" value="17"/>
|
||||
<!-- alternative to button_width button_height distances -->
|
||||
<aspect_ratio name="button" value="1.0"/>
|
||||
<distance name="title_vertical_pad" value="4"/>
|
||||
<border name="title_border" left="3" right="12" top="4" bottom="3"/>
|
||||
<border name="button_border" left="0" right="0" top="1" bottom="1"/>
|
||||
@@ -84,9 +93,9 @@ Themes are in a simple XML-subset format.
|
||||
width="3" dash_on_length="2" dash_off_length="3"/>
|
||||
<rectangle color="blend/gtk:fg[NORMAL]/gtk:bg[NORMAL]/0.7"
|
||||
x="0" y="0" width="width - 1" height="height - 1" filled="true"/>
|
||||
<arc x="0" y="0" width="width - 1" height="height - 1"
|
||||
<arc color="dark gray" x="0" y="0" width="width - 1" height="height - 1"
|
||||
filled="false" start_angle="30" extent_angle="180"/>
|
||||
<tint color="orange" alpha="0.5" x1="0" y1="0" x2="0" y2="height"/>
|
||||
<tint color="orange" alpha="0.5" x="0" y="0" width="width" height="height"/>
|
||||
<!-- may be vertical, horizontal, diagonal -->
|
||||
<gradient type="diagonal"
|
||||
x="10" y="30" width="width / 3" height="height / 4">
|
||||
@@ -164,9 +173,17 @@ Themes are in a simple XML-subset format.
|
||||
<!-- For buttons, drawing methods have to be provided for
|
||||
each of three states:
|
||||
normal, pressed, prelight
|
||||
and the button name must be provided:
|
||||
close, maximize, minimize, menu
|
||||
and the button function or position must be provided:
|
||||
close, maximize, minimize, menu,
|
||||
left_left_background, left_middle_background,
|
||||
left_right_background, right_left_background,
|
||||
right_middle_background, right_right_background
|
||||
So a working theme needs 3*4 = 12 button declarations
|
||||
and a theme may have up to 3*10 = 30 button declarations
|
||||
in order to handle button-rearrangement preferences.
|
||||
|
||||
(The name "function" for the attribute is from before the
|
||||
background values existed.)
|
||||
-->
|
||||
|
||||
<button function="close" state="normal" draw_ops="previously_named"/>
|
||||
@@ -210,7 +227,7 @@ Themes are in a simple XML-subset format.
|
||||
</frame_style_set>
|
||||
|
||||
<!-- Each window type needs a style set
|
||||
Types: normal, dialog, modal_dialog, toolbar, menu, utility
|
||||
Types: normal, dialog, modal_dialog, menu, utility, border
|
||||
-->
|
||||
<window type="normal" style_set="normal"/>
|
||||
|
@@ -1,14 +1,18 @@
|
||||
%define ver @VERSION@
|
||||
%define RELEASE 1
|
||||
%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
|
||||
|
||||
Summary: Metacity window manager
|
||||
Name: metacity
|
||||
Version: 2.3.89
|
||||
Release: 1
|
||||
Version: %ver
|
||||
Release: %rel
|
||||
URL: http://people.redhat.com/~hp/metacity/
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
License: GPL
|
||||
Group: User Interface/Desktops
|
||||
BuildRoot: %{_tmppath}/%{name}-root
|
||||
BuildRequires: gtk2-devel >= 2.0.0
|
||||
BuildRequires: GConf-devel >= 1.1.9
|
||||
BuildRequires: GConf2-devel >= 1.1.9
|
||||
|
||||
%description
|
||||
|
||||
@@ -24,21 +28,46 @@ make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
export GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1
|
||||
%makeinstall
|
||||
unset GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post
|
||||
|
||||
export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
|
||||
SCHEMAS="metacity.schemas"
|
||||
for S in $SCHEMAS; do
|
||||
gconftool-2 --makefile-install-rule %{_sysconfdir}/gconf/schemas/$S > /dev/null
|
||||
done
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc README AUTHORS COPYING NEWS HACKING theme-format.txt
|
||||
%{_bindir}/*
|
||||
%{_libexecdir}/*
|
||||
%{_datadir}/gnome/wm-properties/metacity.desktop
|
||||
%{_sysconfdir}/schemas/*.schemas
|
||||
%{_datadir}/gnome/wm-properties/*
|
||||
%{_sysconfdir}/gconf/schemas/*.schemas
|
||||
%{_datadir}/control-center-2.0/capplets/*
|
||||
%{_datadir}/metacity
|
||||
%{_datadir}/pixmaps/*
|
||||
%{_datadir}/themes/*
|
||||
|
||||
%changelog
|
||||
* Tue Aug 20 2002 Steve Fox <drfickle@k-lug.org>
|
||||
- Autoconf-ize the spec file to magic updates
|
||||
- Include missing dirs
|
||||
|
||||
* Thu May 2 2002 Havoc Pennington <hp@redhat.com>
|
||||
- 2.3.233
|
||||
|
||||
* Thu Apr 25 2002 Havoc Pennington <hp@redhat.com>
|
||||
- rebuild in different environment
|
||||
- add gconf schemas boilerplate
|
||||
|
||||
* Mon Apr 15 2002 Havoc Pennington <hp@pobox.com>
|
||||
- 2.3.89
|
||||
|
696
po/ChangeLog
696
po/ChangeLog
@@ -1,3 +1,667 @@
|
||||
2002-12-09 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-12-09 Miloslav Trmac <mitr@volny.cz>
|
||||
|
||||
* cs.po: Updated Czech translation.
|
||||
|
||||
2002-12-04 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-11-25 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-11-25 Yanko Kaneti <yaneti@declera.com>
|
||||
|
||||
* *.po: Convert all to UTF-8.
|
||||
|
||||
2002-11-24 Kostas Papadimas <pkst@gmx.net>
|
||||
|
||||
* el.po: Updated Greek translation.
|
||||
|
||||
2002-11-23 Kostas Papadimas <pkst@gmx.net>
|
||||
|
||||
* el.po: Updated Greek translation.
|
||||
|
||||
2002-11-19 Andras Timar <timar@gnome.hu>
|
||||
|
||||
* hu.po: Updated Hungarian translation.
|
||||
|
||||
2002-11-15 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-11-14 Gustavo Noronha Silva <kov@debian.org>
|
||||
|
||||
* pt_BR.po: Update translation.
|
||||
|
||||
2002-11-14 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-11-13 Christian Neumair <chris@gnome-de.org>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-11-11 Peteris Krisjanis <peteris.krisjanis@os.lv>
|
||||
|
||||
* lv.po: Updated Latvian translation.
|
||||
|
||||
2002-11-11 Changwoo Ryu <cwryu@debian.org>
|
||||
|
||||
* ko.po: Updated Korean translation by Young-Ho Cha
|
||||
<ganadist@chollian.net>.
|
||||
|
||||
2002-11-10 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-11-05 Hasbullah Bin Pit <sebol@ikhlas.com>
|
||||
|
||||
* ms.po: Updated Malay Translation.
|
||||
|
||||
2002-11-05 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* POTFILES.in: Added missing file.
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-11-01 Christian Neumair <chris@gnome-de.org>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-10-31 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-10-28 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-10-28 Peteris Krisjanis <peteris.krisjanis@os.lv>
|
||||
|
||||
* lv.po: Updated Latvian translation.
|
||||
|
||||
2002-10-24 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* POTFILES.in: Added missing file.
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-10-24 Pablo Saratxaga <pablo@mandrakesoft.com>
|
||||
|
||||
* vi.po: Updated Vietnamese file
|
||||
|
||||
2002-10-22 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-10-21 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-10-17 Andras Timar <timar@gnome.hu>
|
||||
|
||||
* hu.po: Added Hungarian translation.
|
||||
|
||||
2002-10-17 Christophe Merlet <christophe@merlet.net>
|
||||
|
||||
* fr.po: Updated French translation.
|
||||
|
||||
2002-10-16 Christian Neumair <chris@gnome-de.org>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-10-16 Yukihiro Nakai <ynakai@redhat.com>
|
||||
|
||||
* ja.po: Minor fix
|
||||
|
||||
2002-10-16 Bastien Nocera <hadess@hadess.net>
|
||||
|
||||
* en_GB.po: added, more colours for your theme, time to upgrade!
|
||||
|
||||
2002-10-15 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-10-15 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-10-13 Hasbullah Bin Pit <sebol@ikhlas.com>
|
||||
|
||||
* ms.po: Updated Malay Translation.
|
||||
|
||||
2002-10-11 Stanislav Brabec <sbrabec@suse.cz>
|
||||
|
||||
* cs.po: Updated Czech translation from Miloslav Trmac
|
||||
<mitr@volny.cz>.
|
||||
|
||||
2002-10-10 Zbigniew Chyla <cyba@gnome.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-10-06 Zbigniew Chyla <cyba@gnome.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-10-01 Stanislav Brabec <sbrabec@suse.cz>
|
||||
|
||||
* cs.po: Added Czech translation from Miloslav Trmac
|
||||
<mitr@volny.cz>.
|
||||
|
||||
2002-09-28 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-09-26 Christian Neumair <chris@gnome-de.org>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-09-25 Christophe Merlet <christophe@merlet.net>
|
||||
|
||||
* fr.po: Updated French translation.
|
||||
|
||||
2002-09-25 Christian Meyer <chrisime@gnome.org>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-09-24 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-09-23 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-09-20 Christian Neumair <chris@gnome-de.org>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-09-20 Pablo Saratxaga <pablo@mandrakesoft.com>
|
||||
|
||||
* vi.po: Updated Vietnamese file
|
||||
|
||||
2002-09-11 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-09-10 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-09-11 Duncan Mak <duncan@ximian.com>
|
||||
|
||||
* ro.po: Remove diff conflicts.
|
||||
|
||||
2002-09-06 Frederic Crozat <fcrozat@mandrakesoft.com>
|
||||
|
||||
* fr.po: Updated French translation.
|
||||
|
||||
2002-09-05 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-09-05 Christian Neumair <chris@gnome-de.org>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-09-05 Akira TAGOH <tagoh@gnome.gr.jp>
|
||||
|
||||
* ja.po: Updated Japanese translation.
|
||||
|
||||
2002-09-04 Marius Andreiana <mandreiana@yahoo.com>
|
||||
|
||||
* ro.po: added ( thanks to Mugurel Tudor <mugurelu@go.ro> )
|
||||
|
||||
2002-08-30 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-08-28 Hasbullah Bin Pit <sebol@ikhlas.com>
|
||||
|
||||
* ms.po: Updated Malay Translation.
|
||||
|
||||
2002-08-27 Christian Neumair <christian-neumair@web.de>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-08-26 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-08-26 Dmitry G. Mastrukov <dmitry@taurussoft.org>
|
||||
|
||||
* ru.po: updated Russian translation.
|
||||
|
||||
2002-08-26 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-08-24 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-08-23 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-08-23 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-08-22 Zbigniew Chyla <cyba@gnome.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-08-21 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-08-21 Anders Carlsson <andersca@gnu.org>
|
||||
|
||||
* lv.po: Fix build.
|
||||
|
||||
2002-08-21 Peteris Krisjanis <peteris.krisjanis@os.lv>
|
||||
|
||||
* lv.po: Updated Latvian translation.
|
||||
|
||||
2002-08-21 Akira TAGOH <tagoh@gnome.gr.jp>
|
||||
|
||||
* ja.po: Updated Japanese translation.
|
||||
|
||||
2002-08-19 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-08-19 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Fixed a bug. Thanks to rhult for reporting it.
|
||||
|
||||
2002-08-19 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-08-18 Hasbullah Bin Pit <sebol@ikhlas.com>
|
||||
|
||||
* ms.po: Updated Malay Translation.
|
||||
|
||||
2002-08-18 Christian Neumair <christian-neumair@web.de>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-08-18 Christian Neumair <christian-neumair@web.de>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2002-08-17 Simos Xenitellis <simos@hellug.gr>
|
||||
|
||||
* el.po: Added initial Greek translation.
|
||||
|
||||
2002-08-17 Evandro Fernandes Giovanini <evandrofg@ig.com.br>
|
||||
|
||||
* pt_BR.po: Added Brazilian Portuguese translation.
|
||||
|
||||
2002-08-17 Changwoo Ryu <cwryu@debian.org>
|
||||
|
||||
* ko.po: Updated Korean translation by Young-Ho Cha
|
||||
<ganadist@chollian.net>.
|
||||
|
||||
2002-08-16 Zbigniew Chyla <cyba@gnome.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-08-16 Dmitry G. Mastrukov <dmitry@taurussoft.org>
|
||||
|
||||
* ru.po: updated Russian translation.
|
||||
|
||||
2002-08-13 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-08-12 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-08-12 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
* sk.po: Updated Slovak translation.
|
||||
|
||||
2002-08-11 Dmitry G. Mastrukov <dmitry@taurussoft.org>
|
||||
|
||||
* ru.po: updated Russian translation.
|
||||
|
||||
2002-08-10 He Qiangqiang <carton@linux.net.cn>
|
||||
|
||||
* zh_CN.po: Fixed c-format specifiers position error.
|
||||
|
||||
2002-08-08 Akira TAGOH <tagoh@gnome.gr.jp>
|
||||
|
||||
* ja.po: Updated Japanese translation.
|
||||
|
||||
2002-08-07 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-08-06 Manuel Borchers <webmaster@matronix.de>
|
||||
|
||||
* de.po: Update German translation by
|
||||
Christian Neumair <christian-neumair@web.de>
|
||||
|
||||
2002-08-05 He Qiangqiang <carton@linux.net.cn>
|
||||
|
||||
* zh_CN.po: Added simplified Chinese translation from
|
||||
Sun G11n <gnome_int_l10n@ireland.sun.com>.
|
||||
|
||||
2002-08-05 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Fixed Swedish translation.
|
||||
|
||||
2002-08-04 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-07-30 Pablo Saratxaga <pablo@mandrakesoft.com>
|
||||
|
||||
* vi.po: Updated Vietnamese file
|
||||
|
||||
2002-07-28 Christophe Merlet <christophe@merlet.net>
|
||||
|
||||
* fr.po: Updated French translation from contribution of
|
||||
Sun G11n <gnome_int_l10n@ireland.sun.com>.
|
||||
|
||||
2002-07-27 Hasbullah Bin Pit <sebol@ikhlas.com>
|
||||
|
||||
* ms.po: Updated Malay Translation.
|
||||
|
||||
2002-07-25 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-07-25 Zbigniew Chyla <chyla@gnome.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-07-25 Dmitry G. Mastrukov <dmitry@taurussoft.org>
|
||||
|
||||
* ru.po: updated Russian translation with help from
|
||||
SUN G11n <gnome_int_l10n@ireland.sun.com>.
|
||||
|
||||
2002-07-25 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-07-25 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation and merged the
|
||||
Sun changes that are sane.
|
||||
|
||||
2002-07-24 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
* sk.po: Updated Slovak translation.
|
||||
|
||||
2002-07-23 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-07-24 Zbigniew Chyla <chyla@gnome.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-07-19 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-07-16 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-07-15 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Fixed a string.
|
||||
|
||||
2002-07-13 Christophe Fergeau <teuf@users.sourceforge.net>
|
||||
|
||||
* fr.po: Added French translation.
|
||||
|
||||
2002-07-13 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-07-12 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-07-11 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-07-11 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-07-08 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-07-02 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
* sk.po: Updated Slovak translation.
|
||||
|
||||
2002-06-24 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-06-24 Zbigniew Chyla <chyla@buy.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-06-25 Abel Cheung <maddog@linux.org.hk>
|
||||
|
||||
* zh_TW.po: Updated traditional Chinese translation.
|
||||
|
||||
2002-06-23 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-06-23 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-06-19 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-06-16 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-06-16 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* POTFILES.in: Added missing file.
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-06-15 Akira TAGOH <tagoh@gnome.gr.jp>
|
||||
|
||||
* ja.po: Updated Japanese translation.
|
||||
|
||||
2002-06-14 Changwoo Ryu <cwryu@debian.org>
|
||||
|
||||
* ko.po: Updated Korean translation.
|
||||
|
||||
2002-06-10 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-06-10 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
* sk.po: Updated Slovak translation.
|
||||
|
||||
2002-06-09 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-06-09 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-06-07 Zbigniew Chyla <chyla@buy.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-06-06 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-06-06 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-06-05 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-06-05 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-06-04 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-06-04 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
* sk.po: Updated Slovak translation.
|
||||
|
||||
2002-06-04 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-06-03 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-06-03 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
* sk.po: Updated Slovak translation.
|
||||
|
||||
2002-06-03 Changwoo Ryu <cwryu@debian.org>
|
||||
|
||||
* ko.po: Updated Korean translation by Young-Ho Cha
|
||||
<ganadist@chollian.net>.
|
||||
|
||||
2002-06-01 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-05-31 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-05-31 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
* sk.po: Updated Slovak translation.
|
||||
|
||||
2002-05-31 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-05-28 Pablo Gonzalo del Campo <pablodc@bigfoot.com>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2002-05-28 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-05-28 Abel Cheung <maddog@linux.org.hk>
|
||||
|
||||
* zh_TW.po: New traditional Chinese translation.
|
||||
|
||||
2002-05-27 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2002-05-26 Matthias Warkus <mawarkus@gnome.org>
|
||||
|
||||
* de.po: German translation added.
|
||||
|
||||
2002-05-26 Zbigniew Chyla <cyba@gnome.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-05-24 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
* sk.po: Updated Slovak translation.
|
||||
|
||||
2002-05-21 Changwoo Ryu <cwryu@debian.org>
|
||||
|
||||
* ko.po: Updated Korean translation by Young-Ho Cha
|
||||
<ganadist@chollian.net>.
|
||||
|
||||
2002-05-20 Alessio Frusciante <algol@perseus>
|
||||
|
||||
* it.po: Added Italian translation.
|
||||
|
||||
2002-05-20 Pablo Saratxaga <pablo@mandrakesoft.com>
|
||||
|
||||
* ca.po: Added Catalan file
|
||||
* az.po,es.po,ms.po,lv.po: Corrected syntax errors
|
||||
|
||||
2002-05-18 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-05-18 Ole Laursen <olau@hardworking.dk>
|
||||
|
||||
* da.po: Updated Danish translation.
|
||||
|
||||
2002-05-16 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
* sk.po: Updated Slovak translation.
|
||||
|
||||
2002-05-06 Duarte Loreto <happyguy_pt@hotmail.com>
|
||||
|
||||
* pt.po: Updated Portuguese translation and converted to UTF-8.
|
||||
|
||||
2002-04-26 Zbigniew Chyla <cyba@gnome.pl>
|
||||
|
||||
* pl.po: Updated Polish translation by
|
||||
GNOME PL Team <translators@gnome.pl>.
|
||||
|
||||
2002-04-25 Changwoo Ryu <cwryu@debian.org>
|
||||
|
||||
* ko.po: Updated Korean translation from Young-Ho Cha
|
||||
<ganadist@chollian.net>.
|
||||
|
||||
2002-04-22 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-04-19 Changwoo Ryu <cwryu@debian.org>
|
||||
|
||||
* ko.po: Updated Korean translation from Young-Ho Cha
|
||||
<ganadist@chollian.net>.
|
||||
|
||||
2002-04-17 Changwoo Ryu <cwryu@debian.org>
|
||||
|
||||
* ko.po: Added Korean translation from Young-Ho Cha
|
||||
<ganadist@chollian.net>.
|
||||
|
||||
2002-04-16 Akira TAGOH <tagoh@gnome.gr.jp>
|
||||
|
||||
* ja.po: Add Japanese translation.
|
||||
|
||||
2002-04-16 Abel Cheung <maddog@linux.org.hk>
|
||||
|
||||
* .cvsignore: Added some file(s).
|
||||
@@ -10,11 +674,11 @@
|
||||
|
||||
2002-03-28 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-03-27 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-03-22 Zbigniew Chyla <cyba@gnome.pl>
|
||||
|
||||
@@ -22,19 +686,19 @@
|
||||
|
||||
2002-02-22 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-02-17 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-02-16 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-02-12 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-02-11 Duarte Loreto <happyguy_pt@hotmail.com>
|
||||
|
||||
@@ -46,7 +710,7 @@
|
||||
|
||||
2002-02-10 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-02-08 Christian Rose <menthos@menthos.com>
|
||||
|
||||
@@ -63,7 +727,7 @@
|
||||
|
||||
2002-02-02 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-01-31 Christian Rose <menthos@menthos.com>
|
||||
|
||||
@@ -79,7 +743,7 @@
|
||||
|
||||
2002-01-29 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-01-27 Peteris Krisjanis <peteris.krisjanis@ttc.lv>
|
||||
|
||||
@@ -91,7 +755,7 @@
|
||||
|
||||
2002-01-11 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>l) translation.
|
||||
* no.po: Updated Norwegian (bokmål) translation.
|
||||
|
||||
2002-01-09 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
|
||||
|
||||
@@ -103,7 +767,7 @@
|
||||
|
||||
2002-01-06 Fatih Demir <kabalak@gtranslator.org>
|
||||
|
||||
* tr.po: Added Turkish translation by G<EFBFBD>rkem Cetin.
|
||||
* tr.po: Added Turkish translation by Görkem Cetin.
|
||||
|
||||
2002-01-05 Christian Rose <menthos@menthos.com>
|
||||
|
||||
@@ -125,7 +789,7 @@
|
||||
|
||||
2001-12-16 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* no.po: Updated Norwegian (bokm<EFBFBD>) translation.
|
||||
* no.po: Updated Norwegian (bokmᅵ) translation.
|
||||
|
||||
2001-12-15 Christian Rose <menthos@menthos.com>
|
||||
|
||||
@@ -142,17 +806,17 @@
|
||||
2001-11-27 Jesus Bravo Alvarez <jba@pobox.com>
|
||||
|
||||
* gl.po: Added Galician translation from
|
||||
Manuel A. Fern<EFBFBD>dez Montecelo <manuel@sindominio.net>
|
||||
Manuel A. Fernᅵdez Montecelo <manuel@sindominio.net>
|
||||
|
||||
2001-10-29 Yuriy Syrota <rasta@renome.rovno.ua>
|
||||
|
||||
* uk.po: Added Ukrainian translation file.
|
||||
|
||||
2001-10-28 H<EFBFBD>tor Garc<EFBFBD> <20>varez <hector@scouts-es.org>
|
||||
2001-10-28 Hᅵtor Garcᅵ ᅵvarez <hector@scouts-es.org>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2001-10-14 H<EFBFBD>tor Garc<EFBFBD> <20>varez <hector@scouts-es.org>
|
||||
2001-10-14 Hᅵtor Garcᅵ ᅵvarez <hector@scouts-es.org>
|
||||
|
||||
* es.po: Added Spanish translation.
|
||||
|
||||
@@ -162,7 +826,7 @@
|
||||
|
||||
2001-10-11 Christian Rose <menthos@menthos.com>
|
||||
|
||||
* sv.po: Fixed some typos. Thanks to Tomas <EFBFBD>ren <stric@ing.umu.se>
|
||||
* sv.po: Fixed some typos. Thanks to Tomas ᅵren <stric@ing.umu.se>
|
||||
for spotting many of them.
|
||||
|
||||
2001-10-11 Christian Rose <menthos@menthos.com>
|
||||
|
@@ -7,13 +7,20 @@ src/frames.c
|
||||
src/keybindings.c
|
||||
src/main.c
|
||||
src/menu.c
|
||||
src/metaaccellabel.c
|
||||
src/metacity-dialog.c
|
||||
src/metacity.desktop.in
|
||||
src/metacity.schemas.in
|
||||
src/prefs.c
|
||||
src/resizepopup.c
|
||||
src/screen.c
|
||||
src/session.c
|
||||
src/theme.c
|
||||
src/theme-parser.c
|
||||
src/theme.c
|
||||
src/tools/metacity-properties.desktop.in
|
||||
src/tools/metacity-properties.glade
|
||||
src/util.c
|
||||
src/window-props.c
|
||||
src/window.c
|
||||
src/workspace.c
|
||||
src/xprops.c
|
||||
|
2127
po/en_GB.po
Normal file
2127
po/en_GB.po
Normal file
File diff suppressed because it is too large
Load Diff
2886
po/pt_BR.po
Normal file
2886
po/pt_BR.po
Normal file
File diff suppressed because it is too large
Load Diff
2983
po/zh_CN.po
Normal file
2983
po/zh_CN.po
Normal file
File diff suppressed because it is too large
Load Diff
2495
po/zh_TW.po
Normal file
2495
po/zh_TW.po
Normal file
File diff suppressed because it is too large
Load Diff
8
rationales.txt
Normal file
8
rationales.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
Focus windows on map: see http://bugzilla.gnome.org/show_bug.cgi?id=82921
|
||||
Keep panel always on top: http://bugzilla.gnome.org/show_bug.cgi?id=81551
|
||||
Edge flipping: http://bugzilla.gnome.org/show_bug.cgi?id=82917
|
||||
Opaque resize: http://bugzilla.gnome.org/show_bug.cgi?id=92618
|
||||
Super+click to resize: http://bugzilla.gnome.org/show_bug.cgi?id=79315
|
||||
minimized windows in Alt+tab: http://bugzilla.gnome.org/show_bug.cgi?id=89416
|
||||
raise windows on click: http://bugzilla.gnome.org/show_bug.cgi?id=86108
|
@@ -4,5 +4,10 @@ Makefile
|
||||
.deps
|
||||
metacity
|
||||
metacity-theme-viewer
|
||||
metacity-dialog
|
||||
testgradient
|
||||
inlinepixbufs.h
|
||||
metacity.desktop
|
||||
metacity.schemas
|
||||
libmetacity-private.pc
|
||||
testasyncgetprop
|
||||
|
@@ -1,15 +1,24 @@
|
||||
lib_LTLIBRARIES = libmetacity-private.la
|
||||
|
||||
SUBDIRS=wm-tester tools themes
|
||||
|
||||
INCLUDES=@METACITY_CFLAGS@ -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMETACITY_LOCALEDIR=\"$(datadir)/locale\" -DMETACITY_PKGDATADIR=\"$(pkgdatadir)\"
|
||||
INCLUDES=@METACITY_CFLAGS@ -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMETACITY_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMETACITY_PKGDATADIR=\"$(pkgdatadir)\" -DMETACITY_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"metacity\" -DSN_API_NOT_YET_FROZEN=1
|
||||
|
||||
EGGFILES= \
|
||||
eggaccelerators.c \
|
||||
eggaccelerators.h
|
||||
|
||||
metacity_SOURCES= \
|
||||
async-getprop.c \
|
||||
async-getprop.h \
|
||||
common.h \
|
||||
core.c \
|
||||
core.h \
|
||||
delete.c \
|
||||
display.c \
|
||||
display.h \
|
||||
draw-workspace.c \
|
||||
draw-workspace.h \
|
||||
effects.c \
|
||||
effects.h \
|
||||
errors.c \
|
||||
@@ -24,6 +33,11 @@ metacity_SOURCES= \
|
||||
frames.h \
|
||||
gradient.c \
|
||||
gradient.h \
|
||||
group.c \
|
||||
group.h \
|
||||
group-private.h \
|
||||
group-props.c \
|
||||
group-props.h \
|
||||
iconcache.c \
|
||||
iconcache.h \
|
||||
inlinepixbufs.h \
|
||||
@@ -33,6 +47,9 @@ metacity_SOURCES= \
|
||||
main.h \
|
||||
menu.c \
|
||||
menu.h \
|
||||
metaaccellabel.c \
|
||||
metaaccellabel.h \
|
||||
metacity-Xatomtype.h \
|
||||
place.c \
|
||||
place.h \
|
||||
prefs.c \
|
||||
@@ -59,12 +76,15 @@ metacity_SOURCES= \
|
||||
util.h \
|
||||
window.c \
|
||||
window.h \
|
||||
window-props.c \
|
||||
window-props.h \
|
||||
workspace.c \
|
||||
workspace.h \
|
||||
xprops.c \
|
||||
xprops.h
|
||||
xprops.h \
|
||||
$(EGGFILES)
|
||||
|
||||
metacity_theme_viewer_SOURCES= \
|
||||
libmetacity_private_la_SOURCES= \
|
||||
gradient.c \
|
||||
gradient.h \
|
||||
preview-widget.c \
|
||||
@@ -73,9 +93,22 @@ metacity_theme_viewer_SOURCES= \
|
||||
theme.h \
|
||||
theme-parser.c \
|
||||
theme-parser.h \
|
||||
theme-viewer.c \
|
||||
util.c \
|
||||
util.h
|
||||
util.h \
|
||||
common.h
|
||||
|
||||
libmetacityincludedir = $(includedir)/metacity-1/metacity-private
|
||||
|
||||
libmetacityinclude_HEADERS = \
|
||||
common.h \
|
||||
gradient.h \
|
||||
preview-widget.h \
|
||||
theme.h \
|
||||
theme-parser.h \
|
||||
util.h
|
||||
|
||||
metacity_theme_viewer_SOURCES= \
|
||||
theme-viewer.c
|
||||
|
||||
metacity_dialog_SOURCES= \
|
||||
metacity-dialog.c
|
||||
@@ -83,32 +116,58 @@ metacity_dialog_SOURCES= \
|
||||
bin_PROGRAMS=metacity metacity-theme-viewer
|
||||
libexec_PROGRAMS=metacity-dialog
|
||||
|
||||
metacity_LDADD= @METACITY_LIBS@
|
||||
metacity_theme_viewer_LDADD= @METACITY_LIBS@
|
||||
EFENCE=
|
||||
metacity_LDADD=@METACITY_LIBS@ $(EFENCE)
|
||||
metacity_theme_viewer_LDADD= @METACITY_LIBS@ libmetacity-private.la
|
||||
metacity_dialog_LDADD=@METACITY_LIBS@
|
||||
|
||||
testgradient_SOURCES=gradient.h gradient.c testgradient.c
|
||||
testasyncgetprop_SOURCES=async-getprop.h async-getprop.c testasyncgetprop.c
|
||||
|
||||
noinst_PROGRAMS=testgradient
|
||||
noinst_PROGRAMS=testgradient testasyncgetprop
|
||||
|
||||
testgradient_LDADD= @METACITY_LIBS@
|
||||
testasyncgetprop_LDADD= @METACITY_LIBS@
|
||||
|
||||
desktopfilesdir=$(datadir)/gnome/wm-properties
|
||||
desktopfiles_DATA=metacity.desktop
|
||||
desktopfiles_in_files=metacity.desktop.in
|
||||
desktopfiles_DATA = $(desktopfiles_in_files:.desktop.in=.desktop)
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
schemadir = @GCONF_SCHEMA_FILE_DIR@
|
||||
schema_DATA = metacity.schemas
|
||||
schema_in_files = metacity.schemas.in
|
||||
schema_DATA = $(schema_in_files:.schemas.in=.schemas)
|
||||
|
||||
@INTLTOOL_SCHEMAS_RULE@
|
||||
|
||||
install-data-local:
|
||||
GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$(schema_DATA)
|
||||
|
||||
IMAGES=default_icon.png
|
||||
VARIABLES=default_icon_data $(srcdir)/default_icon.png
|
||||
IMAGES=default_icon.png stock_maximize.png stock_minimize.png stock_delete.png
|
||||
VARIABLES=default_icon_data $(srcdir)/default_icon.png \
|
||||
stock_maximize_data $(srcdir)/stock_maximize.png \
|
||||
stock_minimize_data $(srcdir)/stock_minimize.png \
|
||||
stock_delete_data $(srcdir)/stock_delete.png
|
||||
|
||||
BUILT_SOURCES = inlinepixbufs.h
|
||||
CLEANFILES += inlinepixbufs.h
|
||||
CLEANFILES = inlinepixbufs.h
|
||||
|
||||
inlinepixbufs.h: $(IMAGES)
|
||||
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
|
||||
|
||||
EXTRA_DIST=$(desktopfiles_DATA) $(IMAGES) $(schema_DATA)
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
pkgconfig_DATA = libmetacity-private.pc
|
||||
|
||||
EXTRA_DIST=$(desktopfiles_DATA) \
|
||||
$(IMAGES) $(schema_DATA) \
|
||||
update-from-egg.sh \
|
||||
$(desktopfiles_in_files) \
|
||||
$(schema_in_files) \
|
||||
libmetacity-private.pc.in
|
||||
|
||||
|
||||
EGGDIR=$(srcdir)/../../libegg/libegg
|
||||
|
||||
regenerate-built-sources:
|
||||
EGGFILES="$(EGGFILES)" EGGDIR="$(EGGDIR)" $(srcdir)/update-from-egg.sh
|
||||
|
649
src/async-getprop.c
Normal file
649
src/async-getprop.c
Normal file
@@ -0,0 +1,649 @@
|
||||
/* Asynchronous X property getting hack */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Havoc Pennington
|
||||
* Copyright (C) 1986, 1998 The Open Group
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of The Open Group shall not be
|
||||
* used in advertising or otherwise to promote the sale, use or other dealings
|
||||
* in this Software without prior written authorization from The Open Group.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#undef DEBUG_SPEW
|
||||
#ifdef DEBUG_SPEW
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "async-getprop.h"
|
||||
|
||||
#define NEED_REPLIES
|
||||
#include <X11/Xlibint.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
typedef struct _ListNode ListNode;
|
||||
typedef struct _AgPerDisplayData AgPerDisplayData;
|
||||
|
||||
struct _ListNode
|
||||
{
|
||||
ListNode *next;
|
||||
};
|
||||
|
||||
struct _AgGetPropertyTask
|
||||
{
|
||||
ListNode node;
|
||||
|
||||
AgPerDisplayData *dd;
|
||||
Window window;
|
||||
Atom property;
|
||||
|
||||
unsigned long request_seq;
|
||||
int error;
|
||||
|
||||
Atom actual_type;
|
||||
int actual_format;
|
||||
|
||||
unsigned long n_items;
|
||||
unsigned long bytes_after;
|
||||
unsigned char *data;
|
||||
|
||||
Bool have_reply;
|
||||
};
|
||||
|
||||
struct _AgPerDisplayData
|
||||
{
|
||||
ListNode node;
|
||||
_XAsyncHandler async;
|
||||
|
||||
Display *display;
|
||||
ListNode *pending_tasks;
|
||||
ListNode *pending_tasks_tail;
|
||||
ListNode *completed_tasks;
|
||||
ListNode *completed_tasks_tail;
|
||||
int n_tasks_pending;
|
||||
int n_tasks_completed;
|
||||
};
|
||||
|
||||
static ListNode *display_datas = NULL;
|
||||
static ListNode *display_datas_tail = NULL;
|
||||
|
||||
static void
|
||||
append_to_list (ListNode **head,
|
||||
ListNode **tail,
|
||||
ListNode *task)
|
||||
{
|
||||
task->next = NULL;
|
||||
|
||||
if (*tail == NULL)
|
||||
{
|
||||
assert (*head == NULL);
|
||||
*head = task;
|
||||
*tail = task;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*tail)->next = task;
|
||||
*tail = task;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
remove_from_list (ListNode **head,
|
||||
ListNode **tail,
|
||||
ListNode *task)
|
||||
{
|
||||
ListNode *prev;
|
||||
ListNode *node;
|
||||
|
||||
prev = NULL;
|
||||
node = *head;
|
||||
while (node != NULL)
|
||||
{
|
||||
if (node == task)
|
||||
{
|
||||
if (prev)
|
||||
prev->next = node->next;
|
||||
else
|
||||
*head = node->next;
|
||||
|
||||
if (node == *tail)
|
||||
*tail = prev;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
prev = node;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
/* can't remove what's not there */
|
||||
assert (node != NULL);
|
||||
|
||||
node->next = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
move_to_completed (AgPerDisplayData *dd,
|
||||
AgGetPropertyTask *task)
|
||||
{
|
||||
remove_from_list (&dd->pending_tasks,
|
||||
&dd->pending_tasks_tail,
|
||||
&task->node);
|
||||
|
||||
append_to_list (&dd->completed_tasks,
|
||||
&dd->completed_tasks_tail,
|
||||
&task->node);
|
||||
|
||||
dd->n_tasks_pending -= 1;
|
||||
dd->n_tasks_completed += 1;
|
||||
}
|
||||
|
||||
static AgGetPropertyTask*
|
||||
find_pending_by_request_sequence (AgPerDisplayData *dd,
|
||||
unsigned long request_seq)
|
||||
{
|
||||
ListNode *node;
|
||||
|
||||
/* if the sequence is after our last pending task, we
|
||||
* aren't going to find a match
|
||||
*/
|
||||
{
|
||||
AgGetPropertyTask *task = (AgGetPropertyTask*) dd->pending_tasks_tail;
|
||||
if (task != NULL)
|
||||
{
|
||||
if (task->request_seq < request_seq)
|
||||
return NULL;
|
||||
else if (task->request_seq == request_seq)
|
||||
return task; /* why not check this */
|
||||
}
|
||||
}
|
||||
|
||||
/* Generally we should get replies in the order we sent
|
||||
* requests, so we should usually be using the task
|
||||
* at the head of the list, if we use any task at all.
|
||||
* I'm not sure this is 100% guaranteed, if it is,
|
||||
* it would be a big speedup.
|
||||
*/
|
||||
|
||||
node = dd->pending_tasks;
|
||||
while (node != NULL)
|
||||
{
|
||||
AgGetPropertyTask *task = (AgGetPropertyTask*) node;
|
||||
|
||||
if (task->request_seq == request_seq)
|
||||
return task;
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Bool
|
||||
async_get_property_handler (Display *dpy,
|
||||
xReply *rep,
|
||||
char *buf,
|
||||
int len,
|
||||
XPointer data)
|
||||
{
|
||||
xGetPropertyReply replbuf;
|
||||
xGetPropertyReply *reply;
|
||||
AgGetPropertyTask *task;
|
||||
AgPerDisplayData *dd;
|
||||
int bytes_read;
|
||||
|
||||
dd = (AgPerDisplayData*) data;
|
||||
|
||||
#if 0
|
||||
printf ("%s: seeing request seq %ld buflen %d\n", __FUNCTION__,
|
||||
dpy->last_request_read, len);
|
||||
#endif
|
||||
|
||||
task = find_pending_by_request_sequence (dd, dpy->last_request_read);
|
||||
|
||||
if (task == NULL)
|
||||
return False;
|
||||
|
||||
assert (dpy->last_request_read == task->request_seq);
|
||||
|
||||
task->have_reply = True;
|
||||
move_to_completed (dd, task);
|
||||
|
||||
/* read bytes so far */
|
||||
bytes_read = SIZEOF (xReply);
|
||||
|
||||
if (rep->generic.type == X_Error)
|
||||
{
|
||||
xError errbuf;
|
||||
|
||||
task->error = rep->error.errorCode;
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
printf ("%s: error code = %d (ignoring error, eating %d bytes, generic.length = %ld)\n",
|
||||
__FUNCTION__, task->error, (SIZEOF (xError) - bytes_read),
|
||||
rep->generic.length);
|
||||
#endif
|
||||
|
||||
/* We return True (meaning we consumed the reply)
|
||||
* because otherwise it would invoke the X error handler,
|
||||
* and an async API is useless if you have to synchronously
|
||||
* trap X errors. Also GetProperty can always fail, pretty
|
||||
* much, so trapping errors is always what you want.
|
||||
*
|
||||
* We have to eat all the error reply data here.
|
||||
* (kind of a charade as we know sizeof(xError) == sizeof(xReply))
|
||||
*
|
||||
* Passing discard = True seems to break things; I don't understand
|
||||
* why, because there should be no extra data in an error reply,
|
||||
* right?
|
||||
*/
|
||||
_XGetAsyncReply (dpy, (char *)&errbuf, rep, buf, len,
|
||||
(SIZEOF (xError) - bytes_read) >> 2, /* in 32-bit words */
|
||||
False); /* really seems like it should be True */
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
printf ("%s: already read %d bytes reading %d more for total of %d; generic.length = %ld\n",
|
||||
__FUNCTION__, bytes_read, (SIZEOF (xGetPropertyReply) - bytes_read) >> 2,
|
||||
SIZEOF (xGetPropertyReply), rep->generic.length);
|
||||
#endif
|
||||
|
||||
/* (kind of a silly as we know sizeof(xGetPropertyReply) == sizeof(xReply)) */
|
||||
reply = (xGetPropertyReply *)
|
||||
_XGetAsyncReply (dpy, (char *)&replbuf, rep, buf, len,
|
||||
(SIZEOF (xGetPropertyReply) - bytes_read) >> 2, /* in 32-bit words */
|
||||
False); /* False means expecting more data to follow,
|
||||
* don't eat the rest of the reply
|
||||
*/
|
||||
|
||||
bytes_read = SIZEOF (xGetPropertyReply);
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
printf ("%s: have reply propertyType = %ld format = %d n_items = %ld\n",
|
||||
__FUNCTION__, reply->propertyType, reply->format, reply->nItems);
|
||||
#endif
|
||||
|
||||
assert (task->data == NULL);
|
||||
|
||||
/* This is all copied from XGetWindowProperty(). Not sure we should
|
||||
* LockDisplay(). Not sure I'm passing the right args to
|
||||
* XGetAsyncData(). Not sure about a lot of things.
|
||||
*/
|
||||
|
||||
/* LockDisplay (dpy); */
|
||||
|
||||
if (reply->propertyType != None)
|
||||
{
|
||||
long nbytes, netbytes;
|
||||
|
||||
/* this alignment macro from orbit2 */
|
||||
#define ALIGN_VALUE(this, boundary) \
|
||||
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
|
||||
|
||||
switch (reply->format)
|
||||
{
|
||||
/*
|
||||
* One extra byte is malloced than is needed to contain the property
|
||||
* data, but this last byte is null terminated and convenient for
|
||||
* returning string properties, so the client doesn't then have to
|
||||
* recopy the string to make it null terminated.
|
||||
*/
|
||||
case 8:
|
||||
nbytes = reply->nItems;
|
||||
/* there's padding to word boundary */
|
||||
netbytes = ALIGN_VALUE (nbytes, 4);
|
||||
if (nbytes + 1 > 0 &&
|
||||
(task->data = (unsigned char *) Xmalloc ((unsigned)nbytes + 1)))
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
printf ("%s: already read %d bytes using %ld, more eating %ld more\n",
|
||||
__FUNCTION__, bytes_read, nbytes, netbytes);
|
||||
#endif
|
||||
/* _XReadPad (dpy, (char *) task->data, netbytes); */
|
||||
_XGetAsyncData (dpy, task->data, buf, len,
|
||||
bytes_read, nbytes,
|
||||
netbytes);
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
nbytes = reply->nItems * sizeof (short);
|
||||
netbytes = reply->nItems << 1;
|
||||
netbytes = ALIGN_VALUE (netbytes, 4); /* align to word boundary */
|
||||
if (nbytes + 1 > 0 &&
|
||||
(task->data = (unsigned char *) Xmalloc ((unsigned)nbytes + 1)))
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
printf ("%s: already read %d bytes using %ld more, eating %ld more\n",
|
||||
__FUNCTION__, bytes_read, nbytes, netbytes);
|
||||
#endif
|
||||
/* _XRead16Pad (dpy, (short *) task->data, netbytes); */
|
||||
_XGetAsyncData (dpy, task->data, buf, len,
|
||||
bytes_read, nbytes, netbytes);
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
nbytes = reply->nItems * sizeof (long);
|
||||
netbytes = reply->nItems << 2;
|
||||
if (nbytes + 1 > 0 &&
|
||||
(task->data = (unsigned char *) Xmalloc ((unsigned)nbytes + 1)))
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
printf ("%s: already read %d bytes using %ld more, eating %ld more\n",
|
||||
__FUNCTION__, bytes_read, nbytes, netbytes);
|
||||
#endif
|
||||
/* _XRead32 (dpy, (long *) task->data, netbytes); */
|
||||
_XGetAsyncData (dpy, task->data, buf, len,
|
||||
bytes_read, nbytes,
|
||||
netbytes);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* This part of the code should never be reached. If it is,
|
||||
* the server sent back a property with an invalid format.
|
||||
* This is a BadImplementation error.
|
||||
*
|
||||
* However this async GetProperty API doesn't report errors
|
||||
* via the standard X mechanism, so don't do anything about
|
||||
* it, other than store it in task->error.
|
||||
*/
|
||||
{
|
||||
#if 0
|
||||
xError error;
|
||||
#endif
|
||||
|
||||
task->error = BadImplementation;
|
||||
|
||||
#if 0
|
||||
error.sequenceNumber = task->request_seq;
|
||||
error.type = X_Error;
|
||||
error.majorCode = X_GetProperty;
|
||||
error.minorCode = 0;
|
||||
error.errorCode = BadImplementation;
|
||||
|
||||
_XError (dpy, &error);
|
||||
#endif
|
||||
}
|
||||
|
||||
nbytes = netbytes = 0L;
|
||||
break;
|
||||
}
|
||||
|
||||
if (task->data == NULL)
|
||||
{
|
||||
task->error = BadAlloc;
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
printf ("%s: already read %d bytes eating %ld\n",
|
||||
__FUNCTION__, bytes_read, netbytes);
|
||||
#endif
|
||||
/* _XEatData (dpy, (unsigned long) netbytes); */
|
||||
_XGetAsyncData (dpy, NULL, buf, len,
|
||||
bytes_read, 0, netbytes);
|
||||
|
||||
/* UnlockDisplay (dpy); */
|
||||
return BadAlloc; /* not Success */
|
||||
}
|
||||
|
||||
(task->data)[nbytes] = '\0';
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
printf ("%s: have data\n", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
task->actual_type = reply->propertyType;
|
||||
task->actual_format = reply->format;
|
||||
task->n_items = reply->nItems;
|
||||
task->bytes_after = reply->bytesAfter;
|
||||
|
||||
/* UnlockDisplay (dpy); */
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static AgPerDisplayData*
|
||||
get_display_data (Display *display,
|
||||
Bool create)
|
||||
{
|
||||
ListNode *node;
|
||||
AgPerDisplayData *dd;
|
||||
|
||||
node = display_datas;
|
||||
while (node != NULL)
|
||||
{
|
||||
dd = (AgPerDisplayData*) node;
|
||||
|
||||
if (dd->display == display)
|
||||
return dd;
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
if (!create)
|
||||
return NULL;
|
||||
|
||||
dd = Xcalloc (1, sizeof (AgPerDisplayData));
|
||||
if (dd == NULL)
|
||||
return NULL;
|
||||
|
||||
dd->display = display;
|
||||
dd->async.next = display->async_handlers;
|
||||
dd->async.handler = async_get_property_handler;
|
||||
dd->async.data = (XPointer) dd;
|
||||
dd->display->async_handlers = &dd->async;
|
||||
|
||||
append_to_list (&display_datas,
|
||||
&display_datas_tail,
|
||||
&dd->node);
|
||||
|
||||
return dd;
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_free_display_data (AgPerDisplayData *dd)
|
||||
{
|
||||
if (dd->pending_tasks == NULL &&
|
||||
dd->completed_tasks == NULL)
|
||||
{
|
||||
DeqAsyncHandler (dd->display, &dd->async);
|
||||
remove_from_list (&display_datas, &display_datas_tail,
|
||||
&dd->node);
|
||||
XFree (dd);
|
||||
}
|
||||
}
|
||||
|
||||
AgGetPropertyTask*
|
||||
ag_task_create (Display *dpy,
|
||||
Window window,
|
||||
Atom property,
|
||||
long offset,
|
||||
long length,
|
||||
Bool delete,
|
||||
Atom req_type)
|
||||
{
|
||||
AgGetPropertyTask *task;
|
||||
xGetPropertyReq *req;
|
||||
xError error;
|
||||
AgPerDisplayData *dd;
|
||||
|
||||
/* Fire up our request */
|
||||
LockDisplay (dpy);
|
||||
|
||||
dd = get_display_data (dpy, True);
|
||||
if (dd == NULL)
|
||||
{
|
||||
UnlockDisplay (dpy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GetReq (GetProperty, req);
|
||||
req->window = window;
|
||||
req->property = property;
|
||||
req->type = req_type;
|
||||
req->delete = delete;
|
||||
req->longOffset = offset;
|
||||
req->longLength = length;
|
||||
|
||||
error.sequenceNumber = dpy->request;
|
||||
|
||||
/* Queue up our async task */
|
||||
task = Xcalloc (1, sizeof (AgGetPropertyTask));
|
||||
if (task == NULL)
|
||||
{
|
||||
UnlockDisplay (dpy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
task->dd = dd;
|
||||
task->window = window;
|
||||
task->property = property;
|
||||
task->request_seq = dpy->request;
|
||||
|
||||
append_to_list (&dd->pending_tasks,
|
||||
&dd->pending_tasks_tail,
|
||||
&task->node);
|
||||
dd->n_tasks_pending += 1;
|
||||
|
||||
UnlockDisplay (dpy);
|
||||
|
||||
SyncHandle ();
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
static void
|
||||
free_task (AgGetPropertyTask *task)
|
||||
{
|
||||
remove_from_list (&task->dd->completed_tasks,
|
||||
&task->dd->completed_tasks_tail,
|
||||
&task->node);
|
||||
task->dd->n_tasks_completed -= 1;
|
||||
maybe_free_display_data (task->dd);
|
||||
XFree (task);
|
||||
}
|
||||
|
||||
Status
|
||||
ag_task_get_reply_and_free (AgGetPropertyTask *task,
|
||||
Atom *actual_type,
|
||||
int *actual_format,
|
||||
unsigned long *nitems,
|
||||
unsigned long *bytesafter,
|
||||
unsigned char **prop)
|
||||
{
|
||||
Display *dpy;
|
||||
|
||||
*prop = NULL;
|
||||
|
||||
dpy = task->dd->display; /* Xlib macros require a variable named "dpy" */
|
||||
|
||||
if (task->error != Success)
|
||||
{
|
||||
Status s = task->error;
|
||||
|
||||
free_task (task);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
if (!task->have_reply)
|
||||
{
|
||||
free_task (task);
|
||||
|
||||
return BadAlloc; /* not Success */
|
||||
}
|
||||
|
||||
*actual_type = task->actual_type;
|
||||
*actual_format = task->actual_format;
|
||||
*nitems = task->n_items;
|
||||
*bytesafter = task->bytes_after;
|
||||
|
||||
*prop = task->data; /* pass out ownership of task->data */
|
||||
|
||||
SyncHandle ();
|
||||
|
||||
free_task (task);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Bool
|
||||
ag_task_have_reply (AgGetPropertyTask *task)
|
||||
{
|
||||
return task->have_reply;
|
||||
}
|
||||
|
||||
Atom
|
||||
ag_task_get_property (AgGetPropertyTask *task)
|
||||
{
|
||||
return task->property;
|
||||
}
|
||||
|
||||
Window
|
||||
ag_task_get_window (AgGetPropertyTask *task)
|
||||
{
|
||||
return task->window;
|
||||
}
|
||||
|
||||
Display*
|
||||
ag_task_get_display (AgGetPropertyTask *task)
|
||||
{
|
||||
return task->dd->display;
|
||||
}
|
||||
|
||||
AgGetPropertyTask*
|
||||
ag_get_next_completed_task (Display *display)
|
||||
{
|
||||
AgPerDisplayData *dd;
|
||||
|
||||
dd = get_display_data (display, False);
|
||||
|
||||
if (dd == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
printf ("%d pending %d completed\n",
|
||||
dd->n_tasks_pending,
|
||||
dd->n_tasks_completed);
|
||||
#endif
|
||||
|
||||
return (AgGetPropertyTask*) dd->completed_tasks;
|
||||
}
|
||||
|
||||
void*
|
||||
ag_Xmalloc (unsigned long bytes)
|
||||
{
|
||||
return (void*) Xmalloc (bytes);
|
||||
}
|
||||
|
||||
void*
|
||||
ag_Xmalloc0 (unsigned long bytes)
|
||||
{
|
||||
return (void*) Xcalloc (bytes, 1);
|
||||
}
|
65
src/async-getprop.h
Normal file
65
src/async-getprop.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* Asynchronous X property getting hack */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Havoc Pennington
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of The Open Group shall not be
|
||||
* used in advertising or otherwise to promote the sale, use or other dealings
|
||||
* in this Software without prior written authorization from The Open Group.
|
||||
*/
|
||||
|
||||
#ifndef ASYNC_GETPROP_H
|
||||
#define ASYNC_GETPROP_H
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
typedef struct _AgGetPropertyTask AgGetPropertyTask;
|
||||
|
||||
AgGetPropertyTask* ag_task_create (Display *display,
|
||||
Window window,
|
||||
Atom property,
|
||||
long offset,
|
||||
long length,
|
||||
Bool delete,
|
||||
Atom req_type);
|
||||
Status ag_task_get_reply_and_free (AgGetPropertyTask *task,
|
||||
Atom *actual_type,
|
||||
int *actual_format,
|
||||
unsigned long *nitems,
|
||||
unsigned long *bytesafter,
|
||||
unsigned char **prop);
|
||||
|
||||
Bool ag_task_have_reply (AgGetPropertyTask *task);
|
||||
Atom ag_task_get_property (AgGetPropertyTask *task);
|
||||
Window ag_task_get_window (AgGetPropertyTask *task);
|
||||
Display* ag_task_get_display (AgGetPropertyTask *task);
|
||||
|
||||
AgGetPropertyTask* ag_get_next_completed_task (Display *display);
|
||||
|
||||
/* so other headers don't have to include internal Xlib goo */
|
||||
void* ag_Xmalloc (unsigned long bytes);
|
||||
void* ag_Xmalloc0 (unsigned long bytes);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
77
src/common.h
77
src/common.h
@@ -41,7 +41,8 @@ typedef enum
|
||||
META_FRAME_STUCK = 1 << 8,
|
||||
META_FRAME_MAXIMIZED = 1 << 9,
|
||||
META_FRAME_ALLOWS_SHADE = 1 << 10,
|
||||
META_FRAME_ALLOWS_MOVE = 1 << 11
|
||||
META_FRAME_ALLOWS_MOVE = 1 << 11,
|
||||
META_FRAME_FULLSCREEN = 1 << 12
|
||||
} MetaFrameFlags;
|
||||
|
||||
typedef enum
|
||||
@@ -98,8 +99,15 @@ typedef enum
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_SW,
|
||||
META_GRAB_OP_KEYBOARD_RESIZING_NW,
|
||||
|
||||
/* Alt+Tab */
|
||||
META_GRAB_OP_KEYBOARD_TABBING_NORMAL,
|
||||
META_GRAB_OP_KEYBOARD_TABBING_DOCK,
|
||||
|
||||
/* Alt+Esc */
|
||||
META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL,
|
||||
META_GRAB_OP_KEYBOARD_ESCAPING_DOCK,
|
||||
|
||||
META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING,
|
||||
|
||||
/* Frame button ops */
|
||||
META_GRAB_OP_CLICKING_MINIMIZE,
|
||||
@@ -109,7 +117,6 @@ typedef enum
|
||||
META_GRAB_OP_CLICKING_MENU
|
||||
} MetaGrabOp;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_CURSOR_DEFAULT,
|
||||
@@ -120,7 +127,10 @@ typedef enum
|
||||
META_CURSOR_SE_RESIZE,
|
||||
META_CURSOR_SW_RESIZE,
|
||||
META_CURSOR_NE_RESIZE,
|
||||
META_CURSOR_NW_RESIZE
|
||||
META_CURSOR_NW_RESIZE,
|
||||
META_CURSOR_MOVE_WINDOW,
|
||||
META_CURSOR_RESIZE_WINDOW,
|
||||
META_CURSOR_BUSY
|
||||
|
||||
} MetaCursor;
|
||||
|
||||
@@ -131,6 +141,13 @@ typedef enum
|
||||
META_FOCUS_MODE_MOUSE
|
||||
} MetaFocusMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_ACTION_DOUBLE_CLICK_TITLEBAR_TOGGLE_SHADE,
|
||||
META_ACTION_DOUBLE_CLICK_TITLEBAR_TOGGLE_MAXIMIZE,
|
||||
META_ACTION_DOUBLE_CLICK_TITLEBAR_LAST
|
||||
} MetaActionDoubleClickTitlebar;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_FRAME_TYPE_NORMAL,
|
||||
@@ -138,16 +155,68 @@ typedef enum
|
||||
META_FRAME_TYPE_MODAL_DIALOG,
|
||||
META_FRAME_TYPE_UTILITY,
|
||||
META_FRAME_TYPE_MENU,
|
||||
/* META_FRAME_TYPE_TOOLBAR, */
|
||||
META_FRAME_TYPE_BORDER,
|
||||
META_FRAME_TYPE_LAST
|
||||
} MetaFrameType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* Create gratuitous divergence from regular
|
||||
* X mod bits, to be sure we find bugs
|
||||
*/
|
||||
META_VIRTUAL_SHIFT_MASK = 1 << 5,
|
||||
META_VIRTUAL_CONTROL_MASK = 1 << 6,
|
||||
META_VIRTUAL_ALT_MASK = 1 << 7,
|
||||
META_VIRTUAL_META_MASK = 1 << 8,
|
||||
META_VIRTUAL_SUPER_MASK = 1 << 9,
|
||||
META_VIRTUAL_HYPER_MASK = 1 << 10,
|
||||
META_VIRTUAL_MOD2_MASK = 1 << 11,
|
||||
META_VIRTUAL_MOD3_MASK = 1 << 12,
|
||||
META_VIRTUAL_MOD4_MASK = 1 << 13,
|
||||
META_VIRTUAL_MOD5_MASK = 1 << 14
|
||||
} MetaVirtualModifier;
|
||||
|
||||
|
||||
/* Function a window button can have. Note, you can't add stuff here
|
||||
* without extending the theme format to draw a new function and
|
||||
* breaking all existing themes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_BUTTON_FUNCTION_MENU,
|
||||
META_BUTTON_FUNCTION_MINIMIZE,
|
||||
META_BUTTON_FUNCTION_MAXIMIZE,
|
||||
META_BUTTON_FUNCTION_CLOSE,
|
||||
META_BUTTON_FUNCTION_LAST
|
||||
} MetaButtonFunction;
|
||||
|
||||
#define MAX_BUTTONS_PER_CORNER META_BUTTON_FUNCTION_LAST
|
||||
|
||||
typedef struct _MetaButtonLayout MetaButtonLayout;
|
||||
struct _MetaButtonLayout
|
||||
{
|
||||
/* buttons in the group on the left side */
|
||||
MetaButtonFunction left_buttons[MAX_BUTTONS_PER_CORNER];
|
||||
|
||||
/* buttons in the group on the right side */
|
||||
MetaButtonFunction right_buttons[MAX_BUTTONS_PER_CORNER];
|
||||
};
|
||||
|
||||
/* should investigate changing these to whatever most apps use */
|
||||
#define META_ICON_WIDTH 32
|
||||
#define META_ICON_HEIGHT 32
|
||||
#define META_MINI_ICON_WIDTH 16
|
||||
#define META_MINI_ICON_HEIGHT 16
|
||||
|
||||
#define META_PRIORITY_PREFS_NOTIFY (G_PRIORITY_DEFAULT_IDLE + 10)
|
||||
#define META_PRIORITY_WORK_AREA_HINT (G_PRIORITY_DEFAULT_IDLE + 15)
|
||||
|
||||
#define POINT_IN_RECT(xcoord, ycoord, rect) \
|
||||
((xcoord) >= (rect).x && \
|
||||
(xcoord) < ((rect).x + (rect).width) && \
|
||||
(ycoord) >= (rect).y && \
|
||||
(ycoord) < ((rect).y + (rect).height))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
1113
src/constraints.c
Normal file
1113
src/constraints.c
Normal file
File diff suppressed because it is too large
Load Diff
59
src/constraints.h
Normal file
59
src/constraints.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Metacity size/position constraints */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_CONSTRAINTS_H
|
||||
#define META_CONSTRAINTS_H
|
||||
|
||||
#include "util.h"
|
||||
#include "window.h"
|
||||
#include "frame.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_RESIZE_LEFT_OR_TOP,
|
||||
META_RESIZE_CENTER,
|
||||
META_RESIZE_RIGHT_OR_BOTTOM
|
||||
} MetaResizeDirection;
|
||||
|
||||
void meta_window_constrain (MetaWindow *window,
|
||||
MetaFrameGeometry *fgeom,
|
||||
const MetaRectangle *orig,
|
||||
int x_move_delta,
|
||||
int y_move_delta,
|
||||
MetaResizeDirection x_direction,
|
||||
int x_delta,
|
||||
MetaResizeDirection y_direction,
|
||||
int y_delta,
|
||||
MetaRectangle *new);
|
||||
|
||||
MetaResizeDirection meta_x_direction_from_gravity (int gravity);
|
||||
MetaResizeDirection meta_y_direction_from_gravity (int gravity);
|
||||
|
||||
#endif /* META_CONSTRAINTS_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
247
src/core.c
247
src/core.c
@@ -19,9 +19,11 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "core.h"
|
||||
#include "frame.h"
|
||||
#include "workspace.h"
|
||||
#include "prefs.h"
|
||||
|
||||
void
|
||||
meta_core_get_client_size (Display *xdisplay,
|
||||
@@ -66,6 +68,7 @@ meta_core_get_frame_type (Display *xdisplay,
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
MetaFrameType base_type;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||
@@ -73,26 +76,28 @@ meta_core_get_frame_type (Display *xdisplay,
|
||||
if (window == NULL || window->frame == NULL)
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||
|
||||
base_type = META_FRAME_TYPE_LAST;
|
||||
|
||||
switch (window->type)
|
||||
{
|
||||
case META_WINDOW_NORMAL:
|
||||
return META_FRAME_TYPE_NORMAL;
|
||||
base_type = META_FRAME_TYPE_NORMAL;
|
||||
break;
|
||||
|
||||
case META_WINDOW_DIALOG:
|
||||
return META_FRAME_TYPE_DIALOG;
|
||||
base_type = META_FRAME_TYPE_DIALOG;
|
||||
break;
|
||||
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
return META_FRAME_TYPE_MODAL_DIALOG;
|
||||
base_type = META_FRAME_TYPE_MODAL_DIALOG;
|
||||
break;
|
||||
|
||||
case META_WINDOW_MENU:
|
||||
return META_FRAME_TYPE_MENU;
|
||||
base_type = META_FRAME_TYPE_MENU;
|
||||
break;
|
||||
|
||||
case META_WINDOW_UTILITY:
|
||||
return META_FRAME_TYPE_UTILITY;
|
||||
base_type = META_FRAME_TYPE_UTILITY;
|
||||
break;
|
||||
|
||||
case META_WINDOW_DESKTOP:
|
||||
@@ -100,12 +105,16 @@ meta_core_get_frame_type (Display *xdisplay,
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
/* No frame */
|
||||
return META_FRAME_TYPE_LAST;
|
||||
base_type = META_FRAME_TYPE_LAST;
|
||||
break;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
return META_FRAME_TYPE_LAST;
|
||||
if (base_type == META_FRAME_TYPE_LAST)
|
||||
return META_FRAME_TYPE_LAST; /* can't add border if undecorated */
|
||||
else if (window->border_only)
|
||||
return META_FRAME_TYPE_BORDER; /* override base frame type */
|
||||
else
|
||||
return base_type;
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
@@ -209,6 +218,22 @@ meta_core_user_raise (Display *xdisplay,
|
||||
meta_window_raise (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_lower (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||
|
||||
if (window == NULL || window->frame == NULL)
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||
|
||||
meta_window_lower (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_focus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
@@ -298,6 +323,25 @@ meta_core_maximize (Display *xdisplay,
|
||||
meta_window_maximize (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_toggle_maximize (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||
|
||||
if (window == NULL || window->frame == NULL)
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||
|
||||
if (window->maximized)
|
||||
meta_window_unmaximize (window);
|
||||
else
|
||||
meta_window_maximize (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_unmaximize (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
@@ -410,9 +454,8 @@ meta_core_change_workspace (Display *xdisplay,
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||
|
||||
meta_window_change_workspace (window,
|
||||
meta_display_get_workspace_by_screen_index (display,
|
||||
window->screen,
|
||||
new_workspace));
|
||||
meta_screen_get_workspace_by_index (window->screen,
|
||||
new_workspace));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -432,7 +475,7 @@ meta_core_get_active_workspace (Screen *xscreen)
|
||||
|
||||
screen = meta_screen_for_x_screen (xscreen);
|
||||
|
||||
return meta_workspace_screen_index (screen->active_workspace);
|
||||
return meta_workspace_index (screen->active_workspace);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -451,6 +494,34 @@ meta_core_get_frame_workspace (Display *xdisplay,
|
||||
return meta_window_get_net_wm_desktop (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_get_frame_extents (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int *x,
|
||||
int *y,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||
|
||||
if (window == NULL || window->frame == NULL)
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||
|
||||
if (x)
|
||||
*x = window->frame->rect.x;
|
||||
if (y)
|
||||
*y = window->frame->rect.y;
|
||||
if (width)
|
||||
*width = window->frame->rect.width;
|
||||
if (height)
|
||||
*height = window->frame->rect.height;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
@@ -468,9 +539,124 @@ meta_core_show_window_menu (Display *xdisplay,
|
||||
if (window == NULL || window->frame == NULL)
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||
|
||||
meta_window_raise (window);
|
||||
meta_window_focus (window, timestamp);
|
||||
|
||||
meta_window_show_menu (window, root_x, root_y, button, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_get_menu_accelerator (MetaMenuOp menu_op,
|
||||
int workspace,
|
||||
unsigned int *keysym,
|
||||
MetaVirtualModifier *modifiers)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = NULL;
|
||||
|
||||
switch (menu_op)
|
||||
{
|
||||
case META_MENU_OP_DELETE:
|
||||
name = META_KEYBINDING_CLOSE;
|
||||
break;
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
name = META_KEYBINDING_MINIMIZE;
|
||||
break;
|
||||
case META_MENU_OP_UNMAXIMIZE:
|
||||
name = META_KEYBINDING_UNMAXIMIZE;
|
||||
break;
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
name = META_KEYBINDING_MAXIMIZE;
|
||||
break;
|
||||
case META_MENU_OP_UNSHADE:
|
||||
name = META_KEYBINDING_TOGGLE_SHADE;
|
||||
break;
|
||||
case META_MENU_OP_SHADE:
|
||||
name = META_KEYBINDING_TOGGLE_SHADE;
|
||||
break;
|
||||
case META_MENU_OP_UNSTICK:
|
||||
name = META_KEYBINDING_TOGGLE_STICKY;
|
||||
break;
|
||||
case META_MENU_OP_STICK:
|
||||
name = META_KEYBINDING_TOGGLE_STICKY;
|
||||
break;
|
||||
case META_MENU_OP_WORKSPACES:
|
||||
switch (workspace)
|
||||
{
|
||||
case 1:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_1;
|
||||
break;
|
||||
case 2:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_2;
|
||||
break;
|
||||
case 3:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_3;
|
||||
break;
|
||||
case 4:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_4;
|
||||
break;
|
||||
case 5:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_5;
|
||||
break;
|
||||
case 6:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_6;
|
||||
break;
|
||||
case 7:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_7;
|
||||
break;
|
||||
case 8:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_8;
|
||||
break;
|
||||
case 9:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_9;
|
||||
break;
|
||||
case 10:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_10;
|
||||
break;
|
||||
case 11:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_11;
|
||||
break;
|
||||
case 12:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_12;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case META_MENU_OP_MOVE:
|
||||
name = META_KEYBINDING_BEGIN_MOVE;
|
||||
break;
|
||||
case META_MENU_OP_RESIZE:
|
||||
name = META_KEYBINDING_BEGIN_RESIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (name)
|
||||
{
|
||||
meta_prefs_get_window_binding (name, keysym, modifiers);
|
||||
}
|
||||
else
|
||||
{
|
||||
*keysym = 0;
|
||||
*modifiers = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
Window xroot,
|
||||
int index)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaScreen *screen;
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
screen = meta_display_screen_for_root (display, xroot);
|
||||
g_assert (screen != NULL);
|
||||
workspace = meta_screen_get_workspace_by_index (screen, index);
|
||||
return workspace ? meta_workspace_get_name (workspace) : NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_core_begin_grab_op (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
@@ -484,14 +670,18 @@ meta_core_begin_grab_op (Display *xdisplay,
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
MetaScreen *screen;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
screen = meta_display_screen_for_xwindow (display, frame_xwindow);
|
||||
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||
|
||||
g_assert (screen != NULL);
|
||||
|
||||
if (window == NULL || window->frame == NULL)
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||
|
||||
return meta_display_begin_grab_op (display, window,
|
||||
return meta_display_begin_grab_op (display, screen, window,
|
||||
op, pointer_already_grabbed,
|
||||
button, modmask,
|
||||
timestamp, root_x, root_y);
|
||||
@@ -527,11 +717,12 @@ meta_core_get_grab_frame (Display *xdisplay)
|
||||
|
||||
g_assert (display != NULL);
|
||||
g_assert (display->grab_op == META_GRAB_OP_NONE ||
|
||||
display->grab_window != NULL);
|
||||
display->grab_screen != NULL);
|
||||
g_assert (display->grab_op == META_GRAB_OP_NONE ||
|
||||
display->grab_window->display->xdisplay == xdisplay);
|
||||
display->grab_screen->display->xdisplay == xdisplay);
|
||||
|
||||
if (display->grab_op != META_GRAB_OP_NONE &&
|
||||
display->grab_window &&
|
||||
display->grab_window->frame)
|
||||
return display->grab_window->frame->xwindow;
|
||||
else
|
||||
@@ -558,7 +749,8 @@ meta_core_grab_buttons (Display *xdisplay,
|
||||
MetaDisplay *display;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
|
||||
meta_verbose ("Grabbing buttons on frame 0x%lx\n", frame_xwindow);
|
||||
meta_display_grab_window_buttons (display, frame_xwindow);
|
||||
}
|
||||
|
||||
@@ -576,7 +768,28 @@ meta_core_set_screen_cursor (Display *xdisplay,
|
||||
if (window == NULL || window->frame == NULL)
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_on_screen);
|
||||
|
||||
meta_screen_set_cursor (window->screen, cursor);
|
||||
meta_frame_set_screen_cursor (window->frame, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_get_screen_size (Display *xdisplay,
|
||||
Window frame_on_screen,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, frame_on_screen);
|
||||
|
||||
if (window == NULL || window->frame == NULL)
|
||||
meta_bug ("No such frame window 0x%lx!\n", frame_on_screen);
|
||||
|
||||
if (width)
|
||||
*width = window->screen->width;
|
||||
if (height)
|
||||
*height = window->screen->height;
|
||||
}
|
||||
|
||||
void
|
||||
|
25
src/core.h
25
src/core.h
@@ -57,6 +57,8 @@ void meta_core_user_resize (Display *xdisplay,
|
||||
|
||||
void meta_core_user_raise (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_user_lower (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
|
||||
void meta_core_user_focus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
@@ -75,6 +77,8 @@ void meta_core_get_size (Display *xdisplay,
|
||||
|
||||
void meta_core_minimize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_toggle_maximize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_unmaximize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_maximize (Display *xdisplay,
|
||||
@@ -98,6 +102,17 @@ int meta_core_get_num_workspaces (Screen *xscreen);
|
||||
int meta_core_get_active_workspace (Screen *xscreen);
|
||||
int meta_core_get_frame_workspace (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
Window xroot,
|
||||
int index);
|
||||
|
||||
void meta_core_get_frame_extents (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int *x,
|
||||
int *y,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
|
||||
void meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
@@ -106,6 +121,11 @@ void meta_core_show_window_menu (Display *xdisplay,
|
||||
int button,
|
||||
Time timestamp);
|
||||
|
||||
void meta_core_get_menu_accelerator (MetaMenuOp menu_op,
|
||||
int workspace,
|
||||
unsigned int *keysym,
|
||||
MetaVirtualModifier *modifiers);
|
||||
|
||||
gboolean meta_core_begin_grab_op (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaGrabOp op,
|
||||
@@ -129,6 +149,11 @@ void meta_core_set_screen_cursor (Display *xdisplay,
|
||||
Window frame_on_screen,
|
||||
MetaCursor cursor);
|
||||
|
||||
void meta_core_get_screen_size (Display *xdisplay,
|
||||
Window frame_on_screen,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
/* Used because we ignore EnterNotify when a window is unmapped that
|
||||
* really shouldn't cause focus changes, by comparing the event serial
|
||||
* of the EnterNotify and the UnmapNotify.
|
||||
|
14
src/delete.c
14
src/delete.c
@@ -1,7 +1,7 @@
|
||||
/* Metacity window deletion */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@@ -38,11 +38,9 @@ delete_ping_reply_func (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
void *user_data)
|
||||
{
|
||||
MetaWindow *window = user_data;
|
||||
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Got reply to delete ping for %s\n",
|
||||
window->desc);
|
||||
((MetaWindow*)user_data)->desc);
|
||||
|
||||
/* we do nothing */
|
||||
}
|
||||
@@ -266,7 +264,7 @@ io_from_ping_dialog (GIOChannel *channel,
|
||||
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Read %d bytes strlen %d \"%s\" from child\n",
|
||||
len, strlen (str), str);
|
||||
len, str ? strlen (str) : 0, str ? str : "NULL");
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
@@ -341,7 +339,7 @@ delete_ping_timeout_func (MetaDisplay *display,
|
||||
|
||||
channel = g_io_channel_unix_new (window->dialog_pipe);
|
||||
g_io_add_watch_full (channel, G_PRIORITY_DEFAULT,
|
||||
G_IO_IN | G_IO_HUP | G_IO_ERR,
|
||||
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
|
||||
io_from_ping_dialog,
|
||||
NULL, NULL);
|
||||
g_io_channel_unref (channel);
|
||||
@@ -371,7 +369,7 @@ meta_window_delete (MetaWindow *window,
|
||||
window->desc);
|
||||
XKillClient (window->display->xdisplay, window->xwindow);
|
||||
}
|
||||
meta_error_trap_pop (window->display);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
|
||||
meta_display_ping_window (window->display,
|
||||
window,
|
||||
@@ -438,7 +436,7 @@ meta_window_kill (MetaWindow *window)
|
||||
window->desc);
|
||||
meta_error_trap_push (window->display);
|
||||
XKillClient (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
|
1679
src/display.c
1679
src/display.c
File diff suppressed because it is too large
Load Diff
160
src/display.h
160
src/display.h
@@ -22,11 +22,19 @@
|
||||
#ifndef META_DISPLAY_H
|
||||
#define META_DISPLAY_H
|
||||
|
||||
#ifndef PACKAGE
|
||||
#error "config.h not included"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include "eventqueue.h"
|
||||
#include "common.h"
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
#include <libsn/sn.h>
|
||||
#endif
|
||||
|
||||
#define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0)
|
||||
|
||||
/* this doesn't really belong here, oh well. */
|
||||
@@ -40,13 +48,17 @@ struct _MetaRectangle
|
||||
int height;
|
||||
};
|
||||
|
||||
typedef struct _MetaDisplay MetaDisplay;
|
||||
typedef struct _MetaFrame MetaFrame;
|
||||
typedef struct _MetaScreen MetaScreen;
|
||||
typedef struct _MetaStack MetaStack;
|
||||
typedef struct _MetaUISlave MetaUISlave;
|
||||
typedef struct _MetaWindow MetaWindow;
|
||||
typedef struct _MetaWorkspace MetaWorkspace;
|
||||
typedef struct _MetaDisplay MetaDisplay;
|
||||
typedef struct _MetaFrame MetaFrame;
|
||||
typedef struct _MetaKeyBinding MetaKeyBinding;
|
||||
typedef struct _MetaScreen MetaScreen;
|
||||
typedef struct _MetaStack MetaStack;
|
||||
typedef struct _MetaUISlave MetaUISlave;
|
||||
typedef struct _MetaWindow MetaWindow;
|
||||
typedef struct _MetaWorkspace MetaWorkspace;
|
||||
|
||||
typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
|
||||
typedef struct _MetaGroupPropHooks MetaGroupPropHooks;
|
||||
|
||||
typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
@@ -122,28 +134,53 @@ struct _MetaDisplay
|
||||
Atom atom_metacity_set_keybindings_message;
|
||||
Atom atom_net_wm_state_hidden;
|
||||
Atom atom_net_wm_window_type_utility;
|
||||
Atom atom_net_wm_window_type_splashscreen;
|
||||
Atom atom_net_wm_window_type_splash;
|
||||
Atom atom_net_wm_ping;
|
||||
Atom atom_net_wm_pid;
|
||||
Atom atom_wm_client_machine;
|
||||
Atom atom_net_wm_state_fullscreen;
|
||||
Atom atom_net_workarea;
|
||||
Atom atom_net_showing_desktop;
|
||||
Atom atom_net_desktop_layout;
|
||||
Atom atom_manager;
|
||||
Atom atom_targets;
|
||||
Atom atom_multiple;
|
||||
Atom atom_timestamp;
|
||||
Atom atom_version;
|
||||
Atom atom_atom_pair;
|
||||
Atom atom_net_desktop_names;
|
||||
Atom atom_net_wm_allowed_actions;
|
||||
Atom atom_net_wm_action_move;
|
||||
Atom atom_net_wm_action_resize;
|
||||
Atom atom_net_wm_action_shade;
|
||||
Atom atom_net_wm_action_stick;
|
||||
Atom atom_net_wm_action_maximize_horz;
|
||||
Atom atom_net_wm_action_maximize_vert;
|
||||
Atom atom_net_wm_action_change_desktop;
|
||||
Atom atom_net_wm_action_close;
|
||||
Atom atom_net_wm_state_above;
|
||||
Atom atom_net_wm_state_below;
|
||||
Atom atom_net_startup_id;
|
||||
Atom atom_metacity_toggle_verbose;
|
||||
|
||||
/* This is the actual window from focus events,
|
||||
* not the one we last set
|
||||
*/
|
||||
MetaWindow *focus_window;
|
||||
|
||||
/* window we are expecting a FocusIn event for
|
||||
*/
|
||||
MetaWindow *expected_focus_window;
|
||||
|
||||
/* Most recently focused list. Always contains all
|
||||
* live windows.
|
||||
*/
|
||||
GList *mru_list;
|
||||
|
||||
GList *workspaces;
|
||||
GList *mru_list;
|
||||
|
||||
guint showing_desktop : 1;
|
||||
guint static_gravity_works : 1;
|
||||
|
||||
/*< private-ish >*/
|
||||
guint error_trap_synced_at_last_pop : 1;
|
||||
MetaEventQueue *events;
|
||||
GSList *screens;
|
||||
GHashTable *window_ids;
|
||||
@@ -175,19 +212,74 @@ struct _MetaDisplay
|
||||
|
||||
/* Pings which we're waiting for a reply from */
|
||||
GSList *pending_pings;
|
||||
|
||||
/* Pending autoraise */
|
||||
guint autoraise_timeout_id;
|
||||
|
||||
/* Alt+click button grabs */
|
||||
unsigned int window_grab_modifiers;
|
||||
|
||||
/* current window operation */
|
||||
MetaGrabOp grab_op;
|
||||
MetaScreen *grab_screen;
|
||||
MetaWindow *grab_window;
|
||||
Window grab_xwindow;
|
||||
int grab_button;
|
||||
int grab_root_x;
|
||||
int grab_root_y;
|
||||
int grab_initial_root_x;
|
||||
int grab_initial_root_y;
|
||||
int grab_current_root_x;
|
||||
int grab_current_root_y;
|
||||
gulong grab_mask;
|
||||
guint grab_have_pointer : 1;
|
||||
guint grab_have_keyboard : 1;
|
||||
MetaRectangle grab_initial_window_pos;
|
||||
MetaRectangle grab_current_window_pos;
|
||||
MetaResizePopup *grab_resize_popup;
|
||||
GTimeVal grab_last_moveresize_time;
|
||||
|
||||
|
||||
/* Keybindings stuff */
|
||||
MetaKeyBinding *screen_bindings;
|
||||
int n_screen_bindings;
|
||||
MetaKeyBinding *window_bindings;
|
||||
int n_window_bindings;
|
||||
int min_keycode;
|
||||
int max_keycode;
|
||||
KeySym *keymap;
|
||||
int keysyms_per_keycode;
|
||||
XModifierKeymap *modmap;
|
||||
unsigned int ignored_modifier_mask;
|
||||
unsigned int num_lock_mask;
|
||||
unsigned int scroll_lock_mask;
|
||||
unsigned int hyper_mask;
|
||||
unsigned int super_mask;
|
||||
unsigned int meta_mask;
|
||||
|
||||
/* Xinerama cache */
|
||||
unsigned int xinerama_cache_invalidated : 1;
|
||||
|
||||
/* Closing down the display */
|
||||
int closing;
|
||||
|
||||
/* Managed by group.c */
|
||||
GHashTable *groups_by_leader;
|
||||
|
||||
/* currently-active window menu if any */
|
||||
MetaWindowMenu *window_menu;
|
||||
MetaWindow *window_with_menu;
|
||||
|
||||
/* Managed by window-props.c */
|
||||
MetaWindowPropHooks *prop_hooks;
|
||||
|
||||
/* Managed by group-props.c */
|
||||
MetaGroupPropHooks *group_prop_hooks;
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
/* This is at the end in case someone doesn't include config.h before this file
|
||||
* the results won't be catastrophic
|
||||
*/
|
||||
SnDisplay *sn_display;
|
||||
#endif
|
||||
};
|
||||
|
||||
gboolean meta_display_open (const char *name);
|
||||
@@ -196,10 +288,18 @@ MetaScreen* meta_display_screen_for_root (MetaDisplay *display,
|
||||
Window xroot);
|
||||
MetaScreen* meta_display_screen_for_x_screen (MetaDisplay *display,
|
||||
Screen *screen);
|
||||
MetaScreen* meta_display_screen_for_xwindow (MetaDisplay *display,
|
||||
Window xindow);
|
||||
void meta_display_grab (MetaDisplay *display);
|
||||
void meta_display_ungrab (MetaDisplay *display);
|
||||
gboolean meta_display_is_double_click (MetaDisplay *display);
|
||||
|
||||
void meta_display_unmanage_screen (MetaDisplay *display,
|
||||
MetaScreen *screen);
|
||||
|
||||
void meta_display_unmanage_windows_for_screen (MetaDisplay *display,
|
||||
MetaScreen *screen);
|
||||
|
||||
/* A given MetaWindow may have various X windows that "belong"
|
||||
* to it, such as the frame window.
|
||||
*/
|
||||
@@ -216,16 +316,18 @@ GSList* meta_display_list_windows (MetaDisplay *display);
|
||||
MetaDisplay* meta_display_for_x_display (Display *xdisplay);
|
||||
GSList* meta_displays_list (void);
|
||||
|
||||
MetaWorkspace* meta_display_get_workspace_by_index (MetaDisplay *display,
|
||||
int index);
|
||||
MetaWorkspace* meta_display_get_workspace_by_screen_index (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
int index);
|
||||
|
||||
Cursor meta_display_create_x_cursor (MetaDisplay *display,
|
||||
MetaCursor cursor);
|
||||
|
||||
void meta_display_set_grab_op_cursor (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaGrabOp op,
|
||||
gboolean change_pointer,
|
||||
Window grab_xwindow,
|
||||
Time timestamp);
|
||||
|
||||
gboolean meta_display_begin_grab_op (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
MetaGrabOp op,
|
||||
gboolean pointer_already_grabbed,
|
||||
@@ -252,10 +354,6 @@ void meta_display_increment_event_serial (MetaDisplay *display);
|
||||
|
||||
void meta_display_update_active_window_hint (MetaDisplay *display);
|
||||
|
||||
/* Show/hide the desktop (temporarily hide all windows) */
|
||||
void meta_display_show_desktop (MetaDisplay *display);
|
||||
void meta_display_unshow_desktop (MetaDisplay *display);
|
||||
|
||||
guint32 meta_display_get_current_time (MetaDisplay *display);
|
||||
|
||||
/* utility goo */
|
||||
@@ -289,10 +387,24 @@ GSList* meta_display_get_tab_list (MetaDisplay *display,
|
||||
|
||||
MetaWindow* meta_display_get_tab_next (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
MetaScreen *screen,
|
||||
MetaWorkspace *workspace,
|
||||
MetaWindow *window,
|
||||
gboolean backward);
|
||||
|
||||
MetaWindow* meta_display_get_tab_current (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
MetaScreen *screen,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
int meta_resize_gravity_from_grab_op (MetaGrabOp op);
|
||||
|
||||
gboolean meta_rectangle_intersect (MetaRectangle *src1,
|
||||
MetaRectangle *src2,
|
||||
MetaRectangle *dest);
|
||||
|
||||
void meta_display_devirtualize_modifiers (MetaDisplay *display,
|
||||
MetaVirtualModifier modifiers,
|
||||
unsigned int *mask);
|
||||
|
||||
#endif
|
||||
|
218
src/draw-workspace.c
Normal file
218
src/draw-workspace.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/* Draw a workspace */
|
||||
|
||||
/* This file should not be modified to depend on other files in
|
||||
* libwnck or metacity, since it's used in both of them
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "draw-workspace.h"
|
||||
|
||||
|
||||
static void
|
||||
get_window_rect (const WnckWindowDisplayInfo *win,
|
||||
int screen_width,
|
||||
int screen_height,
|
||||
const GdkRectangle *workspace_rect,
|
||||
GdkRectangle *rect)
|
||||
{
|
||||
double width_ratio, height_ratio;
|
||||
int x, y, width, height;
|
||||
|
||||
width_ratio = (double) workspace_rect->width / (double) screen_width;
|
||||
height_ratio = (double) workspace_rect->height / (double) screen_height;
|
||||
|
||||
x = win->x;
|
||||
y = win->y;
|
||||
width = win->width;
|
||||
height = win->height;
|
||||
|
||||
x *= width_ratio;
|
||||
y *= height_ratio;
|
||||
width *= width_ratio;
|
||||
height *= height_ratio;
|
||||
|
||||
x += workspace_rect->x;
|
||||
y += workspace_rect->y;
|
||||
|
||||
if (width < 3)
|
||||
width = 3;
|
||||
if (height < 3)
|
||||
height = 3;
|
||||
|
||||
rect->x = x;
|
||||
rect->y = y;
|
||||
rect->width = width;
|
||||
rect->height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_window (GtkWidget *widget,
|
||||
GdkDrawable *drawable,
|
||||
const WnckWindowDisplayInfo *win,
|
||||
const GdkRectangle *winrect)
|
||||
{
|
||||
GdkPixbuf *icon;
|
||||
int icon_x, icon_y, icon_w, icon_h;
|
||||
|
||||
gdk_draw_rectangle (drawable,
|
||||
win->is_active ?
|
||||
widget->style->bg_gc[GTK_STATE_SELECTED] :
|
||||
widget->style->bg_gc[GTK_STATE_NORMAL],
|
||||
TRUE,
|
||||
winrect->x + 1, winrect->y + 1,
|
||||
winrect->width - 2, winrect->height - 2);
|
||||
|
||||
icon = win->icon;
|
||||
|
||||
icon_w = icon_h = 0;
|
||||
|
||||
if (icon)
|
||||
{
|
||||
icon_w = gdk_pixbuf_get_width (icon);
|
||||
icon_h = gdk_pixbuf_get_height (icon);
|
||||
|
||||
/* If the icon is too big, fall back to mini icon.
|
||||
* We don't arbitrarily scale the icon, because it's
|
||||
* just too slow on my Athlon 850.
|
||||
*/
|
||||
if (icon_w > (winrect->width - 2) ||
|
||||
icon_h > (winrect->height - 2))
|
||||
{
|
||||
icon = win->mini_icon;
|
||||
if (icon)
|
||||
{
|
||||
icon_w = gdk_pixbuf_get_width (icon);
|
||||
icon_h = gdk_pixbuf_get_height (icon);
|
||||
|
||||
/* Give up. */
|
||||
if (icon_w > (winrect->width - 2) ||
|
||||
icon_h > (winrect->height - 2))
|
||||
icon = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (icon)
|
||||
{
|
||||
icon_x = winrect->x + (winrect->width - icon_w) / 2;
|
||||
icon_y = winrect->y + (winrect->height - icon_h) / 2;
|
||||
|
||||
{
|
||||
/* render_to_drawable should take a clip rect to save
|
||||
* us this mess...
|
||||
*/
|
||||
GdkRectangle pixbuf_rect;
|
||||
GdkRectangle draw_rect;
|
||||
|
||||
pixbuf_rect.x = icon_x;
|
||||
pixbuf_rect.y = icon_y;
|
||||
pixbuf_rect.width = icon_w;
|
||||
pixbuf_rect.height = icon_h;
|
||||
|
||||
if (gdk_rectangle_intersect ((GdkRectangle *)winrect, &pixbuf_rect,
|
||||
&draw_rect))
|
||||
{
|
||||
gdk_pixbuf_render_to_drawable_alpha (icon,
|
||||
drawable,
|
||||
draw_rect.x - pixbuf_rect.x,
|
||||
draw_rect.y - pixbuf_rect.y,
|
||||
draw_rect.x, draw_rect.y,
|
||||
draw_rect.width,
|
||||
draw_rect.height,
|
||||
GDK_PIXBUF_ALPHA_FULL,
|
||||
128,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gdk_draw_rectangle (drawable,
|
||||
win->is_active ?
|
||||
widget->style->fg_gc[GTK_STATE_SELECTED] :
|
||||
widget->style->fg_gc[GTK_STATE_NORMAL],
|
||||
FALSE,
|
||||
winrect->x, winrect->y,
|
||||
winrect->width - 1, winrect->height - 1);
|
||||
}
|
||||
|
||||
void
|
||||
wnck_draw_workspace (GtkWidget *widget,
|
||||
GdkDrawable *drawable,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int screen_width,
|
||||
int screen_height,
|
||||
GdkPixbuf *workspace_background,
|
||||
gboolean is_active,
|
||||
const WnckWindowDisplayInfo *windows,
|
||||
int n_windows)
|
||||
{
|
||||
int i;
|
||||
GdkRectangle workspace_rect;
|
||||
|
||||
workspace_rect.x = x;
|
||||
workspace_rect.y = y;
|
||||
workspace_rect.width = width;
|
||||
workspace_rect.height = height;
|
||||
|
||||
|
||||
if (is_active)
|
||||
gdk_draw_rectangle (drawable,
|
||||
GTK_WIDGET (widget)->style->dark_gc[GTK_STATE_SELECTED],
|
||||
TRUE,
|
||||
x, y, width, height);
|
||||
else if (workspace_background)
|
||||
{
|
||||
gdk_pixbuf_render_to_drawable (workspace_background,
|
||||
drawable,
|
||||
GTK_WIDGET (widget)->style->dark_gc[GTK_STATE_SELECTED],
|
||||
0, 0,
|
||||
x, y,
|
||||
-1, -1,
|
||||
GDK_RGB_DITHER_MAX,
|
||||
0, 0);
|
||||
}
|
||||
else
|
||||
gdk_draw_rectangle (drawable,
|
||||
GTK_WIDGET (widget)->style->dark_gc[GTK_STATE_NORMAL],
|
||||
TRUE,
|
||||
x, y, width, height);
|
||||
|
||||
|
||||
i = 0;
|
||||
while (i < n_windows)
|
||||
{
|
||||
const WnckWindowDisplayInfo *win = &windows[i];
|
||||
GdkRectangle winrect;
|
||||
|
||||
get_window_rect (win, screen_width, screen_height, &workspace_rect, &winrect);
|
||||
|
||||
draw_window (widget,
|
||||
drawable,
|
||||
win,
|
||||
&winrect);
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
59
src/draw-workspace.h
Normal file
59
src/draw-workspace.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Draw a workspace */
|
||||
|
||||
/* This file should not be modified to depend on other files in
|
||||
* libwnck or metacity, since it's used in both of them
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef WNCK_DRAW_WORKSPACE_H
|
||||
#define WNCK_DRAW_WORKSPACE_H
|
||||
|
||||
#include <gdk/gdkdrawable.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkPixbuf *icon;
|
||||
GdkPixbuf *mini_icon;
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
guint is_active : 1;
|
||||
|
||||
} WnckWindowDisplayInfo;
|
||||
|
||||
void wnck_draw_workspace (GtkWidget *widget,
|
||||
GdkDrawable *drawable,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int screen_width,
|
||||
int screen_height,
|
||||
GdkPixbuf *workspace_background,
|
||||
gboolean is_active,
|
||||
const WnckWindowDisplayInfo *windows,
|
||||
int n_windows);
|
||||
|
||||
#endif
|
144
src/effects.c
144
src/effects.c
@@ -19,10 +19,23 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "effects.h"
|
||||
#include "display.h"
|
||||
#include "ui.h"
|
||||
|
||||
#ifdef HAVE_SHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_ANIMATION_DRAW_ROOT,
|
||||
META_ANIMATION_WINDOW_WIREFRAME,
|
||||
META_ANIMATION_WINDOW_OPAQUE
|
||||
|
||||
} MetaAnimationStyle;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaScreen *screen;
|
||||
@@ -41,11 +54,14 @@ typedef struct
|
||||
/* used instead of the global flag, since
|
||||
* we don't want to change midstream.
|
||||
*/
|
||||
gboolean use_opaque;
|
||||
MetaAnimationStyle style;
|
||||
|
||||
/* For wireframe */
|
||||
/* For wireframe drawn on root window */
|
||||
GC gc;
|
||||
|
||||
/* For wireframe window */
|
||||
Window wireframe_xwindow;
|
||||
|
||||
/* For opaque */
|
||||
MetaImageWindow *image_window;
|
||||
GdkPixbuf *orig_pixbuf;
|
||||
@@ -54,6 +70,61 @@ typedef struct
|
||||
|
||||
} BoxAnimationContext;
|
||||
|
||||
static void
|
||||
update_wireframe_window (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
const MetaRectangle *rect)
|
||||
{
|
||||
XMoveResizeWindow (display->xdisplay,
|
||||
xwindow,
|
||||
rect->x, rect->y,
|
||||
rect->width, rect->height);
|
||||
|
||||
#ifdef HAVE_SHAPE
|
||||
|
||||
#define OUTLINE_WIDTH 3
|
||||
|
||||
if (rect->width > OUTLINE_WIDTH * 2 &&
|
||||
rect->height > OUTLINE_WIDTH * 2)
|
||||
{
|
||||
XRectangle xrect;
|
||||
Region inner_xregion;
|
||||
Region outer_xregion;
|
||||
|
||||
inner_xregion = XCreateRegion ();
|
||||
outer_xregion = XCreateRegion ();
|
||||
|
||||
xrect.x = 0;
|
||||
xrect.y = 0;
|
||||
xrect.width = rect->width;
|
||||
xrect.height = rect->height;
|
||||
|
||||
XUnionRectWithRegion (&xrect, outer_xregion, outer_xregion);
|
||||
|
||||
xrect.x += OUTLINE_WIDTH;
|
||||
xrect.y += OUTLINE_WIDTH;
|
||||
xrect.width -= OUTLINE_WIDTH * 2;
|
||||
xrect.height -= OUTLINE_WIDTH * 2;
|
||||
|
||||
XUnionRectWithRegion (&xrect, inner_xregion, inner_xregion);
|
||||
|
||||
XSubtractRegion (outer_xregion, inner_xregion, outer_xregion);
|
||||
|
||||
XShapeCombineRegion (display->xdisplay, xwindow,
|
||||
ShapeBounding, 0, 0, outer_xregion, ShapeSet);
|
||||
|
||||
XDestroyRegion (outer_xregion);
|
||||
XDestroyRegion (inner_xregion);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unset the shape */
|
||||
XShapeCombineMask (display->xdisplay, xwindow,
|
||||
ShapeBounding, 0, 0, None, ShapeSet);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
effects_draw_box_animation_timeout (BoxAnimationContext *context)
|
||||
{
|
||||
@@ -64,7 +135,7 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
|
||||
|
||||
if (!context->first_time)
|
||||
{
|
||||
if (!context->use_opaque)
|
||||
if (context->style == META_ANIMATION_DRAW_ROOT)
|
||||
{
|
||||
/* Restore the previously drawn background */
|
||||
XDrawRectangle (context->screen->display->xdisplay,
|
||||
@@ -94,18 +165,23 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
|
||||
if (elapsed > context->millisecs_duration)
|
||||
{
|
||||
/* All done */
|
||||
if (context->use_opaque)
|
||||
if (context->style == META_ANIMATION_WINDOW_OPAQUE)
|
||||
{
|
||||
g_object_unref (G_OBJECT (context->orig_pixbuf));
|
||||
meta_image_window_free (context->image_window);
|
||||
}
|
||||
else
|
||||
else if (context->style == META_ANIMATION_DRAW_ROOT)
|
||||
{
|
||||
meta_display_ungrab (context->screen->display);
|
||||
meta_ui_pop_delay_exposes (context->screen->ui);
|
||||
XFreeGC (context->screen->display->xdisplay,
|
||||
context->gc);
|
||||
}
|
||||
else if (context->style == META_ANIMATION_WINDOW_WIREFRAME)
|
||||
{
|
||||
XDestroyWindow (context->screen->display->xdisplay,
|
||||
context->wireframe_xwindow);
|
||||
}
|
||||
|
||||
g_free (context);
|
||||
return FALSE;
|
||||
@@ -130,7 +206,7 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
|
||||
|
||||
context->last_rect = draw_rect;
|
||||
|
||||
if (context->use_opaque)
|
||||
if (context->style == META_ANIMATION_WINDOW_OPAQUE)
|
||||
{
|
||||
GdkPixbuf *scaled;
|
||||
|
||||
@@ -174,7 +250,7 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
|
||||
g_object_unref (G_OBJECT (scaled));
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (context->style == META_ANIMATION_DRAW_ROOT)
|
||||
{
|
||||
/* Draw the rectangle */
|
||||
XDrawRectangle (context->screen->display->xdisplay,
|
||||
@@ -183,6 +259,12 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
|
||||
draw_rect.x, draw_rect.y,
|
||||
draw_rect.width, draw_rect.height);
|
||||
}
|
||||
else if (context->style == META_ANIMATION_WINDOW_WIREFRAME)
|
||||
{
|
||||
update_wireframe_window (context->screen->display,
|
||||
context->wireframe_xwindow,
|
||||
&draw_rect);
|
||||
}
|
||||
|
||||
/* kick changes onto the server */
|
||||
XFlush (context->screen->display->xdisplay);
|
||||
@@ -198,7 +280,7 @@ effects_draw_box_animation_timeout (BoxAnimationContext *context)
|
||||
* and unmapping of windows that's going on.
|
||||
*/
|
||||
|
||||
static gboolean use_opaque_animations = FALSE;
|
||||
static MetaAnimationStyle animation_style = META_ANIMATION_WINDOW_WIREFRAME;
|
||||
|
||||
void
|
||||
meta_effects_draw_box_animation (MetaScreen *screen,
|
||||
@@ -225,9 +307,14 @@ meta_effects_draw_box_animation (MetaScreen *screen,
|
||||
context->end_rect = *destination_rect;
|
||||
context->anim_type = anim_type;
|
||||
|
||||
context->use_opaque = use_opaque_animations;
|
||||
context->style = animation_style;
|
||||
|
||||
if (context->use_opaque)
|
||||
#ifndef HAVE_SHAPE
|
||||
if (context->style == META_ANIMATION_WINDOW_WIREFRAME)
|
||||
context->style = META_ANIMATION_DRAW_ROOT;
|
||||
#endif
|
||||
|
||||
if (context->style == META_ANIMATION_WINDOW_OPAQUE)
|
||||
{
|
||||
GdkPixbuf *pix;
|
||||
|
||||
@@ -242,11 +329,13 @@ meta_effects_draw_box_animation (MetaScreen *screen,
|
||||
if (pix == NULL)
|
||||
{
|
||||
/* Fall back to wireframe */
|
||||
context->use_opaque = FALSE;
|
||||
context->style = META_ANIMATION_WINDOW_WIREFRAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->image_window = meta_image_window_new (initial_rect->width,
|
||||
context->image_window = meta_image_window_new (screen->display->xdisplay,
|
||||
screen->number,
|
||||
initial_rect->width,
|
||||
initial_rect->height);
|
||||
context->orig_pixbuf = pix;
|
||||
meta_image_window_set (context->image_window,
|
||||
@@ -258,7 +347,36 @@ meta_effects_draw_box_animation (MetaScreen *screen,
|
||||
}
|
||||
|
||||
/* Not an else, so that fallback works */
|
||||
if (!context->use_opaque)
|
||||
if (context->style == META_ANIMATION_WINDOW_WIREFRAME)
|
||||
{
|
||||
XSetWindowAttributes attrs;
|
||||
|
||||
attrs.override_redirect = True;
|
||||
attrs.background_pixel = BlackPixel (screen->display->xdisplay,
|
||||
screen->number);
|
||||
|
||||
context->wireframe_xwindow = XCreateWindow (screen->display->xdisplay,
|
||||
screen->xroot,
|
||||
initial_rect->x,
|
||||
initial_rect->y,
|
||||
initial_rect->width,
|
||||
initial_rect->height,
|
||||
0,
|
||||
CopyFromParent,
|
||||
CopyFromParent,
|
||||
CopyFromParent,
|
||||
CWOverrideRedirect | CWBackPixel,
|
||||
&attrs);
|
||||
|
||||
update_wireframe_window (screen->display,
|
||||
context->wireframe_xwindow,
|
||||
initial_rect);
|
||||
|
||||
XMapWindow (screen->display->xdisplay,
|
||||
context->wireframe_xwindow);
|
||||
}
|
||||
|
||||
if (context->style == META_ANIMATION_DRAW_ROOT)
|
||||
{
|
||||
XGCValues gc_values;
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include "util.h"
|
||||
#include "screen.h"
|
||||
|
||||
#define META_MINIMIZE_ANIMATION_LENGTH 0.5
|
||||
#define META_MINIMIZE_ANIMATION_LENGTH 0.35
|
||||
#define META_SHADE_ANIMATION_LENGTH 0.2
|
||||
|
||||
typedef enum
|
||||
|
657
src/eggaccelerators.c
Normal file
657
src/eggaccelerators.c
Normal file
@@ -0,0 +1,657 @@
|
||||
/* eggaccelerators.c
|
||||
* Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik
|
||||
* Developed by Havoc Pennington, Tim Janik
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "eggaccelerators.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
enum
|
||||
{
|
||||
EGG_MODMAP_ENTRY_SHIFT = 0,
|
||||
EGG_MODMAP_ENTRY_LOCK = 1,
|
||||
EGG_MODMAP_ENTRY_CONTROL = 2,
|
||||
EGG_MODMAP_ENTRY_MOD1 = 3,
|
||||
EGG_MODMAP_ENTRY_MOD2 = 4,
|
||||
EGG_MODMAP_ENTRY_MOD3 = 5,
|
||||
EGG_MODMAP_ENTRY_MOD4 = 6,
|
||||
EGG_MODMAP_ENTRY_MOD5 = 7,
|
||||
EGG_MODMAP_ENTRY_LAST = 8
|
||||
};
|
||||
|
||||
#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST];
|
||||
|
||||
} EggModmap;
|
||||
|
||||
const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap);
|
||||
|
||||
static inline gboolean
|
||||
is_alt (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 'a' || string[1] == 'A') &&
|
||||
(string[2] == 'l' || string[2] == 'L') &&
|
||||
(string[3] == 't' || string[3] == 'T') &&
|
||||
(string[4] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_ctl (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 'c' || string[1] == 'C') &&
|
||||
(string[2] == 't' || string[2] == 'T') &&
|
||||
(string[3] == 'l' || string[3] == 'L') &&
|
||||
(string[4] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_modx (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 'm' || string[1] == 'M') &&
|
||||
(string[2] == 'o' || string[2] == 'O') &&
|
||||
(string[3] == 'd' || string[3] == 'D') &&
|
||||
(string[4] >= '1' && string[4] <= '5') &&
|
||||
(string[5] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_ctrl (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 'c' || string[1] == 'C') &&
|
||||
(string[2] == 't' || string[2] == 'T') &&
|
||||
(string[3] == 'r' || string[3] == 'R') &&
|
||||
(string[4] == 'l' || string[4] == 'L') &&
|
||||
(string[5] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_shft (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 's' || string[1] == 'S') &&
|
||||
(string[2] == 'h' || string[2] == 'H') &&
|
||||
(string[3] == 'f' || string[3] == 'F') &&
|
||||
(string[4] == 't' || string[4] == 'T') &&
|
||||
(string[5] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_shift (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 's' || string[1] == 'S') &&
|
||||
(string[2] == 'h' || string[2] == 'H') &&
|
||||
(string[3] == 'i' || string[3] == 'I') &&
|
||||
(string[4] == 'f' || string[4] == 'F') &&
|
||||
(string[5] == 't' || string[5] == 'T') &&
|
||||
(string[6] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_control (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 'c' || string[1] == 'C') &&
|
||||
(string[2] == 'o' || string[2] == 'O') &&
|
||||
(string[3] == 'n' || string[3] == 'N') &&
|
||||
(string[4] == 't' || string[4] == 'T') &&
|
||||
(string[5] == 'r' || string[5] == 'R') &&
|
||||
(string[6] == 'o' || string[6] == 'O') &&
|
||||
(string[7] == 'l' || string[7] == 'L') &&
|
||||
(string[8] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_release (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 'r' || string[1] == 'R') &&
|
||||
(string[2] == 'e' || string[2] == 'E') &&
|
||||
(string[3] == 'l' || string[3] == 'L') &&
|
||||
(string[4] == 'e' || string[4] == 'E') &&
|
||||
(string[5] == 'a' || string[5] == 'A') &&
|
||||
(string[6] == 's' || string[6] == 'S') &&
|
||||
(string[7] == 'e' || string[7] == 'E') &&
|
||||
(string[8] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_meta (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 'm' || string[1] == 'M') &&
|
||||
(string[2] == 'e' || string[2] == 'E') &&
|
||||
(string[3] == 't' || string[3] == 'T') &&
|
||||
(string[4] == 'a' || string[4] == 'A') &&
|
||||
(string[5] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_super (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 's' || string[1] == 'S') &&
|
||||
(string[2] == 'u' || string[2] == 'U') &&
|
||||
(string[3] == 'p' || string[3] == 'P') &&
|
||||
(string[4] == 'e' || string[4] == 'E') &&
|
||||
(string[5] == 'r' || string[5] == 'R') &&
|
||||
(string[6] == '>'));
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_hyper (const gchar *string)
|
||||
{
|
||||
return ((string[0] == '<') &&
|
||||
(string[1] == 'h' || string[1] == 'H') &&
|
||||
(string[2] == 'y' || string[2] == 'Y') &&
|
||||
(string[3] == 'p' || string[3] == 'P') &&
|
||||
(string[4] == 'e' || string[4] == 'E') &&
|
||||
(string[5] == 'r' || string[5] == 'R') &&
|
||||
(string[6] == '>'));
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_accelerator_parse_virtual:
|
||||
* @accelerator: string representing an accelerator
|
||||
* @accelerator_key: return location for accelerator keyval
|
||||
* @accelerator_mods: return location for accelerator modifier mask
|
||||
*
|
||||
* Parses a string representing a virtual accelerator. The format
|
||||
* looks like "<Control>a" or "<Shift><Alt>F1" or
|
||||
* "<Release>z" (the last one is for key release). The parser
|
||||
* is fairly liberal and allows lower or upper case, and also
|
||||
* abbreviations such as "<Ctl>" and "<Ctrl>".
|
||||
*
|
||||
* If the parse fails, @accelerator_key and @accelerator_mods will
|
||||
* be set to 0 (zero) and %FALSE will be returned. If the string contains
|
||||
* only modifiers, @accelerator_key will be set to 0 but %TRUE will be
|
||||
* returned.
|
||||
*
|
||||
* The virtual vs. concrete accelerator distinction is a relic of
|
||||
* how the X Window System works; there are modifiers Mod2-Mod5 that
|
||||
* can represent various keyboard keys (numlock, meta, hyper, etc.),
|
||||
* the virtual modifier represents the keyboard key, the concrete
|
||||
* modifier the actual Mod2-Mod5 bits in the key press event.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
egg_accelerator_parse_virtual (const gchar *accelerator,
|
||||
guint *accelerator_key,
|
||||
EggVirtualModifierType *accelerator_mods)
|
||||
{
|
||||
guint keyval;
|
||||
GdkModifierType mods;
|
||||
gint len;
|
||||
gboolean bad_keyval;
|
||||
|
||||
if (accelerator_key)
|
||||
*accelerator_key = 0;
|
||||
if (accelerator_mods)
|
||||
*accelerator_mods = 0;
|
||||
|
||||
g_return_val_if_fail (accelerator != NULL, FALSE);
|
||||
|
||||
bad_keyval = FALSE;
|
||||
|
||||
keyval = 0;
|
||||
mods = 0;
|
||||
len = strlen (accelerator);
|
||||
while (len)
|
||||
{
|
||||
if (*accelerator == '<')
|
||||
{
|
||||
if (len >= 9 && is_release (accelerator))
|
||||
{
|
||||
accelerator += 9;
|
||||
len -= 9;
|
||||
mods |= EGG_VIRTUAL_RELEASE_MASK;
|
||||
}
|
||||
else if (len >= 9 && is_control (accelerator))
|
||||
{
|
||||
accelerator += 9;
|
||||
len -= 9;
|
||||
mods |= EGG_VIRTUAL_CONTROL_MASK;
|
||||
}
|
||||
else if (len >= 7 && is_shift (accelerator))
|
||||
{
|
||||
accelerator += 7;
|
||||
len -= 7;
|
||||
mods |= EGG_VIRTUAL_SHIFT_MASK;
|
||||
}
|
||||
else if (len >= 6 && is_shft (accelerator))
|
||||
{
|
||||
accelerator += 6;
|
||||
len -= 6;
|
||||
mods |= EGG_VIRTUAL_SHIFT_MASK;
|
||||
}
|
||||
else if (len >= 6 && is_ctrl (accelerator))
|
||||
{
|
||||
accelerator += 6;
|
||||
len -= 6;
|
||||
mods |= EGG_VIRTUAL_CONTROL_MASK;
|
||||
}
|
||||
else if (len >= 6 && is_modx (accelerator))
|
||||
{
|
||||
static const guint mod_vals[] = {
|
||||
EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK,
|
||||
EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK
|
||||
};
|
||||
|
||||
len -= 6;
|
||||
accelerator += 4;
|
||||
mods |= mod_vals[*accelerator - '1'];
|
||||
accelerator += 2;
|
||||
}
|
||||
else if (len >= 5 && is_ctl (accelerator))
|
||||
{
|
||||
accelerator += 5;
|
||||
len -= 5;
|
||||
mods |= EGG_VIRTUAL_CONTROL_MASK;
|
||||
}
|
||||
else if (len >= 5 && is_alt (accelerator))
|
||||
{
|
||||
accelerator += 5;
|
||||
len -= 5;
|
||||
mods |= EGG_VIRTUAL_ALT_MASK;
|
||||
}
|
||||
else if (len >= 6 && is_meta (accelerator))
|
||||
{
|
||||
accelerator += 6;
|
||||
len -= 6;
|
||||
mods |= EGG_VIRTUAL_META_MASK;
|
||||
}
|
||||
else if (len >= 7 && is_hyper (accelerator))
|
||||
{
|
||||
accelerator += 7;
|
||||
len -= 7;
|
||||
mods |= EGG_VIRTUAL_HYPER_MASK;
|
||||
}
|
||||
else if (len >= 7 && is_super (accelerator))
|
||||
{
|
||||
accelerator += 7;
|
||||
len -= 7;
|
||||
mods |= EGG_VIRTUAL_SUPER_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar last_ch;
|
||||
|
||||
last_ch = *accelerator;
|
||||
while (last_ch && last_ch != '>')
|
||||
{
|
||||
last_ch = *accelerator;
|
||||
accelerator += 1;
|
||||
len -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keyval = gdk_keyval_from_name (accelerator);
|
||||
|
||||
if (keyval == 0)
|
||||
bad_keyval = TRUE;
|
||||
|
||||
accelerator += len;
|
||||
len -= len;
|
||||
}
|
||||
}
|
||||
|
||||
if (accelerator_key)
|
||||
*accelerator_key = gdk_keyval_to_lower (keyval);
|
||||
if (accelerator_mods)
|
||||
*accelerator_mods = mods;
|
||||
|
||||
return !bad_keyval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* egg_virtual_accelerator_name:
|
||||
* @accelerator_key: accelerator keyval
|
||||
* @accelerator_mods: accelerator modifier mask
|
||||
* @returns: a newly-allocated accelerator name
|
||||
*
|
||||
* Converts an accelerator keyval and modifier mask
|
||||
* into a string parseable by egg_accelerator_parse_virtual().
|
||||
* For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK,
|
||||
* this function returns "<Control>q".
|
||||
*
|
||||
* The caller of this function must free the returned string.
|
||||
*/
|
||||
gchar*
|
||||
egg_virtual_accelerator_name (guint accelerator_key,
|
||||
EggVirtualModifierType accelerator_mods)
|
||||
{
|
||||
static const gchar text_release[] = "<Release>";
|
||||
static const gchar text_shift[] = "<Shift>";
|
||||
static const gchar text_control[] = "<Control>";
|
||||
static const gchar text_mod1[] = "<Alt>";
|
||||
static const gchar text_mod2[] = "<Mod2>";
|
||||
static const gchar text_mod3[] = "<Mod3>";
|
||||
static const gchar text_mod4[] = "<Mod4>";
|
||||
static const gchar text_mod5[] = "<Mod5>";
|
||||
static const gchar text_meta[] = "<Meta>";
|
||||
static const gchar text_super[] = "<Super>";
|
||||
static const gchar text_hyper[] = "<Hyper>";
|
||||
guint l;
|
||||
gchar *keyval_name;
|
||||
gchar *accelerator;
|
||||
|
||||
accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK;
|
||||
|
||||
keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key));
|
||||
if (!keyval_name)
|
||||
keyval_name = "";
|
||||
|
||||
l = 0;
|
||||
if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
|
||||
l += sizeof (text_release) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
|
||||
l += sizeof (text_shift) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
|
||||
l += sizeof (text_control) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
|
||||
l += sizeof (text_mod1) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
|
||||
l += sizeof (text_mod2) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
|
||||
l += sizeof (text_mod3) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
|
||||
l += sizeof (text_mod4) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
|
||||
l += sizeof (text_mod5) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_META_MASK)
|
||||
l += sizeof (text_meta) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
|
||||
l += sizeof (text_hyper) - 1;
|
||||
if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
|
||||
l += sizeof (text_super) - 1;
|
||||
l += strlen (keyval_name);
|
||||
|
||||
accelerator = g_new (gchar, l + 1);
|
||||
|
||||
l = 0;
|
||||
accelerator[l] = 0;
|
||||
if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_release);
|
||||
l += sizeof (text_release) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_shift);
|
||||
l += sizeof (text_shift) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_control);
|
||||
l += sizeof (text_control) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_ALT_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_mod1);
|
||||
l += sizeof (text_mod1) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_mod2);
|
||||
l += sizeof (text_mod2) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_mod3);
|
||||
l += sizeof (text_mod3) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_mod4);
|
||||
l += sizeof (text_mod4) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_mod5);
|
||||
l += sizeof (text_mod5) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_META_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_meta);
|
||||
l += sizeof (text_meta) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_hyper);
|
||||
l += sizeof (text_hyper) - 1;
|
||||
}
|
||||
if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK)
|
||||
{
|
||||
strcpy (accelerator + l, text_super);
|
||||
l += sizeof (text_super) - 1;
|
||||
}
|
||||
|
||||
strcpy (accelerator + l, keyval_name);
|
||||
|
||||
return accelerator;
|
||||
}
|
||||
|
||||
void
|
||||
egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
|
||||
EggVirtualModifierType virtual_mods,
|
||||
GdkModifierType *concrete_mods)
|
||||
{
|
||||
GdkModifierType concrete;
|
||||
int i;
|
||||
const EggModmap *modmap;
|
||||
|
||||
g_return_if_fail (GDK_IS_KEYMAP (keymap));
|
||||
g_return_if_fail (concrete_mods != NULL);
|
||||
|
||||
modmap = egg_keymap_get_modmap (keymap);
|
||||
|
||||
/* Not so sure about this algorithm. */
|
||||
|
||||
concrete = 0;
|
||||
i = 0;
|
||||
while (i < EGG_MODMAP_ENTRY_LAST)
|
||||
{
|
||||
if (modmap->mapping[i] & virtual_mods)
|
||||
concrete |= (1 << i);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
*concrete_mods = concrete;
|
||||
}
|
||||
|
||||
void
|
||||
egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
|
||||
GdkModifierType concrete_mods,
|
||||
EggVirtualModifierType *virtual_mods)
|
||||
{
|
||||
GdkModifierType virtual;
|
||||
int i;
|
||||
const EggModmap *modmap;
|
||||
|
||||
g_return_if_fail (GDK_IS_KEYMAP (keymap));
|
||||
g_return_if_fail (virtual_mods != NULL);
|
||||
|
||||
modmap = egg_keymap_get_modmap (keymap);
|
||||
|
||||
/* Not so sure about this algorithm. */
|
||||
|
||||
virtual = 0;
|
||||
i = 0;
|
||||
while (i < EGG_MODMAP_ENTRY_LAST)
|
||||
{
|
||||
if ((1 << i) & concrete_mods)
|
||||
{
|
||||
EggVirtualModifierType cleaned;
|
||||
|
||||
cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK |
|
||||
EGG_VIRTUAL_MOD3_MASK |
|
||||
EGG_VIRTUAL_MOD4_MASK |
|
||||
EGG_VIRTUAL_MOD5_MASK);
|
||||
|
||||
if (cleaned != 0)
|
||||
{
|
||||
virtual |= cleaned;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Rather than dropping mod2->mod5 if not bound,
|
||||
* go ahead and use the concrete names
|
||||
*/
|
||||
virtual |= modmap->mapping[i];
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
*virtual_mods = virtual;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_modmap (GdkKeymap *keymap,
|
||||
EggModmap *modmap)
|
||||
{
|
||||
XModifierKeymap *xmodmap;
|
||||
int map_size;
|
||||
int i;
|
||||
|
||||
/* FIXME multihead */
|
||||
xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ());
|
||||
|
||||
memset (modmap->mapping, 0, sizeof (modmap->mapping));
|
||||
|
||||
/* there are 8 modifiers, and the first 3 are shift, shift lock,
|
||||
* and control
|
||||
*/
|
||||
map_size = 8 * xmodmap->max_keypermod;
|
||||
i = 3 * xmodmap->max_keypermod;
|
||||
while (i < map_size)
|
||||
{
|
||||
/* get the key code at this point in the map,
|
||||
* see if its keysym is one we're interested in
|
||||
*/
|
||||
int keycode = xmodmap->modifiermap[i];
|
||||
GdkKeymapKey *keys;
|
||||
guint *keyvals;
|
||||
int n_entries;
|
||||
int j;
|
||||
EggVirtualModifierType mask;
|
||||
|
||||
keys = NULL;
|
||||
keyvals = NULL;
|
||||
n_entries = 0;
|
||||
|
||||
gdk_keymap_get_entries_for_keycode (keymap,
|
||||
keycode,
|
||||
&keys, &keyvals, &n_entries);
|
||||
|
||||
mask = 0;
|
||||
j = 0;
|
||||
while (j < n_entries)
|
||||
{
|
||||
if (keyvals[j] == GDK_Num_Lock)
|
||||
mask |= EGG_VIRTUAL_NUM_LOCK_MASK;
|
||||
else if (keyvals[j] == GDK_Scroll_Lock)
|
||||
mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK;
|
||||
else if (keyvals[j] == GDK_Meta_L ||
|
||||
keyvals[j] == GDK_Meta_R)
|
||||
mask |= EGG_VIRTUAL_META_MASK;
|
||||
else if (keyvals[j] == GDK_Hyper_L ||
|
||||
keyvals[j] == GDK_Hyper_R)
|
||||
mask |= EGG_VIRTUAL_HYPER_MASK;
|
||||
else if (keyvals[j] == GDK_Super_L ||
|
||||
keyvals[j] == GDK_Super_R)
|
||||
mask |= EGG_VIRTUAL_SUPER_MASK;
|
||||
else if (keyvals[j] == GDK_Mode_switch)
|
||||
mask |= EGG_VIRTUAL_MODE_SWITCH_MASK;
|
||||
|
||||
++j;
|
||||
}
|
||||
|
||||
/* Mod1Mask is 1 << 3 for example, i.e. the
|
||||
* fourth modifier, i / keyspermod is the modifier
|
||||
* index
|
||||
*/
|
||||
modmap->mapping[i/xmodmap->max_keypermod] |= mask;
|
||||
|
||||
g_free (keyvals);
|
||||
g_free (keys);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
/* Add in the not-really-virtual fixed entries */
|
||||
modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK;
|
||||
modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK;
|
||||
modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK;
|
||||
modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK;
|
||||
modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK;
|
||||
modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK;
|
||||
modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK;
|
||||
modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK;
|
||||
|
||||
XFreeModifiermap (xmodmap);
|
||||
}
|
||||
|
||||
const EggModmap*
|
||||
egg_keymap_get_modmap (GdkKeymap *keymap)
|
||||
{
|
||||
EggModmap *modmap;
|
||||
|
||||
/* This is all a hack, much simpler when we can just
|
||||
* modify GDK directly.
|
||||
*/
|
||||
|
||||
modmap = g_object_get_data (G_OBJECT (keymap),
|
||||
"egg-modmap");
|
||||
|
||||
if (modmap == NULL)
|
||||
{
|
||||
modmap = g_new0 (EggModmap, 1);
|
||||
|
||||
/* FIXME modify keymap change events with an event filter
|
||||
* and force a reload if we get one
|
||||
*/
|
||||
|
||||
reload_modmap (keymap, modmap);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (keymap),
|
||||
"egg-modmap",
|
||||
modmap,
|
||||
g_free);
|
||||
}
|
||||
|
||||
g_assert (modmap != NULL);
|
||||
|
||||
return modmap;
|
||||
}
|
87
src/eggaccelerators.h
Normal file
87
src/eggaccelerators.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* eggaccelerators.h
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
* Developed by Havoc Pennington
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __EGG_ACCELERATORS_H__
|
||||
#define __EGG_ACCELERATORS_H__
|
||||
|
||||
#include <gtk/gtkaccelgroup.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Where a value is also in GdkModifierType we coincide,
|
||||
* otherwise we don't overlap.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
EGG_VIRTUAL_SHIFT_MASK = 1 << 0,
|
||||
EGG_VIRTUAL_LOCK_MASK = 1 << 1,
|
||||
EGG_VIRTUAL_CONTROL_MASK = 1 << 2,
|
||||
|
||||
EGG_VIRTUAL_ALT_MASK = 1 << 3, /* fixed as Mod1 */
|
||||
|
||||
EGG_VIRTUAL_MOD2_MASK = 1 << 4,
|
||||
EGG_VIRTUAL_MOD3_MASK = 1 << 5,
|
||||
EGG_VIRTUAL_MOD4_MASK = 1 << 6,
|
||||
EGG_VIRTUAL_MOD5_MASK = 1 << 7,
|
||||
|
||||
#if 0
|
||||
GDK_BUTTON1_MASK = 1 << 8,
|
||||
GDK_BUTTON2_MASK = 1 << 9,
|
||||
GDK_BUTTON3_MASK = 1 << 10,
|
||||
GDK_BUTTON4_MASK = 1 << 11,
|
||||
GDK_BUTTON5_MASK = 1 << 12,
|
||||
/* 13, 14 are used by Xkb for the keyboard group */
|
||||
#endif
|
||||
|
||||
EGG_VIRTUAL_META_MASK = 1 << 24,
|
||||
EGG_VIRTUAL_SUPER_MASK = 1 << 25,
|
||||
EGG_VIRTUAL_HYPER_MASK = 1 << 26,
|
||||
EGG_VIRTUAL_MODE_SWITCH_MASK = 1 << 27,
|
||||
EGG_VIRTUAL_NUM_LOCK_MASK = 1 << 28,
|
||||
EGG_VIRTUAL_SCROLL_LOCK_MASK = 1 << 29,
|
||||
|
||||
/* Also in GdkModifierType */
|
||||
EGG_VIRTUAL_RELEASE_MASK = 1 << 30,
|
||||
|
||||
/* 28-31 24-27 20-23 16-19 12-15 8-11 4-7 0-3
|
||||
* 7 f 0 0 0 0 f f
|
||||
*/
|
||||
EGG_VIRTUAL_MODIFIER_MASK = 0x7f0000ff
|
||||
|
||||
} EggVirtualModifierType;
|
||||
|
||||
gboolean egg_accelerator_parse_virtual (const gchar *accelerator,
|
||||
guint *accelerator_key,
|
||||
EggVirtualModifierType *accelerator_mods);
|
||||
void egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap,
|
||||
EggVirtualModifierType virtual_mods,
|
||||
GdkModifierType *concrete_mods);
|
||||
void egg_keymap_virtualize_modifiers (GdkKeymap *keymap,
|
||||
GdkModifierType concrete_mods,
|
||||
EggVirtualModifierType *virtual_mods);
|
||||
|
||||
gchar* egg_virtual_accelerator_name (guint accelerator_key,
|
||||
EggVirtualModifierType accelerator_mods);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* __EGG_ACCELERATORS_H__ */
|
91
src/errors.c
91
src/errors.c
@@ -37,13 +37,19 @@ meta_errors_init (void)
|
||||
XSetIOErrorHandler (x_io_error_handler);
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_push (MetaDisplay *display)
|
||||
static void
|
||||
meta_error_trap_push_internal (MetaDisplay *display,
|
||||
gboolean need_sync)
|
||||
{
|
||||
/* GDK resets the error handler on each push */
|
||||
int (* old_error_handler) (Display *,
|
||||
XErrorEvent *);
|
||||
|
||||
if (need_sync)
|
||||
{
|
||||
XSync (display->xdisplay, False);
|
||||
}
|
||||
|
||||
gdk_error_trap_push ();
|
||||
|
||||
/* old_error_handler will just be equal to x_error_handler
|
||||
@@ -60,17 +66,22 @@ meta_error_trap_push (MetaDisplay *display)
|
||||
}
|
||||
|
||||
display->error_traps += 1;
|
||||
|
||||
meta_topic (META_DEBUG_ERRORS, "%d traps remain\n", display->error_traps);
|
||||
}
|
||||
|
||||
int
|
||||
meta_error_trap_pop (MetaDisplay *display)
|
||||
static int
|
||||
meta_error_trap_pop_internal (MetaDisplay *display,
|
||||
gboolean need_sync)
|
||||
{
|
||||
int result;
|
||||
|
||||
g_assert (display->error_traps > 0);
|
||||
|
||||
/* just use GDK trap, but we do the sync since GDK doesn't */
|
||||
XSync (display->xdisplay, False);
|
||||
|
||||
if (need_sync)
|
||||
{
|
||||
XSync (display->xdisplay, False);
|
||||
}
|
||||
|
||||
result = gdk_error_trap_pop ();
|
||||
|
||||
@@ -92,9 +103,75 @@ meta_error_trap_pop (MetaDisplay *display)
|
||||
display->error_trap_handler = NULL;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_ERRORS, "%d traps\n", display->error_traps);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_push (MetaDisplay *display)
|
||||
{
|
||||
meta_error_trap_push_internal (display, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_pop (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip)
|
||||
{
|
||||
gboolean need_sync;
|
||||
|
||||
/* we only have to sync when popping the outermost trap */
|
||||
need_sync = (display->error_traps == 1 && !last_request_was_roundtrip);
|
||||
|
||||
if (need_sync)
|
||||
meta_topic (META_DEBUG_SYNC, "Syncing on error_trap_pop, traps = %d, roundtrip = %d\n",
|
||||
display->error_traps, last_request_was_roundtrip);
|
||||
|
||||
display->error_trap_synced_at_last_pop = need_sync || last_request_was_roundtrip;
|
||||
|
||||
meta_error_trap_pop_internal (display, need_sync);
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_push_with_return (MetaDisplay *display)
|
||||
{
|
||||
gboolean need_sync;
|
||||
|
||||
/* We don't sync on push_with_return if there are no traps
|
||||
* currently, because we assume that any errors were either covered
|
||||
* by a previous pop, or were fatal.
|
||||
*
|
||||
* More generally, we don't sync if we were synchronized last time
|
||||
* we popped. This is known to be the case if there are no traps,
|
||||
* but we also keep a flag so we know whether it's the case otherwise.
|
||||
*/
|
||||
|
||||
if (!display->error_trap_synced_at_last_pop)
|
||||
need_sync = TRUE;
|
||||
else
|
||||
need_sync = FALSE;
|
||||
|
||||
if (need_sync)
|
||||
meta_topic (META_DEBUG_SYNC, "Syncing on error_trap_push_with_return, traps = %d\n",
|
||||
display->error_traps);
|
||||
|
||||
meta_error_trap_push_internal (display, FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
meta_error_trap_pop_with_return (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip)
|
||||
{
|
||||
if (!last_request_was_roundtrip)
|
||||
meta_topic (META_DEBUG_SYNC, "Syncing on error_trap_pop_with_return, traps = %d, roundtrip = %d\n",
|
||||
display->error_traps, last_request_was_roundtrip);
|
||||
|
||||
display->error_trap_synced_at_last_pop = TRUE;
|
||||
|
||||
return meta_error_trap_pop_internal (display,
|
||||
!last_request_was_roundtrip);
|
||||
}
|
||||
|
||||
static int
|
||||
x_error_handler (Display *xdisplay,
|
||||
XErrorEvent *error)
|
||||
|
12
src/errors.h
12
src/errors.h
@@ -25,9 +25,15 @@
|
||||
#include "util.h"
|
||||
#include "display.h"
|
||||
|
||||
void meta_errors_init (void);
|
||||
void meta_error_trap_push (MetaDisplay *display);
|
||||
void meta_errors_init (void);
|
||||
void meta_error_trap_push (MetaDisplay *display);
|
||||
void meta_error_trap_pop (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip);
|
||||
|
||||
void meta_error_trap_push_with_return (MetaDisplay *display);
|
||||
/* returns X error code, or 0 for no error */
|
||||
int meta_error_trap_pop (MetaDisplay *display);
|
||||
int meta_error_trap_pop_with_return (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip);
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -19,10 +19,13 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "fixedtip.h"
|
||||
|
||||
static GtkWidget *tip = NULL;
|
||||
static GtkWidget *label = NULL;
|
||||
static int screen_width = 0;
|
||||
static int screen_height = 0;
|
||||
|
||||
static gint
|
||||
expose_handler (GtkTooltips *tooltips)
|
||||
@@ -36,13 +39,31 @@ expose_handler (GtkTooltips *tooltips)
|
||||
}
|
||||
|
||||
void
|
||||
meta_fixed_tip_show (Display *xdisplay,
|
||||
meta_fixed_tip_show (Display *xdisplay, int screen_number,
|
||||
int root_x, int root_y,
|
||||
const char *markup_text)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
if (tip == NULL)
|
||||
{
|
||||
{
|
||||
tip = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
#ifdef HAVE_GTK_MULTIHEAD
|
||||
{
|
||||
GdkScreen *gdk_screen;
|
||||
|
||||
gdk_screen = gdk_display_get_screen (gdk_display_get_default (),
|
||||
screen_number);
|
||||
gtk_window_set_screen (GTK_WINDOW (tip),
|
||||
gdk_screen);
|
||||
screen_width = gdk_screen_get_width (gdk_screen);
|
||||
screen_height = gdk_screen_get_height (gdk_screen);
|
||||
}
|
||||
#else
|
||||
screen_width = gdk_screen_width ();
|
||||
screen_height = gdk_screen_height ();
|
||||
#endif
|
||||
|
||||
gtk_widget_set_app_paintable (tip, TRUE);
|
||||
gtk_window_set_policy (GTK_WINDOW (tip), FALSE, FALSE, TRUE);
|
||||
gtk_widget_set_name (tip, "gtk-tooltips");
|
||||
@@ -65,9 +86,17 @@ meta_fixed_tip_show (Display *xdisplay,
|
||||
GTK_SIGNAL_FUNC (gtk_widget_destroyed),
|
||||
&tip);
|
||||
}
|
||||
|
||||
gtk_widget_set_uposition (tip, root_x, root_y);
|
||||
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup_text);
|
||||
|
||||
/* FIXME should also handle Xinerama here, just to be
|
||||
* really cool
|
||||
*/
|
||||
gtk_window_get_size (GTK_WINDOW (tip), &w, &h);
|
||||
if ((root_x + w) > screen_width)
|
||||
root_x -= (root_x + w) - screen_width;
|
||||
|
||||
gtk_window_move (GTK_WINDOW (tip), root_x, root_y);
|
||||
|
||||
gtk_widget_show (tip);
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
void meta_fixed_tip_show (Display *xdisplay,
|
||||
void meta_fixed_tip_show (Display *xdisplay, int screen_number,
|
||||
int root_x, int root_y,
|
||||
const char *markup_text);
|
||||
void meta_fixed_tip_hide (void);
|
||||
|
133
src/frame.c
133
src/frame.c
@@ -19,6 +19,7 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "frame.h"
|
||||
#include "errors.h"
|
||||
#include "keybindings.h"
|
||||
@@ -29,7 +30,8 @@
|
||||
ButtonPressMask | ButtonReleaseMask | \
|
||||
PointerMotionMask | PointerMotionHintMask | \
|
||||
EnterWindowMask | LeaveWindowMask | \
|
||||
FocusChangeMask)
|
||||
FocusChangeMask | \
|
||||
ColormapChangeMask)
|
||||
|
||||
void
|
||||
meta_window_ensure_frame (MetaWindow *window)
|
||||
@@ -53,6 +55,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
frame->child_y = 0;
|
||||
frame->bottom_height = 0;
|
||||
frame->right_width = 0;
|
||||
frame->current_cursor = 0;
|
||||
|
||||
frame->mapped = FALSE;
|
||||
|
||||
@@ -64,7 +67,10 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
XVisualIDFromVisual (window->screen->default_xvisual) ?
|
||||
"is" : "is not",
|
||||
window->depth, window->screen->default_depth);
|
||||
|
||||
meta_verbose ("Frame geometry %d,%d %dx%d\n",
|
||||
frame->rect.x, frame->rect.y,
|
||||
frame->rect.width, frame->rect.height);
|
||||
|
||||
/* Default depth/visual handles clients with weird visuals; they can
|
||||
* always be children of the root depth/visual obviously, but
|
||||
* e.g. DRI games can't be children of a parent that has the same
|
||||
@@ -119,7 +125,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
window->rect.x,
|
||||
window->rect.y);
|
||||
/* FIXME handle this error */
|
||||
meta_error_trap_pop (window->display);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
|
||||
/* stick frame to the window */
|
||||
window->frame = frame;
|
||||
@@ -134,6 +140,12 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
/* Move keybindings to frame instead of window */
|
||||
meta_window_grab_keys (window);
|
||||
|
||||
/* Shape mask */
|
||||
meta_ui_apply_frame_shape (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
|
||||
meta_display_ungrab (window->display);
|
||||
}
|
||||
|
||||
@@ -169,7 +181,7 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
/* FIXME where to put it back depends on the gravity */
|
||||
window->frame->rect.x,
|
||||
window->frame->rect.y);
|
||||
meta_error_trap_pop (window->display);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
|
||||
meta_display_unregister_x_window (window->display,
|
||||
frame->xwindow);
|
||||
@@ -193,36 +205,40 @@ MetaFrameFlags
|
||||
meta_frame_get_flags (MetaFrame *frame)
|
||||
{
|
||||
MetaFrameFlags flags;
|
||||
|
||||
flags = META_FRAME_ALLOWS_MENU;
|
||||
|
||||
if (frame->window->has_close_func)
|
||||
flags |= META_FRAME_ALLOWS_DELETE;
|
||||
|
||||
if (frame->window->has_maximize_func)
|
||||
flags |= META_FRAME_ALLOWS_MAXIMIZE;
|
||||
|
||||
if (frame->window->has_minimize_func)
|
||||
flags |= META_FRAME_ALLOWS_MINIMIZE;
|
||||
flags = 0;
|
||||
|
||||
if (frame->window->has_shade_func)
|
||||
flags |= META_FRAME_ALLOWS_SHADE;
|
||||
|
||||
if (frame->window->has_move_func)
|
||||
if (frame->window->border_only)
|
||||
{
|
||||
; /* FIXME this may disable the _function_ as well as decor
|
||||
* in some cases, which is sort of wrong.
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= META_FRAME_ALLOWS_MENU;
|
||||
|
||||
if (frame->window->has_close_func)
|
||||
flags |= META_FRAME_ALLOWS_DELETE;
|
||||
|
||||
if (frame->window->has_maximize_func)
|
||||
flags |= META_FRAME_ALLOWS_MAXIMIZE;
|
||||
|
||||
if (frame->window->has_minimize_func)
|
||||
flags |= META_FRAME_ALLOWS_MINIMIZE;
|
||||
|
||||
if (frame->window->has_shade_func)
|
||||
flags |= META_FRAME_ALLOWS_SHADE;
|
||||
}
|
||||
|
||||
if (META_WINDOW_ALLOWS_MOVE (frame->window))
|
||||
flags |= META_FRAME_ALLOWS_MOVE;
|
||||
|
||||
if (frame->window->has_resize_func &&
|
||||
!frame->window->maximized &&
|
||||
!frame->window->shaded)
|
||||
{
|
||||
if (frame->window->size_hints.min_width <
|
||||
frame->window->size_hints.max_width)
|
||||
flags |= META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
|
||||
if (META_WINDOW_ALLOWS_HORIZONTAL_RESIZE (frame->window))
|
||||
flags |= META_FRAME_ALLOWS_HORIZONTAL_RESIZE;
|
||||
|
||||
if (frame->window->size_hints.min_height <
|
||||
frame->window->size_hints.max_height)
|
||||
flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
|
||||
}
|
||||
if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
|
||||
flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
|
||||
|
||||
if (frame->window->has_focus)
|
||||
flags |= META_FRAME_HAS_FOCUS;
|
||||
@@ -234,7 +250,10 @@ meta_frame_get_flags (MetaFrame *frame)
|
||||
flags |= META_FRAME_STUCK;
|
||||
|
||||
if (frame->window->maximized)
|
||||
flags |= META_FRAME_MAXIMIZED;
|
||||
flags |= META_FRAME_MAXIMIZED;
|
||||
|
||||
if (frame->window->fullscreen)
|
||||
flags |= META_FRAME_FULLSCREEN;
|
||||
|
||||
return flags;
|
||||
}
|
||||
@@ -276,11 +295,25 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
|
||||
/* set bg to none to avoid flicker */
|
||||
if (need_resize)
|
||||
meta_ui_unflicker_frame_bg (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
{
|
||||
meta_ui_unflicker_frame_bg (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
|
||||
/* Done before the window resize, because doing it before means
|
||||
* part of the window being resized becomes unshaped, which may
|
||||
* be sort of hard to see with bg = None. If we did it after
|
||||
* window resize, part of the window being resized would become
|
||||
* shaped, which might be more visible.
|
||||
*/
|
||||
|
||||
meta_ui_apply_frame_shape (frame->window->screen->ui,
|
||||
frame->xwindow,
|
||||
frame->rect.width,
|
||||
frame->rect.height);
|
||||
}
|
||||
|
||||
if (need_move && need_resize)
|
||||
XMoveResizeWindow (frame->window->display->xdisplay,
|
||||
frame->xwindow,
|
||||
@@ -300,8 +333,18 @@ meta_frame_sync_to_window (MetaFrame *frame,
|
||||
frame->rect.height);
|
||||
|
||||
if (need_resize)
|
||||
meta_ui_reset_frame_bg (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
{
|
||||
meta_ui_reset_frame_bg (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
|
||||
/* If we're interactively resizing the frame, repaint
|
||||
* it immediately so we don't start to lag.
|
||||
*/
|
||||
if (frame->window->display->grab_window ==
|
||||
frame->window)
|
||||
meta_ui_repaint_frame (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -310,3 +353,21 @@ meta_frame_queue_draw (MetaFrame *frame)
|
||||
meta_ui_queue_frame_draw (frame->window->screen->ui,
|
||||
frame->xwindow);
|
||||
}
|
||||
|
||||
void meta_frame_set_screen_cursor (MetaFrame *frame,
|
||||
MetaCursor cursor)
|
||||
{
|
||||
Cursor xcursor;
|
||||
if (cursor == frame->current_cursor)
|
||||
return;
|
||||
frame->current_cursor = cursor;
|
||||
if (cursor == META_CURSOR_DEFAULT)
|
||||
XUndefineCursor (frame->window->display->xdisplay, frame->xwindow);
|
||||
else
|
||||
{
|
||||
xcursor = meta_display_create_x_cursor (frame->window->display, cursor);
|
||||
XDefineCursor (frame->window->display->xdisplay, frame->xwindow, xcursor);
|
||||
XFreeCursor (frame->window->display->xdisplay, xcursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -43,6 +43,8 @@ struct _MetaFrame
|
||||
/* reparent window */
|
||||
Window xwindow;
|
||||
|
||||
MetaCursor current_cursor;
|
||||
|
||||
/* This rect is trusted info from where we put the
|
||||
* frame, not the result of ConfigureNotify
|
||||
*/
|
||||
@@ -71,6 +73,8 @@ void meta_frame_sync_to_window (MetaFrame *frame,
|
||||
gboolean need_move,
|
||||
gboolean need_resize);
|
||||
|
||||
void meta_frame_set_screen_cursor (MetaFrame *frame,
|
||||
MetaCursor cursor);
|
||||
|
||||
#endif
|
||||
|
||||
|
797
src/frames.c
797
src/frames.c
File diff suppressed because it is too large
Load Diff
10
src/frames.h
10
src/frames.h
@@ -99,7 +99,7 @@ struct _MetaFramesClass
|
||||
|
||||
GType meta_frames_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaFrames *meta_frames_new (void);
|
||||
MetaFrames *meta_frames_new (int screen_number);
|
||||
|
||||
void meta_frames_manage_window (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
@@ -109,6 +109,9 @@ void meta_frames_set_title (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
const char *title);
|
||||
|
||||
void meta_frames_repaint_frame (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
|
||||
void meta_frames_get_geometry (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int *top_height, int *bottom_height,
|
||||
@@ -121,6 +124,11 @@ void meta_frames_unflicker_bg (MetaFrames *frames,
|
||||
int target_width,
|
||||
int target_height);
|
||||
|
||||
void meta_frames_apply_shapes (MetaFrames *frames,
|
||||
Window xwindow,
|
||||
int new_window_width,
|
||||
int new_window_height);
|
||||
|
||||
void meta_frames_queue_draw (MetaFrames *frames,
|
||||
Window xwindow);
|
||||
|
||||
|
173
src/gradient.c
173
src/gradient.c
@@ -730,3 +730,176 @@ meta_gradient_create_multi_diagonal (int width, int height,
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
simple_multiply_alpha (GdkPixbuf *pixbuf,
|
||||
guchar alpha)
|
||||
{
|
||||
guchar *pixels;
|
||||
int rowstride;
|
||||
int height;
|
||||
int row;
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
|
||||
if (alpha == 255)
|
||||
return;
|
||||
|
||||
g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
row = 0;
|
||||
while (row < height)
|
||||
{
|
||||
guchar *p;
|
||||
guchar *end;
|
||||
|
||||
p = pixels + row * rowstride;
|
||||
end = p + rowstride;
|
||||
|
||||
while (p != end)
|
||||
{
|
||||
p += 3; /* skip RGB */
|
||||
|
||||
/* multiply the two alpha channels. not sure this is right.
|
||||
* but some end cases are that if the pixbuf contains 255,
|
||||
* then it should be modified to contain "alpha"; if the
|
||||
* pixbuf contains 0, it should remain 0.
|
||||
*/
|
||||
/* ((*p / 255.0) * (alpha / 255.0)) * 255; */
|
||||
*p = (guchar) (((int) *p * (int) alpha) / (int) 255);
|
||||
|
||||
++p; /* skip A */
|
||||
}
|
||||
|
||||
++row;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
|
||||
const unsigned char *alphas,
|
||||
int n_alphas)
|
||||
{
|
||||
int i, j;
|
||||
long a, da;
|
||||
unsigned char *p;
|
||||
unsigned char *pixels;
|
||||
int width2;
|
||||
int rowstride;
|
||||
int width, height;
|
||||
unsigned char *gradient;
|
||||
unsigned char *gradient_p;
|
||||
unsigned char *gradient_end;
|
||||
|
||||
g_return_if_fail (n_alphas > 0);
|
||||
|
||||
if (n_alphas == 1)
|
||||
{
|
||||
/* Optimize this */
|
||||
simple_multiply_alpha (pixbuf, alphas[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
width = gdk_pixbuf_get_width (pixbuf);
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
gradient = g_new (unsigned char, width);
|
||||
gradient_end = gradient + width;
|
||||
|
||||
if (n_alphas > width)
|
||||
n_alphas = width;
|
||||
|
||||
if (n_alphas > 1)
|
||||
width2 = width / (n_alphas - 1);
|
||||
else
|
||||
width2 = width;
|
||||
|
||||
a = alphas[0] << 8;
|
||||
gradient_p = gradient;
|
||||
|
||||
/* render the gradient into an array */
|
||||
for (i = 1; i < n_alphas; i++)
|
||||
{
|
||||
da = (((int)(alphas[i] - (int) alphas[i-1])) << 8) / (int) width2;
|
||||
|
||||
for (j = 0; j < width2; j++)
|
||||
{
|
||||
*gradient_p++ = (a >> 8);
|
||||
|
||||
a += da;
|
||||
}
|
||||
|
||||
a = alphas[i] << 8;
|
||||
}
|
||||
|
||||
/* get leftover pixels */
|
||||
while (gradient_p != gradient_end)
|
||||
{
|
||||
*gradient_p++ = a >> 8;
|
||||
}
|
||||
|
||||
/* Now for each line of the pixbuf, fill in with the gradient */
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
p = pixels;
|
||||
i = 0;
|
||||
while (i < height)
|
||||
{
|
||||
unsigned char *row_end = p + rowstride;
|
||||
gradient_p = gradient;
|
||||
|
||||
p += 3;
|
||||
while (gradient_p != gradient_end)
|
||||
{
|
||||
/* multiply the two alpha channels. not sure this is right.
|
||||
* but some end cases are that if the pixbuf contains 255,
|
||||
* then it should be modified to contain "alpha"; if the
|
||||
* pixbuf contains 0, it should remain 0.
|
||||
*/
|
||||
/* ((*p / 255.0) * (alpha / 255.0)) * 255; */
|
||||
*p = (guchar) (((int) *p * (int) *gradient_p) / (int) 255);
|
||||
|
||||
p += 4;
|
||||
++gradient_p;
|
||||
}
|
||||
|
||||
p = row_end;
|
||||
++i;
|
||||
}
|
||||
|
||||
g_free (gradient);
|
||||
}
|
||||
|
||||
void
|
||||
meta_gradient_add_alpha (GdkPixbuf *pixbuf,
|
||||
const guchar *alphas,
|
||||
int n_alphas,
|
||||
MetaGradientType type)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
g_return_if_fail (gdk_pixbuf_get_has_alpha (pixbuf));
|
||||
g_return_if_fail (n_alphas > 0);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case META_GRADIENT_HORIZONTAL:
|
||||
meta_gradient_add_alpha_horizontal (pixbuf, alphas, n_alphas);
|
||||
break;
|
||||
|
||||
case META_GRADIENT_VERTICAL:
|
||||
g_printerr ("metacity: vertical alpha channel gradient not implemented yet\n");
|
||||
break;
|
||||
|
||||
case META_GRADIENT_DIAGONAL:
|
||||
g_printerr ("metacity: diagonal alpha channel gradient not implemented yet\n");
|
||||
break;
|
||||
|
||||
case META_GRADIENT_LAST:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -51,4 +51,13 @@ GdkPixbuf* meta_gradient_create_interwoven (int width,
|
||||
int thickness2);
|
||||
|
||||
|
||||
/* Generate an alpha gradient and multiply it with the existing alpha
|
||||
* channel of the given pixbuf
|
||||
*/
|
||||
void meta_gradient_add_alpha (GdkPixbuf *pixbuf,
|
||||
const guchar *alphas,
|
||||
int n_alphas,
|
||||
MetaGradientType type);
|
||||
|
||||
|
||||
#endif
|
||||
|
41
src/group-private.h
Normal file
41
src/group-private.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* Metacity window group private header */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_GROUP_PRIVATE_H
|
||||
#define META_GROUP_PRIVATE_H
|
||||
|
||||
#include "group.h"
|
||||
|
||||
struct _MetaGroup
|
||||
{
|
||||
int refcount;
|
||||
MetaDisplay *display;
|
||||
GSList *windows;
|
||||
Window group_leader;
|
||||
char *startup_id;
|
||||
char *wm_client_machine;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
230
src/group-props.c
Normal file
230
src/group-props.c
Normal file
@@ -0,0 +1,230 @@
|
||||
/* MetaGroup property handling */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "group-props.h"
|
||||
#include "group-private.h"
|
||||
#include "xprops.h"
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
typedef void (* InitValueFunc) (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value);
|
||||
typedef void (* ReloadValueFunc) (MetaGroup *group,
|
||||
MetaPropValue *value);
|
||||
|
||||
struct _MetaGroupPropHooks
|
||||
{
|
||||
Atom property;
|
||||
InitValueFunc init_func;
|
||||
ReloadValueFunc reload_func;
|
||||
};
|
||||
|
||||
static void init_prop_value (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value);
|
||||
static void reload_prop_value (MetaGroup *group,
|
||||
MetaPropValue *value);
|
||||
static MetaGroupPropHooks* find_hooks (MetaDisplay *display,
|
||||
Atom property);
|
||||
|
||||
|
||||
|
||||
void
|
||||
meta_group_reload_property (MetaGroup *group,
|
||||
Atom property)
|
||||
{
|
||||
meta_group_reload_properties (group, &property, 1);
|
||||
}
|
||||
|
||||
void
|
||||
meta_group_reload_properties (MetaGroup *group,
|
||||
const Atom *properties,
|
||||
int n_properties)
|
||||
{
|
||||
int i;
|
||||
MetaPropValue *values;
|
||||
|
||||
g_return_if_fail (properties != NULL);
|
||||
g_return_if_fail (n_properties > 0);
|
||||
|
||||
values = g_new0 (MetaPropValue, n_properties);
|
||||
|
||||
i = 0;
|
||||
while (i < n_properties)
|
||||
{
|
||||
init_prop_value (group->display, properties[i], &values[i]);
|
||||
++i;
|
||||
}
|
||||
|
||||
meta_prop_get_values (group->display, group->group_leader,
|
||||
values, n_properties);
|
||||
|
||||
i = 0;
|
||||
while (i < n_properties)
|
||||
{
|
||||
reload_prop_value (group, &values[i]);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
meta_prop_free_values (values, n_properties);
|
||||
|
||||
g_free (values);
|
||||
}
|
||||
|
||||
/* Fill in the MetaPropValue used to get the value of "property" */
|
||||
static void
|
||||
init_prop_value (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
MetaGroupPropHooks *hooks;
|
||||
|
||||
value->type = META_PROP_VALUE_INVALID;
|
||||
value->atom = None;
|
||||
|
||||
hooks = find_hooks (display, property);
|
||||
if (hooks && hooks->init_func != NULL)
|
||||
(* hooks->init_func) (display, property, value);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_prop_value (MetaGroup *group,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
MetaGroupPropHooks *hooks;
|
||||
|
||||
hooks = find_hooks (group->display, value->atom);
|
||||
if (hooks && hooks->reload_func != NULL)
|
||||
(* hooks->reload_func) (group, value);
|
||||
}
|
||||
|
||||
static void
|
||||
init_wm_client_machine (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_STRING;
|
||||
value->atom = display->atom_wm_client_machine;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_wm_client_machine (MetaGroup *group,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
g_free (group->wm_client_machine);
|
||||
group->wm_client_machine = NULL;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
group->wm_client_machine = g_strdup (value->v.str);
|
||||
|
||||
meta_verbose ("Group has client machine \"%s\"\n",
|
||||
group->wm_client_machine ? group->wm_client_machine : "unset");
|
||||
}
|
||||
|
||||
static void
|
||||
init_net_startup_id (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_UTF8;
|
||||
value->atom = display->atom_net_startup_id;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_startup_id (MetaGroup *group,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
g_free (group->startup_id);
|
||||
group->startup_id = NULL;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
group->startup_id = g_strdup (value->v.str);
|
||||
|
||||
meta_verbose ("Group has startup id \"%s\"\n",
|
||||
group->startup_id ? group->startup_id : "unset");
|
||||
}
|
||||
|
||||
#define N_HOOKS 3
|
||||
|
||||
void
|
||||
meta_display_init_group_prop_hooks (MetaDisplay *display)
|
||||
{
|
||||
int i;
|
||||
MetaGroupPropHooks *hooks;
|
||||
|
||||
g_assert (display->group_prop_hooks == NULL);
|
||||
|
||||
display->group_prop_hooks = g_new0 (MetaGroupPropHooks, N_HOOKS);
|
||||
hooks = display->group_prop_hooks;
|
||||
|
||||
i = 0;
|
||||
|
||||
hooks[i].property = display->atom_wm_client_machine;
|
||||
hooks[i].init_func = init_wm_client_machine;
|
||||
hooks[i].reload_func = reload_wm_client_machine;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom_net_wm_pid;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom_net_startup_id;
|
||||
hooks[i].init_func = init_net_startup_id;
|
||||
hooks[i].reload_func = reload_net_startup_id;
|
||||
++i;
|
||||
|
||||
if (i != N_HOOKS)
|
||||
g_error ("Initialized %d group hooks should have been %d\n", i, N_HOOKS);
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_free_group_prop_hooks (MetaDisplay *display)
|
||||
{
|
||||
g_assert (display->group_prop_hooks != NULL);
|
||||
|
||||
g_free (display->group_prop_hooks);
|
||||
display->group_prop_hooks = NULL;
|
||||
}
|
||||
|
||||
static MetaGroupPropHooks*
|
||||
find_hooks (MetaDisplay *display,
|
||||
Atom property)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* FIXME we could sort the array and do binary search or
|
||||
* something
|
||||
*/
|
||||
|
||||
i = 0;
|
||||
while (i < N_HOOKS)
|
||||
{
|
||||
if (display->group_prop_hooks[i].property == property)
|
||||
return &display->group_prop_hooks[i];
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
35
src/group-props.h
Normal file
35
src/group-props.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* MetaGroup property handling */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_GROUP_PROPS_H
|
||||
#define META_GROUP_PROPS_H
|
||||
|
||||
#include "group.h"
|
||||
|
||||
void meta_group_reload_property (MetaGroup *group,
|
||||
Atom property);
|
||||
void meta_group_reload_properties (MetaGroup *group,
|
||||
const Atom *properties,
|
||||
int n_properties);
|
||||
void meta_display_init_group_prop_hooks (MetaDisplay *display);
|
||||
void meta_display_free_group_prop_hooks (MetaDisplay *display);
|
||||
|
||||
#endif /* META_GROUP_PROPS_H */
|
258
src/group.c
Normal file
258
src/group.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/* Metacity window groups */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "util.h"
|
||||
#include "group-private.h"
|
||||
#include "group-props.h"
|
||||
#include "window.h"
|
||||
|
||||
static MetaGroup*
|
||||
meta_group_new (MetaDisplay *display,
|
||||
Window group_leader)
|
||||
{
|
||||
MetaGroup *group;
|
||||
#define N_INITIAL_PROPS 3
|
||||
Atom initial_props[N_INITIAL_PROPS];
|
||||
int i;
|
||||
|
||||
g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
|
||||
|
||||
group = g_new0 (MetaGroup, 1);
|
||||
|
||||
group->display = display;
|
||||
group->windows = NULL;
|
||||
group->group_leader = group_leader;
|
||||
group->refcount = 1; /* owned by caller, hash table has only weak ref */
|
||||
|
||||
if (display->groups_by_leader == NULL)
|
||||
display->groups_by_leader = g_hash_table_new (meta_unsigned_long_hash,
|
||||
meta_unsigned_long_equal);
|
||||
|
||||
g_assert (g_hash_table_lookup (display->groups_by_leader, &group_leader) == NULL);
|
||||
|
||||
g_hash_table_insert (display->groups_by_leader,
|
||||
&group->group_leader,
|
||||
group);
|
||||
|
||||
/* Fill these in the order we want them to be gotten */
|
||||
i = 0;
|
||||
initial_props[i++] = display->atom_wm_client_machine;
|
||||
initial_props[i++] = display->atom_net_wm_pid;
|
||||
initial_props[i++] = display->atom_net_startup_id;
|
||||
g_assert (N_INITIAL_PROPS == i);
|
||||
|
||||
meta_group_reload_properties (group, initial_props, N_INITIAL_PROPS);
|
||||
|
||||
meta_topic (META_DEBUG_GROUPS,
|
||||
"Created new group with leader 0x%lx\n",
|
||||
group->group_leader);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_group_unref (MetaGroup *group)
|
||||
{
|
||||
g_return_if_fail (group->refcount > 0);
|
||||
|
||||
group->refcount -= 1;
|
||||
if (group->refcount == 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_GROUPS,
|
||||
"Destroying group with leader 0x%lx\n",
|
||||
group->group_leader);
|
||||
|
||||
g_assert (group->display->groups_by_leader != NULL);
|
||||
|
||||
g_hash_table_remove (group->display->groups_by_leader,
|
||||
&group->group_leader);
|
||||
|
||||
/* mop up hash table, this is how it gets freed on display close */
|
||||
if (g_hash_table_size (group->display->groups_by_leader) == 0)
|
||||
{
|
||||
g_hash_table_destroy (group->display->groups_by_leader);
|
||||
group->display->groups_by_leader = NULL;
|
||||
}
|
||||
|
||||
g_free (group->wm_client_machine);
|
||||
g_free (group->startup_id);
|
||||
|
||||
g_free (group);
|
||||
}
|
||||
}
|
||||
|
||||
MetaGroup*
|
||||
meta_window_get_group (MetaWindow *window)
|
||||
{
|
||||
if (window->unmanaging)
|
||||
return NULL;
|
||||
|
||||
if (window->cached_group == NULL)
|
||||
{
|
||||
MetaGroup *group;
|
||||
|
||||
/* use window->xwindow if no window->xgroup_leader */
|
||||
|
||||
group = NULL;
|
||||
|
||||
if (window->display->groups_by_leader)
|
||||
{
|
||||
if (window->xgroup_leader != None)
|
||||
group = g_hash_table_lookup (window->display->groups_by_leader,
|
||||
&window->xgroup_leader);
|
||||
else
|
||||
group = g_hash_table_lookup (window->display->groups_by_leader,
|
||||
&window->xwindow);
|
||||
}
|
||||
|
||||
if (group != NULL)
|
||||
{
|
||||
window->cached_group = group;
|
||||
group->refcount += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->xgroup_leader != None)
|
||||
group = meta_group_new (window->display,
|
||||
window->xgroup_leader);
|
||||
else
|
||||
group = meta_group_new (window->display,
|
||||
window->xwindow);
|
||||
|
||||
window->cached_group = group;
|
||||
}
|
||||
|
||||
window->cached_group->windows = g_slist_prepend (window->cached_group->windows,
|
||||
window);
|
||||
|
||||
meta_topic (META_DEBUG_GROUPS,
|
||||
"Adding %s to group with leader 0x%lx\n",
|
||||
window->desc, group->group_leader);
|
||||
}
|
||||
|
||||
return window->cached_group;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_window_from_group (MetaWindow *window)
|
||||
{
|
||||
if (window->cached_group != NULL)
|
||||
{
|
||||
meta_topic (META_DEBUG_GROUPS,
|
||||
"Removing %s from group with leader 0x%lx\n",
|
||||
window->desc, window->cached_group->group_leader);
|
||||
|
||||
window->cached_group->windows =
|
||||
g_slist_remove (window->cached_group->windows,
|
||||
window);
|
||||
meta_group_unref (window->cached_group);
|
||||
window->cached_group = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_group_leader_changed (MetaWindow *window)
|
||||
{
|
||||
remove_window_from_group (window);
|
||||
meta_window_get_group (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_shutdown_group (MetaWindow *window)
|
||||
{
|
||||
remove_window_from_group (window);
|
||||
}
|
||||
|
||||
MetaGroup*
|
||||
meta_display_lookup_group (MetaDisplay *display,
|
||||
Window group_leader)
|
||||
{
|
||||
MetaGroup *group;
|
||||
|
||||
group = NULL;
|
||||
|
||||
if (display->groups_by_leader)
|
||||
group = g_hash_table_lookup (display->groups_by_leader,
|
||||
&group_leader);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
GSList*
|
||||
meta_group_list_windows (MetaGroup *group)
|
||||
{
|
||||
return g_slist_copy (group->windows);
|
||||
}
|
||||
|
||||
void
|
||||
meta_group_update_layers (MetaGroup *group)
|
||||
{
|
||||
GSList *tmp;
|
||||
GSList *frozen_stacks;
|
||||
|
||||
if (group->windows == NULL)
|
||||
return;
|
||||
|
||||
frozen_stacks = NULL;
|
||||
tmp = group->windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *window = tmp->data;
|
||||
|
||||
/* we end up freezing the same stack a lot of times,
|
||||
* but doesn't hurt anything. have to handle
|
||||
* groups that span 2 screens.
|
||||
*/
|
||||
meta_stack_freeze (window->screen->stack);
|
||||
frozen_stacks = g_slist_prepend (frozen_stacks, window->screen->stack);
|
||||
|
||||
meta_stack_update_layer (window->screen->stack,
|
||||
window);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
tmp = frozen_stacks;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
meta_stack_thaw (tmp->data);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_slist_free (frozen_stacks);
|
||||
}
|
||||
|
||||
const char*
|
||||
meta_group_get_startup_id (MetaGroup *group)
|
||||
{
|
||||
return group->startup_id;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_group_property_notify (MetaGroup *group,
|
||||
XEvent *event)
|
||||
{
|
||||
meta_group_reload_property (group,
|
||||
event->xproperty.atom);
|
||||
|
||||
return TRUE;
|
||||
}
|
50
src/group.h
Normal file
50
src/group.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Metacity window groups */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_GROUP_H
|
||||
#define META_GROUP_H
|
||||
|
||||
#include "window.h"
|
||||
|
||||
/* note, can return NULL */
|
||||
MetaGroup* meta_window_get_group (MetaWindow *window);
|
||||
void meta_window_shutdown_group (MetaWindow *window);
|
||||
|
||||
void meta_window_group_leader_changed (MetaWindow *window);
|
||||
|
||||
/* note, can return NULL */
|
||||
MetaGroup* meta_display_lookup_group (MetaDisplay *display,
|
||||
Window group_leader);
|
||||
|
||||
GSList* meta_group_list_windows (MetaGroup *group);
|
||||
|
||||
void meta_group_update_layers (MetaGroup *group);
|
||||
|
||||
const char* meta_group_get_startup_id (MetaGroup *group);
|
||||
|
||||
gboolean meta_group_property_notify (MetaGroup *group,
|
||||
XEvent *event);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@@ -19,6 +19,7 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "iconcache.h"
|
||||
#include "ui.h"
|
||||
#include "errors.h"
|
||||
@@ -231,7 +232,7 @@ read_rgb_icon (MetaDisplay *display,
|
||||
gulong *best_mini;
|
||||
int mini_w, mini_h;
|
||||
|
||||
meta_error_trap_push (display);
|
||||
meta_error_trap_push_with_return (display);
|
||||
type = None;
|
||||
data = NULL;
|
||||
result = XGetWindowProperty (display->xdisplay,
|
||||
@@ -241,7 +242,7 @@ read_rgb_icon (MetaDisplay *display,
|
||||
False, XA_CARDINAL, &type, &format, &nitems,
|
||||
&bytes_after, ((guchar **)&data));
|
||||
|
||||
err = meta_error_trap_pop (display);
|
||||
err = meta_error_trap_pop_with_return (display, TRUE);
|
||||
|
||||
if (err != Success ||
|
||||
result != Success)
|
||||
@@ -406,7 +407,7 @@ try_pixmap_and_mask (MetaDisplay *display,
|
||||
w, h);
|
||||
}
|
||||
|
||||
meta_error_trap_pop (display);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
|
||||
if (mask)
|
||||
{
|
||||
@@ -470,7 +471,7 @@ get_kwm_win_icon (MetaDisplay *display,
|
||||
*pixmap = None;
|
||||
*mask = None;
|
||||
|
||||
meta_error_trap_push (display);
|
||||
meta_error_trap_push_with_return (display);
|
||||
icons = NULL;
|
||||
result = XGetWindowProperty (display->xdisplay, xwindow,
|
||||
display->atom_kwm_win_icon,
|
||||
@@ -480,7 +481,7 @@ get_kwm_win_icon (MetaDisplay *display,
|
||||
&type, &format, &nitems,
|
||||
&bytes_after, (guchar **)&icons);
|
||||
|
||||
err = meta_error_trap_pop (display);
|
||||
err = meta_error_trap_pop_with_return (display, TRUE);
|
||||
if (err != Success ||
|
||||
result != Success)
|
||||
return;
|
||||
@@ -644,6 +645,27 @@ scaled_from_pixdata (guchar *pixdata,
|
||||
if (src == NULL)
|
||||
return NULL;
|
||||
|
||||
if (w != h)
|
||||
{
|
||||
GdkPixbuf *tmp;
|
||||
int size;
|
||||
|
||||
size = MAX (w, h);
|
||||
|
||||
tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size, size);
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
gdk_pixbuf_fill (tmp, 0);
|
||||
gdk_pixbuf_copy_area (src, 0, 0, w, h,
|
||||
tmp,
|
||||
(size - w) / 2, (size - h) / 2);
|
||||
|
||||
g_object_unref (src);
|
||||
src = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (w != new_w || h != new_h)
|
||||
{
|
||||
dest = gdk_pixbuf_scale_simple (src, new_w, new_h, GDK_INTERP_BILINEAR);
|
||||
|
2849
src/keybindings.c
2849
src/keybindings.c
File diff suppressed because it is too large
Load Diff
@@ -25,17 +25,22 @@
|
||||
#include "display.h"
|
||||
#include "window.h"
|
||||
|
||||
void meta_display_init_keys (MetaDisplay *display);
|
||||
void meta_screen_grab_keys (MetaScreen *screen);
|
||||
void meta_screen_ungrab_keys (MetaScreen *screen);
|
||||
void meta_window_grab_keys (MetaWindow *window);
|
||||
void meta_window_ungrab_keys (MetaWindow *window);
|
||||
gboolean meta_window_grab_all_keys (MetaWindow *window);
|
||||
void meta_window_ungrab_all_keys (MetaWindow *window);
|
||||
void meta_display_process_key_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event);
|
||||
void meta_set_keybindings_disabled (gboolean setting);
|
||||
void meta_display_init_keys (MetaDisplay *display);
|
||||
void meta_display_shutdown_keys (MetaDisplay *display);
|
||||
void meta_screen_grab_keys (MetaScreen *screen);
|
||||
void meta_screen_ungrab_keys (MetaScreen *screen);
|
||||
gboolean meta_screen_grab_all_keys (MetaScreen *screen);
|
||||
void meta_screen_ungrab_all_keys (MetaScreen *screen);
|
||||
void meta_window_grab_keys (MetaWindow *window);
|
||||
void meta_window_ungrab_keys (MetaWindow *window);
|
||||
gboolean meta_window_grab_all_keys (MetaWindow *window);
|
||||
void meta_window_ungrab_all_keys (MetaWindow *window);
|
||||
void meta_display_process_key_event (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
XEvent *event);
|
||||
void meta_set_keybindings_disabled (gboolean setting);
|
||||
void meta_display_process_mapping_event (MetaDisplay *display,
|
||||
XEvent *event);
|
||||
|
||||
#endif
|
||||
|
||||
|
12
src/libmetacity-private.pc.in
Normal file
12
src/libmetacity-private.pc.in
Normal file
@@ -0,0 +1,12 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
libgnome_serverdir=@libexecdir@
|
||||
|
||||
Name: libmetacity-private
|
||||
Description: Metacity internals shared
|
||||
Requires: gtk+-2.0
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lmetacity-private
|
||||
Cflags: -I${includedir}/metacity-1
|
95
src/main.c
95
src/main.c
@@ -38,6 +38,8 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
#include <time.h>
|
||||
|
||||
static MetaExitCode meta_exit_code = META_EXIT_SUCCESS;
|
||||
static GMainLoop *meta_main_loop = NULL;
|
||||
@@ -53,15 +55,27 @@ log_handler (const gchar *log_domain,
|
||||
gpointer user_data)
|
||||
{
|
||||
meta_warning ("Log level %d: %s\n", log_level, message);
|
||||
meta_print_backtrace ();
|
||||
}
|
||||
|
||||
static void
|
||||
usage (void)
|
||||
{
|
||||
g_print ("metacity [--disable-sm] [--sm-save-file=FILENAME] [--display=DISPLAY]\n");
|
||||
g_print (_("metacity [--disable-sm] [--sm-save-file=FILENAME] [--display=DISPLAY] [--replace] [--version]\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
static void
|
||||
version (void)
|
||||
{
|
||||
g_print (_("metacity %s\n"
|
||||
"Copyright (C) 2001-2002 Havoc Pennington, Red Hat, Inc., and others\n"
|
||||
"This is free software; see the source for copying conditions.\n"
|
||||
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
|
||||
VERSION);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@@ -73,23 +87,24 @@ main (int argc, char **argv)
|
||||
gboolean disable_sm;
|
||||
const char *prev_arg;
|
||||
const char *save_file;
|
||||
|
||||
g_set_prgname (argv[0]);
|
||||
|
||||
if (setlocale (LC_ALL, "") == NULL)
|
||||
meta_warning ("Locale not understood by C library, internationalization will not work\n");
|
||||
|
||||
sigemptyset (&empty_mask);
|
||||
act.sa_handler = SIG_IGN;
|
||||
act.sa_mask = empty_mask;
|
||||
act.sa_flags = 0;
|
||||
if (sigaction (SIGPIPE, &act, 0) < 0)
|
||||
g_printerr ("Failed to register SIGPIPE handler: %s\n", strerror (errno));
|
||||
g_printerr ("Failed to register SIGPIPE handler: %s\n",
|
||||
g_strerror (errno));
|
||||
#ifdef SIGXFSZ
|
||||
if (sigaction (SIGXFSZ, &act, 0) < 0)
|
||||
g_printerr ("Failed to register SIGXFSZ handler: %s\n", strerror (errno));
|
||||
g_printerr ("Failed to register SIGXFSZ handler: %s\n",
|
||||
g_strerror (errno));
|
||||
#endif
|
||||
|
||||
g_set_prgname (argv[0]);
|
||||
|
||||
bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
textdomain (GETTEXT_PACKAGE);
|
||||
|
||||
if (g_getenv ("METACITY_VERBOSE"))
|
||||
meta_set_verbose (TRUE);
|
||||
@@ -97,6 +112,26 @@ main (int argc, char **argv)
|
||||
meta_set_debugging (TRUE);
|
||||
meta_set_syncing (g_getenv ("METACITY_SYNC") != NULL);
|
||||
|
||||
{
|
||||
char buf[256];
|
||||
GDate d;
|
||||
g_date_clear (&d, 1);
|
||||
g_date_set_time (&d, time (NULL));
|
||||
g_date_strftime (buf, sizeof (buf), "%x", &d);
|
||||
meta_verbose ("Metacity version %s running on %s\n", VERSION, buf);
|
||||
}
|
||||
|
||||
{
|
||||
const char *charset;
|
||||
g_get_charset (&charset);
|
||||
meta_verbose ("Running in locale \"%s\" with encoding \"%s\"\n",
|
||||
setlocale (LC_ALL, NULL), charset);
|
||||
}
|
||||
|
||||
bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
textdomain (GETTEXT_PACKAGE);
|
||||
|
||||
/* Parse options lamely */
|
||||
|
||||
display_name = NULL;
|
||||
@@ -113,8 +148,12 @@ main (int argc, char **argv)
|
||||
strcmp (arg, "-h") == 0 ||
|
||||
strcmp (arg, "-?") == 0)
|
||||
usage ();
|
||||
else if (strcmp (arg, "--version") == 0)
|
||||
version ();
|
||||
else if (strcmp (arg, "--sm-disable") == 0)
|
||||
disable_sm = TRUE;
|
||||
disable_sm = TRUE;
|
||||
else if (strcmp (arg, "--replace") == 0)
|
||||
meta_set_replace_current_wm (TRUE);
|
||||
else if (strstr (arg, "--display=") == arg)
|
||||
{
|
||||
const char *disp;
|
||||
@@ -212,6 +251,27 @@ main (int argc, char **argv)
|
||||
|
||||
g_type_init ();
|
||||
|
||||
#ifdef HAVE_SHAPE
|
||||
meta_verbose ("Compiled with shape extension\n");
|
||||
#else
|
||||
meta_verbose ("Compiled without shape extension\n");
|
||||
#endif
|
||||
#ifdef HAVE_XINERAMA
|
||||
meta_topic (META_DEBUG_XINERAMA, "Compiled with Xinerama extension\n");
|
||||
#else
|
||||
meta_topic (META_DEBUG_XINERAMA, "Compiled without Xinerama extension\n");
|
||||
#endif
|
||||
#ifdef HAVE_XFREE_XINERAMA
|
||||
meta_topic (META_DEBUG_XINERAMA, " (using XFree86 Xinerama)\n");
|
||||
#else
|
||||
meta_topic (META_DEBUG_XINERAMA, " (not using XFree86 Xinerama)\n");
|
||||
#endif
|
||||
#ifdef HAVE_SOLARIS_XINERAMA
|
||||
meta_topic (META_DEBUG_XINERAMA, " (using Solaris Xinerama)\n");
|
||||
#else
|
||||
meta_topic (META_DEBUG_XINERAMA, " (not using Solaris Xinerama)\n");
|
||||
#endif
|
||||
|
||||
/* Load prefs */
|
||||
meta_prefs_init ();
|
||||
meta_prefs_add_listener (prefs_changed_callback, NULL);
|
||||
@@ -221,10 +281,13 @@ main (int argc, char **argv)
|
||||
/* must be after UI init so we can override GDK handlers */
|
||||
meta_errors_init ();
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
g_log_set_handler (NULL,
|
||||
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
||||
log_handler, NULL);
|
||||
g_log_set_handler (G_LOG_DOMAIN,
|
||||
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
||||
log_handler, NULL);
|
||||
g_log_set_handler ("Gtk",
|
||||
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
||||
log_handler, NULL);
|
||||
@@ -243,10 +306,10 @@ main (int argc, char **argv)
|
||||
g_log_set_handler ("GThread",
|
||||
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
||||
log_handler, NULL);
|
||||
|
||||
if (meta_is_debugging ())
|
||||
g_log_set_always_fatal (G_LOG_LEVEL_MASK);
|
||||
#endif
|
||||
|
||||
if (g_getenv ("METACITY_G_FATAL_WARNINGS") != NULL)
|
||||
g_log_set_always_fatal (G_LOG_LEVEL_MASK);
|
||||
|
||||
meta_ui_set_current_theme (meta_prefs_get_theme (), FALSE);
|
||||
|
||||
@@ -260,7 +323,7 @@ main (int argc, char **argv)
|
||||
meta_ui_set_current_theme ("Crux", FALSE);
|
||||
|
||||
if (!meta_ui_have_a_theme ())
|
||||
meta_fatal (_("Could not find a theme! Be sure %s exits and contains the usual themes."),
|
||||
meta_fatal (_("Could not find a theme! Be sure %s exists and contains the usual themes."),
|
||||
METACITY_PKGDATADIR"/themes");
|
||||
|
||||
/* Connect to SM as late as possible - but before managing display,
|
||||
@@ -292,6 +355,8 @@ main (int argc, char **argv)
|
||||
g_slist_free (displays);
|
||||
}
|
||||
|
||||
meta_session_shutdown ();
|
||||
|
||||
if (meta_restart_after_quit)
|
||||
{
|
||||
GError *err;
|
||||
|
240
src/menu.c
240
src/menu.c
@@ -20,11 +20,14 @@
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "menu.h"
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
#include "core.h"
|
||||
#include "themewidget.h"
|
||||
#include "metaaccellabel.h"
|
||||
|
||||
typedef struct _MenuItem MenuItem;
|
||||
typedef struct _MenuData MenuData;
|
||||
@@ -46,15 +49,16 @@ struct _MenuData
|
||||
static void activate_cb (GtkWidget *menuitem, gpointer data);
|
||||
|
||||
static MenuItem menuitems[] = {
|
||||
{ META_MENU_OP_DELETE, NULL, N_("_Close") },
|
||||
{ META_MENU_OP_MINIMIZE, NULL, N_("_Minimize") },
|
||||
{ META_MENU_OP_MAXIMIZE, NULL, N_("Ma_ximize") },
|
||||
{ META_MENU_OP_UNMAXIMIZE, NULL, N_("_Unmaximize") },
|
||||
{ META_MENU_OP_SHADE, NULL, N_("_Shade") },
|
||||
{ META_MENU_OP_UNSHADE, NULL, N_("U_nshade") },
|
||||
{ META_MENU_OP_MOVE, NULL, N_("Mo_ve") },
|
||||
{ META_MENU_OP_MINIMIZE, METACITY_STOCK_MINIMIZE, N_("Mi_nimize") },
|
||||
{ META_MENU_OP_MAXIMIZE, METACITY_STOCK_MAXIMIZE, N_("Ma_ximize") },
|
||||
{ META_MENU_OP_UNMAXIMIZE, NULL, N_("Unma_ximize") },
|
||||
{ META_MENU_OP_SHADE, NULL, N_("Roll _Up") },
|
||||
{ META_MENU_OP_UNSHADE, NULL, N_("_Unroll") },
|
||||
{ META_MENU_OP_MOVE, NULL, N_("_Move") },
|
||||
{ META_MENU_OP_RESIZE, NULL, N_("_Resize") },
|
||||
{ 0, NULL, NULL }, /* separator */
|
||||
{ META_MENU_OP_DELETE, METACITY_STOCK_DELETE, N_("_Close") },
|
||||
{ 0, NULL, NULL }, /* separator */
|
||||
{ META_MENU_OP_STICK, NULL, N_("Put on _All Workspaces") },
|
||||
{ META_MENU_OP_UNSTICK, NULL, N_("Only on _This Workspace") }
|
||||
};
|
||||
@@ -118,40 +122,102 @@ activate_cb (GtkWidget *menuitem, gpointer data)
|
||||
/* menu may now be freed */
|
||||
}
|
||||
|
||||
static void
|
||||
menu_icon_size_func (MetaArea *area,
|
||||
int *width,
|
||||
int *height,
|
||||
void *user_data)
|
||||
/*
|
||||
* Given a Display and an index, get the workspace name and add any
|
||||
* accelerators. At the moment this means adding a _ if the name is of
|
||||
* the form "Workspace n" where n is less than 10, and escaping any
|
||||
* other '_'s so they do not create inadvertant accelerators.
|
||||
*
|
||||
* The calling code owns the string, and is reponsible to free the
|
||||
* memory after use.
|
||||
*/
|
||||
static char*
|
||||
get_workspace_name_with_accel (Display *display,
|
||||
Window xroot,
|
||||
int index)
|
||||
{
|
||||
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU,
|
||||
width, height);
|
||||
const char *name;
|
||||
int number;
|
||||
|
||||
name = meta_core_get_workspace_name_with_index (display, xroot, index);
|
||||
|
||||
g_assert (name != NULL);
|
||||
|
||||
/*
|
||||
* If the name is of the form "Workspace x" where x is an unsigned
|
||||
* integer, insert a '_' before the number if it is less than 10 and
|
||||
* return it
|
||||
*/
|
||||
number = 0;
|
||||
if (sscanf (name, _("Workspace %d"), &number) == 1)
|
||||
{
|
||||
char *new_name;
|
||||
|
||||
/*
|
||||
* Above name is a pointer into the Workspace struct. Here we make
|
||||
* a copy copy so we can have our wicked way with it.
|
||||
*/
|
||||
new_name = g_strdup_printf (_("Workspace %s%d"),
|
||||
number < 10 ? "_" : "",
|
||||
number);
|
||||
return new_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Otherwise this is just a normal name to which we cannot really
|
||||
* add accelerators. Escape any _ characters so that the user's
|
||||
* workspace names do not get mangled.
|
||||
*/
|
||||
char *new_name;
|
||||
const char *source;
|
||||
char *dest;
|
||||
|
||||
/*
|
||||
* Assume the worst case, that every character is a _
|
||||
*/
|
||||
new_name = g_malloc0 (strlen (name) * 2 + 1);
|
||||
|
||||
/*
|
||||
* Now iterate down the strings, adding '_' to escape as we go
|
||||
*/
|
||||
dest = new_name;
|
||||
source = name;
|
||||
while (*source != '\0')
|
||||
{
|
||||
if (*source == '_')
|
||||
*dest++ = '_';
|
||||
*dest++ = *source++;
|
||||
}
|
||||
|
||||
return new_name;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
menu_icon_expose_func (MetaArea *area,
|
||||
GdkEventExpose *event,
|
||||
int x_offset,
|
||||
int y_offset,
|
||||
void *user_data)
|
||||
static GtkWidget*
|
||||
menu_item_new (const char *label,
|
||||
gboolean with_image,
|
||||
unsigned int key,
|
||||
MetaVirtualModifier mods)
|
||||
{
|
||||
int width, height;
|
||||
MetaMenuIconType type;
|
||||
|
||||
type = GPOINTER_TO_INT (user_data);
|
||||
|
||||
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU,
|
||||
&width, &height);
|
||||
|
||||
meta_theme_draw_menu_icon (meta_theme_get_current (),
|
||||
GTK_WIDGET (area),
|
||||
GTK_WIDGET (area)->window,
|
||||
&event->area,
|
||||
x_offset, y_offset,
|
||||
width, height,
|
||||
type);
|
||||
}
|
||||
GtkWidget *menu_item;
|
||||
GtkWidget *accel_label;
|
||||
|
||||
if (with_image)
|
||||
menu_item = gtk_image_menu_item_new ();
|
||||
else
|
||||
menu_item = gtk_menu_item_new ();
|
||||
accel_label = meta_accel_label_new_with_mnemonic (label);
|
||||
gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (menu_item), accel_label);
|
||||
gtk_widget_show (accel_label);
|
||||
|
||||
meta_accel_label_set_accelerator (META_ACCEL_LABEL (accel_label),
|
||||
key, mods);
|
||||
|
||||
return menu_item;
|
||||
}
|
||||
|
||||
MetaWindowMenu*
|
||||
meta_window_menu_new (MetaFrames *frames,
|
||||
@@ -175,7 +241,10 @@ meta_window_menu_new (MetaFrames *frames,
|
||||
menu->insensitive = insensitive;
|
||||
|
||||
menu->menu = gtk_menu_new ();
|
||||
|
||||
#ifdef HAVE_GTK_MULTIHEAD
|
||||
gtk_menu_set_screen (GTK_MENU (menu->menu),
|
||||
gtk_widget_get_screen (GTK_WIDGET (frames)));
|
||||
#endif
|
||||
i = 0;
|
||||
while (i < (int) G_N_ELEMENTS (menuitems))
|
||||
{
|
||||
@@ -183,7 +252,9 @@ meta_window_menu_new (MetaFrames *frames,
|
||||
{
|
||||
GtkWidget *mi;
|
||||
MenuData *md;
|
||||
|
||||
unsigned int key;
|
||||
MetaVirtualModifier mods;
|
||||
|
||||
if (menuitems[i].op == 0)
|
||||
{
|
||||
mi = gtk_separator_menu_item_new ();
|
||||
@@ -194,65 +265,26 @@ meta_window_menu_new (MetaFrames *frames,
|
||||
|
||||
image = NULL;
|
||||
|
||||
switch (menuitems[i].op)
|
||||
{
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
image = meta_area_new ();
|
||||
meta_area_setup (META_AREA (image),
|
||||
menu_icon_size_func,
|
||||
menu_icon_expose_func,
|
||||
GINT_TO_POINTER (META_MENU_ICON_TYPE_MAXIMIZE),
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_UNMAXIMIZE:
|
||||
image = meta_area_new ();
|
||||
meta_area_setup (META_AREA (image),
|
||||
menu_icon_size_func,
|
||||
menu_icon_expose_func,
|
||||
GINT_TO_POINTER (META_MENU_ICON_TYPE_UNMAXIMIZE),
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
image = meta_area_new ();
|
||||
meta_area_setup (META_AREA (image),
|
||||
menu_icon_size_func,
|
||||
menu_icon_expose_func,
|
||||
GINT_TO_POINTER (META_MENU_ICON_TYPE_MINIMIZE),
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case META_MENU_OP_DELETE:
|
||||
image = meta_area_new ();
|
||||
meta_area_setup (META_AREA (image),
|
||||
menu_icon_size_func,
|
||||
menu_icon_expose_func,
|
||||
GINT_TO_POINTER (META_MENU_ICON_TYPE_CLOSE),
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (image == NULL &&
|
||||
menuitems[i].stock_id)
|
||||
if (menuitems[i].stock_id)
|
||||
{
|
||||
image = gtk_image_new_from_stock (menuitems[i].stock_id,
|
||||
GTK_ICON_SIZE_MENU);
|
||||
|
||||
}
|
||||
|
||||
meta_core_get_menu_accelerator (menuitems[i].op, -1,
|
||||
&key, &mods);
|
||||
|
||||
if (image)
|
||||
{
|
||||
mi = gtk_image_menu_item_new_with_mnemonic (_(menuitems[i].label));
|
||||
mi = menu_item_new (_(menuitems[i].label), TRUE, key, mods);
|
||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi),
|
||||
image);
|
||||
gtk_widget_show (image);
|
||||
}
|
||||
else
|
||||
{
|
||||
mi = gtk_menu_item_new_with_mnemonic (_(menuitems[i].label));
|
||||
mi = menu_item_new (_(menuitems[i].label), FALSE, key, mods);
|
||||
}
|
||||
|
||||
if (insensitive & menuitems[i].op)
|
||||
@@ -287,29 +319,51 @@ meta_window_menu_new (MetaFrames *frames,
|
||||
if (n_workspaces > 0)
|
||||
{
|
||||
GtkWidget *mi;
|
||||
Display *display;
|
||||
Window xroot;
|
||||
|
||||
display = gdk_x11_drawable_get_xdisplay (GTK_WIDGET (frames)->window);
|
||||
|
||||
#ifdef HAVE_GTK_MULTIHEAD
|
||||
{
|
||||
GdkScreen *screen;
|
||||
screen = gdk_drawable_get_screen (GTK_WIDGET (frames)->window);
|
||||
xroot = GDK_DRAWABLE_XID (gdk_screen_get_root_window (screen));
|
||||
}
|
||||
#else
|
||||
{
|
||||
xroot = gdk_x11_get_default_root_xwindow ();
|
||||
}
|
||||
#endif
|
||||
|
||||
i = 0;
|
||||
while (i < n_workspaces)
|
||||
{
|
||||
char *label;
|
||||
char *label, *name;
|
||||
MenuData *md;
|
||||
|
||||
if (ops & META_MENU_OP_UNSTICK)
|
||||
label = g_strdup_printf (_("Only on workspace %s%d"),
|
||||
i < 9 ? "_" : "", i + 1);
|
||||
else
|
||||
label = g_strdup_printf (_("Move to workspace %s%d"),
|
||||
i < 9 ? "_" : "", i + 1);
|
||||
unsigned int key;
|
||||
MetaVirtualModifier mods;
|
||||
|
||||
mi = gtk_menu_item_new_with_mnemonic (label);
|
||||
meta_core_get_menu_accelerator (META_MENU_OP_WORKSPACES,
|
||||
i + 1,
|
||||
&key, &mods);
|
||||
|
||||
name = get_workspace_name_with_accel (display, xroot, i);
|
||||
if (ops & META_MENU_OP_UNSTICK)
|
||||
label = g_strdup_printf (_("Only on %s"), name);
|
||||
else
|
||||
label = g_strdup_printf(_("Move to %s"), name);
|
||||
mi = menu_item_new (label, FALSE, key, mods);
|
||||
|
||||
g_free (name);
|
||||
g_free (label);
|
||||
|
||||
if (!(ops & META_MENU_OP_UNSTICK) &&
|
||||
(active_workspace == i ||
|
||||
insensitive & META_MENU_OP_WORKSPACES))
|
||||
gtk_widget_set_sensitive (mi, FALSE);
|
||||
|
||||
else if (insensitive & META_MENU_OP_WORKSPACES)
|
||||
gtk_widget_set_sensitive (mi, FALSE);
|
||||
md = g_new (MenuData, 1);
|
||||
|
||||
md->menu = menu;
|
||||
|
@@ -25,6 +25,11 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "frames.h"
|
||||
|
||||
/* Stock icons */
|
||||
#define METACITY_STOCK_DELETE "metacity-delete"
|
||||
#define METACITY_STOCK_MINIMIZE "metacity-minimize"
|
||||
#define METACITY_STOCK_MAXIMIZE "metacity-maximize"
|
||||
|
||||
struct _MetaWindowMenu
|
||||
{
|
||||
MetaFrames *frames;
|
||||
|
439
src/metaaccellabel.c
Normal file
439
src/metaaccellabel.c
Normal file
@@ -0,0 +1,439 @@
|
||||
/* Metacity hacked-up GtkAccelLabel */
|
||||
/* Copyright (C) 2002 Red Hat, Inc. */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* MetaAccelLabel: GtkLabel with accelerator monitoring facilities.
|
||||
* Copyright (C) 1998 Tim Janik
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2001. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "metaaccellabel.h"
|
||||
#include <gtk/gtkmain.h>
|
||||
#include <gtk/gtkaccelmap.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
static void meta_accel_label_class_init (MetaAccelLabelClass *klass);
|
||||
static void meta_accel_label_init (MetaAccelLabel *accel_label);
|
||||
static void meta_accel_label_destroy (GtkObject *object);
|
||||
static void meta_accel_label_finalize (GObject *object);
|
||||
static void meta_accel_label_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition);
|
||||
static gboolean meta_accel_label_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
|
||||
static void meta_accel_label_update (MetaAccelLabel *accel_label);
|
||||
static int meta_accel_label_get_accel_width (MetaAccelLabel *accel_label);
|
||||
|
||||
|
||||
static MetaAccelLabelClass *accel_label_class = NULL;
|
||||
static GtkLabelClass *parent_class = NULL;
|
||||
|
||||
|
||||
GtkType
|
||||
meta_accel_label_get_type (void)
|
||||
{
|
||||
static GtkType accel_label_type = 0;
|
||||
|
||||
if (!accel_label_type)
|
||||
{
|
||||
static const GtkTypeInfo accel_label_info =
|
||||
{
|
||||
"MetaAccelLabel",
|
||||
sizeof (MetaAccelLabel),
|
||||
sizeof (MetaAccelLabelClass),
|
||||
(GtkClassInitFunc) meta_accel_label_class_init,
|
||||
(GtkObjectInitFunc) meta_accel_label_init,
|
||||
/* reserved_1 */ NULL,
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
accel_label_type = gtk_type_unique (GTK_TYPE_LABEL, &accel_label_info);
|
||||
}
|
||||
|
||||
return accel_label_type;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_accel_label_class_init (MetaAccelLabelClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
accel_label_class = class;
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
gobject_class->finalize = meta_accel_label_finalize;
|
||||
|
||||
object_class->destroy = meta_accel_label_destroy;
|
||||
|
||||
widget_class->size_request = meta_accel_label_size_request;
|
||||
widget_class->expose_event = meta_accel_label_expose_event;
|
||||
|
||||
class->signal_quote1 = g_strdup ("<:");
|
||||
class->signal_quote2 = g_strdup (":>");
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the shift key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_shift = g_strdup (_("Shift"));
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the control key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_control = g_strdup (_("Ctrl"));
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the alt key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_alt = g_strdup (_("Alt"));
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the meta key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_meta = g_strdup (_("Meta"));
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the super key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_super = g_strdup (_("Super"));
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the hyper key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_hyper = g_strdup (_("Hyper"));
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the mod2 key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_mod2 = g_strdup (_("Mod2"));
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the mod3 key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_mod3 = g_strdup (_("Mod3"));
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the mod4 key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_mod4 = g_strdup (_("Mod4"));
|
||||
/* This is the text that should appear next to menu accelerators
|
||||
* that use the mod5 key. If the text on this key isn't typically
|
||||
* translated on keyboards used for your language, don't translate
|
||||
* this.
|
||||
*/
|
||||
class->mod_name_mod5 = g_strdup (_("Mod5"));
|
||||
|
||||
class->mod_separator = g_strdup ("+");
|
||||
class->accel_seperator = g_strdup (" / ");
|
||||
class->latin1_to_char = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_accel_label_init (MetaAccelLabel *accel_label)
|
||||
{
|
||||
accel_label->accel_padding = 3;
|
||||
accel_label->accel_string = NULL;
|
||||
|
||||
meta_accel_label_update (accel_label);
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
meta_accel_label_new_with_mnemonic (const gchar *string)
|
||||
{
|
||||
MetaAccelLabel *accel_label;
|
||||
|
||||
g_return_val_if_fail (string != NULL, NULL);
|
||||
|
||||
accel_label = g_object_new (META_TYPE_ACCEL_LABEL, NULL);
|
||||
|
||||
gtk_label_set_text_with_mnemonic (GTK_LABEL (accel_label), string);
|
||||
|
||||
return GTK_WIDGET (accel_label);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_accel_label_destroy (GtkObject *object)
|
||||
{
|
||||
MetaAccelLabel *accel_label = META_ACCEL_LABEL (object);
|
||||
|
||||
|
||||
g_free (accel_label->accel_string);
|
||||
accel_label->accel_string = NULL;
|
||||
|
||||
accel_label->accel_mods = 0;
|
||||
accel_label->accel_key = 0;
|
||||
|
||||
GTK_OBJECT_CLASS (parent_class)->destroy (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_accel_label_finalize (GObject *object)
|
||||
{
|
||||
MetaAccelLabel *accel_label = META_ACCEL_LABEL (object);
|
||||
|
||||
g_free (accel_label->accel_string);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
void
|
||||
meta_accel_label_set_accelerator (MetaAccelLabel *accel_label,
|
||||
guint accelerator_key,
|
||||
MetaVirtualModifier accelerator_mods)
|
||||
{
|
||||
g_return_if_fail (META_IS_ACCEL_LABEL (accel_label));
|
||||
|
||||
if (accelerator_key != accel_label->accel_key ||
|
||||
accelerator_mods != accel_label->accel_mods)
|
||||
{
|
||||
accel_label->accel_mods = accelerator_mods;
|
||||
accel_label->accel_key = accelerator_key;
|
||||
|
||||
meta_accel_label_update (accel_label);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
meta_accel_label_get_accel_width (MetaAccelLabel *accel_label)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_ACCEL_LABEL (accel_label), 0);
|
||||
|
||||
return (accel_label->accel_string_width +
|
||||
(accel_label->accel_string_width ? accel_label->accel_padding : 0));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_accel_label_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition)
|
||||
{
|
||||
MetaAccelLabel *accel_label = META_ACCEL_LABEL (widget);
|
||||
PangoLayout *layout;
|
||||
gint width;
|
||||
|
||||
if (GTK_WIDGET_CLASS (parent_class)->size_request)
|
||||
GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, accel_label->accel_string);
|
||||
pango_layout_get_pixel_size (layout, &width, NULL);
|
||||
accel_label->accel_string_width = width;
|
||||
|
||||
g_object_unref (G_OBJECT (layout));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_accel_label_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event)
|
||||
{
|
||||
MetaAccelLabel *accel_label = META_ACCEL_LABEL (widget);
|
||||
GtkMisc *misc = GTK_MISC (accel_label);
|
||||
PangoLayout *layout;
|
||||
|
||||
if (GTK_WIDGET_DRAWABLE (accel_label))
|
||||
{
|
||||
int ac_width;
|
||||
|
||||
ac_width = meta_accel_label_get_accel_width (accel_label);
|
||||
|
||||
if (widget->allocation.width >= widget->requisition.width + ac_width)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
widget->allocation.width -= ac_width;
|
||||
if (GTK_WIDGET_CLASS (parent_class)->expose_event)
|
||||
GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
|
||||
widget->allocation.width += ac_width;
|
||||
|
||||
x = widget->allocation.x + widget->allocation.width - misc->xpad - ac_width;
|
||||
|
||||
y = (widget->allocation.y * (1.0 - misc->yalign) +
|
||||
(widget->allocation.y + widget->allocation.height -
|
||||
(widget->requisition.height - misc->ypad * 2)) *
|
||||
misc->yalign) + 1.5;
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, accel_label->accel_string);
|
||||
|
||||
gtk_paint_layout (widget->style,
|
||||
widget->window,
|
||||
GTK_WIDGET_STATE (widget),
|
||||
FALSE,
|
||||
&event->area,
|
||||
widget,
|
||||
"accellabel",
|
||||
x, y,
|
||||
layout);
|
||||
|
||||
g_object_unref (G_OBJECT (layout));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GTK_WIDGET_CLASS (parent_class)->expose_event)
|
||||
GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_accel_label_update (MetaAccelLabel *accel_label)
|
||||
{
|
||||
MetaAccelLabelClass *class;
|
||||
GString *gstring;
|
||||
gboolean seen_mod = FALSE;
|
||||
gunichar ch;
|
||||
|
||||
g_return_if_fail (META_IS_ACCEL_LABEL (accel_label));
|
||||
|
||||
class = META_ACCEL_LABEL_GET_CLASS (accel_label);
|
||||
|
||||
g_free (accel_label->accel_string);
|
||||
accel_label->accel_string = NULL;
|
||||
|
||||
gstring = g_string_new (accel_label->accel_string);
|
||||
g_string_append (gstring, gstring->len ? class->accel_seperator : " ");
|
||||
|
||||
if (accel_label->accel_mods & META_VIRTUAL_SHIFT_MASK)
|
||||
{
|
||||
g_string_append (gstring, class->mod_name_shift);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
if (accel_label->accel_mods & META_VIRTUAL_CONTROL_MASK)
|
||||
{
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
g_string_append (gstring, class->mod_name_control);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
if (accel_label->accel_mods & META_VIRTUAL_ALT_MASK)
|
||||
{
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
g_string_append (gstring, class->mod_name_alt);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
if (accel_label->accel_mods & META_VIRTUAL_META_MASK)
|
||||
{
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
g_string_append (gstring, class->mod_name_meta);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
if (accel_label->accel_mods & META_VIRTUAL_SUPER_MASK)
|
||||
{
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
g_string_append (gstring, class->mod_name_super);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
if (accel_label->accel_mods & META_VIRTUAL_HYPER_MASK)
|
||||
{
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
g_string_append (gstring, class->mod_name_hyper);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
if (accel_label->accel_mods & META_VIRTUAL_MOD2_MASK)
|
||||
{
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
g_string_append (gstring, class->mod_name_mod2);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
if (accel_label->accel_mods & META_VIRTUAL_MOD3_MASK)
|
||||
{
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
g_string_append (gstring, class->mod_name_mod3);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
if (accel_label->accel_mods & META_VIRTUAL_MOD4_MASK)
|
||||
{
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
g_string_append (gstring, class->mod_name_mod4);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
if (accel_label->accel_mods & META_VIRTUAL_MOD5_MASK)
|
||||
{
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
g_string_append (gstring, class->mod_name_mod5);
|
||||
seen_mod = TRUE;
|
||||
}
|
||||
|
||||
if (seen_mod)
|
||||
g_string_append (gstring, class->mod_separator);
|
||||
|
||||
ch = gdk_keyval_to_unicode (accel_label->accel_key);
|
||||
if (ch && (g_unichar_isgraph (ch) || ch == ' ') &&
|
||||
(ch < 0x80 || class->latin1_to_char))
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case ' ':
|
||||
g_string_append (gstring, "Space");
|
||||
break;
|
||||
case '\\':
|
||||
g_string_append (gstring, "Backslash");
|
||||
break;
|
||||
default:
|
||||
g_string_append_unichar (gstring, g_unichar_toupper (ch));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *tmp;
|
||||
|
||||
tmp = gtk_accelerator_name (accel_label->accel_key, 0);
|
||||
if (tmp[0] != 0 && tmp[1] == 0)
|
||||
tmp[0] = g_ascii_toupper (tmp[0]);
|
||||
g_string_append (gstring, tmp);
|
||||
g_free (tmp);
|
||||
}
|
||||
|
||||
g_free (accel_label->accel_string);
|
||||
accel_label->accel_string = gstring->str;
|
||||
g_string_free (gstring, FALSE);
|
||||
|
||||
g_assert (accel_label->accel_string);
|
||||
/* accel_label->accel_string = g_strdup ("-/-"); */
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (accel_label));
|
||||
}
|
104
src/metaaccellabel.h
Normal file
104
src/metaaccellabel.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* Metacity hacked-up GtkAccelLabel */
|
||||
/* Copyright (C) 2002 Red Hat, Inc. */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
* MetaAccelLabel: GtkLabel with accelerator monitoring facilities.
|
||||
* Copyright (C) 1998 Tim Janik
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2001. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#ifndef __META_ACCEL_LABEL_H__
|
||||
#define __META_ACCEL_LABEL_H__
|
||||
|
||||
#include <gtk/gtklabel.h>
|
||||
#include "common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#define META_TYPE_ACCEL_LABEL (meta_accel_label_get_type ())
|
||||
#define META_ACCEL_LABEL(obj) (GTK_CHECK_CAST ((obj), META_TYPE_ACCEL_LABEL, MetaAccelLabel))
|
||||
#define META_ACCEL_LABEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), META_TYPE_ACCEL_LABEL, MetaAccelLabelClass))
|
||||
#define META_IS_ACCEL_LABEL(obj) (GTK_CHECK_TYPE ((obj), META_TYPE_ACCEL_LABEL))
|
||||
#define META_IS_ACCEL_LABEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), META_TYPE_ACCEL_LABEL))
|
||||
#define META_ACCEL_LABEL_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), META_TYPE_ACCEL_LABEL, MetaAccelLabelClass))
|
||||
|
||||
|
||||
typedef struct _MetaAccelLabel MetaAccelLabel;
|
||||
typedef struct _MetaAccelLabelClass MetaAccelLabelClass;
|
||||
|
||||
struct _MetaAccelLabel
|
||||
{
|
||||
GtkLabel label;
|
||||
|
||||
MetaVirtualModifier accel_mods;
|
||||
guint accel_key;
|
||||
guint accel_padding;
|
||||
gchar *accel_string;
|
||||
guint16 accel_string_width;
|
||||
};
|
||||
|
||||
struct _MetaAccelLabelClass
|
||||
{
|
||||
GtkLabelClass parent_class;
|
||||
|
||||
gchar *signal_quote1;
|
||||
gchar *signal_quote2;
|
||||
gchar *mod_name_shift;
|
||||
gchar *mod_name_control;
|
||||
gchar *mod_name_alt;
|
||||
gchar *mod_name_meta;
|
||||
gchar *mod_name_super;
|
||||
gchar *mod_name_hyper;
|
||||
gchar *mod_name_mod2;
|
||||
gchar *mod_name_mod3;
|
||||
gchar *mod_name_mod4;
|
||||
gchar *mod_name_mod5;
|
||||
gchar *mod_separator;
|
||||
gchar *accel_seperator;
|
||||
guint latin1_to_char : 1;
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
void (*_gtk_reserved3) (void);
|
||||
void (*_gtk_reserved4) (void);
|
||||
};
|
||||
|
||||
GtkType meta_accel_label_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget* meta_accel_label_new_with_mnemonic (const gchar *string);
|
||||
void meta_accel_label_set_accelerator (MetaAccelLabel *accel_label,
|
||||
guint accelerator_key,
|
||||
MetaVirtualModifier accelerator_mods);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* __META_ACCEL_LABEL_H__ */
|
134
src/metacity-Xatomtype.h
Normal file
134
src/metacity-Xatomtype.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/* $Xorg: Xatomtype.h,v 1.4 2001/02/09 02:03:38 xorgcvs Exp $ */
|
||||
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifndef _XATOMTYPE_H_
|
||||
#define _XATOMTYPE_H_
|
||||
|
||||
/*
|
||||
* This files defines crock C structures for calling XGetWindowProperty and
|
||||
* XChangeProperty. All fields must be longs as the semantics of property
|
||||
* routines will handle conversion to and from actual 32 bit objects. If your
|
||||
* compiler doesn't treat &structoflongs the same as &arrayoflongs[0], you
|
||||
* will have some work to do.
|
||||
*/
|
||||
|
||||
#define BOOL long
|
||||
#define SIGNEDINT long
|
||||
#define UNSIGNEDINT unsigned long
|
||||
#define RESOURCEID unsigned long
|
||||
|
||||
|
||||
/* this structure may be extended, but do not change the order */
|
||||
typedef struct {
|
||||
UNSIGNEDINT flags;
|
||||
SIGNEDINT x, y, width, height; /* need to cvt; only for pre-ICCCM */
|
||||
SIGNEDINT minWidth, minHeight; /* need to cvt */
|
||||
SIGNEDINT maxWidth, maxHeight; /* need to cvt */
|
||||
SIGNEDINT widthInc, heightInc; /* need to cvt */
|
||||
SIGNEDINT minAspectX, minAspectY; /* need to cvt */
|
||||
SIGNEDINT maxAspectX, maxAspectY; /* need to cvt */
|
||||
SIGNEDINT baseWidth,baseHeight; /* need to cvt; ICCCM version 1 */
|
||||
SIGNEDINT winGravity; /* need to cvt; ICCCM version 1 */
|
||||
} xPropSizeHints;
|
||||
#define OldNumPropSizeElements 15 /* pre-ICCCM */
|
||||
#define NumPropSizeElements 18 /* ICCCM version 1 */
|
||||
|
||||
/* this structure may be extended, but do not change the order */
|
||||
/* RGB properties */
|
||||
typedef struct {
|
||||
RESOURCEID colormap;
|
||||
UNSIGNEDINT red_max;
|
||||
UNSIGNEDINT red_mult;
|
||||
UNSIGNEDINT green_max;
|
||||
UNSIGNEDINT green_mult;
|
||||
UNSIGNEDINT blue_max;
|
||||
UNSIGNEDINT blue_mult;
|
||||
UNSIGNEDINT base_pixel;
|
||||
RESOURCEID visualid; /* ICCCM version 1 */
|
||||
RESOURCEID killid; /* ICCCM version 1 */
|
||||
} xPropStandardColormap;
|
||||
#define OldNumPropStandardColormapElements 8 /* pre-ICCCM */
|
||||
#define NumPropStandardColormapElements 10 /* ICCCM version 1 */
|
||||
|
||||
|
||||
/* this structure may be extended, but do not change the order */
|
||||
typedef struct {
|
||||
UNSIGNEDINT flags;
|
||||
BOOL input; /* need to convert */
|
||||
SIGNEDINT initialState; /* need to cvt */
|
||||
RESOURCEID iconPixmap;
|
||||
RESOURCEID iconWindow;
|
||||
SIGNEDINT iconX; /* need to cvt */
|
||||
SIGNEDINT iconY; /* need to cvt */
|
||||
RESOURCEID iconMask;
|
||||
UNSIGNEDINT windowGroup;
|
||||
} xPropWMHints;
|
||||
#define NumPropWMHintsElements 9 /* number of elements in this structure */
|
||||
|
||||
/* this structure defines the icon size hints information */
|
||||
typedef struct {
|
||||
SIGNEDINT minWidth, minHeight; /* need to cvt */
|
||||
SIGNEDINT maxWidth, maxHeight; /* need to cvt */
|
||||
SIGNEDINT widthInc, heightInc; /* need to cvt */
|
||||
} xPropIconSize;
|
||||
#define NumPropIconSizeElements 6 /* number of elements in this structure */
|
||||
|
||||
/* this structure defines the window manager state information */
|
||||
typedef struct {
|
||||
SIGNEDINT state; /* need to cvt */
|
||||
RESOURCEID iconWindow;
|
||||
} xPropWMState;
|
||||
#define NumPropWMStateElements 2 /* number of elements in struct */
|
||||
|
||||
#undef BOOL
|
||||
#undef SIGNEDINT
|
||||
#undef UNSIGNEDINT
|
||||
#undef RESOURCEID
|
||||
|
||||
#endif /* _XATOMTYPE_H_ */
|
@@ -109,6 +109,186 @@ kill_window_question (const char *window_name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char*
|
||||
latin1_to_utf8 (const char *text)
|
||||
{
|
||||
GString *str;
|
||||
const char *p;
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
p = text;
|
||||
while (*p)
|
||||
{
|
||||
g_string_append_unichar (str, *p);
|
||||
++p;
|
||||
}
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
COLUMN_TITLE,
|
||||
COLUMN_CLASS,
|
||||
COLUMN_LAST
|
||||
};
|
||||
|
||||
static GtkWidget*
|
||||
create_lame_apps_list (char **lame_apps)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkCellRenderer *cell;
|
||||
GtkWidget *tree_view;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkListStore *model;
|
||||
GtkTreeIter iter;
|
||||
int i;
|
||||
|
||||
model = gtk_list_store_new (COLUMN_LAST,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING);
|
||||
|
||||
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
|
||||
|
||||
g_object_unref (G_OBJECT (model));
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
|
||||
|
||||
gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection),
|
||||
GTK_SELECTION_NONE);
|
||||
|
||||
i = 0;
|
||||
while (lame_apps[i])
|
||||
{
|
||||
char *s;
|
||||
|
||||
gtk_list_store_append (model, &iter);
|
||||
|
||||
/* window class is latin-1 */
|
||||
s = latin1_to_utf8 (lame_apps[i+1]);
|
||||
|
||||
gtk_list_store_set (model,
|
||||
&iter,
|
||||
COLUMN_TITLE, lame_apps[i],
|
||||
COLUMN_CLASS, s,
|
||||
-1);
|
||||
|
||||
g_free (s);
|
||||
|
||||
i += 2;
|
||||
}
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
|
||||
g_object_set (G_OBJECT (cell),
|
||||
"xpad", 2,
|
||||
NULL);
|
||||
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Title"),
|
||||
cell,
|
||||
"text", COLUMN_TITLE,
|
||||
NULL);
|
||||
|
||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_TITLE);
|
||||
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
|
||||
GTK_TREE_VIEW_COLUMN (column));
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Class"),
|
||||
cell,
|
||||
"text", COLUMN_CLASS,
|
||||
NULL);
|
||||
|
||||
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CLASS);
|
||||
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
|
||||
GTK_TREE_VIEW_COLUMN (column));
|
||||
|
||||
return tree_view;
|
||||
}
|
||||
|
||||
static int
|
||||
warn_about_no_sm_support (char **lame_apps)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *list;
|
||||
GtkWidget *sw;
|
||||
|
||||
dialog = gtk_message_dialog_new (NULL,
|
||||
0,
|
||||
GTK_MESSAGE_WARNING,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
_("These windows do not support \"save current setup\" and will have to be restarted manually next time you log in."));
|
||||
|
||||
g_signal_connect (G_OBJECT (dialog),
|
||||
"response",
|
||||
G_CALLBACK (gtk_main_quit),
|
||||
NULL);
|
||||
|
||||
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
|
||||
list = create_lame_apps_list (lame_apps);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (sw), 3);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (sw), list);
|
||||
|
||||
/* sw as geometry widget */
|
||||
gtk_window_set_geometry_hints (GTK_WINDOW (dialog),
|
||||
sw, NULL, 0);
|
||||
|
||||
/* applies to geometry widget; try to avoid scrollbars,
|
||||
* but don't make the window huge
|
||||
*/
|
||||
gtk_window_set_default_size (GTK_WINDOW (dialog),
|
||||
400, 225);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
|
||||
sw,
|
||||
TRUE, TRUE, 0);
|
||||
|
||||
gtk_widget_show_all (dialog);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
error_about_command (const char *gconf_key,
|
||||
const char *command,
|
||||
const char *error)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
/* FIXME offer to change the value of the command's gconf key */
|
||||
|
||||
if (*command != '\0')
|
||||
dialog = gtk_message_dialog_new (NULL, 0,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
_("There was an error running \"%s\":\n"
|
||||
"%s."),
|
||||
command, error);
|
||||
else
|
||||
dialog = gtk_message_dialog_new (NULL, 0,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
"%s", error);
|
||||
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@@ -134,7 +314,32 @@ main (int argc, char **argv)
|
||||
|
||||
return kill_window_question (argv[2], argv[3]);
|
||||
}
|
||||
else if (strcmp (argv[1], "--warn-about-no-sm-support") == 0)
|
||||
{
|
||||
/* argc must be even because we want title-class pairs */
|
||||
if (argc < 3 || (argc % 2) != 0)
|
||||
{
|
||||
g_printerr ("bad args to metacity-dialog\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return warn_about_no_sm_support (&argv[2]);
|
||||
}
|
||||
else if (strcmp (argv[1], "--command-failed-error") == 0)
|
||||
{
|
||||
|
||||
/* the args are the gconf key of the failed command, the text of
|
||||
* the command, and the error message
|
||||
*/
|
||||
if (argc != 5)
|
||||
{
|
||||
g_printerr ("bad args to metacity-dialog\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return error_about_command (argv[2], argv[3], argv[4]);
|
||||
}
|
||||
|
||||
g_printerr ("bad args to metacity-dialog\n");
|
||||
return 1;
|
||||
}
|
||||
|
@@ -1,6 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=Metacity
|
||||
Exec=metacity
|
||||
|
||||
[Window Manager]
|
||||
SessionManaged=true
|
12
src/metacity.desktop.in
Normal file
12
src/metacity.desktop.in
Normal file
@@ -0,0 +1,12 @@
|
||||
[Desktop Entry]
|
||||
_Name=Metacity
|
||||
Exec=metacity
|
||||
# name of loadable control center module
|
||||
X-GNOME-WMSettingsModule=metacity
|
||||
# name we put on the WM spec check window
|
||||
X-GNOME-WMName=Metacity
|
||||
# back compat only
|
||||
X-GnomeWMSettingsLibrary=metacity
|
||||
|
||||
[Window Manager]
|
||||
SessionManaged=true
|
@@ -1,165 +0,0 @@
|
||||
<gconfschemafile>
|
||||
<schemalist>
|
||||
|
||||
<!-- General preferences -->
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/general/focus_mode</key>
|
||||
<applyto>/apps/metacity/general/focus_mode</applyto>
|
||||
<owner>metacity</owner>
|
||||
<type>string</type>
|
||||
<default>click</default>
|
||||
<locale name="C">
|
||||
<short>Window focus mode</short>
|
||||
<long>
|
||||
The window focus mode indicates how windows are activated.
|
||||
It has three possible values; "click" means windows must
|
||||
be clicked in order to focus them, "sloppy" means windows
|
||||
are focused when the mouse enters the window, and "mouse" means
|
||||
windows are focused when the mouse enters the window and
|
||||
unfocused when the mouse leaves the window.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/general/theme</key>
|
||||
<applyto>/apps/metacity/general/theme</applyto>
|
||||
<owner>metacity</owner>
|
||||
<type>string</type>
|
||||
<default>Atlanta</default>
|
||||
<locale name="C">
|
||||
<short>Current theme</short>
|
||||
<long>
|
||||
The theme determines the appearance of window borders,
|
||||
titlebar, and so forth.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/general/titlebar_uses_desktop_font</key>
|
||||
<applyto>/apps/metacity/general/titlebar_uses_desktop_font</applyto>
|
||||
<owner>metacity</owner>
|
||||
<type>bool</type>
|
||||
<default>true</default>
|
||||
<locale name="C">
|
||||
<short>Use standard desktop font in window titles</short>
|
||||
<long>
|
||||
If true, ignore the titlebar_font and titlebar_font_size
|
||||
options, and use the standard application font for window
|
||||
titles.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/general/titlebar_font</key>
|
||||
<applyto>/apps/metacity/general/titlebar_font</applyto>
|
||||
<owner>metacity</owner>
|
||||
<type>string</type>
|
||||
<!-- no default is deliberate - we want to be unset by default -->
|
||||
<locale name="C">
|
||||
<short>Window title font</short>
|
||||
<long>
|
||||
A font description string describing a font for window
|
||||
titlebars. The size from the description
|
||||
will only be used if the titlebar_font_size option is set
|
||||
to 0, however. Also, this option is disabled if the
|
||||
titlebar_uses_desktop_font option is set to true.
|
||||
By default, titlebar_font is unset, causing Metacity to fall
|
||||
back to the desktop font even if titlebar_uses_desktop_font
|
||||
is false.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/general/titlebar_font_size</key>
|
||||
<applyto>/apps/metacity/general/titlebar_font_size</applyto>
|
||||
<owner>metacity</owner>
|
||||
<type>int</type>
|
||||
<default>0</default>
|
||||
<locale name="C">
|
||||
<short>Window title font size</short>
|
||||
<long>
|
||||
The size of the font used in window titlebars, in points.
|
||||
If set to 0, the size comes from the titlebar_font option
|
||||
or from the desktop-wide default. If set to nonzero,
|
||||
overrides those sizes.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/general/num_workspaces</key>
|
||||
<applyto>/apps/metacity/general/num_workspaces</applyto>
|
||||
<owner>metacity</owner>
|
||||
<type>int</type>
|
||||
<default>4</default>
|
||||
<locale name="C">
|
||||
<short>Number of workspaces</short>
|
||||
<long>
|
||||
Number of workspaces. Must be more than zero, and
|
||||
has a fixed maximum (to prevent accidentally destroying
|
||||
your desktop by asking for 34 million workspaces).
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<!-- Keybindings -->
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/keybindings/activate_window_menu</key>
|
||||
<applyto>/apps/metacity/keybindings/activate_window_menu</applyto>
|
||||
<owner>metacity</owner>
|
||||
<type>string</type>
|
||||
<default><Alt>space</default>
|
||||
<locale name="C">
|
||||
<short>Activate window menu</short>
|
||||
<long>
|
||||
The keybinding used to activate the window menu.
|
||||
The format looks like "<Control>a" or "<Shift><Alt>F1" or
|
||||
"<Release>z" (the last one is for key release). The parser is
|
||||
fairly liberal and allows lower or upper case, and also
|
||||
abbreviations such as "<Ctl>" and "<Ctrl>". This option can be
|
||||
set to a single string, or a list of strings; if a list,
|
||||
all of the given keybindings will be present. If you set
|
||||
the option to the special string "disabled", then there
|
||||
will be no keybinding for this action.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/apps/metacity/general/application_based</key>
|
||||
<applyto>/apps/metacity/general/application_based</applyto>
|
||||
<owner>metacity</owner>
|
||||
<type>bool</type>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Navigation works in terms of applications not windows</short>
|
||||
<long>
|
||||
If true, then Metacity works in terms of applications rather
|
||||
than windows. The concept is a bit abstract, but
|
||||
in general an application-based setup is more like
|
||||
the Mac and less like Windows. When you focus a window
|
||||
in application-based mode, all the windows in the
|
||||
application will be raised. Also, in application-based
|
||||
mode, focus clicks are not passed through to windows
|
||||
in other applications.
|
||||
The existence of this setting is somewhat questionable.
|
||||
But it's better than having settings for all the specific
|
||||
details of application-based vs. window-based, e.g.
|
||||
whether to pass through clicks. Also, application-based mode
|
||||
is largely unimplemented at the moment.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
</schemalist>
|
||||
</gconfschemafile>
|
||||
|
||||
|
||||
|
||||
|
1684
src/metacity.schemas.in
Normal file
1684
src/metacity.schemas.in
Normal file
File diff suppressed because it is too large
Load Diff
700
src/place.c
700
src/place.c
@@ -19,8 +19,11 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "place.h"
|
||||
#include "workspace.h"
|
||||
#include "prefs.h"
|
||||
#include <gdk/gdkregion.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
@@ -85,6 +88,8 @@ find_next_cascade (MetaWindow *window,
|
||||
GList *sorted;
|
||||
int cascade_x, cascade_y;
|
||||
int x_threshold, y_threshold;
|
||||
int window_width, window_height;
|
||||
int cascade_stage;
|
||||
MetaRectangle work_area;
|
||||
|
||||
sorted = g_list_copy (windows);
|
||||
@@ -95,32 +100,42 @@ find_next_cascade (MetaWindow *window,
|
||||
* new window after it. If a window is already nearly at that
|
||||
* position, we move on.
|
||||
*/
|
||||
|
||||
|
||||
/* arbitrary-ish threshold, honors user attempts to
|
||||
* manually cascade.
|
||||
*/
|
||||
#define CASCADE_FUZZ 15
|
||||
if (fgeom)
|
||||
{
|
||||
x_threshold = MAX (fgeom->left_width, CASCADE_FUZZ);
|
||||
y_threshold = MAX (fgeom->top_height, CASCADE_FUZZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
x_threshold = CASCADE_FUZZ;
|
||||
y_threshold = CASCADE_FUZZ;
|
||||
}
|
||||
|
||||
/* Find furthest-SE origin of all workspaces.
|
||||
* cascade_x, cascade_y are the target position
|
||||
* of NW corner of window frame.
|
||||
*/
|
||||
meta_window_get_work_area (window, &work_area);
|
||||
|
||||
/* FIXME this is bogus because we get the current xinerama
|
||||
* for the window based on its position, but we haven't
|
||||
* placed it yet.
|
||||
*/
|
||||
meta_window_get_work_area (window, TRUE, &work_area);
|
||||
|
||||
cascade_x = MAX (0, work_area.x);
|
||||
cascade_y = MAX (0, work_area.y);
|
||||
|
||||
/* Find first cascade position that's not used. */
|
||||
|
||||
/* arbitrary-ish threshold, honors user attempts to
|
||||
* manually cascade.
|
||||
*/
|
||||
if (fgeom)
|
||||
{
|
||||
x_threshold = MAX (fgeom->left_width, 10);
|
||||
y_threshold = MAX (fgeom->top_height, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
x_threshold = 10;
|
||||
y_threshold = 10;
|
||||
}
|
||||
|
||||
/* Find first cascade position that's not used. */
|
||||
|
||||
window_width = window->frame ? window->frame->rect.width : window->rect.width;
|
||||
window_height = window->frame ? window->frame->rect.height : window->rect.height;
|
||||
|
||||
cascade_stage = 0;
|
||||
tmp = sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
@@ -140,7 +155,7 @@ find_next_cascade (MetaWindow *window,
|
||||
wx = w->rect.x;
|
||||
wy = w->rect.y;
|
||||
}
|
||||
|
||||
|
||||
if (ABS (wx - cascade_x) < x_threshold &&
|
||||
ABS (wy - cascade_y) < y_threshold)
|
||||
{
|
||||
@@ -151,16 +166,49 @@ find_next_cascade (MetaWindow *window,
|
||||
meta_window_get_position (w, &wx, &wy);
|
||||
cascade_x = wx;
|
||||
cascade_y = wy;
|
||||
|
||||
/* If we go off the screen, start over with a new cascade */
|
||||
if (((cascade_x + window_width) >
|
||||
(work_area.x + work_area.width)) ||
|
||||
((cascade_y + window_height) >
|
||||
(work_area.y + work_area.height)))
|
||||
{
|
||||
cascade_x = MAX (0, work_area.x);
|
||||
cascade_y = MAX (0, work_area.y);
|
||||
|
||||
#define CASCADE_INTERVAL 50 /* space between top-left corners of cascades */
|
||||
cascade_stage += 1;
|
||||
cascade_x += CASCADE_INTERVAL * cascade_stage;
|
||||
|
||||
/* start over with a new cascade translated to the right, unless
|
||||
* we are out of space
|
||||
*/
|
||||
if ((cascade_x + window_width) <
|
||||
(work_area.x + work_area.width))
|
||||
{
|
||||
tmp = sorted;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* All out of space, this cascade_x won't work */
|
||||
cascade_x = MAX (0, work_area.x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
goto found; /* no window at this cascade point. */
|
||||
{
|
||||
/* Keep searching for a further-down-the-diagonal window. */
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* cascade_x and cascade_y will match the last window in the list. */
|
||||
/* cascade_x and cascade_y will match the last window in the list
|
||||
* that was "in the way" (in the approximate cascade diagonal)
|
||||
*/
|
||||
|
||||
found:
|
||||
g_list_free (sorted);
|
||||
|
||||
/* Convert coords to position of window, not position of frame. */
|
||||
@@ -176,6 +224,204 @@ find_next_cascade (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
intcmp (const void* a, const void* b)
|
||||
{
|
||||
const int *ai = a;
|
||||
const int *bi = b;
|
||||
|
||||
if (*ai < *bi)
|
||||
return -1;
|
||||
else if (*ai > *bi)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
window_get_edges (MetaWindow *w,
|
||||
int *left,
|
||||
int *right,
|
||||
int *top,
|
||||
int *bottom)
|
||||
{
|
||||
int left_edge;
|
||||
int right_edge;
|
||||
int top_edge;
|
||||
int bottom_edge;
|
||||
MetaRectangle rect;
|
||||
|
||||
meta_window_get_outer_rect (w, &rect);
|
||||
|
||||
left_edge = rect.x;
|
||||
right_edge = rect.x + rect.width;
|
||||
top_edge = rect.y;
|
||||
bottom_edge = rect.y + rect.height;
|
||||
|
||||
if (left)
|
||||
*left = left_edge;
|
||||
if (right)
|
||||
*right = right_edge;
|
||||
if (top)
|
||||
*top = top_edge;
|
||||
if (bottom)
|
||||
*bottom = bottom_edge;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rectangle_overlaps_some_window (MetaRectangle *rect,
|
||||
GList *windows)
|
||||
{
|
||||
GList *tmp;
|
||||
MetaRectangle dest;
|
||||
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *other = tmp->data;
|
||||
MetaRectangle other_rect;
|
||||
|
||||
switch (other->type)
|
||||
{
|
||||
case META_WINDOW_DOCK:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
case META_WINDOW_DESKTOP:
|
||||
case META_WINDOW_DIALOG:
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
break;
|
||||
|
||||
case META_WINDOW_NORMAL:
|
||||
case META_WINDOW_UTILITY:
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_MENU:
|
||||
meta_window_get_outer_rect (other, &other_rect);
|
||||
|
||||
if (meta_rectangle_intersect (rect, &other_rect, &dest))
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gint
|
||||
leftmost_cmp (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
MetaWindow *aw = (gpointer) a;
|
||||
MetaWindow *bw = (gpointer) b;
|
||||
int ax, bx;
|
||||
|
||||
/* we're interested in the frame position for cascading,
|
||||
* not meta_window_get_position()
|
||||
*/
|
||||
if (aw->frame)
|
||||
ax = aw->frame->rect.x;
|
||||
else
|
||||
ax = aw->rect.x;
|
||||
|
||||
if (bw->frame)
|
||||
bx = bw->frame->rect.x;
|
||||
else
|
||||
bx = bw->rect.x;
|
||||
|
||||
if (ax < bx)
|
||||
return -1;
|
||||
else if (ax > bx)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
topmost_cmp (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
MetaWindow *aw = (gpointer) a;
|
||||
MetaWindow *bw = (gpointer) b;
|
||||
int ay, by;
|
||||
|
||||
/* we're interested in the frame position for cascading,
|
||||
* not meta_window_get_position()
|
||||
*/
|
||||
if (aw->frame)
|
||||
ay = aw->frame->rect.y;
|
||||
else
|
||||
ay = aw->rect.y;
|
||||
|
||||
if (bw->frame)
|
||||
by = bw->frame->rect.y;
|
||||
else
|
||||
by = bw->rect.y;
|
||||
|
||||
if (ay < by)
|
||||
return -1;
|
||||
else if (ay > by)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fit_rect_in_xinerama (MetaScreen *screen,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
int i;
|
||||
int best_index;
|
||||
int best_overlap;
|
||||
const MetaXineramaScreenInfo *xsi;
|
||||
|
||||
/* Find xinerama with best fit, then
|
||||
* shift rect to be entirely within it.
|
||||
*/
|
||||
best_overlap = -1;
|
||||
best_index = -1;
|
||||
|
||||
i = 0;
|
||||
while (i < screen->n_xinerama_infos)
|
||||
{
|
||||
MetaRectangle xinerama_rect;
|
||||
MetaRectangle intersect;
|
||||
int overlap;
|
||||
|
||||
xsi = &screen->xinerama_infos[i];
|
||||
|
||||
xinerama_rect.x = xsi->x_origin;
|
||||
xinerama_rect.y = xsi->y_origin;
|
||||
xinerama_rect.width = xsi->width;
|
||||
xinerama_rect.height = xsi->height;
|
||||
|
||||
if (meta_rectangle_intersect (rect, &xinerama_rect, &intersect))
|
||||
overlap = intersect.width * intersect.height;
|
||||
else
|
||||
overlap = 0;
|
||||
|
||||
if (overlap > best_overlap)
|
||||
{
|
||||
best_index = i;
|
||||
best_overlap = overlap;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
/* some overlap had to be better than -1 */
|
||||
g_assert (best_index >= 0);
|
||||
|
||||
xsi = &screen->xinerama_infos[best_index];
|
||||
|
||||
if (rect->x < xsi->x_origin)
|
||||
rect->x = xsi->x_origin;
|
||||
if (rect->y < xsi->y_origin)
|
||||
rect->y = xsi->y_origin;
|
||||
|
||||
/* Now return whether we are entirely within the xinerama screen */
|
||||
return
|
||||
((rect->x + rect->width) < (xsi->x_origin + xsi->width)) &&
|
||||
((rect->y + rect->height) < (xsi->y_origin + xsi->height));
|
||||
}
|
||||
|
||||
/* Find the leftmost, then topmost, empty area on the workspace
|
||||
* that can contain the new window.
|
||||
*
|
||||
@@ -194,18 +440,217 @@ find_first_fit (MetaWindow *window,
|
||||
int *new_x,
|
||||
int *new_y)
|
||||
{
|
||||
/* FIXME */
|
||||
/* This algorithm is limited - it just brute-force tries
|
||||
* to fit the window in a small number of locations that are aligned
|
||||
* with existing windows. It tries to place the window on
|
||||
* the bottom of each existing window, and then to the right
|
||||
* of each existing window, aligned with the left/top of the
|
||||
* existing window in each of those cases.
|
||||
*/
|
||||
|
||||
int retval;
|
||||
GList *sorted;
|
||||
GList *tmp;
|
||||
MetaRectangle rect;
|
||||
int i;
|
||||
|
||||
retval = FALSE;
|
||||
sorted = NULL;
|
||||
|
||||
rect.width = window->rect.width;
|
||||
rect.height = window->rect.height;
|
||||
|
||||
if (fgeom)
|
||||
{
|
||||
rect.width += fgeom->left_width + fgeom->right_width;
|
||||
rect.height += fgeom->top_height + fgeom->bottom_height;
|
||||
}
|
||||
|
||||
/* Try origin of first Xinerama */
|
||||
rect.x = window->screen->xinerama_infos[0].x_origin;
|
||||
rect.y = window->screen->xinerama_infos[0].y_origin;
|
||||
|
||||
if (fit_rect_in_xinerama (window->screen, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, windows))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (fgeom)
|
||||
{
|
||||
*new_x += fgeom->left_width;
|
||||
*new_y += fgeom->top_height;
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
sorted = g_list_copy (windows);
|
||||
|
||||
/* Below each window */
|
||||
sorted = g_list_sort (sorted, leftmost_cmp);
|
||||
sorted = g_list_sort (sorted, topmost_cmp);
|
||||
|
||||
tmp = sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle outer_rect;
|
||||
|
||||
meta_window_get_outer_rect (w, &outer_rect);
|
||||
|
||||
rect.x = outer_rect.x;
|
||||
rect.y = outer_rect.y + outer_rect.height;
|
||||
|
||||
if (fit_rect_in_xinerama (window->screen, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (fgeom)
|
||||
{
|
||||
*new_x += fgeom->left_width;
|
||||
*new_y += fgeom->top_height;
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* To the right of each window */
|
||||
sorted = g_list_sort (sorted, topmost_cmp);
|
||||
sorted = g_list_sort (sorted, leftmost_cmp);
|
||||
|
||||
tmp = sorted;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaRectangle outer_rect;
|
||||
|
||||
meta_window_get_outer_rect (w, &outer_rect);
|
||||
|
||||
rect.x = outer_rect.x + outer_rect.width;
|
||||
rect.y = outer_rect.y;
|
||||
|
||||
if (fit_rect_in_xinerama (window->screen, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, sorted))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (fgeom)
|
||||
{
|
||||
*new_x += fgeom->left_width;
|
||||
*new_y += fgeom->top_height;
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
/* Origin of each Xinerama screen which isn't the first */
|
||||
i = 1;
|
||||
while (i < window->screen->n_xinerama_infos)
|
||||
{
|
||||
rect.x = window->screen->xinerama_infos[i].x_origin;
|
||||
rect.y = window->screen->xinerama_infos[i].y_origin;
|
||||
|
||||
if (fit_rect_in_xinerama (window->screen, &rect) &&
|
||||
!rectangle_overlaps_some_window (&rect, windows))
|
||||
{
|
||||
*new_x = rect.x;
|
||||
*new_y = rect.y;
|
||||
if (fgeom)
|
||||
{
|
||||
*new_x += fgeom->left_width;
|
||||
*new_y += fgeom->top_height;
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
out:
|
||||
g_list_free (sorted);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
constrain_placement (MetaWindow *window,
|
||||
MetaFrameGeometry *fgeom,
|
||||
int x,
|
||||
int y,
|
||||
int *new_x,
|
||||
int *new_y)
|
||||
{
|
||||
/* The purpose of this function is to apply constraints that are not
|
||||
* covered by window.c:constrain_position(), but should apply
|
||||
* whenever we are _placing_ a window regardless of placement algorithm.
|
||||
*/
|
||||
MetaRectangle work_area;
|
||||
int nw_x, nw_y;
|
||||
int offscreen_w, offscreen_h;
|
||||
MetaRectangle outer_rect;
|
||||
|
||||
meta_window_get_outer_rect (window, &outer_rect);
|
||||
|
||||
/* FIXME this is bogus because we get the current xinerama
|
||||
* for the window based on its position, but we haven't
|
||||
* placed it yet.
|
||||
*/
|
||||
meta_window_get_work_area (window, TRUE, &work_area);
|
||||
|
||||
nw_x = work_area.x;
|
||||
nw_y = work_area.y;
|
||||
if (window->frame)
|
||||
{
|
||||
nw_x += fgeom->left_width;
|
||||
nw_y += fgeom->top_height;
|
||||
}
|
||||
|
||||
/* Keep window from going off the bottom right, though we don't have
|
||||
* this constraint once the window has been placed
|
||||
*/
|
||||
offscreen_w = (outer_rect.x + outer_rect.width) - (work_area.x + work_area.width);
|
||||
if (offscreen_w > 0)
|
||||
nw_x -= offscreen_w;
|
||||
offscreen_h = (outer_rect.y + outer_rect.height) - (work_area.y + work_area.height);
|
||||
if (offscreen_h > 0)
|
||||
nw_y -= offscreen_h;
|
||||
|
||||
/* Keep window from going off left edge, though again we don't have
|
||||
* this constraint once the window has been placed.
|
||||
*/
|
||||
if (x < nw_x)
|
||||
x = nw_x;
|
||||
if (y < nw_y)
|
||||
y = nw_y;
|
||||
|
||||
*new_x = x;
|
||||
*new_y = y;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_place (MetaWindow *window,
|
||||
meta_window_place (MetaWindow *window,
|
||||
MetaFrameGeometry *fgeom,
|
||||
int x,
|
||||
int y,
|
||||
int *new_x,
|
||||
int *new_y)
|
||||
int x,
|
||||
int y,
|
||||
int *new_x,
|
||||
int *new_y)
|
||||
{
|
||||
GList *windows;
|
||||
const MetaXineramaScreenInfo *xi;
|
||||
|
||||
/* frame member variables should NEVER be used in here, only
|
||||
* MetaFrameGeometry. But remember fgeom == NULL
|
||||
@@ -214,13 +659,86 @@ meta_window_place (MetaWindow *window,
|
||||
* placement coordinates.
|
||||
*/
|
||||
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
|
||||
|
||||
/* FIXME copying Mac, when placing a dialog
|
||||
* put it at 1/5 down and horizontally centered
|
||||
*/
|
||||
windows = NULL;
|
||||
|
||||
if (window->xtransient_for != None)
|
||||
switch (window->type)
|
||||
{
|
||||
/* Run placement algorithm on these. */
|
||||
case META_WINDOW_NORMAL:
|
||||
case META_WINDOW_DIALOG:
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
break;
|
||||
|
||||
/* Assume the app knows best how to place these, no placement
|
||||
* algorithm ever (other than "leave them as-is")
|
||||
*/
|
||||
case META_WINDOW_DESKTOP:
|
||||
case META_WINDOW_DOCK:
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_MENU:
|
||||
case META_WINDOW_UTILITY:
|
||||
goto done_no_constraints;
|
||||
break;
|
||||
}
|
||||
|
||||
if (meta_prefs_get_disable_workarounds ())
|
||||
{
|
||||
switch (window->type)
|
||||
{
|
||||
/* Only accept USPosition on normal windows because the app is full
|
||||
* of shit claiming the user set -geometry for a dialog or dock
|
||||
*/
|
||||
case META_WINDOW_NORMAL:
|
||||
if (window->size_hints.flags & USPosition)
|
||||
{
|
||||
/* don't constrain with placement algorithm */
|
||||
meta_topic (META_DEBUG_PLACEMENT,
|
||||
"Honoring USPosition for %s instead of using placement algorithm\n", window->desc);
|
||||
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Ignore even USPosition on dialogs, splashscreen */
|
||||
case META_WINDOW_DIALOG:
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
break;
|
||||
|
||||
/* Assume the app knows best how to place these. */
|
||||
case META_WINDOW_DESKTOP:
|
||||
case META_WINDOW_DOCK:
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_MENU:
|
||||
case META_WINDOW_UTILITY:
|
||||
if (window->size_hints.flags & PPosition)
|
||||
{
|
||||
meta_topic (META_DEBUG_PLACEMENT,
|
||||
"Not placing non-normal non-dialog window with PPosition set\n");
|
||||
goto done_no_constraints;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* workarounds enabled */
|
||||
|
||||
if ((window->size_hints.flags & PPosition) ||
|
||||
(window->size_hints.flags & USPosition))
|
||||
{
|
||||
meta_topic (META_DEBUG_PLACEMENT,
|
||||
"Not placing window with PPosition or USPosition set\n");
|
||||
goto done_no_constraints;
|
||||
}
|
||||
}
|
||||
|
||||
if ((window->type == META_WINDOW_DIALOG ||
|
||||
window->type == META_WINDOW_MODAL_DIALOG) &&
|
||||
window->xtransient_for != None)
|
||||
{
|
||||
/* Center horizontally, at top of parent vertically */
|
||||
|
||||
@@ -242,6 +760,14 @@ meta_window_place (MetaWindow *window,
|
||||
/* center of child over center of parent */
|
||||
x -= window->rect.width / 2;
|
||||
|
||||
/* put child down 1/5 or so from the top of parent, unless
|
||||
* it makes us have more of parent showing above child than
|
||||
* below
|
||||
*/
|
||||
if (window->rect.height <= (parent->rect.height - (parent->rect.height / 5) * 2))
|
||||
y += parent->rect.height / 5;
|
||||
|
||||
/* put top of child's frame, not top of child's client */
|
||||
if (fgeom)
|
||||
y += fgeom->top_height;
|
||||
|
||||
@@ -252,6 +778,10 @@ meta_window_place (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME UTILITY with transient set should be stacked up
|
||||
* on the sides of the parent window or something.
|
||||
*/
|
||||
|
||||
if (window->type == META_WINDOW_DIALOG ||
|
||||
window->type == META_WINDOW_MODAL_DIALOG ||
|
||||
window->type == META_WINDOW_SPLASHSCREEN)
|
||||
@@ -259,15 +789,20 @@ meta_window_place (MetaWindow *window,
|
||||
/* Center on screen */
|
||||
int w, h;
|
||||
|
||||
/* I think whole screen will look nicer than workarea */
|
||||
w = window->screen->width;
|
||||
h = window->screen->height;
|
||||
/* Warning, this function is a round trip! */
|
||||
xi = meta_screen_get_current_xinerama (window->screen);
|
||||
|
||||
w = xi->width;
|
||||
h = xi->height;
|
||||
|
||||
x = (w - window->rect.width) / 2;
|
||||
y = (h - window->rect.height) / 2;
|
||||
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s on screen\n",
|
||||
window->desc);
|
||||
x += xi->x_origin;
|
||||
y += xi->y_origin;
|
||||
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s on screen %d xinerama %d\n",
|
||||
window->desc, window->screen->number, xi->number);
|
||||
|
||||
goto done;
|
||||
}
|
||||
@@ -276,7 +811,6 @@ meta_window_place (MetaWindow *window,
|
||||
* as placed window, may be shaded - if shaded we pretend it isn't
|
||||
* for placement purposes)
|
||||
*/
|
||||
windows = NULL;
|
||||
{
|
||||
GSList *all_windows;
|
||||
GSList *tmp;
|
||||
@@ -296,17 +830,25 @@ meta_window_place (MetaWindow *window,
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Warning, this is a round trip! */
|
||||
xi = meta_screen_get_current_xinerama (window->screen);
|
||||
|
||||
/* "Origin" placement algorithm */
|
||||
x = 0;
|
||||
y = 0;
|
||||
x = xi->x_origin;
|
||||
y = xi->y_origin;
|
||||
|
||||
/* Cascade */
|
||||
if (find_first_fit (window, fgeom, windows, x, y, &x, &y))
|
||||
goto done;
|
||||
|
||||
find_next_cascade (window, fgeom, windows, x, y, &x, &y);
|
||||
|
||||
g_list_free (windows);
|
||||
|
||||
done:
|
||||
g_list_free (windows);
|
||||
|
||||
constrain_placement (window, fgeom, x, y, &x, &y);
|
||||
|
||||
done_no_constraints:
|
||||
*new_x = x;
|
||||
*new_y = y;
|
||||
}
|
||||
@@ -356,50 +898,6 @@ get_windows_on_same_workspace (MetaWindow *window,
|
||||
return windows;
|
||||
}
|
||||
|
||||
static void
|
||||
window_get_edges (MetaWindow *w,
|
||||
int *left,
|
||||
int *right,
|
||||
int *top,
|
||||
int *bottom)
|
||||
{
|
||||
int left_edge;
|
||||
int right_edge;
|
||||
int top_edge;
|
||||
int bottom_edge;
|
||||
MetaRectangle rect;
|
||||
|
||||
meta_window_get_outer_rect (w, &rect);
|
||||
|
||||
left_edge = rect.x;
|
||||
right_edge = rect.x + rect.width;
|
||||
top_edge = rect.y;
|
||||
bottom_edge = rect.y + rect.height;
|
||||
|
||||
if (left)
|
||||
*left = left_edge;
|
||||
if (right)
|
||||
*right = right_edge;
|
||||
if (top)
|
||||
*top = top_edge;
|
||||
if (bottom)
|
||||
*bottom = bottom_edge;
|
||||
}
|
||||
|
||||
static int
|
||||
intcmp (const void* a, const void* b)
|
||||
{
|
||||
const int *ai = a;
|
||||
const int *bi = b;
|
||||
|
||||
if (*ai < *bi)
|
||||
return -1;
|
||||
else if (*ai > *bi)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rects_overlap_vertically (const MetaRectangle *a,
|
||||
const MetaRectangle *b)
|
||||
@@ -436,7 +934,7 @@ get_vertical_edges (MetaWindow *window,
|
||||
GSList *tmp;
|
||||
int n_windows;
|
||||
int *edges;
|
||||
int i;
|
||||
int i, j;
|
||||
int n_edges;
|
||||
MetaRectangle rect;
|
||||
MetaRectangle work_area;
|
||||
@@ -444,11 +942,11 @@ get_vertical_edges (MetaWindow *window,
|
||||
windows = get_windows_on_same_workspace (window, &n_windows);
|
||||
|
||||
i = 0;
|
||||
n_edges = n_windows * 2 + 4; /* 4 = workspace/screen edges */
|
||||
n_edges = n_windows * 2 + 4 + window->screen->n_xinerama_infos - 1; /* 4 = workspace/screen edges */
|
||||
edges = g_new (int, n_edges);
|
||||
|
||||
/* workspace/screen edges */
|
||||
meta_window_get_work_area (window, &work_area);
|
||||
meta_window_get_work_area (window, FALSE, &work_area);
|
||||
|
||||
edges[i] = work_area.x;
|
||||
++i;
|
||||
@@ -463,6 +961,13 @@ get_vertical_edges (MetaWindow *window,
|
||||
|
||||
g_assert (i == 4);
|
||||
|
||||
/* Now get the xinerama screen edges */
|
||||
for (j = 0; j < window->screen->n_xinerama_infos - 1; j++) {
|
||||
edges[i] = window->screen->xinerama_infos[j].x_origin +
|
||||
window->screen->xinerama_infos[j].width;
|
||||
++i;
|
||||
}
|
||||
|
||||
meta_window_get_outer_rect (window, &rect);
|
||||
|
||||
/* get window edges */
|
||||
@@ -502,7 +1007,7 @@ get_horizontal_edges (MetaWindow *window,
|
||||
GSList *tmp;
|
||||
int n_windows;
|
||||
int *edges;
|
||||
int i;
|
||||
int i, j;
|
||||
int n_edges;
|
||||
MetaRectangle rect;
|
||||
MetaRectangle work_area;
|
||||
@@ -510,11 +1015,11 @@ get_horizontal_edges (MetaWindow *window,
|
||||
windows = get_windows_on_same_workspace (window, &n_windows);
|
||||
|
||||
i = 0;
|
||||
n_edges = n_windows * 2 + 4; /* 4 = workspace/screen edges */
|
||||
n_edges = n_windows * 2 + 4 + window->screen->n_xinerama_infos - 1; /* 4 = workspace/screen edges */
|
||||
edges = g_new (int, n_edges);
|
||||
|
||||
/* workspace/screen edges */
|
||||
meta_window_get_work_area (window, &work_area);
|
||||
meta_window_get_work_area (window, FALSE, &work_area);
|
||||
|
||||
edges[i] = work_area.y;
|
||||
++i;
|
||||
@@ -528,6 +1033,13 @@ get_horizontal_edges (MetaWindow *window,
|
||||
++i;
|
||||
|
||||
g_assert (i == 4);
|
||||
|
||||
/* Now get the xinerama screen edges */
|
||||
for (j = 0; j < window->screen->n_xinerama_infos - 1; j++) {
|
||||
edges[i] = window->screen->xinerama_infos[j].y_origin +
|
||||
window->screen->xinerama_infos[j].height;
|
||||
++i;
|
||||
}
|
||||
|
||||
meta_window_get_outer_rect (window, &rect);
|
||||
|
||||
|
1357
src/prefs.c
1357
src/prefs.c
File diff suppressed because it is too large
Load Diff
163
src/prefs.h
163
src/prefs.h
@@ -28,12 +28,21 @@
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_PREF_MOUSE_BUTTON_MODS,
|
||||
META_PREF_FOCUS_MODE,
|
||||
META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
|
||||
META_PREF_AUTO_RAISE,
|
||||
META_PREF_AUTO_RAISE_DELAY,
|
||||
META_PREF_THEME,
|
||||
META_PREF_TITLEBAR_FONT,
|
||||
META_PREF_TITLEBAR_FONT_SIZE,
|
||||
META_PREF_NUM_WORKSPACES,
|
||||
META_PREF_APPLICATION_BASED
|
||||
META_PREF_APPLICATION_BASED,
|
||||
META_PREF_WINDOW_KEYBINDINGS,
|
||||
META_PREF_SCREEN_KEYBINDINGS,
|
||||
META_PREF_DISABLE_WORKAROUNDS,
|
||||
META_PREF_COMMANDS,
|
||||
META_PREF_BUTTON_LAYOUT,
|
||||
META_PREF_WORKSPACE_NAMES
|
||||
} MetaPreference;
|
||||
|
||||
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
|
||||
@@ -47,17 +56,163 @@ void meta_prefs_remove_listener (MetaPrefsChangedFunc func,
|
||||
void meta_prefs_init (void);
|
||||
const char* meta_preference_to_string (MetaPreference pref);
|
||||
|
||||
MetaVirtualModifier meta_prefs_get_mouse_button_mods (void);
|
||||
MetaFocusMode meta_prefs_get_focus_mode (void);
|
||||
const char* meta_prefs_get_theme (void);
|
||||
/* returns NULL if GTK default should be used */
|
||||
const PangoFontDescription* meta_prefs_get_titlebar_font (void);
|
||||
/* returns 0 if default should be used */
|
||||
int meta_prefs_get_titlebar_font_size (void);
|
||||
int meta_prefs_get_num_workspaces (void);
|
||||
gboolean meta_prefs_get_application_based (void);
|
||||
gboolean meta_prefs_get_disable_workarounds (void);
|
||||
gboolean meta_prefs_get_auto_raise (void);
|
||||
int meta_prefs_get_auto_raise_delay (void);
|
||||
|
||||
const char* meta_prefs_get_command (int i);
|
||||
|
||||
char* meta_prefs_get_gconf_key_for_command (int i);
|
||||
|
||||
void meta_prefs_get_button_layout (MetaButtonLayout *button_layout);
|
||||
MetaActionDoubleClickTitlebar meta_prefs_get_action_double_click_titlebar (void);
|
||||
|
||||
void meta_prefs_set_num_workspaces (int n_workspaces);
|
||||
|
||||
const char* meta_prefs_get_workspace_name (int i);
|
||||
void meta_prefs_change_workspace_name (int i,
|
||||
const char *name);
|
||||
|
||||
/* Screen bindings */
|
||||
#define META_KEYBINDING_WORKSPACE_1 "switch_to_workspace_1"
|
||||
#define META_KEYBINDING_WORKSPACE_2 "switch_to_workspace_2"
|
||||
#define META_KEYBINDING_WORKSPACE_3 "switch_to_workspace_3"
|
||||
#define META_KEYBINDING_WORKSPACE_4 "switch_to_workspace_4"
|
||||
#define META_KEYBINDING_WORKSPACE_5 "switch_to_workspace_5"
|
||||
#define META_KEYBINDING_WORKSPACE_6 "switch_to_workspace_6"
|
||||
#define META_KEYBINDING_WORKSPACE_7 "switch_to_workspace_7"
|
||||
#define META_KEYBINDING_WORKSPACE_8 "switch_to_workspace_8"
|
||||
#define META_KEYBINDING_WORKSPACE_9 "switch_to_workspace_9"
|
||||
#define META_KEYBINDING_WORKSPACE_10 "switch_to_workspace_10"
|
||||
#define META_KEYBINDING_WORKSPACE_11 "switch_to_workspace_11"
|
||||
#define META_KEYBINDING_WORKSPACE_12 "switch_to_workspace_12"
|
||||
#define META_KEYBINDING_WORKSPACE_LEFT "switch_to_workspace_left"
|
||||
#define META_KEYBINDING_WORKSPACE_RIGHT "switch_to_workspace_right"
|
||||
#define META_KEYBINDING_WORKSPACE_UP "switch_to_workspace_up"
|
||||
#define META_KEYBINDING_WORKSPACE_DOWN "switch_to_workspace_down"
|
||||
#define META_KEYBINDING_SWITCH_WINDOWS "switch_windows"
|
||||
#define META_KEYBINDING_SWITCH_WINDOWS_BACKWARD "switch_windows_backward"
|
||||
#define META_KEYBINDING_SWITCH_PANELS "switch_panels"
|
||||
#define META_KEYBINDING_SWITCH_PANELS_BACKWARD "switch_panels_backward"
|
||||
#define META_KEYBINDING_CYCLE_WINDOWS "cycle_windows"
|
||||
#define META_KEYBINDING_CYCLE_WINDOWS_BACKWARD "cycle_windows_backward"
|
||||
#define META_KEYBINDING_CYCLE_PANELS "cycle_panels"
|
||||
#define META_KEYBINDING_CYCLE_PANELS_BACKWARD "cycle_panels_backward"
|
||||
#define META_KEYBINDING_SHOW_DESKTOP "show_desktop"
|
||||
#define META_KEYBINDING_COMMAND_1 "run_command_1"
|
||||
#define META_KEYBINDING_COMMAND_2 "run_command_2"
|
||||
#define META_KEYBINDING_COMMAND_3 "run_command_3"
|
||||
#define META_KEYBINDING_COMMAND_4 "run_command_4"
|
||||
#define META_KEYBINDING_COMMAND_5 "run_command_5"
|
||||
#define META_KEYBINDING_COMMAND_6 "run_command_6"
|
||||
#define META_KEYBINDING_COMMAND_7 "run_command_7"
|
||||
#define META_KEYBINDING_COMMAND_8 "run_command_8"
|
||||
#define META_KEYBINDING_COMMAND_9 "run_command_9"
|
||||
#define META_KEYBINDING_COMMAND_10 "run_command_10"
|
||||
#define META_KEYBINDING_COMMAND_11 "run_command_11"
|
||||
#define META_KEYBINDING_COMMAND_12 "run_command_12"
|
||||
|
||||
/* Window bindings */
|
||||
#define META_KEYBINDING_WINDOW_MENU "activate_window_menu"
|
||||
#define META_KEYBINDING_TOGGLE_FULLSCREEN "toggle_fullscreen"
|
||||
#define META_KEYBINDING_TOGGLE_MAXIMIZE "toggle_maximized"
|
||||
#define META_KEYBINDING_MAXIMIZE "maximize"
|
||||
#define META_KEYBINDING_UNMAXIMIZE "unmaximize"
|
||||
#define META_KEYBINDING_TOGGLE_SHADE "toggle_shaded"
|
||||
#define META_KEYBINDING_MINIMIZE "minimize"
|
||||
#define META_KEYBINDING_CLOSE "close"
|
||||
#define META_KEYBINDING_BEGIN_MOVE "begin_move"
|
||||
#define META_KEYBINDING_BEGIN_RESIZE "begin_resize"
|
||||
#define META_KEYBINDING_TOGGLE_STICKY "toggle_on_all_workspaces"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_1 "move_to_workspace_1"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_2 "move_to_workspace_2"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_3 "move_to_workspace_3"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_4 "move_to_workspace_4"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_5 "move_to_workspace_5"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_6 "move_to_workspace_6"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_7 "move_to_workspace_7"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_8 "move_to_workspace_8"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_9 "move_to_workspace_9"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_10 "move_to_workspace_10"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_11 "move_to_workspace_11"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_12 "move_to_workspace_12"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_LEFT "move_to_workspace_left"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_RIGHT "move_to_workspace_right"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_UP "move_to_workspace_up"
|
||||
#define META_KEYBINDING_MOVE_WORKSPACE_DOWN "move_to_workspace_down"
|
||||
#define META_KEYBINDING_RAISE_OR_LOWER "raise_or_lower"
|
||||
#define META_KEYBINDING_RAISE "raise"
|
||||
#define META_KEYBINDING_LOWER "lower"
|
||||
#define META_KEYBINDING_MAXIMIZE_VERTICALLY "maximize_vertically"
|
||||
#define META_KEYBINDING_MAXIMIZE_HORIZONTALLY "maximize_horizontally"
|
||||
|
||||
typedef enum _MetaKeyBindingAction
|
||||
{
|
||||
META_KEYBINDING_ACTION_NONE = -1,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_1,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_2,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_3,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_4,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_5,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_6,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_7,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_8,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_9,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_10,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_11,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_12,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_LEFT,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_RIGHT,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_UP,
|
||||
META_KEYBINDING_ACTION_WORKSPACE_DOWN,
|
||||
META_KEYBINDING_ACTION_SWITCH_WINDOWS,
|
||||
META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD,
|
||||
META_KEYBINDING_ACTION_SWITCH_PANELS,
|
||||
META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD,
|
||||
META_KEYBINDING_ACTION_CYCLE_WINDOWS,
|
||||
META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD,
|
||||
META_KEYBINDING_ACTION_CYCLE_PANELS,
|
||||
META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
|
||||
META_KEYBINDING_ACTION_SHOW_DESKTOP,
|
||||
META_KEYBINDING_ACTION_COMMAND_1,
|
||||
META_KEYBINDING_ACTION_COMMAND_2,
|
||||
META_KEYBINDING_ACTION_COMMAND_3,
|
||||
META_KEYBINDING_ACTION_COMMAND_4,
|
||||
META_KEYBINDING_ACTION_COMMAND_5,
|
||||
META_KEYBINDING_ACTION_COMMAND_6,
|
||||
META_KEYBINDING_ACTION_COMMAND_7,
|
||||
META_KEYBINDING_ACTION_COMMAND_8,
|
||||
META_KEYBINDING_ACTION_COMMAND_9,
|
||||
META_KEYBINDING_ACTION_COMMAND_10,
|
||||
META_KEYBINDING_ACTION_COMMAND_11,
|
||||
META_KEYBINDING_ACTION_COMMAND_12,
|
||||
} MetaKeyBindingAction;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
unsigned int keysym;
|
||||
MetaVirtualModifier modifiers;
|
||||
} MetaKeyPref;
|
||||
|
||||
void meta_prefs_get_screen_bindings (const MetaKeyPref **bindings,
|
||||
int *n_bindings);
|
||||
void meta_prefs_get_window_bindings (const MetaKeyPref **bindings,
|
||||
int *n_bindings);
|
||||
|
||||
MetaKeyBindingAction meta_prefs_get_keybinding_action (const char *name);
|
||||
|
||||
void meta_prefs_get_window_binding (const char *name,
|
||||
unsigned int *keysym,
|
||||
MetaVirtualModifier *modifiers);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@@ -79,8 +79,24 @@ meta_preview_class_init (MetaPreviewClass *class)
|
||||
static void
|
||||
meta_preview_init (MetaPreview *preview)
|
||||
{
|
||||
int i;
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (preview, GTK_NO_WINDOW);
|
||||
|
||||
i = 0;
|
||||
while (i < MAX_BUTTONS_PER_CORNER)
|
||||
{
|
||||
preview->button_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
|
||||
preview->button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
|
||||
++i;
|
||||
}
|
||||
|
||||
preview->button_layout.left_buttons[0] = META_BUTTON_FUNCTION_MENU;
|
||||
|
||||
preview->button_layout.right_buttons[0] = META_BUTTON_FUNCTION_MINIMIZE;
|
||||
preview->button_layout.right_buttons[1] = META_BUTTON_FUNCTION_MAXIMIZE;
|
||||
preview->button_layout.right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
|
||||
|
||||
preview->type = META_FRAME_TYPE_NORMAL;
|
||||
preview->flags =
|
||||
META_FRAME_ALLOWS_DELETE |
|
||||
@@ -143,7 +159,7 @@ ensure_info (MetaPreview *preview)
|
||||
preview->layout = gtk_widget_create_pango_layout (widget,
|
||||
preview->title);
|
||||
|
||||
font_desc = meta_gtk_widget_get_font_desc (widget, scale);
|
||||
font_desc = meta_gtk_widget_get_font_desc (widget, scale, NULL);
|
||||
|
||||
preview->text_height =
|
||||
meta_pango_font_desc_get_text_height (font_desc,
|
||||
@@ -218,7 +234,7 @@ meta_preview_expose (GtkWidget *widget,
|
||||
if (client_width < 0)
|
||||
client_width = 1;
|
||||
if (client_height < 0)
|
||||
client_height = 1;
|
||||
client_height = 1;
|
||||
|
||||
if (preview->theme)
|
||||
{
|
||||
@@ -235,6 +251,7 @@ meta_preview_expose (GtkWidget *widget,
|
||||
client_width, client_height,
|
||||
preview->layout,
|
||||
preview->text_height,
|
||||
&preview->button_layout,
|
||||
button_states,
|
||||
meta_preview_get_mini_icon (),
|
||||
meta_preview_get_icon ());
|
||||
@@ -267,6 +284,13 @@ meta_preview_size_request (GtkWidget *widget,
|
||||
req->width += child_requisition.width;
|
||||
req->height += child_requisition.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
#define NO_CHILD_WIDTH 80
|
||||
#define NO_CHILD_HEIGHT 20
|
||||
req->width += NO_CHILD_WIDTH;
|
||||
req->height += NO_CHILD_HEIGHT;
|
||||
}
|
||||
|
||||
req->width += GTK_CONTAINER (widget)->border_width * 2;
|
||||
req->height += GTK_CONTAINER (widget)->border_width * 2;
|
||||
@@ -369,6 +393,17 @@ meta_preview_set_frame_flags (MetaPreview *preview,
|
||||
gtk_widget_queue_resize (GTK_WIDGET (preview));
|
||||
}
|
||||
|
||||
void
|
||||
meta_preview_set_button_layout (MetaPreview *preview,
|
||||
const MetaButtonLayout *button_layout)
|
||||
{
|
||||
g_return_if_fail (META_IS_PREVIEW (preview));
|
||||
|
||||
preview->button_layout = *button_layout;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (preview));
|
||||
}
|
||||
|
||||
#include "inlinepixbufs.h"
|
||||
|
||||
GdkPixbuf*
|
||||
|
@@ -52,6 +52,7 @@ struct _MetaPreview
|
||||
int top_height;
|
||||
int bottom_height;
|
||||
|
||||
MetaButtonLayout button_layout;
|
||||
};
|
||||
|
||||
struct _MetaPreviewClass
|
||||
@@ -63,14 +64,17 @@ struct _MetaPreviewClass
|
||||
GtkType meta_preview_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget* meta_preview_new (void);
|
||||
|
||||
void meta_preview_set_theme (MetaPreview *preview,
|
||||
MetaTheme *theme);
|
||||
void meta_preview_set_title (MetaPreview *preview,
|
||||
const char *title);
|
||||
void meta_preview_set_frame_type (MetaPreview *preview,
|
||||
MetaFrameType type);
|
||||
void meta_preview_set_frame_flags (MetaPreview *preview,
|
||||
MetaFrameFlags flags);
|
||||
void meta_preview_set_theme (MetaPreview *preview,
|
||||
MetaTheme *theme);
|
||||
void meta_preview_set_title (MetaPreview *preview,
|
||||
const char *title);
|
||||
void meta_preview_set_frame_type (MetaPreview *preview,
|
||||
MetaFrameType type);
|
||||
void meta_preview_set_frame_flags (MetaPreview *preview,
|
||||
MetaFrameFlags flags);
|
||||
void meta_preview_set_button_layout (MetaPreview *preview,
|
||||
const MetaButtonLayout *button_layout);
|
||||
|
||||
|
||||
GdkPixbuf* meta_preview_get_icon (void);
|
||||
GdkPixbuf* meta_preview_get_mini_icon (void);
|
||||
|
@@ -26,23 +26,17 @@
|
||||
#include <gtk/gtklabel.h>
|
||||
#include <gtk/gtkframe.h>
|
||||
#include <gtk/gtkmain.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
struct _MetaResizePopup
|
||||
{
|
||||
GtkWidget *size_window;
|
||||
GtkWidget *size_label;
|
||||
|
||||
GSList *vertical_tick_windows;
|
||||
GSList *horizontal_tick_windows;
|
||||
|
||||
GtkWidget *vertical_size_window;
|
||||
GtkWidget *horizontal_size_window;
|
||||
Display *display;
|
||||
int screen_number;
|
||||
|
||||
int vertical_size;
|
||||
int horizontal_size;
|
||||
|
||||
gboolean need_vertical_feedback;
|
||||
gboolean need_horizontal_feedback;
|
||||
|
||||
gboolean showing;
|
||||
|
||||
@@ -64,51 +58,20 @@ struct _MetaResizePopup
|
||||
};
|
||||
|
||||
MetaResizePopup*
|
||||
meta_ui_resize_popup_new (void)
|
||||
meta_ui_resize_popup_new (Display *display,
|
||||
int screen_number)
|
||||
{
|
||||
MetaResizePopup *popup;
|
||||
|
||||
popup = g_new0 (MetaResizePopup, 1);
|
||||
|
||||
popup->resize_gravity = -1;
|
||||
popup->display = display;
|
||||
popup->screen_number = screen_number;
|
||||
|
||||
return popup;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_tick_labels (MetaResizePopup *popup)
|
||||
{
|
||||
if (popup->vertical_size_window)
|
||||
{
|
||||
gtk_widget_destroy (popup->vertical_size_window);
|
||||
popup->vertical_size_window = NULL;
|
||||
}
|
||||
|
||||
if (popup->horizontal_size_window)
|
||||
{
|
||||
gtk_widget_destroy (popup->horizontal_size_window);
|
||||
popup->horizontal_size_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_tick_windows (MetaResizePopup *popup)
|
||||
{
|
||||
g_slist_foreach (popup->vertical_tick_windows,
|
||||
(GFunc) gtk_widget_destroy,
|
||||
NULL);
|
||||
|
||||
g_slist_free (popup->vertical_tick_windows);
|
||||
popup->vertical_tick_windows = NULL;
|
||||
|
||||
g_slist_foreach (popup->horizontal_tick_windows,
|
||||
(GFunc) gtk_widget_destroy,
|
||||
NULL);
|
||||
|
||||
g_slist_free (popup->horizontal_tick_windows);
|
||||
popup->horizontal_tick_windows = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_resize_popup_free (MetaResizePopup *popup)
|
||||
{
|
||||
@@ -116,9 +79,6 @@ meta_ui_resize_popup_free (MetaResizePopup *popup)
|
||||
|
||||
if (popup->size_window)
|
||||
gtk_widget_destroy (popup->size_window);
|
||||
|
||||
clear_tick_windows (popup);
|
||||
clear_tick_labels (popup);
|
||||
|
||||
g_free (popup);
|
||||
}
|
||||
@@ -130,12 +90,14 @@ ensure_size_window (MetaResizePopup *popup)
|
||||
|
||||
if (popup->size_window)
|
||||
return;
|
||||
|
||||
if (!(popup->need_vertical_feedback || popup->need_horizontal_feedback))
|
||||
return;
|
||||
|
||||
popup->size_window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
|
||||
#ifdef HAVE_GTK_MULTIHEAD
|
||||
gtk_window_set_screen (GTK_WINDOW (popup->size_window),
|
||||
gdk_display_get_screen (gdk_x11_lookup_xdisplay (popup->display),
|
||||
popup->screen_number));
|
||||
#endif
|
||||
|
||||
/* never shrink the size window */
|
||||
gtk_window_set_resizable (GTK_WINDOW (popup->size_window),
|
||||
TRUE);
|
||||
@@ -159,9 +121,6 @@ update_size_window (MetaResizePopup *popup)
|
||||
char *str;
|
||||
int x, y;
|
||||
int width, height;
|
||||
|
||||
if (!(popup->need_vertical_feedback || popup->need_horizontal_feedback))
|
||||
return;
|
||||
|
||||
g_return_if_fail (popup->size_window != NULL);
|
||||
|
||||
@@ -199,19 +158,6 @@ sync_showing (MetaResizePopup *popup)
|
||||
{
|
||||
if (popup->size_window)
|
||||
gtk_widget_show (popup->size_window);
|
||||
|
||||
if (popup->vertical_size_window)
|
||||
gtk_widget_show (popup->vertical_size_window);
|
||||
|
||||
if (popup->horizontal_size_window)
|
||||
gtk_widget_show (popup->horizontal_size_window);
|
||||
|
||||
g_slist_foreach (popup->horizontal_tick_windows,
|
||||
(GFunc) gtk_widget_show,
|
||||
NULL);
|
||||
g_slist_foreach (popup->vertical_tick_windows,
|
||||
(GFunc) gtk_widget_show,
|
||||
NULL);
|
||||
|
||||
if (popup->size_window && GTK_WIDGET_REALIZED (popup->size_window))
|
||||
gdk_window_raise (popup->size_window->window);
|
||||
@@ -220,594 +166,6 @@ sync_showing (MetaResizePopup *popup)
|
||||
{
|
||||
if (popup->size_window)
|
||||
gtk_widget_hide (popup->size_window);
|
||||
|
||||
if (popup->vertical_size_window)
|
||||
gtk_widget_hide (popup->vertical_size_window);
|
||||
|
||||
if (popup->horizontal_size_window)
|
||||
gtk_widget_hide (popup->horizontal_size_window);
|
||||
|
||||
g_slist_foreach (popup->horizontal_tick_windows,
|
||||
(GFunc) gtk_widget_hide,
|
||||
NULL);
|
||||
g_slist_foreach (popup->vertical_tick_windows,
|
||||
(GFunc) gtk_widget_hide,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_size_window (const char *str)
|
||||
{
|
||||
PangoContext *context;
|
||||
PangoLayout *layout;
|
||||
GdkGC *gc;
|
||||
GdkBitmap *bitmap;
|
||||
PangoRectangle rect;
|
||||
GdkColor color;
|
||||
GtkWidget *window;
|
||||
int w, h;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_widget_set_app_paintable (window, TRUE);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window),
|
||||
FALSE);
|
||||
|
||||
context = gdk_pango_context_get ();
|
||||
|
||||
#if 0
|
||||
/* bitmaps have no meaningful cmap */
|
||||
gdk_pango_context_set_colormap (context,
|
||||
gtk_widget_get_colormap (widget));
|
||||
#endif
|
||||
pango_context_set_base_dir (context,
|
||||
gtk_widget_get_direction (window) == GTK_TEXT_DIR_LTR ?
|
||||
PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
|
||||
pango_context_set_font_description (context,
|
||||
window->style->font_desc);
|
||||
pango_context_set_language (context, gtk_get_default_language ());
|
||||
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_text (layout, str, -1);
|
||||
|
||||
g_object_unref (G_OBJECT (context));
|
||||
|
||||
pango_layout_get_pixel_extents (layout, NULL, &rect);
|
||||
|
||||
w = rect.width;
|
||||
h = rect.height;
|
||||
gtk_widget_set_size_request (window, w, h);
|
||||
|
||||
bitmap = gdk_pixmap_new (NULL, w, h, 1);
|
||||
gc = gdk_gc_new (bitmap);
|
||||
color.pixel = 0;
|
||||
gdk_gc_set_foreground (gc, &color);
|
||||
gdk_draw_rectangle (bitmap, gc, TRUE, 0, 0, w, h);
|
||||
color.pixel = 1;
|
||||
gdk_gc_set_foreground (gc, &color);
|
||||
gdk_draw_layout (bitmap, gc, 0, 0, layout);
|
||||
|
||||
gtk_widget_shape_combine_mask (window,
|
||||
bitmap, 0, 0);
|
||||
|
||||
g_object_unref (G_OBJECT (bitmap));
|
||||
g_object_unref (G_OBJECT (gc));
|
||||
g_object_unref (G_OBJECT (layout));
|
||||
|
||||
/* After setting the size */
|
||||
gtk_widget_realize (window);
|
||||
gdk_window_set_background (window->window,
|
||||
&window->style->black);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static void
|
||||
place_vertical_size_window (MetaResizePopup *popup,
|
||||
int x,
|
||||
int y,
|
||||
double align)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
return;
|
||||
|
||||
if (popup->vertical_size_window == NULL)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = g_strdup_printf ("%d", popup->vertical_size);
|
||||
|
||||
popup->vertical_size_window = create_size_window (str);
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (popup->vertical_size_window),
|
||||
&w, &h);
|
||||
|
||||
gtk_window_move (GTK_WINDOW (popup->vertical_size_window),
|
||||
x - w * align,
|
||||
y - h / 2);
|
||||
}
|
||||
|
||||
static void
|
||||
place_horizontal_size_window (MetaResizePopup *popup,
|
||||
int x,
|
||||
int y,
|
||||
double align)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
return;
|
||||
|
||||
if (popup->horizontal_size_window == NULL)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = g_strdup_printf ("%d", popup->horizontal_size);
|
||||
|
||||
popup->horizontal_size_window = create_size_window (str);
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (popup->horizontal_size_window),
|
||||
&w, &h);
|
||||
|
||||
gtk_window_move (GTK_WINDOW (popup->horizontal_size_window),
|
||||
x - w / 2,
|
||||
y - h * align);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
tick_window_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
gpointer data)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
gdk_window_get_size (widget->window, &w, &h);
|
||||
|
||||
#if 0
|
||||
gdk_draw_rectangle (widget->window,
|
||||
widget->style->white_gc,
|
||||
FALSE,
|
||||
0, 0,
|
||||
w - 1,
|
||||
h - 1);
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_tick (int w,
|
||||
int h)
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_widget_set_app_paintable (window, TRUE);
|
||||
|
||||
gtk_widget_set_size_request (window, w, h);
|
||||
|
||||
gtk_widget_realize (window);
|
||||
gdk_window_set_background (window->window,
|
||||
&window->style->black);
|
||||
|
||||
g_signal_connect (G_OBJECT (window), "expose_event",
|
||||
G_CALLBACK (tick_window_expose), NULL);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
#define TICK_WIDTH 1
|
||||
#define TICK_LENGTH 7
|
||||
|
||||
static void
|
||||
add_vertical_tick (MetaResizePopup *popup,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
/* Create a tick for the vertical resize column of
|
||||
* tick marks.
|
||||
*/
|
||||
|
||||
window = create_tick (TICK_LENGTH, TICK_WIDTH);
|
||||
|
||||
gtk_window_move (GTK_WINDOW (window),
|
||||
x, y);
|
||||
|
||||
popup->vertical_tick_windows =
|
||||
g_slist_prepend (popup->vertical_tick_windows,
|
||||
window);
|
||||
|
||||
/* create GdkWindow */
|
||||
gtk_widget_realize (window);
|
||||
|
||||
/* Be sure the size window is above it */
|
||||
if (popup->size_window && GTK_WIDGET_REALIZED (popup->size_window))
|
||||
gdk_window_raise (popup->size_window->window);
|
||||
}
|
||||
|
||||
static void
|
||||
add_horizontal_tick (MetaResizePopup *popup,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
/* Create a tick for the vertical resize column of
|
||||
* tick marks.
|
||||
*/
|
||||
|
||||
window = create_tick (TICK_WIDTH, TICK_LENGTH);
|
||||
|
||||
gtk_window_move (GTK_WINDOW (window),
|
||||
x, y);
|
||||
|
||||
popup->horizontal_tick_windows =
|
||||
g_slist_prepend (popup->horizontal_tick_windows,
|
||||
window);
|
||||
|
||||
/* create GdkWindow */
|
||||
gtk_widget_realize (window);
|
||||
|
||||
/* Be sure the size window is above it */
|
||||
if (popup->size_window && GTK_WIDGET_REALIZED (popup->size_window))
|
||||
gdk_window_raise (popup->size_window->window);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_tick_windows (MetaResizePopup *popup)
|
||||
{
|
||||
int x, y;
|
||||
int max_x, max_y;
|
||||
|
||||
if (popup->resize_gravity < 0)
|
||||
return;
|
||||
|
||||
if (popup->horizontal_tick_windows != NULL ||
|
||||
popup->vertical_tick_windows != NULL)
|
||||
return;
|
||||
|
||||
/* FIXME the current implementation sucks too much to enable. */
|
||||
return;
|
||||
|
||||
max_x = gdk_screen_width ();
|
||||
max_y = gdk_screen_height ();
|
||||
|
||||
if (popup->need_vertical_feedback)
|
||||
{
|
||||
y = popup->tick_origin_y;
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case NorthEastGravity:
|
||||
case EastGravity:
|
||||
case SouthEastGravity:
|
||||
/* Vertical tick column on the fixed East side */
|
||||
x = popup->x + popup->width + popup->frame_right;
|
||||
break;
|
||||
|
||||
case NorthWestGravity:
|
||||
case WestGravity:
|
||||
case SouthWestGravity:
|
||||
/* Vertical ticks on the fixed West side */
|
||||
x = popup->x - TICK_LENGTH - popup->frame_left;
|
||||
break;
|
||||
|
||||
case NorthGravity:
|
||||
case SouthGravity:
|
||||
case CenterGravity:
|
||||
/* Center the vertical ticks */
|
||||
x = popup->x + (popup->width - TICK_LENGTH) / 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* gcc warnings */
|
||||
x = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case SouthGravity:
|
||||
case SouthEastGravity:
|
||||
case SouthWestGravity:
|
||||
while (y > 0)
|
||||
{
|
||||
add_vertical_tick (popup, x, y);
|
||||
y -= popup->height_inc;
|
||||
}
|
||||
break;
|
||||
|
||||
case NorthGravity:
|
||||
case NorthEastGravity:
|
||||
case NorthWestGravity:
|
||||
while (y < max_y)
|
||||
{
|
||||
add_vertical_tick (popup, x, y);
|
||||
y += popup->height_inc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (popup->need_horizontal_feedback)
|
||||
{
|
||||
x = popup->tick_origin_x;
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case SouthWestGravity:
|
||||
case SouthGravity:
|
||||
case SouthEastGravity:
|
||||
/* Horizontal tick column on the fixed South side */
|
||||
y = popup->y + popup->height + popup->frame_bottom;
|
||||
break;
|
||||
|
||||
case NorthWestGravity:
|
||||
case NorthGravity:
|
||||
case NorthEastGravity:
|
||||
/* Horizontal ticks on the fixed North side */
|
||||
y = popup->y - TICK_LENGTH - popup->frame_top;
|
||||
break;
|
||||
|
||||
case EastGravity:
|
||||
case WestGravity:
|
||||
case CenterGravity:
|
||||
/* Center the horizontal ticks */
|
||||
y = popup->y + (popup->height - TICK_LENGTH) / 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* gcc warnings */
|
||||
y = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case EastGravity:
|
||||
case SouthEastGravity:
|
||||
case NorthEastGravity:
|
||||
while (x > 0)
|
||||
{
|
||||
add_horizontal_tick (popup, x, y);
|
||||
x -= popup->width_inc;
|
||||
}
|
||||
break;
|
||||
|
||||
case WestGravity:
|
||||
case SouthWestGravity:
|
||||
case NorthWestGravity:
|
||||
while (x < max_x)
|
||||
{
|
||||
add_horizontal_tick (popup, x, y);
|
||||
x += popup->width_inc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_tick_labels (MetaResizePopup *popup)
|
||||
{
|
||||
int x, y;
|
||||
int left_edge, right_edge, top_edge, bottom_edge;
|
||||
|
||||
if (popup->resize_gravity < 0)
|
||||
return;
|
||||
|
||||
left_edge = popup->x - popup->frame_left;
|
||||
right_edge = popup->x + popup->width + popup->frame_right;
|
||||
top_edge = popup->y - popup->frame_top;
|
||||
bottom_edge = popup->y + popup->height + popup->frame_bottom;
|
||||
|
||||
if (popup->need_vertical_feedback)
|
||||
{
|
||||
int size_x, size_y;
|
||||
double size_align;
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case NorthEastGravity:
|
||||
case EastGravity:
|
||||
case SouthEastGravity:
|
||||
x = popup->x + popup->width + popup->frame_right;
|
||||
size_x = x + TICK_LENGTH;
|
||||
size_align = 0.0;
|
||||
break;
|
||||
|
||||
case NorthWestGravity:
|
||||
case WestGravity:
|
||||
case SouthWestGravity:
|
||||
x = popup->x - TICK_LENGTH - popup->frame_left;
|
||||
size_x = x - TICK_LENGTH;
|
||||
size_align = 1.0;
|
||||
break;
|
||||
|
||||
case NorthGravity:
|
||||
case SouthGravity:
|
||||
case CenterGravity:
|
||||
x = popup->x + (popup->width - TICK_LENGTH) / 2;
|
||||
size_x = x - TICK_LENGTH / 2 - 1;
|
||||
size_align = 1.0;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* gcc warnings */
|
||||
x = 0;
|
||||
size_x = 0;
|
||||
size_align = 0.5;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case SouthGravity:
|
||||
case SouthEastGravity:
|
||||
case SouthWestGravity:
|
||||
size_y = top_edge;
|
||||
break;
|
||||
|
||||
case NorthGravity:
|
||||
case NorthEastGravity:
|
||||
case NorthWestGravity:
|
||||
size_y = bottom_edge;
|
||||
break;
|
||||
|
||||
default:
|
||||
size_y = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
place_vertical_size_window (popup, size_x, size_y, size_align);
|
||||
}
|
||||
|
||||
if (popup->need_horizontal_feedback)
|
||||
{
|
||||
int size_x, size_y;
|
||||
double size_align;
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case SouthWestGravity:
|
||||
case SouthGravity:
|
||||
case SouthEastGravity:
|
||||
y = popup->y + popup->height + popup->frame_bottom;
|
||||
size_y = y + TICK_LENGTH;
|
||||
size_align = 0.0;
|
||||
break;
|
||||
|
||||
case NorthWestGravity:
|
||||
case NorthGravity:
|
||||
case NorthEastGravity:
|
||||
y = popup->y - TICK_LENGTH - popup->frame_top;
|
||||
size_y = y - TICK_LENGTH;
|
||||
size_align = 1.0;
|
||||
break;
|
||||
|
||||
case EastGravity:
|
||||
case WestGravity:
|
||||
case CenterGravity:
|
||||
y = popup->y + (popup->height - TICK_LENGTH) / 2;
|
||||
size_y = y - TICK_LENGTH / 2 - 1;
|
||||
size_align = 1.0;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* gcc warnings */
|
||||
y = 0;
|
||||
size_y = 0;
|
||||
size_align = 0.5;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case WestGravity:
|
||||
case NorthWestGravity:
|
||||
case SouthWestGravity:
|
||||
size_x = right_edge;
|
||||
break;
|
||||
|
||||
case EastGravity:
|
||||
case NorthEastGravity:
|
||||
case SouthEastGravity:
|
||||
size_x = left_edge;
|
||||
break;
|
||||
|
||||
default:
|
||||
size_x = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
place_horizontal_size_window (popup, size_x, size_y, size_align);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_tick_origin (int resize_gravity,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int min_width,
|
||||
int min_height,
|
||||
int frame_left,
|
||||
int frame_right,
|
||||
int frame_top,
|
||||
int frame_bottom,
|
||||
int *origin_x,
|
||||
int *origin_y)
|
||||
{
|
||||
*origin_x = 0;
|
||||
*origin_y = 0;
|
||||
|
||||
switch (resize_gravity)
|
||||
{
|
||||
/* If client is staying fixed on the east during resize, then we
|
||||
* have to move the west edge. Which means ticks originate
|
||||
* on the east.
|
||||
*/
|
||||
case NorthEastGravity:
|
||||
case EastGravity:
|
||||
case SouthEastGravity:
|
||||
*origin_x = x + width - min_width - frame_right + TICK_WIDTH / 2;
|
||||
break;
|
||||
|
||||
case NorthWestGravity:
|
||||
case WestGravity:
|
||||
case SouthWestGravity:
|
||||
*origin_x = x + min_width + frame_left - TICK_WIDTH / 2 - 1;
|
||||
break;
|
||||
|
||||
/* centered horizontally */
|
||||
case NorthGravity:
|
||||
case SouthGravity:
|
||||
case CenterGravity:
|
||||
/* Not going to draw horizontal ticks */
|
||||
*origin_x = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (resize_gravity)
|
||||
{
|
||||
/* If client is staying fixed on the south during resize,
|
||||
* we have to move the north edge, so ticks originate on the
|
||||
* south.
|
||||
*/
|
||||
case SouthGravity:
|
||||
case SouthEastGravity:
|
||||
case SouthWestGravity:
|
||||
*origin_y = y + height - frame_top - min_height + TICK_WIDTH / 2;
|
||||
break;
|
||||
|
||||
/* staying fixed on the north */
|
||||
case NorthGravity:
|
||||
case NorthEastGravity:
|
||||
case NorthWestGravity:
|
||||
*origin_y = y + min_height + frame_bottom - TICK_WIDTH / 2 - 1;
|
||||
break;
|
||||
|
||||
/* centered vertically */
|
||||
case EastGravity:
|
||||
case WestGravity:
|
||||
case CenterGravity:
|
||||
*origin_y = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,53 +188,11 @@ meta_ui_resize_popup_set (MetaResizePopup *popup,
|
||||
int frame_bottom)
|
||||
{
|
||||
gboolean need_update_size;
|
||||
gboolean need_update_ticks;
|
||||
gboolean need_update_tick_labels;
|
||||
int tick_x, tick_y;
|
||||
int display_w, display_h;
|
||||
gboolean need_vertical, need_horizontal;
|
||||
|
||||
g_return_if_fail (popup != NULL);
|
||||
|
||||
need_update_size = FALSE;
|
||||
need_update_ticks = FALSE;
|
||||
need_update_tick_labels = FALSE;
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case SouthGravity:
|
||||
case SouthEastGravity:
|
||||
case SouthWestGravity:
|
||||
case NorthGravity:
|
||||
case NorthEastGravity:
|
||||
case NorthWestGravity:
|
||||
need_vertical = TRUE;
|
||||
break;
|
||||
default:
|
||||
need_vertical = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (height_inc <= (TICK_WIDTH + 1))
|
||||
need_vertical = FALSE;
|
||||
|
||||
switch (popup->resize_gravity)
|
||||
{
|
||||
case EastGravity:
|
||||
case SouthEastGravity:
|
||||
case NorthEastGravity:
|
||||
case WestGravity:
|
||||
case SouthWestGravity:
|
||||
case NorthWestGravity:
|
||||
need_horizontal = TRUE;
|
||||
break;
|
||||
default:
|
||||
need_horizontal = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (popup->width_inc <= (TICK_WIDTH + 1))
|
||||
need_horizontal = FALSE;
|
||||
|
||||
display_w = width - base_width;
|
||||
if (width_inc > 0)
|
||||
@@ -893,33 +209,6 @@ meta_ui_resize_popup_set (MetaResizePopup *popup,
|
||||
display_w != popup->horizontal_size ||
|
||||
display_h != popup->vertical_size)
|
||||
need_update_size = TRUE;
|
||||
|
||||
get_tick_origin (resize_gravity, x, y, width, height,
|
||||
min_width, min_height,
|
||||
frame_left, frame_right,
|
||||
frame_top, frame_bottom,
|
||||
&tick_x, &tick_y);
|
||||
|
||||
if (popup->tick_origin_x != tick_x ||
|
||||
popup->tick_origin_y != tick_y ||
|
||||
popup->frame_left != frame_left ||
|
||||
popup->frame_right != frame_right ||
|
||||
popup->frame_top != frame_top ||
|
||||
popup->frame_bottom != frame_bottom)
|
||||
need_update_ticks = TRUE;
|
||||
|
||||
if (need_update_ticks ||
|
||||
display_w != popup->horizontal_size ||
|
||||
display_h != popup->vertical_size)
|
||||
need_update_tick_labels = TRUE;
|
||||
|
||||
if (need_horizontal != popup->need_horizontal_feedback ||
|
||||
need_vertical != popup->need_vertical_feedback)
|
||||
{
|
||||
need_update_size = TRUE;
|
||||
need_update_ticks = TRUE;
|
||||
need_update_tick_labels = TRUE;
|
||||
}
|
||||
|
||||
popup->resize_gravity = resize_gravity;
|
||||
popup->x = x;
|
||||
@@ -930,28 +219,12 @@ meta_ui_resize_popup_set (MetaResizePopup *popup,
|
||||
popup->min_height = min_height;
|
||||
popup->width_inc = width_inc;
|
||||
popup->height_inc = height_inc;
|
||||
popup->tick_origin_x = tick_x;
|
||||
popup->tick_origin_y = tick_y;
|
||||
popup->frame_left = frame_left;
|
||||
popup->frame_right = frame_right;
|
||||
popup->frame_top = frame_top;
|
||||
popup->frame_bottom = frame_bottom;
|
||||
popup->vertical_size = display_h;
|
||||
popup->horizontal_size = display_w;
|
||||
popup->need_vertical_feedback = need_vertical;
|
||||
popup->need_horizontal_feedback = need_horizontal;
|
||||
|
||||
if (need_update_tick_labels)
|
||||
{
|
||||
clear_tick_labels (popup);
|
||||
update_tick_labels (popup);
|
||||
}
|
||||
|
||||
if (need_update_ticks)
|
||||
{
|
||||
clear_tick_windows (popup);
|
||||
ensure_tick_windows (popup);
|
||||
}
|
||||
|
||||
if (need_update_size)
|
||||
{
|
||||
@@ -976,7 +249,6 @@ meta_ui_resize_popup_set_showing (MetaResizePopup *popup,
|
||||
if (popup->showing)
|
||||
{
|
||||
ensure_size_window (popup);
|
||||
ensure_tick_windows (popup);
|
||||
update_size_window (popup);
|
||||
}
|
||||
|
||||
|
@@ -28,7 +28,8 @@
|
||||
#include <glib.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
MetaResizePopup* meta_ui_resize_popup_new (void);
|
||||
MetaResizePopup* meta_ui_resize_popup_new (Display *display,
|
||||
int screen_number);
|
||||
void meta_ui_resize_popup_free (MetaResizePopup *popup);
|
||||
void meta_ui_resize_popup_set (MetaResizePopup *popup,
|
||||
int resize_gravity,
|
||||
|
@@ -8,10 +8,16 @@ if test -z "$CLIENT_DISPLAY"; then
|
||||
CLIENT_DISPLAY=:1
|
||||
fi
|
||||
|
||||
if test -z "$METACITY_DISPLAY"; then
|
||||
export METACITY_DISPLAY=$CLIENT_DISPLAY
|
||||
fi
|
||||
|
||||
if test -z "$SCREENS"; then
|
||||
SCREENS=1
|
||||
fi
|
||||
|
||||
MAX_SCREEN=`echo $SCREENS-1 | bc`
|
||||
|
||||
if test "$DEBUG" = none; then
|
||||
DEBUG=
|
||||
elif test -z "$DEBUG"; then
|
||||
@@ -38,21 +44,39 @@ if test -n "$DEMO_TEST"; then
|
||||
TEST_CLIENT='./tools/metacity-window-demo'
|
||||
fi
|
||||
|
||||
if test -n "$XINERAMA"; then
|
||||
XINERAMA_FLAGS='+xinerama'
|
||||
fi
|
||||
|
||||
export EF_ALLOW_MALLOC_0=1
|
||||
|
||||
if test -z "$ONLY_WM"; then
|
||||
echo "Launching Xnest"
|
||||
Xnest -ac $XNEST_DISPLAY -scrns $SCREENS -geometry 640x480 -bw 15 &
|
||||
Xnest -ac $XNEST_DISPLAY -scrns $SCREENS -geometry 640x480 -bw 15 $XINERAMA_FLAGS &
|
||||
## usleep 800000
|
||||
sleep 1
|
||||
|
||||
if test -n "$XMON_DIR"; then
|
||||
echo "Launching xmond"
|
||||
$XMON_DIR/xmonui | $XMON_DIR/xmond -server $XNEST_DISPLAY &
|
||||
$XMON_DIR/xmonui | $XMON_DIR/xmond -server localhost:$XNEST_DISPLAY &
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
if test -n "$XSCOPE_DIR"; then
|
||||
## xscope doesn't like to die when it should, it backgrounds itself
|
||||
killall -9 xscope
|
||||
killall -9 xscope
|
||||
echo "Launching xscope"
|
||||
DISPLAY= $XSCOPE_DIR/xscope -o1 -i28 > xscoped-replies.txt &
|
||||
export METACITY_DISPLAY=localhost:28
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
echo "Launching clients"
|
||||
if test -n "$TEST_CLIENT"; then
|
||||
DISPLAY=$CLIENT_DISPLAY $TEST_CLIENT &
|
||||
for I in `seq 0 $MAX_SCREEN`; do
|
||||
DISPLAY=$CLIENT_DISPLAY.$I $TEST_CLIENT &
|
||||
done
|
||||
fi
|
||||
|
||||
if test $CLIENTS != 0; then
|
||||
@@ -68,12 +92,18 @@ if test -z "$ONLY_WM"; then
|
||||
DISPLAY=$CLIENT_DISPLAY gnome-terminal --geometry 25x15 &
|
||||
done
|
||||
fi
|
||||
|
||||
if test -e ~/.Xmodmap; then
|
||||
DISPLAY=$CLIENT_DISPLAY xmodmap ~/.Xmodmap
|
||||
fi
|
||||
|
||||
usleep 50000
|
||||
|
||||
DISPLAY=$CLIENT_DISPLAY xsetroot -solid royalblue3
|
||||
for I in `seq 0 $MAX_SCREEN`; do
|
||||
DISPLAY=$CLIENT_DISPLAY.$I xsetroot -solid royalblue3
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$ONLY_SETUP"; then
|
||||
METACITY_VERBOSE=1 METACITY_DEBUG=1 METACITY_USE_LOGFILE=1 METACITY_DEBUG_BUTTON_GRABS=1 METACITY_DISPLAY=$CLIENT_DISPLAY exec libtool --mode=execute $DEBUG ./metacity $OPTIONS
|
||||
METACITY_VERBOSE=1 METACITY_USE_LOGFILE=1 METACITY_DEBUG_BUTTON_GRABS=1 exec $DEBUG ./metacity $OPTIONS
|
||||
fi
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user