Compare commits
498 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cbedfd680f | ||
![]() |
a1e2e2a13d | ||
![]() |
a53a40c43e | ||
![]() |
33489c8cb8 | ||
![]() |
c382d8f7ea | ||
![]() |
f2ccf70f8d | ||
![]() |
ff04e38326 | ||
![]() |
1123fca3f2 | ||
![]() |
33e2d15495 | ||
![]() |
b265e8099a | ||
![]() |
a2b3f9aeb0 | ||
![]() |
d19295a68e | ||
![]() |
9f5d8d1a2a | ||
![]() |
e75abacec6 | ||
![]() |
1c31e8ffc2 | ||
![]() |
1083a4c0b7 | ||
![]() |
d212be799a | ||
![]() |
84986c7695 | ||
![]() |
aa65f94c67 | ||
![]() |
dc80242e51 | ||
![]() |
f2c63e5eec | ||
![]() |
1fc91dc459 | ||
![]() |
a2e4789b3e | ||
![]() |
7d58524185 | ||
![]() |
635e20d057 | ||
![]() |
1c3f7c4088 | ||
![]() |
5c3b0cda2e | ||
![]() |
a3c6486e52 | ||
![]() |
741d2b761a | ||
![]() |
a0ffe71db3 | ||
![]() |
ecf812db83 | ||
![]() |
afd3b96e2e | ||
![]() |
b79e6c0b3e | ||
![]() |
c6f8ad24bd | ||
![]() |
d4d05e496a | ||
![]() |
0a88329526 | ||
![]() |
b4344b5ab5 | ||
![]() |
4ac836fde4 | ||
![]() |
7897448a5b | ||
![]() |
94f4011844 | ||
![]() |
3f8e6020f7 | ||
![]() |
beb65f011d | ||
![]() |
c2f894963a | ||
![]() |
dacea8edf9 | ||
![]() |
3fed2ab64d | ||
![]() |
476652da0a | ||
![]() |
35289050e4 | ||
![]() |
ed9d7f18a6 | ||
![]() |
a7d1053ff5 | ||
![]() |
97e2b4666b | ||
![]() |
7d8cc4f940 | ||
![]() |
ee2f995fc7 | ||
![]() |
7e852f8c14 | ||
![]() |
b4c1692d14 | ||
![]() |
c0858b247f | ||
![]() |
0a956f56aa | ||
![]() |
66105c6e7e | ||
![]() |
bb1ab0afd9 | ||
![]() |
0d51d9e4cf | ||
![]() |
e3789e31ef | ||
![]() |
8a6b583cdc | ||
![]() |
86b8b9051f | ||
![]() |
4c0763792d | ||
![]() |
599eb5e3e4 | ||
![]() |
31fe25aa78 | ||
![]() |
252657905f | ||
![]() |
77a5e817a5 | ||
![]() |
2521e8103d | ||
![]() |
47fcb998f5 | ||
![]() |
455c40677b | ||
![]() |
9ae8e4c006 | ||
![]() |
d514516543 | ||
![]() |
1024eae742 | ||
![]() |
dad1f01c5b | ||
![]() |
ce53f35974 | ||
![]() |
3d19e800ab | ||
![]() |
2a54baf60e | ||
![]() |
4544fe7571 | ||
![]() |
a125b0179a | ||
![]() |
6b69acdf8b | ||
![]() |
8c11a2e5a3 | ||
![]() |
693c2bc175 | ||
![]() |
8b34b4bd0b | ||
![]() |
8cce57ba44 | ||
![]() |
63f81ed027 | ||
![]() |
c9ebc0ea25 | ||
![]() |
15a214e435 | ||
![]() |
0b3327f04d | ||
![]() |
0839c100c0 | ||
![]() |
08cfdcd802 | ||
![]() |
a1bb3835cc | ||
![]() |
e590cd2b99 | ||
![]() |
77b620e50e | ||
![]() |
9bc723d256 | ||
![]() |
b9f9a230e6 | ||
![]() |
ce1ffa4624 | ||
![]() |
17aa36d343 | ||
![]() |
cc0965f9f9 | ||
![]() |
0e728d7751 | ||
![]() |
3e6cf75d73 | ||
![]() |
bbedba8b18 | ||
![]() |
c8d756dde3 | ||
![]() |
97a8dbb71e | ||
![]() |
6835804dab | ||
![]() |
1a2a374380 | ||
![]() |
2b84afc1e3 | ||
![]() |
bb3d23f7f6 | ||
![]() |
7511ea27e2 | ||
![]() |
adbe3a2312 | ||
![]() |
eda50a91df | ||
![]() |
7853bb8042 | ||
![]() |
37de1b2d25 | ||
![]() |
0c4ac0b48a | ||
![]() |
c24cf44c6a | ||
![]() |
11a8ab47fa | ||
![]() |
7feeb72721 | ||
![]() |
01447d94d1 | ||
![]() |
e267a63330 | ||
![]() |
c65a24486d | ||
![]() |
42e786b15b | ||
![]() |
7a04673dd7 | ||
![]() |
c47d2da0cb | ||
![]() |
fd12eddb5d | ||
![]() |
0b56599d28 | ||
![]() |
27de94b915 | ||
![]() |
9e31f2b1de | ||
![]() |
13ad103823 | ||
![]() |
ff5a73de49 | ||
![]() |
275a6ec63f | ||
![]() |
604da0f6ea | ||
![]() |
72a19dd448 | ||
![]() |
3a73f6b8ec | ||
![]() |
343474a570 | ||
![]() |
91d82bf8c7 | ||
![]() |
ed19060074 | ||
![]() |
f230a67b94 | ||
![]() |
849f101feb | ||
![]() |
f45083ce82 | ||
![]() |
4c143ae9af | ||
![]() |
cd1a1d5778 | ||
![]() |
e28e7a72aa | ||
![]() |
fc9488211f | ||
![]() |
28767c4d34 | ||
![]() |
c6c7b05d7b | ||
![]() |
5526e91b6e | ||
![]() |
9e123695d0 | ||
![]() |
092cc47afc | ||
![]() |
fd20059f68 | ||
![]() |
609aae684f | ||
![]() |
49940877d1 | ||
![]() |
22ae86104b | ||
![]() |
f8dd4c160b | ||
![]() |
11061a23b1 | ||
![]() |
d8b0f213b2 | ||
![]() |
e9fbe4b2c1 | ||
![]() |
edcb351107 | ||
![]() |
0c14640352 | ||
![]() |
cfa30f9876 | ||
![]() |
af60dd3634 | ||
![]() |
ccabce1b34 | ||
![]() |
9915a18810 | ||
![]() |
a78373f324 | ||
![]() |
1d7476a725 | ||
![]() |
e8e78ebfdd | ||
![]() |
b77b0a3d81 | ||
![]() |
95b260f3a9 | ||
![]() |
97a9726845 | ||
![]() |
020aea033c | ||
![]() |
0ac46316af | ||
![]() |
94d47dc25e | ||
![]() |
debf08cac0 | ||
![]() |
ce1393d2d4 | ||
![]() |
fac482c442 | ||
![]() |
ee35540b6e | ||
![]() |
f77507e825 | ||
![]() |
0021efd593 | ||
![]() |
0d955bb873 | ||
![]() |
7fa2e8d2d3 | ||
![]() |
713d94d881 | ||
![]() |
4ecf8964b8 | ||
![]() |
11d044fa6e | ||
![]() |
a2104c5404 | ||
![]() |
1abed05413 | ||
![]() |
1465895ff7 | ||
![]() |
452025e984 | ||
![]() |
d537dd93d5 | ||
![]() |
650a1e807c | ||
![]() |
67f8a33cad | ||
![]() |
ff4f096f1d | ||
![]() |
b5cb353ab5 | ||
![]() |
17a38dfbed | ||
![]() |
f773683601 | ||
![]() |
abeaf828a3 | ||
![]() |
23a8a4201a | ||
![]() |
2d409e5c09 | ||
![]() |
2d57904bf4 | ||
![]() |
8fa83e1be7 | ||
![]() |
8875e73765 | ||
![]() |
65766fcaac | ||
![]() |
4cd4010a70 | ||
![]() |
d21da5643b | ||
![]() |
ba700e6387 | ||
![]() |
bd90fd7033 | ||
![]() |
fb3d352d3a | ||
![]() |
690852e157 | ||
![]() |
aa84d21bcf | ||
![]() |
4d62977c7b | ||
![]() |
cbac2e7bbb | ||
![]() |
88ee4c5b30 | ||
![]() |
12c46c5d8b | ||
![]() |
ab7d4e0e60 | ||
![]() |
708c6162c4 | ||
![]() |
7834bba6f7 | ||
![]() |
857c8aaaa2 | ||
![]() |
1253e6c64e | ||
![]() |
b610b2ecc7 | ||
![]() |
11addbe9c8 | ||
![]() |
709ef05714 | ||
![]() |
c51767eef1 | ||
![]() |
5aab9e878f | ||
![]() |
e7751e170e | ||
![]() |
776d345bc3 | ||
![]() |
a8fc30a13f | ||
![]() |
2d57b1b470 | ||
![]() |
90f21fa5db | ||
![]() |
6638d0e507 | ||
![]() |
c6793d477a | ||
![]() |
11e01ec074 | ||
![]() |
1d827caaaf | ||
![]() |
ba4db78ed9 | ||
![]() |
a321f4c842 | ||
![]() |
b1c465eab0 | ||
![]() |
5134b05af9 | ||
![]() |
dc3a93be99 | ||
![]() |
49aabfec02 | ||
![]() |
11d0d207fd | ||
![]() |
eed3245b1b | ||
![]() |
a7bbde1699 | ||
![]() |
bacccafe3c | ||
![]() |
3a80bd47cc | ||
![]() |
152917d5e1 | ||
![]() |
c588e173f8 | ||
![]() |
c0d2ead351 | ||
![]() |
6ffe5f8343 | ||
![]() |
2a823ef3e4 | ||
![]() |
5159c3f3ca | ||
![]() |
d092924961 | ||
![]() |
e14132b826 | ||
![]() |
df36ff638e | ||
![]() |
ad1fee8233 | ||
![]() |
3883d511a9 | ||
![]() |
10803b0d25 | ||
![]() |
a570a57863 | ||
![]() |
a7590f9717 | ||
![]() |
35224ca8d4 | ||
![]() |
40563e4f84 | ||
![]() |
c30901e9be | ||
![]() |
4fc0a91b31 | ||
![]() |
576417648a | ||
![]() |
0aace5230f | ||
![]() |
8d5ba7a6d7 | ||
![]() |
f8153b84de | ||
![]() |
fac5b0c9e7 | ||
![]() |
eb06413188 | ||
![]() |
066c870271 | ||
![]() |
1a92fa788d | ||
![]() |
3a0ab1cc0c | ||
![]() |
8a7d588bb0 | ||
![]() |
4943d79d68 | ||
![]() |
5de10c34b7 | ||
![]() |
2fbe4c2388 | ||
![]() |
767cb27f78 | ||
![]() |
b8c75c3fc0 | ||
![]() |
edeadf62ef | ||
![]() |
5ac80057c4 | ||
![]() |
210e30556e | ||
![]() |
0487b4213f | ||
![]() |
8f29c14ac4 | ||
![]() |
9543d8be10 | ||
![]() |
43e0003e79 | ||
![]() |
30e63a7244 | ||
![]() |
575f520461 | ||
![]() |
df618c9e91 | ||
![]() |
ebd13a4bae | ||
![]() |
7aa54b5a23 | ||
![]() |
b20cb36f5d | ||
![]() |
86f8c1863e | ||
![]() |
19d85c8566 | ||
![]() |
4241f91a0a | ||
![]() |
05624f099a | ||
![]() |
920f4099b6 | ||
![]() |
aa26750e01 | ||
![]() |
bdb3be7084 | ||
![]() |
14987f2b21 | ||
![]() |
47af6a0bbf | ||
![]() |
1487578ff4 | ||
![]() |
5a03a5d578 | ||
![]() |
2dd137329d | ||
![]() |
db37deb589 | ||
![]() |
ec7a3c516d | ||
![]() |
988d2ffab6 | ||
![]() |
5e2c66e241 | ||
![]() |
0ccfb0d781 | ||
![]() |
01ce961c00 | ||
![]() |
7579b691df | ||
![]() |
2a14deab0c | ||
![]() |
1acefb9eac | ||
![]() |
fb45b8f45c | ||
![]() |
d59a9c2e8a | ||
![]() |
a1c3d8723d | ||
![]() |
c4bd65e97c | ||
![]() |
eac3a2d7ac | ||
![]() |
55bb584778 | ||
![]() |
4584943531 | ||
![]() |
55d2bc0e0b | ||
![]() |
c0cc2fa1b8 | ||
![]() |
c1ecbd4de1 | ||
![]() |
0fb6b8a8ff | ||
![]() |
78ba9adfed | ||
![]() |
3f642ea34f | ||
![]() |
1a3927b40c | ||
![]() |
b09d73ab68 | ||
![]() |
9311addca3 | ||
![]() |
3c76478510 | ||
![]() |
545551e2bc | ||
![]() |
d5e0a95ff1 | ||
![]() |
e811109566 | ||
![]() |
0f805bfdfb | ||
![]() |
200cd629df | ||
![]() |
e8a29c1e82 | ||
![]() |
8589e4f3d3 | ||
![]() |
948e54772d | ||
![]() |
2d4b05a71b | ||
![]() |
a6433e84f5 | ||
![]() |
083854e2de | ||
![]() |
3508c4aa87 | ||
![]() |
d04b15ee25 | ||
![]() |
d6143e4c73 | ||
![]() |
d8ffc3c187 | ||
![]() |
2af788956e | ||
![]() |
d399141d13 | ||
![]() |
f6f899f103 | ||
![]() |
5b8919a246 | ||
![]() |
fe1989979c | ||
![]() |
0895fa9331 | ||
![]() |
b90fe0c52a | ||
![]() |
ab0e22159c | ||
![]() |
6ac0afbce0 | ||
![]() |
9532527e52 | ||
![]() |
defdf9f34c | ||
![]() |
a7dce2dc4e | ||
![]() |
ea8c51f8f3 | ||
![]() |
1e66878447 | ||
![]() |
6cfbdebf6a | ||
![]() |
a4469dcc14 | ||
![]() |
ac3eac7154 | ||
![]() |
65ac9065fa | ||
![]() |
5143e6763b | ||
![]() |
5660a8e9f5 | ||
![]() |
bc2b17df0b | ||
![]() |
f9e7c95348 | ||
![]() |
c6afec4759 | ||
![]() |
eb13498fff | ||
![]() |
163057f521 | ||
![]() |
d8ff1f9873 | ||
![]() |
97b7760de8 | ||
![]() |
acca0f6946 | ||
![]() |
f3f6d67d46 | ||
![]() |
63773d5226 | ||
![]() |
4e4559fc8c | ||
![]() |
44d540d36c | ||
![]() |
c6253a6515 | ||
![]() |
65a5ec2ef3 | ||
![]() |
70e8b35944 | ||
![]() |
ddba25a674 | ||
![]() |
14e6cb6a8f | ||
![]() |
d4619150f3 | ||
![]() |
5c1a1a2dd5 | ||
![]() |
7cfa690aaf | ||
![]() |
e127898312 | ||
![]() |
f63b81c52a | ||
![]() |
1fe673703f | ||
![]() |
979298ce57 | ||
![]() |
66e727e1b2 | ||
![]() |
6925779f59 | ||
![]() |
125d7daf4a | ||
![]() |
cb1020b26d | ||
![]() |
e1945506f3 | ||
![]() |
3a798112f2 | ||
![]() |
c5dd3e5542 | ||
![]() |
2fa9cbfd9e | ||
![]() |
23af4ee93e | ||
![]() |
0317562605 | ||
![]() |
1861e0b2cc | ||
![]() |
e5974809e8 | ||
![]() |
abfae17b9a | ||
![]() |
84b1a62ad2 | ||
![]() |
b6bcaec9bc | ||
![]() |
f19ed84cc4 | ||
![]() |
6c5a946fda | ||
![]() |
c6ffc9427e | ||
![]() |
0f1e64f3b2 | ||
![]() |
1ce5ad3003 | ||
![]() |
64694955c0 | ||
![]() |
97a90d8122 | ||
![]() |
3cd2c08277 | ||
![]() |
c37a2ca1c8 | ||
![]() |
80b38210b2 | ||
![]() |
e5dffb0097 | ||
![]() |
deaa897928 | ||
![]() |
3f9758e706 | ||
![]() |
3c25c265df | ||
![]() |
a8529bd8d1 | ||
![]() |
ba03ca76c4 | ||
![]() |
71fd54ec9e | ||
![]() |
a03343827e | ||
![]() |
4fb7c642d5 | ||
![]() |
8a892d47e5 | ||
![]() |
73abacc20b | ||
![]() |
aea24279ba | ||
![]() |
5c5968e742 | ||
![]() |
3813ed9c2e | ||
![]() |
594897e9a5 | ||
![]() |
40e9f6fa2c | ||
![]() |
35afd2a8fb | ||
![]() |
d9be1d7e32 | ||
![]() |
b625ec30d9 | ||
![]() |
f5313268d7 | ||
![]() |
07dedee37b | ||
![]() |
75f3127ba5 | ||
![]() |
b13fae2556 | ||
![]() |
2e9838699b | ||
![]() |
ba9c3f41c9 | ||
![]() |
e35fae8f32 | ||
![]() |
b0d5f3bd64 | ||
![]() |
ed640bb181 | ||
![]() |
a3511ba9e2 | ||
![]() |
4c9c903648 | ||
![]() |
d12aaddc34 | ||
![]() |
28955bb449 | ||
![]() |
dcd7cae7cf | ||
![]() |
c954bb9456 | ||
![]() |
be0b298d81 | ||
![]() |
409026044b | ||
![]() |
0c311bdcf9 | ||
![]() |
e81775e63d | ||
![]() |
209d7ef613 | ||
![]() |
a6c76a85ce | ||
![]() |
265f9e5433 | ||
![]() |
b86d988b3c | ||
![]() |
c4148cec33 | ||
![]() |
aa57becc41 | ||
![]() |
7269c37c8f | ||
![]() |
3093d7e95a | ||
![]() |
4e0d8a0cbb | ||
![]() |
523151ddf0 | ||
![]() |
0a7cb94ea8 | ||
![]() |
d4b7c0e633 | ||
![]() |
3f76affbd2 | ||
![]() |
a8f8970601 | ||
![]() |
178b5ff626 | ||
![]() |
c47f7c2806 | ||
![]() |
ab6aa5463f | ||
![]() |
42387bff6f | ||
![]() |
3afd25691a | ||
![]() |
a6a963bec1 | ||
![]() |
d6ac4dc22a | ||
![]() |
0b3f45bb1b | ||
![]() |
24f2df926a | ||
![]() |
f00e8655ac | ||
![]() |
41395d9e00 | ||
![]() |
3e00bcbf9f | ||
![]() |
0b402b23f7 | ||
![]() |
691fcaeee7 | ||
![]() |
9f30910653 | ||
![]() |
41a6c2e501 | ||
![]() |
fbc7fc6645 | ||
![]() |
573dbb431e | ||
![]() |
7b2cba7a6c | ||
![]() |
91ff5617ef | ||
![]() |
f1782868f9 | ||
![]() |
66ee22c3e6 | ||
![]() |
2db1222e45 | ||
![]() |
abbd057eb9 | ||
![]() |
6da5b8ccc5 | ||
![]() |
128e2b917d | ||
![]() |
2f4173b267 | ||
![]() |
3fea1e4df5 | ||
![]() |
13d2552274 | ||
![]() |
3d0bfbb4f4 | ||
![]() |
b893e88e8b | ||
![]() |
f2be9e4381 | ||
![]() |
53b5d6d167 | ||
![]() |
92bfe34716 | ||
![]() |
5df096baf3 | ||
![]() |
45cbaa2d13 | ||
![]() |
720a17acd7 | ||
![]() |
dab00ab036 |
31
.gitignore
vendored
31
.gitignore
vendored
@@ -13,17 +13,22 @@ config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
intltool-extract.in
|
||||
intltool-merge.in
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
.deps
|
||||
src/metacity-wm.desktop
|
||||
src/mutter-wm.desktop
|
||||
src/mutter.desktop
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
.libs
|
||||
*.swp
|
||||
*.gir
|
||||
*.typelib
|
||||
tidy-enum-types.[ch]
|
||||
tidy-marshal.[ch]
|
||||
stamp-tidy-enum-types.h
|
||||
@@ -38,19 +43,18 @@ POTFILES
|
||||
50-metacity-desktop-key.xml
|
||||
50-metacity-key.xml
|
||||
inlinepixbufs.h
|
||||
libmetacity-private.pc
|
||||
metacity
|
||||
metacity-dialog
|
||||
metacity-theme-viewer
|
||||
metacity.desktop
|
||||
metacity.schemas
|
||||
libmutter-private.pc
|
||||
mutter
|
||||
mutter-theme-viewer
|
||||
mutter.desktop
|
||||
mutter.schemas
|
||||
testasyncgetprop
|
||||
testboxes
|
||||
testgradient
|
||||
metacity-grayscale
|
||||
metacity-mag
|
||||
metacity-message
|
||||
metacity-window-demo
|
||||
mutter-grayscale
|
||||
mutter-mag
|
||||
mutter-message
|
||||
mutter-window-demo
|
||||
focus-window
|
||||
test-gravity
|
||||
test-resizing
|
||||
@@ -58,3 +62,8 @@ test-size-hints
|
||||
wm-tester
|
||||
INSTALL
|
||||
mkinstalldirs
|
||||
src/mutter-enum-types.[ch]
|
||||
src/stamp-mutter-enum-types.h
|
||||
src/mutter-marshal.[ch]
|
||||
src/stamp-mutter-marshal.h
|
||||
src/mutter-plugins.pc
|
||||
|
185
configure.in
185
configure.in
@@ -1,13 +1,13 @@
|
||||
AC_PREREQ(2.50)
|
||||
|
||||
m4_define([mutter_major_version], [2])
|
||||
m4_define([mutter_minor_version], [27])
|
||||
m4_define([mutter_micro_version], [4])
|
||||
m4_define([mutter_minor_version], [91])
|
||||
m4_define([mutter_micro_version], [0])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
|
||||
m4_define([mutter_plugin_api_version], [2])
|
||||
m4_define([mutter_plugin_api_version], [3])
|
||||
|
||||
AC_INIT([mutter], [mutter_version],
|
||||
[http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
|
||||
@@ -63,68 +63,97 @@ AC_C_BIGENDIAN
|
||||
|
||||
#### Warnings
|
||||
|
||||
# Stay command-line compatible with the gnome-common configure option. Here
|
||||
# minimum/yes/maximum are the same, however.
|
||||
AC_ARG_ENABLE(compile_warnings,
|
||||
AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],[Turn on compiler warnings]),,
|
||||
enable_compile_warnings=error)
|
||||
|
||||
changequote(,)dnl
|
||||
if test "x$GCC" = "xyes"; then
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wall[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wall" ;;
|
||||
esac
|
||||
|
||||
# case " $CFLAGS " in
|
||||
# *[\ \ ]-Wshadow[\ \ ]*) ;;
|
||||
# *) CFLAGS="$CFLAGS -Wshadow" ;;
|
||||
# esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wmissing-declarations[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wmissing-prototypes[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wmissing-prototypes" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wnested-externs[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wnested-externs" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wpointer-arith[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wpointer-arith" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wcast-align[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wcast-align" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wsign-compare[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wsign-compare" ;;
|
||||
esac
|
||||
|
||||
if test "x$enable_ansi" = "xyes"; then
|
||||
if test "$enable_compile_warnings" != no ; then
|
||||
if test "x$GCC" = "xyes"; then
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-ansi[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -ansi" ;;
|
||||
*[\ \ ]-Wall[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wall" ;;
|
||||
esac
|
||||
|
||||
# case " $CFLAGS " in
|
||||
# *[\ \ ]-Wshadow[\ \ ]*) ;;
|
||||
# *) CFLAGS="$CFLAGS -Wshadow" ;;
|
||||
# esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-pedantic[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -pedantic" ;;
|
||||
*[\ \ ]-Wmissing-declarations[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wmissing-prototypes[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wmissing-prototypes" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wnested-externs[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wnested-externs" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wpointer-arith[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wpointer-arith" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wcast-align[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wcast-align" ;;
|
||||
esac
|
||||
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Wsign-compare[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Wsign-compare" ;;
|
||||
esac
|
||||
|
||||
if test "$enable_compile_warnings" = error; then
|
||||
case " $CFLAGS " in
|
||||
*[\ \ ]-Werror[\ \ ]*) ;;
|
||||
*) CFLAGS="$CFLAGS -Werror" ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
changequote([,])dnl
|
||||
|
||||
MUTTER_PC_MODULES='gtk+-2.0 >= 2.10.0 pango >= 1.2.0'
|
||||
AC_MSG_CHECKING([which gtk+ version to compile against])
|
||||
AC_ARG_WITH([gtk],
|
||||
AC_HELP_STRING([--with-gtk=2.0|3.0],
|
||||
[which gtk+ version to compile against (default: 2)]),
|
||||
[case "$with_gtk" in
|
||||
2.0|3.0) ;;
|
||||
*) AC_MSG_ERROR([invalid gtk+ version specified]);;
|
||||
esac],
|
||||
[with_gtk=2.0])
|
||||
AC_MSG_RESULT([$with_gtk])
|
||||
|
||||
case "$with_gtk" in
|
||||
2.0) GTK_API_VERSION=2.0
|
||||
GTK_MIN_VERSION=2.18
|
||||
CANBERRA_GTK=libcanberra-gtk
|
||||
;;
|
||||
3.0) GTK_API_VERSION=3.0
|
||||
GTK_MIN_VERSION=2.90
|
||||
CANBERRA_GTK=libcanberra-gtk3
|
||||
AC_DEFINE(USE_CAIRO_REGION, 1, [Use cairo_region_t instead of GdkRegion])
|
||||
;;
|
||||
esac
|
||||
|
||||
AM_CONDITIONAL(INSTALL_LIBMUTTER_PRIVATE, test "$with_gtk" = "3.0")
|
||||
|
||||
MUTTER_PC_MODULES="gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION pango >= 1.2.0"
|
||||
AC_SUBST(GTK_API_VERSION)
|
||||
|
||||
AC_ARG_ENABLE(gconf,
|
||||
AC_HELP_STRING([--disable-gconf],
|
||||
@@ -160,6 +189,11 @@ AC_ARG_WITH(introspection,
|
||||
[disable the use of GObject introspection]),,
|
||||
with_introspection=auto)
|
||||
|
||||
AC_ARG_WITH(libcanberra,
|
||||
AC_HELP_STRING([--without-libcanberra],
|
||||
[disable the use of libcanberra for playing sounds]),,
|
||||
with_libcanberra=auto)
|
||||
|
||||
AC_ARG_ENABLE(xsync,
|
||||
AC_HELP_STRING([--disable-xsync],
|
||||
[disable mutter's use of the XSync extension]),,
|
||||
@@ -176,11 +210,11 @@ AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
## here we get the flags we'll actually use
|
||||
# GOptionEntry requires glib-2.6.0
|
||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.6.0)
|
||||
# GRegex requires Glib-2.14.0
|
||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
|
||||
# gtk_window_set_icon_name requires gtk2+-2.6.0
|
||||
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-2.0 >= 2.6.0)
|
||||
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-2.0 >= 2.6.0)
|
||||
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION)
|
||||
|
||||
# Unconditionally use this dir to avoid a circular dep with gnomecc
|
||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
||||
@@ -212,6 +246,24 @@ else
|
||||
echo "Building without libstartup-notification"
|
||||
fi
|
||||
|
||||
have_libcanberra=no
|
||||
AC_MSG_CHECKING([libcanberra-gtk])
|
||||
if test x$with_libcanberra = xno ; then
|
||||
AC_MSG_RESULT([disabled])
|
||||
else
|
||||
if $PKG_CONFIG --exists $CANBERRA_GTK; then
|
||||
have_libcanberra=yes
|
||||
AC_MSG_RESULT(yes)
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES $CANBERRA_GTK"
|
||||
AC_DEFINE([HAVE_LIBCANBERRA], 1, [Building with libcanberra for playing sounds])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test x$with_libcanberra = xyes ; then
|
||||
AC_MSG_ERROR([libcanberra forced and libcanberra-gtk was not found])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
XCOMPOSITE_VERSION=0.2
|
||||
|
||||
AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION])
|
||||
@@ -226,7 +278,7 @@ else
|
||||
AC_MSG_ERROR([no. Mutter requires the Xcomposite extension to build.])
|
||||
fi
|
||||
|
||||
CLUTTER_VERSION=1.0.0
|
||||
CLUTTER_VERSION=1.2.0
|
||||
CLUTTER_PACKAGE=clutter-1.0
|
||||
AC_SUBST(CLUTTER_PACKAGE)
|
||||
if $PKG_CONFIG --atleast-version $CLUTTER_VERSION $CLUTTER_PACKAGE ; then
|
||||
@@ -251,7 +303,7 @@ else
|
||||
fi
|
||||
|
||||
if test x$with_introspection != xno; then
|
||||
PKG_CHECK_MODULES(INTROSPECTION, gobject-introspection-1.0, have_introspection=yes, have_introspection=no)
|
||||
PKG_CHECK_MODULES(INTROSPECTION, gobject-introspection-1.0 >= 0.9.5, have_introspection=yes, have_introspection=no)
|
||||
if test x$have_introspection=xyes; then
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gobject-introspection-1.0"
|
||||
AC_DEFINE(HAVE_INTROSPECTION, 1, [Define if GObject introspection is available])
|
||||
@@ -414,7 +466,7 @@ fi
|
||||
|
||||
MUTTER_LIBS="$MUTTER_LIBS $XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
|
||||
MUTTER_MESSAGE_LIBS="$MUTTER_MESSAGE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||
MUTTER_WINDOW_DEMO_LIBS="$MUTTER_WINDOW_DEMO_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||
MUTTER_WINDOW_DEMO_LIBS="$MUTTER_WINDOW_DEMO_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
|
||||
MUTTER_PROPS_LIBS="$MUTTER_PROPS_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||
|
||||
found_sm=no
|
||||
@@ -482,10 +534,8 @@ if test "x$enable_debug" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -g -O"
|
||||
fi
|
||||
|
||||
# Warnings are there for a reason
|
||||
if test "x$GCC" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -Wall -Werror -ansi"
|
||||
fi
|
||||
# For fix-meta-rectangle.py
|
||||
AM_PATH_PYTHON([2.5])
|
||||
|
||||
# Use gnome-doc-utils:
|
||||
GNOME_DOC_INIT([0.8.0])
|
||||
@@ -522,7 +572,7 @@ fi
|
||||
|
||||
dnl ==========================================================================
|
||||
echo "
|
||||
mutter-$VERSION:
|
||||
mutter-$VERSION (using gtk+-${GTK_API_VERSION}):
|
||||
|
||||
prefix: ${prefix}
|
||||
source code location: ${srcdir}
|
||||
@@ -532,6 +582,7 @@ mutter-$VERSION:
|
||||
XFree86 Xinerama: ${use_xfree_xinerama}
|
||||
Solaris Xinerama: ${use_solaris_xinerama}
|
||||
Startup notification: ${have_startup_notification}
|
||||
libcanberra: ${have_libcanberra}
|
||||
Introspection: ${have_introspection}
|
||||
Session management: ${found_sm}
|
||||
Shape extension: ${found_shape}
|
||||
|
@@ -4,6 +4,7 @@ of the theme format, and a given theme can support more than one format.
|
||||
Version 1: THEMEDIR/metacity-1/metacity-theme-1.xml
|
||||
(original metacity format)
|
||||
Version 2: THEMEDIR/metacity-1/metacity-theme-2.xml
|
||||
Version 3: THEMEDIR/metacity-1/metacity-theme-3.xml
|
||||
|
||||
The subdirectory name is "metacity-1" in all versions.
|
||||
|
||||
@@ -21,6 +22,41 @@ This document has separate sections for each format version. You may
|
||||
want to read the document in reverse order, since the base features
|
||||
are discussed under version 1.
|
||||
|
||||
New Features in Theme Format Version 3.1
|
||||
========================================
|
||||
|
||||
Additional predefined variables are added for positioning expressions:
|
||||
|
||||
frame_x_center: the X center of the entire frame, with respect to the
|
||||
piece currently being drawn.
|
||||
frame_y_center: the Y center of the entire frame, with respect to the
|
||||
piece currently being drawn.
|
||||
|
||||
The <title/> element now supports an "ellipsize_width" attribute. When
|
||||
specified, this gives a width at which to ellipsize the title. If not
|
||||
specified, the title will simply be clipped to the title area.
|
||||
|
||||
New Features in Theme Format Version 3
|
||||
======================================
|
||||
|
||||
Format version 3 has exactly one new feature; any element in the file
|
||||
can now have a version attribute:
|
||||
|
||||
version="[<|<=|=>|>] MAJOR.MINOR"
|
||||
|
||||
(< and > should be to be entity escaped as < and >). If this
|
||||
version check is not met, then the element and its children will be
|
||||
ignored. This allows having alternate sections of the theme file for
|
||||
older and newer version of the Metacity theme format.
|
||||
|
||||
When placed on the toplevel <metacity_theme> element, an unsatisfied
|
||||
version check will not just cause the contents of the file to be
|
||||
ignored, it will also cause the lookup of a theme file to proceed on
|
||||
and look for an older format 2 or format 1 file. This allows making a
|
||||
metacity-theme-3.xml file that is only used the format version 3.2 or
|
||||
newer is supported, and using metacity-theme-1.xml for older window
|
||||
managers.
|
||||
|
||||
New Features in Theme Format Version 2
|
||||
======================================
|
||||
|
||||
|
@@ -10,6 +10,7 @@ be@latin
|
||||
bg
|
||||
bn
|
||||
bn_IN
|
||||
br
|
||||
bs
|
||||
ca
|
||||
ca@valencia
|
||||
@@ -56,6 +57,7 @@ mn
|
||||
mr
|
||||
ms
|
||||
nb
|
||||
nds
|
||||
ne
|
||||
nl
|
||||
nn
|
||||
|
@@ -1,5 +1,6 @@
|
||||
# List of source files containing translatable strings.
|
||||
# Please keep this file sorted alphabetically.
|
||||
src/core/bell.c
|
||||
src/core/core.c
|
||||
src/core/delete.c
|
||||
src/core/display.c
|
||||
|
1988
po/en_GB.po
1988
po/en_GB.po
File diff suppressed because it is too large
Load Diff
336
po/eu.po
336
po/eu.po
@@ -3,14 +3,14 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER.
|
||||
#
|
||||
# Hizkuntza Politikarako Sailburuordetza <hizpol@ej-gv.es>, 2004.
|
||||
# Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>, 2004, 2005, 2006, 2008, 2009.
|
||||
# Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>, 2004, 2005, 2006, 2008, 2009, 2010.
|
||||
# Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2007.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: eu\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-09-04 11:40+0200\n"
|
||||
"PO-Revision-Date: 2009-09-04 11:56+0200\n"
|
||||
"POT-Creation-Date: 2010-03-19 17:23+0100\n"
|
||||
"PO-Revision-Date: 2010-03-19 17:27+0100\n"
|
||||
"Last-Translator: Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>\n"
|
||||
"Language-Team: Basque <itzulpena@euskalgnu.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -20,48 +20,53 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"\n"
|
||||
|
||||
#: ../src/core/bell.c:302
|
||||
msgid "Bell event"
|
||||
msgstr "Soinuaren gertaera"
|
||||
|
||||
#: ../src/core/core.c:213
|
||||
#, c-format
|
||||
msgid "Unknown window information request: %d"
|
||||
msgstr "Leihoaren informazio eskaera ezezaguna: %d"
|
||||
|
||||
#: ../src/core/delete.c:105
|
||||
#. Translators: %s is a window title
|
||||
#: ../src/core/delete.c:95
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<big><b><tt>%s</tt> is not responding.</b></big>\n"
|
||||
"\n"
|
||||
"<i>You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely.</i>"
|
||||
msgstr ""
|
||||
"<big><b><tt>%s</tt>(e)k ez du erantzuten.</b></big>\n"
|
||||
"\n"
|
||||
"<i>Aukeratu piskatean zai egotea aplikazioak jarraitzeko edo derrigortu "
|
||||
"aplikazioa erabat ixtea.</i>"
|
||||
msgid "<tt>%s</tt> is not responding."
|
||||
msgstr "<tt>%s</tt>(e)k ez du erantzuten."
|
||||
|
||||
#: ../src/core/delete.c:116
|
||||
#: ../src/core/delete.c:100
|
||||
msgid ""
|
||||
"You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely."
|
||||
msgstr ""
|
||||
"Aukeratu piskatean zai egotea aplikazioak jarraitzeko edo derrigortu "
|
||||
"aplikazioa erabat ixtea."
|
||||
|
||||
#: ../src/core/delete.c:109
|
||||
msgid "_Wait"
|
||||
msgstr "_Itxaron"
|
||||
|
||||
#: ../src/core/delete.c:116
|
||||
#: ../src/core/delete.c:109
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Behartu ixtera"
|
||||
|
||||
#: ../src/core/delete.c:217
|
||||
#: ../src/core/delete.c:207
|
||||
#, c-format
|
||||
msgid "Failed to get hostname: %s\n"
|
||||
msgstr "Huts egin du ostalari-izena hartzean: %s\n"
|
||||
|
||||
#: ../src/core/display.c:329
|
||||
#: ../src/core/display.c:362
|
||||
#, c-format
|
||||
msgid "Missing %s extension required for compositing"
|
||||
msgstr "Konposaketa lantzeko beharrezkoa den %s hedapena falta da"
|
||||
|
||||
#: ../src/core/display.c:414
|
||||
#: ../src/core/display.c:447
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Huts egin du X Window sistemaren '%s' pantaila irekitzean\n"
|
||||
|
||||
#: ../src/core/errors.c:236
|
||||
#: ../src/core/errors.c:233
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Lost connection to the display '%s';\n"
|
||||
@@ -72,12 +77,12 @@ msgstr ""
|
||||
"seguru asko X zerbitzaria itzalita egongo da edo leiho-kudeatzailea \n"
|
||||
"hilko/hondatuko zenuen.\n"
|
||||
|
||||
#: ../src/core/errors.c:243
|
||||
#: ../src/core/errors.c:240
|
||||
#, c-format
|
||||
msgid "Fatal IO error %d (%s) on display '%s'.\n"
|
||||
msgstr "S/Iko %d (%s) errore konponezina '%s' pantailan.\n"
|
||||
|
||||
#: ../src/core/keybindings.c:697
|
||||
#: ../src/core/keybindings.c:708
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Some other program is already using the key %s with modifiers %x as a "
|
||||
@@ -89,7 +94,7 @@ msgstr ""
|
||||
#. Displayed when a keybinding which is
|
||||
#. * supposed to launch a program fails.
|
||||
#.
|
||||
#: ../src/core/keybindings.c:2392
|
||||
#: ../src/core/keybindings.c:2399
|
||||
#, c-format
|
||||
msgid ""
|
||||
"There was an error running <tt>%s</tt>:\n"
|
||||
@@ -100,92 +105,96 @@ msgstr ""
|
||||
"\n"
|
||||
"%s"
|
||||
|
||||
#: ../src/core/keybindings.c:2482
|
||||
#: ../src/core/keybindings.c:2489
|
||||
#, c-format
|
||||
msgid "No command %d has been defined.\n"
|
||||
msgstr "%d komandoa ez dago definituta.\n"
|
||||
|
||||
#: ../src/core/keybindings.c:3495
|
||||
#: ../src/core/keybindings.c:3502
|
||||
#, c-format
|
||||
msgid "No terminal command has been defined.\n"
|
||||
msgstr "Ez da terminalaren komandoa definitu.\n"
|
||||
|
||||
#: ../src/core/main.c:127
|
||||
#: ../src/core/main.c:130
|
||||
#, c-format
|
||||
msgid ""
|
||||
"mutter %s\n"
|
||||
"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n"
|
||||
"Copyright (C) 2001-%d 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"
|
||||
msgstr ""
|
||||
"mutter %s\n"
|
||||
"Copyright-a (C) 2001-2008 Havoc Pennington, Red Hat, Inc., eta beste batzuk\n"
|
||||
"Copyright-a (C) 2001-%d Havoc Pennington, Red Hat, Inc., eta beste batzuk\n"
|
||||
"Hau software librea da; ikus kopiatzeko baldintzak iturburu-kodean.\n"
|
||||
"EZ du bermerik; ezta MERKATURATZEKO edo XEDE JAKIN BATERAKO EGOKITASUNAREN "
|
||||
"BERMERIK ERE.\n"
|
||||
|
||||
#: ../src/core/main.c:257
|
||||
#: ../src/core/main.c:261
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Desgaitu saio-kudeatzailearen konexioa"
|
||||
|
||||
#: ../src/core/main.c:263
|
||||
#: ../src/core/main.c:267
|
||||
msgid "Replace the running window manager with Mutter"
|
||||
msgstr "Ordeztu exekutatzen dagoen leiho-kudeatzailea Mutter-rekin"
|
||||
|
||||
#: ../src/core/main.c:269
|
||||
#: ../src/core/main.c:273
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Zehaztu saio-kudeatzailearen IDa"
|
||||
|
||||
#: ../src/core/main.c:274
|
||||
#: ../src/core/main.c:278
|
||||
msgid "X Display to use"
|
||||
msgstr "X pantaila erabiltzeko"
|
||||
|
||||
#: ../src/core/main.c:280
|
||||
#: ../src/core/main.c:284
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Hasieratu saioa babes-fitxategitik"
|
||||
|
||||
#: ../src/core/main.c:286
|
||||
#: ../src/core/main.c:290
|
||||
msgid "Print version"
|
||||
msgstr "Erakutsi bertsioa"
|
||||
|
||||
#: ../src/core/main.c:292
|
||||
#: ../src/core/main.c:296
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Egin X deiak sinkronoak izatea"
|
||||
|
||||
#: ../src/core/main.c:298
|
||||
#: ../src/core/main.c:302
|
||||
msgid "Turn compositing on"
|
||||
msgstr "Aktibatu konposaketa"
|
||||
|
||||
#: ../src/core/main.c:304
|
||||
#: ../src/core/main.c:308
|
||||
msgid "Turn compositing off"
|
||||
msgstr "Desaktibatu konposaketa"
|
||||
|
||||
#: ../src/core/main.c:310
|
||||
#: ../src/core/main.c:314
|
||||
msgid "Don't make fullscreen windows that are maximized and have no decorations"
|
||||
msgstr "Ez jarri pantaila osoan maximizatuta dauden eta dekoraziorik ez duten leihoak"
|
||||
|
||||
#: ../src/core/main.c:320
|
||||
msgid "Comma-separated list of compositor plugins"
|
||||
msgstr "Konpositoreen pluginen komaz bereiztutako zerrenda"
|
||||
|
||||
#: ../src/core/main.c:316
|
||||
#: ../src/core/main.c:326
|
||||
msgid "Whether window popup/frame should be shown when cycling windows."
|
||||
msgstr "Leihoak begiztan sartzean laster-leihoak/-markoak erakutsiko diren edo ez."
|
||||
|
||||
#: ../src/core/main.c:323
|
||||
#: ../src/core/main.c:333
|
||||
msgid "Internal argument for GObject introspection"
|
||||
msgstr "Barneko argumentua GObject objektua aztertzeko"
|
||||
|
||||
#: ../src/core/main.c:668
|
||||
#: ../src/core/main.c:663
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Huts egin du gaien direktorioa aztertzean: %s\n"
|
||||
|
||||
#: ../src/core/main.c:684
|
||||
#: ../src/core/main.c:679
|
||||
#, c-format
|
||||
msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
msgstr ""
|
||||
"Gai bat ezin izan da aurkitu. Ziurtatu %s badagoela eta ohiko gaiak "
|
||||
"dituela.\n"
|
||||
|
||||
#: ../src/core/main.c:745
|
||||
#: ../src/core/main.c:743
|
||||
#, c-format
|
||||
msgid "Failed to restart: %s\n"
|
||||
msgstr "Ezin izan da berrabiarazi: %s\n"
|
||||
@@ -201,24 +210,24 @@ msgstr "Ezin izan da berrabiarazi: %s\n"
|
||||
#. * (Empty comment follows so the translators don't see this.)
|
||||
#.
|
||||
#.
|
||||
#: ../src/core/prefs.c:522 ../src/core/prefs.c:683
|
||||
#: ../src/core/prefs.c:529 ../src/core/prefs.c:690
|
||||
#, c-format
|
||||
msgid "GConf key '%s' is set to an invalid value\n"
|
||||
msgstr "\"%s\" GConf gakoa balio baliogabean ezarrita dago\n"
|
||||
|
||||
#: ../src/core/prefs.c:609 ../src/core/prefs.c:852
|
||||
#: ../src/core/prefs.c:616 ../src/core/prefs.c:859
|
||||
#, c-format
|
||||
msgid "%d stored in GConf key %s is out of range %d to %d\n"
|
||||
msgstr "%2$s GConf gakoko %1$d balioa %3$d - %4$d barrutitik kanpo dago\n"
|
||||
|
||||
#: ../src/core/prefs.c:653 ../src/core/prefs.c:730 ../src/core/prefs.c:778
|
||||
#: ../src/core/prefs.c:842 ../src/core/prefs.c:1142 ../src/core/prefs.c:1158
|
||||
#: ../src/core/prefs.c:1175 ../src/core/prefs.c:1191
|
||||
#: ../src/core/prefs.c:660 ../src/core/prefs.c:737 ../src/core/prefs.c:785
|
||||
#: ../src/core/prefs.c:849 ../src/core/prefs.c:1149 ../src/core/prefs.c:1165
|
||||
#: ../src/core/prefs.c:1182 ../src/core/prefs.c:1198
|
||||
#, c-format
|
||||
msgid "GConf key \"%s\" is set to an invalid type\n"
|
||||
msgstr "\"%s\" GConf gakoa mota baliogabean ezarrita dago\n"
|
||||
|
||||
#: ../src/core/prefs.c:1282
|
||||
#: ../src/core/prefs.c:1289
|
||||
msgid ""
|
||||
"Workarounds for broken applications disabled. Some applications may not "
|
||||
"behave properly.\n"
|
||||
@@ -226,12 +235,12 @@ msgstr ""
|
||||
"Aplikazio hautsien konponbidea desgaituta. Aplikazio batzuk ez dira behar "
|
||||
"den bezala ibiliko.\n"
|
||||
|
||||
#: ../src/core/prefs.c:1353
|
||||
#: ../src/core/prefs.c:1360
|
||||
#, c-format
|
||||
msgid "Could not parse font description \"%s\" from GConf key %s\n"
|
||||
msgstr "Ezin izan da analizatu \"%s\" letra-tipoaren deskribapena %s GConf gakoan\n"
|
||||
|
||||
#: ../src/core/prefs.c:1415
|
||||
#: ../src/core/prefs.c:1422
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for mouse button "
|
||||
@@ -240,17 +249,17 @@ msgstr ""
|
||||
"Konfigurazioaren datu-basean aurkitutako \"%s\" balioa ez da baliozkoa sagu-"
|
||||
"botoiaren aldatzailearentzat\n"
|
||||
|
||||
#: ../src/core/prefs.c:1839
|
||||
#: ../src/core/prefs.c:1849
|
||||
#, c-format
|
||||
msgid "Error setting number of workspaces to %d: %s\n"
|
||||
msgstr "Errorea laneko %d area ezartzean: %s\n"
|
||||
|
||||
#: ../src/core/prefs.c:2023 ../src/core/prefs.c:2529
|
||||
#: ../src/core/prefs.c:2028 ../src/core/prefs.c:2531
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "%d. laneko area"
|
||||
|
||||
#: ../src/core/prefs.c:2056 ../src/core/prefs.c:2234
|
||||
#: ../src/core/prefs.c:2061 ../src/core/prefs.c:2239
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for keybinding "
|
||||
@@ -259,37 +268,37 @@ msgstr ""
|
||||
"Konfigurazioaren datu-basean aurkitutako \"%s\" balioa ez da baliozkoa \"%s"
|
||||
"\" laster-teklarentzat.\n"
|
||||
|
||||
#: ../src/core/prefs.c:2610
|
||||
#: ../src/core/prefs.c:2612
|
||||
#, c-format
|
||||
msgid "Error setting name for workspace %d to \"%s\": %s\n"
|
||||
msgstr "Errorea %d. laneko areari \"%s\" izena ezartzean: %s\n"
|
||||
|
||||
#: ../src/core/prefs.c:2808
|
||||
#: ../src/core/prefs.c:2816
|
||||
#, c-format
|
||||
msgid "Error setting compositor status: %s\n"
|
||||
msgstr "Errorea konposaketaren egoera ezartzean: %s\n"
|
||||
|
||||
#: ../src/core/prefs.c:2836
|
||||
#: ../src/core/prefs.c:2845
|
||||
#, c-format
|
||||
msgid "Error setting clutter plugin list: %s\n"
|
||||
msgstr "Errorea 'clutter' pluginen zerrenda ezartzean: %s\n"
|
||||
|
||||
#: ../src/core/prefs.c:2879
|
||||
#: ../src/core/prefs.c:2889
|
||||
#, c-format
|
||||
msgid "Error setting live hidden windows status status: %s\n"
|
||||
msgstr "Errorea ezkutuko leihoen bizitzen egoera ezartzean: %s\n"
|
||||
|
||||
#: ../src/core/prefs.c:2907
|
||||
#: ../src/core/prefs.c:2917
|
||||
#, c-format
|
||||
msgid "Error setting no tab popup status: %s\n"
|
||||
msgstr "Errorea fitxarik gabeko laster-leihoen egoera ezartzean: %s\n"
|
||||
|
||||
#: ../src/core/screen.c:561
|
||||
#: ../src/core/screen.c:577
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "'%2$s' bistaratzeko %1$d pantaila ez da baliozkoa\n"
|
||||
|
||||
#: ../src/core/screen.c:577
|
||||
#: ../src/core/screen.c:593
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -298,77 +307,71 @@ msgstr ""
|
||||
"\"%2$s\" bistaratzeko %1$d pantailak badu leiho-kudeatzailea; leiho-"
|
||||
"kudeatzaile hori ordeztu nahi baduzu, saiatu --replace aukerarekin.\n"
|
||||
|
||||
#: ../src/core/screen.c:604
|
||||
#: ../src/core/screen.c:620
|
||||
#, c-format
|
||||
msgid "Could not acquire window manager selection on screen %d display \"%s\"\n"
|
||||
msgstr ""
|
||||
"Ezin izan da eskuratu leiho-kudeatzailearen hautapena \"%2$s\" bistaratzeko %"
|
||||
"1$d pantailan\n"
|
||||
|
||||
#: ../src/core/screen.c:659
|
||||
#: ../src/core/screen.c:675
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "\"%2$s\" bistaratzeko %1$d pantailak badu leiho-kudeatzailea\n"
|
||||
|
||||
#: ../src/core/screen.c:871
|
||||
#: ../src/core/screen.c:857
|
||||
#, c-format
|
||||
msgid "Could not release screen %d on display \"%s\"\n"
|
||||
msgstr "Ezin izan da askatu \"%2$s\" bistaratzeko %1$d pantaila\n"
|
||||
|
||||
#: ../src/core/session.c:851 ../src/core/session.c:858
|
||||
#: ../src/core/session.c:856 ../src/core/session.c:863
|
||||
#, c-format
|
||||
msgid "Could not create directory '%s': %s\n"
|
||||
msgstr "Ezin izan da '%s' direktorioa sortu: %s\n"
|
||||
|
||||
#: ../src/core/session.c:868
|
||||
#: ../src/core/session.c:873
|
||||
#, c-format
|
||||
msgid "Could not open session file '%s' for writing: %s\n"
|
||||
msgstr "Ezin izan da '%s' saio-fitxategia idazteko ireki: %s\n"
|
||||
|
||||
#: ../src/core/session.c:1009
|
||||
#: ../src/core/session.c:1014
|
||||
#, c-format
|
||||
msgid "Error writing session file '%s': %s\n"
|
||||
msgstr "Errorea '%s' saio-fitxategia idaztean: %s\n"
|
||||
|
||||
#: ../src/core/session.c:1014
|
||||
#: ../src/core/session.c:1019
|
||||
#, c-format
|
||||
msgid "Error closing session file '%s': %s\n"
|
||||
msgstr "Errorea '%s' saio-fitxategia ixtean: %s\n"
|
||||
|
||||
#. oh, just give up
|
||||
#: ../src/core/session.c:1107
|
||||
#, c-format
|
||||
msgid "Failed to read saved session file %s: %s\n"
|
||||
msgstr "Huts egin du gordetako %s saio-fitxategia irakurtzean: %s\n"
|
||||
|
||||
#: ../src/core/session.c:1146
|
||||
#: ../src/core/session.c:1149
|
||||
#, c-format
|
||||
msgid "Failed to parse saved session file: %s\n"
|
||||
msgstr "Huts egin du gordetako saio-fitxategia analizatzean: %s\n"
|
||||
|
||||
#: ../src/core/session.c:1195
|
||||
#: ../src/core/session.c:1198
|
||||
#, c-format
|
||||
msgid "<mutter_session> attribute seen but we already have the session ID"
|
||||
msgstr "<mutter_session> atributua ikusi da baina dagoeneko badugu saio-IDa"
|
||||
|
||||
#: ../src/core/session.c:1208 ../src/core/session.c:1283
|
||||
#: ../src/core/session.c:1315 ../src/core/session.c:1387
|
||||
#: ../src/core/session.c:1447
|
||||
#: ../src/core/session.c:1211 ../src/core/session.c:1286
|
||||
#: ../src/core/session.c:1318 ../src/core/session.c:1390
|
||||
#: ../src/core/session.c:1450
|
||||
#, c-format
|
||||
msgid "Unknown attribute %s on <%s> element"
|
||||
msgstr "%s atributu ezezaguna <%s> elementuan"
|
||||
|
||||
#: ../src/core/session.c:1225
|
||||
#: ../src/core/session.c:1228
|
||||
#, c-format
|
||||
msgid "nested <window> tag"
|
||||
msgstr "<window> etiketa habiaratua"
|
||||
|
||||
#: ../src/core/session.c:1467
|
||||
#: ../src/core/session.c:1470
|
||||
#, c-format
|
||||
msgid "Unknown element %s"
|
||||
msgstr "%s elementu ezezaguna"
|
||||
|
||||
#: ../src/core/session.c:1818
|
||||
#: ../src/core/session.c:1822
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
@@ -376,51 +379,51 @@ msgstr ""
|
||||
"Leiho hauek ez dute onartzen "gorde uneko konfigurazioa" eta eskuz "
|
||||
"berrabiarazi beharko dituzu hurrengo saioa hasten duzunean."
|
||||
|
||||
#: ../src/core/util.c:103
|
||||
#: ../src/core/util.c:104
|
||||
#, c-format
|
||||
msgid "Failed to open debug log: %s\n"
|
||||
msgstr "Huts egin du arazketako egunkaria irekitzean: %s\n"
|
||||
|
||||
#: ../src/core/util.c:113
|
||||
#: ../src/core/util.c:114
|
||||
#, c-format
|
||||
msgid "Failed to fdopen() log file %s: %s\n"
|
||||
msgstr "Huts egin du %s egunkari-fitxategian fdopen() egitean: %s\n"
|
||||
|
||||
#: ../src/core/util.c:119
|
||||
#: ../src/core/util.c:120
|
||||
#, c-format
|
||||
msgid "Opened log file %s\n"
|
||||
msgstr "%s egunkari-fitxategia irekita\n"
|
||||
|
||||
#: ../src/core/util.c:138 ../src/tools/mutter-message.c:176
|
||||
#: ../src/core/util.c:139 ../src/tools/mutter-message.c:176
|
||||
#, c-format
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Mutter modu xehatuaren euskarririk gabe konpilatu da\n"
|
||||
|
||||
#: ../src/core/util.c:238
|
||||
#: ../src/core/util.c:239
|
||||
msgid "Window manager: "
|
||||
msgstr "Leiho-kudeatzailea: "
|
||||
|
||||
#: ../src/core/util.c:390
|
||||
#: ../src/core/util.c:391
|
||||
msgid "Bug in window manager: "
|
||||
msgstr "Akatsa leiho-kudeatzailean: "
|
||||
|
||||
#: ../src/core/util.c:423
|
||||
#: ../src/core/util.c:424
|
||||
msgid "Window manager warning: "
|
||||
msgstr "Leiho-kudeatzailearen abisua: "
|
||||
|
||||
#: ../src/core/util.c:451
|
||||
#: ../src/core/util.c:452
|
||||
msgid "Window manager error: "
|
||||
msgstr "Leiho-kudeatzailearen errorea: "
|
||||
|
||||
#. Translators: This is the title used on dialog boxes
|
||||
#. eof all-keybindings.h
|
||||
#: ../src/core/util.c:570 ../src/mutter.desktop.in.h:1
|
||||
#: ../src/core/util.c:573 ../src/mutter.desktop.in.h:1
|
||||
#: ../src/mutter-wm.desktop.in.h:1
|
||||
msgid "Mutter"
|
||||
msgstr "Mutter"
|
||||
|
||||
#. first time through
|
||||
#: ../src/core/window.c:6086
|
||||
#: ../src/core/window.c:6217
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
||||
@@ -436,7 +439,7 @@ msgstr ""
|
||||
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
||||
#. * about these apps but make them work.
|
||||
#.
|
||||
#: ../src/core/window.c:6749
|
||||
#: ../src/core/window.c:6880
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %"
|
||||
@@ -456,7 +459,7 @@ msgstr "Aplikazioak _NET_WM_PID %lu faltsua ezarri du\n"
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (%s)"
|
||||
|
||||
#: ../src/core/window-props.c:1419
|
||||
#: ../src/core/window-props.c:1435
|
||||
#, c-format
|
||||
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
|
||||
msgstr "%2$s(e)n baliogabeko WM_TRANSIENT_FOR 0x%1$lx leihoa zehaztu da.\n"
|
||||
@@ -476,12 +479,12 @@ msgstr ""
|
||||
"Gehiago ematen du aplikazioaren akatsa leiho-kudeatzailearena baino.\n"
|
||||
"Leihoak title=\"%s\" class=\"%s\" name=\"%s\" du\n"
|
||||
|
||||
#: ../src/core/xprops.c:401
|
||||
#: ../src/core/xprops.c:411
|
||||
#, c-format
|
||||
msgid "Property %s on window 0x%lx contained invalid UTF-8\n"
|
||||
msgstr "0x%2$lx leihoko %1$s propietateak UTF-8 baliogabea du\n"
|
||||
|
||||
#: ../src/core/xprops.c:484
|
||||
#: ../src/core/xprops.c:494
|
||||
#, c-format
|
||||
msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"
|
||||
msgstr ""
|
||||
@@ -804,7 +807,9 @@ msgstr "Clutter pluginak"
|
||||
msgid ""
|
||||
"Determines whether hidden windows (i.e., minimized windows and windows on "
|
||||
"other workspaces than the current one) should be kept alive."
|
||||
msgstr "Ezkutuko leihoak (adib. ikonotutakoak, beste laneko arekoak) bizirik iraungo diren edo ez zehazten du."
|
||||
msgstr ""
|
||||
"Ezkutuko leihoak (adib. ikonotutakoak, beste laneko arekoak) bizirik iraungo "
|
||||
"diren edo ez zehazten du."
|
||||
|
||||
#: ../src/mutter.schemas.in.h:3
|
||||
msgid "Live Hidden Windows"
|
||||
@@ -816,7 +821,9 @@ msgstr "Aldatzailea leihoak kudeatzeko eragiketa hedatuetan erabiltzeko"
|
||||
|
||||
#: ../src/mutter.schemas.in.h:5
|
||||
msgid "Plugins to load for the Clutter-based compositing manager."
|
||||
msgstr "Kargatuko diren puginak Clutter-en oinarritutako konposaketa-kudeatzailearentzako"
|
||||
msgstr ""
|
||||
"Kargatuko diren puginak Clutter-en oinarritutako konposaketa-"
|
||||
"kudeatzailearentzako"
|
||||
|
||||
#: ../src/mutter.schemas.in.h:6
|
||||
msgid ""
|
||||
@@ -825,8 +832,8 @@ msgid ""
|
||||
"\"Windows key\" on PC hardware. It's expected that this binding either the "
|
||||
"default or set to the empty string."
|
||||
msgstr ""
|
||||
"Gako honek \"overlay\" (gainjarria) hasieratuko du: hau leihoaren "
|
||||
"ikuspegi orokorraren eta aplikazioa abiarazteko sistemaren arteko konbinazioa da. "
|
||||
"Gako honek \"overlay\" (gainjarria) hasieratuko du: hau leihoaren ikuspegi "
|
||||
"orokorraren eta aplikazioa abiarazteko sistemaren arteko konbinazioa da. "
|
||||
"Lehenetsi gisa, PC ordenagailuko \"Windows tekla\" da. Tekla konbinazio hau "
|
||||
"lehenetsia izatea edo kate hutz gisa ezartzea da."
|
||||
|
||||
@@ -1289,7 +1296,7 @@ msgstr "Koordenatuen adierazpenak ez dirudi eragilerik edo eragigairik duenik"
|
||||
msgid "Theme contained an expression that resulted in an error: %s\n"
|
||||
msgstr "Gaiak errorea ematen duen adierazpen bat dauka: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4187
|
||||
#: ../src/ui/theme.c:4203
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
|
||||
@@ -1298,23 +1305,23 @@ msgstr ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> zehaztu behar "
|
||||
"da marko-estilo honetan"
|
||||
|
||||
#: ../src/ui/theme.c:4695 ../src/ui/theme.c:4720
|
||||
#: ../src/ui/theme.c:4711 ../src/ui/theme.c:4736
|
||||
#, c-format
|
||||
msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
|
||||
msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> falta da"
|
||||
|
||||
#: ../src/ui/theme.c:4764
|
||||
#: ../src/ui/theme.c:4780
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "Huts egin du \"%s\" gaia kargatzean: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4894 ../src/ui/theme.c:4901 ../src/ui/theme.c:4908
|
||||
#: ../src/ui/theme.c:4915 ../src/ui/theme.c:4922
|
||||
#: ../src/ui/theme.c:4910 ../src/ui/theme.c:4917 ../src/ui/theme.c:4924
|
||||
#: ../src/ui/theme.c:4931 ../src/ui/theme.c:4938
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "<%s> ez da ezarri \"%s\" gaian"
|
||||
|
||||
#: ../src/ui/theme.c:4930
|
||||
#: ../src/ui/theme.c:4946
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
@@ -1323,14 +1330,14 @@ msgstr ""
|
||||
"Ez da marko-estilorik ezarri set \"%s\" leiho-motarentzat \"%s\" gaian, "
|
||||
"gehitu <window type=\"%s\" style_set=\"whatever\"/> elementu bat"
|
||||
|
||||
#: ../src/ui/theme.c:5383 ../src/ui/theme.c:5445 ../src/ui/theme.c:5508
|
||||
#: ../src/ui/theme.c:5389 ../src/ui/theme.c:5451 ../src/ui/theme.c:5514
|
||||
#, c-format
|
||||
msgid "User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
msgstr ""
|
||||
"Erabiltzaileak definitutako konstanteak maiuskulaz hasi behar du; \"%s\" ez "
|
||||
"da maiuskulaz hasten"
|
||||
|
||||
#: ../src/ui/theme.c:5391 ../src/ui/theme.c:5453 ../src/ui/theme.c:5516
|
||||
#: ../src/ui/theme.c:5397 ../src/ui/theme.c:5459 ../src/ui/theme.c:5522
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "\"%s\" konstantea lehendik definituta dago"
|
||||
@@ -1449,10 +1456,10 @@ msgid "Window type \"%s\" has already been assigned a style set"
|
||||
msgstr "\"%s\" leiho-motak dagoeneko esleituta du estilo-multzoa"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1229 ../src/ui/theme-parser.c:1293
|
||||
#: ../src/ui/theme-parser.c:1519 ../src/ui/theme-parser.c:2732
|
||||
#: ../src/ui/theme-parser.c:2778 ../src/ui/theme-parser.c:2926
|
||||
#: ../src/ui/theme-parser.c:3118 ../src/ui/theme-parser.c:3156
|
||||
#: ../src/ui/theme-parser.c:3194 ../src/ui/theme-parser.c:3232
|
||||
#: ../src/ui/theme-parser.c:1519 ../src/ui/theme-parser.c:2740
|
||||
#: ../src/ui/theme-parser.c:2786 ../src/ui/theme-parser.c:2934
|
||||
#: ../src/ui/theme-parser.c:3126 ../src/ui/theme-parser.c:3164
|
||||
#: ../src/ui/theme-parser.c:3202 ../src/ui/theme-parser.c:3240
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed below <%s>"
|
||||
msgstr "Ez da onartzen <%s> elementua <%s>(r)en azpian jartzea"
|
||||
@@ -1481,108 +1488,108 @@ msgstr "\"%s\" aspektu-erlazioa ezezaguna da"
|
||||
msgid "Border \"%s\" is unknown"
|
||||
msgstr "\"%s\" ertza ezezaguna da"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1776
|
||||
#: ../src/ui/theme-parser.c:1784
|
||||
#, c-format
|
||||
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
|
||||
msgstr "Ez dago \"start_angle\" edo \"from\" atributurik <%s> elementuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1783
|
||||
#: ../src/ui/theme-parser.c:1791
|
||||
#, c-format
|
||||
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
|
||||
msgstr "Ez dago \"extent_angle\" edo \"to\" atributurik <%s> elementuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2023
|
||||
#: ../src/ui/theme-parser.c:2031
|
||||
#, c-format
|
||||
msgid "Did not understand value \"%s\" for type of gradient"
|
||||
msgstr "Gradiente-motan ez da ulertu \"%s\" balioa"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2101 ../src/ui/theme-parser.c:2476
|
||||
#: ../src/ui/theme-parser.c:2109 ../src/ui/theme-parser.c:2484
|
||||
#, c-format
|
||||
msgid "Did not understand fill type \"%s\" for <%s> element"
|
||||
msgstr "Ez da ulertu \"%s\" betetze-mota <%s> elementuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2268 ../src/ui/theme-parser.c:2351
|
||||
#: ../src/ui/theme-parser.c:2414
|
||||
#: ../src/ui/theme-parser.c:2276 ../src/ui/theme-parser.c:2359
|
||||
#: ../src/ui/theme-parser.c:2422
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" for <%s> element"
|
||||
msgstr "Ez da ulertu \"%s\" egoera <%s> elementuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2278 ../src/ui/theme-parser.c:2361
|
||||
#: ../src/ui/theme-parser.c:2286 ../src/ui/theme-parser.c:2369
|
||||
#, c-format
|
||||
msgid "Did not understand shadow \"%s\" for <%s> element"
|
||||
msgstr "Ez da ulertu \"%s\" itzala <%s> elementuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2288
|
||||
#: ../src/ui/theme-parser.c:2296
|
||||
#, c-format
|
||||
msgid "Did not understand arrow \"%s\" for <%s> element"
|
||||
msgstr "Ez da ulertu \"%s\" gezia <%s> elementuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2588 ../src/ui/theme-parser.c:2684
|
||||
#: ../src/ui/theme-parser.c:2596 ../src/ui/theme-parser.c:2692
|
||||
#, c-format
|
||||
msgid "No <draw_ops> called \"%s\" has been defined"
|
||||
msgstr "Ez da \"%s\" izeneko <draw_ops> bat ere definitu"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2600 ../src/ui/theme-parser.c:2696
|
||||
#: ../src/ui/theme-parser.c:2608 ../src/ui/theme-parser.c:2704
|
||||
#, c-format
|
||||
msgid "Including draw_ops \"%s\" here would create a circular reference"
|
||||
msgstr "Hemen \"%s\" draw_ops sartzen bada, erreferentzia zirkularra sortuko da"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2811
|
||||
#: ../src/ui/theme-parser.c:2819
|
||||
#, c-format
|
||||
msgid "Unknown position \"%s\" for frame piece"
|
||||
msgstr "\"%s\" kokaleku ezezaguna markoarentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2819
|
||||
#: ../src/ui/theme-parser.c:2827
|
||||
#, c-format
|
||||
msgid "Frame style already has a piece at position %s"
|
||||
msgstr "Marko-estiloak badu zati bat %s posizioan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2836 ../src/ui/theme-parser.c:2911
|
||||
#: ../src/ui/theme-parser.c:2844 ../src/ui/theme-parser.c:2919
|
||||
#, c-format
|
||||
msgid "No <draw_ops> with the name \"%s\" has been defined"
|
||||
msgstr "Ez da \"%s\" izeneko <draw_ops> bat ere definitu"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2865
|
||||
#: ../src/ui/theme-parser.c:2873
|
||||
#, c-format
|
||||
msgid "Unknown function \"%s\" for button"
|
||||
msgstr "\"%s\" funtzioa ezezaguna botoiarentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2874
|
||||
#: ../src/ui/theme-parser.c:2882
|
||||
#, c-format
|
||||
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
|
||||
msgstr "\"%s\" botoi-funtzioa ez da existitzen bertsio honetan (%d, %d behar du)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2886
|
||||
#: ../src/ui/theme-parser.c:2894
|
||||
#, c-format
|
||||
msgid "Unknown state \"%s\" for button"
|
||||
msgstr "\"%s\" egoera ezezaguna botoiarentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2894
|
||||
#: ../src/ui/theme-parser.c:2902
|
||||
#, c-format
|
||||
msgid "Frame style already has a button for function %s state %s"
|
||||
msgstr "Marko-estiloak badu botoi bat %s funtzioan %s egoeran"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2965
|
||||
#: ../src/ui/theme-parser.c:2973
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for focus attribute"
|
||||
msgstr "\"%s\" ez da baliozko balioa foku-atributuarentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2974
|
||||
#: ../src/ui/theme-parser.c:2982
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for state attribute"
|
||||
msgstr "\"%s\" ez da baliozko balioa egoera-atributuarentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2984
|
||||
#: ../src/ui/theme-parser.c:2992
|
||||
#, c-format
|
||||
msgid "A style called \"%s\" has not been defined"
|
||||
msgstr "\"%s\" izeneko estiloa ez da definitu"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3005 ../src/ui/theme-parser.c:3028
|
||||
#: ../src/ui/theme-parser.c:3013 ../src/ui/theme-parser.c:3036
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for resize attribute"
|
||||
msgstr "\"%s\" ez da baliozko balioa tamainaz aldatzeko atributuarentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3039
|
||||
#: ../src/ui/theme-parser.c:3047
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
|
||||
@@ -1591,24 +1598,24 @@ msgstr ""
|
||||
"Ez luke izan behar \"resize\" atributurik <%s> elementuan maximizatutako/"
|
||||
"bildutako egoerentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3053
|
||||
#: ../src/ui/theme-parser.c:3061
|
||||
#, c-format
|
||||
msgid "Should not have \"resize\" attribute on <%s> element for maximized states"
|
||||
msgstr ""
|
||||
"Ez luke izan behar \"resize\" atributurik <%s> elementuan maximizatutako "
|
||||
"egoerentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3067 ../src/ui/theme-parser.c:3089
|
||||
#: ../src/ui/theme-parser.c:3075 ../src/ui/theme-parser.c:3097
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s resize %s focus %s"
|
||||
msgstr "Estiloa dagoeneko zehaztu da %s egoeran %s tamaina-aldatzean %s fokuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3078 ../src/ui/theme-parser.c:3100
|
||||
#: ../src/ui/theme-parser.c:3086 ../src/ui/theme-parser.c:3108
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s focus %s"
|
||||
msgstr "Estiloa dagoeneko zehaztu da %s egoeran %s fokuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3139
|
||||
#: ../src/ui/theme-parser.c:3147
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
@@ -1616,7 +1623,7 @@ msgstr ""
|
||||
"Ezin dira bi draw_ops izan <piece> elementu batean (gaiak draw_ops atributu "
|
||||
"bat eta <draw_ops> elementu bat zehaztu ditu, edo bi elementu zehaztu ditu)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3177
|
||||
#: ../src/ui/theme-parser.c:3185
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <button> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
@@ -1624,7 +1631,7 @@ msgstr ""
|
||||
"Ezin dira bi draw_ops izan <button> elementu batean (gaiak draw_ops atributu "
|
||||
"bat eta <draw_ops> elementu bat zehaztu ditu, edo bi elementu zehaztu ditu)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3215
|
||||
#: ../src/ui/theme-parser.c:3223
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <menu_icon> element (theme specified a "
|
||||
"draw_ops attribute and also a <draw_ops> element, or specified two elements)"
|
||||
@@ -1633,76 +1640,63 @@ msgstr ""
|
||||
"atributu bat eta <draw_ops> elementu bat zehaztu ditu, edo bi elementu "
|
||||
"zehaztu ditu)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3263
|
||||
#: ../src/ui/theme-parser.c:3271
|
||||
#, c-format
|
||||
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
|
||||
msgstr "Gaian kanporen dagoen elementuak <metacity_theme> izan behar du, ez <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3283
|
||||
#: ../src/ui/theme-parser.c:3291
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a name/author/date/description element"
|
||||
msgstr "<%s> elementua ez da onartzen name/author/date/description elementuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3288
|
||||
#: ../src/ui/theme-parser.c:3296
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <constant> element"
|
||||
msgstr "<%s> elementua ez da onartzen <constant> elementuaren barnean"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3300
|
||||
#: ../src/ui/theme-parser.c:3308
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element"
|
||||
msgstr "<%s> elementua ez da onartzen distance/border/aspect_ratio elementuan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3322
|
||||
#: ../src/ui/theme-parser.c:3330
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a draw operation element"
|
||||
msgstr "<%s> elementua ez da onartzen marrazteko eragiketaren elementuaren barnean"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3332 ../src/ui/theme-parser.c:3362
|
||||
#: ../src/ui/theme-parser.c:3367 ../src/ui/theme-parser.c:3372
|
||||
#: ../src/ui/theme-parser.c:3340 ../src/ui/theme-parser.c:3370
|
||||
#: ../src/ui/theme-parser.c:3375 ../src/ui/theme-parser.c:3380
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <%s> element"
|
||||
msgstr "<%s> elementua ez da onartzen <%s> elementuaren barnean"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3594
|
||||
#: ../src/ui/theme-parser.c:3602
|
||||
msgid "No draw_ops provided for frame piece"
|
||||
msgstr "Ez da draw_ops-ik eman marko-zatiarentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3609
|
||||
#: ../src/ui/theme-parser.c:3617
|
||||
msgid "No draw_ops provided for button"
|
||||
msgstr "Ez da draw_ops-ik eman botoiarentzat"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3661
|
||||
#: ../src/ui/theme-parser.c:3669
|
||||
#, c-format
|
||||
msgid "No text is allowed inside element <%s>"
|
||||
msgstr "Ez da testurik onartzen <%s> elementuaren barnean"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3716
|
||||
msgid "<name> specified twice for this theme"
|
||||
msgstr "<izena> birritan zehaztu da gai honetan"
|
||||
#: ../src/ui/theme-parser.c:3724 ../src/ui/theme-parser.c:3736
|
||||
#: ../src/ui/theme-parser.c:3748 ../src/ui/theme-parser.c:3760
|
||||
#: ../src/ui/theme-parser.c:3772
|
||||
#, c-format
|
||||
msgid "<%s> specified twice for this theme"
|
||||
msgstr "<%s> birritan zehaztu da gai honetan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3727
|
||||
msgid "<author> specified twice for this theme"
|
||||
msgstr "<egilea> birritan zehaztu da gai honetan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3738
|
||||
msgid "<copyright> specified twice for this theme"
|
||||
msgstr "<copyright-a> birritan zehaztu da gai honetan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3749
|
||||
msgid "<date> specified twice for this theme"
|
||||
msgstr "<data> birritan zehaztu da gai honetan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3760
|
||||
msgid "<description> specified twice for this theme"
|
||||
msgstr "<azalpena> birritan zehaztu da gai honetan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4027
|
||||
#: ../src/ui/theme-parser.c:4040
|
||||
#, c-format
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "Huts egin du %s gaiaren fitxategi egokia bilatzean\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4083
|
||||
#: ../src/ui/theme-parser.c:4096
|
||||
#, c-format
|
||||
msgid "Theme file %s did not contain a root <metacity_theme> element"
|
||||
msgstr "%s gai-fitxategiak ez du erroko <metacity_theme> elementurik"
|
||||
|
2004
po/pt_BR.po
2004
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1984
po/sr@latin.po
1984
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
1981
po/zh_CN.po
1981
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1692
po/zh_HK.po
1692
po/zh_HK.po
File diff suppressed because it is too large
Load Diff
1785
po/zh_TW.po
1785
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,11 @@
|
||||
# Flag build for parallelism; see https://savannah.gnu.org/patch/?6905
|
||||
.AUTOPARALLEL:
|
||||
|
||||
if INSTALL_LIBMUTTER_PRIVATE
|
||||
lib_LTLIBRARIES = libmutter-private.la
|
||||
else
|
||||
noinst_LTLIBRARIES = libmutter-private.la
|
||||
endif
|
||||
|
||||
SUBDIRS=wm-tester tools compositor/plugins
|
||||
|
||||
@@ -16,10 +20,6 @@ mutter_built_sources = \
|
||||
mutter_SOURCES= \
|
||||
core/async-getprop.c \
|
||||
core/async-getprop.h \
|
||||
core/alttabhandler.c \
|
||||
include/alttabhandler.h \
|
||||
core/alttabhandlerdefault.c \
|
||||
include/alttabhandlerdefault.h \
|
||||
core/bell.c \
|
||||
core/bell.h \
|
||||
core/boxes.c \
|
||||
@@ -32,6 +32,8 @@ mutter_SOURCES= \
|
||||
compositor/mutter-plugin-manager.c \
|
||||
compositor/mutter-plugin-manager.h \
|
||||
compositor/mutter-shaped-texture.c \
|
||||
compositor/mutter-texture-tower.c \
|
||||
compositor/mutter-texture-tower.h \
|
||||
compositor/mutter-window.c \
|
||||
compositor/mutter-window-private.h \
|
||||
compositor/mutter-window-group.c \
|
||||
@@ -41,9 +43,14 @@ mutter_SOURCES= \
|
||||
compositor/mutter-shaped-texture.h \
|
||||
compositor/tidy/tidy-texture-frame.c \
|
||||
compositor/tidy/tidy-texture-frame.h \
|
||||
gdk-compat.h \
|
||||
gtk-compat.h \
|
||||
gdk2-drawing-utils.c \
|
||||
gdk2-drawing-utils.h \
|
||||
include/compositor.h \
|
||||
include/mutter-plugin.h \
|
||||
include/mutter-window.h \
|
||||
include/region.h \
|
||||
include/compositor-mutter.h \
|
||||
core/constraints.c \
|
||||
core/constraints.h \
|
||||
@@ -117,12 +124,12 @@ mutter_SOURCES= \
|
||||
include/resizepopup.h \
|
||||
ui/tabpopup.c \
|
||||
include/tabpopup.h \
|
||||
ui/tile-preview.c \
|
||||
include/tile-preview.h \
|
||||
ui/theme-parser.c \
|
||||
ui/theme-parser.h \
|
||||
ui/theme.c \
|
||||
ui/theme.h \
|
||||
ui/themewidget.c \
|
||||
ui/themewidget.h \
|
||||
ui/ui.c \
|
||||
include/all-keybindings.h \
|
||||
$(mutter_built_sources)
|
||||
@@ -140,6 +147,9 @@ libmutter_private_la_SOURCES= \
|
||||
include/common.h \
|
||||
ui/preview-widget.c \
|
||||
ui/preview-widget.h \
|
||||
include/region.h \
|
||||
gdk2-drawing-utils.c \
|
||||
gdk2-drawing-utils.h \
|
||||
ui/theme-parser.c \
|
||||
ui/theme-parser.h \
|
||||
ui/theme.c \
|
||||
@@ -148,12 +158,9 @@ libmutter_private_la_SOURCES= \
|
||||
libmutter_private_la_LDFLAGS = -no-undefined
|
||||
libmutter_private_la_LIBADD = @MUTTER_LIBS@
|
||||
|
||||
libmutterincludedir = $(includedir)/mutter/mutter-private
|
||||
|
||||
# Headers installed for plugins; introspected information will
|
||||
# be extracted into Mutter-<version>.gir
|
||||
libmutterinclude_base_headers = \
|
||||
include/alttabhandler.h \
|
||||
include/boxes.h \
|
||||
ui/gradient.h \
|
||||
include/main.h \
|
||||
@@ -180,11 +187,20 @@ libmutterinclude_base_headers = \
|
||||
# atomnames.h: macros cause problems for scanning process
|
||||
libmutterinclude_extra_headers = \
|
||||
ui/preview-widget.h \
|
||||
include/atomnames.h
|
||||
include/atomnames.h \
|
||||
include/region.h
|
||||
|
||||
if INSTALL_LIBMUTTER_PRIVATE
|
||||
libmutterincludedir = $(includedir)/mutter/mutter-private
|
||||
|
||||
libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_base_headers) \
|
||||
$(libmutterinclude_extra_headers)
|
||||
else
|
||||
noinst_HEADERS = \
|
||||
$(libmutterinclude_base_headers) \
|
||||
$(libmutterinclude_extra_headers)
|
||||
endif
|
||||
|
||||
mutter_theme_viewer_SOURCES= \
|
||||
ui/theme-viewer.c
|
||||
@@ -205,20 +221,25 @@ typelib_DATA = Meta-$(api_version).typelib
|
||||
|
||||
# We need to strip out the attribute that would point back to libmutter-introspect
|
||||
# so that libgirepository looks for symbols in the executable instead
|
||||
Meta-$(api_version).gir: $(G_IR_SCANNER) mutter $(libmutterinclude_HEADERS) $(mutter_SOURCES)
|
||||
Meta-$(api_version).gir: $(G_IR_SCANNER) mutter $(libmutterinclude_HEADERS) $(mutter_SOURCES) Makefile
|
||||
$(AM_V_GEN) pwd=`pwd` ; \
|
||||
cd $(srcdir) && \
|
||||
$(G_IR_SCANNER) \
|
||||
--namespace=Meta \
|
||||
--nsversion=$(api_version) \
|
||||
--warn-all \
|
||||
--warn-error \
|
||||
--accept-unprefixed \
|
||||
--include=GObject-2.0 \
|
||||
--include=Gdk-2.0 \
|
||||
--include=Gtk-2.0 \
|
||||
--include=Gdk-@GTK_API_VERSION@ \
|
||||
--include=Gtk-@GTK_API_VERSION@ \
|
||||
--include=Clutter-1.0 \
|
||||
--pkg=clutter-1.0 \
|
||||
--pkg=gtk+-2.0 \
|
||||
--pkg=gtk+-@GTK_API_VERSION@ \
|
||||
--include=xlib-2.0 \
|
||||
--include=xfixes-4.0 \
|
||||
--program=$$pwd/mutter \
|
||||
mutter-enum-types.h \
|
||||
$(filter %.c,$(mutter_SOURCES)) \
|
||||
$(libmutterinclude_base_headers) \
|
||||
$(INCLUDES) \
|
||||
@@ -289,9 +310,11 @@ CLEANFILES = \
|
||||
inlinepixbufs.h: $(IMAGES)
|
||||
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
|
||||
|
||||
if INSTALL_LIBMUTTER_PRIVATE
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
pkgconfig_DATA = libmutter-private.pc mutter-plugins.pc
|
||||
endif
|
||||
|
||||
EXTRA_DIST=$(desktopfiles_files) \
|
||||
$(wmproperties_files) \
|
||||
|
@@ -33,59 +33,6 @@ composite_at_least_version (MetaDisplay *display, int maj, int min)
|
||||
return (major > maj || (major == maj && minor >= min));
|
||||
}
|
||||
|
||||
static MutterWindow*
|
||||
find_window_for_screen (MetaScreen *screen, Window xwindow)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (info == NULL)
|
||||
return NULL;
|
||||
|
||||
return g_hash_table_lookup (info->windows_by_xid,
|
||||
(gpointer) xwindow);
|
||||
}
|
||||
|
||||
static MutterWindow *
|
||||
find_window_in_display (MetaDisplay *display, Window xwindow)
|
||||
{
|
||||
GSList *index;
|
||||
MetaWindow *window = meta_display_lookup_x_window (display, xwindow);
|
||||
|
||||
if (window)
|
||||
{
|
||||
void *priv = meta_window_get_compositor_private (window);
|
||||
if (priv)
|
||||
return priv;
|
||||
}
|
||||
|
||||
for (index = meta_display_get_screens (display);
|
||||
index;
|
||||
index = index->next)
|
||||
{
|
||||
MutterWindow *cw = find_window_for_screen (index->data, xwindow);
|
||||
|
||||
if (cw != NULL)
|
||||
return cw;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static MutterWindow *
|
||||
find_window_for_child_window_in_display (MetaDisplay *display, Window xwindow)
|
||||
{
|
||||
Window ignored1, *ignored2, parent;
|
||||
guint ignored_children;
|
||||
|
||||
XQueryTree (meta_display_get_xdisplay (display), xwindow, &ignored1,
|
||||
&parent, &ignored2, &ignored_children);
|
||||
|
||||
if (parent != None)
|
||||
return find_window_in_display (display, parent);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void sync_actor_stacking (GList *windows);
|
||||
|
||||
static void
|
||||
@@ -144,9 +91,15 @@ add_win (MetaWindow *window)
|
||||
|
||||
static void
|
||||
process_damage (MetaCompositor *compositor,
|
||||
XDamageNotifyEvent *event)
|
||||
XDamageNotifyEvent *event,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MutterWindow *cw = find_window_in_display (compositor->display, event->drawable);
|
||||
MutterWindow *cw;
|
||||
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
cw = MUTTER_WINDOW (meta_window_get_compositor_private (window));
|
||||
if (cw == NULL)
|
||||
return;
|
||||
|
||||
@@ -156,10 +109,15 @@ process_damage (MetaCompositor *compositor,
|
||||
#ifdef HAVE_SHAPE
|
||||
static void
|
||||
process_shape (MetaCompositor *compositor,
|
||||
XShapeEvent *event)
|
||||
XShapeEvent *event,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MutterWindow *cw = find_window_in_display (compositor->display,
|
||||
event->window);
|
||||
MutterWindow *cw;
|
||||
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
cw = MUTTER_WINDOW (meta_window_get_compositor_private (window));
|
||||
if (cw == NULL)
|
||||
return;
|
||||
|
||||
@@ -172,47 +130,26 @@ process_shape (MetaCompositor *compositor,
|
||||
|
||||
static void
|
||||
process_property_notify (MetaCompositor *compositor,
|
||||
XPropertyEvent *event)
|
||||
XPropertyEvent *event,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaDisplay *display = compositor->display;
|
||||
MutterWindow *cw;
|
||||
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
cw = MUTTER_WINDOW (meta_window_get_compositor_private (window));
|
||||
if (cw == NULL)
|
||||
return;
|
||||
|
||||
/* Check for the opacity changing */
|
||||
if (event->atom == compositor->atom_net_wm_window_opacity)
|
||||
{
|
||||
MutterWindow *cw = find_window_in_display (display, event->window);
|
||||
|
||||
if (!cw)
|
||||
{
|
||||
/* Applications can set this for their toplevel windows, so
|
||||
* this must be propagated to the window managed by the compositor
|
||||
*/
|
||||
cw = find_window_for_child_window_in_display (display,
|
||||
event->window);
|
||||
}
|
||||
|
||||
if (!cw)
|
||||
{
|
||||
DEBUG_TRACE ("process_property_notify: opacity, early exit\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mutter_window_update_opacity (cw);
|
||||
}
|
||||
else if (event->atom == meta_display_get_atom (display,
|
||||
META_ATOM__NET_WM_WINDOW_TYPE))
|
||||
{
|
||||
MutterWindow *cw = find_window_in_display (display, event->window);
|
||||
|
||||
if (!cw)
|
||||
{
|
||||
DEBUG_TRACE ("process_property_notify: net_wm_type, early exit\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mutter_window_update_window_type (cw);
|
||||
DEBUG_TRACE ("process_property_notify: net_wm_type\n");
|
||||
DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n");
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE ("process_property_notify: unknown\n");
|
||||
}
|
||||
|
||||
@@ -247,6 +184,12 @@ get_output_window (MetaScreen *screen)
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_get_stage_for_screen:
|
||||
* @screen: a #MetaScreen
|
||||
*
|
||||
* Returns: (transfer none): The #ClutterStage for the screen
|
||||
*/
|
||||
ClutterActor *
|
||||
mutter_get_stage_for_screen (MetaScreen *screen)
|
||||
{
|
||||
@@ -258,6 +201,12 @@ mutter_get_stage_for_screen (MetaScreen *screen)
|
||||
return info->stage;
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_get_overlay_group_for_screen:
|
||||
* @screen: a #MetaScreen
|
||||
*
|
||||
* Returns: (transfer none): The overlay group corresponding to @screen
|
||||
*/
|
||||
ClutterActor *
|
||||
mutter_get_overlay_group_for_screen (MetaScreen *screen)
|
||||
{
|
||||
@@ -269,6 +218,12 @@ mutter_get_overlay_group_for_screen (MetaScreen *screen)
|
||||
return info->overlay_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_get_window_group_for_screen:
|
||||
* @screen: a #MetaScreen
|
||||
*
|
||||
* Returns: (transfer none): The window group corresponding to @screen
|
||||
*/
|
||||
ClutterActor *
|
||||
mutter_get_window_group_for_screen (MetaScreen *screen)
|
||||
{
|
||||
@@ -280,6 +235,12 @@ mutter_get_window_group_for_screen (MetaScreen *screen)
|
||||
return info->window_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_get_windows:
|
||||
* @screen: a #MetaScreen
|
||||
*
|
||||
* Returns: (transfer none) (element-type Clutter.Actor): The windows on @screen
|
||||
*/
|
||||
GList *
|
||||
mutter_get_windows (MetaScreen *screen)
|
||||
{
|
||||
@@ -390,10 +351,10 @@ mutter_begin_modal_for_plugin (MetaScreen *screen,
|
||||
|
||||
if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
|
||||
{
|
||||
XGrabKeyboard (xdpy, grab_window,
|
||||
False, /* owner_events */
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
timestamp);
|
||||
result = XGrabKeyboard (xdpy, grab_window,
|
||||
False, /* owner_events */
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
timestamp);
|
||||
|
||||
if (result != Success)
|
||||
goto fail;
|
||||
@@ -505,7 +466,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
|
||||
info->output = None;
|
||||
info->windows = NULL;
|
||||
info->windows_by_xid = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
|
||||
meta_screen_set_cm_selection (screen);
|
||||
|
||||
@@ -545,9 +505,17 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
clutter_actor_hide (info->hidden_group);
|
||||
|
||||
info->plugin_mgr =
|
||||
mutter_plugin_manager_new (screen);
|
||||
if (!mutter_plugin_manager_load (info->plugin_mgr))
|
||||
g_critical ("failed to load plugins");
|
||||
mutter_plugin_manager_get (screen);
|
||||
|
||||
if (info->plugin_mgr != mutter_plugin_manager_get_default ())
|
||||
{
|
||||
/* The default plugin manager has been initialized during
|
||||
* global preferences load.
|
||||
*/
|
||||
if (!mutter_plugin_manager_load (info->plugin_mgr))
|
||||
g_critical ("failed to load plugins");
|
||||
}
|
||||
|
||||
if (!mutter_plugin_manager_initialize (info->plugin_mgr))
|
||||
g_critical ("failed to initialize plugins");
|
||||
|
||||
@@ -634,14 +602,17 @@ is_grabbed_event (XEvent *event)
|
||||
case EnterNotify:
|
||||
case LeaveNotify:
|
||||
case MotionNotify:
|
||||
case KeyPressMask:
|
||||
case KeyReleaseMask:
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_compositor_process_event: (skip)
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
meta_compositor_process_event (MetaCompositor *compositor,
|
||||
XEvent *event,
|
||||
@@ -696,38 +667,37 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This trap is so that none of the compositor functions cause
|
||||
* X errors. This is really a hack, but I'm afraid I don't understand
|
||||
* enough about Metacity/X to know how else you are supposed to do it
|
||||
*/
|
||||
|
||||
|
||||
meta_error_trap_push (compositor->display);
|
||||
switch (event->type)
|
||||
{
|
||||
case PropertyNotify:
|
||||
process_property_notify (compositor, (XPropertyEvent *) event);
|
||||
process_property_notify (compositor, (XPropertyEvent *) event, window);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
|
||||
{
|
||||
/* Core code doesn't handle damage events, so we need to extract the MetaWindow
|
||||
* ourselves
|
||||
*/
|
||||
if (window == NULL)
|
||||
{
|
||||
Window xwin = ((XDamageNotifyEvent *) event)->drawable;
|
||||
window = meta_display_lookup_x_window (compositor->display, xwin);
|
||||
}
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
|
||||
process_damage (compositor, (XDamageNotifyEvent *) event);
|
||||
process_damage (compositor, (XDamageNotifyEvent *) event, window);
|
||||
}
|
||||
#ifdef HAVE_SHAPE
|
||||
else if (event->type == meta_display_get_shape_event_base (compositor->display) + ShapeNotify)
|
||||
{
|
||||
DEBUG_TRACE ("meta_compositor_process_event (process_shape)\n");
|
||||
process_shape (compositor, (XShapeEvent *) event);
|
||||
process_shape (compositor, (XShapeEvent *) event, window);
|
||||
}
|
||||
#endif /* HAVE_SHAPE */
|
||||
break;
|
||||
}
|
||||
|
||||
meta_error_trap_pop (compositor->display, FALSE);
|
||||
|
||||
/* Clutter needs to know about MapNotify events otherwise it will
|
||||
think the stage is invisible */
|
||||
if (event->type == MapNotify)
|
||||
@@ -840,7 +810,6 @@ meta_compositor_switch_workspace (MetaCompositor *compositor,
|
||||
|
||||
if (!info->plugin_mgr ||
|
||||
!mutter_plugin_manager_switch_workspace (info->plugin_mgr,
|
||||
(const GList **)&info->windows,
|
||||
from_indx,
|
||||
to_indx,
|
||||
direction))
|
||||
@@ -1048,6 +1017,10 @@ mutter_repaint_func (gpointer data)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_compositor_new: (skip)
|
||||
*
|
||||
*/
|
||||
MetaCompositor *
|
||||
meta_compositor_new (MetaDisplay *display)
|
||||
{
|
||||
@@ -1085,6 +1058,10 @@ meta_compositor_new (MetaDisplay *display)
|
||||
return compositor;
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_get_overlay_window: (skip)
|
||||
*
|
||||
*/
|
||||
Window
|
||||
mutter_get_overlay_window (MetaScreen *screen)
|
||||
{
|
||||
|
@@ -39,26 +39,27 @@
|
||||
*/
|
||||
static GHashTable *plugin_modules = NULL;
|
||||
|
||||
/*
|
||||
* We have one "default plugin manager" that acts for the first screen,
|
||||
* but also can be used before we open any screens, and additional
|
||||
* plugin managers for each screen. (This is ugly. Probably we should
|
||||
* have one plugin manager and only make the plugins per-screen.)
|
||||
*/
|
||||
|
||||
static MutterPluginManager *default_plugin_manager;
|
||||
|
||||
static gboolean mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr);
|
||||
|
||||
struct MutterPluginManager
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
GList /* MutterPluginPending */ *pending_plugin_modules; /* Plugins not yet fully loaded */
|
||||
GList /* MutterPlugin */ *plugins; /* TODO -- maybe use hash table */
|
||||
GList *unload; /* Plugins that are disabled and pending unload */
|
||||
|
||||
guint idle_unload_id;
|
||||
};
|
||||
|
||||
typedef struct MutterPluginPending
|
||||
{
|
||||
MutterModule *module;
|
||||
char *path;
|
||||
char *params;
|
||||
} MutterPluginPending;
|
||||
|
||||
/*
|
||||
* Checks that the plugin is compatible with the WM and sets up the plugin
|
||||
* struct.
|
||||
@@ -78,7 +79,6 @@ mutter_plugin_load (MutterPluginManager *mgr,
|
||||
}
|
||||
|
||||
plugin = g_object_new (plugin_type,
|
||||
"screen", mgr->screen,
|
||||
"params", params,
|
||||
NULL);
|
||||
|
||||
@@ -270,12 +270,14 @@ mutter_plugin_manager_load (MutterPluginManager *plugin_mgr)
|
||||
|
||||
if (use_succeeded)
|
||||
{
|
||||
MutterPluginPending *pending = g_new0 (MutterPluginPending, 1);
|
||||
pending->module = module;
|
||||
pending->path = g_strdup (path);
|
||||
pending->params = g_strdup (params);
|
||||
plugin_mgr->pending_plugin_modules =
|
||||
g_list_prepend (plugin_mgr->pending_plugin_modules, pending);
|
||||
MutterPlugin *plugin = mutter_plugin_load (plugin_mgr, module, params);
|
||||
|
||||
if (plugin)
|
||||
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, plugin);
|
||||
else
|
||||
g_warning ("Plugin load for [%s] failed", path);
|
||||
|
||||
g_type_module_unuse (G_TYPE_MODULE (module));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -293,7 +295,7 @@ mutter_plugin_manager_load (MutterPluginManager *plugin_mgr)
|
||||
if (fallback)
|
||||
g_slist_free (fallback);
|
||||
|
||||
if (plugin_mgr->pending_plugin_modules != NULL)
|
||||
if (plugin_mgr->plugins != NULL)
|
||||
{
|
||||
meta_prefs_add_listener (prefs_changed_callback, plugin_mgr);
|
||||
return TRUE;
|
||||
@@ -307,27 +309,19 @@ mutter_plugin_manager_initialize (MutterPluginManager *plugin_mgr)
|
||||
{
|
||||
GList *iter;
|
||||
|
||||
for (iter = plugin_mgr->pending_plugin_modules; iter; iter = iter->next)
|
||||
for (iter = plugin_mgr->plugins; iter; iter = iter->next)
|
||||
{
|
||||
MutterPluginPending *pending = (MutterPluginPending*) iter->data;
|
||||
MutterPlugin *p;
|
||||
MutterPlugin *plugin = (MutterPlugin*) iter->data;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if ((p = mutter_plugin_load (plugin_mgr, pending->module, pending->params)))
|
||||
{
|
||||
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Plugin load for [%s] failed", pending->path);
|
||||
}
|
||||
g_object_set (plugin,
|
||||
"screen", plugin_mgr->screen,
|
||||
NULL);
|
||||
|
||||
g_type_module_unuse (G_TYPE_MODULE (pending->module));
|
||||
g_free (pending->path);
|
||||
g_free (pending->params);
|
||||
g_free (pending);
|
||||
if (klass->start)
|
||||
klass->start (plugin);
|
||||
}
|
||||
g_list_free (plugin_mgr->pending_plugin_modules);
|
||||
plugin_mgr->pending_plugin_modules = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -349,7 +343,7 @@ mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr)
|
||||
return mutter_plugin_manager_load (plugin_mgr);
|
||||
}
|
||||
|
||||
MutterPluginManager *
|
||||
static MutterPluginManager *
|
||||
mutter_plugin_manager_new (MetaScreen *screen)
|
||||
{
|
||||
MutterPluginManager *plugin_mgr;
|
||||
@@ -364,13 +358,52 @@ mutter_plugin_manager_new (MetaScreen *screen)
|
||||
|
||||
plugin_mgr->screen = screen;
|
||||
|
||||
if (screen)
|
||||
g_object_set_data (G_OBJECT (screen), "mutter-plugin-manager", plugin_mgr);
|
||||
|
||||
return plugin_mgr;
|
||||
}
|
||||
|
||||
MutterPluginManager *
|
||||
mutter_plugin_manager_get_default (void)
|
||||
{
|
||||
if (!default_plugin_manager)
|
||||
{
|
||||
default_plugin_manager = mutter_plugin_manager_new (NULL);
|
||||
}
|
||||
|
||||
return default_plugin_manager;
|
||||
}
|
||||
|
||||
MutterPluginManager *
|
||||
mutter_plugin_manager_get (MetaScreen *screen)
|
||||
{
|
||||
MutterPluginManager *plugin_mgr;
|
||||
|
||||
plugin_mgr = g_object_get_data (G_OBJECT (screen), "mutter-plugin-manager");
|
||||
if (plugin_mgr)
|
||||
return plugin_mgr;
|
||||
|
||||
if (!default_plugin_manager)
|
||||
mutter_plugin_manager_get_default ();
|
||||
|
||||
if (!default_plugin_manager->screen)
|
||||
{
|
||||
/* The default plugin manager is so far unused, we can recycle it */
|
||||
default_plugin_manager->screen = screen;
|
||||
g_object_set_data (G_OBJECT (screen), "mutter-plugin-manager", default_plugin_manager);
|
||||
|
||||
return default_plugin_manager;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mutter_plugin_manager_new (screen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
|
||||
MutterWindow *actor,
|
||||
unsigned long events)
|
||||
mutter_plugin_manager_kill_window_effects (MutterPluginManager *plugin_mgr,
|
||||
MutterWindow *actor)
|
||||
{
|
||||
GList *l = plugin_mgr->plugins;
|
||||
|
||||
@@ -380,17 +413,32 @@ mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!mutter_plugin_disabled (plugin)
|
||||
&& (mutter_plugin_features (plugin) & events)
|
||||
&& klass->kill_effect)
|
||||
klass->kill_effect (plugin, actor, events);
|
||||
&& klass->kill_window_effects)
|
||||
klass->kill_window_effects (plugin, actor);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_manager_kill_switch_workspace (MutterPluginManager *plugin_mgr)
|
||||
{
|
||||
GList *l = plugin_mgr->plugins;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!mutter_plugin_disabled (plugin)
|
||||
&& (mutter_plugin_features (plugin) & MUTTER_PLUGIN_SWITCH_WORKSPACE)
|
||||
&& klass->kill_switch_workspace)
|
||||
klass->kill_switch_workspace (plugin);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
#define ALL_BUT_SWITCH \
|
||||
MUTTER_PLUGIN_ALL_EFFECTS & \
|
||||
~MUTTER_PLUGIN_SWITCH_WORKSPACE
|
||||
/*
|
||||
* Public method that the compositor hooks into for events that require
|
||||
* no additional parameters.
|
||||
@@ -427,10 +475,9 @@ mutter_plugin_manager_event_simple (MutterPluginManager *plugin_mgr,
|
||||
case MUTTER_PLUGIN_MINIMIZE:
|
||||
if (klass->minimize)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
mutter_plugin_manager_kill_window_effects (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
actor);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->minimize (plugin, actor);
|
||||
@@ -439,10 +486,9 @@ mutter_plugin_manager_event_simple (MutterPluginManager *plugin_mgr,
|
||||
case MUTTER_PLUGIN_MAP:
|
||||
if (klass->map)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
mutter_plugin_manager_kill_window_effects (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
actor);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->map (plugin, actor);
|
||||
@@ -506,10 +552,9 @@ mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
|
||||
case MUTTER_PLUGIN_MAXIMIZE:
|
||||
if (klass->maximize)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
mutter_plugin_manager_kill_window_effects (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
actor);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->maximize (plugin, actor,
|
||||
@@ -520,10 +565,9 @@ mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
|
||||
case MUTTER_PLUGIN_UNMAXIMIZE:
|
||||
if (klass->unmaximize)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
mutter_plugin_manager_kill_window_effects (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
actor);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->unmaximize (plugin, actor,
|
||||
@@ -552,7 +596,6 @@ mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
|
||||
*/
|
||||
gboolean
|
||||
mutter_plugin_manager_switch_workspace (MutterPluginManager *plugin_mgr,
|
||||
const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction)
|
||||
@@ -570,19 +613,15 @@ mutter_plugin_manager_switch_workspace (MutterPluginManager *plugin_mgr,
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!mutter_plugin_disabled (plugin) &&
|
||||
(mutter_plugin_features (plugin) & MUTTER_PLUGIN_SWITCH_WORKSPACE) &&
|
||||
(actors && *actors))
|
||||
(mutter_plugin_features (plugin) & MUTTER_PLUGIN_SWITCH_WORKSPACE))
|
||||
{
|
||||
if (klass->switch_workspace)
|
||||
{
|
||||
retval = TRUE;
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
MUTTER_WINDOW ((*actors)->data),
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
mutter_plugin_manager_kill_switch_workspace (plugin_mgr);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->switch_workspace (plugin, actors, from, to, direction);
|
||||
klass->switch_workspace (plugin, from, to, direction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -31,9 +31,24 @@
|
||||
#include "mutter-plugin.h"
|
||||
#undef MUTTER_PLUGIN_FROM_MANAGER_
|
||||
|
||||
#define MUTTER_PLUGIN_MINIMIZE (1<<0)
|
||||
#define MUTTER_PLUGIN_MAXIMIZE (1<<1)
|
||||
#define MUTTER_PLUGIN_UNMAXIMIZE (1<<2)
|
||||
#define MUTTER_PLUGIN_MAP (1<<3)
|
||||
#define MUTTER_PLUGIN_DESTROY (1<<4)
|
||||
#define MUTTER_PLUGIN_SWITCH_WORKSPACE (1<<5)
|
||||
|
||||
#define MUTTER_PLUGIN_ALL_EFFECTS (~0)
|
||||
|
||||
/**
|
||||
* MutterPluginManager: (skip)
|
||||
*
|
||||
*/
|
||||
typedef struct MutterPluginManager MutterPluginManager;
|
||||
|
||||
MutterPluginManager * mutter_plugin_manager_new (MetaScreen *screen);
|
||||
MutterPluginManager * mutter_plugin_manager_get (MetaScreen *screen);
|
||||
MutterPluginManager * mutter_plugin_manager_get_default (void);
|
||||
|
||||
gboolean mutter_plugin_manager_load (MutterPluginManager *mgr);
|
||||
gboolean mutter_plugin_manager_initialize (MutterPluginManager *plugin_mgr);
|
||||
gboolean mutter_plugin_manager_event_simple (MutterPluginManager *mgr,
|
||||
@@ -52,7 +67,6 @@ void mutter_plugin_manager_update_workspaces (MutterPluginManager *mgr);
|
||||
void mutter_plugin_manager_update_workspace (MutterPluginManager *mgr, MetaWorkspace *w);
|
||||
|
||||
gboolean mutter_plugin_manager_switch_workspace (MutterPluginManager *mgr,
|
||||
const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction);
|
||||
|
@@ -238,8 +238,7 @@ mutter_plugin_class_init (MutterPluginClass *klass)
|
||||
"MetaScreen",
|
||||
"MetaScreen",
|
||||
META_TYPE_SCREEN,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PARAMS,
|
||||
@@ -368,9 +367,25 @@ _mutter_plugin_effect_started (MutterPlugin *plugin)
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event)
|
||||
mutter_plugin_switch_workspace_completed (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
MetaScreen *screen = mutter_plugin_get_screen (plugin);
|
||||
|
||||
if (priv->running-- < 0)
|
||||
{
|
||||
g_warning ("Error in running effect accounting, adjusting.");
|
||||
priv->running = 0;
|
||||
}
|
||||
|
||||
mutter_switch_workspace_completed (screen);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_window_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
@@ -392,17 +407,42 @@ mutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
name ? name : "unknown");
|
||||
}
|
||||
|
||||
if (event == MUTTER_PLUGIN_SWITCH_WORKSPACE)
|
||||
{
|
||||
/* The window is just used to identify the screen */
|
||||
MetaWindow *window = mutter_window_get_meta_window (actor);
|
||||
MetaScreen *screen = meta_window_get_screen (window);
|
||||
mutter_switch_workspace_completed (screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
mutter_window_effect_completed (actor, event);
|
||||
}
|
||||
mutter_window_effect_completed (actor, event);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_minimize_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor)
|
||||
{
|
||||
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_maximize_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor)
|
||||
{
|
||||
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_MAXIMIZE);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_unmaximize_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor)
|
||||
{
|
||||
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_UNMAXIMIZE);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_map_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor)
|
||||
{
|
||||
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_MAP);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_destroy_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor)
|
||||
{
|
||||
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_DESTROY);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -459,6 +499,18 @@ mutter_plugin_set_stage_input_region (MutterPlugin *plugin,
|
||||
mutter_set_stage_input_region (screen, region);
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_plugin_get_windows:
|
||||
* @plugin: A #MutterPlugin
|
||||
*
|
||||
* This function returns all of the #MutterWindow objects referenced by Mutter, including
|
||||
* override-redirect windows. The returned list is a snapshot of Mutter's current
|
||||
* stacking order, with the topmost window last.
|
||||
*
|
||||
* The 'restacked' signal of #MetaScreen signals when this value has changed.
|
||||
*
|
||||
* Returns: (transfer none) (element-type MutterWindow): Windows in stacking order, topmost last
|
||||
*/
|
||||
GList *
|
||||
mutter_plugin_get_windows (MutterPlugin *plugin)
|
||||
{
|
||||
|
277
src/compositor/mutter-shaped-texture.c
Executable file → Normal file
277
src/compositor/mutter-shaped-texture.c
Executable file → Normal file
@@ -26,19 +26,27 @@
|
||||
#include <config.h>
|
||||
|
||||
#include "mutter-shaped-texture.h"
|
||||
#include "mutter-texture-tower.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static void mutter_shaped_texture_dispose (GObject *object);
|
||||
static void mutter_shaped_texture_finalize (GObject *object);
|
||||
static void mutter_shaped_texture_notify (GObject *object,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void mutter_shaped_texture_paint (ClutterActor *actor);
|
||||
static void mutter_shaped_texture_pick (ClutterActor *actor,
|
||||
const ClutterColor *color);
|
||||
|
||||
static void mutter_shaped_texture_update_area (ClutterX11TexturePixmap *texture,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
static void mutter_shaped_texture_dirty_mask (MutterShapedTexture *stex);
|
||||
|
||||
#ifdef HAVE_GLX_TEXTURE_PIXMAP
|
||||
@@ -55,18 +63,18 @@ G_DEFINE_TYPE (MutterShapedTexture, mutter_shaped_texture,
|
||||
|
||||
struct _MutterShapedTexturePrivate
|
||||
{
|
||||
MutterTextureTower *paint_tower;
|
||||
CoglHandle mask_texture;
|
||||
CoglHandle material;
|
||||
CoglHandle material_unshaped;
|
||||
#if 1 /* see workaround comment in mutter_shaped_texture_paint */
|
||||
CoglHandle material_workaround;
|
||||
#endif
|
||||
|
||||
GdkRegion *clip_region;
|
||||
MetaRegion *clip_region;
|
||||
|
||||
guint mask_width, mask_height;
|
||||
|
||||
GArray *rectangles;
|
||||
|
||||
guint create_mipmaps : 1;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -74,13 +82,17 @@ mutter_shaped_texture_class_init (MutterShapedTextureClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
|
||||
ClutterX11TexturePixmapClass *x11_texture_class = (ClutterX11TexturePixmapClass *) klass;
|
||||
|
||||
gobject_class->dispose = mutter_shaped_texture_dispose;
|
||||
gobject_class->finalize = mutter_shaped_texture_finalize;
|
||||
gobject_class->notify = mutter_shaped_texture_notify;
|
||||
|
||||
actor_class->paint = mutter_shaped_texture_paint;
|
||||
actor_class->pick = mutter_shaped_texture_pick;
|
||||
|
||||
x11_texture_class->update_area = mutter_shaped_texture_update_area;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MutterShapedTexturePrivate));
|
||||
}
|
||||
|
||||
@@ -93,7 +105,9 @@ mutter_shaped_texture_init (MutterShapedTexture *self)
|
||||
|
||||
priv->rectangles = g_array_new (FALSE, FALSE, sizeof (XRectangle));
|
||||
|
||||
priv->paint_tower = mutter_texture_tower_new ();
|
||||
priv->mask_texture = COGL_INVALID_HANDLE;
|
||||
priv->create_mipmaps = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -102,25 +116,22 @@ mutter_shaped_texture_dispose (GObject *object)
|
||||
MutterShapedTexture *self = (MutterShapedTexture *) object;
|
||||
MutterShapedTexturePrivate *priv = self->priv;
|
||||
|
||||
if (priv->paint_tower)
|
||||
mutter_texture_tower_free (priv->paint_tower);
|
||||
priv->paint_tower = NULL;
|
||||
|
||||
mutter_shaped_texture_dirty_mask (self);
|
||||
|
||||
if (priv->material != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_material_unref (priv->material);
|
||||
cogl_handle_unref (priv->material);
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
}
|
||||
if (priv->material_unshaped != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_material_unref (priv->material_unshaped);
|
||||
cogl_handle_unref (priv->material_unshaped);
|
||||
priv->material_unshaped = COGL_INVALID_HANDLE;
|
||||
}
|
||||
#if 1 /* see comment in mutter_shaped_texture_paint */
|
||||
if (priv->material_workaround != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_material_unref (priv->material_workaround);
|
||||
priv->material_workaround = COGL_INVALID_HANDLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
mutter_shaped_texture_set_clip_region (self, NULL);
|
||||
|
||||
@@ -138,6 +149,31 @@ mutter_shaped_texture_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (mutter_shaped_texture_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_notify (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
if (G_OBJECT_CLASS (mutter_shaped_texture_parent_class)->notify)
|
||||
G_OBJECT_CLASS (mutter_shaped_texture_parent_class)->notify (object, pspec);
|
||||
|
||||
/* It seems like we could just do this out of update_area(), but unfortunately,
|
||||
* clutter_glx_texture_pixmap() doesn't call through the vtable on the
|
||||
* initial update_area, so we need to look for changes to the texture
|
||||
* explicitly.
|
||||
*/
|
||||
if (strcmp (pspec->name, "cogl-texture") == 0)
|
||||
{
|
||||
MutterShapedTexture *stex = (MutterShapedTexture *) object;
|
||||
MutterShapedTexturePrivate *priv = stex->priv;
|
||||
|
||||
mutter_shaped_texture_clear (stex);
|
||||
|
||||
if (priv->create_mipmaps)
|
||||
mutter_texture_tower_set_base_texture (priv->paint_tower,
|
||||
clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex)));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_dirty_mask (MutterShapedTexture *stex)
|
||||
{
|
||||
@@ -151,11 +187,14 @@ mutter_shaped_texture_dirty_mask (MutterShapedTexture *stex)
|
||||
cogl_texture_get_gl_texture (priv->mask_texture,
|
||||
&mask_gl_tex, &mask_gl_target);
|
||||
|
||||
if (mask_gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||
if (mask_gl_target == GL_TEXTURE_RECTANGLE_ARB)
|
||||
glDeleteTextures (1, &mask_gl_tex);
|
||||
|
||||
cogl_texture_unref (priv->mask_texture);
|
||||
cogl_handle_unref (priv->mask_texture);
|
||||
priv->mask_texture = COGL_INVALID_HANDLE;
|
||||
|
||||
if (priv->material != COGL_INVALID_HANDLE)
|
||||
cogl_material_set_layer (priv->material, 1, COGL_INVALID_HANDLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,23 +253,23 @@ mutter_shaped_texture_ensure_mask (MutterShapedTexture *stex)
|
||||
|
||||
cogl_texture_get_gl_texture (paint_tex, NULL, &paint_gl_target);
|
||||
|
||||
if (paint_gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||
if (paint_gl_target == GL_TEXTURE_RECTANGLE_ARB)
|
||||
{
|
||||
GLuint tex;
|
||||
|
||||
glGenTextures (1, &tex);
|
||||
glBindTexture (CGL_TEXTURE_RECTANGLE_ARB, tex);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, tex_width);
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glTexImage2D (CGL_TEXTURE_RECTANGLE_ARB, 0,
|
||||
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
|
||||
GL_ALPHA, tex_width, tex_height,
|
||||
0, GL_ALPHA, GL_UNSIGNED_BYTE, mask_data);
|
||||
|
||||
priv->mask_texture
|
||||
= cogl_texture_new_from_foreign (tex,
|
||||
CGL_TEXTURE_RECTANGLE_ARB,
|
||||
GL_TEXTURE_RECTANGLE_ARB,
|
||||
tex_width, tex_height,
|
||||
0, 0,
|
||||
COGL_PIXEL_FORMAT_A_8);
|
||||
@@ -258,18 +297,40 @@ mutter_shaped_texture_paint (ClutterActor *actor)
|
||||
CoglHandle paint_tex;
|
||||
guint tex_width, tex_height;
|
||||
ClutterActorBox alloc;
|
||||
CoglHandle material;
|
||||
#if 1 /* please see comment below about workaround */
|
||||
guint depth;
|
||||
#endif
|
||||
|
||||
if (priv->clip_region && gdk_region_empty (priv->clip_region))
|
||||
static CoglHandle material_template = COGL_INVALID_HANDLE;
|
||||
static CoglHandle material_unshaped_template = COGL_INVALID_HANDLE;
|
||||
|
||||
CoglHandle material;
|
||||
|
||||
if (priv->clip_region && meta_region_is_empty (priv->clip_region))
|
||||
return;
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
|
||||
clutter_actor_realize (CLUTTER_ACTOR (stex));
|
||||
|
||||
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
|
||||
/* The GL EXT_texture_from_pixmap extension does allow for it to be
|
||||
* used together with SGIS_generate_mipmap, however this is very
|
||||
* rarely supported. Also, even when it is supported there
|
||||
* are distinct performance implications from:
|
||||
*
|
||||
* - Updating mipmaps that we don't need
|
||||
* - Having to reallocate pixmaps on the server into larger buffers
|
||||
*
|
||||
* So, we just unconditionally use our mipmap emulation code. If we
|
||||
* wanted to use SGIS_generate_mipmap, we'd have to query COGL to
|
||||
* see if it was supported (no API currently), and then if and only
|
||||
* if that was the case, set the clutter texture quality to HIGH.
|
||||
* Setting the texture quality to high without SGIS_generate_mipmap
|
||||
* support for TFP textures will result in fallbacks to XGetImage.
|
||||
*/
|
||||
if (priv->create_mipmaps)
|
||||
paint_tex = mutter_texture_tower_get_paint_texture (priv->paint_tower);
|
||||
else
|
||||
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
|
||||
|
||||
if (paint_tex == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
tex_width = cogl_texture_get_width (paint_tex);
|
||||
tex_height = cogl_texture_get_height (paint_tex);
|
||||
@@ -277,17 +338,18 @@ mutter_shaped_texture_paint (ClutterActor *actor)
|
||||
if (tex_width == 0 || tex_height == 0) /* no contents yet */
|
||||
return;
|
||||
|
||||
if (paint_tex == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
if (priv->rectangles->len < 1)
|
||||
{
|
||||
/* If there are no rectangles use a single-layer texture */
|
||||
|
||||
if (priv->material_unshaped == COGL_INVALID_HANDLE)
|
||||
priv->material_unshaped = cogl_material_new ();
|
||||
if (priv->material_unshaped == COGL_INVALID_HANDLE)
|
||||
{
|
||||
if (G_UNLIKELY (material_unshaped_template == COGL_INVALID_HANDLE))
|
||||
material_unshaped_template = cogl_material_new ();
|
||||
|
||||
material = priv->material_unshaped;
|
||||
priv->material_unshaped = cogl_material_copy (material_unshaped_template);
|
||||
}
|
||||
material = priv->material_unshaped;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -295,43 +357,17 @@ mutter_shaped_texture_paint (ClutterActor *actor)
|
||||
|
||||
if (priv->material == COGL_INVALID_HANDLE)
|
||||
{
|
||||
priv->material = cogl_material_new ();
|
||||
|
||||
cogl_material_set_layer_combine (priv->material, 1,
|
||||
if (G_UNLIKELY (material_template == COGL_INVALID_HANDLE))
|
||||
{
|
||||
material_template = cogl_material_new ();
|
||||
cogl_material_set_layer_combine (material_template, 1,
|
||||
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
|
||||
NULL);
|
||||
}
|
||||
priv->material = cogl_material_copy (material_template);
|
||||
}
|
||||
material = priv->material;
|
||||
|
||||
#if 1
|
||||
/* This was added as a workaround. It seems that with the intel
|
||||
* drivers when multi-texturing using an RGB TFP texture, the
|
||||
* texture is actually setup internally as an RGBA texture, where
|
||||
* the alpha channel is mostly 0.0 so you only see a shimmer of the
|
||||
* window. This workaround forcibly defines the alpha channel as
|
||||
* 1.0. Maybe there is some clutter/cogl state that is interacting
|
||||
* with this that is being overlooked, but for now this seems to
|
||||
* work. */
|
||||
g_object_get (stex, "pixmap-depth", &depth, NULL);
|
||||
if (depth == 24)
|
||||
{
|
||||
if (priv->material_workaround == COGL_INVALID_HANDLE)
|
||||
{
|
||||
material = priv->material_workaround = cogl_material_new ();
|
||||
|
||||
cogl_material_set_layer_combine (material, 0,
|
||||
"RGB = MODULATE (TEXTURE, PREVIOUS)"
|
||||
"A = REPLACE (PREVIOUS)",
|
||||
NULL);
|
||||
cogl_material_set_layer_combine (material, 1,
|
||||
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
|
||||
NULL);
|
||||
}
|
||||
|
||||
material = priv->material_workaround;
|
||||
}
|
||||
#endif
|
||||
|
||||
cogl_material_set_layer (material, 1, priv->mask_texture);
|
||||
}
|
||||
|
||||
@@ -359,7 +395,7 @@ mutter_shaped_texture_paint (ClutterActor *actor)
|
||||
# define MAX_RECTS 16
|
||||
|
||||
/* Would be nice to be able to check the number of rects first */
|
||||
gdk_region_get_rectangles (priv->clip_region, &rects, &n_rects);
|
||||
meta_region_get_rectangles (priv->clip_region, &rects, &n_rects);
|
||||
if (n_rects > MAX_RECTS)
|
||||
{
|
||||
g_free (rects);
|
||||
@@ -367,24 +403,34 @@ mutter_shaped_texture_paint (ClutterActor *actor)
|
||||
}
|
||||
else
|
||||
{
|
||||
float coords[MAX_RECTS * 8];
|
||||
float coords[8];
|
||||
float x1, y1, x2, y2;
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
GdkRectangle *rect = &rects[i];
|
||||
|
||||
coords[i * 8 + 0] = rect->x;
|
||||
coords[i * 8 + 1] = rect->y;
|
||||
coords[i * 8 + 2] = rect->x + rect->width;
|
||||
coords[i * 8 + 3] = rect->y + rect->height;
|
||||
coords[i * 8 + 4] = rect->x / (alloc.x2 - alloc.x1);
|
||||
coords[i * 8 + 5] = rect->y / (alloc.y2 - alloc.y1);
|
||||
coords[i * 8 + 6] = (rect->x + rect->width) / (alloc.x2 - alloc.x1);
|
||||
coords[i * 8 + 7] = (rect->y + rect->height) / (alloc.y2 - alloc.y1);
|
||||
}
|
||||
x1 = rect->x;
|
||||
y1 = rect->y;
|
||||
x2 = rect->x + rect->width;
|
||||
y2 = rect->y + rect->height;
|
||||
|
||||
coords[0] = rect->x / (alloc.x2 - alloc.x1);
|
||||
coords[1] = rect->y / (alloc.y2 - alloc.y1);
|
||||
coords[2] = (rect->x + rect->width) / (alloc.x2 - alloc.x1);
|
||||
coords[3] = (rect->y + rect->height) / (alloc.y2 - alloc.y1);
|
||||
|
||||
coords[4] = coords[0];
|
||||
coords[5] = coords[1];
|
||||
coords[6] = coords[2];
|
||||
coords[7] = coords[3];
|
||||
|
||||
cogl_rectangle_with_multitexture_coords (x1, y1, x2, y2,
|
||||
&coords[0], 8);
|
||||
}
|
||||
|
||||
g_free (rects);
|
||||
|
||||
cogl_rectangles_with_texture_coords (coords, n_rects);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -438,6 +484,22 @@ mutter_shaped_texture_pick (ClutterActor *actor,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_update_area (ClutterX11TexturePixmap *texture,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
MutterShapedTexture *stex = (MutterShapedTexture *) texture;
|
||||
MutterShapedTexturePrivate *priv = stex->priv;
|
||||
|
||||
CLUTTER_X11_TEXTURE_PIXMAP_CLASS (mutter_shaped_texture_parent_class)->update_area (texture,
|
||||
x, y, width, height);
|
||||
|
||||
mutter_texture_tower_update_area (priv->paint_tower, x, y, width, height);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_shaped_texture_new (void)
|
||||
{
|
||||
@@ -446,6 +508,65 @@ mutter_shaped_texture_new (void)
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
mutter_shaped_texture_set_create_mipmaps (MutterShapedTexture *stex,
|
||||
gboolean create_mipmaps)
|
||||
{
|
||||
MutterShapedTexturePrivate *priv;
|
||||
|
||||
g_return_if_fail (MUTTER_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
create_mipmaps = create_mipmaps != FALSE;
|
||||
|
||||
if (create_mipmaps != priv->create_mipmaps)
|
||||
{
|
||||
CoglHandle base_texture;
|
||||
|
||||
priv->create_mipmaps = create_mipmaps;
|
||||
|
||||
base_texture = create_mipmaps ?
|
||||
clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex)) : COGL_INVALID_HANDLE;
|
||||
|
||||
mutter_texture_tower_set_base_texture (priv->paint_tower, base_texture);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is a workaround for deficiencies in the hack tower:
|
||||
*
|
||||
* When we call clutter_x11_texture_pixmap_set_pixmap(tp, None),
|
||||
* ClutterX11TexturePixmap knows that it has to get rid of the old texture, but
|
||||
* clutter_texture_set_cogl_texture(texture, COGL_INVALID_HANDLE) isn't allowed, so
|
||||
* it grabs the material for the texture and manually sets the texture in it. This means
|
||||
* that the "cogl-texture" property isn't notified, so we don't find out about it.
|
||||
*
|
||||
* And if we keep the CoglX11TexturePixmap around after the X pixmap is freed, then
|
||||
* we'll trigger X errors when we actually try to free it.
|
||||
*
|
||||
* The only correct thing to do here is to change our code to derive
|
||||
* from ClutterActor and get rid of the inheritance hack tower. Once
|
||||
* we want to depend on Clutter-1.4 (which has CoglTexturePixmapX11),
|
||||
* that will be very easy to do.
|
||||
*/
|
||||
void
|
||||
mutter_shaped_texture_clear (MutterShapedTexture *stex)
|
||||
{
|
||||
MutterShapedTexturePrivate *priv;
|
||||
|
||||
g_return_if_fail (MUTTER_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
mutter_texture_tower_set_base_texture (priv->paint_tower, COGL_INVALID_HANDLE);
|
||||
|
||||
if (priv->material != COGL_INVALID_HANDLE)
|
||||
cogl_material_set_layer (priv->material, 0, COGL_INVALID_HANDLE);
|
||||
|
||||
if (priv->material_unshaped != COGL_INVALID_HANDLE)
|
||||
cogl_material_set_layer (priv->material_unshaped, 0, COGL_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_shaped_texture_clear_rectangles (MutterShapedTexture *stex)
|
||||
{
|
||||
@@ -503,7 +624,7 @@ mutter_shaped_texture_add_rectangles (MutterShapedTexture *stex,
|
||||
*/
|
||||
void
|
||||
mutter_shaped_texture_set_clip_region (MutterShapedTexture *stex,
|
||||
GdkRegion *clip_region)
|
||||
MetaRegion *clip_region)
|
||||
{
|
||||
MutterShapedTexturePrivate *priv;
|
||||
|
||||
@@ -513,7 +634,7 @@ mutter_shaped_texture_set_clip_region (MutterShapedTexture *stex,
|
||||
|
||||
if (priv->clip_region)
|
||||
{
|
||||
gdk_region_destroy (priv->clip_region);
|
||||
meta_region_destroy (priv->clip_region);
|
||||
priv->clip_region = NULL;
|
||||
}
|
||||
|
||||
|
@@ -26,12 +26,14 @@
|
||||
#ifndef __MUTTER_SHAPED_TEXTURE_H__
|
||||
#define __MUTTER_SHAPED_TEXTURE_H__
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#ifdef HAVE_GLX_TEXTURE_PIXMAP
|
||||
#include <clutter/glx/clutter-glx.h>
|
||||
#endif /* HAVE_GLX_TEXTURE_PIXMAP */
|
||||
|
||||
#include <gdk/gdkregion.h>
|
||||
#include "region.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -84,6 +86,11 @@ GType mutter_shaped_texture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor *mutter_shaped_texture_new (void);
|
||||
|
||||
void mutter_shaped_texture_set_create_mipmaps (MutterShapedTexture *stex,
|
||||
gboolean create_mipmaps);
|
||||
|
||||
void mutter_shaped_texture_clear (MutterShapedTexture *stex);
|
||||
|
||||
void mutter_shaped_texture_clear_rectangles (MutterShapedTexture *stex);
|
||||
|
||||
void mutter_shaped_texture_add_rectangle (MutterShapedTexture *stex,
|
||||
@@ -94,7 +101,7 @@ void mutter_shaped_texture_add_rectangles (MutterShapedTexture *stex,
|
||||
|
||||
/* Assumes ownership of clip_region */
|
||||
void mutter_shaped_texture_set_clip_region (MutterShapedTexture *stex,
|
||||
GdkRegion *clip_region);
|
||||
MetaRegion *clip_region);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
654
src/compositor/mutter-texture-tower.c
Normal file
654
src/compositor/mutter-texture-tower.c
Normal file
@@ -0,0 +1,654 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* MutterTextureTower
|
||||
*
|
||||
* Mipmap emulation by creation of scaled down images
|
||||
*
|
||||
* Copyright (C) 2009 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 <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mutter-texture-tower.h"
|
||||
|
||||
#ifndef M_LOG2E
|
||||
#define M_LOG2E 1.4426950408889634074
|
||||
#endif
|
||||
|
||||
#define MAX_TEXTURE_LEVELS 12
|
||||
|
||||
/* If the texture format in memory doesn't match this, then Mesa
|
||||
* will do the conversion, so things will still work, but it might
|
||||
* be slow depending on how efficient Mesa is. These should be the
|
||||
* native formats unless the display is 16bpp. If conversions
|
||||
* here are a bottleneck, investigate whether we are converting when
|
||||
* storing window data *into* the texture before adding extra code
|
||||
* to handle multiple texture formats.
|
||||
*/
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_BGRA_8888_PRE
|
||||
#else
|
||||
#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_ARGB_8888_PRE
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint16 x1;
|
||||
guint16 y1;
|
||||
guint16 x2;
|
||||
guint16 y2;
|
||||
} Box;
|
||||
|
||||
struct _MutterTextureTower
|
||||
{
|
||||
int n_levels;
|
||||
CoglHandle textures[MAX_TEXTURE_LEVELS];
|
||||
CoglHandle fbos[MAX_TEXTURE_LEVELS];
|
||||
Box invalid[MAX_TEXTURE_LEVELS];
|
||||
};
|
||||
|
||||
/**
|
||||
* mutter_texture_tower_new:
|
||||
*
|
||||
* Creates a new texture tower. The base texture has to be set with
|
||||
* mutter_texture_tower_set_base_texture() before use.
|
||||
*
|
||||
* Return value: the new texture tower. Free with mutter_texture_tower_free()
|
||||
*/
|
||||
MutterTextureTower *
|
||||
mutter_texture_tower_new (void)
|
||||
{
|
||||
MutterTextureTower *tower;
|
||||
|
||||
tower = g_slice_new0 (MutterTextureTower);
|
||||
|
||||
return tower;
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_texture_tower_free:
|
||||
* @tower: a #MutterTextureTower
|
||||
*
|
||||
* Frees a texture tower created with mutter_texture_tower_new().
|
||||
*/
|
||||
void
|
||||
mutter_texture_tower_free (MutterTextureTower *tower)
|
||||
{
|
||||
g_return_if_fail (tower != NULL);
|
||||
|
||||
mutter_texture_tower_set_base_texture (tower, COGL_INVALID_HANDLE);
|
||||
|
||||
g_slice_free (MutterTextureTower, tower);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
texture_is_rectangle (CoglHandle texture)
|
||||
{
|
||||
GLuint gl_tex;
|
||||
GLenum gl_target;
|
||||
|
||||
cogl_texture_get_gl_texture (texture, &gl_tex, &gl_target);
|
||||
return gl_target == GL_TEXTURE_RECTANGLE_ARB;
|
||||
}
|
||||
|
||||
static void
|
||||
free_texture (CoglHandle texture)
|
||||
{
|
||||
GLuint gl_tex;
|
||||
GLenum gl_target;
|
||||
|
||||
cogl_texture_get_gl_texture (texture, &gl_tex, &gl_target);
|
||||
|
||||
if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
|
||||
glDeleteTextures (1, &gl_tex);
|
||||
|
||||
cogl_handle_unref (texture);
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_texture_tower_update_area:
|
||||
* @tower: a MutterTextureTower
|
||||
* @texture: the new texture used as a base for scaled down versions
|
||||
*
|
||||
* Sets the base texture that is the scaled texture that the
|
||||
* scaled textures of the tower are derived from. The texture itself
|
||||
* will be used as level 0 of the tower and will be referenced until
|
||||
* unset or until the tower is freed.
|
||||
*/
|
||||
void
|
||||
mutter_texture_tower_set_base_texture (MutterTextureTower *tower,
|
||||
CoglHandle texture)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_return_if_fail (tower != NULL);
|
||||
|
||||
if (texture == tower->textures[0])
|
||||
return;
|
||||
|
||||
if (tower->textures[0] != COGL_INVALID_HANDLE)
|
||||
{
|
||||
for (i = 1; i < tower->n_levels; i++)
|
||||
{
|
||||
if (tower->textures[i] != COGL_INVALID_HANDLE)
|
||||
{
|
||||
free_texture (tower->textures[i]);
|
||||
tower->textures[i] = COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (tower->fbos[i] != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_handle_unref (tower->fbos[i]);
|
||||
tower->fbos[i] = COGL_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
cogl_handle_unref (tower->textures[0]);
|
||||
}
|
||||
|
||||
tower->textures[0] = texture;
|
||||
|
||||
if (tower->textures[0] != COGL_INVALID_HANDLE)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
cogl_handle_ref (tower->textures[0]);
|
||||
|
||||
width = cogl_texture_get_width (tower->textures[0]);
|
||||
height = cogl_texture_get_height (tower->textures[0]);
|
||||
|
||||
tower->n_levels = 1 + MAX ((int)(M_LOG2E * log (width)), (int)(M_LOG2E * log (height)));
|
||||
tower->n_levels = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);
|
||||
|
||||
mutter_texture_tower_update_area (tower, 0, 0, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
tower->n_levels = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_texture_tower_update_area:
|
||||
* @tower: a MutterTextureTower
|
||||
* @x: X coordinate of upper left of rectangle that changed
|
||||
* @y: Y coordinate of upper left of rectangle that changed
|
||||
* @width: width of rectangle that changed
|
||||
* @height: height rectangle that changed
|
||||
*
|
||||
* Mark a region of the base texture as having changed; the next
|
||||
* time a scaled down version of the base texture is retrieved,
|
||||
* the appropriate area of the scaled down texture will be updated.
|
||||
*/
|
||||
void
|
||||
mutter_texture_tower_update_area (MutterTextureTower *tower,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
int texture_width, texture_height;
|
||||
Box invalid;
|
||||
int i;
|
||||
|
||||
g_return_if_fail (tower != NULL);
|
||||
|
||||
texture_width = cogl_texture_get_width (tower->textures[0]);
|
||||
texture_height = cogl_texture_get_height (tower->textures[0]);
|
||||
|
||||
invalid.x1 = x;
|
||||
invalid.y1 = y;
|
||||
invalid.x2 = x + width;
|
||||
invalid.y2 = y + height;
|
||||
|
||||
for (i = 1; i < tower->n_levels; i++)
|
||||
{
|
||||
texture_width = MAX (1, texture_width / 2);
|
||||
texture_height = MAX (1, texture_height / 2);
|
||||
|
||||
invalid.x1 = invalid.x1 / 2;
|
||||
invalid.y1 = invalid.y1 / 2;
|
||||
invalid.x2 = MIN (texture_width, (invalid.x2 + 1) / 2);
|
||||
invalid.y2 = MIN (texture_height, (invalid.y2 + 1) / 2);
|
||||
|
||||
if (tower->invalid[i].x1 == tower->invalid[i].x2 ||
|
||||
tower->invalid[i].y1 == tower->invalid[i].y2)
|
||||
{
|
||||
tower->invalid[i] = invalid;
|
||||
}
|
||||
else
|
||||
{
|
||||
tower->invalid[i].x1 = MIN (tower->invalid[i].x1, invalid.x1);
|
||||
tower->invalid[i].y1 = MIN (tower->invalid[i].y1, invalid.y1);
|
||||
tower->invalid[i].x2 = MAX (tower->invalid[i].x2, invalid.x2);
|
||||
tower->invalid[i].y2 = MAX (tower->invalid[i].y2, invalid.y2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* It generally looks worse if we scale up a window texture by even a
|
||||
* small amount than if we scale it down using bilinear filtering, so
|
||||
* we always pick the *larger* adjacent level. */
|
||||
#define LOD_BIAS (-0.49)
|
||||
|
||||
/* This determines the appropriate level of detail to use when drawing the
|
||||
* texture, in a way that corresponds to what the GL specification does
|
||||
* when mip-mapping. This is probably fancier and slower than what we need,
|
||||
* but we do the computation only once each time we paint a window, and
|
||||
* its easier to just use the equations from the specification than to
|
||||
* come up with something simpler.
|
||||
*
|
||||
* If window is being painted at an angle from the viewer, then we have to
|
||||
* pick a point in the texture; we use the middle of the texture (which is
|
||||
* why the width/height are passed in.) This is not the normal case for
|
||||
* Mutter.
|
||||
*/
|
||||
static int
|
||||
get_paint_level (int width, int height)
|
||||
{
|
||||
CoglMatrix projection, modelview, pm;
|
||||
float v[4];
|
||||
double viewport_width, viewport_height;
|
||||
double u0, v0;
|
||||
double xc, yc, wc;
|
||||
double dxdu_, dxdv_, dydu_, dydv_;
|
||||
double det_, det_sq;
|
||||
double rho_sq;
|
||||
double lambda;
|
||||
|
||||
/* See
|
||||
* http://www.opengl.org/registry/doc/glspec32.core.20090803.pdf
|
||||
* Section 3.8.9, p. 1.6.2. Here we have
|
||||
*
|
||||
* u(x,y) = x_o;
|
||||
* v(x,y) = y_o;
|
||||
*
|
||||
* Since we are mapping 1:1 from object coordinates into pixel
|
||||
* texture coordinates, the clip coordinates are:
|
||||
*
|
||||
* (x_c) (x_o) (u)
|
||||
* (y_c) = (M_projection)(M_modelview) (y_o) = (PM) (v)
|
||||
* (z_c) (z_o) (0)
|
||||
* (w_c) (w_o) (1)
|
||||
*/
|
||||
|
||||
cogl_get_projection_matrix (&projection);
|
||||
cogl_get_modelview_matrix (&modelview);
|
||||
|
||||
cogl_matrix_multiply (&pm, &projection, &modelview);
|
||||
|
||||
cogl_get_viewport (v);
|
||||
viewport_width = v[2];
|
||||
viewport_height = v[3];
|
||||
|
||||
u0 = width / 2.;
|
||||
v0 = height / 2.;
|
||||
|
||||
xc = pm.xx * u0 + pm.xy * v0 + pm.xw;
|
||||
yc = pm.yx * u0 + pm.yy * v0 + pm.yw;
|
||||
wc = pm.wx * u0 + pm.wy * v0 + pm.ww;
|
||||
|
||||
/* We'll simplify the equations below for a bit of micro-optimization.
|
||||
* The commented out code is the unsimplified version.
|
||||
|
||||
// Partial derivates of window coordinates:
|
||||
//
|
||||
// x_w = 0.5 * viewport_width * x_c / w_c + viewport_center_x
|
||||
// y_w = 0.5 * viewport_height * y_c / w_c + viewport_center_y
|
||||
//
|
||||
// with respect to u, v, using
|
||||
// d(a/b)/dx = da/dx * (1/b) - a * db/dx / (b^2)
|
||||
|
||||
dxdu = 0.5 * viewport_width * (pm.xx - pm.wx * (xc/wc)) / wc;
|
||||
dxdv = 0.5 * viewport_width * (pm.xy - pm.wy * (xc/wc)) / wc;
|
||||
dydu = 0.5 * viewport_height * (pm.yx - pm.wx * (yc/wc)) / wc;
|
||||
dydv = 0.5 * viewport_height * (pm.yy - pm.wy * (yc/wc)) / wc;
|
||||
|
||||
// Compute the inverse partials as the matrix inverse
|
||||
det = dxdu * dydv - dxdv * dydu;
|
||||
|
||||
dudx = dydv / det;
|
||||
dudy = - dxdv / det;
|
||||
dvdx = - dydu / det;
|
||||
dvdy = dvdu / det;
|
||||
|
||||
// Scale factor; maximum of the distance in texels for a change of 1 pixel
|
||||
// in the X direction or 1 pixel in the Y direction
|
||||
rho = MAX (sqrt (dudx * dudx + dvdx * dvdx), sqrt(dudy * dudy + dvdy * dvdy));
|
||||
|
||||
// Level of detail
|
||||
lambda = log2 (rho) + LOD_BIAS;
|
||||
*/
|
||||
|
||||
/* dxdu * wc, etc */
|
||||
dxdu_ = 0.5 * viewport_width * (pm.xx - pm.wx * (xc/wc));
|
||||
dxdv_ = 0.5 * viewport_width * (pm.xy - pm.wy * (xc/wc));
|
||||
dydu_ = 0.5 * viewport_height * (pm.yx - pm.wx * (yc/wc));
|
||||
dydv_ = 0.5 * viewport_height * (pm.yy - pm.wy * (yc/wc));
|
||||
|
||||
/* det * wc^2 */
|
||||
det_ = dxdu_ * dydv_ - dxdv_ * dydu_;
|
||||
det_sq = det_ * det_;
|
||||
if (det_sq == 0.0)
|
||||
return -1;
|
||||
|
||||
/* (rho * det * wc)^2 */
|
||||
rho_sq = MAX (dydv_ * dydv_ + dydu_ * dydu_, dxdv_ * dxdv_ + dxdu_ * dxdu_);
|
||||
lambda = 0.5 * M_LOG2E * log (rho_sq * wc * wc / det_sq) + LOD_BIAS;
|
||||
|
||||
#if 0
|
||||
g_print ("%g %g %g\n", 0.5 * viewport_width * pm.xx / pm.ww, 0.5 * viewport_height * pm.yy / pm.ww, lambda);
|
||||
#endif
|
||||
|
||||
if (lambda <= 0.)
|
||||
return 0;
|
||||
else
|
||||
return (int)(0.5 + lambda);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_power_of_two (int x)
|
||||
{
|
||||
return (x & (x - 1)) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
texture_tower_create_texture (MutterTextureTower *tower,
|
||||
int level,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
|
||||
texture_is_rectangle (tower->textures[level - 1]))
|
||||
{
|
||||
GLuint tex = 0;
|
||||
|
||||
glGenTextures (1, &tex);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
|
||||
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
|
||||
GL_RGBA, width,height,
|
||||
#if TEXTURE_FORMAT == COGL_PIXEL_FORMAT_BGRA_8888_PRE
|
||||
0, GL_BGRA, GL_UNSIGNED_BYTE,
|
||||
#else /* assume big endian */
|
||||
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
#endif
|
||||
NULL);
|
||||
|
||||
tower->textures[level] = cogl_texture_new_from_foreign (tex, GL_TEXTURE_RECTANGLE_ARB,
|
||||
width, height,
|
||||
0, 0,
|
||||
TEXTURE_FORMAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
tower->textures[level] = cogl_texture_new_with_size (width, height,
|
||||
COGL_TEXTURE_NO_AUTO_MIPMAP,
|
||||
TEXTURE_FORMAT);
|
||||
}
|
||||
|
||||
tower->invalid[level].x1 = 0;
|
||||
tower->invalid[level].y1 = 0;
|
||||
tower->invalid[level].x2 = width;
|
||||
tower->invalid[level].y2 = height;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
texture_tower_revalidate_fbo (MutterTextureTower *tower,
|
||||
int level)
|
||||
{
|
||||
CoglHandle source_texture = tower->textures[level - 1];
|
||||
int source_texture_width = cogl_texture_get_width (source_texture);
|
||||
int source_texture_height = cogl_texture_get_height (source_texture);
|
||||
CoglHandle dest_texture = tower->textures[level];
|
||||
int dest_texture_width = cogl_texture_get_width (dest_texture);
|
||||
int dest_texture_height = cogl_texture_get_height (dest_texture);
|
||||
Box *invalid = &tower->invalid[level];
|
||||
CoglMatrix modelview;
|
||||
|
||||
if (tower->fbos[level] == COGL_INVALID_HANDLE)
|
||||
{
|
||||
/* Work around http://bugzilla.openedhand.com/show_bug.cgi?id=2110 */
|
||||
cogl_flush();
|
||||
|
||||
tower->fbos[level] = cogl_offscreen_new_to_texture (dest_texture);
|
||||
}
|
||||
|
||||
if (tower->fbos[level] == COGL_INVALID_HANDLE)
|
||||
return FALSE;
|
||||
|
||||
cogl_push_framebuffer (tower->fbos[level]);
|
||||
|
||||
cogl_ortho (0, dest_texture_width, dest_texture_height, 0, -1., 1.);
|
||||
|
||||
cogl_matrix_init_identity (&modelview);
|
||||
cogl_set_modelview_matrix (&modelview);
|
||||
|
||||
cogl_set_source_texture (tower->textures[level - 1]);
|
||||
cogl_rectangle_with_texture_coords (invalid->x1, invalid->y1,
|
||||
invalid->x2, invalid->y2,
|
||||
(2. * invalid->x1) / source_texture_width,
|
||||
(2. * invalid->y1) / source_texture_height,
|
||||
(2. * invalid->x2) / source_texture_width,
|
||||
(2. * invalid->y2) / source_texture_height);
|
||||
|
||||
cogl_pop_framebuffer ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_copy (guchar *buf,
|
||||
const guchar *source,
|
||||
int width)
|
||||
{
|
||||
memcpy (buf, source, width * 4);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_scale_down (guchar *buf,
|
||||
const guchar *source,
|
||||
int width)
|
||||
{
|
||||
while (width > 1)
|
||||
{
|
||||
buf[0] = (source[0] + source[4]) / 2;
|
||||
buf[1] = (source[1] + source[5]) / 2;
|
||||
buf[2] = (source[2] + source[6]) / 2;
|
||||
buf[3] = (source[3] + source[7]) / 2;
|
||||
|
||||
buf += 4;
|
||||
source += 8;
|
||||
width -= 2;
|
||||
}
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
buf[0] = source[0] / 2;
|
||||
buf[1] = source[1] / 2;
|
||||
buf[2] = source[2] / 2;
|
||||
buf[3] = source[3] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
texture_tower_revalidate_client (MutterTextureTower *tower,
|
||||
int level)
|
||||
{
|
||||
CoglHandle source_texture = tower->textures[level - 1];
|
||||
int source_texture_width = cogl_texture_get_width (source_texture);
|
||||
int source_texture_height = cogl_texture_get_height (source_texture);
|
||||
guint source_rowstride;
|
||||
guchar *source_data;
|
||||
CoglHandle dest_texture = tower->textures[level];
|
||||
int dest_texture_width = cogl_texture_get_width (dest_texture);
|
||||
int dest_texture_height = cogl_texture_get_height (dest_texture);
|
||||
int dest_x = tower->invalid[level].x1;
|
||||
int dest_y = tower->invalid[level].y1;
|
||||
int dest_width = tower->invalid[level].x2 - tower->invalid[level].x1;
|
||||
int dest_height = tower->invalid[level].y2 - tower->invalid[level].y1;
|
||||
guchar *dest_data;
|
||||
guchar *source_tmp1 = NULL, *source_tmp2 = NULL;
|
||||
int i, j;
|
||||
|
||||
source_rowstride = source_texture_width * 4;
|
||||
|
||||
source_data = g_malloc (source_texture_height * source_rowstride);
|
||||
cogl_texture_get_data (source_texture, TEXTURE_FORMAT, source_rowstride,
|
||||
source_data);
|
||||
|
||||
dest_data = g_malloc (dest_height * dest_width * 4);
|
||||
|
||||
if (dest_texture_height < source_texture_height)
|
||||
{
|
||||
source_tmp1 = g_malloc (dest_width * 4);
|
||||
source_tmp2 = g_malloc (dest_width * 4);
|
||||
}
|
||||
|
||||
for (i = 0; i < dest_height; i++)
|
||||
{
|
||||
guchar *dest_row = dest_data + i * dest_width * 4;
|
||||
if (dest_texture_height < source_texture_height)
|
||||
{
|
||||
guchar *source1, *source2;
|
||||
guchar *dest;
|
||||
|
||||
if (dest_texture_width < source_texture_width)
|
||||
{
|
||||
fill_scale_down (source_tmp1,
|
||||
source_data + ((i + dest_y) * 2) * source_rowstride + dest_x * 2 * 4,
|
||||
dest_width * 2);
|
||||
fill_scale_down (source_tmp2,
|
||||
source_data + ((i + dest_y) * 2 + 1) * source_rowstride + dest_x * 2 * 4,
|
||||
dest_width * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill_copy (source_tmp1,
|
||||
source_data + ((i + dest_y) * 2) * source_rowstride + dest_x * 4,
|
||||
dest_width);
|
||||
fill_copy (source_tmp2,
|
||||
source_data + ((i + dest_y) * 2 + 1) * source_rowstride + dest_x * 4,
|
||||
dest_width);
|
||||
}
|
||||
|
||||
source1 = source_tmp1;
|
||||
source2 = source_tmp2;
|
||||
|
||||
dest = dest_row;
|
||||
for (j = 0; j < dest_width * 4; j++)
|
||||
*(dest++) = (*(source1++) + *(source2++)) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dest_texture_width < source_texture_width)
|
||||
fill_scale_down (dest_row,
|
||||
source_data + (i + dest_y) * source_rowstride + dest_x * 2 * 4,
|
||||
dest_width * 2);
|
||||
else
|
||||
fill_copy (dest_row,
|
||||
source_data + (i + dest_y) * source_rowstride,
|
||||
dest_width);
|
||||
}
|
||||
}
|
||||
|
||||
cogl_texture_set_region (dest_texture,
|
||||
0, 0,
|
||||
dest_x, dest_y,
|
||||
dest_width, dest_height,
|
||||
dest_width, dest_height,
|
||||
TEXTURE_FORMAT,
|
||||
4 * dest_width,
|
||||
dest_data);
|
||||
|
||||
if (dest_height < source_texture_height)
|
||||
{
|
||||
g_free (source_tmp1);
|
||||
g_free (source_tmp2);
|
||||
}
|
||||
|
||||
g_free (source_data);
|
||||
g_free (dest_data);
|
||||
}
|
||||
|
||||
static void
|
||||
texture_tower_revalidate (MutterTextureTower *tower,
|
||||
int level)
|
||||
{
|
||||
if (!texture_tower_revalidate_fbo (tower, level))
|
||||
texture_tower_revalidate_client (tower, level);
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_texture_tower_get_paint_texture:
|
||||
* @tower: a MutterTextureTower
|
||||
*
|
||||
* Gets the texture from the tower that best matches the current
|
||||
* rendering scale. (On the assumption here the texture is going to
|
||||
* be rendered with vertex coordinates that correspond to its
|
||||
* size in pixels, so a 200x200 texture will be rendered on the
|
||||
* rectangle (0, 0, 200, 200).
|
||||
*
|
||||
* Return value: the COGL texture handle to use for painting, or
|
||||
* %COGL_INVALID_HANDLE if no base texture has yet been set.
|
||||
*/
|
||||
CoglHandle
|
||||
mutter_texture_tower_get_paint_texture (MutterTextureTower *tower)
|
||||
{
|
||||
int texture_width, texture_height;
|
||||
int level;
|
||||
|
||||
g_return_val_if_fail (tower != NULL, COGL_INVALID_HANDLE);
|
||||
|
||||
if (tower->textures[0] == COGL_INVALID_HANDLE)
|
||||
return COGL_INVALID_HANDLE;
|
||||
|
||||
texture_width = cogl_texture_get_width (tower->textures[0]);
|
||||
texture_height = cogl_texture_get_height (tower->textures[0]);
|
||||
|
||||
level = get_paint_level(texture_width, texture_height);
|
||||
if (level < 0) /* singular paint matrix, scaled to nothing */
|
||||
return COGL_INVALID_HANDLE;
|
||||
level = MIN (level, tower->n_levels - 1);
|
||||
|
||||
if (tower->textures[level] == COGL_INVALID_HANDLE ||
|
||||
(tower->invalid[level].x2 != tower->invalid[level].x1 &&
|
||||
tower->invalid[level].y2 != tower->invalid[level].y1))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= level; i++)
|
||||
{
|
||||
/* Use "floor" convention here to be consistent with the NPOT texture extension */
|
||||
texture_width = MAX (1, texture_width / 2);
|
||||
texture_height = MAX (1, texture_height / 2);
|
||||
|
||||
if (tower->textures[i] == COGL_INVALID_HANDLE)
|
||||
texture_tower_create_texture (tower, i, texture_width, texture_height);
|
||||
}
|
||||
|
||||
for (i = 1; i <= level; i++)
|
||||
{
|
||||
if (tower->invalid[level].x2 != tower->invalid[level].x1 &&
|
||||
tower->invalid[level].y2 != tower->invalid[level].y1)
|
||||
texture_tower_revalidate (tower, i);
|
||||
}
|
||||
}
|
||||
|
||||
return tower->textures[level];
|
||||
}
|
69
src/compositor/mutter-texture-tower.h
Normal file
69
src/compositor/mutter-texture-tower.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* MutterTextureTower
|
||||
*
|
||||
* Mipmap emulation by creation of scaled down images
|
||||
*
|
||||
* Copyright (C) 2009 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 __MUTTER_TEXTURE_TOWER_H__
|
||||
#define __MUTTER_TEXTURE_TOWER_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:MutterTextureTower
|
||||
* @short_description: mipmap emulation by creation of scaled down images
|
||||
*
|
||||
* A #MutterTextureTower is used to get good looking scaled down images when
|
||||
* we can't use the GL drivers mipmap support. There are two separate reasons
|
||||
*
|
||||
* - Some cards (including radeon cards <= r5xx) only support
|
||||
* TEXTURE_RECTANGLE_ARB and not NPOT textures. Rectangular textures
|
||||
* are defined not to support mipmapping.
|
||||
* - Even when NPOT textures are available, the combination of NPOT
|
||||
* textures, texture_from_pixmap, and mipmapping doesn't typically
|
||||
* work, since the X server doesn't allocate pixmaps in the right
|
||||
* layout for mipmapping.
|
||||
*
|
||||
* So, what we do is create the "mipmap" levels ourselves by successive
|
||||
* power-of-two scaledowns, and when rendering pick the single texture
|
||||
* that best matches the scale we are rendering at. (Since we aren't
|
||||
* typically using perspective transforms, we'll frequently have a single
|
||||
* scale for the entire texture.)
|
||||
*/
|
||||
|
||||
typedef struct _MutterTextureTower MutterTextureTower;
|
||||
|
||||
MutterTextureTower *mutter_texture_tower_new (void);
|
||||
void mutter_texture_tower_free (MutterTextureTower *tower);
|
||||
void mutter_texture_tower_set_base_texture (MutterTextureTower *tower,
|
||||
CoglHandle texture);
|
||||
void mutter_texture_tower_update_area (MutterTextureTower *tower,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
CoglHandle mutter_texture_tower_get_paint_texture (MutterTextureTower *tower);
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#endif /* __MUTTER_TEXTURE_TOWER_H__ */
|
@@ -1,10 +1,13 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define _ISOC99_SOURCE /* for roundf */
|
||||
#include <math.h>
|
||||
|
||||
#include "mutter-window-private.h"
|
||||
#include "mutter-window-group.h"
|
||||
#include "region.h"
|
||||
|
||||
struct _MutterWindowGroupClass
|
||||
{
|
||||
@@ -99,7 +102,7 @@ static void
|
||||
mutter_window_group_paint (ClutterActor *actor)
|
||||
{
|
||||
MutterWindowGroup *window_group = MUTTER_WINDOW_GROUP (actor);
|
||||
GdkRegion *visible_region;
|
||||
MetaRegion *visible_region;
|
||||
GdkRectangle screen_rect = { 0 };
|
||||
GList *children, *l;
|
||||
|
||||
@@ -116,7 +119,7 @@ mutter_window_group_paint (ClutterActor *actor)
|
||||
* optimization, however.)
|
||||
*/
|
||||
meta_screen_get_size (window_group->screen, &screen_rect.width, &screen_rect.height);
|
||||
visible_region = gdk_region_rectangle (&screen_rect);
|
||||
visible_region = meta_region_new_from_rectangle (&screen_rect);
|
||||
|
||||
for (l = children; l; l = l->next)
|
||||
{
|
||||
@@ -132,22 +135,22 @@ mutter_window_group_paint (ClutterActor *actor)
|
||||
continue;
|
||||
|
||||
/* Temporarily move to the coordinate system of the actor */
|
||||
gdk_region_offset (visible_region, - x, - y);
|
||||
meta_region_translate (visible_region, - x, - y);
|
||||
|
||||
mutter_window_set_visible_region (cw, visible_region);
|
||||
|
||||
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (cw)) == 0xff)
|
||||
{
|
||||
GdkRegion *obscured_region = mutter_window_get_obscured_region (cw);
|
||||
MetaRegion *obscured_region = mutter_window_get_obscured_region (cw);
|
||||
if (obscured_region)
|
||||
gdk_region_subtract (visible_region, obscured_region);
|
||||
meta_region_subtract (visible_region, obscured_region);
|
||||
}
|
||||
|
||||
mutter_window_set_visible_region_beneath (cw, visible_region);
|
||||
gdk_region_offset (visible_region, x, y);
|
||||
meta_region_translate (visible_region, x, y);
|
||||
}
|
||||
|
||||
gdk_region_destroy (visible_region);
|
||||
meta_region_destroy (visible_region);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (mutter_window_group_parent_class)->paint (actor);
|
||||
|
||||
|
@@ -3,9 +3,11 @@
|
||||
#ifndef MUTTER_WINDOW_PRIVATE_H
|
||||
#define MUTTER_WINDOW_PRIVATE_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include "compositor-mutter.h"
|
||||
#include "region.h"
|
||||
|
||||
MutterWindow *mutter_window_new (MetaWindow *window);
|
||||
|
||||
@@ -30,19 +32,18 @@ void mutter_window_pre_paint (MutterWindow *self);
|
||||
gboolean mutter_window_effect_in_progress (MutterWindow *cw);
|
||||
void mutter_window_sync_actor_position (MutterWindow *cw);
|
||||
void mutter_window_sync_visibility (MutterWindow *cw);
|
||||
void mutter_window_update_window_type (MutterWindow *cw);
|
||||
void mutter_window_update_shape (MutterWindow *cw,
|
||||
gboolean shaped);
|
||||
void mutter_window_update_opacity (MutterWindow *cw);
|
||||
void mutter_window_mapped (MutterWindow *cw);
|
||||
void mutter_window_unmapped (MutterWindow *cw);
|
||||
|
||||
GdkRegion *mutter_window_get_obscured_region (MutterWindow *cw);
|
||||
MetaRegion *mutter_window_get_obscured_region (MutterWindow *cw);
|
||||
|
||||
void mutter_window_set_visible_region (MutterWindow *cw,
|
||||
GdkRegion *visible_region);
|
||||
MetaRegion *visible_region);
|
||||
void mutter_window_set_visible_region_beneath (MutterWindow *cw,
|
||||
GdkRegion *beneath_region);
|
||||
MetaRegion *beneath_region);
|
||||
void mutter_window_reset_visible_regions (MutterWindow *cw);
|
||||
|
||||
void mutter_window_effect_completed (MutterWindow *actor,
|
||||
|
@@ -34,7 +34,6 @@ struct _MutterWindowPrivate
|
||||
ClutterActor *shadow;
|
||||
Pixmap back_pixmap;
|
||||
|
||||
MetaCompWindowType type;
|
||||
Damage damage;
|
||||
|
||||
guint8 opacity;
|
||||
@@ -42,10 +41,12 @@ struct _MutterWindowPrivate
|
||||
gchar * desc;
|
||||
|
||||
/* If the window is shaped, a region that matches the shape */
|
||||
GdkRegion *shape_region;
|
||||
MetaRegion *shape_region;
|
||||
/* A rectangular region with the unshaped extends of the window
|
||||
* texture */
|
||||
GdkRegion *bounding_region;
|
||||
MetaRegion *bounding_region;
|
||||
|
||||
gint freeze_count;
|
||||
|
||||
/*
|
||||
* These need to be counters rather than flags, since more plugins
|
||||
@@ -65,7 +66,10 @@ struct _MutterWindowPrivate
|
||||
guint disposed : 1;
|
||||
guint redecorating : 1;
|
||||
|
||||
guint needs_repair : 1;
|
||||
guint needs_damage_all : 1;
|
||||
guint received_damage : 1;
|
||||
|
||||
guint needs_pixmap : 1;
|
||||
guint needs_reshape : 1;
|
||||
guint size_changed : 1;
|
||||
|
||||
@@ -272,9 +276,6 @@ mutter_meta_window_decorated_notify (MetaWindow *mw,
|
||||
priv->damage = None;
|
||||
}
|
||||
|
||||
g_hash_table_remove (info->windows_by_xid, (gpointer) priv->xwindow);
|
||||
g_hash_table_insert (info->windows_by_xid, (gpointer) new_xwindow, self);
|
||||
|
||||
g_free (priv->desc);
|
||||
priv->desc = NULL;
|
||||
|
||||
@@ -322,8 +323,6 @@ mutter_window_constructed (GObject *object)
|
||||
|
||||
compositor = meta_display_get_compositor (display);
|
||||
|
||||
mutter_window_update_window_type (self);
|
||||
|
||||
#ifdef HAVE_SHAPE
|
||||
/* Listen for ShapeNotify events on the window */
|
||||
if (meta_display_has_shape (display))
|
||||
@@ -335,7 +334,8 @@ mutter_window_constructed (GObject *object)
|
||||
if (priv->attrs.class == InputOnly)
|
||||
priv->damage = None;
|
||||
else
|
||||
priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportNonEmpty);
|
||||
priv->damage = XDamageCreate (xdisplay, xwindow,
|
||||
XDamageReportBoundingBox);
|
||||
|
||||
format = XRenderFindVisualFormat (xdisplay, priv->attrs.visual);
|
||||
|
||||
@@ -355,10 +355,6 @@ mutter_window_constructed (GObject *object)
|
||||
{
|
||||
priv->actor = mutter_shaped_texture_new ();
|
||||
|
||||
if (!clutter_glx_texture_pixmap_using_extension (
|
||||
CLUTTER_GLX_TEXTURE_PIXMAP (priv->actor)))
|
||||
g_warning ("NOTE: Not using GLX TFP!\n");
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (self), priv->actor);
|
||||
|
||||
/*
|
||||
@@ -421,7 +417,6 @@ mutter_window_dispose (GObject *object)
|
||||
}
|
||||
|
||||
info->windows = g_list_remove (info->windows, (gconstpointer) self);
|
||||
g_hash_table_remove (info->windows_by_xid, (gpointer) priv->xwindow);
|
||||
|
||||
/*
|
||||
* Release the extra reference we took on the actor.
|
||||
@@ -537,13 +532,6 @@ mutter_window_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutter_window_update_window_type (MutterWindow *self)
|
||||
{
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
priv->type = (MetaCompWindowType) meta_window_get_window_type (priv->window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_shaped (MetaDisplay *display, Window xwindow)
|
||||
{
|
||||
@@ -567,6 +555,7 @@ static gboolean
|
||||
mutter_window_has_shadow (MutterWindow *self)
|
||||
{
|
||||
MutterWindowPrivate * priv = self->priv;
|
||||
MetaWindowType window_type = meta_window_get_window_type (priv->window);
|
||||
|
||||
if (priv->no_shadow)
|
||||
return FALSE;
|
||||
@@ -620,17 +609,17 @@ mutter_window_has_shadow (MutterWindow *self)
|
||||
/*
|
||||
* Don't put shadow around DND icon windows
|
||||
*/
|
||||
if (priv->type == META_COMP_WINDOW_DND ||
|
||||
priv->type == META_COMP_WINDOW_DESKTOP)
|
||||
if (window_type == META_WINDOW_DND ||
|
||||
window_type == META_WINDOW_DESKTOP)
|
||||
{
|
||||
meta_verbose ("Window 0x%x has no shadow as it is DND or Desktop\n",
|
||||
(guint)priv->xwindow);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (priv->type == META_COMP_WINDOW_MENU
|
||||
if (window_type == META_WINDOW_MENU
|
||||
#if 0
|
||||
|| priv->type == META_COMP_WINDOW_DROPDOWN_MENU
|
||||
|| window_type == META_WINDOW_DROPDOWN_MENU
|
||||
#endif
|
||||
)
|
||||
{
|
||||
@@ -640,7 +629,7 @@ mutter_window_has_shadow (MutterWindow *self)
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (priv->type == META_COMP_WINDOW_TOOLTIP)
|
||||
if (window_type == META_WINDOW_TOOLTIP)
|
||||
{
|
||||
meta_verbose ("Window 0x%x has shadow as it is a tooltip\n",
|
||||
(guint)priv->xwindow);
|
||||
@@ -653,6 +642,10 @@ mutter_window_has_shadow (MutterWindow *self)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_window_get_x_window: (skip)
|
||||
*
|
||||
*/
|
||||
Window
|
||||
mutter_window_get_x_window (MutterWindow *self)
|
||||
{
|
||||
@@ -688,15 +681,6 @@ mutter_window_get_texture (MutterWindow *self)
|
||||
return self->priv->actor;
|
||||
}
|
||||
|
||||
MetaCompWindowType
|
||||
mutter_window_get_window_type (MutterWindow *self)
|
||||
{
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
return self->priv->type;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_window_is_override_redirect (MutterWindow *self)
|
||||
{
|
||||
@@ -722,6 +706,18 @@ const char *mutter_window_get_description (MutterWindow *self)
|
||||
return self->priv->desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* mutter_window_get_workspace:
|
||||
* @mcw: #MutterWindow
|
||||
*
|
||||
* Returns the index of workspace on which this window is located; if the
|
||||
* window is sticky, or is not currently located on any workspace, returns -1.
|
||||
* This function is deprecated and should not be used in newly written code;
|
||||
* meta_window_get_workspace() instead.
|
||||
*
|
||||
* Return value: (transfer none): index of workspace on which this window is
|
||||
* located.
|
||||
*/
|
||||
gint
|
||||
mutter_window_get_workspace (MutterWindow *self)
|
||||
{
|
||||
@@ -738,6 +734,9 @@ mutter_window_get_workspace (MutterWindow *self)
|
||||
|
||||
workspace = meta_window_get_workspace (priv->window);
|
||||
|
||||
if (!workspace)
|
||||
return -1;
|
||||
|
||||
return meta_workspace_index (workspace);
|
||||
}
|
||||
|
||||
@@ -754,6 +753,60 @@ mutter_window_showing_on_its_workspace (MutterWindow *self)
|
||||
return meta_window_showing_on_its_workspace (self->priv->window);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_window_freeze (MutterWindow *self)
|
||||
{
|
||||
self->priv->freeze_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_window_damage_all (MutterWindow *self)
|
||||
{
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
ClutterX11TexturePixmap *texture_x11 = CLUTTER_X11_TEXTURE_PIXMAP (priv->actor);
|
||||
guint pixmap_width = 0;
|
||||
guint pixmap_height = 0;
|
||||
|
||||
if (!priv->needs_damage_all)
|
||||
return;
|
||||
|
||||
g_object_get (texture_x11,
|
||||
"pixmap-width", &pixmap_width,
|
||||
"pixmap-height", &pixmap_height,
|
||||
NULL);
|
||||
|
||||
clutter_x11_texture_pixmap_update_area (texture_x11,
|
||||
0,
|
||||
0,
|
||||
pixmap_width,
|
||||
pixmap_height);
|
||||
|
||||
priv->needs_damage_all = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_window_thaw (MutterWindow *self)
|
||||
{
|
||||
self->priv->freeze_count--;
|
||||
|
||||
if (G_UNLIKELY (self->priv->freeze_count < 0))
|
||||
{
|
||||
g_warning ("Error in freeze/thaw accounting.");
|
||||
self->priv->freeze_count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->priv->freeze_count)
|
||||
return;
|
||||
|
||||
/* Since we ignore damage events while a window is frozen for certain effects
|
||||
* we may need to issue an update_area() covering the whole pixmap if we
|
||||
* don't know what real damage has happened. */
|
||||
|
||||
if (self->priv->needs_damage_all)
|
||||
mutter_window_damage_all (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_window_effect_in_progress (MutterWindow *self)
|
||||
{
|
||||
@@ -765,11 +818,11 @@ mutter_window_effect_in_progress (MutterWindow *self)
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_window_mark_for_repair (MutterWindow *self)
|
||||
mutter_window_queue_create_pixmap (MutterWindow *self)
|
||||
{
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
|
||||
priv->needs_repair = TRUE;
|
||||
priv->needs_pixmap = TRUE;
|
||||
|
||||
if (!priv->mapped)
|
||||
return;
|
||||
@@ -785,6 +838,21 @@ mutter_window_mark_for_repair (MutterWindow *self)
|
||||
clutter_actor_queue_redraw (priv->actor);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_freeze_thaw_effect (gulong event)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case MUTTER_PLUGIN_DESTROY:
|
||||
case MUTTER_PLUGIN_MAXIMIZE:
|
||||
case MUTTER_PLUGIN_UNMAXIMIZE:
|
||||
return TRUE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
start_simple_effect (MutterWindow *self,
|
||||
gulong event)
|
||||
@@ -792,6 +860,7 @@ start_simple_effect (MutterWindow *self,
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen);
|
||||
gint *counter = NULL;
|
||||
gboolean use_freeze_thaw = FALSE;
|
||||
|
||||
if (!info->plugin_mgr)
|
||||
return FALSE;
|
||||
@@ -816,6 +885,11 @@ start_simple_effect (MutterWindow *self,
|
||||
|
||||
g_assert (counter);
|
||||
|
||||
use_freeze_thaw = is_freeze_thaw_effect (event);
|
||||
|
||||
if (use_freeze_thaw)
|
||||
mutter_window_freeze (self);
|
||||
|
||||
(*counter)++;
|
||||
|
||||
if (!mutter_plugin_manager_event_simple (info->plugin_mgr,
|
||||
@@ -823,6 +897,8 @@ start_simple_effect (MutterWindow *self,
|
||||
event))
|
||||
{
|
||||
(*counter)--;
|
||||
if (use_freeze_thaw)
|
||||
mutter_window_thaw (self);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -846,7 +922,7 @@ mutter_window_after_effects (MutterWindow *self)
|
||||
if (!meta_window_is_mapped (priv->window))
|
||||
mutter_window_detach (self);
|
||||
|
||||
if (priv->needs_repair)
|
||||
if (priv->needs_pixmap)
|
||||
clutter_actor_queue_redraw (priv->actor);
|
||||
}
|
||||
|
||||
@@ -915,6 +991,9 @@ mutter_window_effect_completed (MutterWindow *self,
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_freeze_thaw_effect (event))
|
||||
mutter_window_thaw (self);
|
||||
|
||||
if (!mutter_window_effect_in_progress (self))
|
||||
mutter_window_after_effects (self);
|
||||
}
|
||||
@@ -935,12 +1014,19 @@ mutter_window_detach (MutterWindow *self)
|
||||
if (!priv->back_pixmap)
|
||||
return;
|
||||
|
||||
XFreePixmap (xdisplay, priv->back_pixmap);
|
||||
priv->back_pixmap = None;
|
||||
/* Get rid of all references to the pixmap before freeing it; it's unclear whether
|
||||
* you are supposed to be able to free a GLXPixmap after freeing the underlying
|
||||
* pixmap, but it certainly doesn't work with current DRI/Mesa
|
||||
*/
|
||||
clutter_x11_texture_pixmap_set_pixmap (CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
|
||||
None);
|
||||
mutter_shaped_texture_clear (MUTTER_SHAPED_TEXTURE (priv->actor));
|
||||
cogl_flush();
|
||||
|
||||
mutter_window_mark_for_repair (self);
|
||||
XFreePixmap (xdisplay, priv->back_pixmap);
|
||||
priv->back_pixmap = None;
|
||||
|
||||
mutter_window_queue_create_pixmap (self);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -949,10 +1035,12 @@ mutter_window_destroy (MutterWindow *self)
|
||||
MetaWindow *window;
|
||||
MetaCompScreen *info;
|
||||
MutterWindowPrivate *priv;
|
||||
MetaWindowType window_type;
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
window = priv->window;
|
||||
window_type = meta_window_get_window_type (window);
|
||||
meta_window_set_compositor_private (window, NULL);
|
||||
|
||||
/*
|
||||
@@ -961,15 +1049,14 @@ mutter_window_destroy (MutterWindow *self)
|
||||
*/
|
||||
info = meta_screen_get_compositor_data (priv->screen);
|
||||
info->windows = g_list_remove (info->windows, (gconstpointer) self);
|
||||
g_hash_table_remove (info->windows_by_xid, (gpointer)priv->xwindow);
|
||||
|
||||
if (priv->type == META_COMP_WINDOW_DROPDOWN_MENU ||
|
||||
priv->type == META_COMP_WINDOW_POPUP_MENU ||
|
||||
priv->type == META_COMP_WINDOW_TOOLTIP ||
|
||||
priv->type == META_COMP_WINDOW_NOTIFICATION ||
|
||||
priv->type == META_COMP_WINDOW_COMBO ||
|
||||
priv->type == META_COMP_WINDOW_DND ||
|
||||
priv->type == META_COMP_WINDOW_OVERRIDE_OTHER)
|
||||
if (window_type == META_WINDOW_DROPDOWN_MENU ||
|
||||
window_type == META_WINDOW_POPUP_MENU ||
|
||||
window_type == META_WINDOW_TOOLTIP ||
|
||||
window_type == META_WINDOW_NOTIFICATION ||
|
||||
window_type == META_WINDOW_COMBO ||
|
||||
window_type == META_WINDOW_DND ||
|
||||
window_type == META_WINDOW_OVERRIDE_OTHER)
|
||||
{
|
||||
/*
|
||||
* No effects, just kill it.
|
||||
@@ -1004,7 +1091,7 @@ mutter_window_sync_actor_position (MutterWindow *self)
|
||||
priv->attrs.height != window_rect.height)
|
||||
{
|
||||
priv->size_changed = TRUE;
|
||||
mutter_window_mark_for_repair (self);
|
||||
mutter_window_queue_create_pixmap (self);
|
||||
}
|
||||
|
||||
/* XXX deprecated: please use meta_window_get_outer_rect instead */
|
||||
@@ -1121,6 +1208,7 @@ mutter_window_maximize (MutterWindow *self,
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height);
|
||||
|
||||
self->priv->maximize_in_progress++;
|
||||
mutter_window_freeze (self);
|
||||
|
||||
if (!info->plugin_mgr ||
|
||||
!mutter_plugin_manager_event_maximize (info->plugin_mgr,
|
||||
@@ -1131,6 +1219,7 @@ mutter_window_maximize (MutterWindow *self,
|
||||
|
||||
{
|
||||
self->priv->maximize_in_progress--;
|
||||
mutter_window_thaw (self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1148,6 +1237,7 @@ mutter_window_unmaximize (MutterWindow *self,
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height);
|
||||
|
||||
self->priv->unmaximize_in_progress++;
|
||||
mutter_window_freeze (self);
|
||||
|
||||
if (!info->plugin_mgr ||
|
||||
!mutter_plugin_manager_event_maximize (info->plugin_mgr,
|
||||
@@ -1157,6 +1247,7 @@ mutter_window_unmaximize (MutterWindow *self,
|
||||
new_rect->width, new_rect->height))
|
||||
{
|
||||
self->priv->unmaximize_in_progress--;
|
||||
mutter_window_thaw (self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1195,6 +1286,8 @@ mutter_window_new (MetaWindow *window)
|
||||
priv = self->priv;
|
||||
|
||||
priv->mapped = meta_window_toplevel_is_mapped (priv->window);
|
||||
if (priv->mapped)
|
||||
mutter_window_queue_create_pixmap (self);
|
||||
|
||||
mutter_window_sync_actor_position (self);
|
||||
|
||||
@@ -1209,7 +1302,6 @@ mutter_window_new (MetaWindow *window)
|
||||
* before we first paint.
|
||||
*/
|
||||
info->windows = g_list_append (info->windows, self);
|
||||
g_hash_table_insert (info->windows_by_xid, (gpointer) top_window, self);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -1223,7 +1315,7 @@ mutter_window_mapped (MutterWindow *self)
|
||||
|
||||
priv->mapped = TRUE;
|
||||
|
||||
mutter_window_mark_for_repair (self);
|
||||
mutter_window_queue_create_pixmap (self);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1239,7 +1331,7 @@ mutter_window_unmapped (MutterWindow *self)
|
||||
return;
|
||||
|
||||
mutter_window_detach (self);
|
||||
priv->needs_repair = FALSE;
|
||||
priv->needs_pixmap = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1249,7 +1341,7 @@ mutter_window_clear_shape_region (MutterWindow *self)
|
||||
|
||||
if (priv->shape_region)
|
||||
{
|
||||
gdk_region_destroy (priv->shape_region);
|
||||
meta_region_destroy (priv->shape_region);
|
||||
priv->shape_region = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1261,7 +1353,7 @@ mutter_window_clear_bounding_region (MutterWindow *self)
|
||||
|
||||
if (priv->bounding_region)
|
||||
{
|
||||
gdk_region_destroy (priv->bounding_region);
|
||||
meta_region_destroy (priv->bounding_region);
|
||||
priv->bounding_region = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1276,7 +1368,7 @@ mutter_window_update_bounding_region (MutterWindow *self,
|
||||
|
||||
mutter_window_clear_bounding_region (self);
|
||||
|
||||
priv->bounding_region = gdk_region_rectangle (&bounding_rectangle);
|
||||
priv->bounding_region = meta_region_new_from_rectangle (&bounding_rectangle);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1289,11 +1381,11 @@ mutter_window_update_shape_region (MutterWindow *self,
|
||||
|
||||
mutter_window_clear_shape_region (self);
|
||||
|
||||
priv->shape_region = gdk_region_new ();
|
||||
priv->shape_region = meta_region_new ();
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
GdkRectangle rect = { rects[i].x, rects[i].y, rects[i].width, rects[i].height };
|
||||
gdk_region_union_with_rect (priv->shape_region, &rect);
|
||||
meta_region_union_rectangle (priv->shape_region, &rect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1307,7 +1399,7 @@ mutter_window_update_shape_region (MutterWindow *self,
|
||||
* Return value: (transfer none): the area obscured by the window,
|
||||
* %NULL is the same as an empty region.
|
||||
*/
|
||||
GdkRegion *
|
||||
MetaRegion *
|
||||
mutter_window_get_obscured_region (MutterWindow *self)
|
||||
{
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
@@ -1326,13 +1418,13 @@ mutter_window_get_obscured_region (MutterWindow *self)
|
||||
#if 0
|
||||
/* Print out a region; useful for debugging */
|
||||
static void
|
||||
dump_region (GdkRegion *region)
|
||||
dump_region (MetaRegion *region)
|
||||
{
|
||||
GdkRectangle *rects;
|
||||
int n_rects;
|
||||
int i;
|
||||
|
||||
gdk_region_get_rectangles (region, &rects, &n_rects);
|
||||
meta_region_get_rectangles (region, &rects, &n_rects);
|
||||
g_print ("[");
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
@@ -1356,10 +1448,10 @@ dump_region (GdkRegion *region)
|
||||
*/
|
||||
void
|
||||
mutter_window_set_visible_region (MutterWindow *self,
|
||||
GdkRegion *visible_region)
|
||||
MetaRegion *visible_region)
|
||||
{
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
GdkRegion *texture_clip_region = NULL;
|
||||
MetaRegion *texture_clip_region = NULL;
|
||||
|
||||
/* Get the area of the window texture that would be drawn if
|
||||
* we weren't obscured at all
|
||||
@@ -1367,21 +1459,21 @@ mutter_window_set_visible_region (MutterWindow *self,
|
||||
if (priv->shaped)
|
||||
{
|
||||
if (priv->shape_region)
|
||||
texture_clip_region = gdk_region_copy (priv->shape_region);
|
||||
texture_clip_region = meta_region_copy (priv->shape_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priv->bounding_region)
|
||||
texture_clip_region = gdk_region_copy (priv->bounding_region);
|
||||
texture_clip_region = meta_region_copy (priv->bounding_region);
|
||||
}
|
||||
|
||||
if (!texture_clip_region)
|
||||
texture_clip_region = gdk_region_new ();
|
||||
texture_clip_region = meta_region_new ();
|
||||
|
||||
/* Then intersect that with the visible region to get the region
|
||||
* that we actually need to redraw.
|
||||
*/
|
||||
gdk_region_intersect (texture_clip_region, visible_region);
|
||||
meta_region_intersect (texture_clip_region, visible_region);
|
||||
|
||||
/* Assumes ownership */
|
||||
mutter_shaped_texture_set_clip_region (MUTTER_SHAPED_TEXTURE (priv->actor),
|
||||
@@ -1402,7 +1494,7 @@ mutter_window_set_visible_region (MutterWindow *self,
|
||||
*/
|
||||
void
|
||||
mutter_window_set_visible_region_beneath (MutterWindow *self,
|
||||
GdkRegion *beneath_region)
|
||||
MetaRegion *beneath_region)
|
||||
{
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
|
||||
@@ -1410,7 +1502,7 @@ mutter_window_set_visible_region_beneath (MutterWindow *self,
|
||||
{
|
||||
GdkRectangle shadow_rect;
|
||||
ClutterActorBox box;
|
||||
GdkOverlapType overlap;
|
||||
MetaOverlapType overlap;
|
||||
|
||||
/* We could compute an full clip region as we do for the window
|
||||
* texture, but the shadow is relatively cheap to draw, and
|
||||
@@ -1425,10 +1517,10 @@ mutter_window_set_visible_region_beneath (MutterWindow *self,
|
||||
shadow_rect.width = roundf (box.x2 - box.x1);
|
||||
shadow_rect.height = roundf (box.y2 - box.y1);
|
||||
|
||||
overlap = gdk_region_rect_in (beneath_region, &shadow_rect);
|
||||
overlap = meta_region_contains_rectangle (beneath_region, &shadow_rect);
|
||||
|
||||
tidy_texture_frame_set_needs_paint (TIDY_TEXTURE_FRAME (priv->shadow),
|
||||
overlap != GDK_OVERLAP_RECTANGLE_OUT);
|
||||
overlap != META_REGION_OVERLAP_OUT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,7 +1543,7 @@ mutter_window_reset_visible_regions (MutterWindow *self)
|
||||
}
|
||||
|
||||
static void
|
||||
check_needs_repair (MutterWindow *self)
|
||||
check_needs_pixmap (MutterWindow *self)
|
||||
{
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
@@ -1462,7 +1554,7 @@ check_needs_repair (MutterWindow *self)
|
||||
Window xwindow = priv->xwindow;
|
||||
gboolean full = FALSE;
|
||||
|
||||
if (!priv->needs_repair)
|
||||
if (!priv->needs_pixmap)
|
||||
return;
|
||||
|
||||
if (!priv->mapped)
|
||||
@@ -1509,17 +1601,21 @@ check_needs_repair (MutterWindow *self)
|
||||
return;
|
||||
}
|
||||
|
||||
/* MUST call before setting pixmap or serious performance issues
|
||||
* seemingly caused by cogl_texture_set_filters() in set_filter
|
||||
* Not sure if that call is actually needed.
|
||||
*/
|
||||
if (!compositor->no_mipmaps)
|
||||
clutter_texture_set_filter_quality (CLUTTER_TEXTURE (priv->actor),
|
||||
CLUTTER_TEXTURE_QUALITY_HIGH );
|
||||
if (compositor->no_mipmaps)
|
||||
mutter_shaped_texture_set_create_mipmaps (MUTTER_SHAPED_TEXTURE (priv->actor),
|
||||
FALSE);
|
||||
|
||||
clutter_x11_texture_pixmap_set_pixmap
|
||||
(CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
|
||||
priv->back_pixmap);
|
||||
/*
|
||||
* This only works *after* actually setting the pixmap, so we have to
|
||||
* do it here.
|
||||
* See: http://bugzilla.clutter-project.org/show_bug.cgi?id=2236
|
||||
*/
|
||||
if (!clutter_glx_texture_pixmap_using_extension (
|
||||
CLUTTER_GLX_TEXTURE_PIXMAP (priv->actor)))
|
||||
g_warning ("NOTE: Not using GLX TFP!\n");
|
||||
|
||||
g_object_get (priv->actor,
|
||||
"pixmap-width", &pxm_width,
|
||||
@@ -1534,74 +1630,52 @@ check_needs_repair (MutterWindow *self)
|
||||
full = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO -- on some gfx hardware updating the whole texture instead of
|
||||
* the individual rectangles is actually quicker, so we might want to
|
||||
* make this a configurable option (on desktop HW with multiple pipelines
|
||||
* it is usually quicker to just update the damaged parts).
|
||||
*
|
||||
* If we are using TFP we update the whole texture (this simply trigers
|
||||
* the texture rebind).
|
||||
*/
|
||||
if (full
|
||||
#ifdef HAVE_GLX_TEXTURE_PIXMAP
|
||||
|| (CLUTTER_GLX_IS_TEXTURE_PIXMAP (priv->actor) &&
|
||||
clutter_glx_texture_pixmap_using_extension
|
||||
(CLUTTER_GLX_TEXTURE_PIXMAP (priv->actor)))
|
||||
#endif /* HAVE_GLX_TEXTURE_PIXMAP */
|
||||
)
|
||||
{
|
||||
XDamageSubtract (xdisplay, priv->damage, None, None);
|
||||
|
||||
clutter_x11_texture_pixmap_update_area
|
||||
(CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
|
||||
0,
|
||||
0,
|
||||
clutter_actor_get_width (priv->actor),
|
||||
clutter_actor_get_height (priv->actor));
|
||||
}
|
||||
else
|
||||
{
|
||||
XRectangle *r_damage;
|
||||
XRectangle r_bounds;
|
||||
XserverRegion parts;
|
||||
int i, r_count;
|
||||
|
||||
parts = XFixesCreateRegion (xdisplay, 0, 0);
|
||||
XDamageSubtract (xdisplay, priv->damage, None, parts);
|
||||
|
||||
r_damage = XFixesFetchRegionAndBounds (xdisplay,
|
||||
parts,
|
||||
&r_count,
|
||||
&r_bounds);
|
||||
|
||||
if (r_damage)
|
||||
{
|
||||
for (i = 0; i < r_count; ++i)
|
||||
{
|
||||
clutter_x11_texture_pixmap_update_area
|
||||
(CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
|
||||
r_damage[i].x,
|
||||
r_damage[i].y,
|
||||
r_damage[i].width,
|
||||
r_damage[i].height);
|
||||
}
|
||||
}
|
||||
|
||||
XFree (r_damage);
|
||||
XFixesDestroyRegion (xdisplay, parts);
|
||||
}
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
|
||||
priv->needs_repair = FALSE;
|
||||
priv->needs_pixmap = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_frozen (MutterWindow *self)
|
||||
{
|
||||
return self->priv->freeze_count ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
mutter_window_process_damage (MutterWindow *self,
|
||||
XDamageNotifyEvent *event)
|
||||
{
|
||||
mutter_window_mark_for_repair (self);
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
ClutterX11TexturePixmap *texture_x11 = CLUTTER_X11_TEXTURE_PIXMAP (priv->actor);
|
||||
|
||||
priv->received_damage = TRUE;
|
||||
|
||||
if (is_frozen (self))
|
||||
{
|
||||
/* The window is frozen due to an effect in progress: we ignore damage
|
||||
* here on the off chance that this will stop the corresponding
|
||||
* texture_from_pixmap from being update.
|
||||
*
|
||||
* needs_damage_all tracks that some unknown damage happened while the
|
||||
* window was frozen so that when the window becomes unfrozen we can
|
||||
* issue a full window update to cover any lost damage.
|
||||
*
|
||||
* It should be noted that this is an unreliable mechanism since it's
|
||||
* quite likely that drivers will aim to provide a zero-copy
|
||||
* implementation of the texture_from_pixmap extension and in those cases
|
||||
* any drawing done to the window is always immediately reflected in the
|
||||
* texture regardless of damage event handling.
|
||||
*/
|
||||
priv->needs_damage_all = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
clutter_x11_texture_pixmap_update_area (texture_x11,
|
||||
event->area.x,
|
||||
event->area.y,
|
||||
event->area.width,
|
||||
event->area.height);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1622,6 +1696,8 @@ static void
|
||||
check_needs_reshape (MutterWindow *self)
|
||||
{
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
|
||||
if (!priv->needs_reshape)
|
||||
return;
|
||||
@@ -1632,15 +1708,17 @@ check_needs_reshape (MutterWindow *self)
|
||||
#ifdef HAVE_SHAPE
|
||||
if (priv->shaped)
|
||||
{
|
||||
Display *xdisplay = meta_display_get_xdisplay (meta_window_get_display (priv->window));
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
XRectangle *rects;
|
||||
int n_rects, ordering;
|
||||
|
||||
meta_error_trap_push (display);
|
||||
rects = XShapeGetRectangles (xdisplay,
|
||||
priv->xwindow,
|
||||
ShapeBounding,
|
||||
&n_rects,
|
||||
&ordering);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
|
||||
if (rects)
|
||||
{
|
||||
@@ -1673,16 +1751,27 @@ void
|
||||
mutter_window_pre_paint (MutterWindow *self)
|
||||
{
|
||||
MutterWindowPrivate *priv = self->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
/* The window is frozen due to a pending animation: we'll wait until
|
||||
* the animation finishes to reshape and repair the window */
|
||||
if (priv->destroy_in_progress ||
|
||||
priv->maximize_in_progress ||
|
||||
priv->unmaximize_in_progress)
|
||||
return;
|
||||
if (is_frozen (self))
|
||||
{
|
||||
/* The window is frozen due to a pending animation: we'll wait until
|
||||
* the animation finishes to reshape and repair the window */
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->received_damage)
|
||||
{
|
||||
meta_error_trap_push (display);
|
||||
XDamageSubtract (xdisplay, priv->damage, None, None);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
priv->received_damage = FALSE;
|
||||
}
|
||||
|
||||
check_needs_reshape (self);
|
||||
check_needs_repair (self);
|
||||
check_needs_pixmap (self);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "mutter-plugin.h"
|
||||
#include "window.h"
|
||||
|
||||
#include <libintl.h>
|
||||
#define _(x) dgettext (GETTEXT_PACKAGE, x)
|
||||
@@ -81,11 +82,12 @@ static void unmaximize (MutterPlugin *plugin,
|
||||
gint x, gint y, gint width, gint height);
|
||||
|
||||
static void switch_workspace (MutterPlugin *plugin,
|
||||
const GList **actors, gint from, gint to,
|
||||
gint from, gint to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
static void kill_effect (MutterPlugin *plugin,
|
||||
MutterWindow *actor, gulong event);
|
||||
static void kill_window_effects (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
static void kill_switch_workspace (MutterPlugin *plugin);
|
||||
|
||||
static const MutterPluginInfo * plugin_info (MutterPlugin *plugin);
|
||||
|
||||
@@ -99,7 +101,6 @@ struct _MutterDefaultPluginPrivate
|
||||
/* Valid only when switch_workspace effect is in progress */
|
||||
ClutterTimeline *tml_switch_workspace1;
|
||||
ClutterTimeline *tml_switch_workspace2;
|
||||
GList **actors;
|
||||
ClutterActor *desktop1;
|
||||
ClutterActor *desktop2;
|
||||
|
||||
@@ -175,10 +176,9 @@ mutter_default_plugin_get_property (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_constructed (GObject *object)
|
||||
start (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPlugin *plugin = MUTTER_PLUGIN (object);
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (object)->priv;
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
|
||||
guint destroy_timeout = DESTROY_TIMEOUT;
|
||||
guint minimize_timeout = MINIMIZE_TIMEOUT;
|
||||
@@ -201,7 +201,6 @@ mutter_default_plugin_constructed (GObject *object)
|
||||
map_timeout *= 2;
|
||||
switch_timeout *= 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -212,18 +211,19 @@ mutter_default_plugin_class_init (MutterDefaultPluginClass *klass)
|
||||
|
||||
gobject_class->finalize = mutter_default_plugin_finalize;
|
||||
gobject_class->dispose = mutter_default_plugin_dispose;
|
||||
gobject_class->constructed = mutter_default_plugin_constructed;
|
||||
gobject_class->set_property = mutter_default_plugin_set_property;
|
||||
gobject_class->get_property = mutter_default_plugin_get_property;
|
||||
|
||||
plugin_class->start = start;
|
||||
plugin_class->map = map;
|
||||
plugin_class->minimize = minimize;
|
||||
plugin_class->maximize = maximize;
|
||||
plugin_class->unmaximize = unmaximize;
|
||||
plugin_class->destroy = destroy;
|
||||
plugin_class->switch_workspace = switch_workspace;
|
||||
plugin_class->kill_effect = kill_effect;
|
||||
plugin_class->plugin_info = plugin_info;
|
||||
plugin_class->kill_window_effects = kill_window_effects;
|
||||
plugin_class->kill_switch_workspace = kill_switch_workspace;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (MutterDefaultPluginPrivate));
|
||||
}
|
||||
@@ -272,20 +272,12 @@ get_actor_private (MutterWindow *actor)
|
||||
return priv;
|
||||
}
|
||||
|
||||
typedef struct SwitchWorkspaceData
|
||||
{
|
||||
MutterPlugin *plugin;
|
||||
const GList **actors;
|
||||
} SwitchWorkspaceData;
|
||||
|
||||
static void
|
||||
on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
|
||||
{
|
||||
SwitchWorkspaceData *sw_data = data;
|
||||
MutterPlugin *plugin = sw_data->plugin;
|
||||
MutterPlugin *plugin = MUTTER_PLUGIN (data);
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
GList *l = *((GList**)sw_data->actors);
|
||||
MutterWindow *actor_for_cb = l->data;
|
||||
GList *l = mutter_plugin_get_windows (plugin);
|
||||
|
||||
while (l)
|
||||
{
|
||||
@@ -305,21 +297,17 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
|
||||
clutter_actor_destroy (priv->desktop1);
|
||||
clutter_actor_destroy (priv->desktop2);
|
||||
|
||||
priv->actors = NULL;
|
||||
priv->tml_switch_workspace1 = NULL;
|
||||
priv->tml_switch_workspace2 = NULL;
|
||||
priv->desktop1 = NULL;
|
||||
priv->desktop2 = NULL;
|
||||
|
||||
g_free (data);
|
||||
|
||||
mutter_plugin_effect_completed (plugin, actor_for_cb,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
mutter_plugin_switch_workspace_completed (plugin);
|
||||
}
|
||||
|
||||
static void
|
||||
switch_workspace (MutterPlugin *plugin,
|
||||
const GList **actors, gint from, gint to,
|
||||
gint from, gint to,
|
||||
MetaMotionDirection direction)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
@@ -330,12 +318,8 @@ switch_workspace (MutterPlugin *plugin,
|
||||
ClutterActor *stage;
|
||||
int screen_width, screen_height;
|
||||
MetaScreen *screen = mutter_plugin_get_screen (plugin);
|
||||
SwitchWorkspaceData *sw_data = g_new (SwitchWorkspaceData, 1);
|
||||
ClutterAnimation *animation;
|
||||
|
||||
sw_data->plugin = plugin;
|
||||
sw_data->actors = actors;
|
||||
|
||||
stage = mutter_plugin_get_stage (plugin);
|
||||
|
||||
mutter_plugin_query_screen_size (plugin,
|
||||
@@ -355,14 +339,13 @@ switch_workspace (MutterPlugin *plugin,
|
||||
|
||||
if (from == to)
|
||||
{
|
||||
mutter_plugin_effect_completed (plugin, NULL,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
mutter_plugin_switch_workspace_completed (plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
n_workspaces = meta_screen_get_n_workspaces (screen);
|
||||
|
||||
l = g_list_last (*((GList**) actors));
|
||||
l = g_list_last (mutter_plugin_get_windows (plugin));
|
||||
|
||||
while (l)
|
||||
{
|
||||
@@ -397,7 +380,6 @@ switch_workspace (MutterPlugin *plugin,
|
||||
l = l->prev;
|
||||
}
|
||||
|
||||
priv->actors = (GList **)actors;
|
||||
priv->desktop1 = workspace0;
|
||||
priv->desktop2 = workspace1;
|
||||
|
||||
@@ -410,7 +392,7 @@ switch_workspace (MutterPlugin *plugin,
|
||||
g_signal_connect (priv->tml_switch_workspace1,
|
||||
"completed",
|
||||
G_CALLBACK (on_switch_workspace_effect_complete),
|
||||
sw_data);
|
||||
plugin);
|
||||
|
||||
animation = clutter_actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
|
||||
SWITCH_TIMEOUT,
|
||||
@@ -448,8 +430,7 @@ on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data
|
||||
CLUTTER_GRAVITY_NORTH_WEST);
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
mutter_plugin_minimize_completed (plugin, mc_window);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
@@ -461,12 +442,14 @@ on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data
|
||||
static void
|
||||
minimize (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
MetaCompWindowType type;
|
||||
MetaWindowType type;
|
||||
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
type = meta_window_get_window_type (meta_window);
|
||||
|
||||
if (type == META_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
@@ -492,8 +475,7 @@ minimize (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
|
||||
}
|
||||
else
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
mutter_plugin_minimize_completed (plugin, mc_window);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -518,8 +500,7 @@ on_maximize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data
|
||||
CLUTTER_GRAVITY_NORTH_WEST);
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
mutter_plugin_maximize_completed (plugin, mc_window);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
@@ -537,17 +518,18 @@ maximize (MutterPlugin *plugin,
|
||||
MutterWindow *mc_window,
|
||||
gint end_x, gint end_y, gint end_width, gint end_height)
|
||||
{
|
||||
MetaCompWindowType type;
|
||||
MetaWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
|
||||
|
||||
gdouble scale_x = 1.0;
|
||||
gdouble scale_y = 1.0;
|
||||
gfloat anchor_x = 0;
|
||||
gfloat anchor_y = 0;
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
type = meta_window_get_window_type (meta_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
if (type == META_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
@@ -589,8 +571,7 @@ maximize (MutterPlugin *plugin,
|
||||
return;
|
||||
}
|
||||
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
mutter_plugin_maximize_completed (plugin, mc_window);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -603,9 +584,10 @@ unmaximize (MutterPlugin *plugin,
|
||||
MutterWindow *mc_window,
|
||||
gint end_x, gint end_y, gint end_width, gint end_height)
|
||||
{
|
||||
MetaCompWindowType type = mutter_window_get_window_type (mc_window);
|
||||
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
|
||||
MetaWindowType type = meta_window_get_window_type (meta_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
if (type == META_WINDOW_NORMAL)
|
||||
{
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
@@ -613,8 +595,7 @@ unmaximize (MutterPlugin *plugin,
|
||||
}
|
||||
|
||||
/* Do this conditionally, if the effect requires completion callback. */
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_UNMAXIMIZE);
|
||||
mutter_plugin_unmaximize_completed (plugin, mc_window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -633,7 +614,7 @@ on_map_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
|
||||
CLUTTER_GRAVITY_NORTH_WEST);
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
mutter_plugin_effect_completed (plugin, mc_window, MUTTER_PLUGIN_MAP);
|
||||
mutter_plugin_map_completed (plugin, mc_window);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
@@ -645,12 +626,13 @@ on_map_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
|
||||
static void
|
||||
map (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
MetaCompWindowType type;
|
||||
MetaWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
type = meta_window_get_window_type (meta_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
if (type == META_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
@@ -679,8 +661,7 @@ map (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
|
||||
}
|
||||
else
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAP);
|
||||
mutter_plugin_map_completed (plugin, mc_window);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -696,8 +677,7 @@ on_destroy_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
|
||||
|
||||
apriv->tml_destroy = NULL;
|
||||
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_DESTROY);
|
||||
mutter_plugin_destroy_completed (plugin, mc_window);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -706,12 +686,13 @@ on_destroy_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
|
||||
static void
|
||||
destroy (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
MetaCompWindowType type;
|
||||
MetaWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
type = meta_window_get_window_type (meta_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
if (type == META_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
@@ -734,54 +715,48 @@ destroy (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
data);
|
||||
}
|
||||
else
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_DESTROY);
|
||||
mutter_plugin_destroy_completed (plugin, mc_window);
|
||||
}
|
||||
|
||||
static void
|
||||
kill_effect (MutterPlugin *plugin, MutterWindow *mc_window, gulong event)
|
||||
kill_switch_workspace (MutterPlugin *plugin)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
|
||||
if (priv->tml_switch_workspace1)
|
||||
{
|
||||
clutter_timeline_stop (priv->tml_switch_workspace1);
|
||||
clutter_timeline_stop (priv->tml_switch_workspace2);
|
||||
g_signal_emit_by_name (priv->tml_switch_workspace1, "completed", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kill_window_effects (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
ActorPrivate *apriv;
|
||||
|
||||
if (event & MUTTER_PLUGIN_SWITCH_WORKSPACE)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
|
||||
if (priv->tml_switch_workspace1)
|
||||
{
|
||||
clutter_timeline_stop (priv->tml_switch_workspace1);
|
||||
clutter_timeline_stop (priv->tml_switch_workspace2);
|
||||
g_signal_emit_by_name (priv->tml_switch_workspace1, "completed", NULL);
|
||||
}
|
||||
|
||||
if (!(event & ~MUTTER_PLUGIN_SWITCH_WORKSPACE))
|
||||
{
|
||||
/* Workspace switch only, nothing more to do */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
apriv = get_actor_private (mc_window);
|
||||
|
||||
if ((event & MUTTER_PLUGIN_MINIMIZE) && apriv->tml_minimize)
|
||||
if (apriv->tml_minimize)
|
||||
{
|
||||
clutter_timeline_stop (apriv->tml_minimize);
|
||||
g_signal_emit_by_name (apriv->tml_minimize, "completed", NULL);
|
||||
}
|
||||
|
||||
if ((event & MUTTER_PLUGIN_MAXIMIZE) && apriv->tml_maximize)
|
||||
if (apriv->tml_maximize)
|
||||
{
|
||||
clutter_timeline_stop (apriv->tml_maximize);
|
||||
g_signal_emit_by_name (apriv->tml_maximize, "completed", NULL);
|
||||
}
|
||||
|
||||
if ((event & MUTTER_PLUGIN_MAP) && apriv->tml_map)
|
||||
if (apriv->tml_map)
|
||||
{
|
||||
clutter_timeline_stop (apriv->tml_map);
|
||||
g_signal_emit_by_name (apriv->tml_map, "completed", NULL);
|
||||
}
|
||||
|
||||
if ((event & MUTTER_PLUGIN_DESTROY) && apriv->tml_destroy)
|
||||
if (apriv->tml_destroy)
|
||||
{
|
||||
clutter_timeline_stop (apriv->tml_destroy);
|
||||
g_signal_emit_by_name (apriv->tml_destroy, "completed", NULL);
|
||||
|
@@ -155,7 +155,7 @@ tidy_texture_frame_unrealize (ClutterActor *self)
|
||||
if (priv->material == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
cogl_material_unref (priv->material);
|
||||
cogl_handle_unref (priv->material);
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
|
||||
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||
@@ -415,7 +415,7 @@ tidy_texture_frame_dispose (GObject *gobject)
|
||||
|
||||
if (priv->material)
|
||||
{
|
||||
cogl_material_unref (priv->material);
|
||||
cogl_handle_unref (priv->material);
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
@@ -1,138 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Metacity Alt-Tab abstraction */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009 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 "alttabhandlerdefault.h"
|
||||
#include "screen-private.h"
|
||||
|
||||
static GType handler_type = G_TYPE_INVALID;
|
||||
|
||||
GType meta_alt_tab_handler_default_get_type (void);
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_register (GType type)
|
||||
{
|
||||
handler_type = type;
|
||||
}
|
||||
|
||||
MetaAltTabHandler *
|
||||
meta_alt_tab_handler_new (MetaScreen *screen,
|
||||
gboolean immediate)
|
||||
{
|
||||
if (handler_type == G_TYPE_INVALID)
|
||||
handler_type = meta_alt_tab_handler_default_get_type ();
|
||||
|
||||
return g_object_new (handler_type,
|
||||
"screen", screen,
|
||||
"immediate", immediate,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void meta_alt_tab_handler_class_init (GObjectClass *object_class);
|
||||
|
||||
GType
|
||||
meta_alt_tab_handler_get_type (void)
|
||||
{
|
||||
static volatile gsize g_define_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
||||
{
|
||||
const GTypeInfo type_info =
|
||||
{
|
||||
sizeof (MetaAltTabHandlerInterface), /* class_size */
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc)meta_alt_tab_handler_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
0,
|
||||
0, /* n_preallocs */
|
||||
NULL
|
||||
};
|
||||
GType g_define_type_id =
|
||||
g_type_register_static (G_TYPE_INTERFACE, "MetaAltTabHandler",
|
||||
&type_info, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
|
||||
|
||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
|
||||
}
|
||||
|
||||
return g_define_type_id__volatile;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_class_init (GObjectClass *object_class)
|
||||
{
|
||||
g_object_interface_install_property (object_class,
|
||||
g_param_spec_object ("screen",
|
||||
"Screen",
|
||||
"MetaScreen this is the switcher for",
|
||||
META_TYPE_SCREEN,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_interface_install_property (object_class,
|
||||
g_param_spec_boolean ("immediate",
|
||||
"Immediate mode",
|
||||
"Whether or not to select windows immediately",
|
||||
FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_add_window (MetaAltTabHandler *handler,
|
||||
MetaWindow *window)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->add_window (handler, window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_show (MetaAltTabHandler *handler,
|
||||
MetaWindow *initial_selection)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->show (handler,
|
||||
initial_selection);
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_destroy (MetaAltTabHandler *handler)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->destroy (handler);
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_forward (MetaAltTabHandler *handler)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->forward (handler);
|
||||
}
|
||||
|
||||
void
|
||||
meta_alt_tab_handler_backward (MetaAltTabHandler *handler)
|
||||
{
|
||||
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->backward (handler);
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_alt_tab_handler_get_selected (MetaAltTabHandler *handler)
|
||||
{
|
||||
return META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->get_selected (handler);
|
||||
}
|
@@ -1,223 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Metacity Alt-Tab abstraction: default implementation */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009 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 "alttabhandlerdefault.h"
|
||||
#include "frame-private.h"
|
||||
#include "window-private.h"
|
||||
|
||||
static void meta_alt_tab_handler_default_interface_init (MetaAltTabHandlerInterface *handler_iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaAltTabHandlerDefault, meta_alt_tab_handler_default, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_ALT_TAB_HANDLER,
|
||||
meta_alt_tab_handler_default_interface_init))
|
||||
|
||||
enum {
|
||||
PROP_SCREEN = 1,
|
||||
PROP_IMMEDIATE
|
||||
};
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_init (MetaAltTabHandlerDefault *hd)
|
||||
{
|
||||
hd->entries = g_array_new (FALSE, FALSE, sizeof (MetaTabEntry));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SCREEN:
|
||||
hd->screen = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_IMMEDIATE:
|
||||
hd->immediate_mode = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_finalize (GObject *object)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (object);
|
||||
|
||||
g_array_free (hd->entries, TRUE);
|
||||
|
||||
if (hd->tab_popup)
|
||||
meta_ui_tab_popup_free (hd->tab_popup);
|
||||
|
||||
G_OBJECT_CLASS (meta_alt_tab_handler_default_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_add_window (MetaAltTabHandler *handler,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
MetaTabEntry entry;
|
||||
MetaRectangle r;
|
||||
|
||||
entry.key = (MetaTabEntryKey) window;
|
||||
entry.title = window->title;
|
||||
entry.icon = window->icon;
|
||||
entry.blank = FALSE;
|
||||
entry.hidden = !meta_window_showing_on_its_workspace (window);
|
||||
entry.demands_attention = window->wm_state_demands_attention;
|
||||
|
||||
if (hd->immediate_mode || !entry.hidden ||
|
||||
!meta_window_get_icon_geometry (window, &r))
|
||||
meta_window_get_outer_rect (window, &r);
|
||||
entry.rect = r;
|
||||
|
||||
/* Find inside of highlight rectangle to be used when window is
|
||||
* outlined for tabbing. This should be the size of the
|
||||
* east/west frame, and the size of the south frame, on those
|
||||
* sides. On the top it should be the size of the south frame
|
||||
* edge.
|
||||
*/
|
||||
#define OUTLINE_WIDTH 5
|
||||
/* Top side */
|
||||
if (!entry.hidden &&
|
||||
window->frame && window->frame->bottom_height > 0 &&
|
||||
window->frame->child_y >= window->frame->bottom_height)
|
||||
entry.inner_rect.y = window->frame->bottom_height;
|
||||
else
|
||||
entry.inner_rect.y = OUTLINE_WIDTH;
|
||||
|
||||
/* Bottom side */
|
||||
if (!entry.hidden &&
|
||||
window->frame && window->frame->bottom_height != 0)
|
||||
entry.inner_rect.height = r.height
|
||||
- entry.inner_rect.y - window->frame->bottom_height;
|
||||
else
|
||||
entry.inner_rect.height = r.height
|
||||
- entry.inner_rect.y - OUTLINE_WIDTH;
|
||||
|
||||
/* Left side */
|
||||
if (!entry.hidden && window->frame && window->frame->child_x != 0)
|
||||
entry.inner_rect.x = window->frame->child_x;
|
||||
else
|
||||
entry.inner_rect.x = OUTLINE_WIDTH;
|
||||
|
||||
/* Right side */
|
||||
if (!entry.hidden &&
|
||||
window->frame && window->frame->right_width != 0)
|
||||
entry.inner_rect.width = r.width
|
||||
- entry.inner_rect.x - window->frame->right_width;
|
||||
else
|
||||
entry.inner_rect.width = r.width
|
||||
- entry.inner_rect.x - OUTLINE_WIDTH;
|
||||
|
||||
g_array_append_val (hd->entries, entry);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_show (MetaAltTabHandler *handler,
|
||||
MetaWindow *initial_selection)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
return;
|
||||
|
||||
hd->tab_popup = meta_ui_tab_popup_new ((MetaTabEntry *)hd->entries->data,
|
||||
hd->screen->number,
|
||||
hd->entries->len,
|
||||
5, /* FIXME */
|
||||
TRUE);
|
||||
meta_ui_tab_popup_select (hd->tab_popup, (MetaTabEntryKey) initial_selection);
|
||||
meta_ui_tab_popup_set_showing (hd->tab_popup, !hd->immediate_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_destroy (MetaAltTabHandler *handler)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
{
|
||||
meta_ui_tab_popup_free (hd->tab_popup);
|
||||
hd->tab_popup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_forward (MetaAltTabHandler *handler)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
meta_ui_tab_popup_forward (hd->tab_popup);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_backward (MetaAltTabHandler *handler)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
meta_ui_tab_popup_backward (hd->tab_popup);
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
meta_alt_tab_handler_default_get_selected (MetaAltTabHandler *handler)
|
||||
{
|
||||
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
|
||||
|
||||
if (hd->tab_popup)
|
||||
return (MetaWindow *)meta_ui_tab_popup_get_selected (hd->tab_popup);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_class_init (MetaAltTabHandlerDefaultClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = meta_alt_tab_handler_default_set_property;
|
||||
object_class->finalize = meta_alt_tab_handler_default_finalize;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_SCREEN, "screen");
|
||||
g_object_class_override_property (object_class, PROP_IMMEDIATE, "immediate");
|
||||
}
|
||||
|
||||
static void
|
||||
meta_alt_tab_handler_default_interface_init (MetaAltTabHandlerInterface *handler_iface)
|
||||
{
|
||||
handler_iface->add_window = meta_alt_tab_handler_default_add_window;
|
||||
handler_iface->show = meta_alt_tab_handler_default_show;
|
||||
handler_iface->destroy = meta_alt_tab_handler_default_destroy;
|
||||
handler_iface->forward = meta_alt_tab_handler_default_forward;
|
||||
handler_iface->backward = meta_alt_tab_handler_default_backward;
|
||||
handler_iface->get_selected = meta_alt_tab_handler_default_get_selected;
|
||||
}
|
@@ -52,6 +52,9 @@
|
||||
#include "bell.h"
|
||||
#include "screen-private.h"
|
||||
#include "prefs.h"
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
#include <canberra-gtk.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Flashes one entire screen. This is done by making a window the size of the
|
||||
@@ -228,18 +231,18 @@ bell_flash_window_frame (MetaWindow *window)
|
||||
*/
|
||||
static void
|
||||
bell_flash_frame (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
XkbAnyEvent *xkb_ev)
|
||||
{
|
||||
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
|
||||
MetaWindow *window;
|
||||
|
||||
g_assert (xkb_ev->xkb_type == XkbBellNotify);
|
||||
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
|
||||
if (!window && (display->focus_window) && (display->focus_window->frame))
|
||||
if (!window && (display->focus_window))
|
||||
{
|
||||
window = display->focus_window;
|
||||
}
|
||||
if (window)
|
||||
if (window && window->frame)
|
||||
{
|
||||
bell_flash_window_frame (window);
|
||||
}
|
||||
@@ -285,6 +288,48 @@ meta_bell_notify (MetaDisplay *display,
|
||||
/* flash something */
|
||||
if (meta_prefs_get_visual_bell ())
|
||||
bell_visual_notify (display, xkb_ev);
|
||||
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
if (meta_prefs_bell_is_audible ())
|
||||
{
|
||||
ca_proplist *p;
|
||||
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
|
||||
MetaWindow *window;
|
||||
int res;
|
||||
|
||||
ca_proplist_create (&p);
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_ID, "bell-window-system");
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
|
||||
ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
|
||||
|
||||
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
|
||||
if (!window && (display->focus_window) && (display->focus_window->frame))
|
||||
window = display->focus_window;
|
||||
|
||||
if (window)
|
||||
{
|
||||
ca_proplist_sets (p, CA_PROP_WINDOW_NAME, window->title);
|
||||
ca_proplist_setf (p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long)window->xwindow);
|
||||
ca_proplist_sets (p, CA_PROP_APPLICATION_NAME, window->res_name);
|
||||
ca_proplist_setf (p, CA_PROP_APPLICATION_PROCESS_ID, "%d", window->net_wm_pid);
|
||||
}
|
||||
|
||||
/* First, we try to play a real sound ... */
|
||||
res = ca_context_play_full (ca_gtk_context_get (), 1, p, NULL, NULL);
|
||||
|
||||
ca_proplist_destroy (p);
|
||||
|
||||
if (res != CA_SUCCESS && res != CA_ERROR_DISABLED)
|
||||
{
|
||||
/* ...and in case that failed we use the classic X11 bell. */
|
||||
XkbForceDeviceBell (display->xdisplay,
|
||||
xkb_bell_event->device,
|
||||
xkb_bell_event->bell_class,
|
||||
xkb_bell_event->bell_id,
|
||||
xkb_bell_event->percent);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_LIBCANBERRA */
|
||||
}
|
||||
#endif /* HAVE_XKB */
|
||||
|
||||
@@ -292,11 +337,19 @@ void
|
||||
meta_bell_set_audible (MetaDisplay *display, gboolean audible)
|
||||
{
|
||||
#ifdef HAVE_XKB
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
/* When we are playing sounds using libcanberra support, we handle the
|
||||
* bell whether its an audible bell or a visible bell */
|
||||
gboolean enable_system_bell = FALSE;
|
||||
#else
|
||||
gboolean enable_system_bell = audible;
|
||||
#endif /* HAVE_LIBCANBERRA */
|
||||
|
||||
XkbChangeEnabledControls (display->xdisplay,
|
||||
XkbUseCoreKbd,
|
||||
XkbAudibleBellMask,
|
||||
audible ? XkbAudibleBellMask : 0);
|
||||
#endif
|
||||
XkbUseCoreKbd,
|
||||
XkbAudibleBellMask,
|
||||
enable_system_bell ? XkbAudibleBellMask : 0);
|
||||
#endif /* HAVE_XKB */
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -323,11 +376,7 @@ meta_bell_init (MetaDisplay *display)
|
||||
XkbUseCoreKbd,
|
||||
XkbBellNotifyMask,
|
||||
XkbBellNotifyMask);
|
||||
XkbChangeEnabledControls (display->xdisplay,
|
||||
XkbUseCoreKbd,
|
||||
XkbAudibleBellMask,
|
||||
meta_prefs_bell_is_audible ()
|
||||
? XkbAudibleBellMask : 0);
|
||||
meta_bell_set_audible (display, meta_prefs_bell_is_audible ());
|
||||
if (visual_bell_auto_reset) {
|
||||
XkbSetAutoResetControls (display->xdisplay,
|
||||
XkbAudibleBellMask,
|
||||
|
@@ -30,6 +30,35 @@
|
||||
#include "util.h"
|
||||
#include <X11/Xutil.h> /* Just for the definition of the various gravities */
|
||||
|
||||
/* It would make sense to use GSlice here, but until we clean up the
|
||||
* rest of this file and the internal API to use these functions, we
|
||||
* leave it using g_malloc()/g_free() for consistency.
|
||||
*/
|
||||
|
||||
MetaRectangle *
|
||||
meta_rectangle_copy (const MetaRectangle *rect)
|
||||
{
|
||||
return g_memdup (rect, sizeof (MetaRectangle));
|
||||
}
|
||||
|
||||
void
|
||||
meta_rectangle_free (MetaRectangle *rect)
|
||||
{
|
||||
g_free (rect);
|
||||
}
|
||||
|
||||
GType
|
||||
meta_rectangle_get_type (void)
|
||||
{
|
||||
static GType type_id = 0;
|
||||
|
||||
if (!type_id)
|
||||
type_id = g_boxed_type_register_static (g_intern_static_string ("MetaRectangle"),
|
||||
(GBoxedCopyFunc) meta_rectangle_copy,
|
||||
(GBoxedFreeFunc) meta_rectangle_free);
|
||||
return type_id;
|
||||
}
|
||||
|
||||
char*
|
||||
meta_rectangle_to_string (const MetaRectangle *rect,
|
||||
char *output)
|
||||
@@ -500,7 +529,12 @@ compare_rect_areas (gconstpointer a, gconstpointer b)
|
||||
return b_area - a_area; /* positive ret value denotes b > a, ... */
|
||||
}
|
||||
|
||||
/* This function is trying to find a "minimal spanning set (of rectangles)"
|
||||
/**
|
||||
* meta_rectangle_get_minimal_spanning_set_for_region:
|
||||
* @basic_rect: Input rectangle
|
||||
* @all_struts: (element-type Meta.Rectangle): List of struts
|
||||
*
|
||||
* This function is trying to find a "minimal spanning set (of rectangles)"
|
||||
* for a given region.
|
||||
*
|
||||
* The region is given by taking basic_rect, then removing the areas
|
||||
@@ -513,10 +547,7 @@ compare_rect_areas (gconstpointer a, gconstpointer b)
|
||||
* the region if and only if it is contained within at least one of the
|
||||
* rectangles.
|
||||
*
|
||||
* The GList* returned will be a list of (allocated) MetaRectangles.
|
||||
* The list will need to be freed by calling
|
||||
* meta_rectangle_free_spanning_set() on it (or by manually
|
||||
* implementing that function...)
|
||||
* Returns: (transfer full) (element-type Meta.Rectangle): Minimal spanning set
|
||||
*/
|
||||
GList*
|
||||
meta_rectangle_get_minimal_spanning_set_for_region (
|
||||
@@ -649,6 +680,10 @@ meta_rectangle_get_minimal_spanning_set_for_region (
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_rectangle_expand_region: (skip)
|
||||
*
|
||||
*/
|
||||
GList*
|
||||
meta_rectangle_expand_region (GList *region,
|
||||
const int left_expand,
|
||||
@@ -665,6 +700,10 @@ meta_rectangle_expand_region (GList *region,
|
||||
0);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_rectangle_expand_region_conditionally: (skip)
|
||||
*
|
||||
*/
|
||||
GList*
|
||||
meta_rectangle_expand_region_conditionally (GList *region,
|
||||
const int left_expand,
|
||||
@@ -1642,7 +1681,10 @@ fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
|
||||
}
|
||||
}
|
||||
|
||||
/* This function removes intersections of edges with the rectangles from the
|
||||
/**
|
||||
* meta_rectangle_remove_intersections_with_boxes_from_edges: (skip)
|
||||
*
|
||||
* This function removes intersections of edges with the rectangles from the
|
||||
* list of edges.
|
||||
*/
|
||||
GList*
|
||||
@@ -1708,7 +1750,11 @@ meta_rectangle_remove_intersections_with_boxes_from_edges (
|
||||
return edges;
|
||||
}
|
||||
|
||||
/* This function is trying to find all the edges of an onscreen region. */
|
||||
/**
|
||||
* meta_rectangle_find_onscreen_edges: (skip)
|
||||
*
|
||||
* This function is trying to find all the edges of an onscreen region.
|
||||
*/
|
||||
GList*
|
||||
meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
|
||||
const GSList *all_struts)
|
||||
@@ -1791,6 +1837,10 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_rectangle_find_nonintersected_monitor_edges: (skip)
|
||||
*
|
||||
*/
|
||||
GList*
|
||||
meta_rectangle_find_nonintersected_monitor_edges (
|
||||
const GList *monitor_rects,
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "constraints.h"
|
||||
#include "workspace-private.h"
|
||||
#include "place.h"
|
||||
#include "prefs.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
@@ -97,6 +98,7 @@ typedef enum
|
||||
PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1,
|
||||
PRIORITY_SIZE_HINTS_INCREMENTS = 1,
|
||||
PRIORITY_MAXIMIZATION = 2,
|
||||
PRIORITY_TILING = 2,
|
||||
PRIORITY_FULLSCREEN = 2,
|
||||
PRIORITY_SIZE_HINTS_LIMITS = 3,
|
||||
PRIORITY_TITLEBAR_VISIBLE = 4,
|
||||
@@ -139,11 +141,18 @@ typedef struct
|
||||
GList *usable_screen_region;
|
||||
GList *usable_monitor_region;
|
||||
} ConstraintInfo;
|
||||
|
||||
static gboolean constrain_modal_dialog (MetaWindow *window,
|
||||
ConstraintInfo *info,
|
||||
ConstraintPriority priority,
|
||||
gboolean check_only);
|
||||
static gboolean constrain_maximization (MetaWindow *window,
|
||||
ConstraintInfo *info,
|
||||
ConstraintPriority priority,
|
||||
gboolean check_only);
|
||||
static gboolean constrain_tiling (MetaWindow *window,
|
||||
ConstraintInfo *info,
|
||||
ConstraintPriority priority,
|
||||
gboolean check_only);
|
||||
static gboolean constrain_fullscreen (MetaWindow *window,
|
||||
ConstraintInfo *info,
|
||||
ConstraintPriority priority,
|
||||
@@ -209,7 +218,9 @@ typedef struct {
|
||||
} Constraint;
|
||||
|
||||
static const Constraint all_constraints[] = {
|
||||
{constrain_modal_dialog, "constrain_modal_dialog"},
|
||||
{constrain_maximization, "constrain_maximization"},
|
||||
{constrain_tiling, "constrain_tiling"},
|
||||
{constrain_fullscreen, "constrain_fullscreen"},
|
||||
{constrain_size_increments, "constrain_size_increments"},
|
||||
{constrain_size_limits, "constrain_size_limits"},
|
||||
@@ -424,7 +435,8 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
/* Workaround braindead legacy apps that don't know how to
|
||||
* fullscreen themselves properly.
|
||||
*/
|
||||
if (meta_rectangle_equal (new, &monitor_info->rect) &&
|
||||
if (meta_prefs_get_force_fullscreen() &&
|
||||
meta_rectangle_equal (new, &monitor_info->rect) &&
|
||||
window->has_fullscreen_func &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
@@ -526,10 +538,11 @@ place_window_if_needed(MetaWindow *window,
|
||||
if (window->placed || did_placement)
|
||||
{
|
||||
if (window->maximize_horizontally_after_placement ||
|
||||
window->maximize_vertically_after_placement)
|
||||
window->maximize_vertically_after_placement ||
|
||||
window->fullscreen_after_placement)
|
||||
{
|
||||
/* define a sane saved_rect so that the user can unmaximize to
|
||||
* something reasonable.
|
||||
/* define a sane saved_rect so that the user can unmaximize or
|
||||
* make unfullscreen to something reasonable.
|
||||
*/
|
||||
if (info->current.width >= info->work_area_monitor.width)
|
||||
{
|
||||
@@ -556,6 +569,15 @@ place_window_if_needed(MetaWindow *window,
|
||||
if (window->frame && !window->fullscreen)
|
||||
meta_frame_calc_geometry (window->frame, info->fgeom);
|
||||
|
||||
if (window->fullscreen_after_placement)
|
||||
{
|
||||
window->saved_rect = info->current;
|
||||
window->fullscreen = TRUE;
|
||||
window->fullscreen_after_placement = FALSE;
|
||||
|
||||
g_object_notify (G_OBJECT (window), "fullscreen");
|
||||
}
|
||||
|
||||
window->maximize_horizontally_after_placement = FALSE;
|
||||
window->maximize_vertically_after_placement = FALSE;
|
||||
}
|
||||
@@ -714,6 +736,48 @@ get_size_limits (const MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
constrain_modal_dialog (MetaWindow *window,
|
||||
ConstraintInfo *info,
|
||||
ConstraintPriority priority,
|
||||
gboolean check_only)
|
||||
{
|
||||
int x, y;
|
||||
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||
gboolean constraint_already_satisfied;
|
||||
|
||||
if (!meta_prefs_get_attach_modal_dialogs ())
|
||||
return TRUE;
|
||||
if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
|
||||
return TRUE;
|
||||
|
||||
x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2);
|
||||
y = 0;
|
||||
if (parent->frame)
|
||||
{
|
||||
MetaFrameGeometry fgeom;
|
||||
|
||||
x += parent->frame->rect.x;
|
||||
y += parent->frame->rect.y;
|
||||
|
||||
meta_frame_calc_geometry (parent->frame, &fgeom);
|
||||
y += fgeom.top_height;
|
||||
|
||||
y += info->fgeom->top_height;
|
||||
}
|
||||
else
|
||||
y = parent->rect.y + info->fgeom->top_height;
|
||||
|
||||
constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
|
||||
|
||||
if (check_only || constraint_already_satisfied)
|
||||
return constraint_already_satisfied;
|
||||
|
||||
info->current.y = y;
|
||||
info->current.x = x;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
constrain_maximization (MetaWindow *window,
|
||||
ConstraintInfo *info,
|
||||
@@ -730,7 +794,8 @@ constrain_maximization (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Determine whether constraint applies; exit if it doesn't */
|
||||
if (!window->maximized_horizontally && !window->maximized_vertically)
|
||||
if ((!window->maximized_horizontally && !window->maximized_vertically) ||
|
||||
META_WINDOW_TILED (window))
|
||||
return TRUE;
|
||||
|
||||
/* Calculate target_size = maximized size of (window + frame) */
|
||||
@@ -798,6 +863,59 @@ constrain_maximization (MetaWindow *window,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
constrain_tiling (MetaWindow *window,
|
||||
ConstraintInfo *info,
|
||||
ConstraintPriority priority,
|
||||
gboolean check_only)
|
||||
{
|
||||
MetaRectangle target_size;
|
||||
MetaRectangle min_size, max_size;
|
||||
gboolean hminbad, vminbad;
|
||||
gboolean horiz_equal, vert_equal;
|
||||
gboolean constraint_already_satisfied;
|
||||
|
||||
if (priority > PRIORITY_TILING)
|
||||
return TRUE;
|
||||
|
||||
/* Determine whether constraint applies; exit if it doesn't */
|
||||
if (!META_WINDOW_TILED (window))
|
||||
return TRUE;
|
||||
|
||||
/* Calculate target_size - as the tile previews need this as well, we
|
||||
* use an external function for the actual calculation
|
||||
*/
|
||||
meta_window_get_current_tile_area (window, &target_size);
|
||||
unextend_by_frame (&target_size, info->fgeom);
|
||||
|
||||
/* Check min size constraints; max size constraints are ignored as for
|
||||
* maximized windows.
|
||||
*/
|
||||
get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
|
||||
hminbad = target_size.width < min_size.width;
|
||||
vminbad = target_size.height < min_size.height;
|
||||
if (hminbad || vminbad)
|
||||
return TRUE;
|
||||
|
||||
/* Determine whether constraint is already satisfied; exit if it is */
|
||||
horiz_equal = target_size.x == info->current.x &&
|
||||
target_size.width == info->current.width;
|
||||
vert_equal = target_size.y == info->current.y &&
|
||||
target_size.height == info->current.height;
|
||||
constraint_already_satisfied = horiz_equal && vert_equal;
|
||||
if (check_only || constraint_already_satisfied)
|
||||
return constraint_already_satisfied;
|
||||
|
||||
/*** Enforce constraint ***/
|
||||
info->current.x = target_size.x;
|
||||
info->current.width = target_size.width;
|
||||
info->current.y = target_size.y;
|
||||
info->current.height = target_size.height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
constrain_fullscreen (MetaWindow *window,
|
||||
ConstraintInfo *info,
|
||||
@@ -849,7 +967,7 @@ constrain_size_increments (MetaWindow *window,
|
||||
|
||||
/* Determine whether constraint applies; exit if it doesn't */
|
||||
if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
info->action_type == ACTION_MOVE)
|
||||
META_WINDOW_TILED (window) || info->action_type == ACTION_MOVE)
|
||||
return TRUE;
|
||||
|
||||
/* Determine whether constraint is already satisfied; exit if it is */
|
||||
@@ -980,7 +1098,7 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
constraints_are_inconsistent = minr > maxr;
|
||||
if (constraints_are_inconsistent ||
|
||||
META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
info->action_type == ACTION_MOVE)
|
||||
META_WINDOW_TILED (window) || info->action_type == ACTION_MOVE)
|
||||
return TRUE;
|
||||
|
||||
/* Determine whether constraint is already satisfied; exit if it is. We
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "frame-private.h"
|
||||
#include "workspace-private.h"
|
||||
#include "prefs.h"
|
||||
#include "errors.h"
|
||||
|
||||
/* Looks up the MetaWindow representing the frame of the given X window.
|
||||
* Used as a helper function by a bunch of the functions below.
|
||||
@@ -260,15 +261,14 @@ meta_core_user_raise (Display *xdisplay,
|
||||
meta_window_raise (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_lower_and_unfocus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp)
|
||||
static gboolean
|
||||
lower_window_and_transients (MetaWindow *window,
|
||||
gpointer data)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_lower (window);
|
||||
|
||||
meta_window_foreach_transient (window, lower_window_and_transients, NULL);
|
||||
|
||||
if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
|
||||
meta_prefs_get_raise_on_click ())
|
||||
{
|
||||
@@ -296,11 +296,59 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
|
||||
}
|
||||
}
|
||||
|
||||
/* focus the default window, if needed */
|
||||
if (window->has_focus)
|
||||
meta_workspace_focus_default_window (window->screen->active_workspace,
|
||||
NULL,
|
||||
timestamp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_lower_and_unfocus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
lower_window_and_transients (window, NULL);
|
||||
|
||||
/* Rather than try to figure that out whether we just lowered
|
||||
* the focus window, assume that's always the case. (Typically,
|
||||
* this will be invoked via keyboard action or by a mouse action;
|
||||
* in either case the window or a modal child will have been focused.) */
|
||||
meta_workspace_focus_default_window (window->screen->active_workspace,
|
||||
NULL,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_lower_beneath_focus_window (Display *xdisplay,
|
||||
Window xwindow,
|
||||
guint32 timestamp)
|
||||
{
|
||||
XWindowChanges changes;
|
||||
MetaDisplay *display;
|
||||
MetaScreen *screen;
|
||||
MetaWindow *focus_window;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
screen = meta_display_screen_for_xwindow (display, xwindow);
|
||||
focus_window = meta_stack_get_top (screen->stack);
|
||||
|
||||
if (focus_window == NULL)
|
||||
return;
|
||||
|
||||
changes.stack_mode = Below;
|
||||
changes.sibling = focus_window->frame ? focus_window->frame->xwindow
|
||||
: focus_window->xwindow;
|
||||
|
||||
meta_stack_tracker_record_lower_below (screen->stack_tracker,
|
||||
xwindow,
|
||||
changes.sibling,
|
||||
XNextRequest (screen->display->xdisplay));
|
||||
|
||||
meta_error_trap_push (display);
|
||||
XConfigureWindow (xdisplay,
|
||||
xwindow,
|
||||
CWSibling | CWStackMode,
|
||||
&changes);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -526,6 +574,9 @@ meta_core_get_menu_accelerator (MetaMenuOp menu_op,
|
||||
|
||||
switch (menu_op)
|
||||
{
|
||||
case META_MENU_OP_NONE:
|
||||
/* No keybinding for this one */
|
||||
break;
|
||||
case META_MENU_OP_DELETE:
|
||||
name = "close";
|
||||
break;
|
||||
|
@@ -22,8 +22,7 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _SVID_SOURCE /* for gethostname() */
|
||||
#define _XOPEN_SOURCE /* for kill() */
|
||||
|
||||
#include <config.h>
|
||||
#include "util.h"
|
||||
@@ -32,6 +31,7 @@
|
||||
#include "workspace.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
@@ -55,27 +55,16 @@ delete_ping_reply_func (MetaDisplay *display,
|
||||
/* we do nothing */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
delete_window_callback (gpointer w_p)
|
||||
{
|
||||
meta_window_kill ((MetaWindow*) w_p);
|
||||
|
||||
return FALSE; /* don't do it again */
|
||||
}
|
||||
|
||||
static void
|
||||
sigchld_handler (MetaNexus *nexus, guint arg1, gpointer arg2, gpointer user_data)
|
||||
dialog_exited (GPid pid, int status, gpointer user_data)
|
||||
{
|
||||
MetaWindow *ours = (MetaWindow*) user_data;
|
||||
|
||||
if (GPOINTER_TO_INT (arg2) == ours->dialog_pid)
|
||||
{
|
||||
if (arg1 == 1 /* pressed "force quit" */)
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT,
|
||||
delete_window_callback, user_data, NULL);
|
||||
ours->dialog_pid = -1;
|
||||
|
||||
ours->dialog_pid = -1; /* forget it anyway */
|
||||
}
|
||||
/* exit status of 1 means the user pressed "Force Quit" */
|
||||
if (WIFEXITED (status) && WEXITSTATUS (status) == 1)
|
||||
meta_window_kill (ours);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -86,7 +75,7 @@ delete_ping_timeout_func (MetaDisplay *display,
|
||||
{
|
||||
MetaWindow *window = user_data;
|
||||
char *window_title;
|
||||
gchar *window_content;
|
||||
gchar *window_content, *tmp;
|
||||
GPid dialog_pid;
|
||||
|
||||
meta_topic (META_DEBUG_PING,
|
||||
@@ -101,11 +90,14 @@ delete_ping_timeout_func (MetaDisplay *display,
|
||||
|
||||
window_title = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL);
|
||||
|
||||
window_content = g_strdup_printf(
|
||||
_("<big><b><tt>%s</tt> is not responding.</b></big>\n\n"
|
||||
"<i>You may choose to wait a short while for it to "
|
||||
"continue or force the application to quit entirely.</i>"),
|
||||
window_title);
|
||||
/* Translators: %s is a window title */
|
||||
tmp = g_strdup_printf (_("<tt>%s</tt> is not responding."),
|
||||
window_title);
|
||||
window_content = g_strdup_printf (
|
||||
"<big><b>%s</b></big>\n\n<i>%s</i>",
|
||||
tmp,
|
||||
_("You may choose to wait a short while for it to "
|
||||
"continue or force the application to quit entirely."));
|
||||
|
||||
g_free (window_title);
|
||||
|
||||
@@ -117,13 +109,10 @@ delete_ping_timeout_func (MetaDisplay *display,
|
||||
NULL, NULL);
|
||||
|
||||
g_free (window_content);
|
||||
g_free (tmp);
|
||||
|
||||
window->dialog_pid = dialog_pid;
|
||||
|
||||
g_signal_connect (sigchld_nexus, "sigchld",
|
||||
G_CALLBACK (sigchld_handler),
|
||||
window);
|
||||
|
||||
g_child_watch_add (dialog_pid, dialog_exited, window);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -189,36 +178,23 @@ meta_window_delete (MetaWindow *window,
|
||||
void
|
||||
meta_window_kill (MetaWindow *window)
|
||||
{
|
||||
char buf[257];
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Killing %s brutally\n",
|
||||
window->desc);
|
||||
|
||||
if (window->wm_client_machine != NULL &&
|
||||
if (!meta_window_is_remote (window) &&
|
||||
window->net_wm_pid > 0)
|
||||
{
|
||||
if (gethostname (buf, sizeof(buf)-1) == 0)
|
||||
{
|
||||
if (strcmp (buf, window->wm_client_machine) == 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Killing %s with kill()\n",
|
||||
window->desc);
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Killing %s with kill()\n",
|
||||
window->desc);
|
||||
|
||||
if (kill (window->net_wm_pid, 9) < 0)
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Failed to signal %s: %s\n",
|
||||
window->desc, strerror (errno));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_warning (_("Failed to get hostname: %s\n"),
|
||||
strerror (errno));
|
||||
}
|
||||
if (kill (window->net_wm_pid, 9) < 0)
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Failed to signal %s: %s\n",
|
||||
window->desc, strerror (errno));
|
||||
}
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Disconnecting %s with XKillClient()\n",
|
||||
window->desc);
|
||||
|
@@ -83,10 +83,11 @@ struct _MetaDisplay
|
||||
|
||||
char *name;
|
||||
Display *xdisplay;
|
||||
char *hostname;
|
||||
|
||||
Window leader_window;
|
||||
Window timestamp_pinging_window;
|
||||
|
||||
|
||||
/* Pull in all the names of atoms as fields; we will intern them when the
|
||||
* class is constructed.
|
||||
*/
|
||||
@@ -150,6 +151,15 @@ struct _MetaDisplay
|
||||
|
||||
guint32 current_time;
|
||||
|
||||
/* We maintain a sequence counter, incremented for each #MetaWindow
|
||||
* created. This is exposed by meta_window_get_stable_sequence()
|
||||
* but is otherwise not used inside mutter.
|
||||
*
|
||||
* It can be useful to plugins which want to sort windows in a
|
||||
* stable fashion.
|
||||
*/
|
||||
guint32 window_sequence_counter;
|
||||
|
||||
/* Pings which we're waiting for a reply from */
|
||||
GSList *pending_pings;
|
||||
|
||||
@@ -175,6 +185,9 @@ struct _MetaDisplay
|
||||
guint grab_have_pointer : 1;
|
||||
guint grab_have_keyboard : 1;
|
||||
guint grab_frame_action : 1;
|
||||
/* During a resize operation, the directions in which we've broken
|
||||
* out of the initial maximization state */
|
||||
guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
|
||||
MetaRectangle grab_initial_window_pos;
|
||||
int grab_initial_x, grab_initial_y; /* These are only relevant for */
|
||||
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
|
||||
@@ -294,22 +307,15 @@ struct _MetaDisplayClass
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
/* Xserver time can wraparound, thus comparing two timestamps needs to take
|
||||
* this into account. Here's a little macro to help out. If no wraparound
|
||||
* has occurred, this is equivalent to
|
||||
* time1 < time2
|
||||
* Of course, the rest of the ugliness of this macro comes from accounting
|
||||
* for the fact that wraparound can occur and the fact that a timestamp of
|
||||
* 0 must be special-cased since it means older than anything else.
|
||||
*
|
||||
* Note that this is NOT an equivalent for time1 <= time2; if that's what
|
||||
* you need then you'll need to swap the order of the arguments and negate
|
||||
* the result.
|
||||
*/
|
||||
#define XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) \
|
||||
( (( (time1) < (time2) ) && ( (time2) - (time1) < ((guint32)-1)/2 )) || \
|
||||
(( (time1) > (time2) ) && ( (time1) - (time2) > ((guint32)-1)/2 )) \
|
||||
)
|
||||
/**
|
||||
* XSERVER_TIME_IS_BEFORE:
|
||||
*
|
||||
* See the docs for meta_display_xserver_time_is_before().
|
||||
*/
|
||||
#define XSERVER_TIME_IS_BEFORE(time1, time2) \
|
||||
( (time1) == 0 || \
|
||||
(XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) && \
|
||||
@@ -349,6 +355,9 @@ void meta_display_register_x_window (MetaDisplay *display,
|
||||
void meta_display_unregister_x_window (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
|
||||
void meta_display_notify_window_created (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
GSList* meta_display_list_windows (MetaDisplay *display,
|
||||
MetaListWindowsFlags flags);
|
||||
|
||||
@@ -378,9 +387,8 @@ void meta_display_grab_focus_window_button (MetaDisplay *display,
|
||||
void meta_display_ungrab_focus_window_button (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
/* Next two functions are defined in edge-resistance.c */
|
||||
void meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display);
|
||||
void meta_display_cleanup_edges (MetaDisplay *display);
|
||||
/* Next function is defined in edge-resistance.c */
|
||||
void meta_display_cleanup_edges (MetaDisplay *display);
|
||||
|
||||
/* make a request to ensure the event serial has changed */
|
||||
void meta_display_increment_event_serial (MetaDisplay *display);
|
||||
|
@@ -30,6 +30,8 @@
|
||||
* The display is represented as a MetaDisplay struct.
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 600 /* for gethostname() */
|
||||
|
||||
#include <config.h>
|
||||
#include "display-private.h"
|
||||
#include "util.h"
|
||||
@@ -72,6 +74,7 @@
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define GRAB_OP_IS_WINDOW_SWITCH(g) \
|
||||
(g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \
|
||||
@@ -129,6 +132,9 @@ enum
|
||||
{
|
||||
OVERLAY_KEY,
|
||||
FOCUS_WINDOW,
|
||||
WINDOW_CREATED,
|
||||
WINDOW_DEMANDS_ATTENTION,
|
||||
WINDOW_MARKED_URGENT,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -148,8 +154,10 @@ static guint display_signals [LAST_SIGNAL] = { 0 };
|
||||
*/
|
||||
static MetaDisplay *the_display = NULL;
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
static void meta_spew_event (MetaDisplay *display,
|
||||
XEvent *event);
|
||||
#endif
|
||||
|
||||
static gboolean event_callback (XEvent *event,
|
||||
gpointer data);
|
||||
@@ -226,6 +234,34 @@ meta_display_class_init (MetaDisplayClass *klass)
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
display_signals[WINDOW_CREATED] =
|
||||
g_signal_new ("window-created",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, META_TYPE_WINDOW);
|
||||
|
||||
display_signals[WINDOW_DEMANDS_ATTENTION] =
|
||||
g_signal_new ("window-demands-attention",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, META_TYPE_WINDOW);
|
||||
|
||||
display_signals[WINDOW_MARKED_URGENT] =
|
||||
g_signal_new ("window-marked-urgent",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
META_TYPE_WINDOW);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_FOCUS_WINDOW,
|
||||
g_param_spec_object ("focus-window",
|
||||
@@ -396,6 +432,7 @@ meta_display_open (void)
|
||||
GSList *tmp;
|
||||
int i;
|
||||
guint32 timestamp;
|
||||
char buf[257];
|
||||
|
||||
/* A list of all atom names, so that we can intern them in one go. */
|
||||
char *atom_names[] = {
|
||||
@@ -430,6 +467,11 @@ meta_display_open (void)
|
||||
*/
|
||||
the_display->name = g_strdup (XDisplayName (NULL));
|
||||
the_display->xdisplay = xdisplay;
|
||||
if (gethostname (buf, sizeof(buf)-1) == 0)
|
||||
{
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
the_display->hostname = g_strdup (buf);
|
||||
}
|
||||
the_display->error_trap_synced_at_last_pop = TRUE;
|
||||
the_display->error_traps = 0;
|
||||
the_display->error_trap_handler = NULL;
|
||||
@@ -1287,6 +1329,43 @@ meta_grab_op_is_moving (MetaGrabOp op)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_xserver_time_is_before:
|
||||
* @display: a #MetaDisplay
|
||||
* @time1: An event timestamp
|
||||
* @time2: An event timestamp
|
||||
*
|
||||
* Xserver time can wraparound, thus comparing two timestamps needs to take
|
||||
* this into account. If no wraparound has occurred, this is equivalent to
|
||||
* time1 < time2
|
||||
* Otherwise, we need to account for the fact that wraparound can occur
|
||||
* and the fact that a timestamp of 0 must be special-cased since it
|
||||
* means "older than anything else".
|
||||
*
|
||||
* Note that this is NOT an equivalent for time1 <= time2; if that's what
|
||||
* you need then you'll need to swap the order of the arguments and negate
|
||||
* the result.
|
||||
*/
|
||||
gboolean
|
||||
meta_display_xserver_time_is_before (MetaDisplay *display,
|
||||
guint32 time1,
|
||||
guint32 time2)
|
||||
{
|
||||
return XSERVER_TIME_IS_BEFORE(time1, time2);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_last_user_time:
|
||||
* @display: a #MetaDisplay
|
||||
*
|
||||
* Returns: Timestamp of the last user interaction event with a window
|
||||
*/
|
||||
guint32
|
||||
meta_display_get_last_user_time (MetaDisplay *display)
|
||||
{
|
||||
return display->last_user_time;
|
||||
}
|
||||
|
||||
/* Get time of current event, or CurrentTime if none. */
|
||||
guint32
|
||||
meta_display_get_current_time (MetaDisplay *display)
|
||||
@@ -1656,7 +1735,8 @@ event_callback (XEvent *event,
|
||||
}
|
||||
#endif /* HAVE_SHAPE */
|
||||
|
||||
if (window && ((event->type == KeyPress) || (event->type == ButtonPress)))
|
||||
if (window && !window->override_redirect &&
|
||||
((event->type == KeyPress) || (event->type == ButtonPress)))
|
||||
{
|
||||
if (CurrentTime == display->current_time)
|
||||
{
|
||||
@@ -2556,7 +2636,7 @@ event_callback (XEvent *event,
|
||||
{
|
||||
case XkbBellNotify:
|
||||
if (XSERVER_TIME_IS_BEFORE(display->last_bell_time,
|
||||
xkb_ev->time - 1000))
|
||||
xkb_ev->time - 100))
|
||||
{
|
||||
display->last_bell_time = xkb_ev->time;
|
||||
meta_bell_notify (display, xkb_ev);
|
||||
@@ -3210,6 +3290,13 @@ meta_display_unregister_x_window (MetaDisplay *display,
|
||||
remove_pending_pings_for_window (display, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_notify_window_created (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
g_signal_emit (display, display_signals[WINDOW_CREATED], 0, window);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_xwindow_is_a_no_focus_window:
|
||||
* @display: A #MetaDisplay
|
||||
@@ -3523,6 +3610,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
display->grab_last_user_action_was_snap = FALSE;
|
||||
#endif
|
||||
display->grab_frame_action = frame_action;
|
||||
display->grab_resize_unmaximize = 0;
|
||||
|
||||
if (display->grab_resize_timeout_id)
|
||||
{
|
||||
@@ -3598,18 +3686,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
g_assert (display->grab_window != NULL || display->grab_screen != NULL);
|
||||
g_assert (display->grab_op != META_GRAB_OP_NONE);
|
||||
|
||||
/* If this is a move or resize, cache the window edges for
|
||||
* resistance/snapping
|
||||
*/
|
||||
if (meta_grab_op_is_resizing (display->grab_op) ||
|
||||
meta_grab_op_is_moving (display->grab_op))
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Computing edges to resist-movement or snap-to for %s.\n",
|
||||
window->desc);
|
||||
meta_display_compute_resistance_and_snapping_edges (display);
|
||||
}
|
||||
|
||||
/* Save the old stacking */
|
||||
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
|
||||
{
|
||||
@@ -4104,8 +4180,8 @@ meta_set_syncing (gboolean setting)
|
||||
if (setting != is_syncing)
|
||||
{
|
||||
is_syncing = setting;
|
||||
|
||||
XSynchronize (meta_get_display ()->xdisplay, is_syncing);
|
||||
if (meta_get_display ())
|
||||
XSynchronize (meta_get_display ()->xdisplay, is_syncing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4113,7 +4189,7 @@ meta_set_syncing (gboolean setting)
|
||||
* How long, in milliseconds, we should wait after pinging a window
|
||||
* before deciding it's not going to get back to us.
|
||||
*/
|
||||
#define PING_TIMEOUT_DELAY 2250
|
||||
#define PING_TIMEOUT_DELAY 5000
|
||||
|
||||
/**
|
||||
* Does whatever it is we decided to do when a window didn't respond
|
||||
@@ -4475,6 +4551,18 @@ find_tab_backward (MetaDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_tab_list:
|
||||
* @display: a #MetaDisplay
|
||||
* @type: type of tab list
|
||||
* @screen: a #MetaScreen
|
||||
* @workspace: origin workspace
|
||||
*
|
||||
* Determine the list of windows that should be displayed for Alt-TAB
|
||||
* functionality. The windows are returned in most recently used order.
|
||||
*
|
||||
* Returns: (transfer container) (element-type Meta.Window): List of windows
|
||||
*/
|
||||
GList*
|
||||
meta_display_get_tab_list (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
@@ -4538,7 +4626,8 @@ meta_display_get_tab_list (MetaDisplay *display,
|
||||
|
||||
/* Check to see if it demands attention */
|
||||
if (l_window->wm_state_demands_attention &&
|
||||
l_window->workspace!=workspace)
|
||||
l_window->workspace!=workspace &&
|
||||
IN_TAB_CHAIN (l_window, type))
|
||||
{
|
||||
/* if it does, add it to the popup */
|
||||
tab_list = g_list_prepend (tab_list, l_window);
|
||||
@@ -4551,6 +4640,21 @@ meta_display_get_tab_list (MetaDisplay *display,
|
||||
return tab_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_tab_next:
|
||||
* @display: a #MetaDisplay
|
||||
* @type: type of tab list
|
||||
* @screen: a #MetaScreen
|
||||
* @workspace: origin workspace
|
||||
* @window: (allow-none): starting window
|
||||
* @backward: If %TRUE, look for the previous window.
|
||||
*
|
||||
* Determine the next window that should be displayed for Alt-TAB
|
||||
* functionality.
|
||||
*
|
||||
* Returns: (transfer none): Next window
|
||||
*
|
||||
*/
|
||||
MetaWindow*
|
||||
meta_display_get_tab_next (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
@@ -4601,6 +4705,18 @@ meta_display_get_tab_next (MetaDisplay *display,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_tab_current:
|
||||
* @display: a #MetaDisplay
|
||||
* @type: type of tab list
|
||||
* @screen: a #MetaScreen
|
||||
* @workspace: origin workspace
|
||||
*
|
||||
* Determine the active window that should be displayed for Alt-TAB.
|
||||
*
|
||||
* Returns: (transfer none): Current window
|
||||
*
|
||||
*/
|
||||
MetaWindow*
|
||||
meta_display_get_tab_current (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
@@ -4945,6 +5061,34 @@ meta_display_stack_cmp (const void *a,
|
||||
return 0; /* not reached in theory, if windows on same display */
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_sort_windows_by_stacking:
|
||||
* @display: a #MetaDisplay
|
||||
* @windows: (element-type MetaWindow): Set of windows
|
||||
*
|
||||
* Sorts a set of windows according to their current stacking order. If windows
|
||||
* from multiple screens are present in the set of input windows, then all the
|
||||
* windows on screen 0 are sorted below all the windows on screen 1, and so forth.
|
||||
* Since the stacking order of override-redirect windows isn't controlled by
|
||||
* Metacity, if override-redirect windows are in the input, the result may not
|
||||
* correspond to the actual stacking order in the X server.
|
||||
*
|
||||
* An example of using this would be to sort the list of transient dialogs for a
|
||||
* window into their current stacking order.
|
||||
*
|
||||
* Returns: (transfer container): Input windows sorted by stacking order, from lowest to highest
|
||||
*/
|
||||
GSList *
|
||||
meta_display_sort_windows_by_stacking (MetaDisplay *display,
|
||||
GSList *windows)
|
||||
{
|
||||
GSList *copy = g_slist_copy (windows);
|
||||
|
||||
copy = g_slist_sort (copy, meta_display_stack_cmp);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_devirtualize_modifiers (MetaDisplay *display,
|
||||
MetaVirtualModifier modifiers,
|
||||
@@ -5049,6 +5193,34 @@ prefs_changed_callback (MetaPreference pref,
|
||||
else
|
||||
disable_compositor (display);
|
||||
}
|
||||
else if (pref == META_PREF_ATTACH_MODAL_DIALOGS)
|
||||
{
|
||||
MetaDisplay *display = data;
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
|
||||
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
||||
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
MetaWindow *parent = meta_window_get_transient_for (w);
|
||||
meta_window_recalc_features (w);
|
||||
|
||||
if (w->type == META_WINDOW_MODAL_DIALOG && parent && parent != w)
|
||||
{
|
||||
int x, y;
|
||||
/* Forcing a call to move_resize() does two things: first, it handles
|
||||
* resizing the dialog frame window to the correct size when we remove
|
||||
* or add the decorations. Second, it will take care of positioning the
|
||||
* dialog as "attached" to the parent when we turn the preference on
|
||||
* via the constrain_modal_dialog() constraint.
|
||||
**/
|
||||
meta_window_get_position (w, &x, &y);
|
||||
meta_window_move (w, FALSE, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -5249,18 +5421,32 @@ meta_display_get_compositor_version (MetaDisplay *display,
|
||||
*minor = display->composite_minor_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_xdisplay: (skip)
|
||||
*
|
||||
*/
|
||||
Display *
|
||||
meta_display_get_xdisplay (MetaDisplay *display)
|
||||
{
|
||||
return display->xdisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_compositor: (skip)
|
||||
*
|
||||
*/
|
||||
MetaCompositor *
|
||||
meta_display_get_compositor (MetaDisplay *display)
|
||||
{
|
||||
return display->compositor;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_screens:
|
||||
* @display: a #MetaDisplay
|
||||
*
|
||||
* Returns: (transfer none) (element-type Meta.Screen): Screens for this display
|
||||
*/
|
||||
GSList *
|
||||
meta_display_get_screens (MetaDisplay *display)
|
||||
{
|
||||
@@ -5311,3 +5497,19 @@ Atom meta_display_get_atom (MetaDisplay *display, MetaAtom meta_atom)
|
||||
|
||||
return atoms[meta_atom - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_get_leader_window:
|
||||
* @display: a #MetaDisplay
|
||||
*
|
||||
* Returns the window manager's leader window (as defined by the
|
||||
* _NET_SUPPORTING_WM_CHECK mechanism of EWMH). For use by plugins that wish
|
||||
* to attach additional custom properties to this window.
|
||||
*
|
||||
* Return value: (transfer none): xid of the leader window.
|
||||
**/
|
||||
Window
|
||||
meta_display_get_leader_window (MetaDisplay *display)
|
||||
{
|
||||
return display->leader_window;
|
||||
}
|
||||
|
@@ -63,6 +63,8 @@ struct MetaEdgeResistanceData
|
||||
ResistanceDataForAnEdge bottom_data;
|
||||
};
|
||||
|
||||
static void compute_resistance_and_snapping_edges (MetaDisplay *display);
|
||||
|
||||
/* !WARNING!: this function can return invalid indices (namely, either -1 or
|
||||
* edges->len); this is by design, but you need to remember this.
|
||||
*/
|
||||
@@ -550,7 +552,9 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
|
||||
gboolean modified;
|
||||
int new_left, new_right, new_top, new_bottom;
|
||||
|
||||
g_assert (display->grab_edge_resistance_data != NULL);
|
||||
if (display->grab_edge_resistance_data == NULL)
|
||||
compute_resistance_and_snapping_edges (display);
|
||||
|
||||
edge_data = display->grab_edge_resistance_data;
|
||||
|
||||
if (auto_snap)
|
||||
@@ -671,7 +675,8 @@ meta_display_cleanup_edges (MetaDisplay *display)
|
||||
MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
|
||||
GHashTable *edges_to_be_freed;
|
||||
|
||||
g_assert (edge_data != NULL);
|
||||
if (edge_data == NULL) /* Not currently cached */
|
||||
return;
|
||||
|
||||
/* We first need to clean out any window edges */
|
||||
edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||
@@ -938,8 +943,8 @@ initialize_grab_edge_resistance_data (MetaDisplay *display)
|
||||
edge_data->bottom_data.keyboard_buildup = 0;
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
static void
|
||||
compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
{
|
||||
GList *stacked_windows;
|
||||
GList *cur_window_iter;
|
||||
@@ -952,6 +957,11 @@ meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
*/
|
||||
GSList *rem_windows, *rem_win_stacking;
|
||||
|
||||
g_assert (display->grab_window != NULL);
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Computing edges to resist-movement or snap-to for %s.\n",
|
||||
display->grab_window->desc);
|
||||
|
||||
/*
|
||||
* 1st: Get the list of relevant windows, from bottom to top
|
||||
*/
|
||||
|
@@ -28,18 +28,68 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h> /* Only for GTK_CHECK_VERSION */
|
||||
|
||||
/* In GTK+-3.0, the error trapping code was significantly rewritten. The new code
|
||||
* has some neat features (like knowing automatically if a sync is needed or not
|
||||
* and handling errors asynchronously when the error code isn't needed immediately),
|
||||
* but it's basically incompatible with the hacks we played with GTK+-2.0 to
|
||||
* use a custom error handler along with gdk_error_trap_push().
|
||||
*
|
||||
* Since the main point of our custom error trap was to get the error logged
|
||||
* to the right place, with GTK+-3.0 we simply omit our own error handler and
|
||||
* use the GTK+ handling straight-up.
|
||||
* (See https://bugzilla.gnome.org/show_bug.cgi?id=630216 for restoring logging.)
|
||||
*/
|
||||
#if GTK_CHECK_VERSION(2, 90, 0)
|
||||
#define USE_GDK_ERROR_HANDLERS 1
|
||||
#endif
|
||||
|
||||
#ifndef USE_GDK_ERROR_HANDLERS
|
||||
static int x_error_handler (Display *display,
|
||||
XErrorEvent *error);
|
||||
static int x_io_error_handler (Display *display);
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_errors_init (void)
|
||||
{
|
||||
#ifndef USE_GDK_ERROR_HANDLERS
|
||||
XSetErrorHandler (x_error_handler);
|
||||
XSetIOErrorHandler (x_io_error_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_GDK_ERROR_HANDLERS
|
||||
|
||||
void
|
||||
meta_error_trap_push (MetaDisplay *display)
|
||||
{
|
||||
gdk_error_trap_push ();
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_pop (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip)
|
||||
{
|
||||
gdk_error_trap_pop_ignored ();
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_push_with_return (MetaDisplay *display)
|
||||
{
|
||||
gdk_error_trap_push ();
|
||||
}
|
||||
|
||||
int
|
||||
meta_error_trap_pop_with_return (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip)
|
||||
{
|
||||
return gdk_error_trap_pop ();
|
||||
}
|
||||
|
||||
#else /* !USE_GDK_ERROR_HANDLERS */
|
||||
|
||||
static void
|
||||
meta_error_trap_push_internal (MetaDisplay *display,
|
||||
gboolean need_sync)
|
||||
@@ -186,10 +236,10 @@ x_error_handler (Display *xdisplay,
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
/* Display can be NULL here because the compositing manager
|
||||
* has its own Display, but Xlib only has one global error handler
|
||||
/* Display can be NULL here Xlib only has one global error handler; and
|
||||
* there might be other displays open in the process.
|
||||
*/
|
||||
if (display->error_traps > 0)
|
||||
if (display && display->error_traps > 0)
|
||||
{
|
||||
/* we're in an error trap, chain to the trap handler
|
||||
* saved from GDK
|
||||
@@ -228,21 +278,18 @@ x_io_error_handler (Display *xdisplay)
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
if (display == NULL)
|
||||
meta_bug ("IO error received for unknown display?\n");
|
||||
|
||||
if (errno == EPIPE)
|
||||
{
|
||||
meta_warning (_("Lost connection to the display '%s';\n"
|
||||
"most likely the X server was shut down or you killed/destroyed\n"
|
||||
"the window manager.\n"),
|
||||
display->name);
|
||||
display ? display->name : DisplayString (xdisplay));
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_warning (_("Fatal IO error %d (%s) on display '%s'.\n"),
|
||||
errno, g_strerror (errno),
|
||||
display->name);
|
||||
display ? display->name : DisplayString (xdisplay));
|
||||
}
|
||||
|
||||
/* Xlib would force an exit anyhow */
|
||||
@@ -250,3 +297,5 @@ x_io_error_handler (Display *xdisplay)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* USE_GDK_ERROR_HANDLERS */
|
||||
|
@@ -276,7 +276,7 @@ meta_frame_get_flags (MetaFrame *frame)
|
||||
if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
|
||||
flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
|
||||
|
||||
if (frame->window->has_focus)
|
||||
if (meta_window_appears_focused (frame->window))
|
||||
flags |= META_FRAME_HAS_FOCUS;
|
||||
|
||||
if (frame->window->shaded)
|
||||
|
@@ -104,6 +104,10 @@ meta_group_unref (MetaGroup *group)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_group: (skip)
|
||||
*
|
||||
*/
|
||||
MetaGroup*
|
||||
meta_window_get_group (MetaWindow *window)
|
||||
{
|
||||
@@ -198,6 +202,10 @@ meta_window_shutdown_group (MetaWindow *window)
|
||||
remove_window_from_group (window);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_display_lookup_group: (skip)
|
||||
*
|
||||
*/
|
||||
MetaGroup*
|
||||
meta_display_lookup_group (MetaDisplay *display,
|
||||
Window group_leader)
|
||||
@@ -213,6 +221,12 @@ meta_display_lookup_group (MetaDisplay *display,
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_group_list_windows:
|
||||
* @group: A #MetaGroup
|
||||
*
|
||||
* Returns: (transfer container) (element-type Meta.Window): List of windows
|
||||
*/
|
||||
GSList*
|
||||
meta_group_list_windows (MetaGroup *group)
|
||||
{
|
||||
@@ -263,6 +277,10 @@ meta_group_get_startup_id (MetaGroup *group)
|
||||
return group->startup_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_group_property_notify: (skip)
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
meta_group_property_notify (MetaGroup *group,
|
||||
XEvent *event)
|
||||
|
@@ -394,17 +394,15 @@ try_pixmap_and_mask (MetaDisplay *display,
|
||||
|
||||
get_pixmap_geometry (display, src_pixmap, &w, &h, NULL);
|
||||
|
||||
unscaled = meta_gdk_pixbuf_get_from_pixmap (NULL,
|
||||
src_pixmap,
|
||||
0, 0, 0, 0,
|
||||
unscaled = meta_gdk_pixbuf_get_from_pixmap (src_pixmap,
|
||||
0, 0,
|
||||
w, h);
|
||||
|
||||
if (unscaled && src_mask != None)
|
||||
{
|
||||
get_pixmap_geometry (display, src_mask, &w, &h, NULL);
|
||||
mask = meta_gdk_pixbuf_get_from_pixmap (NULL,
|
||||
src_mask,
|
||||
0, 0, 0, 0,
|
||||
mask = meta_gdk_pixbuf_get_from_pixmap (src_mask,
|
||||
0, 0,
|
||||
w, h);
|
||||
}
|
||||
|
||||
|
@@ -499,14 +499,25 @@ display_get_keybinding (MetaDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static MetaKeyBindingAction
|
||||
display_get_keybinding_action (MetaDisplay *display,
|
||||
unsigned int keysym,
|
||||
unsigned int keycode,
|
||||
unsigned long mask)
|
||||
/**
|
||||
* meta_display_get_keybinding_action:
|
||||
* @display: A #MetaDisplay
|
||||
* @keysym: Key symbol
|
||||
* @keycode: Raw keycode
|
||||
* @mask: Event mask
|
||||
*
|
||||
* Returns: The action that should be taken for the given key, or %META_KEYBINDING_ACTION_NONE.
|
||||
*
|
||||
*/
|
||||
MetaKeyBindingAction
|
||||
meta_display_get_keybinding_action (MetaDisplay *display,
|
||||
unsigned int keysym,
|
||||
unsigned int keycode,
|
||||
unsigned long mask)
|
||||
{
|
||||
MetaKeyBinding *binding;
|
||||
|
||||
mask = mask & 0xff & ~display->ignored_modifier_mask;
|
||||
binding = display_get_keybinding (display, keysym, keycode, mask);
|
||||
|
||||
if (binding)
|
||||
@@ -2047,15 +2058,11 @@ process_tab_grab (MetaDisplay *display,
|
||||
action = META_KEYBINDING_ACTION_NONE;
|
||||
|
||||
/*
|
||||
* There are currently two different ways of customizing Alt-Tab, you can either
|
||||
* provide a replacement AltTabHandler object, or you can hook into the keybindings
|
||||
* meta_keybindings_set_custom_handler() and call meta_display_begin_grab_op()
|
||||
* yourself with one of the "tabbing" grab ops META_GRAB_OP_KEYBOARD_TABBING_NORMAL,
|
||||
* etc. See meta_display_process_key_event() for the complete list. If screen->tab_handler
|
||||
* is NULL, the latter mechanism is being used. We skip most of our normal
|
||||
* processing and just make sure that the right custom handlers get called.
|
||||
* If there is no tab_pop up object, i.e., there is some custom handler
|
||||
* implementing Alt+Tab & Co., we call this custom handler; we do not
|
||||
* mess about with the grab, as that is up to the handler to deal with.
|
||||
*/
|
||||
if (!screen->tab_handler)
|
||||
if (!screen->tab_popup)
|
||||
{
|
||||
if (event->type == KeyRelease)
|
||||
{
|
||||
@@ -2102,6 +2109,16 @@ process_tab_grab (MetaDisplay *display,
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case META_KEYBINDING_ACTION_NONE:
|
||||
{
|
||||
/*
|
||||
* If this is simply user pressing the Shift key, we do not want
|
||||
* to cancel the grab.
|
||||
*/
|
||||
if (is_modifier (display, event->xkey.keycode))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2760,10 +2777,10 @@ process_workspace_switch_grab (MetaDisplay *display,
|
||||
MetaWorkspace *target_workspace;
|
||||
MetaKeyBindingAction action;
|
||||
|
||||
action = display_get_keybinding_action (display,
|
||||
keysym,
|
||||
event->xkey.keycode,
|
||||
display->grab_mask);
|
||||
action = meta_display_get_keybinding_action (display,
|
||||
keysym,
|
||||
event->xkey.keycode,
|
||||
display->grab_mask);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
@@ -3530,6 +3547,10 @@ meta_keybindings_set_custom_handler (const gchar *name,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_keybindings_switch_window: (skip)
|
||||
*
|
||||
*/
|
||||
void
|
||||
meta_keybindings_switch_window (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
|
@@ -68,6 +68,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
@@ -124,11 +125,13 @@ log_handler (const gchar *log_domain,
|
||||
static void
|
||||
version (void)
|
||||
{
|
||||
const int latest_year = 2010;
|
||||
|
||||
g_print (_("mutter %s\n"
|
||||
"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n"
|
||||
"Copyright (C) 2001-%d 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);
|
||||
VERSION, latest_year);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
@@ -226,6 +229,7 @@ typedef struct
|
||||
gboolean sync;
|
||||
gboolean composite;
|
||||
gboolean no_composite;
|
||||
gboolean no_force_fullscreen;
|
||||
gboolean no_tab_popup;
|
||||
gchar *introspect;
|
||||
} MetaArguments;
|
||||
@@ -304,6 +308,12 @@ meta_parse_options (int *argc, char ***argv,
|
||||
N_("Turn compositing off"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"no-force-fullscreen", 0, COMPOSITE_OPTS_FLAGS, G_OPTION_ARG_NONE,
|
||||
&my_args.no_force_fullscreen,
|
||||
N_("Don't make fullscreen windows that are maximized and have no decorations"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"mutter-plugins", 0, 0, G_OPTION_ARG_STRING,
|
||||
&my_args.mutter_plugins,
|
||||
@@ -331,6 +341,7 @@ meta_parse_options (int *argc, char ***argv,
|
||||
ctx = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (ctx, options, "mutter");
|
||||
g_option_context_add_group (ctx, clutter_get_option_group_without_init ());
|
||||
g_option_context_add_group (ctx, cogl_get_option_group ());
|
||||
|
||||
if (!g_option_context_parse (ctx, argc, argv, &error))
|
||||
{
|
||||
@@ -390,7 +401,7 @@ static GSourceFuncs event_funcs = {
|
||||
static void
|
||||
meta_clutter_init (GOptionContext *ctx, int *argc, char ***argv)
|
||||
{
|
||||
clutter_x11_set_display (gdk_display);
|
||||
clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
||||
clutter_x11_disable_event_retrieval ();
|
||||
|
||||
if (CLUTTER_INIT_SUCCESS == clutter_init (argc, argv))
|
||||
@@ -436,37 +447,28 @@ meta_finalize (void)
|
||||
meta_session_shutdown ();
|
||||
}
|
||||
|
||||
static int sigterm_pipe_fds[2] = { -1, -1 };
|
||||
|
||||
static void
|
||||
sigterm_handler (int signum)
|
||||
{
|
||||
meta_finalize ();
|
||||
|
||||
exit (meta_exit_code);
|
||||
}
|
||||
|
||||
static guint sigchld_signal_id = 0;
|
||||
|
||||
static void
|
||||
sigchld_handler (int signum, siginfo_t *info, void *context)
|
||||
{
|
||||
int stat;
|
||||
|
||||
if (info->si_code == CLD_EXITED)
|
||||
if (sigterm_pipe_fds[1] >= 0)
|
||||
{
|
||||
g_signal_emit (sigchld_nexus, sigchld_signal_id, 0,
|
||||
info->si_status,
|
||||
GINT_TO_POINTER (info->si_pid));
|
||||
int dummy;
|
||||
|
||||
dummy = write (sigterm_pipe_fds[1], "", 1);
|
||||
close (sigterm_pipe_fds[1]);
|
||||
sigterm_pipe_fds[1] = -1;
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_matched (sigchld_nexus,
|
||||
G_SIGNAL_MATCH_DATA,
|
||||
sigchld_signal_id,
|
||||
0, NULL, NULL,
|
||||
GINT_TO_POINTER (info->si_pid));
|
||||
|
||||
waitpid (info->si_pid, &stat, WNOHANG);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
on_sigterm (void)
|
||||
{
|
||||
meta_quit (META_EXIT_SUCCESS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is where the story begins. It parses commandline options and
|
||||
* environment variables, sets up the screen, hands control off to
|
||||
@@ -489,8 +491,9 @@ main (int argc, char **argv)
|
||||
"Pango", "GLib-GObject", "GThread"
|
||||
};
|
||||
guint i;
|
||||
GIOChannel *channel;
|
||||
GOptionContext *ctx;
|
||||
|
||||
|
||||
if (!g_thread_supported ())
|
||||
g_thread_init (NULL);
|
||||
|
||||
@@ -512,29 +515,21 @@ main (int argc, char **argv)
|
||||
g_strerror (errno));
|
||||
#endif
|
||||
|
||||
if (pipe (sigterm_pipe_fds) != 0)
|
||||
g_printerr ("Failed to create SIGTERM pipe: %s\n",
|
||||
g_strerror (errno));
|
||||
|
||||
channel = g_io_channel_unix_new (sigterm_pipe_fds[0]);
|
||||
g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
|
||||
g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_sigterm, NULL);
|
||||
g_io_channel_set_close_on_unref (channel, TRUE);
|
||||
g_io_channel_unref (channel);
|
||||
|
||||
act.sa_handler = &sigterm_handler;
|
||||
if (sigaction (SIGTERM, &act, NULL) < 0)
|
||||
g_printerr ("Failed to register SIGTERM handler: %s\n",
|
||||
g_strerror (errno));
|
||||
|
||||
sigchld_nexus = g_object_new (META_TYPE_NEXUS, NULL);
|
||||
|
||||
sigchld_signal_id =
|
||||
g_signal_new ("sigchld", META_TYPE_NEXUS,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__UINT_POINTER,
|
||||
G_TYPE_NONE,
|
||||
2,
|
||||
G_TYPE_UINT, G_TYPE_POINTER);
|
||||
|
||||
act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
|
||||
act.sa_handler = SIG_DFL;
|
||||
act.sa_sigaction = &sigchld_handler;
|
||||
if (sigaction (SIGCHLD, &act, NULL) < 0)
|
||||
g_printerr ("Failed to register SIGCHLD handler: %s\n",
|
||||
g_strerror (errno));
|
||||
|
||||
if (g_getenv ("MUTTER_VERBOSE"))
|
||||
meta_set_verbose (TRUE);
|
||||
if (g_getenv ("MUTTER_DEBUG"))
|
||||
@@ -591,7 +586,7 @@ main (int argc, char **argv)
|
||||
* is initialized at this point, and we don't plan to run any real
|
||||
* plugin code.
|
||||
*/
|
||||
MutterPluginManager *mgr = mutter_plugin_manager_new (NULL);
|
||||
MutterPluginManager *mgr = mutter_plugin_manager_get_default ();
|
||||
if (!mutter_plugin_manager_load (mgr))
|
||||
g_critical ("failed to load plugins");
|
||||
}
|
||||
@@ -716,6 +711,9 @@ main (int argc, char **argv)
|
||||
if (meta_args.composite || meta_args.no_composite)
|
||||
meta_prefs_set_compositing_manager (meta_args.composite);
|
||||
|
||||
if (meta_args.no_force_fullscreen)
|
||||
meta_prefs_set_force_fullscreen (FALSE);
|
||||
|
||||
if (meta_args.no_tab_popup)
|
||||
{
|
||||
meta_prefs_override_no_tab_popup (TRUE);
|
||||
|
584
src/core/prefs.c
584
src/core/prefs.c
@@ -27,6 +27,7 @@
|
||||
#include "prefs.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "compositor/mutter-plugin-manager.h"
|
||||
#ifdef HAVE_GCONF
|
||||
#include <gconf/gconf-client.h>
|
||||
#endif
|
||||
@@ -52,6 +53,7 @@
|
||||
#define KEY_COMPOSITOR "/apps/metacity/general/compositing_manager"
|
||||
#define KEY_GNOME_ACCESSIBILITY "/desktop/gnome/interface/accessibility"
|
||||
|
||||
#define KEY_COMMAND_DIRECTORY "/apps/metacity/keybinding_commands"
|
||||
#define KEY_COMMAND_PREFIX "/apps/metacity/keybinding_commands/command_"
|
||||
|
||||
#define KEY_TERMINAL_DIR "/desktop/gnome/applications/terminal"
|
||||
@@ -62,6 +64,7 @@
|
||||
#define KEY_WINDOW_BINDINGS_PREFIX "/apps/metacity/window_keybindings"
|
||||
#define KEY_LIST_BINDINGS_SUFFIX "_list"
|
||||
|
||||
#define KEY_WORKSPACE_NAME_DIRECTORY "/apps/metacity/workspace_names"
|
||||
#define KEY_WORKSPACE_NAME_PREFIX "/apps/metacity/workspace_names/name_"
|
||||
|
||||
#define KEY_CLUTTER_PLUGINS "/apps/mutter/general/clutter_plugins"
|
||||
@@ -83,6 +86,7 @@ static MetaVirtualModifier mouse_button_mods = Mod1Mask;
|
||||
static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
|
||||
static MetaFocusNewWindows focus_new_windows = META_FOCUS_NEW_WINDOWS_SMART;
|
||||
static gboolean raise_on_click = TRUE;
|
||||
static gboolean attach_modal_dialogs = FALSE;
|
||||
static char* current_theme = NULL;
|
||||
static int num_workspaces = 4;
|
||||
static MetaActionTitlebar action_double_click_titlebar = META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE;
|
||||
@@ -100,6 +104,8 @@ static char *cursor_theme = NULL;
|
||||
static int cursor_size = 24;
|
||||
static gboolean compositing_manager = FALSE;
|
||||
static gboolean resize_with_right_button = FALSE;
|
||||
static gboolean side_by_side_tiling = FALSE;
|
||||
static gboolean force_fullscreen = TRUE;
|
||||
|
||||
static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH;
|
||||
static MetaButtonLayout button_layout;
|
||||
@@ -121,18 +127,30 @@ static gboolean no_tab_popup = FALSE;
|
||||
#ifdef HAVE_GCONF
|
||||
static gboolean handle_preference_update_enum (const gchar *key, GConfValue *value);
|
||||
|
||||
static gboolean update_key_binding (const char *name,
|
||||
static char *binding_name (const char *gconf_key);
|
||||
|
||||
static gboolean update_key_binding (const char *key,
|
||||
const char *value);
|
||||
static gboolean find_and_update_list_binding (MetaKeyPref *bindings,
|
||||
const char *name,
|
||||
GSList *value);
|
||||
static gboolean update_key_list_binding (const char *name,
|
||||
GSList *value);
|
||||
typedef enum
|
||||
{
|
||||
META_LIST_OF_STRINGS,
|
||||
META_LIST_OF_GCONFVALUE_STRINGS
|
||||
} MetaStringListType;
|
||||
|
||||
static gboolean find_and_update_list_binding (MetaKeyPref *bindings,
|
||||
const char *key,
|
||||
GSList *value,
|
||||
MetaStringListType type_of_value);
|
||||
static gboolean update_key_list_binding (const char *key,
|
||||
GSList *value,
|
||||
MetaStringListType type_of_value);
|
||||
static gboolean update_command (const char *name,
|
||||
const char *value);
|
||||
static gboolean update_workspace_name (const char *name,
|
||||
const char *value);
|
||||
|
||||
static void notify_new_value (const char *key,
|
||||
GConfValue *value);
|
||||
static void change_notify (GConfClient *client,
|
||||
guint cnxn_id,
|
||||
GConfEntry *entry,
|
||||
@@ -142,14 +160,8 @@ static char* gconf_key_for_workspace_name (int i);
|
||||
|
||||
static void queue_changed (MetaPreference pref);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_LIST_OF_STRINGS,
|
||||
META_LIST_OF_GCONFVALUE_STRINGS
|
||||
} MetaStringListType;
|
||||
|
||||
static gboolean update_list_binding (MetaKeyPref *binding,
|
||||
GSList *value,
|
||||
static gboolean update_list_binding (MetaKeyPref *binding,
|
||||
GSList *value,
|
||||
MetaStringListType type_of_value);
|
||||
|
||||
static void cleanup_error (GError **error);
|
||||
@@ -221,7 +233,12 @@ static GConfEnumStringPair symtab_titlebar_action[] =
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* Note that 'gchar *key' is the first element of all these structures;
|
||||
* we count on that below in key_is_used and do_override.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The details of one preference which is constrained to be
|
||||
* one of a small number of string values-- in other words,
|
||||
* an enumeration.
|
||||
@@ -234,21 +251,6 @@ static GConfEnumStringPair symtab_titlebar_action[] =
|
||||
* been outweighed by the bugs caused when the ordering of the enum
|
||||
* strings got out of sync with the actual enum statement. Also,
|
||||
* there is existing library code to use this kind of symbol tables.
|
||||
*
|
||||
* Other things we might consider doing to clean this up in the
|
||||
* future include:
|
||||
*
|
||||
* - most of the keys begin with the same prefix, and perhaps we
|
||||
* could assume it if they don't start with a slash
|
||||
*
|
||||
* - there are several cases where a single identifier could be used
|
||||
* to generate an entire entry, and perhaps this could be done
|
||||
* with a macro. (This would reduce clarity, however, and is
|
||||
* probably a bad thing.)
|
||||
*
|
||||
* - these types all begin with a gchar* (and contain a MetaPreference)
|
||||
* and we can factor out the repeated code in the handlers by taking
|
||||
* advantage of this using some kind of union arrangement.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
@@ -361,6 +363,11 @@ static MetaEnumPreference preferences_enum[] =
|
||||
|
||||
static MetaBoolPreference preferences_bool[] =
|
||||
{
|
||||
{ "/apps/mutter/general/attach_modal_dialogs",
|
||||
META_PREF_ATTACH_MODAL_DIALOGS,
|
||||
&attach_modal_dialogs,
|
||||
TRUE,
|
||||
},
|
||||
{ "/apps/metacity/general/raise_on_click",
|
||||
META_PREF_RAISE_ON_CLICK,
|
||||
&raise_on_click,
|
||||
@@ -416,6 +423,11 @@ static MetaBoolPreference preferences_bool[] =
|
||||
&resize_with_right_button,
|
||||
FALSE,
|
||||
},
|
||||
{ "/apps/metacity/general/side_by_side_tiling",
|
||||
META_PREF_SIDE_BY_SIDE_TILING,
|
||||
&side_by_side_tiling,
|
||||
FALSE,
|
||||
},
|
||||
{ "/apps/mutter/general/live_hidden_windows",
|
||||
META_PREF_LIVE_HIDDEN_WINDOWS,
|
||||
&live_hidden_windows,
|
||||
@@ -489,6 +501,20 @@ static MetaIntPreference preferences_int[] =
|
||||
{ NULL, 0, NULL, 0, 0, 0, },
|
||||
};
|
||||
|
||||
/*
|
||||
* This is used to keep track of preferences that have been
|
||||
* repointed to a different GConf key location; we modify the
|
||||
* preferences arrays directly, but we also need to remember
|
||||
* what we have done to handle subsequent overrides correctly.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
gchar *original_key;
|
||||
gchar *new_key;
|
||||
} MetaPrefsOverriddenKey;
|
||||
|
||||
static GSList *overridden_keys;
|
||||
|
||||
static void
|
||||
handle_preference_init_enum (void)
|
||||
{
|
||||
@@ -872,6 +898,10 @@ handle_preference_update_int (const gchar *key, GConfValue *value)
|
||||
/* Listeners. */
|
||||
/****************************************************************************/
|
||||
|
||||
/**
|
||||
* meta_prefs_add_listener: (skip)
|
||||
*
|
||||
*/
|
||||
void
|
||||
meta_prefs_add_listener (MetaPrefsChangedFunc func,
|
||||
gpointer data)
|
||||
@@ -885,6 +915,10 @@ meta_prefs_add_listener (MetaPrefsChangedFunc func,
|
||||
listeners = g_list_prepend (listeners, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_prefs_remove_listener: (skip)
|
||||
*
|
||||
*/
|
||||
void
|
||||
meta_prefs_remove_listener (MetaPrefsChangedFunc func,
|
||||
gpointer data)
|
||||
@@ -1024,6 +1058,7 @@ meta_prefs_init (void)
|
||||
#ifdef HAVE_GCONF
|
||||
GError *err = NULL;
|
||||
gchar **gconf_dir_cursor;
|
||||
MutterPluginManager *plugin_manager;
|
||||
|
||||
if (default_client != NULL)
|
||||
return;
|
||||
@@ -1042,12 +1077,7 @@ meta_prefs_init (void)
|
||||
cleanup_error (&err);
|
||||
}
|
||||
|
||||
/* Pick up initial values. */
|
||||
|
||||
handle_preference_init_enum ();
|
||||
handle_preference_init_bool ();
|
||||
handle_preference_init_string ();
|
||||
handle_preference_init_int ();
|
||||
/* The plugin list is special and needs to be handled first */
|
||||
|
||||
if (!clutter_plugins_overridden)
|
||||
clutter_plugins = gconf_client_get_list (default_client, KEY_CLUTTER_PLUGINS,
|
||||
@@ -1055,6 +1085,18 @@ meta_prefs_init (void)
|
||||
|
||||
cleanup_error (&err);
|
||||
|
||||
/* We now initialize plugins so that they can override any preference locations */
|
||||
|
||||
plugin_manager = mutter_plugin_manager_get_default ();
|
||||
mutter_plugin_manager_load (plugin_manager);
|
||||
|
||||
/* Pick up initial values. */
|
||||
|
||||
handle_preference_init_enum ();
|
||||
handle_preference_init_bool ();
|
||||
handle_preference_init_string ();
|
||||
handle_preference_init_int ();
|
||||
|
||||
/* @@@ Is there any reason we don't do the add_dir here? */
|
||||
for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
|
||||
*gconf_dir_cursor!=NULL;
|
||||
@@ -1087,6 +1129,160 @@ meta_prefs_init (void)
|
||||
init_workspace_names ();
|
||||
}
|
||||
|
||||
/* This count on the key being the first element of the
|
||||
* preference structure */
|
||||
static gboolean
|
||||
key_is_used (void *prefs,
|
||||
size_t pref_size,
|
||||
const char *new_key)
|
||||
{
|
||||
void *p = prefs;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
char **key = p;
|
||||
if (*key == NULL)
|
||||
break;
|
||||
|
||||
if (strcmp (*key, new_key) == 0)
|
||||
return TRUE;
|
||||
|
||||
p = (guchar *)p + pref_size;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_override (void *prefs,
|
||||
size_t pref_size,
|
||||
const char *search_key,
|
||||
char *new_key)
|
||||
{
|
||||
void *p = prefs;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
char **key = p;
|
||||
if (*key == NULL)
|
||||
break;
|
||||
|
||||
if (strcmp (*key, search_key) == 0)
|
||||
{
|
||||
*key = new_key;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
p = (guchar *)p + pref_size;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_prefs_override_preference_location
|
||||
* @original_key: the normal Metacity preference location
|
||||
* @new_key: the Metacity preference location to use instead.
|
||||
*
|
||||
* Substitute a different location to use instead of a standard Metacity
|
||||
* GConf key location. This might be used if a plugin expected a different
|
||||
* value for some preference than the Metacity default. While this function
|
||||
* can be called at any point, this function should generally be called
|
||||
* in a plugin's constructor, rather than in its start() method so the
|
||||
* preference isn't first loaded with one value then changed to another
|
||||
* value.
|
||||
*/
|
||||
void
|
||||
meta_prefs_override_preference_location (const char *original_key,
|
||||
const char *new_key)
|
||||
{
|
||||
const char *search_key;
|
||||
char *new_key_copy;
|
||||
gboolean found;
|
||||
MetaPrefsOverriddenKey *overridden;
|
||||
GSList *tmp;
|
||||
|
||||
/* Merge identical overrides, this isn't an error */
|
||||
for (tmp = overridden_keys; tmp; tmp = tmp->next)
|
||||
{
|
||||
MetaPrefsOverriddenKey *tmp_overridden = tmp->data;
|
||||
if (strcmp (tmp_overridden->original_key, original_key) == 0 &&
|
||||
strcmp (tmp_overridden->new_key, new_key) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* We depend on a unique mapping from GConf key to preference, so
|
||||
* enforce this */
|
||||
|
||||
if (key_is_used (preferences_enum, sizeof(MetaEnumPreference), new_key) ||
|
||||
key_is_used (preferences_bool, sizeof(MetaBoolPreference), new_key) ||
|
||||
key_is_used (preferences_string, sizeof(MetaStringPreference), new_key) ||
|
||||
key_is_used (preferences_int, sizeof(MetaIntPreference), new_key))
|
||||
{
|
||||
meta_warning (_("GConf key %s is already in use and can't be used to override %s\n"),
|
||||
new_key, original_key);
|
||||
|
||||
}
|
||||
|
||||
new_key_copy = g_strdup (new_key);
|
||||
|
||||
search_key = original_key;
|
||||
overridden = NULL;
|
||||
|
||||
for (tmp = overridden_keys; tmp; tmp = tmp->next)
|
||||
{
|
||||
MetaPrefsOverriddenKey *tmp_overridden = tmp->data;
|
||||
if (strcmp (overridden->original_key, original_key) == 0)
|
||||
{
|
||||
overridden = tmp_overridden;
|
||||
search_key = tmp_overridden->new_key;
|
||||
}
|
||||
}
|
||||
|
||||
found =
|
||||
do_override (preferences_enum, sizeof(MetaEnumPreference), search_key, new_key_copy) ||
|
||||
do_override (preferences_bool, sizeof(MetaBoolPreference), search_key, new_key_copy) ||
|
||||
do_override (preferences_string, sizeof(MetaStringPreference), search_key, new_key_copy) ||
|
||||
do_override (preferences_int, sizeof(MetaIntPreference), search_key, new_key_copy);
|
||||
if (found)
|
||||
{
|
||||
if (overridden)
|
||||
{
|
||||
g_free (overridden->new_key);
|
||||
overridden->new_key = new_key_copy;
|
||||
}
|
||||
else
|
||||
{
|
||||
overridden = g_slice_new (MetaPrefsOverriddenKey);
|
||||
overridden->original_key = g_strdup (original_key);
|
||||
overridden->new_key = new_key_copy;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GCONF
|
||||
if (default_client != NULL)
|
||||
{
|
||||
/* We're already initialized, so notify of a change */
|
||||
|
||||
GConfValue *value;
|
||||
GError *err = NULL;
|
||||
|
||||
value = gconf_client_get (default_client, new_key, &err);
|
||||
cleanup_error (&err);
|
||||
|
||||
notify_new_value (new_key, value);
|
||||
|
||||
if (value)
|
||||
gconf_value_free (value);
|
||||
}
|
||||
#endif /* HAVE_GCONF */
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_warning (_("Can't override GConf key, %s not found\n"), original_key);
|
||||
g_free (new_key_copy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Updates. */
|
||||
@@ -1102,6 +1298,23 @@ gboolean (*preference_update_handler[]) (const gchar*, GConfValue*) = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
notify_new_value (const char *key,
|
||||
GConfValue *value)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* FIXME: Use MetaGenericPreference and save a bit of code duplication */
|
||||
|
||||
while (preference_update_handler[i] != NULL)
|
||||
{
|
||||
if (preference_update_handler[i] (key, value))
|
||||
return;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
change_notify (GConfClient *client,
|
||||
guint cnxn_id,
|
||||
@@ -1110,25 +1323,13 @@ change_notify (GConfClient *client,
|
||||
{
|
||||
const char *key;
|
||||
GConfValue *value;
|
||||
gint i=0;
|
||||
|
||||
key = gconf_entry_get_key (entry);
|
||||
value = gconf_entry_get_value (entry);
|
||||
|
||||
/* First, search for a handler that might know what to do. */
|
||||
|
||||
/* FIXME: When this is all working, since the first item in every
|
||||
* array is the gchar* of the key, there's no reason we can't
|
||||
* find the correct record for that key here and save code duplication.
|
||||
*/
|
||||
|
||||
while (preference_update_handler[i]!=NULL)
|
||||
{
|
||||
if (preference_update_handler[i] (key, value))
|
||||
goto out; /* Get rid of this eventually */
|
||||
|
||||
i++;
|
||||
}
|
||||
notify_new_value (key, value);
|
||||
|
||||
if (g_str_has_prefix (key, KEY_WINDOW_BINDINGS_PREFIX) ||
|
||||
g_str_has_prefix (key, KEY_SCREEN_BINDINGS_PREFIX))
|
||||
@@ -1146,7 +1347,7 @@ change_notify (GConfClient *client,
|
||||
|
||||
list = value ? gconf_value_get_list (value) : NULL;
|
||||
|
||||
if (update_key_list_binding (key, list))
|
||||
if (update_key_list_binding (key, list, META_LIST_OF_GCONFVALUE_STRINGS))
|
||||
queue_changed (META_PREF_KEYBINDINGS);
|
||||
}
|
||||
else
|
||||
@@ -1304,6 +1505,12 @@ meta_prefs_get_focus_new_windows (void)
|
||||
return focus_new_windows;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_attach_modal_dialogs (void)
|
||||
{
|
||||
return attach_modal_dialogs;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_raise_on_click (void)
|
||||
{
|
||||
@@ -1725,6 +1932,9 @@ meta_preference_to_string (MetaPreference pref)
|
||||
case META_PREF_FOCUS_NEW_WINDOWS:
|
||||
return "FOCUS_NEW_WINDOWS";
|
||||
|
||||
case META_PREF_ATTACH_MODAL_DIALOGS:
|
||||
return "ATTACH_MODAL_DIALOGS";
|
||||
|
||||
case META_PREF_RAISE_ON_CLICK:
|
||||
return "RAISE_ON_CLICK";
|
||||
|
||||
@@ -1800,6 +2010,12 @@ meta_preference_to_string (MetaPreference pref)
|
||||
case META_PREF_RESIZE_WITH_RIGHT_BUTTON:
|
||||
return "RESIZE_WITH_RIGHT_BUTTON";
|
||||
|
||||
case META_PREF_SIDE_BY_SIDE_TILING:
|
||||
return "SIDE_BY_SIDE_TILING";
|
||||
|
||||
case META_PREF_FORCE_FULLSCREEN:
|
||||
return "FORCE_FULLSCREEN";
|
||||
|
||||
case META_PREF_CLUTTER_PLUGINS:
|
||||
return "CLUTTER_PLUGINS";
|
||||
|
||||
@@ -1888,57 +2104,64 @@ init_special_bindings (void)
|
||||
static void
|
||||
init_bindings (void)
|
||||
{
|
||||
#ifdef HAVE_GCONF
|
||||
int i = 0;
|
||||
GError *err;
|
||||
#ifdef HAVE_GCONF
|
||||
const char *prefix[] = {
|
||||
KEY_WINDOW_BINDINGS_PREFIX,
|
||||
KEY_SCREEN_BINDINGS_PREFIX,
|
||||
NULL
|
||||
};
|
||||
int i;
|
||||
GSList *list, *l, *list_val;
|
||||
const char *str_val;
|
||||
const char *key;
|
||||
GConfEntry *entry;
|
||||
GConfValue *value;
|
||||
GHashTable *to_update;
|
||||
|
||||
to_update = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
|
||||
for (i = 0; prefix[i]; i++)
|
||||
{
|
||||
list = gconf_client_all_entries (default_client, prefix[i], NULL);
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
entry = l->data;
|
||||
key = gconf_entry_get_key (entry);
|
||||
value = gconf_entry_get_value (entry);
|
||||
if (g_str_has_suffix (key, KEY_LIST_BINDINGS_SUFFIX))
|
||||
{
|
||||
/* List bindings are used in addition to the normal bindings and never
|
||||
* have defaults, so we just go ahead and set them immediately; there
|
||||
* will be only a few of them, so don't worry about the linear scan
|
||||
* in find_and_update_list_binding.
|
||||
*/
|
||||
list_val = gconf_client_get_list (default_client, key, GCONF_VALUE_STRING, NULL);
|
||||
|
||||
update_key_list_binding (key, list_val, META_LIST_OF_STRINGS);
|
||||
g_slist_foreach (list_val, (GFunc)g_free, NULL);
|
||||
g_slist_free (list_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_val = gconf_value_get_string (value);
|
||||
g_hash_table_insert (to_update, binding_name (key), g_strdup (str_val));
|
||||
}
|
||||
gconf_entry_free (entry);
|
||||
}
|
||||
g_slist_free (list);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (key_bindings[i].name)
|
||||
{
|
||||
GSList *list_val, *tmp;
|
||||
char *str_val;
|
||||
char *key;
|
||||
|
||||
key = g_strconcat (key_bindings[i].per_window?
|
||||
KEY_WINDOW_BINDINGS_PREFIX:
|
||||
KEY_SCREEN_BINDINGS_PREFIX,
|
||||
"/",
|
||||
key_bindings[i].name, NULL);
|
||||
|
||||
err = NULL;
|
||||
str_val = gconf_client_get_string (default_client, key, &err);
|
||||
cleanup_error (&err);
|
||||
|
||||
update_binding (&key_bindings[i], str_val);
|
||||
|
||||
g_free (str_val);
|
||||
g_free (key);
|
||||
|
||||
key = g_strconcat (key_bindings[i].per_window?
|
||||
KEY_WINDOW_BINDINGS_PREFIX:
|
||||
KEY_SCREEN_BINDINGS_PREFIX,
|
||||
"/",
|
||||
key_bindings[i].name,
|
||||
KEY_LIST_BINDINGS_SUFFIX, NULL);
|
||||
|
||||
err = NULL;
|
||||
|
||||
list_val = gconf_client_get_list (default_client, key, GCONF_VALUE_STRING, &err);
|
||||
cleanup_error (&err);
|
||||
|
||||
update_list_binding (&key_bindings[i], list_val, META_LIST_OF_STRINGS);
|
||||
|
||||
tmp = list_val;
|
||||
while (tmp)
|
||||
{
|
||||
g_free (tmp->data);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
g_slist_free (list_val);
|
||||
g_free (key);
|
||||
update_binding (&key_bindings[i],
|
||||
g_hash_table_lookup (to_update, key_bindings[i].name));
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
g_hash_table_destroy (to_update);
|
||||
|
||||
#else /* HAVE_GCONF */
|
||||
int i = 0;
|
||||
while (key_bindings[i].name)
|
||||
@@ -1960,28 +2183,23 @@ static void
|
||||
init_commands (void)
|
||||
{
|
||||
#ifdef HAVE_GCONF
|
||||
int i;
|
||||
GError *err;
|
||||
|
||||
i = 0;
|
||||
while (i < MAX_COMMANDS)
|
||||
GSList *list, *l;
|
||||
const char *str_val;
|
||||
const char *key;
|
||||
GConfEntry *entry;
|
||||
GConfValue *value;
|
||||
|
||||
list = gconf_client_all_entries (default_client, KEY_COMMAND_DIRECTORY, NULL);
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
char *str_val;
|
||||
char *key;
|
||||
|
||||
key = meta_prefs_get_gconf_key_for_command (i);
|
||||
|
||||
err = NULL;
|
||||
str_val = gconf_client_get_string (default_client, key, &err);
|
||||
cleanup_error (&err);
|
||||
|
||||
entry = l->data;
|
||||
key = gconf_entry_get_key (entry);
|
||||
value = gconf_entry_get_value (entry);
|
||||
str_val = gconf_value_get_string (value);
|
||||
update_command (key, str_val);
|
||||
|
||||
g_free (str_val);
|
||||
g_free (key);
|
||||
|
||||
++i;
|
||||
gconf_entry_free (entry);
|
||||
}
|
||||
g_slist_free (list);
|
||||
#else
|
||||
int i;
|
||||
for (i = 0; i < MAX_COMMANDS; i++)
|
||||
@@ -1992,39 +2210,34 @@ init_commands (void)
|
||||
static void
|
||||
init_workspace_names (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef HAVE_GCONF
|
||||
int i;
|
||||
GError *err;
|
||||
|
||||
i = 0;
|
||||
while (i < MAX_REASONABLE_WORKSPACES)
|
||||
GSList *list, *l;
|
||||
const char *str_val;
|
||||
const char *key;
|
||||
GConfEntry *entry;
|
||||
GConfValue *value;
|
||||
|
||||
list = gconf_client_all_entries (default_client, KEY_WORKSPACE_NAME_DIRECTORY, NULL);
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
char *str_val;
|
||||
char *key;
|
||||
|
||||
key = gconf_key_for_workspace_name (i);
|
||||
|
||||
err = NULL;
|
||||
str_val = gconf_client_get_string (default_client, key, &err);
|
||||
cleanup_error (&err);
|
||||
|
||||
entry = l->data;
|
||||
key = gconf_entry_get_key (entry);
|
||||
value = gconf_entry_get_value (entry);
|
||||
str_val = gconf_value_get_string (value);
|
||||
update_workspace_name (key, str_val);
|
||||
|
||||
g_assert (workspace_names[i] != NULL);
|
||||
|
||||
g_free (str_val);
|
||||
g_free (key);
|
||||
|
||||
++i;
|
||||
gconf_entry_free (entry);
|
||||
}
|
||||
#else
|
||||
int i;
|
||||
g_slist_free (list);
|
||||
#endif /* HAVE_GCONF */
|
||||
|
||||
for (i = 0; i < MAX_REASONABLE_WORKSPACES; i++)
|
||||
workspace_names[i] = g_strdup_printf (_("Workspace %d"), i + 1);
|
||||
if (workspace_names[i] == NULL)
|
||||
workspace_names[i] = g_strdup_printf (_("Workspace %d"), i + 1);
|
||||
|
||||
meta_topic (META_DEBUG_PREFS,
|
||||
"Initialized workspace names\n");
|
||||
#endif /* HAVE_GCONF */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2275,16 +2488,22 @@ update_list_binding (MetaKeyPref *binding,
|
||||
return changed;
|
||||
}
|
||||
|
||||
static const gchar*
|
||||
relative_key (const gchar* key)
|
||||
static char *
|
||||
binding_name (const char *gconf_key)
|
||||
{
|
||||
const gchar* end;
|
||||
|
||||
end = strrchr (key, '/');
|
||||
const char *start, *end;
|
||||
|
||||
++end;
|
||||
if (*gconf_key == '/')
|
||||
start = strrchr (gconf_key, '/') + 1;
|
||||
else
|
||||
start = gconf_key;
|
||||
|
||||
return end;
|
||||
if (g_str_has_suffix (gconf_key, KEY_LIST_BINDINGS_SUFFIX))
|
||||
end = gconf_key + strlen(gconf_key) - strlen (KEY_LIST_BINDINGS_SUFFIX);
|
||||
else
|
||||
end = gconf_key + strlen(gconf_key);
|
||||
|
||||
return g_strndup (start, end - start);
|
||||
}
|
||||
|
||||
/* Return value is TRUE if a preference changed and we need to
|
||||
@@ -2292,22 +2511,19 @@ relative_key (const gchar* key)
|
||||
*/
|
||||
static gboolean
|
||||
find_and_update_binding (MetaKeyPref *bindings,
|
||||
const char *name,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
const char *key;
|
||||
char *name = binding_name (key);
|
||||
int i;
|
||||
|
||||
if (*name == '/')
|
||||
key = relative_key (name);
|
||||
else
|
||||
key = name;
|
||||
|
||||
i = 0;
|
||||
while (bindings[i].name &&
|
||||
strcmp (key, bindings[i].name) != 0)
|
||||
strcmp (name, bindings[i].name) != 0)
|
||||
++i;
|
||||
|
||||
g_free (name);
|
||||
|
||||
if (bindings[i].name)
|
||||
return update_binding (&bindings[i], value);
|
||||
else
|
||||
@@ -2315,46 +2531,40 @@ find_and_update_binding (MetaKeyPref *bindings,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_key_binding (const char *name,
|
||||
const char *value)
|
||||
update_key_binding (const char *key,
|
||||
const char *value)
|
||||
{
|
||||
return find_and_update_binding (key_bindings, name, value);
|
||||
return find_and_update_binding (key_bindings, key, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_and_update_list_binding (MetaKeyPref *bindings,
|
||||
const char *name,
|
||||
GSList *value)
|
||||
find_and_update_list_binding (MetaKeyPref *bindings,
|
||||
const char *key,
|
||||
GSList *value,
|
||||
MetaStringListType type_of_value)
|
||||
{
|
||||
const char *key;
|
||||
char *name = binding_name (key);
|
||||
int i;
|
||||
gchar *name_without_suffix = g_strdup(name);
|
||||
|
||||
name_without_suffix[strlen(name_without_suffix) - strlen(KEY_LIST_BINDINGS_SUFFIX)] = 0;
|
||||
|
||||
if (*name_without_suffix == '/')
|
||||
key = relative_key (name_without_suffix);
|
||||
else
|
||||
key = name_without_suffix;
|
||||
|
||||
i = 0;
|
||||
while (bindings[i].name &&
|
||||
strcmp (key, bindings[i].name) != 0)
|
||||
strcmp (name, bindings[i].name) != 0)
|
||||
++i;
|
||||
|
||||
g_free (name_without_suffix);
|
||||
g_free (name);
|
||||
|
||||
if (bindings[i].name)
|
||||
return update_list_binding (&bindings[i], value, META_LIST_OF_GCONFVALUE_STRINGS);
|
||||
return update_list_binding (&bindings[i], value, type_of_value);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_key_list_binding (const char *name,
|
||||
GSList *value)
|
||||
update_key_list_binding (const char *key,
|
||||
GSList *value,
|
||||
MetaStringListType type_of_value)
|
||||
{
|
||||
return find_and_update_list_binding (key_bindings, name, value);
|
||||
return find_and_update_list_binding (key_bindings, key, value, type_of_value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2713,6 +2923,12 @@ meta_prefs_get_gnome_animations ()
|
||||
return gnome_animations;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_side_by_side_tiling ()
|
||||
{
|
||||
return side_by_side_tiling;
|
||||
}
|
||||
|
||||
MetaKeyBindingAction
|
||||
meta_prefs_get_keybinding_action (const char *name)
|
||||
{
|
||||
@@ -2792,6 +3008,12 @@ meta_prefs_get_mouse_button_menu (void)
|
||||
return resize_with_right_button ? 2: 3;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_force_fullscreen (void)
|
||||
{
|
||||
return force_fullscreen;
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_set_compositing_manager (gboolean whether)
|
||||
{
|
||||
@@ -2814,6 +3036,11 @@ meta_prefs_set_compositing_manager (gboolean whether)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_prefs_get_clutter_plugins:
|
||||
*
|
||||
* Returns: (transfer none) (element-type utf8): Plugin names to load
|
||||
*/
|
||||
GSList *
|
||||
meta_prefs_get_clutter_plugins (void)
|
||||
{
|
||||
@@ -2823,6 +3050,7 @@ meta_prefs_get_clutter_plugins (void)
|
||||
void
|
||||
meta_prefs_set_clutter_plugins (GSList *list)
|
||||
{
|
||||
#ifdef HAVE_GCONF
|
||||
GError *err = NULL;
|
||||
|
||||
gconf_client_set_list (default_client,
|
||||
@@ -2837,6 +3065,7 @@ meta_prefs_set_clutter_plugins (GSList *list)
|
||||
err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2957,3 +3186,10 @@ init_button_layout(void)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_prefs_set_force_fullscreen (gboolean whether)
|
||||
{
|
||||
force_fullscreen = whether;
|
||||
}
|
||||
|
||||
|
@@ -37,7 +37,6 @@
|
||||
#include "screen.h"
|
||||
#include <X11/Xutil.h>
|
||||
#include "stack-tracker.h"
|
||||
#include "alttabhandler.h"
|
||||
#include "ui.h"
|
||||
|
||||
typedef struct _MetaMonitorInfo MetaMonitorInfo;
|
||||
@@ -82,9 +81,11 @@ struct _MetaScreen
|
||||
Visual *default_xvisual;
|
||||
MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */
|
||||
MetaUI *ui;
|
||||
MetaAltTabHandler *tab_handler;
|
||||
MetaTabPopup *ws_popup;
|
||||
|
||||
MetaTabPopup *tab_popup, *ws_popup;
|
||||
MetaTilePreview *tile_preview;
|
||||
|
||||
guint tile_preview_timeout_id;
|
||||
|
||||
MetaWorkspace *active_workspace;
|
||||
|
||||
/* This window holds the focus when we don't want to focus
|
||||
@@ -118,8 +119,9 @@ struct _MetaScreen
|
||||
#endif
|
||||
|
||||
Window wm_cm_selection_window;
|
||||
guint32 wm_cm_timestamp;
|
||||
|
||||
guint work_area_idle;
|
||||
guint work_area_later;
|
||||
|
||||
int rows_of_workspaces;
|
||||
int columns_of_workspaces;
|
||||
@@ -131,9 +133,6 @@ struct _MetaScreen
|
||||
|
||||
int closing;
|
||||
|
||||
/* gc for XOR on root window */
|
||||
GC root_xor_gc;
|
||||
|
||||
/* Managed by compositor.c */
|
||||
gpointer compositor_data;
|
||||
|
||||
@@ -147,7 +146,8 @@ struct _MetaScreenClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*restacked) (MetaScreen *);
|
||||
void (*restacked) (MetaScreen *);
|
||||
void (*workareas_changed) (MetaScreen *);
|
||||
};
|
||||
|
||||
MetaScreen* meta_screen_new (MetaDisplay *display,
|
||||
@@ -182,6 +182,9 @@ void meta_screen_workspace_popup_select (MetaScreen *screen,
|
||||
MetaWorkspace*meta_screen_workspace_popup_get_selected (MetaScreen *screen);
|
||||
void meta_screen_workspace_popup_destroy (MetaScreen *screen);
|
||||
|
||||
void meta_screen_tile_preview_update (MetaScreen *screen,
|
||||
gboolean delay);
|
||||
|
||||
MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen,
|
||||
MetaWindow *not_this_one);
|
||||
|
||||
|
@@ -38,7 +38,6 @@
|
||||
#include "stack.h"
|
||||
#include "xprops.h"
|
||||
#include "compositor.h"
|
||||
#include "alttabhandlerdefault.h"
|
||||
#include "mutter-marshal.h"
|
||||
#include "mutter-enum-types.h"
|
||||
|
||||
@@ -86,6 +85,7 @@ enum
|
||||
WORKSPACE_REMOVED,
|
||||
WORKSPACE_SWITCHED,
|
||||
STARTUP_SEQUENCE_CHANGED,
|
||||
WORKAREAS_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@@ -218,6 +218,15 @@ meta_screen_class_init (MetaScreenClass *klass)
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
screen_signals[WORKAREAS_CHANGED] =
|
||||
g_signal_new ("workareas-changed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MetaScreenClass, workareas_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_N_WORKSPACES,
|
||||
pspec);
|
||||
@@ -255,6 +264,13 @@ set_wm_check_hint (MetaScreen *screen)
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
unset_wm_check_hint (MetaScreen *screen)
|
||||
{
|
||||
XDeleteProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom__NET_SUPPORTING_WM_CHECK);
|
||||
}
|
||||
|
||||
static int
|
||||
set_supported_hint (MetaScreen *screen)
|
||||
{
|
||||
@@ -687,7 +703,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
|
||||
xroot,
|
||||
NoEventMask);
|
||||
screen->work_area_idle = 0;
|
||||
screen->work_area_later = 0;
|
||||
|
||||
screen->active_workspace = NULL;
|
||||
screen->workspaces = NULL;
|
||||
@@ -698,35 +714,6 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->compositor_data = NULL;
|
||||
screen->guard_window = None;
|
||||
|
||||
{
|
||||
XFontStruct *font_info;
|
||||
XGCValues gc_values;
|
||||
gulong value_mask = 0;
|
||||
|
||||
gc_values.subwindow_mode = IncludeInferiors;
|
||||
value_mask |= GCSubwindowMode;
|
||||
gc_values.function = GXinvert;
|
||||
value_mask |= GCFunction;
|
||||
gc_values.line_width = META_WIREFRAME_XOR_LINE_WIDTH;
|
||||
value_mask |= GCLineWidth;
|
||||
|
||||
font_info = XLoadQueryFont (screen->display->xdisplay, "fixed");
|
||||
|
||||
if (font_info != NULL)
|
||||
{
|
||||
gc_values.font = font_info->fid;
|
||||
value_mask |= GCFont;
|
||||
XFreeFontInfo (NULL, font_info, 1);
|
||||
}
|
||||
else
|
||||
meta_warning ("xserver doesn't have 'fixed' font.\n");
|
||||
|
||||
screen->root_xor_gc = XCreateGC (screen->display->xdisplay,
|
||||
screen->xroot,
|
||||
value_mask,
|
||||
&gc_values);
|
||||
}
|
||||
|
||||
screen->monitor_infos = NULL;
|
||||
screen->n_monitor_infos = 0;
|
||||
screen->last_monitor_index = 0;
|
||||
@@ -781,9 +768,12 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->ui = meta_ui_new (screen->display->xdisplay,
|
||||
screen->xscreen);
|
||||
|
||||
screen->tab_handler = NULL;
|
||||
screen->tab_popup = NULL;
|
||||
screen->ws_popup = NULL;
|
||||
|
||||
screen->tile_preview = NULL;
|
||||
|
||||
screen->tile_preview_timeout_id = 0;
|
||||
|
||||
screen->stack = meta_stack_new (screen);
|
||||
screen->stack_tracker = meta_stack_tracker_new (screen);
|
||||
|
||||
@@ -822,7 +812,6 @@ meta_screen_free (MetaScreen *screen,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
XGCValues gc_values = { 0 };
|
||||
|
||||
display = screen->display;
|
||||
|
||||
@@ -871,27 +860,22 @@ meta_screen_free (MetaScreen *screen,
|
||||
meta_warning (_("Could not release screen %d on display \"%s\"\n"),
|
||||
screen->number, screen->display->name);
|
||||
|
||||
unset_wm_check_hint (screen);
|
||||
|
||||
XDestroyWindow (screen->display->xdisplay,
|
||||
screen->wm_sn_selection_window);
|
||||
|
||||
if (screen->work_area_idle != 0)
|
||||
g_source_remove (screen->work_area_idle);
|
||||
if (screen->work_area_later != 0)
|
||||
g_source_remove (screen->work_area_later);
|
||||
|
||||
|
||||
if (XGetGCValues (screen->display->xdisplay,
|
||||
screen->root_xor_gc,
|
||||
GCFont,
|
||||
&gc_values))
|
||||
{
|
||||
XUnloadFont (screen->display->xdisplay,
|
||||
gc_values.font);
|
||||
}
|
||||
|
||||
XFreeGC (screen->display->xdisplay,
|
||||
screen->root_xor_gc);
|
||||
|
||||
if (screen->monitor_infos)
|
||||
g_free (screen->monitor_infos);
|
||||
|
||||
if (screen->tile_preview_timeout_id)
|
||||
g_source_remove (screen->tile_preview_timeout_id);
|
||||
|
||||
if (screen->tile_preview)
|
||||
meta_tile_preview_free (screen->tile_preview);
|
||||
|
||||
g_free (screen->screen_name);
|
||||
|
||||
@@ -1291,7 +1275,8 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
|
||||
GList *l;
|
||||
MetaWorkspace *neighbour = NULL;
|
||||
GList *next = NULL;
|
||||
int index;
|
||||
int index;
|
||||
int new_num;
|
||||
|
||||
l = screen->workspaces;
|
||||
while (l)
|
||||
@@ -1333,7 +1318,10 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
|
||||
/* This also removes the workspace from the screens list */
|
||||
meta_workspace_remove (workspace);
|
||||
|
||||
set_number_of_spaces_hint (screen, g_list_length (screen->workspaces));
|
||||
new_num = g_list_length (screen->workspaces);
|
||||
|
||||
set_number_of_spaces_hint (screen, new_num);
|
||||
meta_prefs_set_num_workspaces (new_num);
|
||||
|
||||
l = next;
|
||||
while (l)
|
||||
@@ -1369,6 +1357,7 @@ meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWorkspace *w;
|
||||
int new_num;
|
||||
|
||||
/* This also adds the workspace to the screen list */
|
||||
w = meta_workspace_new (screen);
|
||||
@@ -1379,7 +1368,10 @@ meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate,
|
||||
if (activate)
|
||||
meta_workspace_activate (w, timestamp);
|
||||
|
||||
set_number_of_spaces_hint (screen, g_list_length (screen->workspaces));
|
||||
new_num = g_list_length (screen->workspaces);
|
||||
|
||||
set_number_of_spaces_hint (screen, new_num);
|
||||
meta_prefs_set_num_workspaces (new_num);
|
||||
|
||||
meta_screen_queue_workarea_recalc (screen);
|
||||
|
||||
@@ -1406,6 +1398,9 @@ update_num_workspaces (MetaScreen *screen,
|
||||
|
||||
g_assert (new_num > 0);
|
||||
|
||||
if (g_list_length (screen->workspaces) == (guint) new_num)
|
||||
return;
|
||||
|
||||
last_remaining = NULL;
|
||||
extras = NULL;
|
||||
i = 0;
|
||||
@@ -1516,58 +1511,146 @@ meta_screen_tab_popup_create (MetaScreen *screen,
|
||||
MetaTabShowType show_type,
|
||||
MetaWindow *initial_selection)
|
||||
{
|
||||
MetaTabEntry *entries;
|
||||
GList *tab_list;
|
||||
GList *tmp;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
g_return_if_fail (screen->tab_handler == NULL);
|
||||
|
||||
screen->tab_handler = meta_alt_tab_handler_new (screen,
|
||||
show_type == META_TAB_SHOW_INSTANTLY);
|
||||
if (screen->tab_popup)
|
||||
return;
|
||||
|
||||
tab_list = meta_display_get_tab_list (screen->display,
|
||||
list_type,
|
||||
screen,
|
||||
screen->active_workspace);
|
||||
|
||||
for (tmp = tab_list; tmp; tmp = tmp->next)
|
||||
meta_alt_tab_handler_add_window (screen->tab_handler, tmp->data);
|
||||
|
||||
meta_alt_tab_handler_show (screen->tab_handler, initial_selection);
|
||||
|
||||
len = g_list_length (tab_list);
|
||||
|
||||
entries = g_new (MetaTabEntry, len + 1);
|
||||
entries[len].key = NULL;
|
||||
entries[len].title = NULL;
|
||||
entries[len].icon = NULL;
|
||||
|
||||
i = 0;
|
||||
tmp = tab_list;
|
||||
while (i < len)
|
||||
{
|
||||
MetaWindow *window;
|
||||
MetaRectangle r;
|
||||
|
||||
window = tmp->data;
|
||||
|
||||
entries[i].key = (MetaTabEntryKey) window;
|
||||
entries[i].title = window->title;
|
||||
entries[i].icon = g_object_ref (window->icon);
|
||||
entries[i].blank = FALSE;
|
||||
entries[i].hidden = !meta_window_showing_on_its_workspace (window);
|
||||
entries[i].demands_attention = window->wm_state_demands_attention;
|
||||
|
||||
if (show_type == META_TAB_SHOW_INSTANTLY ||
|
||||
!entries[i].hidden ||
|
||||
!meta_window_get_icon_geometry (window, &r))
|
||||
meta_window_get_outer_rect (window, &r);
|
||||
|
||||
entries[i].rect = r;
|
||||
|
||||
/* Find inside of highlight rectangle to be used when window is
|
||||
* outlined for tabbing. This should be the size of the
|
||||
* east/west frame, and the size of the south frame, on those
|
||||
* sides. On the top it should be the size of the south frame
|
||||
* edge.
|
||||
*/
|
||||
#define OUTLINE_WIDTH 5
|
||||
/* Top side */
|
||||
if (!entries[i].hidden &&
|
||||
window->frame && window->frame->bottom_height > 0 &&
|
||||
window->frame->child_y >= window->frame->bottom_height)
|
||||
entries[i].inner_rect.y = window->frame->bottom_height;
|
||||
else
|
||||
entries[i].inner_rect.y = OUTLINE_WIDTH;
|
||||
|
||||
/* Bottom side */
|
||||
if (!entries[i].hidden &&
|
||||
window->frame && window->frame->bottom_height != 0)
|
||||
entries[i].inner_rect.height = r.height
|
||||
- entries[i].inner_rect.y - window->frame->bottom_height;
|
||||
else
|
||||
entries[i].inner_rect.height = r.height
|
||||
- entries[i].inner_rect.y - OUTLINE_WIDTH;
|
||||
|
||||
/* Left side */
|
||||
if (!entries[i].hidden && window->frame && window->frame->child_x != 0)
|
||||
entries[i].inner_rect.x = window->frame->child_x;
|
||||
else
|
||||
entries[i].inner_rect.x = OUTLINE_WIDTH;
|
||||
|
||||
/* Right side */
|
||||
if (!entries[i].hidden &&
|
||||
window->frame && window->frame->right_width != 0)
|
||||
entries[i].inner_rect.width = r.width
|
||||
- entries[i].inner_rect.x - window->frame->right_width;
|
||||
else
|
||||
entries[i].inner_rect.width = r.width
|
||||
- entries[i].inner_rect.x - OUTLINE_WIDTH;
|
||||
|
||||
++i;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if (!meta_prefs_get_no_tab_popup ())
|
||||
screen->tab_popup = meta_ui_tab_popup_new (entries,
|
||||
screen->number,
|
||||
len,
|
||||
5, /* FIXME */
|
||||
TRUE);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
g_object_unref (entries[i].icon);
|
||||
|
||||
g_free (entries);
|
||||
|
||||
g_list_free (tab_list);
|
||||
|
||||
meta_ui_tab_popup_select (screen->tab_popup,
|
||||
(MetaTabEntryKey) initial_selection);
|
||||
|
||||
if (show_type != META_TAB_SHOW_INSTANTLY)
|
||||
meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_tab_popup_forward (MetaScreen *screen)
|
||||
{
|
||||
g_return_if_fail (screen->tab_handler != NULL);
|
||||
g_return_if_fail (screen->tab_popup != NULL);
|
||||
|
||||
meta_alt_tab_handler_forward (screen->tab_handler);
|
||||
meta_ui_tab_popup_forward (screen->tab_popup);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_tab_popup_backward (MetaScreen *screen)
|
||||
{
|
||||
g_return_if_fail (screen->tab_handler != NULL);
|
||||
g_return_if_fail (screen->tab_popup != NULL);
|
||||
|
||||
meta_alt_tab_handler_backward (screen->tab_handler);
|
||||
meta_ui_tab_popup_backward (screen->tab_popup);
|
||||
}
|
||||
|
||||
MetaWindow *
|
||||
meta_screen_tab_popup_get_selected (MetaScreen *screen)
|
||||
{
|
||||
g_return_val_if_fail (screen->tab_handler != NULL, NULL);
|
||||
g_return_val_if_fail (screen->tab_popup != NULL, NULL);
|
||||
|
||||
return meta_alt_tab_handler_get_selected (screen->tab_handler);
|
||||
return (MetaWindow *) meta_ui_tab_popup_get_selected (screen->tab_popup);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_tab_popup_destroy (MetaScreen *screen)
|
||||
{
|
||||
if (!screen->tab_handler)
|
||||
return;
|
||||
|
||||
meta_alt_tab_handler_destroy (screen->tab_handler);
|
||||
g_object_unref (screen->tab_handler);
|
||||
screen->tab_handler = NULL;
|
||||
if (screen->tab_popup)
|
||||
{
|
||||
meta_ui_tab_popup_free (screen->tab_popup);
|
||||
screen->tab_popup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1580,8 +1663,9 @@ meta_screen_workspace_popup_create (MetaScreen *screen,
|
||||
MetaWorkspaceLayout layout;
|
||||
int n_workspaces;
|
||||
int current_workspace;
|
||||
|
||||
g_return_if_fail (screen->ws_popup == NULL);
|
||||
|
||||
if (screen->ws_popup || meta_prefs_get_no_tab_popup ())
|
||||
return;
|
||||
|
||||
current_workspace = meta_workspace_index (screen->active_workspace);
|
||||
n_workspaces = meta_screen_get_n_workspaces (screen);
|
||||
@@ -1668,6 +1752,69 @@ meta_screen_workspace_popup_destroy (MetaScreen *screen)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_tile_preview_update_timeout (gpointer data)
|
||||
{
|
||||
MetaScreen *screen = data;
|
||||
MetaWindow *window = screen->display->grab_window;
|
||||
gboolean composited = screen->display->compositor != NULL;
|
||||
|
||||
screen->tile_preview_timeout_id = 0;
|
||||
|
||||
if (!screen->tile_preview)
|
||||
{
|
||||
Window xwindow;
|
||||
gulong create_serial;
|
||||
|
||||
screen->tile_preview = meta_tile_preview_new (screen->number,
|
||||
composited);
|
||||
xwindow = meta_tile_preview_get_xwindow (screen->tile_preview,
|
||||
&create_serial);
|
||||
meta_stack_tracker_record_add (screen->stack_tracker,
|
||||
xwindow,
|
||||
create_serial);
|
||||
}
|
||||
|
||||
if (window
|
||||
&& !META_WINDOW_TILED (window)
|
||||
&& window->tile_mode != META_TILE_NONE)
|
||||
{
|
||||
MetaRectangle tile_rect;
|
||||
|
||||
meta_window_get_current_tile_area (window, &tile_rect);
|
||||
meta_tile_preview_show (screen->tile_preview, &tile_rect);
|
||||
}
|
||||
else
|
||||
meta_tile_preview_hide (screen->tile_preview);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define TILE_PREVIEW_TIMEOUT_MS 200
|
||||
|
||||
void
|
||||
meta_screen_tile_preview_update (MetaScreen *screen,
|
||||
gboolean delay)
|
||||
{
|
||||
if (delay)
|
||||
{
|
||||
if (screen->tile_preview_timeout_id > 0)
|
||||
return;
|
||||
|
||||
screen->tile_preview_timeout_id =
|
||||
g_timeout_add (TILE_PREVIEW_TIMEOUT_MS,
|
||||
meta_screen_tile_preview_update_timeout,
|
||||
screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (screen->tile_preview_timeout_id > 0)
|
||||
g_source_remove (screen->tile_preview_timeout_id);
|
||||
|
||||
meta_screen_tile_preview_update_timeout ((gpointer)screen);
|
||||
}
|
||||
}
|
||||
|
||||
MetaWindow*
|
||||
meta_screen_get_mouse_window (MetaScreen *screen,
|
||||
MetaWindow *not_this_one)
|
||||
@@ -2200,15 +2347,17 @@ set_work_area_hint (MetaScreen *screen)
|
||||
(guchar*) data, num_workspaces*4);
|
||||
g_free (data);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
|
||||
g_signal_emit (screen, screen_signals[WORKAREAS_CHANGED], 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_work_area_idle_func (MetaScreen *screen)
|
||||
set_work_area_later_func (MetaScreen *screen)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Running work area idle function\n");
|
||||
"Running work area hint computation function\n");
|
||||
|
||||
screen->work_area_idle = 0;
|
||||
screen->work_area_later = 0;
|
||||
|
||||
set_work_area_hint (screen);
|
||||
|
||||
@@ -2218,16 +2367,16 @@ set_work_area_idle_func (MetaScreen *screen)
|
||||
void
|
||||
meta_screen_queue_workarea_recalc (MetaScreen *screen)
|
||||
{
|
||||
/* Recompute work area in an idle */
|
||||
if (screen->work_area_idle == 0)
|
||||
/* Recompute work area later before redrawing */
|
||||
if (screen->work_area_later == 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_WORKAREA,
|
||||
"Adding work area hint idle function\n");
|
||||
screen->work_area_idle =
|
||||
g_idle_add_full (META_PRIORITY_BEFORE_REDRAW,
|
||||
(GSourceFunc) set_work_area_idle_func,
|
||||
screen,
|
||||
NULL);
|
||||
"Adding work area hint computation function\n");
|
||||
screen->work_area_later =
|
||||
meta_later_add (META_LATER_BEFORE_REDRAW,
|
||||
(GSourceFunc) set_work_area_later_func,
|
||||
screen,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3045,6 +3194,10 @@ meta_screen_get_display (MetaScreen *screen)
|
||||
return screen->display;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_screen_get_xroot: (skip)
|
||||
*
|
||||
*/
|
||||
Window
|
||||
meta_screen_get_xroot (MetaScreen *screen)
|
||||
{
|
||||
@@ -3060,6 +3213,10 @@ meta_screen_get_size (MetaScreen *screen,
|
||||
*height = screen->rect.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_screen_get_compositor_data: (skip)
|
||||
*
|
||||
*/
|
||||
gpointer
|
||||
meta_screen_get_compositor_data (MetaScreen *screen)
|
||||
{
|
||||
@@ -3079,11 +3236,14 @@ meta_screen_set_cm_selection (MetaScreen *screen)
|
||||
char selection[32];
|
||||
Atom a;
|
||||
|
||||
screen->wm_cm_timestamp = meta_display_get_current_time_roundtrip (
|
||||
screen->display);
|
||||
|
||||
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
|
||||
meta_verbose ("Setting selection: %s\n", selection);
|
||||
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
|
||||
XSetSelectionOwner (screen->display->xdisplay, a,
|
||||
screen->wm_cm_selection_window, CurrentTime);
|
||||
screen->wm_cm_selection_window, screen->wm_cm_timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3094,9 +3254,16 @@ meta_screen_unset_cm_selection (MetaScreen *screen)
|
||||
|
||||
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
|
||||
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
|
||||
XSetSelectionOwner (screen->display->xdisplay, a, None, CurrentTime);
|
||||
XSetSelectionOwner (screen->display->xdisplay, a,
|
||||
None, screen->wm_cm_timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_screen_get_workspaces: (skip)
|
||||
* @screen: a #MetaScreen
|
||||
*
|
||||
* Returns: (transfer none) (element-type Meta.Workspace): The workspaces for @screen
|
||||
*/
|
||||
GList *
|
||||
meta_screen_get_workspaces (MetaScreen *screen)
|
||||
{
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#ifndef HAVE_SM
|
||||
void
|
||||
@@ -83,6 +84,7 @@ static char* load_state (const char *previous_save_file);
|
||||
static void regenerate_save_file (void);
|
||||
static const char* full_save_file (void);
|
||||
static void warn_about_lame_clients_and_finish_interact (gboolean shutdown);
|
||||
static void disconnect (void);
|
||||
|
||||
/* This is called when data is available on an ICE connection. */
|
||||
static gboolean
|
||||
@@ -105,9 +107,12 @@ process_ice_messages (GIOChannel *channel,
|
||||
IcePointer context = IceGetConnectionContext (connection);
|
||||
#endif
|
||||
|
||||
/* We were disconnected */
|
||||
IceSetShutdownNegotiation (connection, False);
|
||||
IceCloseConnection (connection);
|
||||
/* We were disconnected; close our connection to the
|
||||
* session manager, this will result in the ICE connection
|
||||
* being cleaned up, since it is owned by libSM.
|
||||
*/
|
||||
disconnect ();
|
||||
meta_quit (META_EXIT_SUCCESS);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1104,8 +1109,6 @@ load_state (const char *previous_save_file)
|
||||
{
|
||||
/* oh, just give up */
|
||||
|
||||
meta_warning (_("Failed to read saved session file %s: %s\n"),
|
||||
canonical_session_file, error->message);
|
||||
g_error_free (error);
|
||||
g_free (session_file);
|
||||
g_free (canonical_session_file);
|
||||
@@ -1749,11 +1752,11 @@ finish_interact (gboolean shutdown)
|
||||
}
|
||||
|
||||
static void
|
||||
sigchld_handler (MetaNexus *nexus, guint arg1, gpointer arg2, gpointer user_data)
|
||||
dialog_closed (GPid pid, int status, gpointer user_data)
|
||||
{
|
||||
gboolean shutdown = GPOINTER_TO_INT (user_data);
|
||||
|
||||
if (arg1 == 0) /* pressed "OK" */
|
||||
if (WIFEXITED (status) && WEXITSTATUS (status) == 0) /* pressed "OK" */
|
||||
{
|
||||
finish_interact (shutdown);
|
||||
}
|
||||
@@ -1767,6 +1770,7 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
|
||||
GSList *lame_details = NULL;
|
||||
GSList *tmp;
|
||||
GSList *columns = NULL;
|
||||
GPid pid;
|
||||
|
||||
windows = meta_display_list_windows (meta_get_display (), META_LIST_DEFAULT);
|
||||
tmp = windows;
|
||||
@@ -1814,23 +1818,20 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
|
||||
}
|
||||
g_slist_free (lame);
|
||||
|
||||
meta_show_dialog("--list",
|
||||
_("These windows do not support "save current setup" "
|
||||
"and will have to be restarted manually next time "
|
||||
"you log in."),
|
||||
"240",
|
||||
meta_screen_get_screen_number (meta_get_display()->active_screen),
|
||||
NULL, NULL,
|
||||
None,
|
||||
columns,
|
||||
lame_details);
|
||||
pid = meta_show_dialog("--list",
|
||||
_("These windows do not support "save current setup" "
|
||||
"and will have to be restarted manually next time "
|
||||
"you log in."),
|
||||
"240",
|
||||
meta_screen_get_screen_number (meta_get_display()->active_screen),
|
||||
NULL, NULL,
|
||||
None,
|
||||
columns,
|
||||
lame_details);
|
||||
|
||||
g_slist_free (lame_details);
|
||||
|
||||
g_signal_connect (sigchld_nexus, "sigchld",
|
||||
G_CALLBACK (sigchld_handler),
|
||||
GINT_TO_POINTER (shutdown));
|
||||
|
||||
g_child_watch_add (pid, dialog_closed, GINT_TO_POINTER (shutdown));
|
||||
}
|
||||
|
||||
#endif /* HAVE_SM */
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "frame-private.h"
|
||||
#include "screen-private.h"
|
||||
#include "stack-tracker.h"
|
||||
#include "util.h"
|
||||
@@ -134,7 +135,7 @@ struct _MetaStackTracker
|
||||
/* Idle function used to sync the compositor's view of the window
|
||||
* stack up with our best guess before a frame is drawn.
|
||||
*/
|
||||
guint sync_stack_idle;
|
||||
guint sync_stack_later;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -383,8 +384,8 @@ meta_stack_tracker_new (MetaScreen *screen)
|
||||
void
|
||||
meta_stack_tracker_free (MetaStackTracker *tracker)
|
||||
{
|
||||
if (tracker->sync_stack_idle)
|
||||
g_source_remove (tracker->sync_stack_idle);
|
||||
if (tracker->sync_stack_later)
|
||||
meta_later_remove (tracker->sync_stack_later);
|
||||
|
||||
g_array_free (tracker->server_stack, TRUE);
|
||||
if (tracker->predicted_stack)
|
||||
@@ -667,10 +668,10 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
||||
int n_windows;
|
||||
int i;
|
||||
|
||||
if (tracker->sync_stack_idle)
|
||||
if (tracker->sync_stack_later)
|
||||
{
|
||||
g_source_remove (tracker->sync_stack_idle);
|
||||
tracker->sync_stack_idle = 0;
|
||||
meta_later_remove (tracker->sync_stack_later);
|
||||
tracker->sync_stack_later = 0;
|
||||
}
|
||||
|
||||
meta_stack_tracker_get_stack (tracker, &windows, &n_windows);
|
||||
@@ -682,7 +683,15 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
||||
|
||||
meta_window = meta_display_lookup_x_window (tracker->screen->display,
|
||||
windows[i]);
|
||||
if (meta_window)
|
||||
/* When mapping back from xwindow to MetaWindow we have to be a bit careful;
|
||||
* children of the root could include unmapped windows created by toolkits
|
||||
* for internal purposes, including ones that we have registered in our
|
||||
* XID => window table. (Wine uses a toplevel for _NET_WM_USER_TIME_WINDOW;
|
||||
* see window-prop.c:reload_net_wm_user_time_window() for registration.)
|
||||
*/
|
||||
if (meta_window &&
|
||||
(windows[i] == meta_window->xwindow ||
|
||||
(meta_window->frame && windows[i] == meta_window->frame->xwindow)))
|
||||
meta_windows = g_list_prepend (meta_windows, meta_window);
|
||||
}
|
||||
|
||||
@@ -696,7 +705,7 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
stack_tracker_sync_stack_idle (gpointer data)
|
||||
stack_tracker_sync_stack_later (gpointer data)
|
||||
{
|
||||
meta_stack_tracker_sync_stack (data);
|
||||
|
||||
@@ -719,10 +728,10 @@ stack_tracker_sync_stack_idle (gpointer data)
|
||||
void
|
||||
meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker)
|
||||
{
|
||||
if (tracker->sync_stack_idle == 0)
|
||||
if (tracker->sync_stack_later == 0)
|
||||
{
|
||||
tracker->sync_stack_idle = g_idle_add_full (META_PRIORITY_BEFORE_REDRAW,
|
||||
stack_tracker_sync_stack_idle,
|
||||
tracker->sync_stack_later = meta_later_add (META_LATER_BEFORE_REDRAW,
|
||||
stack_tracker_sync_stack_later,
|
||||
tracker, NULL);
|
||||
}
|
||||
}
|
||||
|
343
src/core/util.c
343
src/core/util.c
@@ -26,9 +26,12 @@
|
||||
#define _POSIX_C_SOURCE 200112L /* for fdopen() */
|
||||
|
||||
#include <config.h>
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <clutter/clutter.h> /* For clutter_threads_add_repaint_func() */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -37,7 +40,12 @@
|
||||
#include <X11/Xlib.h> /* must explicitly be included for Solaris; #326746 */
|
||||
#include <X11/Xutil.h> /* Just for the definition of the various gravities */
|
||||
|
||||
MetaNexus *sigchld_nexus;
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
static void
|
||||
meta_topic_real_valist (MetaDebugTopic topic,
|
||||
const char *format,
|
||||
va_list args);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BACKTRACE
|
||||
#include <execinfo.h>
|
||||
@@ -70,7 +78,7 @@ meta_print_backtrace (void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean is_verbose = FALSE;
|
||||
static gint verbose_topics = 0;
|
||||
static gboolean is_debugging = FALSE;
|
||||
static gboolean replace_current = FALSE;
|
||||
static int no_prefix = 0;
|
||||
@@ -127,7 +135,7 @@ ensure_logfile (void)
|
||||
gboolean
|
||||
meta_is_verbose (void)
|
||||
{
|
||||
return is_verbose;
|
||||
return verbose_topics != 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -140,8 +148,48 @@ meta_set_verbose (gboolean setting)
|
||||
if (setting)
|
||||
ensure_logfile ();
|
||||
#endif
|
||||
|
||||
is_verbose = setting;
|
||||
|
||||
if (setting)
|
||||
meta_add_verbose_topic (META_DEBUG_VERBOSE);
|
||||
else
|
||||
meta_remove_verbose_topic (META_DEBUG_VERBOSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_add_verbose_topic:
|
||||
* @topic: Topic for which logging will be started
|
||||
*
|
||||
* Ensure log messages for the given topic @topic
|
||||
* will be printed.
|
||||
*/
|
||||
void
|
||||
meta_add_verbose_topic (MetaDebugTopic topic)
|
||||
{
|
||||
if (verbose_topics == META_DEBUG_VERBOSE)
|
||||
return;
|
||||
if (topic == META_DEBUG_VERBOSE)
|
||||
verbose_topics = META_DEBUG_VERBOSE;
|
||||
else
|
||||
verbose_topics |= topic;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_remove_verbose_topic:
|
||||
* @topic: Topic for which logging will be stopped
|
||||
*
|
||||
* Stop printing log messages for the given topic @topic. Note
|
||||
* that this method does not stack with meta_add_verbose_topic();
|
||||
* i.e. if two calls to meta_add_verbose_topic() for the same
|
||||
* topic are made, one call to meta_remove_verbose_topic() will
|
||||
* remove it.
|
||||
*/
|
||||
void
|
||||
meta_remove_verbose_topic (MetaDebugTopic topic)
|
||||
{
|
||||
if (topic == META_DEBUG_VERBOSE)
|
||||
verbose_topics = 0;
|
||||
else
|
||||
verbose_topics &= ~topic;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -249,27 +297,10 @@ void
|
||||
meta_verbose_real (const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
gchar *str;
|
||||
FILE *out;
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
if (!is_verbose)
|
||||
return;
|
||||
|
||||
va_start (args, format);
|
||||
str = g_strdup_vprintf (format, args);
|
||||
meta_topic_real_valist (META_DEBUG_VERBOSE, format, args);
|
||||
va_end (args);
|
||||
|
||||
out = logfile ? logfile : stderr;
|
||||
|
||||
if (no_prefix == 0)
|
||||
utf8_fputs ("Window manager: ", out);
|
||||
utf8_fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
#endif /* WITH_VERBOSE_MODE */
|
||||
|
||||
@@ -323,6 +354,8 @@ topic_name (MetaDebugTopic topic)
|
||||
return "COMPOSITOR";
|
||||
case META_DEBUG_EDGE_RESISTANCE:
|
||||
return "EDGE_RESISTANCE";
|
||||
case META_DEBUG_VERBOSE:
|
||||
return "VERBOSE";
|
||||
}
|
||||
|
||||
return "WM";
|
||||
@@ -330,23 +363,22 @@ topic_name (MetaDebugTopic topic)
|
||||
|
||||
static int sync_count = 0;
|
||||
|
||||
void
|
||||
meta_topic_real (MetaDebugTopic topic,
|
||||
const char *format,
|
||||
...)
|
||||
static void
|
||||
meta_topic_real_valist (MetaDebugTopic topic,
|
||||
const char *format,
|
||||
va_list args)
|
||||
{
|
||||
va_list args;
|
||||
gchar *str;
|
||||
FILE *out;
|
||||
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
if (!is_verbose)
|
||||
if (verbose_topics == 0
|
||||
|| (topic == META_DEBUG_VERBOSE && verbose_topics != META_DEBUG_VERBOSE)
|
||||
|| (!(verbose_topics & topic)))
|
||||
return;
|
||||
|
||||
va_start (args, format);
|
||||
|
||||
str = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
out = logfile ? logfile : stderr;
|
||||
|
||||
@@ -365,6 +397,18 @@ meta_topic_real (MetaDebugTopic topic,
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
void
|
||||
meta_topic_real (MetaDebugTopic topic,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
meta_topic_real_valist (topic, format, args);
|
||||
va_end (args);
|
||||
}
|
||||
#endif /* WITH_VERBOSE_MODE */
|
||||
|
||||
void
|
||||
@@ -557,7 +601,7 @@ meta_show_dialog (const char *type,
|
||||
int i=0;
|
||||
GPid child_pid;
|
||||
const char **argvl = g_malloc(sizeof (char*) *
|
||||
(15 +
|
||||
(17 +
|
||||
g_slist_length (columns)*2 +
|
||||
g_slist_length (entries)));
|
||||
|
||||
@@ -565,6 +609,8 @@ meta_show_dialog (const char *type,
|
||||
argvl[i++] = type;
|
||||
argvl[i++] = "--screen";
|
||||
argvl[i++] = screen_number_text;
|
||||
argvl[i++] = "--class";
|
||||
argvl[i++] = "mutter-dialog";
|
||||
argvl[i++] = "--title";
|
||||
/* Translators: This is the title used on dialog boxes */
|
||||
argvl[i++] = _("Mutter");
|
||||
@@ -638,30 +684,225 @@ meta_show_dialog (const char *type,
|
||||
return child_pid;
|
||||
}
|
||||
|
||||
GType
|
||||
meta_nexus_get_type (void)
|
||||
/***************************************************************************
|
||||
* Later functions: like idles but integrated with the Clutter repaint loop
|
||||
***************************************************************************/
|
||||
|
||||
static guint last_later_id = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
static GType nexus_type = 0;
|
||||
guint id;
|
||||
MetaLaterType when;
|
||||
GSourceFunc func;
|
||||
gpointer data;
|
||||
GDestroyNotify notify;
|
||||
int source;
|
||||
gboolean run_once;
|
||||
} MetaLater;
|
||||
|
||||
if (!nexus_type)
|
||||
static GSList *laters = NULL;
|
||||
/* This is a dummy timeline used to get the Clutter master clock running */
|
||||
static ClutterTimeline *later_timeline;
|
||||
static guint later_repaint_func = 0;
|
||||
|
||||
static void ensure_later_repaint_func (void);
|
||||
|
||||
static void
|
||||
destroy_later (MetaLater *later)
|
||||
{
|
||||
if (later->source)
|
||||
g_source_remove (later->source);
|
||||
if (later->notify)
|
||||
later->notify (later->data);
|
||||
g_slice_free (MetaLater, later);
|
||||
}
|
||||
|
||||
/* Used to sort the list of laters with the highest priority
|
||||
* functions first.
|
||||
*/
|
||||
static int
|
||||
compare_laters (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
return ((const MetaLater *)a)->when - ((const MetaLater *)b)->when;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
run_repaint_laters (gpointer data)
|
||||
{
|
||||
GSList *old_laters = laters;
|
||||
GSList *l;
|
||||
gboolean keep_timeline_running = FALSE;
|
||||
laters = NULL;
|
||||
|
||||
for (l = old_laters; l; l = l->next)
|
||||
{
|
||||
static const GTypeInfo nexus_info =
|
||||
{
|
||||
sizeof (MetaNexusClass),
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
sizeof (MetaNexus),
|
||||
0,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
nexus_type = g_type_register_static (G_TYPE_OBJECT,
|
||||
"MetaNexus",
|
||||
&nexus_info,
|
||||
0);
|
||||
MetaLater *later = l->data;
|
||||
if (later->source == 0 ||
|
||||
(later->when <= META_LATER_BEFORE_REDRAW && !later->run_once))
|
||||
{
|
||||
if (later->func (later->data))
|
||||
{
|
||||
if (later->source == 0)
|
||||
keep_timeline_running = TRUE;
|
||||
laters = g_slist_insert_sorted (laters, later, compare_laters);
|
||||
}
|
||||
else
|
||||
destroy_later (later);
|
||||
}
|
||||
else
|
||||
laters = g_slist_insert_sorted (laters, later, compare_laters);
|
||||
}
|
||||
|
||||
return nexus_type;
|
||||
if (!keep_timeline_running)
|
||||
clutter_timeline_stop (later_timeline);
|
||||
|
||||
g_slist_free (old_laters);
|
||||
|
||||
/* Just keep the repaint func around - it's cheap if the list is empty */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_later_repaint_func (void)
|
||||
{
|
||||
if (!later_timeline)
|
||||
later_timeline = clutter_timeline_new (G_MAXUINT);
|
||||
|
||||
if (later_repaint_func == 0)
|
||||
later_repaint_func = clutter_threads_add_repaint_func (run_repaint_laters,
|
||||
NULL, NULL);
|
||||
|
||||
/* Make sure the repaint function gets run */
|
||||
clutter_timeline_start (later_timeline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
call_idle_later (gpointer data)
|
||||
{
|
||||
MetaLater *later = data;
|
||||
|
||||
if (!later->func (later->data))
|
||||
{
|
||||
laters = g_slist_remove (laters, later);
|
||||
later->source = 0;
|
||||
destroy_later (later);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
later->run_once = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_later_add:
|
||||
* @when: enumeration value determining the phase at which to run the callback
|
||||
* @func: callback to run later
|
||||
* @data: data to pass to the callback
|
||||
* @notify: function to call to destroy @data when it is no longer in use, or %NULL
|
||||
*
|
||||
* Sets up a callback to be called at some later time. @when determines the
|
||||
* particular later occasion at which it is called. This is much like g_idle_add(),
|
||||
* except that the functions interact properly with clutter event handling.
|
||||
* If a "later" function is added from a clutter event handler, and is supposed
|
||||
* to be run before the stage is redrawn, it will be run before that redraw
|
||||
* of the stage, not the next one.
|
||||
*
|
||||
* Return value: an integer ID (guaranteed to be non-zero) that can be used
|
||||
* to cancel the callback and prevent it from being run.
|
||||
*/
|
||||
guint
|
||||
meta_later_add (MetaLaterType when,
|
||||
GSourceFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
MetaLater *later = g_slice_new0 (MetaLater);
|
||||
|
||||
later->id = ++last_later_id;
|
||||
later->when = when;
|
||||
later->func = func;
|
||||
later->data = data;
|
||||
later->notify = notify;
|
||||
|
||||
laters = g_slist_insert_sorted (laters, later, compare_laters);
|
||||
|
||||
switch (when)
|
||||
{
|
||||
case META_LATER_RESIZE:
|
||||
/* We add this one two ways - as a high-priority idle and as a
|
||||
* repaint func. If we are in a clutter event callback, the repaint
|
||||
* handler will get hit first, and we'll take care of this function
|
||||
* there so it gets called before the stage is redrawn, even if
|
||||
* we haven't gotten back to the main loop. Otherwise, the idle
|
||||
* handler will get hit first and we want to call this function
|
||||
* there so it will happen before GTK+ repaints.
|
||||
*/
|
||||
later->source = g_idle_add_full (META_PRIORITY_RESIZE, call_idle_later, later, NULL);
|
||||
ensure_later_repaint_func ();
|
||||
break;
|
||||
case META_LATER_BEFORE_REDRAW:
|
||||
ensure_later_repaint_func ();
|
||||
break;
|
||||
case META_LATER_IDLE:
|
||||
later->source = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, call_idle_later, later, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return later->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_later_remove:
|
||||
* @later_id: the integer ID returned from meta_later_add()
|
||||
*
|
||||
* Removes a callback added with meta_later_add()
|
||||
*/
|
||||
void
|
||||
meta_later_remove (guint later_id)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = laters; l; l = l->next)
|
||||
{
|
||||
MetaLater *later = l->data;
|
||||
if (later->id == later_id)
|
||||
{
|
||||
laters = g_slist_remove_link (laters, l);
|
||||
/* If this was a "repaint func" later, we just let the
|
||||
* repaint func run and get removed
|
||||
*/
|
||||
destroy_later (later);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO_REGION
|
||||
#include "region.h"
|
||||
|
||||
void
|
||||
meta_region_get_rectangles (MetaRegion *region,
|
||||
GdkRectangle **rectangles,
|
||||
int *n_rectangles)
|
||||
{
|
||||
int n = cairo_region_num_rectangles (region);
|
||||
|
||||
if (n_rectangles != NULL)
|
||||
*n_rectangles = n;
|
||||
|
||||
if (rectangles != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
*rectangles = g_new (cairo_rectangle_int_t, n);
|
||||
for (i = 0; i < n; i++)
|
||||
cairo_region_get_rectangle (region, i, *rectangles + i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* eof util.c */
|
||||
|
||||
|
@@ -46,9 +46,6 @@
|
||||
|
||||
typedef struct _MetaWindowQueue MetaWindowQueue;
|
||||
|
||||
typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window,
|
||||
void *data);
|
||||
|
||||
typedef enum {
|
||||
META_CLIENT_TYPE_UNKNOWN = 0,
|
||||
META_CLIENT_TYPE_APPLICATION = 1,
|
||||
@@ -64,6 +61,12 @@ typedef enum {
|
||||
|
||||
#define NUMBER_OF_QUEUES 3
|
||||
|
||||
typedef enum {
|
||||
META_TILE_NONE,
|
||||
META_TILE_LEFT,
|
||||
META_TILE_RIGHT
|
||||
} MetaTileMode;
|
||||
|
||||
struct _MetaWindow
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -99,6 +102,7 @@ struct _MetaWindow
|
||||
char *sm_client_id;
|
||||
char *wm_client_machine;
|
||||
char *startup_id;
|
||||
char *mutter_hints;
|
||||
|
||||
int net_wm_pid;
|
||||
|
||||
@@ -124,12 +128,23 @@ struct _MetaWindow
|
||||
guint maximize_vertically_after_placement : 1;
|
||||
guint minimize_after_placement : 1;
|
||||
|
||||
/* The current or requested tile mode. If maximized_vertically is true,
|
||||
* this is the current mode. If not, it is the mode which will be
|
||||
* requested after the window grab is released */
|
||||
guint tile_mode : 2;
|
||||
|
||||
/* Whether we're shaded */
|
||||
guint shaded : 1;
|
||||
|
||||
/* Whether we're fullscreen */
|
||||
guint fullscreen : 1;
|
||||
|
||||
/* Whether the urgent flag of WM_HINTS is set */
|
||||
guint wm_hints_urgent : 1;
|
||||
|
||||
/* Whether we have to fullscreen after placement */
|
||||
guint fullscreen_after_placement : 1;
|
||||
|
||||
/* Area to cover when in fullscreen mode. If _NET_WM_FULLSCREEN_MONITORS has
|
||||
* been overridden (via a client message), the window will cover the union of
|
||||
* these monitors. If not, this is the single monitor which the window's
|
||||
@@ -246,6 +261,9 @@ struct _MetaWindow
|
||||
/* Have we placed this window? */
|
||||
guint placed : 1;
|
||||
|
||||
/* Must we force_save_user_window_placement? */
|
||||
guint force_save_user_rect : 1;
|
||||
|
||||
/* Is this not a transient of the focus window which is being denied focus? */
|
||||
guint denied_focus_and_not_transient : 1;
|
||||
|
||||
@@ -316,6 +334,9 @@ struct _MetaWindow
|
||||
*/
|
||||
int unmaps_pending;
|
||||
|
||||
/* See docs for meta_window_get_stable_sequence() */
|
||||
guint32 stable_sequence;
|
||||
|
||||
/* set to the most recent user-interaction event timestamp that we
|
||||
know about for this window */
|
||||
guint32 net_wm_user_time;
|
||||
@@ -377,6 +398,7 @@ struct _MetaWindowClass
|
||||
void (*workspace_changed) (MetaWindow *window, int old_workspace);
|
||||
void (*focus) (MetaWindow *window);
|
||||
void (*raised) (MetaWindow *window);
|
||||
void (*unmanaged) (MetaWindow *window);
|
||||
};
|
||||
|
||||
/* These differ from window->has_foo_func in that they consider
|
||||
@@ -387,8 +409,11 @@ struct _MetaWindowClass
|
||||
(w)->maximized_vertically)
|
||||
#define META_WINDOW_MAXIMIZED_VERTICALLY(w) ((w)->maximized_vertically)
|
||||
#define META_WINDOW_MAXIMIZED_HORIZONTALLY(w) ((w)->maximized_horizontally)
|
||||
#define META_WINDOW_TILED(w) ((w)->maximized_vertically && \
|
||||
!(w)->maximized_horizontally && \
|
||||
(w)->tile_mode != META_TILE_NONE)
|
||||
#define META_WINDOW_ALLOWS_MOVE(w) ((w)->has_move_func && !(w)->fullscreen)
|
||||
#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !(w)->fullscreen && !(w)->shaded)
|
||||
#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !META_WINDOW_TILED(w) && !(w)->fullscreen && !(w)->shaded)
|
||||
#define META_WINDOW_ALLOWS_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && \
|
||||
(((w)->size_hints.min_width < (w)->size_hints.max_width) || \
|
||||
((w)->size_hints.min_height < (w)->size_hints.max_height)))
|
||||
@@ -411,6 +436,11 @@ void meta_window_queue (MetaWindow *window,
|
||||
void meta_window_maximize_internal (MetaWindow *window,
|
||||
MetaMaximizeFlags directions,
|
||||
MetaRectangle *saved_rect);
|
||||
void meta_window_unmaximize_with_gravity (MetaWindow *window,
|
||||
MetaMaximizeFlags directions,
|
||||
int new_width,
|
||||
int new_height,
|
||||
int gravity);
|
||||
void meta_window_make_above (MetaWindow *window);
|
||||
void meta_window_unmake_above (MetaWindow *window);
|
||||
void meta_window_shade (MetaWindow *window,
|
||||
@@ -431,6 +461,8 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
|
||||
unsigned long left,
|
||||
unsigned long right);
|
||||
|
||||
gboolean meta_window_appears_focused (MetaWindow *window);
|
||||
|
||||
/* args to move are window pos, not frame pos */
|
||||
void meta_window_move (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
@@ -493,8 +525,6 @@ void meta_window_get_geometry (MetaWindow *window,
|
||||
void meta_window_kill (MetaWindow *window);
|
||||
void meta_window_focus (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void meta_window_raise (MetaWindow *window);
|
||||
void meta_window_lower (MetaWindow *window);
|
||||
|
||||
void meta_window_update_unfocused_button_grabs (MetaWindow *window);
|
||||
|
||||
@@ -552,6 +582,9 @@ void meta_window_get_work_area_for_monitor (MetaWindow *window,
|
||||
void meta_window_get_work_area_all_monitors (MetaWindow *window,
|
||||
MetaRectangle *area);
|
||||
|
||||
void meta_window_get_current_tile_area (MetaWindow *window,
|
||||
MetaRectangle *tile_area);
|
||||
|
||||
|
||||
gboolean meta_window_same_application (MetaWindow *window,
|
||||
MetaWindow *other_window);
|
||||
@@ -569,12 +602,6 @@ void meta_window_refresh_resize_popup (MetaWindow *window);
|
||||
|
||||
void meta_window_free_delete_dialog (MetaWindow *window);
|
||||
|
||||
void meta_window_foreach_transient (MetaWindow *window,
|
||||
MetaWindowForeachFunc func,
|
||||
void *data);
|
||||
void meta_window_foreach_ancestor (MetaWindow *window,
|
||||
MetaWindowForeachFunc func,
|
||||
void *data);
|
||||
|
||||
void meta_window_begin_grab_op (MetaWindow *window,
|
||||
MetaGrabOp op,
|
||||
@@ -597,10 +624,6 @@ void meta_window_stack_just_below (MetaWindow *window,
|
||||
void meta_window_set_user_time (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_window_set_demands_attention (MetaWindow *window);
|
||||
|
||||
void meta_window_unset_demands_attention (MetaWindow *window);
|
||||
|
||||
void meta_window_update_icon_now (MetaWindow *window);
|
||||
|
||||
void meta_window_update_role (MetaWindow *window);
|
||||
|
@@ -523,6 +523,49 @@ reload_wm_name (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reload_mutter_hints (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
char *new_hints = value->v.str;
|
||||
char *old_hints = window->mutter_hints;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
if (new_hints)
|
||||
{
|
||||
if (!old_hints || strcmp (new_hints, old_hints))
|
||||
changed = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (old_hints)
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
g_free (old_hints);
|
||||
|
||||
if (new_hints)
|
||||
window->mutter_hints = g_strdup (new_hints);
|
||||
else
|
||||
window->mutter_hints = NULL;
|
||||
|
||||
g_object_notify (G_OBJECT (window), "mutter-hints");
|
||||
}
|
||||
}
|
||||
else if (window->mutter_hints)
|
||||
{
|
||||
g_free (window->mutter_hints);
|
||||
window->mutter_hints = NULL;
|
||||
|
||||
g_object_notify (G_OBJECT (window), "mutter-hints");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_icon_title (MetaWindow *window,
|
||||
const char *title)
|
||||
@@ -604,6 +647,7 @@ reload_net_wm_state (MetaWindow *window,
|
||||
window->shaded = FALSE;
|
||||
window->maximized_horizontally = FALSE;
|
||||
window->maximized_vertically = FALSE;
|
||||
window->fullscreen = FALSE;
|
||||
window->wm_state_modal = FALSE;
|
||||
window->wm_state_skip_taskbar = FALSE;
|
||||
window->wm_state_skip_pager = FALSE;
|
||||
@@ -632,13 +676,7 @@ reload_net_wm_state (MetaWindow *window,
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER)
|
||||
window->wm_state_skip_pager = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_FULLSCREEN)
|
||||
{
|
||||
if (!window->fullscreen)
|
||||
{
|
||||
window->fullscreen = TRUE;
|
||||
g_object_notify (G_OBJECT (window), "fullscreen");
|
||||
}
|
||||
}
|
||||
window->fullscreen_after_placement = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE)
|
||||
window->wm_state_above = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_BELOW)
|
||||
@@ -1350,8 +1388,10 @@ reload_wm_hints (MetaWindow *window,
|
||||
gboolean initial)
|
||||
{
|
||||
Window old_group_leader;
|
||||
|
||||
gboolean old_urgent;
|
||||
|
||||
old_group_leader = window->xgroup_leader;
|
||||
old_urgent = window->wm_hints_urgent;
|
||||
|
||||
/* Fill in defaults */
|
||||
window->input = TRUE;
|
||||
@@ -1359,7 +1399,8 @@ reload_wm_hints (MetaWindow *window,
|
||||
window->xgroup_leader = None;
|
||||
window->wm_hints_pixmap = None;
|
||||
window->wm_hints_mask = None;
|
||||
|
||||
window->wm_hints_urgent = FALSE;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
const XWMHints *hints = value->v.wm_hints;
|
||||
@@ -1378,7 +1419,10 @@ reload_wm_hints (MetaWindow *window,
|
||||
|
||||
if (hints->flags & IconMaskHint)
|
||||
window->wm_hints_mask = hints->icon_mask;
|
||||
|
||||
|
||||
if (hints->flags & XUrgencyHint)
|
||||
window->wm_hints_urgent = TRUE;
|
||||
|
||||
meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n",
|
||||
window->input, window->initially_iconic,
|
||||
window->xgroup_leader,
|
||||
@@ -1394,6 +1438,21 @@ reload_wm_hints (MetaWindow *window,
|
||||
meta_window_group_leader_changed (window);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not emit urgency notification on the inital property load
|
||||
*/
|
||||
if (!initial && (window->wm_hints_urgent != old_urgent))
|
||||
g_object_notify (G_OBJECT (window), "urgent");
|
||||
|
||||
/*
|
||||
* Do not emit signal for the initial property load, let the constructor to
|
||||
* take care of it once the MetaWindow is fully constructed.
|
||||
*
|
||||
* Only emit if the property is both changed and set.
|
||||
*/
|
||||
if (!initial && window->wm_hints_urgent && !old_urgent)
|
||||
g_signal_emit_by_name (window->display, "window-marked-urgent", window);
|
||||
|
||||
meta_icon_cache_property_changed (&window->icon_cache,
|
||||
window->display,
|
||||
XA_WM_HINTS);
|
||||
@@ -1490,6 +1549,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
{ XA_WM_CLASS, META_PROP_VALUE_CLASS_HINT, reload_wm_class, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_PID, META_PROP_VALUE_CARDINAL, reload_net_wm_pid, TRUE, TRUE },
|
||||
{ XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name, TRUE, TRUE },
|
||||
{ display->atom__MUTTER_HINTS, META_PROP_VALUE_TEXT_PROPERTY, reload_mutter_hints, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_ICON_NAME, META_PROP_VALUE_UTF8, reload_net_wm_icon_name, TRUE, FALSE },
|
||||
{ XA_WM_ICON_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_icon_name, TRUE, FALSE },
|
||||
{ display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop, TRUE, FALSE },
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,9 @@
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
#include <canberra-gtk.h>
|
||||
#endif
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@@ -439,6 +442,69 @@ meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
workspace_switch_sound(MetaWorkspace *from,
|
||||
MetaWorkspace *to)
|
||||
{
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
MetaWorkspaceLayout layout;
|
||||
int i, nw, x, y, fi, ti;
|
||||
const char *e;
|
||||
|
||||
nw = meta_screen_get_n_workspaces(from->screen);
|
||||
fi = meta_workspace_index(from);
|
||||
ti = meta_workspace_index(to);
|
||||
|
||||
meta_screen_calc_workspace_layout(from->screen,
|
||||
nw,
|
||||
fi,
|
||||
&layout);
|
||||
|
||||
for (i = 0; i < nw; i++)
|
||||
if (layout.grid[i] == ti)
|
||||
break;
|
||||
|
||||
if (i >= nw)
|
||||
{
|
||||
meta_bug("Failed to find destination workspace in layout\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
y = i / layout.cols;
|
||||
x = i % layout.cols;
|
||||
|
||||
/* We priorize horizontal over vertical movements here. The
|
||||
rationale for this is that horizontal movements are probably more
|
||||
interesting for sound effects because speakers are usually
|
||||
positioned on a horizontal and not a vertical axis. i.e. your
|
||||
spatial "Woosh!" effects will easily be able to encode horizontal
|
||||
movement but not such much vertical movement. */
|
||||
|
||||
if (x < layout.current_col)
|
||||
e = "desktop-switch-left";
|
||||
else if (x > layout.current_col)
|
||||
e = "desktop-switch-right";
|
||||
else if (y < layout.current_row)
|
||||
e = "desktop-switch-up";
|
||||
else if (y > layout.current_row)
|
||||
e = "desktop-switch-down";
|
||||
else
|
||||
{
|
||||
meta_bug("Uh, origin and destination workspace at same logic position!\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
ca_context_play(ca_gtk_context_get(), 1,
|
||||
CA_PROP_EVENT_ID, e,
|
||||
CA_PROP_EVENT_DESCRIPTION, "Desktop switched",
|
||||
CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
|
||||
NULL);
|
||||
|
||||
finish:
|
||||
meta_screen_free_workspace_layout (&layout);
|
||||
#endif /* HAVE_LIBCANBERRA */
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_workspace_activate_with_focus:
|
||||
* @workspace: a #MetaWorkspace
|
||||
@@ -478,6 +544,13 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
if (workspace->screen->active_workspace == workspace)
|
||||
return;
|
||||
|
||||
/* Free any cached pointers to the workspaces's edges from
|
||||
* a current resize or move operation */
|
||||
meta_display_cleanup_edges (workspace->screen->display);
|
||||
|
||||
if (workspace->screen->active_workspace)
|
||||
workspace_switch_sound (workspace->screen->active_workspace, workspace);
|
||||
|
||||
/* Note that old can be NULL; e.g. when starting up */
|
||||
old = workspace->screen->active_workspace;
|
||||
|
||||
@@ -633,12 +706,12 @@ meta_workspace_update_window_hints (MetaWorkspace *workspace)
|
||||
|
||||
/**
|
||||
* meta_workspace_list_windows:
|
||||
* @display: a #MetaDisplay
|
||||
* @workspace: a #MetaWorkspace
|
||||
*
|
||||
* Gets windows contained on the workspace, including workspace->windows
|
||||
* and also sticky windows. Override-redirect windows are not included.
|
||||
*
|
||||
* Return value: (transfer container): the list of windows.
|
||||
* Return value: (transfer container) (element-type MetaWindow): the list of windows.
|
||||
*/
|
||||
GList*
|
||||
meta_workspace_list_windows (MetaWorkspace *workspace)
|
||||
@@ -713,6 +786,11 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
||||
"Invalidating work area for workspace %d\n",
|
||||
meta_workspace_index (workspace));
|
||||
|
||||
/* If we are in the middle of a resize or move operation, we
|
||||
* might have cached pointers to the workspace's edges */
|
||||
if (workspace == workspace->screen->active_workspace)
|
||||
meta_display_cleanup_edges (workspace->screen->display);
|
||||
|
||||
g_free (workspace->work_area_monitor);
|
||||
workspace->work_area_monitor = NULL;
|
||||
|
||||
@@ -950,6 +1028,23 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
strut_lists_equal (GSList *l,
|
||||
GSList *m)
|
||||
{
|
||||
for (; l && m; l = l->next, m = m->next)
|
||||
{
|
||||
MetaStrut *a = l->data;
|
||||
MetaStrut *b = m->data;
|
||||
|
||||
if (a->side != b->side ||
|
||||
!meta_rectangle_equal (&a->rect, &b->rect))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return l == NULL && m == NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_workspace_set_builtin_struts:
|
||||
* @workspace: a #MetaWorkspace
|
||||
@@ -963,6 +1058,12 @@ void
|
||||
meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
|
||||
GSList *struts)
|
||||
{
|
||||
/* Reordering doesn't actually matter, so we don't catch all
|
||||
* no-impact changes, but this is just a (possibly unnecessary
|
||||
* anyways) optimization */
|
||||
if (strut_lists_equal (struts, workspace->builtin_struts))
|
||||
return;
|
||||
|
||||
workspace_free_builtin_struts (workspace);
|
||||
workspace->builtin_struts = copy_strut_list (struts);
|
||||
|
||||
@@ -1202,7 +1303,10 @@ focus_ancestor_or_mru_window (MetaWorkspace *workspace,
|
||||
MetaWindow *ancestor;
|
||||
ancestor = NULL;
|
||||
meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor);
|
||||
if (ancestor != NULL)
|
||||
if (ancestor != NULL &&
|
||||
(ancestor->on_all_workspaces ||
|
||||
ancestor->workspace == workspace) &&
|
||||
meta_window_showing_on_its_workspace (ancestor))
|
||||
{
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing %s, ancestor of %s\n",
|
||||
|
@@ -264,6 +264,16 @@ cardinal_list_from_results (GetPropertyResults *results,
|
||||
*n_cardinals_p = results->n_items;
|
||||
results->prop = NULL;
|
||||
|
||||
#if GLIB_SIZEOF_LONG == 8
|
||||
/* Xlib sign-extends format=32 items, but we want them unsigned */
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < *n_cardinals_p; i++)
|
||||
(*cardinals_p)[i] = (*cardinals_p)[i] & 0xffffffff;
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -608,6 +618,10 @@ cardinal_with_atom_type_from_results (GetPropertyResults *results,
|
||||
return FALSE;
|
||||
|
||||
*cardinal_p = *(gulong*) results->prop;
|
||||
#if GLIB_SIZEOF_LONG == 8
|
||||
/* Xlib sign-extends format=32 items, but we want them unsigned */
|
||||
*cardinal_p &= 0xffffffff;
|
||||
#endif
|
||||
XFree (results->prop);
|
||||
results->prop = NULL;
|
||||
|
||||
|
80
src/gdk-compat.h
Normal file
80
src/gdk-compat.h
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef __GDK_COMPAT_H__
|
||||
#define __GDK_COMPAT_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Provide a compatibility layer for accessor function introduced
|
||||
* in GTK+ 2.22 which we need to build without deprecated GDK symbols.
|
||||
* That way it is still possible to build with GTK+ 2.18 when not
|
||||
* using GDK_DISABLE_DEPRECATED.
|
||||
*/
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 21, 1)
|
||||
|
||||
#define gdk_visual_get_depth(v) GDK_VISUAL(v)->depth
|
||||
|
||||
#endif /* GTK_CHECK_VERSION (2, 21, 1) */
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 90, 8)
|
||||
|
||||
#define gdk_window_get_screen gdk_drawable_get_screen
|
||||
#define gdk_pixbuf_get_from_window(window, src_x, src_y, width, height) \
|
||||
gdk_pixbuf_get_from_drawable(NULL, window, NULL, src_x, src_y, 0, 0, width, height)
|
||||
|
||||
static inline int
|
||||
gdk_window_get_width (GdkWindow *window)
|
||||
{
|
||||
int width;
|
||||
|
||||
gdk_drawable_get_size (window, &width, NULL);
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
static inline int
|
||||
gdk_window_get_height (GdkWindow *window)
|
||||
{
|
||||
int height;
|
||||
|
||||
gdk_drawable_get_size (window, NULL, &height);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
static inline gboolean
|
||||
gdk_cairo_get_clip_rectangle (cairo_t *cr,
|
||||
GdkRectangle *rect)
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
gboolean clip_exists;
|
||||
|
||||
cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
|
||||
|
||||
clip_exists = x1 < x2 && y1 < y2;
|
||||
|
||||
if (rect)
|
||||
{
|
||||
x1 = floor (x1);
|
||||
y1 = floor (y1);
|
||||
x2 = ceil (x2);
|
||||
y2 = ceil (y2);
|
||||
|
||||
rect->x = CLAMP (x1, G_MININT, G_MAXINT);
|
||||
rect->y = CLAMP (y1, G_MININT, G_MAXINT);
|
||||
rect->width = CLAMP (x2 - x1, G_MININT, G_MAXINT);
|
||||
rect->height = CLAMP (y2 - y1, G_MININT, G_MAXINT);
|
||||
}
|
||||
|
||||
return clip_exists;
|
||||
}
|
||||
|
||||
#endif /* GTK_CHECK_VERSION (2, 90, 8) */
|
||||
|
||||
/* Compatibility with old GDK key symbols */
|
||||
#ifndef GDK_KEY_Escape
|
||||
#define GDK_KEY_Escape GDK_Escape
|
||||
#endif /* GDK_KEY_Escape */
|
||||
|
||||
#endif /* __GDK_COMPAT_H__ */
|
177
src/gdk2-drawing-utils.c
Normal file
177
src/gdk2-drawing-utils.c
Normal file
@@ -0,0 +1,177 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010 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 "gdk2-drawing-utils.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "gdk-compat.h"
|
||||
|
||||
#ifndef USE_GTK3
|
||||
|
||||
static const cairo_user_data_key_t context_key;
|
||||
|
||||
cairo_t *
|
||||
meta_cairo_create (GdkDrawable *drawable)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
cr = gdk_cairo_create (drawable);
|
||||
cairo_set_user_data (cr, &context_key, drawable, NULL);
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
static GdkWindow *
|
||||
extract_window (cairo_t *cr,
|
||||
int *dx,
|
||||
int *dy,
|
||||
GdkRectangle *clip_area)
|
||||
{
|
||||
GdkWindow *window = cairo_get_user_data (cr, &context_key);
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
g_assert (dx != NULL);
|
||||
g_assert (dy != NULL);
|
||||
g_assert (clip_area != NULL);
|
||||
|
||||
/* lots of stuff that mustn't happen because we can't cope with it. */
|
||||
if (window == NULL)
|
||||
{
|
||||
g_error ("Could not get the GdkWindow from the cairo context passed to\n"
|
||||
"theme drawing functions. A GdkWindow must be set on all cairo\n"
|
||||
"context passed to theme drawing functions when using GTK2.\n"
|
||||
"Please use meta_cairo_create() to create the Cairo context.\n");
|
||||
}
|
||||
cairo_get_matrix (cr, &matrix);
|
||||
if (matrix.xx != 1.0 || matrix.yy != 1.0 ||
|
||||
matrix.xy != 0.0 || matrix.yx != 0.0 ||
|
||||
floor (matrix.x0) != matrix.x0 ||
|
||||
floor (matrix.y0) != matrix.y0)
|
||||
{
|
||||
g_error ("GTK2 drawing requires that the matrix set on the cairo context\n"
|
||||
"is an integer translation, however that is not the case.\n");
|
||||
}
|
||||
|
||||
gdk_cairo_get_clip_rectangle (cr, clip_area);
|
||||
clip_area->x += matrix.x0;
|
||||
clip_area->y += matrix.y0;
|
||||
|
||||
*dx = matrix.x0;
|
||||
*dy = matrix.y0;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void
|
||||
meta_paint_vline (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint y1_,
|
||||
gint y2_,
|
||||
gint x)
|
||||
{
|
||||
int dx, dy;
|
||||
GdkWindow *window;
|
||||
GdkRectangle area;
|
||||
|
||||
window = extract_window (cr, &dx, &dy, &area);
|
||||
|
||||
gtk_paint_vline (style, window, state_type, &area,
|
||||
widget, detail, y1_ + dy, y2_ + dy, x + dx);
|
||||
}
|
||||
|
||||
void
|
||||
meta_paint_arrow (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
GtkArrowType arrow_type,
|
||||
gboolean fill,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
int dx, dy;
|
||||
GdkWindow *window;
|
||||
GdkRectangle area;
|
||||
|
||||
window = extract_window (cr, &dx, &dy, &area);
|
||||
|
||||
gtk_paint_arrow (style, window, state_type, shadow_type,
|
||||
&area, widget, detail, arrow_type,
|
||||
fill, x + dx, y + dy, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
meta_paint_box (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
int dx, dy;
|
||||
GdkWindow *window;
|
||||
GdkRectangle area;
|
||||
|
||||
window = extract_window (cr, &dx, &dy, &area);
|
||||
|
||||
gtk_paint_box (style, window, state_type, shadow_type,
|
||||
&area, widget, detail,
|
||||
x + dx, y + dy, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
meta_paint_flat_box (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
int dx, dy;
|
||||
GdkWindow *window;
|
||||
GdkRectangle area;
|
||||
|
||||
window = extract_window (cr, &dx, &dy, &area);
|
||||
|
||||
gtk_paint_flat_box (style, window, state_type, shadow_type,
|
||||
&area, widget, detail,
|
||||
x + dx, y + dy, width, height);
|
||||
}
|
||||
|
||||
#endif /* USE_GTK3 */
|
100
src/gdk2-drawing-utils.h
Normal file
100
src/gdk2-drawing-utils.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010 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 __GTK3_COMPAT_H__
|
||||
#define __GTK3_COMPAT_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#if GTK_CHECK_VERSION (2, 90, 8)
|
||||
|
||||
#define USE_GTK3 1
|
||||
|
||||
#define MetaPixmap cairo_surface_t
|
||||
|
||||
#define meta_pixmap_new(window, w, h) gdk_window_create_similar_surface (window, CAIRO_CONTENT_COLOR, w, h)
|
||||
#define meta_pixmap_free(pixmap) cairo_surface_destroy (pixmap)
|
||||
#define meta_pixmap_cairo_create(pixmap) cairo_create (pixmap)
|
||||
#define meta_cairo_set_source_pixmap(cr, pixmap, x, y) cairo_set_source_surface (cr, pixmap, x, y)
|
||||
|
||||
#define meta_paint_vline gtk_paint_vline
|
||||
#define meta_paint_box gtk_paint_box
|
||||
#define meta_paint_arrow gtk_paint_arrow
|
||||
#define meta_paint_flat_box gtk_paint_flat_box
|
||||
|
||||
#else /* GTK_VERSION < 2.90.8 */
|
||||
|
||||
#undef USE_GTK3
|
||||
|
||||
#define MetaPixmap GdkPixmap
|
||||
|
||||
#define meta_pixmap_new(window, w, h) gdk_pixmap_new (window, w, h, -1)
|
||||
#define meta_pixmap_free(pixmap) g_object_unref (pixmap)
|
||||
#define meta_pixmap_cairo_create(pixmap) meta_cairo_create (pixmap)
|
||||
#define meta_cairo_set_source_pixmap(cr, pixmap, x, y) gdk_cairo_set_source_pixmap (cr, pixmap, x, y)
|
||||
|
||||
/* This function only exists for GTK2 code. */
|
||||
cairo_t * meta_cairo_create (GdkDrawable *drawable);
|
||||
|
||||
void meta_paint_vline (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint y1_,
|
||||
gint y2_,
|
||||
gint x);
|
||||
void meta_paint_arrow (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
GtkArrowType arrow_type,
|
||||
gboolean fill,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
void meta_paint_box (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
void meta_paint_flat_box (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
#endif /* GTK_VERSION < 2.90.8 */
|
||||
|
||||
#endif /* __GTK3_COMPAT_H__ */
|
26
src/gtk-compat.h
Normal file
26
src/gtk-compat.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __GTK_COMPAT_H__
|
||||
#define __GTK_COMPAT_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* Provide a compatibility layer for accessor function introduces
|
||||
* in GTK+ 2.20 which we need to build with GSEAL_ENABLE.
|
||||
* That way it is still possible to build with GTK+ 2.18 when not
|
||||
* using GSEAL_ENABLE
|
||||
*/
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 20, 0)
|
||||
|
||||
#define gtk_widget_get_realized(w) GTK_WIDGET_REALIZED (w)
|
||||
#define gtk_widget_get_requisition(w,r) (*r = GTK_WIDGET (w)->requisition)
|
||||
#define gtk_widget_set_mapped(w,m) \
|
||||
G_STMT_START { \
|
||||
if (m) \
|
||||
GTK_WIDGET_SET_FLAGS (w, GTK_MAPPED); \
|
||||
else \
|
||||
GTK_WIDGET_UNSET_FLAGS (w, GTK_MAPPED); \
|
||||
} G_STMT_END
|
||||
|
||||
#endif /* GTK_CHECK_VERSION */
|
||||
|
||||
#endif /* __GTK_COMPAT_H__ */
|
@@ -167,7 +167,7 @@ keybind (switch_panels_backward, handle_switch, META_TAB_LIST_DOCKS,
|
||||
"using a popup window"))
|
||||
|
||||
keybind (cycle_group, handle_cycle, META_TAB_LIST_GROUP,
|
||||
BINDING_REVERSES, "<Alt>F6",
|
||||
BINDING_REVERSES, "<Alt>grave",
|
||||
_("Move between windows of an application immediately"))
|
||||
keybind (cycle_group_backward, handle_cycle, META_TAB_LIST_GROUP,
|
||||
REVERSES_AND_REVERSED, NULL,
|
||||
|
@@ -1,73 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Metacity Alt-Tab abstraction */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009 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_ALT_TAB_HANDLER_H
|
||||
#define META_ALT_TAB_HANDLER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define META_TYPE_ALT_TAB_HANDLER (meta_alt_tab_handler_get_type ())
|
||||
#define META_ALT_TAB_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_ALT_TAB_HANDLER, MetaAltTabHandler))
|
||||
#define META_ALT_TAB_HANDLER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), META_TYPE_ALT_TAB_HANDLER, MetaAltTabHandlerInterface))
|
||||
|
||||
typedef struct _MetaAltTabHandler MetaAltTabHandler;
|
||||
typedef struct _MetaAltTabHandlerInterface MetaAltTabHandlerInterface;
|
||||
|
||||
struct _MetaAltTabHandlerInterface {
|
||||
GTypeInterface g_iface;
|
||||
|
||||
void (*add_window) (MetaAltTabHandler *handler,
|
||||
MetaWindow *window);
|
||||
|
||||
void (*show) (MetaAltTabHandler *handler,
|
||||
MetaWindow *initial_selection);
|
||||
void (*destroy) (MetaAltTabHandler *handler);
|
||||
|
||||
void (*forward) (MetaAltTabHandler *handler);
|
||||
void (*backward) (MetaAltTabHandler *handler);
|
||||
|
||||
MetaWindow * (*get_selected) (MetaAltTabHandler *handler);
|
||||
};
|
||||
|
||||
GType meta_alt_tab_handler_get_type (void);
|
||||
|
||||
void meta_alt_tab_handler_register (GType type);
|
||||
MetaAltTabHandler *meta_alt_tab_handler_new (MetaScreen *screen,
|
||||
gboolean immediate);
|
||||
|
||||
void meta_alt_tab_handler_add_window (MetaAltTabHandler *handler,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_alt_tab_handler_show (MetaAltTabHandler *handler,
|
||||
MetaWindow *initial_selection);
|
||||
void meta_alt_tab_handler_destroy (MetaAltTabHandler *handler);
|
||||
|
||||
void meta_alt_tab_handler_forward (MetaAltTabHandler *handler);
|
||||
void meta_alt_tab_handler_backward (MetaAltTabHandler *handler);
|
||||
|
||||
MetaWindow *meta_alt_tab_handler_get_selected (MetaAltTabHandler *handler);
|
||||
|
||||
#endif
|
||||
|
@@ -1,55 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Metacity Alt-Tab abstraction: default implementation */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009 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_ALT_TAB_HANDLER_DEFAULT_H
|
||||
#define META_ALT_TAB_HANDLER_DEFAULT_H
|
||||
|
||||
#include "alttabhandler.h"
|
||||
#include "tabpopup.h"
|
||||
|
||||
#define META_TYPE_ALT_TAB_HANDLER_DEFAULT (meta_alt_tab_handler_default_get_type ())
|
||||
#define META_ALT_TAB_HANDLER_DEFAULT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_ALT_TAB_HANDLER_DEFAULT, MetaAltTabHandlerDefault))
|
||||
|
||||
typedef struct _MetaAltTabHandlerDefault MetaAltTabHandlerDefault;
|
||||
typedef struct _MetaAltTabHandlerDefaultClass MetaAltTabHandlerDefaultClass;
|
||||
|
||||
struct _MetaAltTabHandlerDefault {
|
||||
GObject parent_instance;
|
||||
|
||||
MetaScreen *screen;
|
||||
|
||||
GArray *entries;
|
||||
gboolean immediate_mode;
|
||||
|
||||
MetaTabPopup *tab_popup;
|
||||
};
|
||||
|
||||
struct _MetaAltTabHandlerDefaultClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
};
|
||||
|
||||
GType meta_alt_tab_handler_default_get_type (void);
|
||||
|
||||
#endif
|
||||
|
@@ -58,6 +58,7 @@ item(_MUTTER_RESTART_MESSAGE)
|
||||
item(_MUTTER_RELOAD_THEME_MESSAGE)
|
||||
item(_MUTTER_SET_KEYBINDINGS_MESSAGE)
|
||||
item(_MUTTER_TOGGLE_VERBOSE)
|
||||
item(_MUTTER_HINTS)
|
||||
item(_GNOME_WM_KEYBINDINGS)
|
||||
item(_GNOME_PANEL_ACTION)
|
||||
item(_GNOME_PANEL_ACTION_MAIN_MENU)
|
||||
|
@@ -24,9 +24,11 @@
|
||||
#ifndef META_BOXES_H
|
||||
#define META_BOXES_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include "common.h"
|
||||
|
||||
#define META_TYPE_RECTANGLE (meta_rectangle_get_type ())
|
||||
|
||||
typedef struct _MetaRectangle MetaRectangle;
|
||||
struct _MetaRectangle
|
||||
{
|
||||
@@ -70,6 +72,11 @@ struct _MetaEdge
|
||||
MetaEdgeType edge_type;
|
||||
};
|
||||
|
||||
GType meta_rectangle_get_type (void);
|
||||
|
||||
MetaRectangle *meta_rectangle_copy (const MetaRectangle *rect);
|
||||
void meta_rectangle_free (MetaRectangle *rect);
|
||||
|
||||
/* Output functions -- note that the output buffer had better be big enough:
|
||||
* rect_to_string: RECT_LENGTH
|
||||
* region_to_string: (RECT_LENGTH+strlen(separator_string)) *
|
||||
|
@@ -52,6 +52,7 @@ typedef enum
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_MENU_OP_NONE = 0,
|
||||
META_MENU_OP_DELETE = 1 << 0,
|
||||
META_MENU_OP_MINIMIZE = 1 << 1,
|
||||
META_MENU_OP_UNMAXIMIZE = 1 << 2,
|
||||
@@ -317,8 +318,10 @@ struct _MetaButtonLayout
|
||||
* coelesce multiple things together, the appropriate place to
|
||||
* do it is usually META_PRIORITY_BEFORE_REDRAW.
|
||||
*
|
||||
* (FIXME: Use a Clutter paint() function instead, to prevent
|
||||
* starving the repaints)
|
||||
* Note that its usually better to use meta_later_add() rather
|
||||
* than calling g_idle_add() directly; this will make sure things
|
||||
* get run when added from a clutter event handler without
|
||||
* waiting for another repaint cycle.
|
||||
*
|
||||
* If something has a priority lower than the redraw priority
|
||||
* (such as a default priority idle), then it may be arbitrarily
|
||||
|
@@ -30,29 +30,6 @@
|
||||
#include "window.h"
|
||||
#include "workspace.h"
|
||||
|
||||
typedef enum _MetaCompWindowType
|
||||
{
|
||||
META_COMP_WINDOW_NORMAL = META_WINDOW_NORMAL,
|
||||
META_COMP_WINDOW_DESKTOP = META_WINDOW_DESKTOP,
|
||||
META_COMP_WINDOW_DOCK = META_WINDOW_DOCK,
|
||||
META_COMP_WINDOW_DIALOG = META_WINDOW_DIALOG,
|
||||
META_COMP_WINDOW_MODAL_DIALOG = META_WINDOW_MODAL_DIALOG,
|
||||
META_COMP_WINDOW_TOOLBAR = META_WINDOW_TOOLBAR,
|
||||
META_COMP_WINDOW_MENU = META_WINDOW_MENU,
|
||||
META_COMP_WINDOW_UTILITY = META_WINDOW_UTILITY,
|
||||
META_COMP_WINDOW_SPLASHSCREEN = META_WINDOW_SPLASHSCREEN,
|
||||
|
||||
/* override redirect window types, */
|
||||
META_COMP_WINDOW_DROPDOWN_MENU = META_WINDOW_DROPDOWN_MENU,
|
||||
META_COMP_WINDOW_POPUP_MENU = META_WINDOW_POPUP_MENU,
|
||||
META_COMP_WINDOW_TOOLTIP = META_WINDOW_TOOLTIP,
|
||||
META_COMP_WINDOW_NOTIFICATION = META_WINDOW_NOTIFICATION,
|
||||
META_COMP_WINDOW_COMBO = META_WINDOW_COMBO,
|
||||
META_COMP_WINDOW_DND = META_WINDOW_DND,
|
||||
META_COMP_WINDOW_OVERRIDE_OTHER = META_WINDOW_OVERRIDE_OTHER
|
||||
|
||||
} MetaCompWindowType;
|
||||
|
||||
/**
|
||||
* MetaCompEffect:
|
||||
* @META_COMP_EFFECT_CREATE: The window is newly created
|
||||
|
@@ -116,6 +116,10 @@ void meta_core_user_focus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_core_lower_beneath_focus_window (Display *xdisplay,
|
||||
Window xwindow,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_core_minimize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_toggle_maximize (Display *xdisplay,
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "prefs.h"
|
||||
#include "common.h"
|
||||
|
||||
typedef enum
|
||||
@@ -81,6 +82,12 @@ gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
|
||||
int meta_display_get_damage_event_base (MetaDisplay *display);
|
||||
int meta_display_get_shape_event_base (MetaDisplay *display);
|
||||
Atom meta_display_get_atom (MetaDisplay *display, MetaAtom meta_atom);
|
||||
|
||||
gboolean meta_display_xserver_time_is_before (MetaDisplay *display,
|
||||
guint32 time1,
|
||||
guint32 time2);
|
||||
|
||||
guint32 meta_display_get_last_user_time (MetaDisplay *display);
|
||||
guint32 meta_display_get_current_time (MetaDisplay *display);
|
||||
guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display);
|
||||
|
||||
@@ -117,6 +124,10 @@ void meta_display_end_grab_op (MetaDisplay *display,
|
||||
|
||||
MetaGrabOp meta_display_get_grab_op (MetaDisplay *display);
|
||||
|
||||
MetaKeyBindingAction meta_display_get_keybinding_action (MetaDisplay *display,
|
||||
unsigned int keysym,
|
||||
unsigned int keycode,
|
||||
unsigned long mask);
|
||||
|
||||
/* meta_display_set_input_focus_window is like XSetInputFocus, except
|
||||
* that (a) it can't detect timestamps later than the current time,
|
||||
@@ -140,4 +151,9 @@ void meta_display_focus_the_no_focus_window (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
guint32 timestamp);
|
||||
|
||||
GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display,
|
||||
GSList *windows);
|
||||
|
||||
Window meta_display_get_leader_window (MetaDisplay *display);
|
||||
|
||||
#endif
|
||||
|
@@ -23,6 +23,10 @@
|
||||
#include "display.h"
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* MetaKeyHandlerFunc: (skip)
|
||||
*
|
||||
*/
|
||||
typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
|
@@ -32,19 +32,6 @@
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
/*
|
||||
* FIXME -- move these to a private include
|
||||
* Required by plugin manager.
|
||||
*/
|
||||
#define MUTTER_PLUGIN_MINIMIZE (1<<0)
|
||||
#define MUTTER_PLUGIN_MAXIMIZE (1<<1)
|
||||
#define MUTTER_PLUGIN_UNMAXIMIZE (1<<2)
|
||||
#define MUTTER_PLUGIN_MAP (1<<3)
|
||||
#define MUTTER_PLUGIN_DESTROY (1<<4)
|
||||
#define MUTTER_PLUGIN_SWITCH_WORKSPACE (1<<5)
|
||||
|
||||
#define MUTTER_PLUGIN_ALL_EFFECTS (~0)
|
||||
|
||||
#define MUTTER_TYPE_PLUGIN (mutter_plugin_get_type ())
|
||||
#define MUTTER_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_PLUGIN, MutterPlugin))
|
||||
#define MUTTER_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_PLUGIN, MutterPluginClass))
|
||||
@@ -52,7 +39,15 @@
|
||||
#define MUTTER_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_PLUGIN))
|
||||
#define MUTTER_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_PLUGIN, MutterPluginClass))
|
||||
|
||||
/**
|
||||
* MutterPlugin: (skip)
|
||||
*
|
||||
*/
|
||||
typedef struct _MutterPlugin MutterPlugin;
|
||||
/**
|
||||
* MutterPluginClass: (skip)
|
||||
*
|
||||
*/
|
||||
typedef struct _MutterPluginClass MutterPluginClass;
|
||||
typedef struct _MutterPluginVersion MutterPluginVersion;
|
||||
typedef struct _MutterPluginInfo MutterPluginInfo;
|
||||
@@ -69,6 +64,8 @@ struct _MutterPluginClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*start) (MutterPlugin *plugin);
|
||||
|
||||
void (*minimize) (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
@@ -93,20 +90,18 @@ struct _MutterPluginClass
|
||||
MutterWindow *actor);
|
||||
|
||||
void (*switch_workspace) (MutterPlugin *plugin,
|
||||
const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
/*
|
||||
* Called if an effect should be killed prematurely; the plugin must
|
||||
* Called if an effects should be killed prematurely; the plugin must
|
||||
* call the completed() callback as if the effect terminated naturally.
|
||||
* The events parameter is a bitmask indicating which effects are to be
|
||||
* killed.
|
||||
*/
|
||||
void (*kill_effect) (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gulong events);
|
||||
void (*kill_window_effects) (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
void (*kill_switch_workspace) (MutterPlugin *plugin);
|
||||
|
||||
/* General XEvent filter. This is fired *before* mutter itself handles
|
||||
* an event. Return TRUE to block any further processing.
|
||||
@@ -225,9 +220,27 @@ struct _MutterPluginVersion
|
||||
} \
|
||||
|
||||
void
|
||||
mutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event);
|
||||
mutter_plugin_switch_workspace_completed (MutterPlugin *plugin);
|
||||
|
||||
void
|
||||
mutter_plugin_minimize_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
void
|
||||
mutter_plugin_maximize_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
void
|
||||
mutter_plugin_unmaximize_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
void
|
||||
mutter_plugin_map_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
void
|
||||
mutter_plugin_destroy_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_overlay_group (MutterPlugin *plugin);
|
||||
|
@@ -59,7 +59,6 @@ struct _MutterWindow
|
||||
GType mutter_window_get_type (void);
|
||||
|
||||
Window mutter_window_get_x_window (MutterWindow *mcw);
|
||||
MetaCompWindowType mutter_window_get_window_type (MutterWindow *mcw);
|
||||
gint mutter_window_get_workspace (MutterWindow *mcw);
|
||||
gboolean mutter_window_is_hidden (MutterWindow *mcw);
|
||||
MetaWindow * mutter_window_get_meta_window (MutterWindow *mcw);
|
||||
|
@@ -34,6 +34,7 @@ typedef enum
|
||||
META_PREF_MOUSE_BUTTON_MODS,
|
||||
META_PREF_FOCUS_MODE,
|
||||
META_PREF_FOCUS_NEW_WINDOWS,
|
||||
META_PREF_ATTACH_MODAL_DIALOGS,
|
||||
META_PREF_RAISE_ON_CLICK,
|
||||
META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
|
||||
META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
|
||||
@@ -59,9 +60,11 @@ typedef enum
|
||||
META_PREF_CURSOR_SIZE,
|
||||
META_PREF_COMPOSITING_MANAGER,
|
||||
META_PREF_RESIZE_WITH_RIGHT_BUTTON,
|
||||
META_PREF_SIDE_BY_SIDE_TILING,
|
||||
META_PREF_FORCE_FULLSCREEN,
|
||||
META_PREF_CLUTTER_PLUGINS,
|
||||
META_PREF_LIVE_HIDDEN_WINDOWS,
|
||||
META_PREF_NO_TAB_POPUP,
|
||||
META_PREF_NO_TAB_POPUP
|
||||
} MetaPreference;
|
||||
|
||||
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
|
||||
@@ -73,6 +76,10 @@ void meta_prefs_remove_listener (MetaPrefsChangedFunc func,
|
||||
gpointer data);
|
||||
|
||||
void meta_prefs_init (void);
|
||||
|
||||
void meta_prefs_override_preference_location (const char *original_key,
|
||||
const char *new_key);
|
||||
|
||||
const char* meta_preference_to_string (MetaPreference pref);
|
||||
|
||||
MetaVirtualModifier meta_prefs_get_mouse_button_mods (void);
|
||||
@@ -80,6 +87,7 @@ guint meta_prefs_get_mouse_button_resize (void);
|
||||
guint meta_prefs_get_mouse_button_menu (void);
|
||||
MetaFocusMode meta_prefs_get_focus_mode (void);
|
||||
MetaFocusNewWindows meta_prefs_get_focus_new_windows (void);
|
||||
gboolean meta_prefs_get_attach_modal_dialogs (void);
|
||||
gboolean meta_prefs_get_raise_on_click (void);
|
||||
const char* meta_prefs_get_theme (void);
|
||||
/* returns NULL if GTK default should be used */
|
||||
@@ -91,6 +99,7 @@ gboolean meta_prefs_get_auto_raise (void);
|
||||
int meta_prefs_get_auto_raise_delay (void);
|
||||
gboolean meta_prefs_get_gnome_accessibility (void);
|
||||
gboolean meta_prefs_get_gnome_animations (void);
|
||||
gboolean meta_prefs_get_side_by_side_tiling (void);
|
||||
|
||||
const char* meta_prefs_get_command (int i);
|
||||
|
||||
@@ -115,6 +124,7 @@ void meta_prefs_change_workspace_name (int i,
|
||||
const char* meta_prefs_get_cursor_theme (void);
|
||||
int meta_prefs_get_cursor_size (void);
|
||||
gboolean meta_prefs_get_compositing_manager (void);
|
||||
gboolean meta_prefs_get_force_fullscreen (void);
|
||||
|
||||
/**
|
||||
* Sets whether the compositor is turned on.
|
||||
@@ -123,6 +133,8 @@ gboolean meta_prefs_get_compositing_manager (void);
|
||||
*/
|
||||
void meta_prefs_set_compositing_manager (gboolean whether);
|
||||
|
||||
void meta_prefs_set_force_fullscreen (gboolean whether);
|
||||
|
||||
GSList * meta_prefs_get_clutter_plugins (void);
|
||||
|
||||
/**
|
||||
|
60
src/include/region.h
Normal file
60
src/include/region.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef META_REGION_H
|
||||
#define META_REGION_H
|
||||
|
||||
#ifndef PACKAGE_NAME
|
||||
#error "<config.h> must be included before region.h"
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#ifdef USE_CAIRO_REGION
|
||||
#include <cairo.h>
|
||||
|
||||
#define MetaRegion cairo_region_t
|
||||
|
||||
typedef enum {
|
||||
META_REGION_OVERLAP_IN = CAIRO_REGION_OVERLAP_IN,
|
||||
META_REGION_OVERLAP_OUT = CAIRO_REGION_OVERLAP_OUT,
|
||||
META_REGION_OVERLAP_PART = CAIRO_REGION_OVERLAP_PART
|
||||
} MetaOverlapType;
|
||||
|
||||
#define meta_region_new() cairo_region_create()
|
||||
#define meta_region_new_from_rectangle(rect) cairo_region_create_rectangle(rect)
|
||||
#define meta_region_copy(r) cairo_region_copy(r)
|
||||
#define meta_region_destroy(r) cairo_region_destroy(r)
|
||||
#define meta_region_is_empty(r) cairo_region_is_empty(r)
|
||||
#define meta_region_union_rectangle(r, rect) cairo_region_union_rectangle(r, rect)
|
||||
#define meta_region_subtract(r, other) cairo_region_subtract(r, other)
|
||||
#define meta_region_translate(r, x, y) cairo_region_translate(r, x, y)
|
||||
#define meta_region_intersect(r, other) cairo_region_intersect(r, other)
|
||||
#define meta_region_contains_rectangle(r, rect) cairo_region_contains_rectangle(r, rect)
|
||||
|
||||
void meta_region_get_rectangles (MetaRegion *region,
|
||||
GdkRectangle **rectangles,
|
||||
int *n_rectangles);
|
||||
|
||||
#else
|
||||
|
||||
#define MetaRegion GdkRegion
|
||||
|
||||
typedef enum {
|
||||
META_REGION_OVERLAP_IN = GDK_OVERLAP_RECTANGLE_IN,
|
||||
META_REGION_OVERLAP_OUT = GDK_OVERLAP_RECTANGLE_OUT,
|
||||
META_REGION_OVERLAP_PART = GDK_OVERLAP_RECTANGLE_PART
|
||||
} MetaOverlapType;
|
||||
|
||||
#define meta_region_new() gdk_region_new()
|
||||
#define meta_region_new_from_rectangle(rect) gdk_region_rectangle(rect)
|
||||
#define meta_region_copy(r) gdk_region_copy(r)
|
||||
#define meta_region_destroy(r) gdk_region_destroy(r)
|
||||
#define meta_region_is_empty(r) gdk_region_empty(r)
|
||||
#define meta_region_union_rectangle(r, rect) gdk_region_union_with_rect(r, rect)
|
||||
#define meta_region_subtract(r, other) gdk_region_subtract(r, other)
|
||||
#define meta_region_translate(r, x, y) gdk_region_offset(r, x, y)
|
||||
#define meta_region_intersect(r, other) gdk_region_intersect(r, other)
|
||||
#define meta_region_contains_rectangle(r, rect) gdk_region_rect_in(r, rect)
|
||||
#define meta_region_get_rectangles(r, rects, num) gdk_region_get_rectangles(r, rects, num)
|
||||
|
||||
#endif /* HAVE_CAIRO_REGION */
|
||||
|
||||
#endif /* META_REGION_H */
|
39
src/include/tile-preview.h
Normal file
39
src/include/tile-preview.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Meta tile preview */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010 Florian Müllner
|
||||
*
|
||||
* 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_TILE_PREVIEW_H
|
||||
#define META_TILE_PREVIEW_H
|
||||
|
||||
#include "boxes.h"
|
||||
|
||||
typedef struct _MetaTilePreview MetaTilePreview;
|
||||
|
||||
MetaTilePreview *meta_tile_preview_new (int screen_number,
|
||||
gboolean composited);
|
||||
void meta_tile_preview_free (MetaTilePreview *preview);
|
||||
void meta_tile_preview_show (MetaTilePreview *preview,
|
||||
MetaRectangle *rect);
|
||||
void meta_tile_preview_hide (MetaTilePreview *preview);
|
||||
Window meta_tile_preview_get_xwindow (MetaTilePreview *preview,
|
||||
gulong *create_serial);
|
||||
|
||||
#endif /* META_TILE_PREVIEW_H */
|
@@ -22,12 +22,20 @@
|
||||
#ifndef META_TYPES_H
|
||||
#define META_TYPES_H
|
||||
|
||||
/**
|
||||
* MetaCompositor: (skip)
|
||||
*
|
||||
*/
|
||||
typedef struct _MetaCompositor MetaCompositor;
|
||||
typedef struct _MetaDisplay MetaDisplay;
|
||||
typedef struct _MetaFrame MetaFrame;
|
||||
typedef struct _MetaScreen MetaScreen;
|
||||
typedef struct _MetaWindow MetaWindow;
|
||||
typedef struct _MetaWorkspace MetaWorkspace;
|
||||
/**
|
||||
* MetaGroup: (skip)
|
||||
*
|
||||
*/
|
||||
typedef struct _MetaGroup MetaGroup;
|
||||
typedef struct _MetaKeyBinding MetaKeyBinding;
|
||||
|
||||
|
@@ -33,8 +33,6 @@
|
||||
|
||||
typedef struct _MetaUI MetaUI;
|
||||
|
||||
typedef struct _MetaImageWindow MetaImageWindow;
|
||||
|
||||
typedef gboolean (* MetaEventFunc) (XEvent *xevent, gpointer data);
|
||||
|
||||
typedef enum
|
||||
@@ -132,34 +130,10 @@ void meta_ui_window_menu_popup (MetaWindowMenu *menu,
|
||||
void meta_ui_window_menu_free (MetaWindowMenu *menu);
|
||||
|
||||
|
||||
MetaImageWindow* meta_image_window_new (Display *xdisplay,
|
||||
int screen_number,
|
||||
int max_width,
|
||||
int max_height);
|
||||
void meta_image_window_free (MetaImageWindow *iw);
|
||||
void meta_image_window_set_showing (MetaImageWindow *iw,
|
||||
gboolean showing);
|
||||
void meta_image_window_set (MetaImageWindow *iw,
|
||||
GdkPixbuf *pixbuf,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
/* FIXME these lack a display arg */
|
||||
GdkPixbuf* meta_gdk_pixbuf_get_from_window (GdkPixbuf *dest,
|
||||
Window xwindow,
|
||||
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (GdkPixbuf *dest,
|
||||
Pixmap xpixmap,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
@@ -200,8 +174,7 @@ int meta_ui_get_drag_threshold (MetaUI *ui);
|
||||
|
||||
MetaUIDirection meta_ui_get_direction (void);
|
||||
|
||||
GdkPixbuf *meta_ui_get_pixbuf_from_pixmap (Pixmap pmap);
|
||||
|
||||
#include "tabpopup.h"
|
||||
#include "tile-preview.h"
|
||||
|
||||
#endif
|
||||
|
@@ -51,6 +51,7 @@ void meta_fatal (const char *format,
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_DEBUG_VERBOSE = -1,
|
||||
META_DEBUG_FOCUS = 1 << 0,
|
||||
META_DEBUG_WORKAREA = 1 << 1,
|
||||
META_DEBUG_STACK = 1 << 2,
|
||||
@@ -78,6 +79,8 @@ typedef enum
|
||||
void meta_topic_real (MetaDebugTopic topic,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF (2, 3);
|
||||
void meta_add_verbose_topic (MetaDebugTopic topic);
|
||||
void meta_remove_verbose_topic (MetaDebugTopic topic);
|
||||
|
||||
void meta_push_no_msg_prefix (void);
|
||||
void meta_pop_no_msg_prefix (void);
|
||||
@@ -131,35 +134,25 @@ GPid meta_show_dialog (const char *type,
|
||||
|
||||
#endif /* !WITH_VERBOSE_MODE */
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#define META_TYPE_NEXUS (meta_nexus_get_type ())
|
||||
#define META_NEXUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_NEXUS, MetaNexus))
|
||||
#define META_NEXUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_NEXUS, MetaNexusClass))
|
||||
#define META_IS_NEXUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_NEXUS))
|
||||
#define META_IS_NEXUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_NEXUS))
|
||||
#define META_NEXUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_NEXUS, MetaNexusClass))
|
||||
|
||||
typedef struct _MetaNexus
|
||||
{
|
||||
GObject parent_instance;
|
||||
} MetaNexus;
|
||||
|
||||
typedef struct _MetaNexusClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
} MetaNexusClass;
|
||||
|
||||
GType meta_nexus_get_type (void) G_GNUC_CONST;
|
||||
MetaNexus *meta_nexus_new ();
|
||||
|
||||
/**
|
||||
* An object which exists purely to attach signals to; this is to receive
|
||||
* signals when a child process exits. The signal is "sigchld" with no detail.
|
||||
*
|
||||
* \bug Eventually we should have a specialised type for objects like these.
|
||||
*/
|
||||
extern MetaNexus *sigchld_nexus;
|
||||
* MetaLaterType:
|
||||
* @META_LATER_RESIZE: call in a resize processing phase that is done
|
||||
* before GTK+ repainting (including window borders) is done.
|
||||
* @META_LATER_BEFORE_REDRAW: call before the stage is redrawn
|
||||
* @META_LATER_IDLE: call at a very low priority (can be blocked
|
||||
* by running animations or redrawing applications)
|
||||
**/
|
||||
typedef enum {
|
||||
META_LATER_RESIZE,
|
||||
META_LATER_BEFORE_REDRAW,
|
||||
META_LATER_IDLE
|
||||
} MetaLaterType;
|
||||
|
||||
guint meta_later_add (MetaLaterType when,
|
||||
GSourceFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
void meta_later_remove (guint later_id);
|
||||
|
||||
#endif /* META_UTIL_H */
|
||||
|
||||
|
@@ -88,9 +88,13 @@ void meta_window_activate_with_workspace (MetaWindow *window,
|
||||
MetaWorkspace *workspace);
|
||||
const char * meta_window_get_description (MetaWindow *window);
|
||||
const char * meta_window_get_wm_class (MetaWindow *window);
|
||||
const char * meta_window_get_wm_class_instance (MetaWindow *window);
|
||||
/* Return whether the window would be showing if we were on its workspace */
|
||||
gboolean meta_window_showing_on_its_workspace (MetaWindow *window);
|
||||
|
||||
void meta_window_set_demands_attention (MetaWindow *window);
|
||||
void meta_window_unset_demands_attention (MetaWindow *window);
|
||||
|
||||
const char* meta_window_get_startup_id (MetaWindow *window);
|
||||
void meta_window_change_workspace_by_index (MetaWindow *window,
|
||||
gint space_index,
|
||||
@@ -104,6 +108,17 @@ MetaStackLayer meta_window_get_layer (MetaWindow *window);
|
||||
MetaWindow* meta_window_find_root_ancestor (MetaWindow *window);
|
||||
gboolean meta_window_is_ancestor_of_transient (MetaWindow *window,
|
||||
MetaWindow *transient);
|
||||
|
||||
typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window,
|
||||
void *data);
|
||||
|
||||
void meta_window_foreach_transient (MetaWindow *window,
|
||||
MetaWindowForeachFunc func,
|
||||
void *user_data);
|
||||
void meta_window_foreach_ancestor (MetaWindow *window,
|
||||
MetaWindowForeachFunc func,
|
||||
void *user_data);
|
||||
|
||||
gboolean meta_window_is_mapped (MetaWindow *window);
|
||||
gboolean meta_window_toplevel_is_mapped (MetaWindow *window);
|
||||
gboolean meta_window_get_icon_geometry (MetaWindow *window,
|
||||
@@ -114,12 +129,18 @@ void meta_window_unmaximize (MetaWindow *window,
|
||||
MetaMaximizeFlags directions);
|
||||
void meta_window_minimize (MetaWindow *window);
|
||||
void meta_window_unminimize (MetaWindow *window);
|
||||
void meta_window_raise (MetaWindow *window);
|
||||
void meta_window_lower (MetaWindow *window);
|
||||
const char *meta_window_get_title (MetaWindow *window);
|
||||
MetaWindow *meta_window_get_transient_for (MetaWindow *window);
|
||||
Window meta_window_get_transient_for_as_xid (MetaWindow *window);
|
||||
void meta_window_delete (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
guint meta_window_get_stable_sequence (MetaWindow *window);
|
||||
guint32 meta_window_get_user_time (MetaWindow *window);
|
||||
int meta_window_get_pid (MetaWindow *window);
|
||||
const char *meta_window_get_client_machine (MetaWindow *window);
|
||||
gboolean meta_window_is_remote (MetaWindow *window);
|
||||
gboolean meta_window_is_modal (MetaWindow *window);
|
||||
const char *meta_window_get_mutter_hints (MetaWindow *window);
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user