Compare commits
741 Commits
3.23.90
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
9a13882a95 | |||
4f6a3cd874 | |||
59e89f0d63 | |||
8ec46e8021 | |||
92ce68d257 | |||
ff79e651f0 | |||
0f9b388526 | |||
d7cb3da324 | |||
ca654ac544 | |||
6e3b0eb430 | |||
3483cc8831 | |||
798026498d | |||
49f029571c | |||
290b257288 | |||
2b60fb0144 | |||
7f5f5eb847 | |||
44269e6a1d | |||
70dfe8c97d | |||
072afa5fa3 | |||
519a0fd93d | |||
5f132f3975 | |||
1546989845 | |||
1923db97c1 | |||
db32047a5d | |||
b505eb261e | |||
1a1db9ef8d | |||
b1587f0716 | |||
93e450f37c | |||
fc713ecb70 | |||
500c13ab6f | |||
050267fe74 | |||
ce25a0171c | |||
b7518c8651 | |||
62dedfbef3 | |||
4508978ea5 | |||
c533a06e93 | |||
5d3b4f0134 | |||
4cf340ae9b | |||
053ac03f01 | |||
28a9439209 | |||
cf4b5efdd1 | |||
3067dab84c | |||
1790320ba3 | |||
f45df4265d | |||
bcbcd6a68c | |||
b1a0bf8916 | |||
6c18bae83c | |||
d0531966eb | |||
989a47ee8c | |||
03be6b687b | |||
32c22d375a | |||
bdf3f49a82 | |||
356b4b0dc5 | |||
3fc2ea8297 | |||
06d976e853 | |||
96ebd1c214 | |||
fa28481736 | |||
76b064cffc | |||
333b5d12a0 | |||
aa73504d95 | |||
32305b453d | |||
7d5e08c843 | |||
dc0fc65229 | |||
428af6d213 | |||
2ffe597617 | |||
0461eed0cb | |||
ca1bacc212 | |||
2229365ca8 | |||
8c367364b6 | |||
58909da425 | |||
ff32bf467c | |||
c5572d3095 | |||
e706bcdf73 | |||
d9ebcbd55c | |||
240b13aa74 | |||
97635d6f84 | |||
6c21a22e4d | |||
0add6f62b6 | |||
049418cd03 | |||
3ee1999c70 | |||
e4b8920688 | |||
eb236649fc | |||
0a36a4545f | |||
180985018b | |||
c86c5d6905 | |||
c2fad2dc7c | |||
1196b7bde4 | |||
19eddfd756 | |||
ed280ef4ac | |||
b6200ac3ff | |||
626621a53a | |||
fb3a64491e | |||
294f9419f7 | |||
a37956c95f | |||
89f5ca3301 | |||
07745b3082 | |||
054c25f693 | |||
01de04d8c9 | |||
08e4cb54a8 | |||
c71faffb71 | |||
91e3a0b3a9 | |||
5fa8f78434 | |||
ab5ac21104 | |||
0ebea2be9c | |||
6f54bab0a8 | |||
5d7deab6da | |||
35fcf4a4ae | |||
74565380aa | |||
fa37496ffb | |||
cc772ddd61 | |||
4d2647cdbc | |||
3caefd8fda | |||
12381d57d1 | |||
4ad8c4b86b | |||
dbd2827ca1 | |||
1a78557e0b | |||
2e99963087 | |||
4d763e1828 | |||
a17b343c21 | |||
556136dacc | |||
a8c80ccece | |||
f044511037 | |||
b31e545c9d | |||
fad5657eda | |||
eaf9ccde39 | |||
f9c625924e | |||
64cb735abf | |||
c85f322b20 | |||
76096a725b | |||
6eb7d13894 | |||
7928b25ebf | |||
78e6258b44 | |||
c9259c2b15 | |||
492d2eb573 | |||
376dcd3b92 | |||
60781bc6c2 | |||
2d8827cb0c | |||
802f7dcd30 | |||
e62cfd9043 | |||
cbcf6a4f23 | |||
b0e42d3f6e | |||
18eb66de06 | |||
b32cccddf9 | |||
362e26b3e2 | |||
5c53284bde | |||
e45d7f70e8 | |||
70edc7dda4 | |||
3244ed37a9 | |||
406359bba1 | |||
8b23dd915f | |||
7e1f65405f | |||
c1683073f1 | |||
18ec86bd90 | |||
315a6f43d7 | |||
7603bb5fd5 | |||
d53b79f8c3 | |||
f534452c6a | |||
0f6b83e7df | |||
16a6aef5a7 | |||
518fb9fb5e | |||
547ace3cf8 | |||
a4ba38ee78 | |||
e32d52b9b8 | |||
de40ced8b4 | |||
cfee58798e | |||
7ea01693a7 | |||
e0d839aea2 | |||
d3efd73429 | |||
2db5505216 | |||
f44b6c772a | |||
f64fab1d2d | |||
39bc2e0333 | |||
5bb6f0ad8b | |||
903537a2a0 | |||
1db937826c | |||
c1fe1c5d6b | |||
a62e9f99a2 | |||
9817a6aa47 | |||
8185373bd4 | |||
18c41aefc9 | |||
32917f1922 | |||
7a843e1fd1 | |||
0e154ccf76 | |||
120db06c60 | |||
e76ab05d45 | |||
43eeb009ce | |||
9000eef49d | |||
e198c8452b | |||
aea66ddff6 | |||
a5f4ffa58c | |||
a1c39e142d | |||
e76a0f564c | |||
8307d9c4de | |||
1dbf6b096b | |||
6fe71ecc01 | |||
57e58eaf2a | |||
00a5db71cf | |||
c7fa57cd28 | |||
8f2c86d79e | |||
56f1da5c66 | |||
30a205c0e3 | |||
98d77d37d0 | |||
0853fb940a | |||
6dd819a61e | |||
39aae19ed7 | |||
20749e5dbd | |||
99e1cd549d | |||
efdbeb7c1b | |||
ea4dbd14bc | |||
838df4b00b | |||
b6110ba8dc | |||
fd763ad857 | |||
e3d59832c5 | |||
2c85bb4178 | |||
8493777961 | |||
4e7405aca9 | |||
34207ba509 | |||
6dc499f305 | |||
92e2242cf0 | |||
ea214fbe0f | |||
487b8a0430 | |||
8b060342bd | |||
27d6c063ad | |||
0e62b71959 | |||
2c3f79829e | |||
5d2b0bc0cc | |||
7e3a780dcd | |||
1035200f26 | |||
8532b10290 | |||
f0c6c4eb1f | |||
ba194bd19e | |||
a35274ddb7 | |||
ab541e3e0f | |||
67ce04993e | |||
22cdc8f414 | |||
8b022a5595 | |||
7a1393ba26 | |||
5ed954e6de | |||
96572fbe6a | |||
4ab47e72e5 | |||
70e0fd0b45 | |||
26cd031be8 | |||
743e8cc249 | |||
2bf7974076 | |||
9c16e4e2f3 | |||
07f6c85cc7 | |||
d4968e10e5 | |||
bd3817198e | |||
5b5737f65e | |||
5af8753171 | |||
8bef74f441 | |||
f1a42b0f97 | |||
95682a9494 | |||
ef41867303 | |||
8d4b03ce87 | |||
06263354a5 | |||
aa30e11c8b | |||
65bca8e008 | |||
068791f6c1 | |||
cbc4563b30 | |||
f381d7c3bf | |||
0a8d8128b3 | |||
46135d4f0f | |||
7ba44e7945 | |||
dd4ad4efc4 | |||
807658e972 | |||
8499a29d0a | |||
283eedef90 | |||
ce515c5389 | |||
83440614bc | |||
a93661f9e1 | |||
216f7631de | |||
361bf847af | |||
46f54eb3d9 | |||
bc47c6cc4f | |||
8bfdfa1f46 | |||
999542c915 | |||
cb38e9c4a2 | |||
42c56c2460 | |||
e2d904c32b | |||
fa9c09feee | |||
3f6a2d02fd | |||
5b37901b57 | |||
2df4ccd1cd | |||
dcd15e6145 | |||
2a318eb3f2 | |||
522eec00cd | |||
be11c32815 | |||
24c91d95de | |||
7562eb6006 | |||
0aa7405a2a | |||
a119e58773 | |||
8a32b42172 | |||
94a15404da | |||
fefede5b51 | |||
5be00f23be | |||
bdbd2e96de | |||
7785a57f8a | |||
cf01e26b2f | |||
6e46ad9f3a | |||
921b18f713 | |||
53175e8788 | |||
920541fa26 | |||
9d8922764c | |||
97f2c7c161 | |||
38235bc145 | |||
3ce3a5a952 | |||
3005a400ca | |||
34e7134db2 | |||
12710dc644 | |||
a10ad577a7 | |||
d3c559a917 | |||
1e7628a3ef | |||
d5a85997f2 | |||
5a37e0e1ef | |||
00f6a74397 | |||
c9439107c1 | |||
ba65664cbd | |||
3da0730a31 | |||
98fcd616a3 | |||
06d0989014 | |||
c248feb3c1 | |||
3f2c5ca9bd | |||
520c56fe53 | |||
d3a670b043 | |||
6eca267eee | |||
fdefe776d3 | |||
bba8776184 | |||
e075242801 | |||
0f9686fb5a | |||
168479862d | |||
483ed98777 | |||
14fe6e9c95 | |||
6584d06bb5 | |||
92a53f08f4 | |||
a81d4aed7a | |||
517488ef67 | |||
33f1706634 | |||
5685449e15 | |||
a6d67b164a | |||
f950380202 | |||
a4270fa7ac | |||
35c9280fb6 | |||
8b92ad1d4b | |||
0d6e3fd675 | |||
b140e7fbeb | |||
6c0f107db0 | |||
61950755ec | |||
bc3162460f | |||
27a4f9f862 | |||
88f2441330 | |||
ab04286c6b | |||
e8a62861c9 | |||
9ac87b36c1 | |||
ce7819949f | |||
12792f99a0 | |||
66996dee4b | |||
2f45e88f06 | |||
c1439e141e | |||
dceb0f1f1f | |||
a7915ff8ae | |||
420a712ad5 | |||
9a47e5c832 | |||
dbc63430d8 | |||
0f861cecac | |||
586f9666d7 | |||
05a2331052 | |||
9f8bee7781 | |||
d9505315da | |||
c9937faf1e | |||
98606bc046 | |||
49096f0530 | |||
ff6eb86bb4 | |||
c735eab216 | |||
299aa9759c | |||
35e9020f4c | |||
6d4234e300 | |||
0457870ff1 | |||
a52c4c2795 | |||
bb8c388a37 | |||
46cb506f8f | |||
ce20c964a6 | |||
e3f76e9482 | |||
b894fbd9ff | |||
2ca0871724 | |||
dd12f569d9 | |||
c54377e3ba | |||
346acaf7f6 | |||
3343a199c2 | |||
1fb3c9f8bf | |||
b7b5fb293d | |||
1455c402b9 | |||
4c1fe4c30d | |||
9b97a44760 | |||
26fa7b8f6a | |||
7486783692 | |||
9929efb65e | |||
5db48faca4 | |||
b0c54b6675 | |||
d8354cb153 | |||
9a348aa859 | |||
fe6e24ddbd | |||
7e330bd65f | |||
3f9c5823cb | |||
2bdd97e067 | |||
32fd1e8c08 | |||
e126b6ed16 | |||
4d8cb5408b | |||
f852d2b0eb | |||
5c3b27d02f | |||
ead6556b50 | |||
4afa66fe41 | |||
408292959e | |||
2d8d9dea97 | |||
f38c90961a | |||
aa47374d0e | |||
5aee5048ba | |||
0e3f80d238 | |||
ef13ee4488 | |||
8b5d34b24a | |||
c614a2db28 | |||
7360f51ee8 | |||
6ae42f3845 | |||
26b66826dc | |||
6d082bf442 | |||
aad2280309 | |||
e3d5bc077d | |||
777963eeb6 | |||
4cc5b25493 | |||
49c5228655 | |||
85638c1b19 | |||
2507e53d04 | |||
a9c1c6d9fb | |||
0a8e108f10 | |||
859b01fc39 | |||
e42206cc43 | |||
41eea5a942 | |||
197401fbf8 | |||
9ab338d7b6 | |||
aa5d8ac68c | |||
0adc56779f | |||
67eb289a6a | |||
dfc4d0d523 | |||
5f2bb43061 | |||
fef81cd628 | |||
3e8d0204bd | |||
b2a530b326 | |||
5ab116a87f | |||
10b0351a59 | |||
b64c69e4bc | |||
c2e49f1bb5 | |||
a3d63d0ac0 | |||
88cae8bd3d | |||
a6ec2b1d42 | |||
ca600973ba | |||
4b8dd51c4d | |||
56c468a2ef | |||
10b30eaba5 | |||
328e3f8f4f | |||
7bd69f0b32 | |||
538e402d71 | |||
9af6ec78ab | |||
41e22ab592 | |||
1303c626b1 | |||
7eea82d3d7 | |||
80e5955918 | |||
ce989976fa | |||
529e5adb2e | |||
a70ae50ca9 | |||
74882b2502 | |||
5f49bda591 | |||
edab8c3a4c | |||
8153c5b544 | |||
a4cef8586c | |||
9b9bb9cf86 | |||
dc5b2e396c | |||
d23275bc76 | |||
48e820235e | |||
2d3c56b089 | |||
85b2e59e7e | |||
e1950ed76f | |||
7938f41c11 | |||
9f41bdb086 | |||
8457e2bad6 | |||
4d7329a7e2 | |||
b4120a75e0 | |||
b19e4592df | |||
e9c9ee844c | |||
f5f0ff0a2f | |||
68dacb531b | |||
dd82f4afcd | |||
fc010e0edc | |||
5132ea64be | |||
82325cbcfd | |||
fb5ebffb8d | |||
94d843b80e | |||
c32e2d17d9 | |||
2b05748d5c | |||
cd775929bf | |||
7303a78b06 | |||
07b8cc0773 | |||
1bb0e18042 | |||
05bc2e2331 | |||
3b097c7e77 | |||
0bc312a54b | |||
2718699ccc | |||
be175558c3 | |||
df39a7d0fd | |||
43cdf81f6b | |||
183f4b0c13 | |||
38a772bce7 | |||
dd451547a5 | |||
270da95cbc | |||
76198e0b3b | |||
efc190789f | |||
81e99c2680 | |||
755755a2f3 | |||
4b23eb064c | |||
498200776c | |||
27b949d6ba | |||
27ea62a79d | |||
cf1edff9ed | |||
5cb5baa7d4 | |||
d620189ae3 | |||
bc041e02b3 | |||
4b4c2b1afa | |||
05d15f8885 | |||
561d71b8ae | |||
177e47952a | |||
374bb630f0 | |||
fe5138dfc4 | |||
68a9675d42 | |||
020e0bb2ac | |||
b47de58edd | |||
24195d8d15 | |||
3a7c37c60a | |||
c69d5d978c | |||
2f30098ab5 | |||
e146428038 | |||
5758401443 | |||
f241bdba93 | |||
410d66ca37 | |||
f2309cdb55 | |||
3887d25dbc | |||
d6d01c85a6 | |||
d0bfb94ff0 | |||
2b1537cdf5 | |||
d3362a6f05 | |||
9cf8aa4584 | |||
c76eedd794 | |||
9131f26cae | |||
8ed0dda40d | |||
0fd9e38175 | |||
891cab3bb3 | |||
454bd88d27 | |||
3ced749c89 | |||
69b6479502 | |||
a641b59f22 | |||
704bd4c331 | |||
229ac9c9dc | |||
e435cf301f | |||
0608ae2d4e | |||
3f107da479 | |||
813de50eba | |||
a4cb1f0f7a | |||
612432ac3e | |||
47a01013b1 | |||
69e7ad4402 | |||
c214eb15bf | |||
e6eac46629 | |||
de61da16ae | |||
bdcb395b33 | |||
1caa7f7627 | |||
5b4a96e3a3 | |||
15dd23a323 | |||
04d7fcf60d | |||
9755cd469c | |||
1bdadfa3e1 | |||
20fcb88632 | |||
6791d1b8e2 | |||
6c8b103a7b | |||
95d0117784 | |||
740436ab4d | |||
89fbf1e1d2 | |||
c391cefd71 | |||
52af529950 | |||
c30cb069f5 | |||
99a0b43f28 | |||
af4017de49 | |||
d804ecbd95 | |||
1ad3382bff | |||
9787b1cfd5 | |||
0ac2eba4d3 | |||
17c54c6e03 | |||
dd14e1cebc | |||
1e2266aa47 | |||
472a434212 | |||
7c226462e0 | |||
93c6a869ec | |||
9d914091f5 | |||
afcc1bf512 | |||
8a29c51b73 | |||
d38c4c1f2d | |||
2091df3856 | |||
744b4dcb7c | |||
0c64c35a8a | |||
57acbc53fb | |||
ac68631f4c | |||
8163ca6821 | |||
094e0356e8 | |||
63450d69d3 | |||
0952409de4 | |||
1c54c7a1bb | |||
f25f14351c | |||
691e7951ea | |||
7eaeba520a | |||
9a5b94a340 | |||
079b125430 | |||
770a5a5bff | |||
0548c9e7d5 | |||
68a6cc5976 | |||
2035f2f2e2 | |||
1892a6b0c4 | |||
b464004bb3 | |||
ea4438284f | |||
d050fdb17f | |||
9003a42df3 | |||
9e8ee491e6 | |||
3b46345db4 | |||
6b2a111428 | |||
bc56971e18 | |||
fcc0288f0c | |||
4e03e89869 | |||
4e17017501 | |||
63bc86cd43 | |||
ee32ca3efe | |||
a393a614a1 | |||
753e9c65a1 | |||
409c92a68f | |||
53a93deafc | |||
3a374a6db5 | |||
aec4b4af97 | |||
2392432780 | |||
0d5274b3b7 | |||
42c0809216 | |||
420311b463 | |||
efae039ad9 | |||
e60dfd5b23 | |||
df45c50d0b | |||
8f691c28f3 | |||
a77da353f3 | |||
70a4f59960 | |||
ac813d5285 | |||
5d3e7d6ffd | |||
5b378ea648 | |||
ea04ff5d46 | |||
982ad7361b | |||
10dfe2059b | |||
61e9594f63 | |||
2d8eaa082f | |||
29b240e883 | |||
e081bb3921 | |||
ad24967d78 | |||
90d83b4bb9 | |||
eb3ff3f44a | |||
db14e6099e | |||
5aa02c0378 | |||
73b2b30a1d | |||
cf6b7bcb79 | |||
4b86af839f | |||
f434f88c0c | |||
cdedd017d6 | |||
a48c9d6cd9 | |||
1039386e10 | |||
944339f6a5 | |||
4cfcd4bce0 | |||
4f386e5131 | |||
3ace913aed | |||
8f2daed9e0 | |||
c5dc0f4a2e | |||
615587cd06 | |||
df068a3649 | |||
7967ceee98 | |||
979bc4390a | |||
e20e60783a | |||
38c5a1610e | |||
572610d01e | |||
21b2eff334 | |||
35388fb33c | |||
aa5738c777 | |||
f7ffb1790f | |||
65e9c89ed9 | |||
5fafaf92df | |||
4e4b24e7a8 | |||
542ed1d024 | |||
eda0f45ab5 | |||
4fdc551209 | |||
58043cbc8b | |||
09fa27cd09 | |||
d8ee96c6cb | |||
3821ed162b | |||
1f20e82a96 | |||
1079850621 | |||
aab5f7c42b | |||
f8a6c27791 | |||
95e9fa10ef | |||
89871e04aa | |||
1705a26fc7 | |||
95c924460a | |||
97b1a8dfc8 | |||
fbcc8fae77 | |||
3d2cb7f1ef | |||
fc9a24824a | |||
383ba566bd | |||
d200868459 | |||
690b232258 | |||
e078838774 | |||
1b03dd6704 | |||
1171c4f16d | |||
a9f139cab6 | |||
5ba38a4ab6 | |||
8f5a0ec83d | |||
bb2e8ff09a | |||
1fe10f09d7 | |||
328b4d24c6 | |||
4b2d4a0169 | |||
3564b5845e | |||
2907b234c9 | |||
e1ffe15d94 | |||
1b0a3f11f9 | |||
b202f5d094 | |||
cd5c52b550 | |||
46d516cb04 | |||
4d0a886c45 | |||
5db3eebfbb | |||
36ee6f656a | |||
966725fcb4 | |||
90923903ae | |||
191525cdb4 | |||
2d18b18fe5 | |||
ead62f1901 |
8
.gitignore
vendored
8
.gitignore
vendored
@ -55,6 +55,7 @@ mutter-restart-helper
|
||||
mutter-test-client
|
||||
mutter-test-runner
|
||||
mutter-test-unit-tests
|
||||
mutter-test-headless-start-test
|
||||
mutter-all.test
|
||||
org.gnome.mutter.gschema.valid
|
||||
org.gnome.mutter.gschema.xml
|
||||
@ -71,6 +72,8 @@ src/stamp-meta-enum-types.h
|
||||
src/meta-dbus-display-config.[ch]
|
||||
src/meta-dbus-idle-monitor.[ch]
|
||||
src/meta-dbus-login1.[ch]
|
||||
src/meta-dbus-remote-desktop.[ch]
|
||||
src/meta-dbus-screen-cast.[ch]
|
||||
src/gtk-primary-selection-protocol.c
|
||||
src/gtk-primary-selection-server-protocol.h
|
||||
src/gtk-shell-protocol.c
|
||||
@ -85,6 +88,10 @@ src/pointer-constraints-unstable-v*-protocol.c
|
||||
src/pointer-constraints-unstable-v*-server-protocol.h
|
||||
src/xdg-foreign-unstable-v*-protocol.c
|
||||
src/xdg-foreign-unstable-v*-server-protocol.h
|
||||
src/xdg-output-unstable-v1-protocol.c
|
||||
src/xdg-output-unstable-v1-server-protocol.h
|
||||
src/xwayland-keyboard-grab-unstable-v1-protocol.c
|
||||
src/xwayland-keyboard-grab-unstable-v1-server-protocol.h
|
||||
src/meta/meta-version.h
|
||||
src/libmutter-*.pc
|
||||
doc/reference/*.args
|
||||
@ -112,3 +119,4 @@ ltsugar.m4
|
||||
ltversion.m4
|
||||
lt~obsolete.m4
|
||||
.dirstamp
|
||||
**/tags.*
|
||||
|
246
NEWS
246
NEWS
@ -1,3 +1,249 @@
|
||||
3.27.1
|
||||
======
|
||||
* Work with clients that require older linux_dmabuf protocol [Daniel; #788558]
|
||||
* Support hybrid GPU systems [Jonas; #785381]
|
||||
* Prevent crash when closing maximized windows [Jonni; #788666]
|
||||
* Use the correct monitor for HiDPI scaling of shell chrome [Jonas; #788820]
|
||||
* Fix unredirection of fullscreen windows [Rui, Jonas; #788493]
|
||||
* Fix list of supported monitor scales on X11 [Jonas; #788901]
|
||||
* Misc. bug fixes [Florian, Jonas, Marco; #788572, #788569, #788607, #788860,
|
||||
#788921]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner, Daniel Stone,
|
||||
Marco Trevisan, Jonni Westphalen
|
||||
|
||||
Translations:
|
||||
Xavi Ivars [ca@valencia]
|
||||
|
||||
3.26.1
|
||||
======
|
||||
* Fix crash when respawning shortcut inhibitor dialog [Olivier; #787568]
|
||||
* Fix crash during monitor configuration migration [Carlos, Jonas; #787668]
|
||||
* Fix multihead regressions in X11 session [Jonas; #787477]
|
||||
* Fix screen rotation regressions [Hans; #787836]
|
||||
* Fix keybindings not being resolved with non-latin layouts [Jonas; #787016]
|
||||
* Support snap packages for sandboxed app IDs [Marco; #788217]
|
||||
* Fix crash when reconnecting tablet device [Jason; #787649]
|
||||
* Support running headless [Jonas; #730551, #787637]
|
||||
* Support _NET_RESTACK_WINDOW and ConfigureRequest siblings [Vasilis; #786365]
|
||||
* Fix monitor layout not being remembered across sessions [Jonas; #787629]
|
||||
* Make sure to export _NET_NUMBER_OF_DESKTOPS [Florian; #760651]
|
||||
* Allow resizing of tiled windows [Georges, Florian; #645153]
|
||||
* Export tiling information to clients [Georges; #751857]
|
||||
* Misc. bug fixes [Jonas, Florian, Jeremy, Rico; #787570, #787715, #787953,
|
||||
#788049, #788199, #788292, #788197]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Andrea Azzarone, Georges Basile Stavracas Neto, Hans de Goede,
|
||||
Olivier Fourdan, Carlos Garnacho, Jason Gerecke, Vasilis Liaskovitis,
|
||||
Rui Matos, Florian Müllner, Jeremy Soller, Marco Trevisan, Rico Tzschichholz
|
||||
|
||||
Translations:
|
||||
Matej Urbančič [sl], gogo [hr], Cheng-Chia Tseng [zh_TW]
|
||||
|
||||
3.26.0
|
||||
======
|
||||
Contributors:
|
||||
Florian Müllner
|
||||
|
||||
Translations:
|
||||
Trần Ngọc Quân [vi], Inaki Larranaga Murgoitio [eu], Jordi Mas [ca],
|
||||
Anders Jonsson [sv], Alexander Shopov [bg], Ask Hjorth Larsen [da],
|
||||
Jean-Baptiste Holcroft [fr], A S Alam [pa]
|
||||
|
||||
3.25.92
|
||||
=======
|
||||
* Add screencast and remote desktop support [Jonas; #784199]
|
||||
* Support running with no attached monitors [Jonas; #730551]
|
||||
* Add a vertical gradient effect to background actor [Alessandro; #786618]
|
||||
* Misc. bug fixes [Mario, Daniel, Piotr, Jonas, Bastien; #786619, #786677,
|
||||
#772218, #786918, #760670]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Alessandro Bono, Piotr Drąg, Bastien Nocera,
|
||||
Mario Sanchez Prada, Daniel Stone
|
||||
|
||||
Translations:
|
||||
Marek Cernocky [cs], Aurimas Černius [lt], Piotr Drąg [pl],
|
||||
Fran Dieguez [gl], gogo [hr], Dušan Kazik [sk], Milo Casagrande [it],
|
||||
Jordi Mas [ca], Cheng-Chia Tseng [zh_TW], Марко Костић [sr],
|
||||
Милош Поповић [sr@latin], Rūdolfs Mazurs [lv], Matej Urbančič [sl],
|
||||
Ask Hjorth Larsen [da], Piotr Drąg [it, lt], Jiri Grönroos [fi],
|
||||
Emin Tufan Çetin [tr], Wolfgang Stöggl [de], Kukuh Syafaat [id],
|
||||
Yuras Shumovich [be], Changwoo Ryu [ko], Alexander Shopov [bg],
|
||||
Rafael Fontenelle [pt_BR], Balázs Úr [hu]
|
||||
|
||||
3.25.91
|
||||
=======
|
||||
* Reduce memory use of suspended instances [Jonas; #786299]
|
||||
* Make supported scales determination saner [Rui; #786474]
|
||||
* Fix crash on inhibit-shortcuts dialog reponse [Jonas; #786385]
|
||||
* Support libinput's tag-and-drag setting [freeroot; #775755]
|
||||
* Avoid overlapping keybindings with multiple layouts [Jonas; #786408]
|
||||
* Fix non-transformed cursor on rotated monitors [Jonas; #786023]
|
||||
* Avoid unnecessary work during background painting [Alessandro; #783512]
|
||||
* Misc. bug fixes [Alberts, Jonas, Mario; #691611, #786300, #777732, #786568]
|
||||
|
||||
Contributors:
|
||||
freeroot, Jonas Ådahl, Alessandro Bono, Carlos Garnacho, Rui Matos,
|
||||
Alberts Muktupāvels, Mario Sanchez Prada
|
||||
|
||||
Translations:
|
||||
Muhammet Kara [tr], Claude Paroz [fr], Мирослав Николић [sr, sr@latin],
|
||||
Pawan Chitrakar [ne], Kukuh Syafaat [id]
|
||||
|
||||
3.25.90
|
||||
=======
|
||||
* Add zwp_linux_dmabuf_v1 support [Daniel; #785262]
|
||||
* Add (x)wayland shortcut inhibitor support [Olivier; #783342]
|
||||
* Misc. bug fixes [Daniel, Carlos, Cosimo; #785263, #785347, #767805]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Cosimo Cecchi, Olivier Fourdan, Carlos Garnacho, Daniel Stone
|
||||
|
||||
Translations:
|
||||
Fabio Tomat [fur], Kukuh Syafaat [id], Aurimas Černius [lt],
|
||||
Daniel Mustieles [es], Baurzhan Muftakhidinov [kk], Jordi Mas [ca],
|
||||
Matej Urbančič [sl], Marek Cernocky [cs], gogo [hr], Fran Dieguez [gl],
|
||||
Balázs Meskó [hu]
|
||||
|
||||
3.25.4
|
||||
======
|
||||
* Do not throttle motion events on tablet tools [Carlos; #783535]
|
||||
* Handle left-handed mode on pen/eraser devices [Carlos; #782027]
|
||||
* Add wl_surface.damage_buffer() support [Jonas; #784080]
|
||||
* Fix crash when moving across on-adjacent monitors [Jonas; #783630]
|
||||
* Fix window moving/resizing via tablet tools [Jason; #777333]
|
||||
* Support fractional monitor scaling [Jonas, Marco; #765011]
|
||||
* Keep override-redirect windows stacked on top [Rui; #780485]
|
||||
* Implement tablet rings/strips configuration [Carlos; #782033]
|
||||
* Support tablet wheel events on wayland [Jason; #783716]
|
||||
* Move g-s-d xrandr functionality into mutter [Rui; #781906]
|
||||
* Misc. bug fixes [Florian, Jason, Miguel, Carlos, Jonas; #783502, #784009,
|
||||
#784223, #784272, #784402, #784881, #762083, #784867, #781723]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Miguel A. Vico, Emmanuele Bassi, Carlos Garnacho, Jason Gerecke,
|
||||
Rui Matos, Florian Müllner, Marco Trevisan (Treviño)
|
||||
|
||||
3.25.3
|
||||
======
|
||||
* Ignore hotplug-mode-update value on startup [Marco; #783073]
|
||||
* Implement configurable monitor scales on X11 [Jonas; #777732]
|
||||
* Fix handling of tiled monitors [Jonas; #781723]
|
||||
* Handle multiple keycodes for keysym [Christian; #781223]
|
||||
* Consider subsurfaces when grabbing [mindtree; #781811]
|
||||
* Fix logic for HiPDPI scaling of TV outputs [Christian; #777347]
|
||||
* Fix handling of left-handed mode on pen/eraser devices [Carlos; #782027]
|
||||
* Fix output cycling in non-display-attached tablets [Carlos; #782032]
|
||||
* Fix wacom cursor offset on wayland [Jason; #784009]
|
||||
* Handle EXIF orientation of backgrounds [Silvère; #783125]
|
||||
* Misc. bug fixes [Piotr, Tim, Bastien, Jonas, Florian, Benoit, Carlos; #772218,
|
||||
#783161, #780407, #783113, #783293, #783505, #781703]
|
||||
|
||||
Contributors:
|
||||
mitchmindtree, Jonas Ådahl, Ikey Doherty, Piotr Drąg, Carlos Garnacho,
|
||||
Jason Gerecke, Benoit Gschwind, Christian Kellner, Silvère Latchurié,
|
||||
Tim Lunn, Florian Müllner, Bastien Nocera, Marco Trevisan (Treviño)
|
||||
|
||||
Translations:
|
||||
Fabio Tomat [fur], Kukuh Syafaat [id], Khaled Hosny [ar],
|
||||
Daniel Mustieles [es]
|
||||
|
||||
3.25.2
|
||||
======
|
||||
* Fix frame updates on hide-titlebar-when-maximized changes [Florian; #781862]
|
||||
* Fix accessible screen coordinates on X11 [Florian; #781902]
|
||||
* Use less CPU when rendering fast-updating windows [Carlos, Emmanuele; #782344]
|
||||
* Compute geometry of clients that don't set one explicitly [Olivier; #782213]
|
||||
* Fix copy+paste of UTF8 strings between X11 and wayland [Carlos; #782472]
|
||||
* Fix non-wayland builds [Chris; #780533]
|
||||
* Add plugin vfunc to implement a custom force-quit dialog [Carlos; #711619]
|
||||
* Fix swapped red and blue channels in CoglTexture data [Carlos; #779234
|
||||
* Fix build where libtool's link_all_deplibs defaults to 'no' [Marco; #782821]
|
||||
* Fix glitches when opening a window maximized [Olivier; #781353, #782183]
|
||||
* Fix wrong cursor after window underneath the pointer changed [Carlos; #755164]
|
||||
* Implement support for disable-while-typing option [Evan; #764852]
|
||||
* Emit size-change signal when tiling [Alessandro; #782968]
|
||||
* Misc. bug fixes [Nigel, Matthias, Jonas; #759085, #780215, #782156, #782152]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Emmanuele Bassi, Alessandro Bono, Olivier Fourdan,
|
||||
Carlos Garnacho, Matthias Liertzer, Florian Müllner, Nigel Taylor,
|
||||
Marco Trevisan (Treviño), Chris Vine, Evan Welsh
|
||||
|
||||
Translations:
|
||||
Fabio Tomat [fur], Jordi Mas [ca], Mario Blättermann [de],
|
||||
Emin Tufan Çetin [tr], Balázs Úr [hu]
|
||||
|
||||
3.25.1
|
||||
======
|
||||
* Always sync window geometry on state changes [Jonas; #780292]
|
||||
* Use EGL instead of GLX when drawing using GLES [Jonas; #771636]
|
||||
* Fix HiDPI detection on vertical monitor layouts [Carlos; #777687]
|
||||
* Get double-click timing from desktop mouse settings [Armin; #771576]
|
||||
* Scale relative motion deltas with monitor scale [Jonas, Carlos; #778119]
|
||||
* Use texture fallback when setting hardware cursor fails [Jente; #770020]
|
||||
* Fix lock-up when using additional theme variants [Shantanu; #780254]
|
||||
* Rework low-level monitor configuration [Jonas; #777732]
|
||||
* Fix building with GLES2 instead of GL [Mario; #781398]
|
||||
* Misc. bug fixes [Jonas, Piotr, Philip; #780304, #772218, #781242, #781391]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Philip Chimento, Piotr Drąg, Carlos Garnacho, Shantanu Goel,
|
||||
Jente Hidskes, Armin Krezović, Rui Matos, Florian Müllner, Mario Sanchez Prada
|
||||
|
||||
Translations:
|
||||
Yuras Shumovich [be], Yosef Or Boczko [he], Tom Tryfonidis [el],
|
||||
Fabio Tomat [fur], Kukuh Syafaat [id]
|
||||
|
||||
3.24.0
|
||||
======
|
||||
|
||||
Translations:
|
||||
Yuri Myasoedov [ru], Rūdolfs Mazurs [lv], Jordi Mas [ca]
|
||||
|
||||
3.23.92
|
||||
=======
|
||||
* Properly handle EGLOutput acquire errors [Jonas, Miguel; #779112]
|
||||
* Fix crash when a window closes during Alt+Tab [Rui; #779483]
|
||||
* Implement DnD handling code in wayland [Hyungwon; #765003]
|
||||
* Fix fallout from pixel conversion optimization in 3.23.91 [Carlos; #779234]
|
||||
* Fix mouse input stopping to work in applications [Carlos; #763246]
|
||||
* Fix DnD between QT5 and GTK3 applications on wayland [Carlos; #779757]
|
||||
* Make EDID reading less fragile [Jonas; #779837]
|
||||
* Add support for tablet grouping [Carlos; #779986]
|
||||
* Misc. bug fixes and cleanups [Rui, Jonas; #779436, #779001, #779745]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Miguel A. Vico, Olivier Fourdan, Carlos Garnacho,
|
||||
Hyungwon Hwang, Rui Matos
|
||||
|
||||
Translations:
|
||||
Chao-Hsiung Liao [zh_TW], Sveinn í Felli [is], Ask Hjorth Larsen [da],
|
||||
Changwoo Ryu [ko], Aurimas Černius [lt], GNOME Translation Robot [gd],
|
||||
Marek Černocký [cs], Fran Dieguez [gl], Dušan Kazik [sk]
|
||||
|
||||
3.23.91
|
||||
=======
|
||||
* Give libinput read-only access to /sys [Carlos; #778472]
|
||||
* Allow edge-scrolling without 2-finger-scroll capable devices [Rui; #778554]
|
||||
* Fullscreen windows on the requested monitor on wayland [Rui; #772525]
|
||||
* Implement threaded swap_event fallback for NVIDIA driver [Owen; #779039]
|
||||
* Avoid pixel conversions when storing textures from cairo [Carlos; #779234]
|
||||
* Misc. bug fixes [Piotr, Rui, Florian; #772218, #776919, #778831, #642652]
|
||||
|
||||
Contributors:
|
||||
Piotr Drąg, Carlos Garnacho, Rui Matos, Florian Müllner, Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Inaki Larranaga Murgoitio [eu], Daniel Mustieles [es], Claude Paroz [fr],
|
||||
Mario Blättermann [de], Kjartan Maraas [nb], Piotr Drąg [pl],
|
||||
Andika Triwidada [id], Anders Jonsson [sv], Milo Casagrande [it],
|
||||
Fabio Tomat [fur], Rafael Fontenelle [pt_BR],
|
||||
Мирослав Николић [sr, sr@latin], Balázs Meskó [hu], Chao-Hsiung Liao [zh_TW]
|
||||
|
||||
3.23.90
|
||||
=======
|
||||
* Fix window menu placement with HiDPI [Jonas; #776055]
|
||||
|
25
autogen.sh
25
autogen.sh
@ -6,16 +6,23 @@ test -z "$srcdir" && srcdir=.
|
||||
|
||||
REQUIRED_AUTOMAKE_VERSION=1.11
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -d $srcdir/src) || {
|
||||
olddir="$(pwd)"
|
||||
|
||||
cd "${srcdir}"
|
||||
|
||||
(test -f configure.ac \
|
||||
&& test -d src) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level metacity directory"
|
||||
echo " top-level mutter directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
which gnome-autogen.sh || {
|
||||
echo "You need to install gnome-common from GNOME Subversion (or from"
|
||||
echo "your distribution's package manager)."
|
||||
exit 1
|
||||
}
|
||||
. gnome-autogen.sh
|
||||
aclocal --install || exit 1
|
||||
intltoolize --force --copy --automake || exit 1
|
||||
autoreconf --verbose --force --install || exit 1
|
||||
|
||||
cd "${olddir}"
|
||||
|
||||
if [ "$NOCONFIGURE" = "" ]; then
|
||||
"${srcdir}/configure" "$@" || exit 1
|
||||
fi
|
||||
|
@ -87,6 +87,8 @@ source_h = \
|
||||
clutter-image.h \
|
||||
clutter-input-device.h \
|
||||
clutter-input-device-tool.h \
|
||||
clutter-input-focus.h \
|
||||
clutter-input-method.h \
|
||||
clutter-interval.h \
|
||||
clutter-keyframe-transition.h \
|
||||
clutter-keysyms.h \
|
||||
@ -169,6 +171,8 @@ source_c = \
|
||||
clutter-image.c \
|
||||
clutter-input-device.c \
|
||||
clutter-input-device-tool.c \
|
||||
clutter-input-focus.c \
|
||||
clutter-input-method.c \
|
||||
clutter-virtual-input-device.c \
|
||||
clutter-interval.c \
|
||||
clutter-keyframe-transition.c \
|
||||
@ -388,6 +392,7 @@ x11_source_c = \
|
||||
x11/clutter-keymap-x11.c \
|
||||
x11/clutter-stage-x11.c \
|
||||
x11/clutter-x11-texture-pixmap.c \
|
||||
x11/clutter-xkb-a11y-x11.c \
|
||||
$(NULL)
|
||||
|
||||
x11_source_h = \
|
||||
@ -402,6 +407,7 @@ x11_source_h_priv = \
|
||||
x11/clutter-keymap-x11.h \
|
||||
x11/clutter-settings-x11.h \
|
||||
x11/clutter-stage-x11.h \
|
||||
x11/clutter-xkb-a11y-x11.h \
|
||||
$(NULL)
|
||||
|
||||
x11_source_c_priv = \
|
||||
|
@ -34,6 +34,7 @@ stamp-marshal: $(marshal_list)
|
||||
$(AM_V_GEN)$(GLIB_GENMARSHAL) \
|
||||
--prefix=$(glib_marshal_prefix) \
|
||||
--header \
|
||||
--valist-marshallers \
|
||||
$(marshal_list) > xgen-mh \
|
||||
&& (cmp -s xgen-mh $(marshal_h) || cp -f xgen-mh $(marshal_h)) \
|
||||
&& rm -f xgen-mh \
|
||||
@ -43,10 +44,11 @@ $(marshal_h): stamp-marshal
|
||||
@true
|
||||
|
||||
$(marshal_c): $(marshal_h)
|
||||
$(AM_V_GEN)(echo "#include \"$(marshal_h)\"" ; \
|
||||
$(GLIB_GENMARSHAL) \
|
||||
$(AM_V_GEN)$(GLIB_GENMARSHAL) \
|
||||
--prefix=$(glib_marshal_prefix) \
|
||||
--body \
|
||||
$(marshal_list)) > xgen-mc \
|
||||
&& cp xgen-mc $(marshal_c) \
|
||||
--valist-marshallers \
|
||||
--prototypes \
|
||||
$(marshal_list) > xgen-mc \
|
||||
&& (cmp -s xgen-mc $(marshal_c) || cp -f xgen-mc $(marshal_c)) \
|
||||
&& rm -f xgen-mc
|
||||
|
@ -781,7 +781,7 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
|
||||
"position of the stage");
|
||||
}
|
||||
else
|
||||
#else
|
||||
#endif
|
||||
{
|
||||
static gboolean yet_warned = FALSE;
|
||||
|
||||
@ -793,7 +793,6 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
|
||||
"atk_component_get_extents() with ATK_XY_SCREEN.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (xp)
|
||||
*xp = x;
|
||||
|
@ -2656,7 +2656,15 @@ _clutter_actor_signal_queue_redraw (ClutterActor *self,
|
||||
_clutter_actor_queue_redraw_on_clones (self);
|
||||
|
||||
/* calls klass->queue_redraw in default handler */
|
||||
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin);
|
||||
if (g_signal_has_handler_pending (self, actor_signals[QUEUE_REDRAW],
|
||||
0, TRUE))
|
||||
{
|
||||
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLUTTER_ACTOR_GET_CLASS (self)->queue_redraw (self, origin);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4015,7 +4023,11 @@ clutter_actor_continue_paint (ClutterActor *self)
|
||||
clutter_paint_node_unref (dummy);
|
||||
|
||||
/* XXX:2.0 - Call the paint() virtual directly */
|
||||
g_signal_emit (self, actor_signals[PAINT], 0);
|
||||
if (g_signal_has_handler_pending (self, actor_signals[PAINT],
|
||||
0, TRUE))
|
||||
g_signal_emit (self, actor_signals[PAINT], 0);
|
||||
else
|
||||
CLUTTER_ACTOR_GET_CLASS (self)->paint (self);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4029,7 +4041,11 @@ clutter_actor_continue_paint (ClutterActor *self)
|
||||
*
|
||||
* XXX:2.0 - Call the pick() virtual directly
|
||||
*/
|
||||
g_signal_emit (self, actor_signals[PICK], 0, &col);
|
||||
if (g_signal_has_handler_pending (self, actor_signals[PICK],
|
||||
0, TRUE))
|
||||
g_signal_emit (self, actor_signals[PICK], 0, &col);
|
||||
else
|
||||
CLUTTER_ACTOR_GET_CLASS (self)->pick (self, &col);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -58,6 +58,8 @@ struct _ClutterBackend
|
||||
gint32 units_serial;
|
||||
|
||||
GList *event_translators;
|
||||
|
||||
ClutterInputMethod *input_method;
|
||||
};
|
||||
|
||||
struct _ClutterBackendClass
|
||||
@ -100,6 +102,8 @@ struct _ClutterBackendClass
|
||||
|
||||
PangoDirection (* get_keymap_direction) (ClutterBackend *backend);
|
||||
|
||||
void (* bell_notify) (ClutterBackend *backend);
|
||||
|
||||
/* signals */
|
||||
void (* resolution_changed) (ClutterBackend *backend);
|
||||
void (* font_changed) (ClutterBackend *backend);
|
||||
|
@ -127,6 +127,7 @@ clutter_backend_finalize (GObject *gobject)
|
||||
|
||||
g_free (backend->font_name);
|
||||
clutter_backend_set_font_options (backend, NULL);
|
||||
g_clear_object (&backend->input_method);
|
||||
|
||||
G_OBJECT_CLASS (clutter_backend_parent_class)->finalize (gobject);
|
||||
}
|
||||
@ -1363,3 +1364,41 @@ clutter_set_allowed_drivers (const char *drivers)
|
||||
|
||||
allowed_drivers = g_strdup (drivers);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_backend_bell_notify (ClutterBackend *backend)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
if (klass->bell_notify)
|
||||
klass->bell_notify (backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_get_input_method:
|
||||
* @backend: the #CLutterBackend
|
||||
*
|
||||
* Returns the input method used by Clutter
|
||||
*
|
||||
* Returns: (transfer none): the input method
|
||||
**/
|
||||
ClutterInputMethod *
|
||||
clutter_backend_get_input_method (ClutterBackend *backend)
|
||||
{
|
||||
return backend->input_method;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_set_input_method:
|
||||
* @backend: the #ClutterBackend
|
||||
* @method: the input method
|
||||
*
|
||||
* Sets the input method to be used by Clutter
|
||||
**/
|
||||
void
|
||||
clutter_backend_set_input_method (ClutterBackend *backend,
|
||||
ClutterInputMethod *method)
|
||||
{
|
||||
g_set_object (&backend->input_method, method);
|
||||
}
|
||||
|
@ -74,6 +74,15 @@ const cairo_font_options_t * clutter_backend_get_font_options (Clutter
|
||||
CLUTTER_AVAILABLE_IN_1_8
|
||||
CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_backend_bell_notify (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_backend_set_input_method (ClutterBackend *backend,
|
||||
ClutterInputMethod *method);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BACKEND_H__ */
|
||||
|
@ -76,9 +76,6 @@ struct _ClutterCanvasPrivate
|
||||
gboolean dirty;
|
||||
|
||||
CoglBitmap *buffer;
|
||||
|
||||
int scale_factor;
|
||||
guint scale_factor_set : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -87,8 +84,6 @@ enum
|
||||
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_SCALE_FACTOR,
|
||||
PROP_SCALE_FACTOR_SET,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
@ -185,11 +180,6 @@ clutter_canvas_set_property (GObject *gobject,
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
clutter_canvas_set_scale_factor (CLUTTER_CANVAS (gobject),
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -214,17 +204,6 @@ clutter_canvas_get_property (GObject *gobject,
|
||||
g_value_set_int (value, priv->height);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
if (priv->scale_factor_set)
|
||||
g_value_set_int (value, priv->scale_factor);
|
||||
else
|
||||
g_value_set_int (value, -1);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR_SET:
|
||||
g_value_set_boolean (value, priv->scale_factor_set);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -268,46 +247,6 @@ clutter_canvas_class_init (ClutterCanvasClass *klass)
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterCanvas:scale-factor-set:
|
||||
*
|
||||
* Whether the #ClutterCanvas:scale-factor property is set.
|
||||
*
|
||||
* If the #ClutterCanvas:scale-factor-set property is %FALSE
|
||||
* then #ClutterCanvas will use the #ClutterSettings:window-scaling-factor
|
||||
* property.
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
obj_props[PROP_SCALE_FACTOR_SET] =
|
||||
g_param_spec_boolean ("scale-factor-set",
|
||||
P_("Scale Factor Set"),
|
||||
P_("Whether the scale-factor property is set"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterCanvas:scale-factor:
|
||||
*
|
||||
* The scaling factor to be applied to the Cairo surface used for
|
||||
* drawing.
|
||||
*
|
||||
* If #ClutterCanvas:scale-factor is set to a negative value, the
|
||||
* value of the #ClutterSettings:window-scaling-factor property is
|
||||
* used instead.
|
||||
*
|
||||
* Use #ClutterCanvas:scale-factor-set to check if the scale factor
|
||||
* is set.
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
obj_props[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor",
|
||||
P_("Scale Factor"),
|
||||
P_("The scaling factor for the surface"),
|
||||
-1, 1000,
|
||||
-1,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterCanvas::draw:
|
||||
@ -354,7 +293,6 @@ clutter_canvas_init (ClutterCanvas *self)
|
||||
|
||||
self->priv->width = -1;
|
||||
self->priv->height = -1;
|
||||
self->priv->scale_factor = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -397,7 +335,6 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
|
||||
gboolean mapped_buffer;
|
||||
unsigned char *data;
|
||||
CoglBuffer *buffer;
|
||||
int window_scale = 1;
|
||||
gboolean res;
|
||||
cairo_t *cr;
|
||||
|
||||
@ -405,20 +342,11 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
|
||||
|
||||
priv->dirty = TRUE;
|
||||
|
||||
if (priv->scale_factor_set)
|
||||
window_scale = priv->scale_factor;
|
||||
else
|
||||
g_object_get (clutter_settings_get_default (),
|
||||
"window-scaling-factor", &window_scale,
|
||||
NULL);
|
||||
real_width = priv->width;
|
||||
real_height = priv->height;
|
||||
|
||||
real_width = priv->width * window_scale;
|
||||
real_height = priv->height * window_scale;
|
||||
|
||||
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d (real: %d x %d, scale: %d)",
|
||||
priv->width, priv->height,
|
||||
real_width, real_height,
|
||||
window_scale);
|
||||
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d",
|
||||
priv->width, priv->height);
|
||||
|
||||
if (priv->buffer == NULL)
|
||||
{
|
||||
@ -461,8 +389,6 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
|
||||
mapped_buffer = FALSE;
|
||||
}
|
||||
|
||||
cairo_surface_set_device_scale (surface, window_scale, window_scale);
|
||||
|
||||
self->priv->cr = cr = cairo_create (surface);
|
||||
|
||||
g_signal_emit (self, canvas_signals[DRAW], 0,
|
||||
@ -636,81 +562,3 @@ clutter_canvas_set_size (ClutterCanvas *canvas,
|
||||
|
||||
return clutter_canvas_invalidate_internal (canvas, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_canvas_set_scale_factor:
|
||||
* @canvas: a #ClutterCanvas
|
||||
* @scale: the scale factor, or -1 for the default
|
||||
*
|
||||
* Sets the scaling factor for the Cairo surface used by @canvas.
|
||||
*
|
||||
* This function should rarely be used.
|
||||
*
|
||||
* The default scaling factor of a #ClutterCanvas content uses the
|
||||
* #ClutterSettings:window-scaling-factor property, which is set by
|
||||
* the windowing system. By using this function it is possible to
|
||||
* override that setting.
|
||||
*
|
||||
* Changing the scale factor will invalidate the @canvas.
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
void
|
||||
clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
|
||||
int scale)
|
||||
{
|
||||
ClutterCanvasPrivate *priv;
|
||||
GObject *obj;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
|
||||
g_return_if_fail (scale != 0);
|
||||
|
||||
priv = canvas->priv;
|
||||
|
||||
if (scale < 0)
|
||||
{
|
||||
if (!priv->scale_factor_set)
|
||||
return;
|
||||
|
||||
priv->scale_factor_set = FALSE;
|
||||
priv->scale_factor = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priv->scale_factor_set && priv->scale_factor == scale)
|
||||
return;
|
||||
|
||||
priv->scale_factor_set = TRUE;
|
||||
priv->scale_factor = scale;
|
||||
}
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
|
||||
|
||||
obj = G_OBJECT (canvas);
|
||||
|
||||
g_object_notify_by_pspec (obj, obj_props[PROP_SCALE_FACTOR]);
|
||||
g_object_notify_by_pspec (obj, obj_props[PROP_SCALE_FACTOR_SET]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_canvas_get_scale_factor:
|
||||
* @canvas: a #ClutterCanvas
|
||||
*
|
||||
* Retrieves the scaling factor of @canvas, as set using
|
||||
* clutter_canvas_set_scale_factor().
|
||||
*
|
||||
* Return value: the scaling factor, or -1 if the @canvas
|
||||
* uses the default from #ClutterSettings
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
int
|
||||
clutter_canvas_get_scale_factor (ClutterCanvas *canvas)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), -1);
|
||||
|
||||
if (!canvas->priv->scale_factor_set)
|
||||
return -1;
|
||||
|
||||
return canvas->priv->scale_factor;
|
||||
}
|
||||
|
@ -54,6 +54,7 @@
|
||||
struct _ClutterClonePrivate
|
||||
{
|
||||
ClutterActor *clone_source;
|
||||
gulong source_destroy_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterClone, clutter_clone, CLUTTER_TYPE_ACTOR)
|
||||
@ -376,6 +377,13 @@ clutter_clone_new (ClutterActor *source)
|
||||
return g_object_new (CLUTTER_TYPE_CLONE, "source", source, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_source_destroyed (ClutterActor *source,
|
||||
ClutterClone *self)
|
||||
{
|
||||
clutter_clone_set_source_internal (self, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_set_source_internal (ClutterClone *self,
|
||||
ClutterActor *source)
|
||||
@ -387,6 +395,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
|
||||
|
||||
if (priv->clone_source != NULL)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->clone_source, priv->source_destroy_id);
|
||||
priv->source_destroy_id = 0;
|
||||
_clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self));
|
||||
g_object_unref (priv->clone_source);
|
||||
priv->clone_source = NULL;
|
||||
@ -396,6 +406,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
|
||||
{
|
||||
priv->clone_source = g_object_ref (source);
|
||||
_clutter_actor_attach_clone (priv->clone_source, CLUTTER_ACTOR (self));
|
||||
priv->source_destroy_id = g_signal_connect (priv->clone_source, "destroy",
|
||||
G_CALLBACK (on_source_destroyed), self);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SOURCE]);
|
||||
|
@ -48,7 +48,7 @@
|
||||
#include "clutter-debug.h"
|
||||
|
||||
/* XXX - keep in sync with the ClutterStaticColor enumeration order */
|
||||
static const ClutterColor const static_colors[] = {
|
||||
static const ClutterColor static_colors[] = {
|
||||
/* CGA/EGA color palette */
|
||||
{ 0xff, 0xff, 0xff, 0xff }, /* white */
|
||||
{ 0x00, 0x00, 0x00, 0xff }, /* black */
|
||||
|
@ -145,6 +145,9 @@ struct _ClutterInputDevice
|
||||
guint is_enabled : 1;
|
||||
};
|
||||
|
||||
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
|
||||
ClutterInputDevice *device);
|
||||
|
||||
struct _ClutterInputDeviceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
@ -160,6 +163,14 @@ struct _ClutterInputDeviceClass
|
||||
guint button);
|
||||
gint (* get_group_n_modes) (ClutterInputDevice *device,
|
||||
gint group);
|
||||
|
||||
gboolean (* is_grouped) (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device);
|
||||
|
||||
/* Keyboard accessbility */
|
||||
void (* process_kbd_a11y_event) (ClutterEvent *event,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEmitInputDeviceEvent emit_event_func);
|
||||
};
|
||||
|
||||
/* Platform-dependent interface */
|
||||
|
@ -54,6 +54,9 @@ struct _ClutterDeviceManagerPrivate
|
||||
{
|
||||
/* back-pointer to the backend */
|
||||
ClutterBackend *backend;
|
||||
|
||||
/* Keyboard a11y */
|
||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -72,6 +75,8 @@ enum
|
||||
DEVICE_ADDED,
|
||||
DEVICE_REMOVED,
|
||||
TOOL_CHANGED,
|
||||
KBD_A11Y_MASK_CHANGED,
|
||||
KBD_A11Y_FLAGS_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@ -196,6 +201,46 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
|
||||
G_TYPE_NONE, 2,
|
||||
CLUTTER_TYPE_INPUT_DEVICE,
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::kbd-a11y-mods-state-changed:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @latched_mask: the latched modifier mask from stickykeys
|
||||
* @locked_mask: the locked modifier mask from stickykeys
|
||||
*
|
||||
* The ::kbd-a11y-mods-state-changed signal is emitted each time either the
|
||||
* latched modifiers mask or locked modifiers mask are changed as the
|
||||
* result of keyboard accessibilty's sticky keys operations.
|
||||
*/
|
||||
manager_signals[KBD_A11Y_MASK_CHANGED] =
|
||||
g_signal_new (I_("kbd-a11y-mods-state-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__UINT_UINT,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_UINT);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::kbd-a11y-flags-changed:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @settings_flags: the new ClutterKeyboardA11yFlags configuration
|
||||
* @changed_mask: the ClutterKeyboardA11yFlags changed
|
||||
*
|
||||
* The ::kbd-a11y-flags-changed signal is emitted each time the
|
||||
* ClutterKeyboardA11yFlags configuration is changed as the result of
|
||||
* keyboard accessibilty operations.
|
||||
*/
|
||||
manager_signals[KBD_A11Y_FLAGS_CHANGED] =
|
||||
g_signal_new (I_("kbd-a11y-flags-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__UINT_UINT,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_UINT);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -487,3 +532,43 @@ _clutter_device_manager_compress_motion (ClutterDeviceManager *device_manager,
|
||||
|
||||
manager_class->compress_motion (device_manager, event, to_discard);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
|
||||
ClutterKbdA11ySettings *b)
|
||||
{
|
||||
return (a->controls == b->controls &&
|
||||
a->slowkeys_delay == b->slowkeys_delay &&
|
||||
a->debounce_delay == b->debounce_delay &&
|
||||
a->timeout_delay == b->timeout_delay &&
|
||||
a->mousekeys_init_delay == b->mousekeys_init_delay &&
|
||||
a->mousekeys_max_speed == b->mousekeys_max_speed &&
|
||||
a->mousekeys_accel_time == b->mousekeys_accel_time);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings)
|
||||
{
|
||||
ClutterDeviceManagerClass *manager_class;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
if (are_kbd_a11y_settings_equal (&device_manager->priv->kbd_a11y_settings, settings))
|
||||
return;
|
||||
|
||||
device_manager->priv->kbd_a11y_settings = *settings;
|
||||
|
||||
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
|
||||
if (manager_class->apply_kbd_a11y_settings)
|
||||
manager_class->apply_kbd_a11y_settings (device_manager, settings);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
*settings = device_manager->priv->kbd_a11y_settings;
|
||||
}
|
||||
|
@ -44,6 +44,25 @@ typedef struct _ClutterDeviceManager ClutterDeviceManager;
|
||||
typedef struct _ClutterDeviceManagerPrivate ClutterDeviceManagerPrivate;
|
||||
typedef struct _ClutterDeviceManagerClass ClutterDeviceManagerClass;
|
||||
|
||||
|
||||
/**
|
||||
* ClutterKbdA11ySettings:
|
||||
*
|
||||
* The #ClutterKbdA11ySettings structure contains keyboard accessibility
|
||||
* settings
|
||||
*
|
||||
*/
|
||||
typedef struct _ClutterKbdA11ySettings
|
||||
{
|
||||
ClutterKeyboardA11yFlags controls;
|
||||
gint slowkeys_delay;
|
||||
gint debounce_delay;
|
||||
gint timeout_delay;
|
||||
gint mousekeys_init_delay;
|
||||
gint mousekeys_max_speed;
|
||||
gint mousekeys_accel_time;
|
||||
} ClutterKbdA11ySettings;
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager:
|
||||
*
|
||||
@ -88,7 +107,9 @@ struct _ClutterDeviceManagerClass
|
||||
void (* compress_motion) (ClutterDeviceManager *device_manger,
|
||||
ClutterEvent *event,
|
||||
const ClutterEvent *to_discard);
|
||||
|
||||
/* Keyboard accessbility */
|
||||
void (* apply_kbd_a11y_settings) (ClutterDeviceManager *device_manger,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
/* padding */
|
||||
gpointer _padding[6];
|
||||
};
|
||||
@ -114,6 +135,13 @@ CLUTTER_AVAILABLE_IN_ALL
|
||||
ClutterVirtualInputDevice *clutter_device_manager_create_virtual_device (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDeviceType device_type);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_DEVICE_MANAGER_H__ */
|
||||
|
@ -396,6 +396,43 @@ typedef enum {
|
||||
CLUTTER_MODIFIER_MASK = 0x5c001fff
|
||||
} ClutterModifierType;
|
||||
|
||||
/**
|
||||
* ClutterKeyboardA11yFlags:
|
||||
* @CLUTTER_A11Y_KEYBOARD_ENABLED:
|
||||
* @CLUTTER_A11Y_TIMEOUT_ENABLED:
|
||||
* @CLUTTER_A11Y_MOUSE_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT:
|
||||
* @CLUTTER_A11Y_BOUNCE_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT:
|
||||
* @CLUTTER_A11Y_TOGGLE_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_STICKY_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF:
|
||||
* @CLUTTER_A11Y_STICKY_KEYS_BEEP:
|
||||
* @CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP:
|
||||
*
|
||||
* Keyboard accessibility features applied to a ClutterInputDevice keyboard.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_KEYBOARD_ENABLED = 1 << 0,
|
||||
CLUTTER_A11Y_TIMEOUT_ENABLED = 1 << 1,
|
||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED = 1 << 2,
|
||||
CLUTTER_A11Y_SLOW_KEYS_ENABLED = 1 << 3,
|
||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4,
|
||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5,
|
||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6,
|
||||
CLUTTER_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7,
|
||||
CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8,
|
||||
CLUTTER_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9,
|
||||
CLUTTER_A11Y_STICKY_KEYS_ENABLED = 1 << 10,
|
||||
CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11,
|
||||
CLUTTER_A11Y_STICKY_KEYS_BEEP = 1 << 12,
|
||||
CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
|
||||
} ClutterKeyboardA11yFlags;
|
||||
|
||||
/**
|
||||
* ClutterActorFlags:
|
||||
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
|
||||
@ -730,8 +767,9 @@ typedef enum { /*< prefix=CLUTTER_DRAG >*/
|
||||
* Since: 0.6
|
||||
*/
|
||||
typedef enum { /*< flags prefix=CLUTTER_EVENT >*/
|
||||
CLUTTER_EVENT_NONE = 0,
|
||||
CLUTTER_EVENT_FLAG_SYNTHETIC = 1 << 0
|
||||
CLUTTER_EVENT_NONE = 0,
|
||||
CLUTTER_EVENT_FLAG_SYNTHETIC = 1 << 0,
|
||||
CLUTTER_EVENT_FLAG_INPUT_METHOD = 1 << 1
|
||||
} ClutterEventFlags;
|
||||
|
||||
/**
|
||||
@ -1536,6 +1574,41 @@ typedef enum {
|
||||
CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE,
|
||||
} ClutterInputDeviceMapping;
|
||||
|
||||
typedef enum {
|
||||
CLUTTER_INPUT_CONTENT_HINT_COMPLETION = 1 << 0,
|
||||
CLUTTER_INPUT_CONTENT_HINT_SPELLCHECK = 1 << 1,
|
||||
CLUTTER_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION = 1 << 2,
|
||||
CLUTTER_INPUT_CONTENT_HINT_LOWERCASE = 1 << 3,
|
||||
CLUTTER_INPUT_CONTENT_HINT_UPPERCASE = 1 << 4,
|
||||
CLUTTER_INPUT_CONTENT_HINT_TITLECASE = 1 << 5,
|
||||
CLUTTER_INPUT_CONTENT_HINT_HIDDEN_TEXT = 1 << 6,
|
||||
CLUTTER_INPUT_CONTENT_HINT_SENSITIVE_DATA = 1 << 7,
|
||||
CLUTTER_INPUT_CONTENT_HINT_LATIN = 1 << 8,
|
||||
CLUTTER_INPUT_CONTENT_HINT_MULTILINE = 1 << 9,
|
||||
} ClutterInputContentHintFlags;
|
||||
|
||||
typedef enum {
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_ALPHA,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_DIGITS,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_NUMBER,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_PHONE,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_URL,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_EMAIL,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_NAME,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_PASSWORD,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_DATE,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_TIME,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_DATETIME,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_TERMINAL,
|
||||
} ClutterInputContentPurpose;
|
||||
|
||||
typedef enum {
|
||||
CLUTTER_INPUT_PANEL_STATE_OFF,
|
||||
CLUTTER_INPUT_PANEL_STATE_ON,
|
||||
CLUTTER_INPUT_PANEL_STATE_TOGGLE,
|
||||
} ClutterInputPanelState;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ENUMS_H__ */
|
||||
|
@ -2179,3 +2179,61 @@ clutter_event_get_mode_group (const ClutterEvent *event)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_event_get_pad_event_details:
|
||||
* @event: a pad event
|
||||
* @number: (out) (optional): ring/strip/button number
|
||||
* @mode: (out) (optional): pad mode as per the event
|
||||
* @value: (out) (optional): event axis value
|
||||
*
|
||||
* Returns the details of a pad event.
|
||||
*
|
||||
* Returns: #TRUE if event details could be obtained
|
||||
**/
|
||||
gboolean
|
||||
clutter_event_get_pad_event_details (const ClutterEvent *event,
|
||||
guint *number,
|
||||
guint *mode,
|
||||
gdouble *value)
|
||||
{
|
||||
guint n, m;
|
||||
gdouble v;
|
||||
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS ||
|
||||
event->type == CLUTTER_PAD_BUTTON_RELEASE ||
|
||||
event->type == CLUTTER_PAD_RING ||
|
||||
event->type == CLUTTER_PAD_STRIP, FALSE);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_PAD_BUTTON_PRESS:
|
||||
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||
n = event->pad_button.button;
|
||||
m = event->pad_button.mode;
|
||||
v = 0.0;
|
||||
break;
|
||||
case CLUTTER_PAD_RING:
|
||||
n = event->pad_ring.ring_number;
|
||||
m = event->pad_ring.mode;
|
||||
v = event->pad_ring.angle;
|
||||
break;
|
||||
case CLUTTER_PAD_STRIP:
|
||||
n = event->pad_strip.strip_number;
|
||||
m = event->pad_strip.mode;
|
||||
v = event->pad_strip.value;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (number)
|
||||
*number = n;
|
||||
if (mode)
|
||||
*mode = m;
|
||||
if (value)
|
||||
*value = v;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -778,6 +778,12 @@ ClutterScrollFinishFlags clutter_event_get_scroll_finish_flags (const Clut
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
guint clutter_event_get_mode_group (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
gboolean clutter_event_get_pad_event_details (const ClutterEvent *event,
|
||||
guint *number,
|
||||
guint *mode,
|
||||
gdouble *value);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -2243,10 +2243,15 @@ clutter_input_device_get_device_node (ClutterInputDevice *device)
|
||||
ClutterInputDeviceMapping
|
||||
clutter_input_device_get_mapping_mode (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterInputDeviceType device_type;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device),
|
||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE);
|
||||
g_return_val_if_fail (clutter_input_device_get_device_type (device) ==
|
||||
CLUTTER_TABLET_DEVICE,
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
g_return_val_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
|
||||
device_type == CLUTTER_PEN_DEVICE ||
|
||||
device_type == CLUTTER_ERASER_DEVICE,
|
||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE);
|
||||
|
||||
return device->mapping_mode;
|
||||
@ -2256,9 +2261,14 @@ void
|
||||
clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
|
||||
ClutterInputDeviceMapping mapping)
|
||||
{
|
||||
ClutterInputDeviceType device_type;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
||||
g_return_if_fail (clutter_input_device_get_device_type (device) ==
|
||||
CLUTTER_TABLET_DEVICE);
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
g_return_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
|
||||
device_type == CLUTTER_PEN_DEVICE ||
|
||||
device_type == CLUTTER_ERASER_DEVICE);
|
||||
|
||||
if (device->mapping_mode == mapping)
|
||||
return;
|
||||
@ -2266,3 +2276,13 @@ clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
|
||||
device->mapping_mode = mapping;
|
||||
g_object_notify (G_OBJECT (device), "mapping-mode");
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_device_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (other_device), FALSE);
|
||||
|
||||
return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->is_grouped (device, other_device);
|
||||
}
|
||||
|
@ -168,6 +168,9 @@ ClutterInputDeviceMapping clutter_input_device_get_mapping_mode (ClutterInputDev
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
|
||||
ClutterInputDeviceMapping mapping);
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
gboolean clutter_input_device_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
229
clutter/clutter/clutter-input-focus.c
Normal file
229
clutter/clutter/clutter-input-focus.c
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-input-focus.h"
|
||||
|
||||
enum {
|
||||
FOCUS_IN,
|
||||
FOCUS_OUT,
|
||||
COMMIT,
|
||||
DELETE_SURROUNDING,
|
||||
REQUEST_SURROUNDING,
|
||||
SET_PREEDIT_TEXT,
|
||||
N_SIGNALS,
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
G_DEFINE_INTERFACE (ClutterInputFocus, clutter_input_focus, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
clutter_input_focus_default_init (ClutterInputFocusInterface *iface)
|
||||
{
|
||||
signals[FOCUS_IN] =
|
||||
g_signal_new ("focus-in",
|
||||
CLUTTER_TYPE_INPUT_FOCUS,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterInputFocusInterface, focus_in),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, CLUTTER_TYPE_INPUT_METHOD);
|
||||
signals[FOCUS_OUT] =
|
||||
g_signal_new ("focus-out",
|
||||
CLUTTER_TYPE_INPUT_FOCUS,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterInputFocusInterface, focus_out),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
signals[COMMIT] =
|
||||
g_signal_new ("commit",
|
||||
CLUTTER_TYPE_INPUT_FOCUS,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterInputFocusInterface, commit_text),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
signals[DELETE_SURROUNDING] =
|
||||
g_signal_new ("delete-surrounding",
|
||||
CLUTTER_TYPE_INPUT_FOCUS,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterInputFocusInterface, delete_surrounding),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
|
||||
signals[REQUEST_SURROUNDING] =
|
||||
g_signal_new ("request-surrounding",
|
||||
CLUTTER_TYPE_INPUT_FOCUS,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterInputFocusInterface, request_surrounding),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
signals[SET_PREEDIT_TEXT] =
|
||||
g_signal_new ("set-preedit-text",
|
||||
CLUTTER_TYPE_INPUT_FOCUS,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (ClutterInputFocusInterface, set_preedit_text),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_reset (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
if (clutter_input_method_get_focus (method) != focus)
|
||||
return;
|
||||
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (method)->reset (method);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_cursor_location (ClutterInputFocus *focus,
|
||||
const ClutterRect *rect)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
if (clutter_input_method_get_focus (method) != focus)
|
||||
return;
|
||||
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (method)->set_cursor_location (method, rect);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_surrounding (ClutterInputFocus *focus,
|
||||
const gchar *text,
|
||||
guint cursor,
|
||||
guint anchor)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
if (clutter_input_method_get_focus (method) != focus)
|
||||
return;
|
||||
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (method)->set_surrounding (method, text, cursor, anchor);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_content_hints (ClutterInputFocus *focus,
|
||||
ClutterInputContentHintFlags hints)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
if (clutter_input_method_get_focus (method) != focus)
|
||||
return;
|
||||
|
||||
g_object_set (G_OBJECT (method), "content-hints", hints, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_content_purpose (ClutterInputFocus *focus,
|
||||
ClutterInputContentPurpose purpose)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
if (clutter_input_method_get_focus (method) != focus)
|
||||
return;
|
||||
|
||||
g_object_set (G_OBJECT (method), "content-purpose", purpose, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_focus_in (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
clutter_input_method_focus_in (method, focus);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_focus_out (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
if (clutter_input_method_get_focus (method) == focus)
|
||||
clutter_input_method_focus_out (method);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_focus_filter_key_event (ClutterInputFocus *focus,
|
||||
const ClutterKeyEvent *key)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_METHOD (method), FALSE);
|
||||
|
||||
if (clutter_event_get_flags ((ClutterEvent *) key) & CLUTTER_EVENT_FLAG_INPUT_METHOD)
|
||||
return FALSE;
|
||||
|
||||
if (clutter_input_method_get_focus (method) == focus)
|
||||
{
|
||||
ClutterInputMethodClass *im_class = CLUTTER_INPUT_METHOD_GET_CLASS (method);
|
||||
|
||||
if (im_class->filter_key_event)
|
||||
return im_class->filter_key_event (method, (const ClutterEvent *) key);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_can_show_preedit (ClutterInputFocus *focus,
|
||||
gboolean can_show_preedit)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
if (clutter_input_method_get_focus (method) == focus)
|
||||
g_object_set (G_OBJECT (method), "can-show-preedit", can_show_preedit, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_request_toggle_input_panel (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
if (clutter_input_method_get_focus (method) == focus)
|
||||
{
|
||||
g_signal_emit_by_name (method, "input-panel-state",
|
||||
CLUTTER_INPUT_PANEL_STATE_TOGGLE);
|
||||
}
|
||||
}
|
86
clutter/clutter/clutter-input-focus.h
Normal file
86
clutter/clutter/clutter-input-focus.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_FOCUS_H__
|
||||
#define __CLUTTER_INPUT_FOCUS_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_FOCUS (clutter_input_focus_get_type ())
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
G_DECLARE_INTERFACE (ClutterInputFocus, clutter_input_focus,
|
||||
CLUTTER, INPUT_FOCUS, GObject)
|
||||
|
||||
typedef struct _ClutterInputFocusInterface ClutterInputFocusInterface;
|
||||
|
||||
struct _ClutterInputFocusInterface
|
||||
{
|
||||
GTypeInterface iface;
|
||||
|
||||
void (* focus_in) (ClutterInputFocus *focus,
|
||||
ClutterInputMethod *input_method);
|
||||
void (* focus_out) (ClutterInputFocus *focus);
|
||||
|
||||
void (* request_surrounding) (ClutterInputFocus *focus);
|
||||
void (* delete_surrounding) (ClutterInputFocus *focus,
|
||||
guint offset,
|
||||
guint len);
|
||||
void (* commit_text) (ClutterInputFocus *focus,
|
||||
const gchar *text);
|
||||
|
||||
void (* set_preedit_text) (ClutterInputFocus *focus,
|
||||
const gchar *preedit,
|
||||
guint cursor);
|
||||
};
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_focus_in (ClutterInputFocus *focus);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_focus_out (ClutterInputFocus *focus);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_reset (ClutterInputFocus *focus);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_cursor_location (ClutterInputFocus *focus,
|
||||
const ClutterRect *rect);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_surrounding (ClutterInputFocus *focus,
|
||||
const gchar *text,
|
||||
guint cursor,
|
||||
guint anchor);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_content_hints (ClutterInputFocus *focus,
|
||||
ClutterInputContentHintFlags hint);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_content_purpose (ClutterInputFocus *focus,
|
||||
ClutterInputContentPurpose purpose);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
gboolean clutter_input_focus_filter_key_event (ClutterInputFocus *focus,
|
||||
const ClutterKeyEvent *key);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_can_show_preedit (ClutterInputFocus *focus,
|
||||
gboolean can_show_preedit);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_request_toggle_input_panel (ClutterInputFocus *focus);
|
||||
|
||||
#endif /* __CLUTTER_INPUT_FOCUS_H__ */
|
359
clutter/clutter/clutter-input-method.c
Normal file
359
clutter/clutter/clutter-input-method.c
Normal file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-private.h"
|
||||
#include "clutter/clutter-input-method.h"
|
||||
|
||||
typedef struct _ClutterInputMethodPrivate ClutterInputMethodPrivate;
|
||||
|
||||
struct _ClutterInputMethodPrivate
|
||||
{
|
||||
ClutterInputFocus *focus;
|
||||
ClutterInputContentHintFlags content_hints;
|
||||
ClutterInputContentPurpose content_purpose;
|
||||
gboolean can_show_preedit;
|
||||
};
|
||||
|
||||
enum {
|
||||
COMMIT,
|
||||
DELETE_SURROUNDING,
|
||||
REQUEST_SURROUNDING,
|
||||
INPUT_PANEL_STATE,
|
||||
N_SIGNALS,
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CONTENT_HINTS,
|
||||
PROP_CONTENT_PURPOSE,
|
||||
PROP_CAN_SHOW_PREEDIT,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
static GParamSpec *pspecs[N_PROPS] = { 0 };
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterInputMethod, clutter_input_method, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
set_content_hints (ClutterInputMethod *method,
|
||||
ClutterInputContentHintFlags content_hints)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
priv->content_hints = content_hints;
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (method)->update_content_hints (method,
|
||||
content_hints);
|
||||
}
|
||||
|
||||
static void
|
||||
set_content_purpose (ClutterInputMethod *method,
|
||||
ClutterInputContentPurpose content_purpose)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
priv->content_purpose = content_purpose;
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (method)->update_content_purpose (method,
|
||||
content_purpose);
|
||||
}
|
||||
|
||||
static void
|
||||
set_can_show_preedit (ClutterInputMethod *method,
|
||||
gboolean can_show_preedit)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
priv->can_show_preedit = can_show_preedit;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_method_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT_HINTS:
|
||||
set_content_hints (CLUTTER_INPUT_METHOD (object),
|
||||
g_value_get_flags (value));
|
||||
break;
|
||||
case PROP_CONTENT_PURPOSE:
|
||||
set_content_purpose (CLUTTER_INPUT_METHOD (object),
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_CAN_SHOW_PREEDIT:
|
||||
set_can_show_preedit (CLUTTER_INPUT_METHOD (object),
|
||||
g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_method_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
ClutterInputMethod *method;
|
||||
|
||||
method = CLUTTER_INPUT_METHOD (object);
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT_HINTS:
|
||||
g_value_set_flags (value, priv->content_hints);
|
||||
break;
|
||||
case PROP_CONTENT_PURPOSE:
|
||||
g_value_set_enum (value, priv->content_purpose);
|
||||
break;
|
||||
case PROP_CAN_SHOW_PREEDIT:
|
||||
g_value_set_boolean (value, priv->can_show_preedit);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_method_class_init (ClutterInputMethodClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = clutter_input_method_set_property;
|
||||
object_class->get_property = clutter_input_method_get_property;
|
||||
|
||||
signals[COMMIT] =
|
||||
g_signal_new ("commit",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
signals[DELETE_SURROUNDING] =
|
||||
g_signal_new ("delete-surrounding",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
|
||||
signals[REQUEST_SURROUNDING] =
|
||||
g_signal_new ("request-surrounding",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
signals[INPUT_PANEL_STATE] =
|
||||
g_signal_new ("input-panel-state",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_INPUT_PANEL_STATE);
|
||||
|
||||
pspecs[PROP_CONTENT_HINTS] =
|
||||
g_param_spec_flags ("content-hints",
|
||||
P_("Content hints"),
|
||||
P_("Content hints"),
|
||||
CLUTTER_TYPE_INPUT_CONTENT_HINT_FLAGS, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
pspecs[PROP_CONTENT_PURPOSE] =
|
||||
g_param_spec_enum ("content-purpose",
|
||||
P_("Content purpose"),
|
||||
P_("Content purpose"),
|
||||
CLUTTER_TYPE_INPUT_CONTENT_PURPOSE, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
pspecs[PROP_CAN_SHOW_PREEDIT] =
|
||||
g_param_spec_boolean ("can-show-preedit",
|
||||
P_("Can show preedit"),
|
||||
P_("Can show preedit"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, pspecs);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_method_init (ClutterInputMethod *method)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_focus_in (ClutterInputMethod *method,
|
||||
ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
ClutterInputMethodClass *klass;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
|
||||
if (priv->focus == focus)
|
||||
return;
|
||||
|
||||
if (priv->focus)
|
||||
clutter_input_method_focus_out (method);
|
||||
|
||||
g_set_object (&priv->focus, focus);
|
||||
|
||||
if (focus)
|
||||
{
|
||||
klass = CLUTTER_INPUT_METHOD_GET_CLASS (method);
|
||||
klass->focus_in (method, focus);
|
||||
|
||||
g_signal_emit_by_name (priv->focus, "focus-in", method);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_focus_out (ClutterInputMethod *method)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
ClutterInputMethodClass *klass;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
|
||||
if (!priv->focus)
|
||||
return;
|
||||
|
||||
g_signal_emit_by_name (priv->focus, "focus-out");
|
||||
g_clear_object (&priv->focus);
|
||||
|
||||
klass = CLUTTER_INPUT_METHOD_GET_CLASS (method);
|
||||
klass->focus_out (method);
|
||||
|
||||
g_signal_emit (method, signals[INPUT_PANEL_STATE],
|
||||
0, CLUTTER_INPUT_PANEL_STATE_OFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_method_get_focus:
|
||||
* @method: the #ClutterInputMethod
|
||||
*
|
||||
* Retrieves the current focus of the input method, or %NULL
|
||||
* if there is none.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the current focus
|
||||
**/
|
||||
ClutterInputFocus *
|
||||
clutter_input_method_get_focus (ClutterInputMethod *method)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
return priv->focus;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_commit (ClutterInputMethod *method,
|
||||
const gchar *text)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
if (priv->focus)
|
||||
g_signal_emit_by_name (priv->focus, "commit", text);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_delete_surrounding (ClutterInputMethod *method,
|
||||
guint offset,
|
||||
guint len)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
if (priv->focus)
|
||||
g_signal_emit_by_name (priv->focus, "delete-surrounding", offset, len);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_request_surrounding (ClutterInputMethod *method)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
if (priv->focus)
|
||||
g_signal_emit_by_name (priv->focus, "request-surrounding");
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_method_set_preedit_text:
|
||||
* @method: a #ClutterInputMethod
|
||||
* @preedit: (nullable): the preedit text, or %NULL
|
||||
*
|
||||
* Sets the preedit text on the current input focus.
|
||||
**/
|
||||
void
|
||||
clutter_input_method_set_preedit_text (ClutterInputMethod *method,
|
||||
const gchar *preedit,
|
||||
guint cursor)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (method));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (method);
|
||||
if (priv->focus)
|
||||
g_signal_emit_by_name (priv->focus, "set-preedit-text", preedit, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_notify_key_event (ClutterInputMethod *method,
|
||||
const ClutterEvent *event,
|
||||
gboolean filtered)
|
||||
{
|
||||
if (!filtered)
|
||||
{
|
||||
ClutterEvent *copy;
|
||||
|
||||
/* XXX: we rely on the IM implementation to notify back of
|
||||
* key events in the exact same order they were given.
|
||||
*/
|
||||
copy = clutter_event_copy (event);
|
||||
clutter_event_set_flags (copy, clutter_event_get_flags (event) |
|
||||
CLUTTER_EVENT_FLAG_INPUT_METHOD);
|
||||
clutter_event_put (copy);
|
||||
clutter_event_free (copy);
|
||||
}
|
||||
}
|
89
clutter/clutter/clutter-input-method.h
Normal file
89
clutter/clutter/clutter-input-method.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Red Hat
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_METHOD_H__
|
||||
#define __CLUTTER_INPUT_METHOD_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_METHOD (clutter_input_method_get_type ())
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterInputMethod, clutter_input_method,
|
||||
CLUTTER, INPUT_METHOD, GObject)
|
||||
|
||||
typedef struct _ClutterInputMethodClass ClutterInputMethodClass;
|
||||
|
||||
struct _ClutterInputMethodClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* focus_in) (ClutterInputMethod *method,
|
||||
ClutterInputFocus *actor);
|
||||
void (* focus_out) (ClutterInputMethod *method);
|
||||
|
||||
void (* reset) (ClutterInputMethod *method);
|
||||
|
||||
void (* set_cursor_location) (ClutterInputMethod *method,
|
||||
const ClutterRect *rect);
|
||||
void (* set_surrounding) (ClutterInputMethod *method,
|
||||
const gchar *text,
|
||||
guint cursor,
|
||||
guint anchor);
|
||||
void (* update_content_hints) (ClutterInputMethod *method,
|
||||
ClutterInputContentHintFlags hint);
|
||||
void (* update_content_purpose) (ClutterInputMethod *method,
|
||||
ClutterInputContentPurpose purpose);
|
||||
|
||||
gboolean (* filter_key_event) (ClutterInputMethod *method,
|
||||
const ClutterEvent *key);
|
||||
};
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_focus_in (ClutterInputMethod *method,
|
||||
ClutterInputFocus *focus);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_focus_out (ClutterInputMethod *method);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
ClutterInputFocus * clutter_input_method_get_focus (ClutterInputMethod *method);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_commit (ClutterInputMethod *method,
|
||||
const gchar *text);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_delete_surrounding (ClutterInputMethod *method,
|
||||
guint offset,
|
||||
guint len);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_request_surrounding (ClutterInputMethod *method);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_set_preedit_text (ClutterInputMethod *method,
|
||||
const gchar *preedit,
|
||||
guint cursor);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_notify_key_event (ClutterInputMethod *method,
|
||||
const ClutterEvent *event,
|
||||
gboolean filtered);
|
||||
|
||||
#endif /* __CLUTTER_INPUT_METHOD_H__ */
|
@ -2089,6 +2089,21 @@ emit_keyboard_event (ClutterEvent *event,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
process_key_event (ClutterEvent *event,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device);
|
||||
|
||||
if (device_class->process_kbd_a11y_event)
|
||||
{
|
||||
device_class->process_kbd_a11y_event (event, device, emit_keyboard_event);
|
||||
return;
|
||||
}
|
||||
|
||||
emit_keyboard_event (event, device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_off_stage (ClutterActor *stage,
|
||||
gfloat x,
|
||||
@ -2176,7 +2191,7 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
}
|
||||
}
|
||||
|
||||
emit_keyboard_event (event, device);
|
||||
process_key_event (event, device);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -17,6 +17,7 @@ VOID:BOXED,FLAGS
|
||||
VOID:INT
|
||||
VOID:INT64,INT64,FLOAT,BOOLEAN
|
||||
VOID:INT,INT
|
||||
VOID:INT,POINTER
|
||||
VOID:FLOAT,FLOAT
|
||||
VOID:INT,INT,INT,INT
|
||||
VOID:OBJECT
|
||||
|
@ -40,6 +40,12 @@ gboolean _clutter_get_sync_to_vblank (void);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
int64_t clutter_stage_get_frame_counter (ClutterStage *stage);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_stage_capture_into (ClutterStage *stage,
|
||||
gboolean paint,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data);
|
||||
|
||||
#undef __CLUTTER_H_INSIDE__
|
||||
|
||||
#endif /* __CLUTTER_MUTTER_H__ */
|
||||
|
@ -77,9 +77,7 @@ struct _ClutterSettings
|
||||
|
||||
guint password_hint_time;
|
||||
|
||||
gint window_scaling_factor;
|
||||
gint unscaled_font_dpi;
|
||||
guint fixed_scaling_factor : 1;
|
||||
};
|
||||
|
||||
struct _ClutterSettingsClass
|
||||
@ -112,7 +110,6 @@ enum
|
||||
|
||||
PROP_PASSWORD_HINT_TIME,
|
||||
|
||||
PROP_WINDOW_SCALING_FACTOR,
|
||||
PROP_UNSCALED_FONT_DPI,
|
||||
|
||||
PROP_LAST
|
||||
@ -355,14 +352,6 @@ clutter_settings_set_property (GObject *gobject,
|
||||
self->password_hint_time = g_value_get_uint (value);
|
||||
break;
|
||||
|
||||
case PROP_WINDOW_SCALING_FACTOR:
|
||||
if (!self->fixed_scaling_factor)
|
||||
{
|
||||
self->window_scaling_factor = g_value_get_int (value);
|
||||
self->fixed_scaling_factor = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_UNSCALED_FONT_DPI:
|
||||
self->font_dpi = g_value_get_int (value);
|
||||
settings_update_resolution (self);
|
||||
@ -382,14 +371,7 @@ clutter_settings_set_property_internal (ClutterSettings *self,
|
||||
|
||||
property = g_intern_string (property);
|
||||
|
||||
if (property == I_("window-scaling-factor") &&
|
||||
self->fixed_scaling_factor)
|
||||
return;
|
||||
|
||||
g_object_set_property (G_OBJECT (self), property, value);
|
||||
|
||||
if (property == I_("window-scaling-factor"))
|
||||
self->fixed_scaling_factor = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -446,10 +428,6 @@ clutter_settings_get_property (GObject *gobject,
|
||||
g_value_set_uint (value, self->password_hint_time);
|
||||
break;
|
||||
|
||||
case PROP_WINDOW_SCALING_FACTOR:
|
||||
g_value_set_int (value, self->window_scaling_factor);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -677,14 +655,6 @@ clutter_settings_class_init (ClutterSettingsClass *klass)
|
||||
500,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
obj_props[PROP_WINDOW_SCALING_FACTOR] =
|
||||
g_param_spec_int ("window-scaling-factor",
|
||||
P_("Window Scaling Factor"),
|
||||
P_("The scaling factor to be applied to windows"),
|
||||
1, G_MAXINT,
|
||||
1,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
obj_props[PROP_FONTCONFIG_TIMESTAMP] =
|
||||
g_param_spec_uint ("fontconfig-timestamp",
|
||||
P_("Fontconfig configuration timestamp"),
|
||||
@ -722,8 +692,6 @@ clutter_settings_class_init (ClutterSettingsClass *klass)
|
||||
static void
|
||||
clutter_settings_init (ClutterSettings *self)
|
||||
{
|
||||
const char *scale_str;
|
||||
|
||||
self->resolution = -1.0;
|
||||
|
||||
self->font_dpi = -1;
|
||||
@ -742,18 +710,6 @@ clutter_settings_init (ClutterSettings *self)
|
||||
self->xft_rgba = NULL;
|
||||
|
||||
self->long_press_duration = 500;
|
||||
|
||||
/* if the scaling factor was set by the environment we ignore
|
||||
* any explicit setting
|
||||
*/
|
||||
scale_str = g_getenv ("CLUTTER_SCALE");
|
||||
if (scale_str != NULL)
|
||||
{
|
||||
self->window_scaling_factor = atol (scale_str);
|
||||
self->fixed_scaling_factor = TRUE;
|
||||
}
|
||||
else
|
||||
self->window_scaling_factor = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "clutter/clutter-stage-view.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
#include <math.h>
|
||||
|
||||
enum
|
||||
{
|
||||
@ -28,6 +29,7 @@ enum
|
||||
PROP_LAYOUT,
|
||||
PROP_FRAMEBUFFER,
|
||||
PROP_OFFSCREEN,
|
||||
PROP_SCALE,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
@ -37,6 +39,7 @@ static GParamSpec *obj_props[PROP_LAST];
|
||||
typedef struct _ClutterStageViewPrivate
|
||||
{
|
||||
cairo_rectangle_int_t layout;
|
||||
float scale;
|
||||
CoglFramebuffer *framebuffer;
|
||||
|
||||
CoglOffscreen *offscreen;
|
||||
@ -141,6 +144,15 @@ clutter_stage_view_blit_offscreen (ClutterStageView *view,
|
||||
cogl_framebuffer_pop_matrix (priv->framebuffer);
|
||||
}
|
||||
|
||||
float
|
||||
clutter_stage_view_get_scale (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
return priv->scale;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_stage_view_is_dirty_viewport (ClutterStageView *view)
|
||||
{
|
||||
@ -179,16 +191,24 @@ clutter_stage_view_set_dirty_projection (ClutterStageView *view,
|
||||
priv->dirty_projection = dirty;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view,
|
||||
CoglMatrix *matrix)
|
||||
{
|
||||
ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view);
|
||||
|
||||
view_class->get_offscreen_transformation_matrix (view, matrix);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
|
||||
gfloat *x,
|
||||
gfloat *y)
|
||||
{
|
||||
ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view);
|
||||
gfloat z = 0, w = 1;
|
||||
CoglMatrix matrix;
|
||||
|
||||
view_class->get_offscreen_transformation_matrix (view, &matrix);
|
||||
clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
|
||||
cogl_matrix_get_inverse (&matrix, &matrix);
|
||||
cogl_matrix_transform_point (&matrix, x, y, &z, &w);
|
||||
}
|
||||
@ -221,6 +241,9 @@ clutter_stage_view_get_property (GObject *object,
|
||||
case PROP_OFFSCREEN:
|
||||
g_value_set_boxed (value, priv->offscreen);
|
||||
break;
|
||||
case PROP_SCALE:
|
||||
g_value_set_float (value, priv->scale);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -245,10 +268,27 @@ clutter_stage_view_set_property (GObject *object,
|
||||
break;
|
||||
case PROP_FRAMEBUFFER:
|
||||
priv->framebuffer = g_value_dup_boxed (value);
|
||||
#ifndef G_DISABLE_CHECKS
|
||||
if (priv->framebuffer)
|
||||
{
|
||||
int fb_width, fb_height;
|
||||
|
||||
fb_width = cogl_framebuffer_get_width (priv->framebuffer);
|
||||
fb_height = cogl_framebuffer_get_height (priv->framebuffer);
|
||||
|
||||
g_warn_if_fail (fabsf (roundf (fb_width / priv->scale) -
|
||||
fb_width / priv->scale) < FLT_EPSILON);
|
||||
g_warn_if_fail (fabsf (roundf (fb_height / priv->scale) -
|
||||
fb_height / priv->scale) < FLT_EPSILON);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case PROP_OFFSCREEN:
|
||||
priv->offscreen = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_SCALE:
|
||||
priv->scale = g_value_get_float (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -276,6 +316,7 @@ clutter_stage_view_init (ClutterStageView *view)
|
||||
|
||||
priv->dirty_viewport = TRUE;
|
||||
priv->dirty_projection = TRUE;
|
||||
priv->scale = 1.0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -296,6 +337,7 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
"The view layout on the screen",
|
||||
CAIRO_GOBJECT_TYPE_RECTANGLE_INT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_FRAMEBUFFER] =
|
||||
@ -304,6 +346,7 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
"The front buffer of the view",
|
||||
COGL_TYPE_HANDLE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_OFFSCREEN] =
|
||||
@ -312,7 +355,16 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
"Framebuffer used as intermediate buffer",
|
||||
COGL_TYPE_HANDLE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_SCALE] =
|
||||
g_param_spec_float ("scale",
|
||||
"View scale",
|
||||
"The view scale",
|
||||
0.5, G_MAXFLOAT, 1.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
|
||||
|
@ -60,6 +60,9 @@ void clutter_stage_view_transform_to_onscreen (ClutterStageView *vie
|
||||
void clutter_stage_view_blit_offscreen (ClutterStageView *view,
|
||||
const cairo_rectangle_int_t *clip);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
float clutter_stage_view_get_scale (ClutterStageView *view);
|
||||
|
||||
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
|
||||
|
||||
void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
|
||||
@ -70,4 +73,8 @@ gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
|
||||
void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
|
||||
gboolean dirty);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view,
|
||||
CoglMatrix *matrix);
|
||||
|
||||
#endif /* __CLUTTER_STAGE_VIEW_H__ */
|
||||
|
@ -303,33 +303,6 @@ _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_window_set_scale_factor (ClutterStageWindow *window,
|
||||
int factor)
|
||||
{
|
||||
ClutterStageWindowIface *iface;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
|
||||
|
||||
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
if (iface->set_scale_factor != NULL)
|
||||
iface->set_scale_factor (window, factor);
|
||||
}
|
||||
|
||||
int
|
||||
_clutter_stage_window_get_scale_factor (ClutterStageWindow *window)
|
||||
{
|
||||
ClutterStageWindowIface *iface;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 1);
|
||||
|
||||
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
if (iface->get_scale_factor != NULL)
|
||||
return iface->get_scale_factor (window);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
GList *
|
||||
_clutter_stage_window_get_views (ClutterStageWindow *window)
|
||||
{
|
||||
|
@ -83,9 +83,6 @@ struct _ClutterStageWindowIface
|
||||
|
||||
gboolean (* can_clip_redraws) (ClutterStageWindow *stage_window);
|
||||
|
||||
void (* set_scale_factor) (ClutterStageWindow *stage_window,
|
||||
int factor);
|
||||
int (* get_scale_factor) (ClutterStageWindow *stage_window);
|
||||
GList *(* get_views) (ClutterStageWindow *stage_window);
|
||||
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
|
||||
void (* finish_frame) (ClutterStageWindow *stage_window);
|
||||
@ -140,10 +137,6 @@ void _clutter_stage_window_get_dirty_pixel (ClutterStageWin
|
||||
|
||||
gboolean _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window);
|
||||
|
||||
void _clutter_stage_window_set_scale_factor (ClutterStageWindow *window,
|
||||
int factor);
|
||||
int _clutter_stage_window_get_scale_factor (ClutterStageWindow *window);
|
||||
|
||||
GList * _clutter_stage_window_get_views (ClutterStageWindow *window);
|
||||
|
||||
void _clutter_stage_window_finish_frame (ClutterStageWindow *window);
|
||||
|
@ -161,6 +161,7 @@ struct _ClutterStagePrivate
|
||||
guint accept_focus : 1;
|
||||
guint motion_events_enabled : 1;
|
||||
guint has_custom_perspective : 1;
|
||||
guint stage_was_relayout : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -364,7 +365,6 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
float new_width, new_height;
|
||||
float width, height;
|
||||
cairo_rectangle_int_t window_size;
|
||||
int scale_factor;
|
||||
|
||||
if (priv->impl == NULL)
|
||||
return;
|
||||
@ -465,11 +465,6 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
*/
|
||||
_clutter_stage_window_get_geometry (priv->impl, &window_size);
|
||||
|
||||
scale_factor = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
|
||||
window_size.width *= scale_factor;
|
||||
window_size.height *= scale_factor;
|
||||
|
||||
cogl_onscreen_clutter_backend_set_size (window_size.width,
|
||||
window_size.height);
|
||||
|
||||
@ -630,15 +625,13 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
||||
float clip_poly[8];
|
||||
float viewport[4];
|
||||
cairo_rectangle_int_t geom;
|
||||
int window_scale;
|
||||
|
||||
_clutter_stage_window_get_geometry (priv->impl, &geom);
|
||||
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
|
||||
viewport[0] = priv->viewport[0] * window_scale;
|
||||
viewport[1] = priv->viewport[1] * window_scale;
|
||||
viewport[2] = priv->viewport[2] * window_scale;
|
||||
viewport[3] = priv->viewport[3] * window_scale;
|
||||
viewport[0] = priv->viewport[0];
|
||||
viewport[1] = priv->viewport[1];
|
||||
viewport[2] = priv->viewport[2];
|
||||
viewport[3] = priv->viewport[3];
|
||||
|
||||
if (!clip)
|
||||
{
|
||||
@ -646,16 +639,14 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
||||
clip = &view_layout;
|
||||
}
|
||||
|
||||
clip_poly[0] = MAX (clip->x * window_scale, 0);
|
||||
clip_poly[1] = MAX (clip->y * window_scale, 0);
|
||||
clip_poly[0] = MAX (clip->x, 0);
|
||||
clip_poly[1] = MAX (clip->y, 0);
|
||||
|
||||
clip_poly[2] = MIN ((clip->x + clip->width) * window_scale,
|
||||
geom.width * window_scale);
|
||||
clip_poly[2] = MIN (clip->x + clip->width, geom.width);
|
||||
clip_poly[3] = clip_poly[1];
|
||||
|
||||
clip_poly[4] = clip_poly[2];
|
||||
clip_poly[5] = MIN ((clip->y + clip->height) * window_scale,
|
||||
geom.height * window_scale);
|
||||
clip_poly[5] = MIN (clip->y + clip->height, geom.height);
|
||||
|
||||
clip_poly[6] = clip_poly[0];
|
||||
clip_poly[7] = clip_poly[5];
|
||||
@ -971,6 +962,7 @@ _clutter_stage_process_queued_events (ClutterStage *stage)
|
||||
ClutterEvent *next_event;
|
||||
ClutterInputDevice *device;
|
||||
ClutterInputDevice *next_device;
|
||||
ClutterInputDeviceType device_type;
|
||||
gboolean check_device = FALSE;
|
||||
|
||||
event = l->data;
|
||||
@ -986,8 +978,16 @@ _clutter_stage_process_queued_events (ClutterStage *stage)
|
||||
if (device != NULL && next_device != NULL)
|
||||
check_device = TRUE;
|
||||
|
||||
/* Skip consecutive motion events coming from the same device */
|
||||
if (priv->throttle_motion_events && next_event != NULL)
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
|
||||
/* Skip consecutive motion events coming from the same device,
|
||||
* except those of tablet tools, since users of these events
|
||||
* want no precision loss.
|
||||
*/
|
||||
if (priv->throttle_motion_events && next_event != NULL &&
|
||||
device_type != CLUTTER_TABLET_DEVICE &&
|
||||
device_type != CLUTTER_PEN_DEVICE &&
|
||||
device_type != CLUTTER_ERASER_DEVICE)
|
||||
{
|
||||
if (event->type == CLUTTER_MOTION &&
|
||||
(next_event->type == CLUTTER_MOTION ||
|
||||
@ -1069,6 +1069,7 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
|
||||
if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
|
||||
{
|
||||
priv->relayout_pending = FALSE;
|
||||
priv->stage_was_relayout = TRUE;
|
||||
|
||||
CLUTTER_NOTE (ACTOR, "Recomputing layout");
|
||||
|
||||
@ -1139,6 +1140,58 @@ clutter_stage_do_redraw (ClutterStage *stage)
|
||||
stage);
|
||||
}
|
||||
|
||||
static GSList *
|
||||
_clutter_stage_check_updated_pointers (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
ClutterDeviceManager *device_manager;
|
||||
GSList *updating = NULL;
|
||||
const GSList *devices;
|
||||
cairo_rectangle_int_t clip;
|
||||
ClutterPoint point;
|
||||
gboolean has_clip;
|
||||
|
||||
has_clip = _clutter_stage_window_get_redraw_clip_bounds (priv->impl, &clip);
|
||||
|
||||
device_manager = clutter_device_manager_get_default ();
|
||||
devices = clutter_device_manager_peek_devices (device_manager);
|
||||
|
||||
for (; devices != NULL; devices = devices->next)
|
||||
{
|
||||
ClutterInputDevice *dev = devices->data;
|
||||
|
||||
if (clutter_input_device_get_device_mode (dev) !=
|
||||
CLUTTER_INPUT_MODE_MASTER)
|
||||
continue;
|
||||
|
||||
switch (clutter_input_device_get_device_type (dev))
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
case CLUTTER_TABLET_DEVICE:
|
||||
case CLUTTER_PEN_DEVICE:
|
||||
case CLUTTER_ERASER_DEVICE:
|
||||
case CLUTTER_CURSOR_DEVICE:
|
||||
if (!clutter_input_device_get_coords (dev, NULL, &point))
|
||||
continue;
|
||||
|
||||
if (!has_clip ||
|
||||
(point.x >= clip.x && point.x < clip.x + clip.width &&
|
||||
point.y >= clip.y && point.y < clip.y + clip.height))
|
||||
updating = g_slist_prepend (updating, dev);
|
||||
break;
|
||||
default:
|
||||
/* Any other devices don't need checking, either because they
|
||||
* don't have x/y coordinates, or because they're implicitly
|
||||
* grabbed on an actor by default as it's the case of
|
||||
* touch(screens).
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return updating;
|
||||
}
|
||||
|
||||
/**
|
||||
* _clutter_stage_do_update:
|
||||
* @stage: A #ClutterStage
|
||||
@ -1151,6 +1204,10 @@ gboolean
|
||||
_clutter_stage_do_update (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
gboolean stage_was_relayout = priv->stage_was_relayout;
|
||||
GSList *pointers = NULL;
|
||||
|
||||
priv->stage_was_relayout = FALSE;
|
||||
|
||||
/* if the stage is being destroyed, or if the destruction already
|
||||
* happened and we don't have an StageWindow any more, then we
|
||||
@ -1171,6 +1228,9 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
if (!priv->redraw_pending)
|
||||
return FALSE;
|
||||
|
||||
if (stage_was_relayout)
|
||||
pointers = _clutter_stage_check_updated_pointers (stage);
|
||||
|
||||
clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
|
||||
clutter_stage_do_redraw (stage);
|
||||
@ -1188,6 +1248,12 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
}
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
while (pointers)
|
||||
{
|
||||
_clutter_input_device_update (pointers->data, NULL, TRUE);
|
||||
pointers = g_slist_delete_link (pointers, pointers);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1378,19 +1444,19 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
|
||||
gint dirty_y;
|
||||
gint read_x;
|
||||
gint read_y;
|
||||
int window_scale;
|
||||
float fb_width, fb_height;
|
||||
int viewport_offset_x;
|
||||
int viewport_offset_y;
|
||||
float fb_scale;
|
||||
float viewport_offset_x;
|
||||
float viewport_offset_y;
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
context = _clutter_context_get_default ();
|
||||
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
fb_width = view_layout.width;
|
||||
fb_height = view_layout.height;
|
||||
fb_width = view_layout.width * fb_scale;
|
||||
fb_height = view_layout.height * fb_scale;
|
||||
cogl_push_framebuffer (fb);
|
||||
|
||||
/* needed for when a context switch happens */
|
||||
@ -1400,38 +1466,38 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
|
||||
* picking to not work at all, so setting it the whole framebuffer content
|
||||
* for now. */
|
||||
cogl_framebuffer_push_scissor_clip (fb, 0, 0,
|
||||
view_layout.width,
|
||||
view_layout.height);
|
||||
view_layout.width * fb_scale,
|
||||
view_layout.height * fb_scale);
|
||||
|
||||
_clutter_stage_window_get_dirty_pixel (priv->impl, view, &dirty_x, &dirty_y);
|
||||
|
||||
if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
|
||||
{
|
||||
CLUTTER_NOTE (PICK, "Pushing pick scissor clip x: %d, y: %d, 1x1",
|
||||
dirty_x * window_scale,
|
||||
dirty_y * window_scale);
|
||||
cogl_framebuffer_push_scissor_clip (fb, dirty_x * window_scale, dirty_y * window_scale, 1, 1);
|
||||
(int) dirty_x * fb_scale,
|
||||
(int) dirty_y * fb_scale);
|
||||
cogl_framebuffer_push_scissor_clip (fb, dirty_x * fb_scale, dirty_y * fb_scale, 1, 1);
|
||||
}
|
||||
|
||||
viewport_offset_x = x * window_scale - dirty_x * window_scale;
|
||||
viewport_offset_y = y * window_scale - dirty_y * window_scale;
|
||||
viewport_offset_x = x * fb_scale - dirty_x * fb_scale;
|
||||
viewport_offset_y = y * fb_scale - dirty_y * fb_scale;
|
||||
CLUTTER_NOTE (PICK, "Setting viewport to %f, %f, %f, %f",
|
||||
priv->viewport[0] * window_scale - viewport_offset_x,
|
||||
priv->viewport[1] * window_scale - viewport_offset_y,
|
||||
priv->viewport[2] * window_scale,
|
||||
priv->viewport[3] * window_scale);
|
||||
cogl_set_viewport (priv->viewport[0] * window_scale - viewport_offset_x,
|
||||
priv->viewport[1] * window_scale - viewport_offset_y,
|
||||
priv->viewport[2] * window_scale,
|
||||
priv->viewport[3] * window_scale);
|
||||
priv->viewport[0] * fb_scale - viewport_offset_x,
|
||||
priv->viewport[1] * fb_scale - viewport_offset_y,
|
||||
priv->viewport[2] * fb_scale,
|
||||
priv->viewport[3] * fb_scale);
|
||||
cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x,
|
||||
priv->viewport[1] * fb_scale - viewport_offset_y,
|
||||
priv->viewport[2] * fb_scale,
|
||||
priv->viewport[3] * fb_scale);
|
||||
|
||||
read_x = dirty_x * window_scale;
|
||||
read_y = dirty_y * window_scale;
|
||||
read_x = dirty_x * fb_scale;
|
||||
read_y = dirty_y * fb_scale;
|
||||
|
||||
CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d",
|
||||
CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d s: %d",
|
||||
x, y,
|
||||
view_layout.width, view_layout.height,
|
||||
view_layout.x, view_layout.y);
|
||||
view_layout.x, view_layout.y, fb_scale);
|
||||
|
||||
cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255);
|
||||
cogl_clear (&stage_pick_id, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH);
|
||||
@ -2186,8 +2252,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
g_signal_new (I_("presented"),
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__INT_POINTER,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_INT, G_TYPE_POINTER);
|
||||
|
||||
@ -2210,7 +2276,6 @@ clutter_stage_init (ClutterStage *self)
|
||||
ClutterStagePrivate *priv;
|
||||
ClutterStageWindow *impl;
|
||||
ClutterBackend *backend;
|
||||
int window_scale = 1;
|
||||
GError *error;
|
||||
|
||||
/* a stage is a top-level object */
|
||||
@ -2228,7 +2293,6 @@ clutter_stage_init (ClutterStage *self)
|
||||
{
|
||||
_clutter_stage_set_window (self, impl);
|
||||
_clutter_stage_window_get_geometry (priv->impl, &geom);
|
||||
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2282,8 +2346,8 @@ clutter_stage_init (ClutterStage *self)
|
||||
priv->perspective.aspect,
|
||||
priv->perspective.z_near,
|
||||
50, /* distance to 2d plane */
|
||||
geom.width * window_scale,
|
||||
geom.height * window_scale);
|
||||
geom.width,
|
||||
geom.height);
|
||||
|
||||
|
||||
/* FIXME - remove for 2.0 */
|
||||
@ -3412,16 +3476,6 @@ clutter_stage_ensure_viewport (ClutterStage *stage)
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_apply_scale (ClutterStage *stage)
|
||||
{
|
||||
int factor;
|
||||
|
||||
factor = _clutter_stage_window_get_scale_factor (stage->priv->impl);
|
||||
if (factor != 1)
|
||||
cogl_matrix_scale (&stage->priv->view, factor, factor, 1.f);
|
||||
}
|
||||
|
||||
# define _DEG_TO_RAD(d) ((d) * ((float) G_PI / 180.0f))
|
||||
|
||||
/* This calculates a distance into the view frustum to position the
|
||||
@ -3568,9 +3622,9 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
{
|
||||
cairo_rectangle_int_t view_layout;
|
||||
ClutterPerspective perspective;
|
||||
int window_scale;
|
||||
int viewport_offset_x;
|
||||
int viewport_offset_y;
|
||||
float fb_scale;
|
||||
float viewport_offset_x;
|
||||
float viewport_offset_y;
|
||||
float z_2d;
|
||||
|
||||
CLUTTER_NOTE (PAINT,
|
||||
@ -3578,15 +3632,15 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
priv->viewport[2],
|
||||
priv->viewport[3]);
|
||||
|
||||
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
viewport_offset_x = view_layout.x * window_scale;
|
||||
viewport_offset_y = view_layout.y * window_scale;
|
||||
cogl_set_viewport (priv->viewport[0] * window_scale - viewport_offset_x,
|
||||
priv->viewport[1] * window_scale - viewport_offset_y,
|
||||
priv->viewport[2] * window_scale,
|
||||
priv->viewport[3] * window_scale);
|
||||
viewport_offset_x = view_layout.x * fb_scale;
|
||||
viewport_offset_y = view_layout.y * fb_scale;
|
||||
cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x,
|
||||
priv->viewport[1] * fb_scale - viewport_offset_y,
|
||||
priv->viewport[2] * fb_scale,
|
||||
priv->viewport[3] * fb_scale);
|
||||
|
||||
perspective = priv->perspective;
|
||||
|
||||
@ -3617,10 +3671,8 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
perspective.aspect,
|
||||
perspective.z_near,
|
||||
z_2d,
|
||||
priv->viewport[2] * window_scale,
|
||||
priv->viewport[3] * window_scale);
|
||||
|
||||
clutter_stage_apply_scale (stage);
|
||||
priv->viewport[2],
|
||||
priv->viewport[3]);
|
||||
|
||||
clutter_stage_view_set_dirty_viewport (view, FALSE);
|
||||
}
|
||||
@ -4635,23 +4687,6 @@ clutter_stage_skip_sync_delay (ClutterStage *stage)
|
||||
_clutter_stage_window_schedule_update (stage_window, -1);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_set_scale_factor (ClutterStage *stage,
|
||||
int factor)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
|
||||
return;
|
||||
|
||||
if (priv->impl == NULL)
|
||||
return;
|
||||
|
||||
_clutter_stage_window_set_scale_factor (priv->impl, factor);
|
||||
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
int64_t
|
||||
clutter_stage_get_frame_counter (ClutterStage *stage)
|
||||
{
|
||||
@ -4685,18 +4720,22 @@ capture_view (ClutterStage *stage,
|
||||
int stride;
|
||||
CoglBitmap *bitmap;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
float view_scale;
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
|
||||
if (paint)
|
||||
{
|
||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||
cogl_push_framebuffer (framebuffer);
|
||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||
clutter_stage_do_paint_view (stage, view, rect);
|
||||
}
|
||||
|
||||
view_scale = clutter_stage_view_get_scale (view);
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
rect->width, rect->height);
|
||||
rect->width * view_scale,
|
||||
rect->height * view_scale);
|
||||
cairo_surface_set_device_scale (image, view_scale, view_scale);
|
||||
|
||||
data = cairo_image_surface_get_data (image);
|
||||
stride = cairo_image_surface_get_stride (image);
|
||||
@ -4704,7 +4743,8 @@ capture_view (ClutterStage *stage,
|
||||
backend = clutter_get_default_backend ();
|
||||
context = clutter_backend_get_cogl_context (backend);
|
||||
bitmap = cogl_bitmap_new_for_data (context,
|
||||
rect->width, rect->height,
|
||||
rect->width * view_scale,
|
||||
rect->height * view_scale,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
stride,
|
||||
data);
|
||||
@ -4712,8 +4752,8 @@ capture_view (ClutterStage *stage,
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
||||
rect->x - view_layout.x,
|
||||
rect->y - view_layout.y,
|
||||
(rect->x - view_layout.x) * view_scale,
|
||||
(rect->y - view_layout.y) * view_scale,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
bitmap);
|
||||
|
||||
@ -4770,3 +4810,93 @@ clutter_stage_capture (ClutterStage *stage,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
capture_view_into (ClutterStage *stage,
|
||||
gboolean paint,
|
||||
ClutterStageView *view,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data,
|
||||
int stride)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
ClutterBackend *backend;
|
||||
CoglContext *context;
|
||||
CoglBitmap *bitmap;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
|
||||
if (paint)
|
||||
{
|
||||
cogl_push_framebuffer (framebuffer);
|
||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||
clutter_stage_do_paint_view (stage, view, rect);
|
||||
}
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
context = clutter_backend_get_cogl_context (backend);
|
||||
bitmap = cogl_bitmap_new_for_data (context,
|
||||
rect->width, rect->height,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
stride,
|
||||
data);
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
||||
rect->x - view_layout.x,
|
||||
rect->y - view_layout.y,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
bitmap);
|
||||
|
||||
if (paint)
|
||||
cogl_pop_framebuffer ();
|
||||
|
||||
cogl_object_unref (bitmap);
|
||||
}
|
||||
|
||||
static ClutterStageView *
|
||||
get_view_at_rect (ClutterStage *stage,
|
||||
cairo_rectangle_int_t *rect)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
GList *views = _clutter_stage_window_get_views (priv->impl);
|
||||
GList *l;
|
||||
|
||||
for (l = views; l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
cairo_region_t *region;
|
||||
cairo_rectangle_int_t view_capture_rect;
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
region = cairo_region_create_rectangle (&view_layout);
|
||||
cairo_region_intersect_rectangle (region, rect);
|
||||
cairo_region_get_extents (region, &view_capture_rect);
|
||||
cairo_region_destroy (region);
|
||||
|
||||
if (view_capture_rect.width == 0 || view_capture_rect.height == 0)
|
||||
continue;
|
||||
|
||||
g_assert (view_capture_rect.width == rect->width &&
|
||||
view_capture_rect.height == rect->height);
|
||||
return view;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_capture_into (ClutterStage *stage,
|
||||
gboolean paint,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data)
|
||||
{
|
||||
ClutterStageView *view;
|
||||
int bpp = 4;
|
||||
|
||||
view = get_view_at_rect (stage, rect);
|
||||
capture_view_into (stage, paint, view, rect, data, rect->width * bpp);
|
||||
}
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "clutter-units.h"
|
||||
#include "clutter-paint-volume-private.h"
|
||||
#include "clutter-scriptable.h"
|
||||
#include "clutter-input-focus.h"
|
||||
|
||||
/* cursor width in pixels */
|
||||
#define DEFAULT_CURSOR_SIZE 2
|
||||
@ -176,6 +177,9 @@ struct _ClutterTextPrivate
|
||||
/* Signal handler for when the :text-direction changes */
|
||||
guint direction_changed_id;
|
||||
|
||||
ClutterInputContentHintFlags input_hints;
|
||||
ClutterInputContentPurpose input_purpose;
|
||||
|
||||
/* bitfields */
|
||||
guint alignment : 2;
|
||||
guint wrap : 1;
|
||||
@ -236,6 +240,8 @@ enum
|
||||
PROP_SINGLE_LINE_MODE,
|
||||
PROP_SELECTED_TEXT_COLOR,
|
||||
PROP_SELECTED_TEXT_COLOR_SET,
|
||||
PROP_INPUT_HINTS,
|
||||
PROP_INPUT_PURPOSE,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
@ -269,6 +275,7 @@ static const ClutterColor default_selected_text_color = { 0, 0, 0, 255 };
|
||||
static ClutterAnimatableIface *parent_animatable_iface = NULL;
|
||||
static ClutterScriptableIface *parent_scriptable_iface = NULL;
|
||||
|
||||
static void clutter_input_focus_iface_init (ClutterInputFocusInterface *iface);
|
||||
static void clutter_scriptable_iface_init (ClutterScriptableIface *iface);
|
||||
static void clutter_animatable_iface_init (ClutterAnimatableIface *iface);
|
||||
|
||||
@ -276,11 +283,91 @@ G_DEFINE_TYPE_WITH_CODE (ClutterText,
|
||||
clutter_text,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_ADD_PRIVATE (ClutterText)
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_INPUT_FOCUS,
|
||||
clutter_input_focus_iface_init)
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE,
|
||||
clutter_scriptable_iface_init)
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_ANIMATABLE,
|
||||
clutter_animatable_iface_init));
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_request_surrounding (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterText *clutter_text = CLUTTER_TEXT (focus);
|
||||
ClutterTextBuffer *buffer;
|
||||
const gchar *text;
|
||||
gint anchor_pos, cursor_pos;
|
||||
|
||||
buffer = clutter_text_get_buffer (clutter_text);
|
||||
text = clutter_text_buffer_get_text (buffer);
|
||||
|
||||
cursor_pos = clutter_text_get_cursor_position (clutter_text);
|
||||
if (cursor_pos < 0)
|
||||
cursor_pos = clutter_text_buffer_get_length (buffer);
|
||||
|
||||
anchor_pos = clutter_text_get_selection_bound (clutter_text);
|
||||
if (anchor_pos < 0)
|
||||
anchor_pos = cursor_pos;
|
||||
|
||||
clutter_input_focus_set_surrounding (focus, text,
|
||||
g_utf8_offset_to_pointer (text, cursor_pos) - text,
|
||||
g_utf8_offset_to_pointer (text, anchor_pos) - text);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_delete_surrounding (ClutterInputFocus *focus,
|
||||
guint offset,
|
||||
guint len)
|
||||
{
|
||||
ClutterText *clutter_text = CLUTTER_TEXT (focus);
|
||||
|
||||
if (clutter_text_get_editable (clutter_text))
|
||||
clutter_text_delete_text (clutter_text, offset, len);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_commit_text (ClutterInputFocus *focus,
|
||||
const gchar *text)
|
||||
{
|
||||
ClutterText *clutter_text = CLUTTER_TEXT (focus);
|
||||
|
||||
if (clutter_text_get_editable (clutter_text))
|
||||
{
|
||||
clutter_text_delete_selection (clutter_text);
|
||||
clutter_text_insert_text (clutter_text, text,
|
||||
clutter_text_get_cursor_position (clutter_text));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_set_preedit_text (ClutterInputFocus *focus,
|
||||
const gchar *preedit_text,
|
||||
guint cursor_pos)
|
||||
{
|
||||
ClutterText *clutter_text = CLUTTER_TEXT (focus);
|
||||
|
||||
if (clutter_text_get_editable (clutter_text))
|
||||
{
|
||||
PangoAttrList *list;
|
||||
|
||||
list = pango_attr_list_new ();
|
||||
pango_attr_list_insert (list, pango_attr_underline_new (PANGO_UNDERLINE_SINGLE));
|
||||
clutter_text_set_preedit_string (clutter_text,
|
||||
preedit_text, list,
|
||||
cursor_pos);
|
||||
pango_attr_list_unref (list);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_focus_iface_init (ClutterInputFocusInterface *iface)
|
||||
{
|
||||
iface->request_surrounding = clutter_text_input_focus_request_surrounding;
|
||||
iface->delete_surrounding = clutter_text_input_focus_delete_surrounding;
|
||||
iface->commit_text = clutter_text_input_focus_commit_text;
|
||||
iface->set_preedit_text = clutter_text_input_focus_set_preedit_text;
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_text_dirty_paint_volume (ClutterText *text)
|
||||
{
|
||||
@ -1009,6 +1096,22 @@ clutter_text_position_to_coords (ClutterText *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
update_cursor_location (ClutterText *self)
|
||||
{
|
||||
ClutterTextPrivate *priv = self->priv;
|
||||
ClutterRect rect;
|
||||
float x, y;
|
||||
|
||||
if (!priv->editable)
|
||||
return;
|
||||
|
||||
rect = priv->cursor_rect;
|
||||
clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &x, &y);
|
||||
clutter_rect_offset (&rect, x, y);
|
||||
clutter_input_focus_set_cursor_location (CLUTTER_INPUT_FOCUS (self), &rect);
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_text_ensure_cursor_position (ClutterText *self)
|
||||
{
|
||||
@ -1057,6 +1160,8 @@ clutter_text_ensure_cursor_position (ClutterText *self)
|
||||
g_signal_emit (self, text_signals[CURSOR_EVENT], 0, &cursor_pos);
|
||||
|
||||
g_signal_emit (self, text_signals[CURSOR_CHANGED], 0);
|
||||
|
||||
update_cursor_location (self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1859,6 +1964,7 @@ clutter_text_press (ClutterActor *actor,
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
clutter_actor_grab_key_focus (actor);
|
||||
clutter_input_focus_request_toggle_input_panel (CLUTTER_INPUT_FOCUS (self));
|
||||
|
||||
/* if the actor is empty we just reset everything and not
|
||||
* set up the dragging of the selection since there's nothing
|
||||
@ -2085,9 +2191,11 @@ clutter_text_key_press (ClutterActor *actor,
|
||||
g_assert (pool != NULL);
|
||||
|
||||
/* we allow passing synthetic events that only contain
|
||||
* the Unicode value and not the key symbol
|
||||
* the Unicode value and not the key symbol, unless they
|
||||
* contain the input method flag.
|
||||
*/
|
||||
if (event->keyval == 0 && (event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC))
|
||||
if (event->keyval == 0 && (event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC) &&
|
||||
!(event->flags & CLUTTER_EVENT_FLAG_INPUT_METHOD))
|
||||
res = FALSE;
|
||||
else
|
||||
res = clutter_binding_pool_activate (pool, event->keyval,
|
||||
@ -2105,6 +2213,9 @@ clutter_text_key_press (ClutterActor *actor,
|
||||
{
|
||||
gunichar key_unichar;
|
||||
|
||||
if (clutter_input_focus_filter_key_event (CLUTTER_INPUT_FOCUS (actor), event))
|
||||
return CLUTTER_EVENT_STOP;
|
||||
|
||||
/* Skip keys when control is pressed */
|
||||
key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) event);
|
||||
|
||||
@ -2141,6 +2252,16 @@ clutter_text_key_press (ClutterActor *actor,
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_text_key_release (ClutterActor *actor,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
if (clutter_input_focus_filter_key_event (CLUTTER_INPUT_FOCUS (actor), event))
|
||||
return CLUTTER_EVENT_STOP;
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_compute_layout_offsets (ClutterText *self,
|
||||
PangoLayout *layout,
|
||||
@ -2664,6 +2785,9 @@ clutter_text_key_focus_in (ClutterActor *actor)
|
||||
{
|
||||
ClutterTextPrivate *priv = CLUTTER_TEXT (actor)->priv;
|
||||
|
||||
if (priv->editable)
|
||||
clutter_input_focus_focus_in (CLUTTER_INPUT_FOCUS (actor));
|
||||
|
||||
priv->has_focus = TRUE;
|
||||
|
||||
clutter_text_queue_redraw (actor);
|
||||
@ -2676,6 +2800,9 @@ clutter_text_key_focus_out (ClutterActor *actor)
|
||||
|
||||
priv->has_focus = FALSE;
|
||||
|
||||
if (priv->editable)
|
||||
clutter_input_focus_focus_out (CLUTTER_INPUT_FOCUS (actor));
|
||||
|
||||
clutter_text_queue_redraw (actor);
|
||||
}
|
||||
|
||||
@ -3369,6 +3496,7 @@ clutter_text_class_init (ClutterTextClass *klass)
|
||||
actor_class->get_preferred_height = clutter_text_get_preferred_height;
|
||||
actor_class->allocate = clutter_text_allocate;
|
||||
actor_class->key_press_event = clutter_text_key_press;
|
||||
actor_class->key_release_event = clutter_text_key_release;
|
||||
actor_class->button_press_event = clutter_text_button_press;
|
||||
actor_class->button_release_event = clutter_text_button_release;
|
||||
actor_class->motion_event = clutter_text_motion;
|
||||
@ -3869,6 +3997,22 @@ clutter_text_class_init (ClutterTextClass *klass)
|
||||
obj_props[PROP_SELECTED_TEXT_COLOR_SET] = pspec;
|
||||
g_object_class_install_property (gobject_class, PROP_SELECTED_TEXT_COLOR_SET, pspec);
|
||||
|
||||
pspec = g_param_spec_flags ("input-hints",
|
||||
P_("Input hints"),
|
||||
P_("Input hints"),
|
||||
CLUTTER_TYPE_INPUT_CONTENT_HINT_FLAGS,
|
||||
0, CLUTTER_PARAM_READWRITE);
|
||||
obj_props[PROP_INPUT_HINTS] = pspec;
|
||||
g_object_class_install_property (gobject_class, PROP_INPUT_HINTS, pspec);
|
||||
|
||||
pspec = g_param_spec_enum ("input-purpose",
|
||||
P_("Input purpose"),
|
||||
P_("Input purpose"),
|
||||
CLUTTER_TYPE_INPUT_CONTENT_PURPOSE,
|
||||
0, CLUTTER_PARAM_READWRITE);
|
||||
obj_props[PROP_INPUT_PURPOSE] = pspec;
|
||||
g_object_class_install_property (gobject_class, PROP_INPUT_PURPOSE, pspec);
|
||||
|
||||
/**
|
||||
* ClutterText::text-changed:
|
||||
* @self: the #ClutterText that emitted the signal
|
||||
@ -4469,6 +4613,11 @@ clutter_text_set_editable (ClutterText *self,
|
||||
{
|
||||
priv->editable = editable;
|
||||
|
||||
if (!priv->editable)
|
||||
clutter_input_focus_focus_out (CLUTTER_INPUT_FOCUS (self));
|
||||
else if (priv->has_focus)
|
||||
clutter_input_focus_focus_in (CLUTTER_INPUT_FOCUS (self));
|
||||
|
||||
clutter_text_queue_redraw (CLUTTER_ACTOR (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_EDITABLE]);
|
||||
@ -6298,3 +6447,49 @@ clutter_text_get_cursor_rect (ClutterText *self,
|
||||
|
||||
*rect = self->priv->cursor_rect;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_text_set_input_hints (ClutterText *self,
|
||||
ClutterInputContentHintFlags hints)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
||||
|
||||
self->priv->input_hints = hints;
|
||||
clutter_input_focus_set_content_hints (CLUTTER_INPUT_FOCUS (self), hints);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_HINTS]);
|
||||
}
|
||||
|
||||
ClutterInputContentHintFlags
|
||||
clutter_text_get_input_hints (ClutterText *self)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0);
|
||||
|
||||
return self->priv->input_hints;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_text_set_input_purpose (ClutterText *self,
|
||||
ClutterInputContentPurpose purpose)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
||||
|
||||
self->priv->input_purpose = purpose;
|
||||
clutter_input_focus_set_content_purpose (CLUTTER_INPUT_FOCUS (self), purpose);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_PURPOSE]);
|
||||
}
|
||||
|
||||
ClutterInputContentPurpose
|
||||
clutter_text_get_input_purpose (ClutterText *self)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0);
|
||||
|
||||
return self->priv->input_purpose;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_text_has_preedit (ClutterText *self)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE);
|
||||
|
||||
return self->priv->preedit_set;
|
||||
}
|
||||
|
@ -302,6 +302,20 @@ void clutter_text_get_layout_offsets (ClutterText *
|
||||
gint *x,
|
||||
gint *y);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_text_set_input_hints (ClutterText *self,
|
||||
ClutterInputContentHintFlags hints);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_text_set_input_purpose (ClutterText *self,
|
||||
ClutterInputContentPurpose purpose);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
ClutterInputContentHintFlags clutter_text_get_input_hints (ClutterText *self);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
ClutterInputContentPurpose clutter_text_get_input_purpose (ClutterText *self);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
gboolean clutter_text_has_preedit (ClutterText *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_TEXT_H__ */
|
||||
|
@ -97,6 +97,9 @@ typedef struct _ClutterInputDeviceTool ClutterInputDeviceTool;
|
||||
typedef struct _ClutterInputDevice ClutterInputDevice;
|
||||
typedef struct _ClutterVirtualInputDevice ClutterVirtualInputDevice;
|
||||
|
||||
typedef struct _ClutterInputMethod ClutterInputMethod;
|
||||
typedef struct _ClutterInputFocus ClutterInputFocus;
|
||||
|
||||
typedef CoglMatrix ClutterMatrix;
|
||||
|
||||
typedef union _ClutterEvent ClutterEvent;
|
||||
|
@ -312,7 +312,7 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
const guint clutter_major_version;
|
||||
extern const guint clutter_major_version;
|
||||
|
||||
/**
|
||||
* clutter_minor_version:
|
||||
@ -326,7 +326,7 @@ const guint clutter_major_version;
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
const guint clutter_minor_version;
|
||||
extern const guint clutter_minor_version;
|
||||
|
||||
/**
|
||||
* clutter_micro_version:
|
||||
@ -340,7 +340,7 @@ const guint clutter_minor_version;
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
const guint clutter_micro_version;
|
||||
extern const guint clutter_micro_version;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -115,6 +115,19 @@ clutter_virtual_input_device_notify_keyval (ClutterVirtualInputDevice *virtual_d
|
||||
klass->notify_keyval (virtual_device, time_us, keyval, key_state);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_virtual_input_device_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
ClutterVirtualInputDeviceClass *klass =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
|
||||
|
||||
klass->notify_discrete_scroll (virtual_device, time_us,
|
||||
direction, scroll_source);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_virtual_input_device_get_manager:
|
||||
* @virtual_device: a virtual device
|
||||
|
@ -76,6 +76,11 @@ struct _ClutterVirtualInputDeviceClass
|
||||
uint64_t time_us,
|
||||
uint32_t keyval,
|
||||
ClutterKeyState key_state);
|
||||
|
||||
void (*notify_discrete_scroll) (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source);
|
||||
};
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
@ -108,6 +113,13 @@ void clutter_virtual_input_device_notify_keyval (ClutterVirtualInputDevice *virt
|
||||
uint32_t keyval,
|
||||
ClutterKeyState key_state);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_virtual_input_device_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source);
|
||||
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
ClutterDeviceManager * clutter_virtual_input_device_get_manager (ClutterVirtualInputDevice *virtual_device);
|
||||
|
||||
|
@ -72,6 +72,8 @@
|
||||
#include "clutter-image.h"
|
||||
#include "clutter-input-device.h"
|
||||
#include "clutter-input-device-tool.h"
|
||||
#include "clutter-input-method.h"
|
||||
#include "clutter-input-focus.h"
|
||||
#include "clutter-interval.h"
|
||||
#include "clutter-keyframe-transition.h"
|
||||
#include "clutter-keysyms.h"
|
||||
|
@ -51,7 +51,9 @@
|
||||
|
||||
typedef struct _ClutterStageViewCoglPrivate
|
||||
{
|
||||
/* Stores a list of previous damaged areas in the stage coordinate space */
|
||||
/*
|
||||
* List of previous damaged areas in stage view framebuffer coordinate space.
|
||||
*/
|
||||
#define DAMAGE_HISTORY_MAX 16
|
||||
#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
|
||||
cairo_rectangle_int_t damage_history[DAMAGE_HISTORY_MAX];
|
||||
@ -435,13 +437,20 @@ fill_current_damage_history_and_step (ClutterStageView *view)
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
cairo_rectangle_int_t view_rect;
|
||||
cairo_rectangle_int_t *current_damage;
|
||||
float fb_scale;
|
||||
cairo_rectangle_int_t *current_fb_damage;
|
||||
|
||||
current_damage =
|
||||
current_fb_damage =
|
||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
|
||||
clutter_stage_view_get_layout (view, &view_rect);
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
|
||||
*current_damage = view_rect;
|
||||
*current_fb_damage = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale
|
||||
};
|
||||
view_priv->damage_index++;
|
||||
}
|
||||
|
||||
@ -481,6 +490,40 @@ transform_swap_region_to_onscreen (ClutterStageView *view,
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_scissor_region (cairo_rectangle_int_t *fb_clip_region,
|
||||
int subpixel_compensation,
|
||||
int fb_width,
|
||||
int fb_height,
|
||||
cairo_rectangle_int_t *out_scissor_rect)
|
||||
{
|
||||
int scissor_x;
|
||||
int scissor_y;
|
||||
int scissor_width;
|
||||
int scissor_height;
|
||||
|
||||
scissor_x = fb_clip_region->x;
|
||||
scissor_y = fb_clip_region->y;
|
||||
scissor_width = fb_clip_region->width;
|
||||
scissor_height = fb_clip_region->height;
|
||||
|
||||
if (fb_clip_region->x > 0)
|
||||
scissor_x += subpixel_compensation;
|
||||
if (fb_clip_region->y > 0)
|
||||
scissor_y += subpixel_compensation;
|
||||
if (fb_clip_region->x + fb_clip_region->width < fb_width)
|
||||
scissor_width -= 2 * subpixel_compensation;
|
||||
if (fb_clip_region->y + fb_clip_region->height < fb_height)
|
||||
scissor_height -= 2 * subpixel_compensation;
|
||||
|
||||
*out_scissor_rect = (cairo_rectangle_int_t) {
|
||||
.x = scissor_x,
|
||||
.y = scissor_y,
|
||||
.width = scissor_width,
|
||||
.height = scissor_height
|
||||
};
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
ClutterStageView *view)
|
||||
@ -501,13 +544,18 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
ClutterActor *wrapper;
|
||||
cairo_rectangle_int_t redraw_clip;
|
||||
cairo_rectangle_int_t swap_region;
|
||||
cairo_rectangle_int_t clip_region;
|
||||
cairo_rectangle_int_t fb_clip_region;
|
||||
gboolean clip_region_empty;
|
||||
int window_scale;
|
||||
float fb_scale;
|
||||
int subpixel_compensation = 0;
|
||||
int fb_width, fb_height;
|
||||
|
||||
wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_rect);
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
fb_width = cogl_framebuffer_get_width (fb);
|
||||
fb_height = cogl_framebuffer_get_height (fb);
|
||||
|
||||
can_blit_sub_buffer =
|
||||
cogl_is_onscreen (fb) &&
|
||||
@ -542,11 +590,24 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
|
||||
{
|
||||
may_use_clipped_redraw = TRUE;
|
||||
clip_region = redraw_clip;
|
||||
|
||||
if (fb_scale != floorf (fb_scale))
|
||||
subpixel_compensation = ceilf (fb_scale);
|
||||
|
||||
fb_clip_region = (cairo_rectangle_int_t) {
|
||||
.x = (floorf ((redraw_clip.x - view_rect.x) * fb_scale) -
|
||||
subpixel_compensation),
|
||||
.y = (floorf ((redraw_clip.y - view_rect.y) * fb_scale) -
|
||||
subpixel_compensation),
|
||||
.width = (ceilf (redraw_clip.width * fb_scale) +
|
||||
(2 * subpixel_compensation)),
|
||||
.height = (ceilf (redraw_clip.height * fb_scale) +
|
||||
(2 * subpixel_compensation))
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
clip_region = (cairo_rectangle_int_t){ 0 };
|
||||
fb_clip_region = (cairo_rectangle_int_t) { 0 };
|
||||
}
|
||||
|
||||
if (may_use_clipped_redraw &&
|
||||
@ -555,9 +616,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
else
|
||||
use_clipped_redraw = FALSE;
|
||||
|
||||
clip_region_empty = may_use_clipped_redraw && clip_region.width == 0;
|
||||
|
||||
window_scale = _clutter_stage_window_get_scale_factor (stage_window);
|
||||
clip_region_empty = may_use_clipped_redraw && fb_clip_region.width == 0;
|
||||
|
||||
swap_with_damage = FALSE;
|
||||
if (has_buffer_age)
|
||||
@ -565,34 +624,44 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
if (use_clipped_redraw && !clip_region_empty)
|
||||
{
|
||||
int age, i;
|
||||
cairo_rectangle_int_t *current_damage =
|
||||
cairo_rectangle_int_t *current_fb_damage =
|
||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index++)];
|
||||
|
||||
age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
|
||||
|
||||
if (valid_buffer_age (view_cogl, age))
|
||||
{
|
||||
*current_damage = clip_region;
|
||||
cairo_rectangle_int_t damage_region;
|
||||
|
||||
*current_fb_damage = fb_clip_region;
|
||||
|
||||
for (i = 1; i <= age; i++)
|
||||
{
|
||||
cairo_rectangle_int_t *damage =
|
||||
cairo_rectangle_int_t *fb_damage =
|
||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)];
|
||||
|
||||
_clutter_util_rectangle_union (&clip_region, damage, &clip_region);
|
||||
_clutter_util_rectangle_union (&fb_clip_region,
|
||||
fb_damage,
|
||||
&fb_clip_region);
|
||||
}
|
||||
|
||||
/* Update the bounding redraw clip state with the extra damage. */
|
||||
damage_region = (cairo_rectangle_int_t) {
|
||||
.x = view_rect.x + floorf (fb_clip_region.x / fb_scale),
|
||||
.y = view_rect.y + floorf (fb_clip_region.y / fb_scale),
|
||||
.width = ceilf (fb_clip_region.width / fb_scale),
|
||||
.height = ceilf (fb_clip_region.height / fb_scale)
|
||||
};
|
||||
_clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip,
|
||||
&clip_region,
|
||||
&damage_region,
|
||||
&stage_cogl->bounding_redraw_clip);
|
||||
|
||||
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: x=%d, y=%d, width=%d, height=%d\n",
|
||||
age,
|
||||
clip_region.x,
|
||||
clip_region.y,
|
||||
clip_region.width,
|
||||
clip_region.height);
|
||||
fb_clip_region.x,
|
||||
fb_clip_region.y,
|
||||
fb_clip_region.width,
|
||||
fb_clip_region.height);
|
||||
|
||||
swap_with_damage = TRUE;
|
||||
}
|
||||
@ -600,7 +669,12 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
{
|
||||
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
|
||||
use_clipped_redraw = FALSE;
|
||||
*current_damage = view_rect;
|
||||
*current_fb_damage = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (!use_clipped_redraw)
|
||||
@ -616,26 +690,34 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
}
|
||||
else if (use_clipped_redraw)
|
||||
{
|
||||
int scissor_x;
|
||||
int scissor_y;
|
||||
cairo_rectangle_int_t scissor_rect;
|
||||
|
||||
calculate_scissor_region (&fb_clip_region,
|
||||
subpixel_compensation,
|
||||
fb_width, fb_height,
|
||||
&scissor_rect);
|
||||
|
||||
CLUTTER_NOTE (CLIPPING,
|
||||
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
|
||||
clip_region.x,
|
||||
clip_region.y,
|
||||
clip_region.width,
|
||||
clip_region.height);
|
||||
scissor_rect.x,
|
||||
scissor_rect.y,
|
||||
scissor_rect.width,
|
||||
scissor_rect.height);
|
||||
|
||||
stage_cogl->using_clipped_redraw = TRUE;
|
||||
|
||||
scissor_x = (clip_region.x - view_rect.x) * window_scale;
|
||||
scissor_y = (clip_region.y - view_rect.y) * window_scale;
|
||||
cogl_framebuffer_push_scissor_clip (fb,
|
||||
scissor_x,
|
||||
scissor_y,
|
||||
clip_region.width * window_scale,
|
||||
clip_region.height * window_scale);
|
||||
paint_stage (stage_cogl, view, &clip_region);
|
||||
scissor_rect.x,
|
||||
scissor_rect.y,
|
||||
scissor_rect.width,
|
||||
scissor_rect.height);
|
||||
paint_stage (stage_cogl, view,
|
||||
&(cairo_rectangle_int_t) {
|
||||
.x = view_rect.x + floorf ((fb_clip_region.x - 0) / fb_scale),
|
||||
.y = view_rect.y + floorf ((fb_clip_region.y - 0) / fb_scale),
|
||||
.width = ceilf ((fb_clip_region.width + 0) / fb_scale),
|
||||
.height = ceilf ((fb_clip_region.height + 0) / fb_scale)
|
||||
});
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
|
||||
stage_cogl->using_clipped_redraw = FALSE;
|
||||
@ -650,17 +732,25 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
may_use_clipped_redraw &&
|
||||
!clip_region_empty)
|
||||
{
|
||||
int scissor_x;
|
||||
int scissor_y;
|
||||
cairo_rectangle_int_t scissor_rect;
|
||||
|
||||
calculate_scissor_region (&fb_clip_region,
|
||||
subpixel_compensation,
|
||||
fb_width, fb_height,
|
||||
&scissor_rect);
|
||||
|
||||
scissor_x = (clip_region.x - view_rect.x) * window_scale;;
|
||||
scissor_y = (clip_region.y - view_rect.y) * window_scale;
|
||||
cogl_framebuffer_push_scissor_clip (fb,
|
||||
scissor_x,
|
||||
scissor_y,
|
||||
clip_region.width * window_scale,
|
||||
clip_region.height * window_scale);
|
||||
paint_stage (stage_cogl, view, &clip_region);
|
||||
scissor_rect.x,
|
||||
scissor_rect.y,
|
||||
scissor_rect.width,
|
||||
scissor_rect.height);
|
||||
paint_stage (stage_cogl, view,
|
||||
&(cairo_rectangle_int_t) {
|
||||
.x = view_rect.x + floorf (fb_clip_region.x / fb_scale),
|
||||
.y = view_rect.y + floorf (fb_clip_region.y / fb_scale),
|
||||
.width = ceilf (fb_clip_region.width / fb_scale),
|
||||
.height = ceilf (fb_clip_region.height / fb_scale)
|
||||
});
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
}
|
||||
else
|
||||
@ -723,12 +813,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
}
|
||||
else if (use_clipped_redraw)
|
||||
{
|
||||
swap_region = (cairo_rectangle_int_t) {
|
||||
.x = (clip_region.x - view_rect.x) * window_scale,
|
||||
.y = (clip_region.y - view_rect.y) * window_scale,
|
||||
.width = clip_region.width * window_scale,
|
||||
.height = clip_region.height * window_scale,
|
||||
};
|
||||
swap_region = fb_clip_region;
|
||||
g_assert (swap_region.width > 0);
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
@ -737,8 +822,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
swap_region = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * window_scale,
|
||||
.height = view_rect.height * window_scale,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale,
|
||||
};
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
@ -810,9 +895,25 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
|
||||
gboolean has_buffer_age =
|
||||
cogl_is_onscreen (framebuffer) &&
|
||||
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
||||
cairo_rectangle_int_t *rect;
|
||||
float fb_scale;
|
||||
gboolean scale_is_fractional;
|
||||
|
||||
if (!has_buffer_age)
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
if (fb_scale != floorf (fb_scale))
|
||||
scale_is_fractional = TRUE;
|
||||
else
|
||||
scale_is_fractional = FALSE;
|
||||
|
||||
/*
|
||||
* Buffer damage is tracked in the framebuffer coordinate space
|
||||
* using the damage history. When fractional scaling is used, a
|
||||
* coordinate on the stage might not correspond to the exact position of any
|
||||
* physical pixel, which causes issues when painting using the pick mode.
|
||||
*
|
||||
* For now, always use the (0, 0) pixel for picking when using fractional
|
||||
* framebuffer scaling.
|
||||
*/
|
||||
if (!has_buffer_age || scale_is_fractional)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
@ -823,12 +924,13 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
cairo_rectangle_int_t view_layout;
|
||||
cairo_rectangle_int_t *fb_damage;
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
rect = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
|
||||
*x = rect->x - view_layout.x;
|
||||
*y = rect->y - view_layout.y;
|
||||
fb_damage = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
|
||||
*x = fb_damage->x / fb_scale;
|
||||
*y = fb_damage->y / fb_scale;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-settings-private.h"
|
||||
|
||||
#ifdef COGL_HAS_EGL_SUPPORT
|
||||
#include "clutter-egl.h"
|
||||
@ -60,6 +61,8 @@ clutter_backend_egl_native_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterBackendEglNative *backend_egl_native = CLUTTER_BACKEND_EGL_NATIVE (gobject);
|
||||
|
||||
g_clear_object (&backend_egl_native->xsettings);
|
||||
|
||||
if (backend_egl_native->event_timer != NULL)
|
||||
{
|
||||
g_timer_destroy (backend_egl_native->event_timer);
|
||||
@ -77,9 +80,181 @@ clutter_backend_egl_native_class_init (ClutterBackendEglNativeClass *klass)
|
||||
gobject_class->dispose = clutter_backend_egl_native_dispose;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cairo_antialias_t cairo_antialias;
|
||||
gint clutter_font_antialias;
|
||||
|
||||
cairo_hint_style_t cairo_hint_style;
|
||||
const char *clutter_font_hint_style;
|
||||
|
||||
cairo_subpixel_order_t cairo_subpixel_order;
|
||||
const char *clutter_font_subpixel_order;
|
||||
} FontSettings;
|
||||
|
||||
static void
|
||||
get_font_gsettings (GSettings *xsettings,
|
||||
FontSettings *output)
|
||||
{
|
||||
/* org.gnome.settings-daemon.GsdFontAntialiasingMode */
|
||||
static const struct
|
||||
{
|
||||
cairo_antialias_t cairo_antialias;
|
||||
gint clutter_font_antialias;
|
||||
}
|
||||
antialiasings[] =
|
||||
{
|
||||
/* none=0 */ {CAIRO_ANTIALIAS_NONE, 0},
|
||||
/* grayscale=1 */ {CAIRO_ANTIALIAS_GRAY, 1},
|
||||
/* rgba=2 */ {CAIRO_ANTIALIAS_SUBPIXEL, 1},
|
||||
};
|
||||
|
||||
/* org.gnome.settings-daemon.GsdFontHinting */
|
||||
static const struct
|
||||
{
|
||||
cairo_hint_style_t cairo_hint_style;
|
||||
const char *clutter_font_hint_style;
|
||||
}
|
||||
hintings[] =
|
||||
{
|
||||
/* none=0 */ {CAIRO_HINT_STYLE_NONE, "hintnone"},
|
||||
/* slight=1 */ {CAIRO_HINT_STYLE_SLIGHT, "hintslight"},
|
||||
/* medium=2 */ {CAIRO_HINT_STYLE_MEDIUM, "hintmedium"},
|
||||
/* full=3 */ {CAIRO_HINT_STYLE_FULL, "hintfull"},
|
||||
};
|
||||
|
||||
/* org.gnome.settings-daemon.GsdFontRgbaOrder */
|
||||
static const struct
|
||||
{
|
||||
cairo_subpixel_order_t cairo_subpixel_order;
|
||||
const char *clutter_font_subpixel_order;
|
||||
}
|
||||
rgba_orders[] =
|
||||
{
|
||||
/* rgba=0 */ {CAIRO_SUBPIXEL_ORDER_RGB, "rgb"}, /* XXX what is 'rgba'? */
|
||||
/* rgb=1 */ {CAIRO_SUBPIXEL_ORDER_RGB, "rgb"},
|
||||
/* bgr=2 */ {CAIRO_SUBPIXEL_ORDER_BGR, "bgr"},
|
||||
/* vrgb=3 */ {CAIRO_SUBPIXEL_ORDER_VRGB, "vrgb"},
|
||||
/* vbgr=4 */ {CAIRO_SUBPIXEL_ORDER_VBGR, "vbgr"},
|
||||
};
|
||||
guint i;
|
||||
|
||||
i = g_settings_get_enum (xsettings, "hinting");
|
||||
if (i < G_N_ELEMENTS (hintings))
|
||||
{
|
||||
output->cairo_hint_style = hintings[i].cairo_hint_style;
|
||||
output->clutter_font_hint_style = hintings[i].clutter_font_hint_style;
|
||||
}
|
||||
else
|
||||
{
|
||||
output->cairo_hint_style = CAIRO_HINT_STYLE_DEFAULT;
|
||||
output->clutter_font_hint_style = NULL;
|
||||
}
|
||||
|
||||
i = g_settings_get_enum (xsettings, "antialiasing");
|
||||
if (i < G_N_ELEMENTS (antialiasings))
|
||||
{
|
||||
output->cairo_antialias = antialiasings[i].cairo_antialias;
|
||||
output->clutter_font_antialias = antialiasings[i].clutter_font_antialias;
|
||||
}
|
||||
else
|
||||
{
|
||||
output->cairo_antialias = CAIRO_ANTIALIAS_DEFAULT;
|
||||
output->clutter_font_antialias = -1;
|
||||
}
|
||||
|
||||
i = g_settings_get_enum (xsettings, "rgba-order");
|
||||
if (i < G_N_ELEMENTS (rgba_orders))
|
||||
{
|
||||
output->cairo_subpixel_order = rgba_orders[i].cairo_subpixel_order;
|
||||
output->clutter_font_subpixel_order = rgba_orders[i].clutter_font_subpixel_order;
|
||||
}
|
||||
else
|
||||
{
|
||||
output->cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
output->clutter_font_subpixel_order = NULL;
|
||||
}
|
||||
|
||||
if (output->cairo_antialias == CAIRO_ANTIALIAS_GRAY)
|
||||
output->clutter_font_subpixel_order = "none";
|
||||
}
|
||||
|
||||
static void
|
||||
init_font_options (ClutterBackendEglNative *backend_egl_native)
|
||||
{
|
||||
GSettings *xsettings = backend_egl_native->xsettings;
|
||||
cairo_font_options_t *options = cairo_font_options_create ();
|
||||
FontSettings fs;
|
||||
|
||||
get_font_gsettings (xsettings, &fs);
|
||||
|
||||
cairo_font_options_set_hint_style (options, fs.cairo_hint_style);
|
||||
cairo_font_options_set_antialias (options, fs.cairo_antialias);
|
||||
cairo_font_options_set_subpixel_order (options, fs.cairo_subpixel_order);
|
||||
|
||||
clutter_backend_set_font_options (CLUTTER_BACKEND (backend_egl_native),
|
||||
options);
|
||||
|
||||
cairo_font_options_destroy (options);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_xsettings_change_event (GSettings *xsettings,
|
||||
gpointer keys,
|
||||
gint n_keys,
|
||||
gpointer user_data)
|
||||
{
|
||||
/*
|
||||
* A simpler alternative to this function that does not update the screen
|
||||
* immediately (like macOS :P):
|
||||
*
|
||||
* init_font_options (CLUTTER_BACKEND_EGL_NATIVE (user_data));
|
||||
*
|
||||
* which has the added benefit of eliminating the need for all the
|
||||
* FontSettings.clutter_ fields. However the below approach is better for
|
||||
* testing settings and more consistent with the existing x11 backend...
|
||||
*/
|
||||
ClutterSettings *csettings = clutter_settings_get_default ();
|
||||
FontSettings fs;
|
||||
gint hinting;
|
||||
|
||||
get_font_gsettings (xsettings, &fs);
|
||||
hinting = fs.cairo_hint_style == CAIRO_HINT_STYLE_NONE ? 0 : 1;
|
||||
g_object_set (csettings,
|
||||
"font-hinting", hinting,
|
||||
"font-hint-style", fs.clutter_font_hint_style,
|
||||
"font-antialias", fs.clutter_font_antialias,
|
||||
"font-subpixel-order", fs.clutter_font_subpixel_order,
|
||||
NULL);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_egl_native_init (ClutterBackendEglNative *backend_egl_native)
|
||||
{
|
||||
static const gchar xsettings_path[] = "org.gnome.settings-daemon.plugins.xsettings";
|
||||
GSettingsSchemaSource *source = g_settings_schema_source_get_default ();
|
||||
GSettingsSchema *schema = g_settings_schema_source_lookup (source,
|
||||
xsettings_path,
|
||||
FALSE);
|
||||
|
||||
if (!schema)
|
||||
{
|
||||
g_warning ("Failed to find schema: %s", xsettings_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
backend_egl_native->xsettings = g_settings_new_full (schema, NULL, NULL);
|
||||
if (backend_egl_native->xsettings)
|
||||
{
|
||||
init_font_options (backend_egl_native);
|
||||
g_signal_connect (backend_egl_native->xsettings, "change-event",
|
||||
G_CALLBACK (on_xsettings_change_event),
|
||||
backend_egl_native);
|
||||
}
|
||||
}
|
||||
|
||||
backend_egl_native->event_timer = g_timer_new ();
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,9 @@ struct _ClutterBackendEglNative
|
||||
|
||||
/* event timer */
|
||||
GTimer *event_timer;
|
||||
|
||||
/* "xsettings" is still the defacto place for Xft settings, even in Wayland */
|
||||
GSettings *xsettings;
|
||||
};
|
||||
|
||||
struct _ClutterBackendEglNativeClass
|
||||
|
@ -59,9 +59,6 @@
|
||||
|
||||
#include "clutter-device-manager-evdev.h"
|
||||
|
||||
#define DISCRETE_SCROLL_STEP 10.0
|
||||
|
||||
|
||||
/*
|
||||
* Clutter makes the assumption that two core devices have ID's 2 and 3 (core
|
||||
* pointer and core keyboard).
|
||||
@ -102,6 +99,9 @@ struct _ClutterDeviceManagerEvdevPrivate
|
||||
gpointer constrain_data;
|
||||
GDestroyNotify constrain_data_notify;
|
||||
|
||||
ClutterRelativeMotionFilter relative_motion_filter;
|
||||
gpointer relative_motion_filter_user_data;
|
||||
|
||||
ClutterStageManager *stage_manager;
|
||||
guint stage_added_handler;
|
||||
guint stage_removed_handler;
|
||||
@ -264,6 +264,22 @@ _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *mana
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_device_manager_evdev_filter_relative_motion (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy)
|
||||
{
|
||||
ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
||||
|
||||
if (!priv->relative_motion_filter)
|
||||
return;
|
||||
|
||||
priv->relative_motion_filter (device, x, y, dx, dy,
|
||||
priv->relative_motion_filter_user_data);
|
||||
}
|
||||
|
||||
static ClutterEvent *
|
||||
new_absolute_motion_event (ClutterInputDevice *input_device,
|
||||
@ -358,131 +374,29 @@ notify_relative_tool_motion (ClutterInputDevice *input_device,
|
||||
gfloat dy,
|
||||
gdouble *axes)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterEvent *event;
|
||||
ClutterSeatEvdev *seat;
|
||||
gfloat x, y;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
x = input_device->current_x + dx;
|
||||
y = input_device->current_y + dy;
|
||||
|
||||
_clutter_device_manager_evdev_filter_relative_motion (seat->manager_evdev,
|
||||
input_device,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&dx,
|
||||
&dy);
|
||||
|
||||
event = new_absolute_motion_event (input_device, time_us, x, y, axes);
|
||||
_clutter_evdev_event_set_relative_motion (event, dx, dy, 0, 0);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static ClutterScrollDirection
|
||||
discrete_to_direction (gdouble discrete_x,
|
||||
gdouble discrete_y)
|
||||
{
|
||||
if (discrete_x > 0)
|
||||
return CLUTTER_SCROLL_RIGHT;
|
||||
else if (discrete_x < 0)
|
||||
return CLUTTER_SCROLL_LEFT;
|
||||
else if (discrete_y > 0)
|
||||
return CLUTTER_SCROLL_DOWN;
|
||||
else if (discrete_y < 0)
|
||||
return CLUTTER_SCROLL_UP;
|
||||
else
|
||||
return CLUTTER_SCROLL_SMOOTH;
|
||||
}
|
||||
|
||||
static void
|
||||
notify_discrete_scroll (ClutterInputDevice *input_device,
|
||||
guint64 time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source,
|
||||
gboolean emulated)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
|
||||
if (direction == CLUTTER_SCROLL_SMOOTH)
|
||||
return;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
event->scroll.device = seat->core_pointer;
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
event->scroll.direction = direction;
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = scroll_source;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_scroll (ClutterInputDevice *input_device,
|
||||
guint64 time_us,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
ClutterScrollSource source,
|
||||
ClutterScrollFinishFlags flags,
|
||||
gboolean emulated)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
gdouble scroll_factor;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
event->scroll.device = seat->core_pointer;
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
/* libinput pointer axis events are in pointer motion coordinate space.
|
||||
* To convert to Xi2 discrete step coordinate space, multiply the factor
|
||||
* 1/10. */
|
||||
event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
|
||||
scroll_factor = 1.0 / DISCRETE_SCROLL_STEP;
|
||||
clutter_event_set_scroll_delta (event,
|
||||
scroll_factor * dx,
|
||||
scroll_factor * dy);
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = source;
|
||||
event->scroll.finish_flags = flags;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_touch_event (ClutterInputDevice *input_device,
|
||||
ClutterEventType evtype,
|
||||
@ -1122,40 +1036,6 @@ process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
return handled;
|
||||
}
|
||||
|
||||
static void
|
||||
check_notify_discrete_scroll (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
ClutterInputDevice *device,
|
||||
guint64 time_us,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (device);
|
||||
ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
int i, n_xscrolls, n_yscrolls;
|
||||
|
||||
n_xscrolls = floor (fabs (seat->accum_scroll_dx) / DISCRETE_SCROLL_STEP);
|
||||
n_yscrolls = floor (fabs (seat->accum_scroll_dy) / DISCRETE_SCROLL_STEP);
|
||||
|
||||
for (i = 0; i < n_xscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dx > 0 ?
|
||||
CLUTTER_SCROLL_RIGHT : CLUTTER_SCROLL_LEFT,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_yscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dy > 0 ?
|
||||
CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
seat->accum_scroll_dx = fmodf (seat->accum_scroll_dx, DISCRETE_SCROLL_STEP);
|
||||
seat->accum_scroll_dy = fmodf (seat->accum_scroll_dy, DISCRETE_SCROLL_STEP);
|
||||
}
|
||||
|
||||
static ClutterScrollSource
|
||||
translate_scroll_source (enum libinput_pointer_axis_source source)
|
||||
{
|
||||
@ -1303,6 +1183,68 @@ seat_from_device (ClutterInputDevice *device)
|
||||
return _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_continuous_axis (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollSource scroll_source,
|
||||
struct libinput_event_pointer *axis_event)
|
||||
{
|
||||
gdouble dx = 0.0, dy = 0.0;
|
||||
ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE;
|
||||
|
||||
if (libinput_event_pointer_has_axis (axis_event,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
|
||||
{
|
||||
dx = libinput_event_pointer_get_axis_value (
|
||||
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
|
||||
|
||||
if (fabs (dx) < DBL_EPSILON)
|
||||
finish_flags |= CLUTTER_SCROLL_FINISHED_HORIZONTAL;
|
||||
}
|
||||
if (libinput_event_pointer_has_axis (axis_event,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
|
||||
{
|
||||
dy = libinput_event_pointer_get_axis_value (
|
||||
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
|
||||
|
||||
if (fabs (dy) < DBL_EPSILON)
|
||||
finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL;
|
||||
}
|
||||
|
||||
clutter_seat_evdev_notify_scroll_continuous (seat, device, time_us,
|
||||
dx, dy,
|
||||
scroll_source, finish_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_discrete_axis (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollSource scroll_source,
|
||||
struct libinput_event_pointer *axis_event)
|
||||
{
|
||||
gdouble discrete_dx = 0.0, discrete_dy = 0.0;
|
||||
|
||||
if (libinput_event_pointer_has_axis (axis_event,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
|
||||
{
|
||||
discrete_dx = libinput_event_pointer_get_axis_value_discrete (
|
||||
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
|
||||
}
|
||||
if (libinput_event_pointer_has_axis (axis_event,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
|
||||
{
|
||||
discrete_dy = libinput_event_pointer_get_axis_value_discrete (
|
||||
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
|
||||
}
|
||||
|
||||
clutter_seat_evdev_notify_discrete_scroll (seat, device,
|
||||
time_us,
|
||||
discrete_dx, discrete_dy,
|
||||
scroll_source);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
struct libinput_event *event)
|
||||
@ -1429,17 +1371,12 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
|
||||
case LIBINPUT_EVENT_POINTER_AXIS:
|
||||
{
|
||||
gdouble dx = 0.0, dy = 0.0;
|
||||
gdouble discrete_x = 0.0, discrete_y = 0.0;
|
||||
guint64 time_us;
|
||||
gboolean wheel = FALSE;
|
||||
enum libinput_pointer_axis axis;
|
||||
enum libinput_pointer_axis_source source;
|
||||
struct libinput_event_pointer *axis_event =
|
||||
libinput_event_get_pointer_event (event);
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterScrollSource scroll_source;
|
||||
ClutterScrollFinishFlags finish_flags = 0;
|
||||
|
||||
device = libinput_device_get_user_data (libinput_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
|
||||
@ -1453,63 +1390,20 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
backwards-compat with existing clients, we just send multiples of
|
||||
the click count. */
|
||||
|
||||
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL)
|
||||
wheel = TRUE;
|
||||
|
||||
axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
|
||||
if (libinput_event_pointer_has_axis (axis_event, axis))
|
||||
switch (scroll_source)
|
||||
{
|
||||
discrete_y = libinput_event_pointer_get_axis_value_discrete (axis_event, axis);
|
||||
dy = libinput_event_pointer_get_axis_value (axis_event, axis);
|
||||
|
||||
if (wheel)
|
||||
seat->accum_scroll_dy = 0;
|
||||
else if (fabs (dy) < DBL_EPSILON)
|
||||
{
|
||||
finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL;
|
||||
seat->accum_scroll_dy = 0;
|
||||
}
|
||||
else
|
||||
seat->accum_scroll_dy += dy;
|
||||
case CLUTTER_SCROLL_SOURCE_WHEEL:
|
||||
notify_discrete_axis (seat, device, time_us, scroll_source,
|
||||
axis_event);
|
||||
break;
|
||||
case CLUTTER_SCROLL_SOURCE_FINGER:
|
||||
case CLUTTER_SCROLL_SOURCE_CONTINUOUS:
|
||||
case CLUTTER_SCROLL_SOURCE_UNKNOWN:
|
||||
notify_continuous_axis (seat, device, time_us, scroll_source,
|
||||
axis_event);
|
||||
break;
|
||||
}
|
||||
|
||||
axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
|
||||
if (libinput_event_pointer_has_axis (axis_event, axis))
|
||||
{
|
||||
discrete_x = libinput_event_pointer_get_axis_value_discrete (axis_event, axis);
|
||||
dx = libinput_event_pointer_get_axis_value (axis_event, axis);
|
||||
|
||||
if (wheel)
|
||||
seat->accum_scroll_dx = 0;
|
||||
else if (fabs (dx) < DBL_EPSILON)
|
||||
{
|
||||
finish_flags |= CLUTTER_SCROLL_FINISHED_HORIZONTAL;
|
||||
seat->accum_scroll_dx = 0;
|
||||
}
|
||||
else
|
||||
seat->accum_scroll_dx += dx;
|
||||
}
|
||||
|
||||
if (wheel)
|
||||
{
|
||||
notify_scroll (device, time_us,
|
||||
discrete_x * DISCRETE_SCROLL_STEP,
|
||||
discrete_y * DISCRETE_SCROLL_STEP,
|
||||
scroll_source, finish_flags, TRUE);
|
||||
notify_discrete_scroll (device, time_us,
|
||||
discrete_to_direction (discrete_x, discrete_y),
|
||||
scroll_source, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
notify_scroll (device, time_us, dx, dy,
|
||||
scroll_source, finish_flags, FALSE);
|
||||
check_notify_discrete_scroll (manager_evdev, device,
|
||||
time_us, scroll_source);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case LIBINPUT_EVENT_TOUCH_DOWN:
|
||||
@ -2029,6 +1923,18 @@ clutter_device_manager_evdev_compress_motion (ClutterDeviceManager *device_mange
|
||||
dy_unaccel + dst_dy_unaccel);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_evdev_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
|
||||
device = clutter_device_manager_evdev_get_core_device (device_manager, CLUTTER_KEYBOARD_DEVICE);
|
||||
if (device)
|
||||
clutter_input_device_evdev_apply_kbd_a11y_settings (CLUTTER_INPUT_DEVICE_EVDEV (device),
|
||||
settings);
|
||||
}
|
||||
|
||||
/*
|
||||
* GObject implementation
|
||||
*/
|
||||
@ -2171,6 +2077,7 @@ clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass)
|
||||
manager_class->get_device = clutter_device_manager_evdev_get_device;
|
||||
manager_class->create_virtual_device = clutter_device_manager_evdev_create_virtual_device;
|
||||
manager_class->compress_motion = clutter_device_manager_evdev_compress_motion;
|
||||
manager_class->apply_kbd_a11y_settings = clutter_device_manager_evdev_apply_kbd_a11y_settings;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2291,7 +2198,7 @@ _clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev *mana
|
||||
|
||||
first = g_list_first (priv->free_device_ids);
|
||||
next_id = GPOINTER_TO_INT (first->data);
|
||||
priv->free_device_ids = g_list_remove_link (priv->free_device_ids, first);
|
||||
priv->free_device_ids = g_list_delete_link (priv->free_device_ids, first);
|
||||
|
||||
return next_id;
|
||||
}
|
||||
@ -2410,7 +2317,7 @@ clutter_evdev_update_xkb_state (ClutterDeviceManagerEvdev *manager_evdev)
|
||||
0, /* depressed */
|
||||
latched_mods,
|
||||
locked_mods,
|
||||
0, 0, 0);
|
||||
0, 0, seat->layout_idx);
|
||||
|
||||
seat->caps_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_CAPS);
|
||||
seat->num_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_NUM);
|
||||
@ -2558,6 +2465,7 @@ clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
||||
xkb_mod_mask_t latched_mods;
|
||||
xkb_mod_mask_t locked_mods;
|
||||
struct xkb_state *state;
|
||||
GSList *l;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev));
|
||||
|
||||
@ -2569,6 +2477,24 @@ clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
||||
locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED);
|
||||
|
||||
xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx);
|
||||
for (l = manager_evdev->priv->seats; l; l = l->next)
|
||||
{
|
||||
ClutterSeatEvdev *seat = l->data;
|
||||
|
||||
seat->layout_idx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_evdev_get_keyboard_layout_index: (skip)
|
||||
*/
|
||||
xkb_layout_index_t
|
||||
clutter_evdev_get_keyboard_layout_index (ClutterDeviceManager *evdev)
|
||||
{
|
||||
ClutterDeviceManagerEvdev *manager_evdev;
|
||||
|
||||
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev);
|
||||
return manager_evdev->priv->main_seat->layout_idx;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2661,6 +2587,23 @@ clutter_evdev_set_pointer_constrain_callback (ClutterDeviceManager *e
|
||||
priv->constrain_data_notify = user_data_notify;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_evdev_set_relative_motion_filter (ClutterDeviceManager *evdev,
|
||||
ClutterRelativeMotionFilter filter,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterDeviceManagerEvdev *manager_evdev;
|
||||
ClutterDeviceManagerEvdevPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev));
|
||||
|
||||
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev);
|
||||
priv = manager_evdev->priv;
|
||||
|
||||
priv->relative_motion_filter = filter;
|
||||
priv->relative_motion_filter_user_data = user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_evdev_set_keyboard_repeat:
|
||||
* @evdev: the #ClutterDeviceManager created by the evdev backend
|
||||
|
@ -76,6 +76,13 @@ void _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev
|
||||
float *new_x,
|
||||
float *new_y);
|
||||
|
||||
void _clutter_device_manager_evdev_filter_relative_motion (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy);
|
||||
|
||||
void _clutter_device_manager_evdev_dispatch (ClutterDeviceManagerEvdev *manager_evdev);
|
||||
|
||||
static inline guint64
|
||||
|
@ -97,6 +97,18 @@ void clutter_evdev_set_pointer_constrain_callback (ClutterDeviceManager
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_notify);
|
||||
|
||||
typedef void (*ClutterRelativeMotionFilter) (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_evdev_set_relative_motion_filter (ClutterDeviceManager *evdev,
|
||||
ClutterRelativeMotionFilter filter,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_1_16
|
||||
void clutter_evdev_set_keyboard_map (ClutterDeviceManager *evdev,
|
||||
struct xkb_keymap *keymap);
|
||||
@ -108,6 +120,9 @@ CLUTTER_AVAILABLE_IN_1_20
|
||||
void clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
||||
xkb_layout_index_t idx);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
xkb_layout_index_t clutter_evdev_get_keyboard_layout_index (ClutterDeviceManager *evdev);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_1_26
|
||||
void clutter_evdev_set_keyboard_numlock (ClutterDeviceManager *evdev,
|
||||
gboolean numlock_state);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -70,6 +70,29 @@ struct _ClutterInputDeviceEvdev
|
||||
cairo_matrix_t device_matrix;
|
||||
gdouble device_aspect_ratio; /* w:h */
|
||||
gdouble output_ratio; /* w:h */
|
||||
|
||||
/* Keyboard a11y */
|
||||
ClutterKeyboardA11yFlags a11y_flags;
|
||||
GList *slow_keys_list;
|
||||
guint debounce_timer;
|
||||
guint16 debounce_key;
|
||||
xkb_mod_mask_t stickykeys_depressed_mask;
|
||||
xkb_mod_mask_t stickykeys_latched_mask;
|
||||
xkb_mod_mask_t stickykeys_locked_mask;
|
||||
guint toggle_slowkeys_timer;
|
||||
guint16 shift_count;
|
||||
guint32 last_shift_time;
|
||||
gint mousekeys_btn;
|
||||
gboolean mousekeys_btn_states[3];
|
||||
guint32 mousekeys_first_motion_time; /* ms */
|
||||
guint32 mousekeys_last_motion_time; /* ms */
|
||||
guint mousekeys_init_delay;
|
||||
guint mousekeys_accel_time;
|
||||
guint mousekeys_max_speed;
|
||||
gdouble mousekeys_curve_factor;
|
||||
guint move_mousekeys_timer;
|
||||
guint16 last_mousekeys_key;
|
||||
ClutterVirtualInputDevice *mousekeys_virtual_device;
|
||||
};
|
||||
|
||||
GType _clutter_input_device_evdev_get_type (void) G_GNUC_CONST;
|
||||
@ -111,6 +134,9 @@ void clutter_input_device_evdev_translate_coordinates (Clut
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
|
||||
void clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *device,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_H__ */
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "clutter-seat-evdev.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-input-device-evdev.h"
|
||||
@ -42,6 +43,8 @@
|
||||
|
||||
#define AUTOREPEAT_VALUE 2
|
||||
|
||||
#define DISCRETE_SCROLL_STEP 10.0
|
||||
|
||||
void
|
||||
clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
|
||||
struct libinput_seat *libinput_seat)
|
||||
@ -405,6 +408,13 @@ clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev *seat,
|
||||
if (!_clutter_input_device_get_stage (input_device))
|
||||
return;
|
||||
|
||||
_clutter_device_manager_evdev_filter_relative_motion (seat->manager_evdev,
|
||||
input_device,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&dx,
|
||||
&dy);
|
||||
|
||||
new_x = seat->pointer_x + dx;
|
||||
new_y = seat->pointer_y + dy;
|
||||
event = new_absolute_motion_event (seat, input_device,
|
||||
@ -562,6 +572,194 @@ clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_scroll (ClutterInputDevice *input_device,
|
||||
guint64 time_us,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags flags,
|
||||
gboolean emulated)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
gdouble scroll_factor;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
event->scroll.device = seat->core_pointer;
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
/* libinput pointer axis events are in pointer motion coordinate space.
|
||||
* To convert to Xi2 discrete step coordinate space, multiply the factor
|
||||
* 1/10. */
|
||||
event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
|
||||
scroll_factor = 1.0 / DISCRETE_SCROLL_STEP;
|
||||
clutter_event_set_scroll_delta (event,
|
||||
scroll_factor * dx,
|
||||
scroll_factor * dy);
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = scroll_source;
|
||||
event->scroll.finish_flags = flags;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_discrete_scroll (ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source,
|
||||
gboolean emulated)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
|
||||
if (direction == CLUTTER_SCROLL_SMOOTH)
|
||||
return;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
event->scroll.device = seat->core_pointer;
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
event->scroll.direction = direction;
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = scroll_source;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
check_notify_discrete_scroll (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
int i, n_xscrolls, n_yscrolls;
|
||||
|
||||
n_xscrolls = floor (fabs (seat->accum_scroll_dx) / DISCRETE_SCROLL_STEP);
|
||||
n_yscrolls = floor (fabs (seat->accum_scroll_dy) / DISCRETE_SCROLL_STEP);
|
||||
|
||||
for (i = 0; i < n_xscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dx > 0 ?
|
||||
CLUTTER_SCROLL_RIGHT : CLUTTER_SCROLL_LEFT,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_yscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dy > 0 ?
|
||||
CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
seat->accum_scroll_dx = fmodf (seat->accum_scroll_dx, DISCRETE_SCROLL_STEP);
|
||||
seat->accum_scroll_dy = fmodf (seat->accum_scroll_dy, DISCRETE_SCROLL_STEP);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_notify_scroll_continuous (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
if (finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL)
|
||||
seat->accum_scroll_dx = 0;
|
||||
else
|
||||
seat->accum_scroll_dx += dx;
|
||||
|
||||
if (finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL)
|
||||
seat->accum_scroll_dy = 0;
|
||||
else
|
||||
seat->accum_scroll_dy += dy;
|
||||
|
||||
notify_scroll (input_device, time_us, dx, dy, scroll_source,
|
||||
finish_flags, FALSE);
|
||||
check_notify_discrete_scroll (seat, input_device, time_us, scroll_source);
|
||||
}
|
||||
|
||||
static ClutterScrollDirection
|
||||
discrete_to_direction (double discrete_dx,
|
||||
double discrete_dy)
|
||||
{
|
||||
if (discrete_dx > 0)
|
||||
return CLUTTER_SCROLL_RIGHT;
|
||||
else if (discrete_dx < 0)
|
||||
return CLUTTER_SCROLL_LEFT;
|
||||
else if (discrete_dy > 0)
|
||||
return CLUTTER_SCROLL_DOWN;
|
||||
else if (discrete_dy < 0)
|
||||
return CLUTTER_SCROLL_UP;
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_notify_discrete_scroll (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double discrete_dx,
|
||||
double discrete_dy,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
notify_scroll (input_device, time_us,
|
||||
discrete_dx * DISCRETE_SCROLL_STEP,
|
||||
discrete_dy * DISCRETE_SCROLL_STEP,
|
||||
scroll_source, CLUTTER_SCROLL_FINISHED_NONE,
|
||||
TRUE);
|
||||
notify_discrete_scroll (input_device, time_us,
|
||||
discrete_to_direction (discrete_dx, discrete_dy),
|
||||
scroll_source, FALSE);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_free (ClutterSeatEvdev *seat)
|
||||
{
|
||||
|
@ -58,6 +58,7 @@ struct _ClutterSeatEvdev
|
||||
xkb_led_index_t caps_lock_led;
|
||||
xkb_led_index_t num_lock_led;
|
||||
xkb_led_index_t scroll_lock_led;
|
||||
xkb_layout_index_t layout_idx;
|
||||
uint32_t button_state;
|
||||
int button_count[KEY_CNT];
|
||||
|
||||
@ -106,6 +107,21 @@ void clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
|
||||
uint32_t button,
|
||||
uint32_t state);
|
||||
|
||||
void clutter_seat_evdev_notify_scroll_continuous (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource source,
|
||||
ClutterScrollFinishFlags flags);
|
||||
|
||||
void clutter_seat_evdev_notify_discrete_scroll (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double discrete_dx,
|
||||
double discrete_dy,
|
||||
ClutterScrollSource source);
|
||||
|
||||
void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
|
||||
struct libinput_seat *libinput_seat);
|
||||
|
||||
|
@ -156,6 +156,9 @@ clutter_virtual_input_device_evdev_notify_relative_motion (ClutterVirtualInputDe
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
clutter_seat_evdev_notify_relative_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
@ -172,6 +175,9 @@ clutter_virtual_input_device_evdev_notify_absolute_motion (ClutterVirtualInputDe
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
clutter_seat_evdev_notify_absolute_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
@ -189,6 +195,9 @@ clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *vir
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
int button_count;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
if (get_button_type (button) != EVDEV_BUTTON_TYPE_BUTTON)
|
||||
{
|
||||
g_warning ("Unknown/invalid virtual device button 0x%x pressed",
|
||||
@ -222,6 +231,9 @@ clutter_virtual_input_device_evdev_notify_key (ClutterVirtualInputDevice *virtua
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
int key_count;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
if (get_button_type (key) != EVDEV_BUTTON_TYPE_KEY)
|
||||
{
|
||||
g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", key);
|
||||
@ -343,6 +355,9 @@ clutter_virtual_input_device_evdev_notify_keyval (ClutterVirtualInputDevice *vir
|
||||
int key_count;
|
||||
guint keycode = 0, level = 0, evcode = 0;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
if (!pick_keycode_for_keyval_in_current_group (virtual_device,
|
||||
keyval, &keycode, &level))
|
||||
{
|
||||
@ -382,6 +397,57 @@ clutter_virtual_input_device_evdev_notify_keyval (ClutterVirtualInputDevice *vir
|
||||
apply_level_modifiers (virtual_device, time_us, level, key_state);
|
||||
}
|
||||
|
||||
static void
|
||||
direction_to_discrete (ClutterScrollDirection direction,
|
||||
double *discrete_dx,
|
||||
double *discrete_dy)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case CLUTTER_SCROLL_UP:
|
||||
*discrete_dx = 0.0;
|
||||
*discrete_dy = -1.0;
|
||||
break;
|
||||
case CLUTTER_SCROLL_DOWN:
|
||||
*discrete_dx = 0.0;
|
||||
*discrete_dy = 1.0;
|
||||
break;
|
||||
case CLUTTER_SCROLL_LEFT:
|
||||
*discrete_dx = -1.0;
|
||||
*discrete_dy = 0.0;
|
||||
break;
|
||||
case CLUTTER_SCROLL_RIGHT:
|
||||
*discrete_dx = 1.0;
|
||||
*discrete_dy = 0.0;
|
||||
break;
|
||||
case CLUTTER_SCROLL_SMOOTH:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_evdev_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
double discrete_dx = 0.0, discrete_dy = 0.0;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
direction_to_discrete (direction, &discrete_dx, &discrete_dy);
|
||||
|
||||
clutter_seat_evdev_notify_discrete_scroll (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
discrete_dx, discrete_dy,
|
||||
scroll_source);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_evdev_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -485,6 +551,7 @@ clutter_virtual_input_device_evdev_class_init (ClutterVirtualInputDeviceEvdevCla
|
||||
virtual_input_device_class->notify_button = clutter_virtual_input_device_evdev_notify_button;
|
||||
virtual_input_device_class->notify_key = clutter_virtual_input_device_evdev_notify_key;
|
||||
virtual_input_device_class->notify_keyval = clutter_virtual_input_device_evdev_notify_keyval;
|
||||
virtual_input_device_class->notify_discrete_scroll = clutter_virtual_input_device_evdev_notify_discrete_scroll;
|
||||
|
||||
obj_props[PROP_SEAT] = g_param_spec_pointer ("seat",
|
||||
P_("ClutterSeatEvdev"),
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "clutter-event-translator.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-xkb-a11y-x11.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@ -136,7 +137,6 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
ClutterTranslateReturn res;
|
||||
ClutterStage *stage;
|
||||
XEvent *xevent;
|
||||
int window_scale;
|
||||
|
||||
manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (translator);
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
@ -152,8 +152,6 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage));
|
||||
|
||||
window_scale = stage_x11->scale_factor;
|
||||
|
||||
event->any.stage = stage;
|
||||
|
||||
res = CLUTTER_TRANSLATE_CONTINUE;
|
||||
@ -226,8 +224,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
event->scroll.direction = CLUTTER_SCROLL_RIGHT;
|
||||
|
||||
event->scroll.time = xevent->xbutton.time;
|
||||
event->scroll.x = xevent->xbutton.x / window_scale;
|
||||
event->scroll.y = xevent->xbutton.y / window_scale;
|
||||
event->scroll.x = xevent->xbutton.x;
|
||||
event->scroll.y = xevent->xbutton.y;
|
||||
event->scroll.modifier_state = xevent->xbutton.state;
|
||||
event->scroll.axes = NULL;
|
||||
break;
|
||||
@ -235,8 +233,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
default:
|
||||
event->button.type = event->type = CLUTTER_BUTTON_PRESS;
|
||||
event->button.time = xevent->xbutton.time;
|
||||
event->button.x = xevent->xbutton.x / window_scale;
|
||||
event->button.y = xevent->xbutton.y / window_scale;
|
||||
event->button.x = xevent->xbutton.x;
|
||||
event->button.y = xevent->xbutton.y;
|
||||
event->button.modifier_state = xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
event->button.axes = NULL;
|
||||
@ -269,8 +267,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
|
||||
event->button.time = xevent->xbutton.time;
|
||||
event->button.x = xevent->xbutton.x / window_scale;
|
||||
event->button.y = xevent->xbutton.y / window_scale;
|
||||
event->button.x = xevent->xbutton.x;
|
||||
event->button.y = xevent->xbutton.y;
|
||||
event->button.modifier_state = xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
event->button.axes = NULL;
|
||||
@ -287,8 +285,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
event->motion.type = event->type = CLUTTER_MOTION;
|
||||
event->motion.time = xevent->xmotion.time;
|
||||
event->motion.x = xevent->xmotion.x / window_scale;
|
||||
event->motion.y = xevent->xmotion.y / window_scale;
|
||||
event->motion.x = xevent->xmotion.x;
|
||||
event->motion.y = xevent->xmotion.y;
|
||||
event->motion.modifier_state = xevent->xmotion.state;
|
||||
event->motion.axes = NULL;
|
||||
clutter_event_set_device (event, manager_x11->core_pointer);
|
||||
@ -301,8 +299,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
event->crossing.type = CLUTTER_ENTER;
|
||||
event->crossing.time = xevent->xcrossing.time;
|
||||
event->crossing.x = xevent->xcrossing.x / window_scale;
|
||||
event->crossing.y = xevent->xcrossing.y / window_scale;
|
||||
event->crossing.x = xevent->xcrossing.x;
|
||||
event->crossing.y = xevent->xcrossing.y;
|
||||
event->crossing.source = CLUTTER_ACTOR (stage);
|
||||
event->crossing.related = NULL;
|
||||
clutter_event_set_device (event, manager_x11->core_pointer);
|
||||
@ -327,8 +325,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
event->crossing.type = CLUTTER_LEAVE;
|
||||
event->crossing.time = xevent->xcrossing.time;
|
||||
event->crossing.x = xevent->xcrossing.x / window_scale;
|
||||
event->crossing.y = xevent->xcrossing.y / window_scale;
|
||||
event->crossing.x = xevent->xcrossing.x;
|
||||
event->crossing.y = xevent->xcrossing.y;
|
||||
event->crossing.source = CLUTTER_ACTOR (stage);
|
||||
event->crossing.related = NULL;
|
||||
clutter_event_set_device (event, manager_x11->core_pointer);
|
||||
@ -355,9 +353,11 @@ static void
|
||||
clutter_device_manager_x11_constructed (GObject *gobject)
|
||||
{
|
||||
ClutterDeviceManagerX11 *manager_x11;
|
||||
ClutterDeviceManager *manager;
|
||||
ClutterBackendX11 *backend_x11;
|
||||
|
||||
manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (gobject);
|
||||
manager = CLUTTER_DEVICE_MANAGER (gobject);
|
||||
|
||||
g_object_get (gobject, "backend", &backend_x11, NULL);
|
||||
g_assert (backend_x11 != NULL);
|
||||
@ -392,6 +392,8 @@ clutter_device_manager_x11_constructed (GObject *gobject)
|
||||
_clutter_input_device_set_associated_device (manager_x11->core_keyboard,
|
||||
manager_x11->core_pointer);
|
||||
|
||||
clutter_device_manager_x11_a11y_init (manager);
|
||||
|
||||
if (G_OBJECT_CLASS (clutter_device_manager_x11_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (clutter_device_manager_x11_parent_class)->constructed (gobject);
|
||||
}
|
||||
@ -535,6 +537,7 @@ clutter_device_manager_x11_class_init (ClutterDeviceManagerX11Class *klass)
|
||||
manager_class->get_core_device = clutter_device_manager_x11_get_core_device;
|
||||
manager_class->get_device = clutter_device_manager_x11_get_device;
|
||||
manager_class->create_virtual_device = clutter_device_manager_x11_create_virtual_device;
|
||||
manager_class->apply_kbd_a11y_settings = clutter_device_manager_x11_apply_kbd_a11y_settings;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "clutter-event-translator.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-xkb-a11y-x11.h"
|
||||
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
@ -66,6 +67,14 @@ static const char *clutter_input_axis_atom_names[] = {
|
||||
|
||||
#define N_AXIS_ATOMS G_N_ELEMENTS (clutter_input_axis_atom_names)
|
||||
|
||||
enum {
|
||||
PAD_AXIS_FIRST = 3, /* First axes are always x/y/pressure, ignored in pads */
|
||||
PAD_AXIS_STRIP1 = PAD_AXIS_FIRST,
|
||||
PAD_AXIS_STRIP2,
|
||||
PAD_AXIS_RING1,
|
||||
PAD_AXIS_RING2,
|
||||
};
|
||||
|
||||
static Atom clutter_input_axis_atoms[N_AXIS_ATOMS] = { 0, };
|
||||
|
||||
static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface);
|
||||
@ -359,6 +368,36 @@ get_device_node_path (ClutterBackendX11 *backend_x11,
|
||||
return node_path;
|
||||
}
|
||||
|
||||
static void
|
||||
get_pad_features (XIDeviceInfo *info,
|
||||
guint *n_rings,
|
||||
guint *n_strips)
|
||||
{
|
||||
gint i, rings = 0, strips = 0;
|
||||
|
||||
for (i = PAD_AXIS_FIRST; i < info->num_classes; i++)
|
||||
{
|
||||
XIValuatorClassInfo *valuator = (XIValuatorClassInfo*) info->classes[i];
|
||||
int axis = valuator->number;
|
||||
|
||||
if (valuator->type != XIValuatorClass)
|
||||
continue;
|
||||
if (valuator->max <= 1)
|
||||
continue;
|
||||
|
||||
/* Ring/strip axes are fixed in pad devices as handled by the
|
||||
* wacom driver. Match those to detect pad features.
|
||||
*/
|
||||
if (axis == PAD_AXIS_STRIP1 || axis == PAD_AXIS_STRIP2)
|
||||
strips++;
|
||||
else if (axis == PAD_AXIS_RING1 || axis == PAD_AXIS_RING2)
|
||||
rings++;
|
||||
}
|
||||
|
||||
*n_rings = rings;
|
||||
*n_strips = strips;
|
||||
}
|
||||
|
||||
static ClutterInputDevice *
|
||||
create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
ClutterBackendX11 *backend_x11,
|
||||
@ -368,7 +407,7 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
ClutterInputDevice *retval;
|
||||
ClutterInputMode mode;
|
||||
gboolean is_enabled;
|
||||
guint num_touches = 0;
|
||||
guint num_touches = 0, num_rings = 0, num_strips = 0;
|
||||
gchar *vendor_id = NULL, *product_id = NULL, *node_path = NULL;
|
||||
|
||||
if (info->use == XIMasterKeyboard || info->use == XISlaveKeyboard)
|
||||
@ -436,6 +475,12 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
node_path = get_device_node_path (backend_x11, info);
|
||||
}
|
||||
|
||||
if (source == CLUTTER_PAD_DEVICE)
|
||||
{
|
||||
is_enabled = TRUE;
|
||||
get_pad_features (info, &num_rings, &num_strips);
|
||||
}
|
||||
|
||||
retval = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_XI2,
|
||||
"name", info->name,
|
||||
"id", info->deviceid,
|
||||
@ -448,6 +493,8 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
"vendor-id", vendor_id,
|
||||
"product-id", product_id,
|
||||
"device-node", node_path,
|
||||
"n-rings", num_rings,
|
||||
"n-strips", num_strips,
|
||||
NULL);
|
||||
|
||||
translate_device_classes (backend_x11->xdpy, retval,
|
||||
@ -847,6 +894,54 @@ translate_axes (ClutterInputDevice *device,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
translate_pad_axis (ClutterInputDevice *device,
|
||||
XIValuatorState *valuators,
|
||||
ClutterEventType *evtype,
|
||||
guint *number,
|
||||
gdouble *value)
|
||||
{
|
||||
double *values;
|
||||
gint i;
|
||||
|
||||
values = valuators->values;
|
||||
|
||||
for (i = PAD_AXIS_FIRST; i < valuators->mask_len * 8; i++)
|
||||
{
|
||||
gdouble val;
|
||||
guint axis_number = 0;
|
||||
|
||||
if (!XIMaskIsSet (valuators->mask, i))
|
||||
continue;
|
||||
|
||||
val = *values++;
|
||||
if (val <= 0)
|
||||
continue;
|
||||
|
||||
_clutter_input_device_translate_axis (device, i, val, value);
|
||||
|
||||
if (i == PAD_AXIS_RING1 || i == PAD_AXIS_RING2)
|
||||
{
|
||||
*evtype = CLUTTER_PAD_RING;
|
||||
(*value) *= 360.0;
|
||||
}
|
||||
else if (i == PAD_AXIS_STRIP1 || i == PAD_AXIS_STRIP2)
|
||||
{
|
||||
*evtype = CLUTTER_PAD_STRIP;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
if (i == PAD_AXIS_STRIP2 || i == PAD_AXIS_RING2)
|
||||
axis_number++;
|
||||
|
||||
*number = axis_number;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
translate_coords (ClutterStageX11 *stage_x11,
|
||||
gdouble event_x,
|
||||
@ -861,8 +956,8 @@ translate_coords (ClutterStageX11 *stage_x11,
|
||||
|
||||
clutter_actor_get_size (stage, &stage_width, &stage_height);
|
||||
|
||||
*x_out = CLAMP (event_x / stage_x11->scale_factor, 0, stage_width);
|
||||
*y_out = CLAMP (event_y / stage_x11->scale_factor, 0, stage_height);
|
||||
*x_out = CLAMP (event_x, 0, stage_width);
|
||||
*y_out = CLAMP (event_y, 0, stage_height);
|
||||
}
|
||||
|
||||
static gdouble
|
||||
@ -1025,6 +1120,54 @@ handle_property_event (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
translate_pad_event (ClutterEvent *event,
|
||||
XIDeviceEvent *xev,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
gdouble value;
|
||||
guint number;
|
||||
|
||||
if (!translate_pad_axis (device, &xev->valuators,
|
||||
&event->any.type,
|
||||
&number, &value))
|
||||
return FALSE;
|
||||
|
||||
/* When touching a ring/strip a first XI_Motion event
|
||||
* is generated. Use it to reset the pad state, so
|
||||
* later events actually have a directionality.
|
||||
*/
|
||||
if (xev->evtype == XI_Motion)
|
||||
value = -1;
|
||||
|
||||
if (event->any.type == CLUTTER_PAD_RING)
|
||||
{
|
||||
event->pad_ring.ring_number = number;
|
||||
event->pad_ring.angle = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
event->pad_strip.strip_number = number;
|
||||
event->pad_strip.value = value;
|
||||
}
|
||||
|
||||
event->any.time = xev->time;
|
||||
clutter_event_set_device (event, device);
|
||||
clutter_event_set_source_device (event, device);
|
||||
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"%s: win:0x%x, device:%d '%s', time:%d "
|
||||
"(value:%f)",
|
||||
event->any.type == CLUTTER_PAD_RING
|
||||
? "pad ring "
|
||||
: "pad strip",
|
||||
(unsigned int) xev->event,
|
||||
device->id,
|
||||
device->device_name,
|
||||
event->any.time, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterTranslateReturn
|
||||
clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
gpointer native,
|
||||
@ -1206,15 +1349,23 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
XIAsyncDevice,
|
||||
xev->time);
|
||||
|
||||
/* Ignore 4-7 buttons */
|
||||
if (xev->detail >= 4 && xev->detail <= 7)
|
||||
return CLUTTER_TRANSLATE_REMOVE;
|
||||
event->any.stage = stage;
|
||||
|
||||
event->pad_button.type =
|
||||
if (xev->detail >= 4 && xev->detail <= 7)
|
||||
{
|
||||
retval = CLUTTER_TRANSLATE_REMOVE;
|
||||
|
||||
if (xi_event->evtype == XI_ButtonPress &&
|
||||
translate_pad_event (event, xev, source_device))
|
||||
retval = CLUTTER_TRANSLATE_QUEUE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
event->any.type =
|
||||
(xi_event->evtype == XI_ButtonPress) ? CLUTTER_PAD_BUTTON_PRESS
|
||||
: CLUTTER_PAD_BUTTON_RELEASE;
|
||||
event->pad_button.time = xev->time;
|
||||
event->pad_button.stage = stage;
|
||||
event->any.time = xev->time;
|
||||
|
||||
/* The 4-7 button range is taken as non-existent on pad devices,
|
||||
* let the buttons above that take over this range.
|
||||
@ -1224,6 +1375,7 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
/* Pad buttons are 0-indexed */
|
||||
event->pad_button.button = xev->detail - 1;
|
||||
clutter_event_set_device (event, device);
|
||||
clutter_event_set_source_device (event, source_device);
|
||||
|
||||
CLUTTER_NOTE (EVENT,
|
||||
@ -1380,6 +1532,15 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
||||
GINT_TO_POINTER (xev->deviceid));
|
||||
|
||||
if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE)
|
||||
{
|
||||
event->any.stage = stage;
|
||||
|
||||
if (translate_pad_event (event, xev, source_device))
|
||||
retval = CLUTTER_TRANSLATE_QUEUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the stage for core events coming out of nowhere (see bug #684509) */
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER &&
|
||||
clutter_input_device_get_pointer_stage (device) == NULL &&
|
||||
@ -1827,6 +1988,8 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
|
||||
|
||||
XSync (backend_x11->xdpy, False);
|
||||
|
||||
clutter_device_manager_x11_a11y_init (manager);
|
||||
|
||||
if (G_OBJECT_CLASS (clutter_device_manager_xi2_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (clutter_device_manager_xi2_parent_class)->constructed (gobject);
|
||||
}
|
||||
@ -1889,6 +2052,7 @@ clutter_device_manager_xi2_class_init (ClutterDeviceManagerXI2Class *klass)
|
||||
manager_class->get_device = clutter_device_manager_xi2_get_device;
|
||||
manager_class->select_stage_events = clutter_device_manager_xi2_select_stage_events;
|
||||
manager_class->create_virtual_device = clutter_device_manager_xi2_create_virtual_device;
|
||||
manager_class->apply_kbd_a11y_settings = clutter_device_manager_x11_apply_kbd_a11y_settings;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -80,6 +80,13 @@ clutter_input_device_xi2_keycode_to_evdev (ClutterInputDevice *device,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_input_device_xi2_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
|
||||
{
|
||||
@ -89,6 +96,7 @@ clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
|
||||
gobject_class->constructed = clutter_input_device_xi2_constructed;
|
||||
|
||||
device_class->keycode_to_evdev = clutter_input_device_xi2_keycode_to_evdev;
|
||||
device_class->is_grouped = clutter_input_device_xi2_is_grouped;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -6,18 +6,14 @@ static const struct {
|
||||
const char *xsetting_name;
|
||||
const char *settings_property;
|
||||
} _clutter_settings_map[] = {
|
||||
{ "Net/DoubleClickTime", "double-click-time" },
|
||||
{ "Net/DoubleClickDistance", "double-click-distance" },
|
||||
{ "Net/DndDragThreshold", "dnd-drag-threshold" },
|
||||
{ "Gtk/FontName", "font-name" },
|
||||
{ "Xft/Antialias", "font-antialias" },
|
||||
{ "Xft/DPI", "font-dpi" },
|
||||
{ "Xft/Hinting", "font-hinting" },
|
||||
{ "Xft/HintStyle", "font-hint-style" },
|
||||
{ "Xft/RGBA", "font-subpixel-order" },
|
||||
{ "Fontconfig/Timestamp", "fontconfig-timestamp" },
|
||||
{ "Gdk/WindowScalingFactor", "window-scaling-factor" },
|
||||
{ "Gdk/UnscaledDPI", "unscaled-font-dpi" },
|
||||
};
|
||||
|
||||
static const gint _n_clutter_settings_map = G_N_ELEMENTS (_clutter_settings_map);
|
||||
|
@ -162,10 +162,10 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
|
||||
&min_height);
|
||||
|
||||
if (new_width <= 0)
|
||||
new_width = min_width * stage_x11->scale_factor;
|
||||
new_width = min_width;
|
||||
|
||||
if (new_height <= 0)
|
||||
new_height = min_height * stage_x11->scale_factor;
|
||||
new_height = min_height;
|
||||
|
||||
size_hints->flags = 0;
|
||||
|
||||
@ -175,8 +175,8 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
|
||||
{
|
||||
if (resize)
|
||||
{
|
||||
size_hints->min_width = min_width * stage_x11->scale_factor;
|
||||
size_hints->min_height = min_height * stage_x11->scale_factor;
|
||||
size_hints->min_width = min_width;
|
||||
size_hints->min_height = min_height;
|
||||
size_hints->flags = PMinSize;
|
||||
}
|
||||
else
|
||||
@ -236,8 +236,8 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window,
|
||||
return;
|
||||
}
|
||||
|
||||
geometry->width = stage_x11->xwin_width / stage_x11->scale_factor;
|
||||
geometry->height = stage_x11->xwin_height / stage_x11->scale_factor;
|
||||
geometry->width = stage_x11->xwin_width;
|
||||
geometry->height = stage_x11->xwin_height;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -255,8 +255,8 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
|
||||
* so we need to manually set the size and queue a relayout on the
|
||||
* stage here (as is normally done in response to ConfigureNotify).
|
||||
*/
|
||||
stage_x11->xwin_width = width * stage_x11->scale_factor;
|
||||
stage_x11->xwin_height = height * stage_x11->scale_factor;
|
||||
stage_x11->xwin_width = width;
|
||||
stage_x11->xwin_height = height;
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_cogl->wrapper));
|
||||
return;
|
||||
}
|
||||
@ -277,9 +277,6 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height);
|
||||
|
||||
width *= stage_x11->scale_factor;
|
||||
height *= stage_x11->scale_factor;
|
||||
|
||||
if (stage_x11->xwin != None)
|
||||
{
|
||||
clutter_stage_x11_fix_window_size (stage_x11, width, height);
|
||||
@ -400,20 +397,6 @@ set_cursor_visible (ClutterStageX11 *stage_x11)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_window_scaling_factor_notify (GObject *settings,
|
||||
GParamSpec *pspec,
|
||||
ClutterStageX11 *stage_x11)
|
||||
{
|
||||
g_object_get (settings,
|
||||
"window-scaling-factor", &stage_x11->scale_factor,
|
||||
NULL);
|
||||
|
||||
clutter_stage_x11_resize (CLUTTER_STAGE_WINDOW (stage_x11),
|
||||
stage_x11->xwin_width,
|
||||
stage_x11->xwin_height);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
|
||||
{
|
||||
@ -643,12 +626,8 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Wrapper size: %.2f x %.2f", width, height);
|
||||
|
||||
width = width * (float) stage_x11->scale_factor;
|
||||
height = height * (float) stage_x11->scale_factor;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Creating a new Cogl onscreen surface: %.2f x %.2f (factor: %d)",
|
||||
width, height,
|
||||
stage_x11->scale_factor);
|
||||
CLUTTER_NOTE (BACKEND, "Creating a new Cogl onscreen surface: %.2f x %.2f",
|
||||
width, height);
|
||||
|
||||
stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
|
||||
|
||||
@ -909,28 +888,6 @@ clutter_stage_x11_can_clip_redraws (ClutterStageWindow *stage_window)
|
||||
return stage_x11->clipped_redraws_cool_off == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_set_scale_factor (ClutterStageWindow *stage_window,
|
||||
int factor)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
if (stage_x11->scale_factor == factor)
|
||||
return;
|
||||
|
||||
stage_x11->scale_factor = factor;
|
||||
|
||||
clutter_stage_x11_resize (stage_window, stage_x11->xwin_width, stage_x11->xwin_height);
|
||||
}
|
||||
|
||||
static int
|
||||
clutter_stage_x11_get_scale_factor (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
return stage_x11->scale_factor;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_legacy_view (ClutterStageWindow *stage_window)
|
||||
{
|
||||
@ -1002,8 +959,6 @@ clutter_stage_x11_class_init (ClutterStageX11Class *klass)
|
||||
static void
|
||||
clutter_stage_x11_init (ClutterStageX11 *stage)
|
||||
{
|
||||
ClutterSettings *settings;
|
||||
|
||||
stage->xwin = None;
|
||||
stage->xwin_width = 640;
|
||||
stage->xwin_height = 480;
|
||||
@ -1016,12 +971,6 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
|
||||
stage->accept_focus = TRUE;
|
||||
|
||||
stage->title = NULL;
|
||||
|
||||
settings = clutter_settings_get_default ();
|
||||
g_signal_connect (settings, "notify::window-scaling-factor",
|
||||
G_CALLBACK (on_window_scaling_factor_notify),
|
||||
stage);
|
||||
on_window_scaling_factor_notify (G_OBJECT (settings), NULL, stage);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1041,8 +990,6 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||
iface->realize = clutter_stage_x11_realize;
|
||||
iface->unrealize = clutter_stage_x11_unrealize;
|
||||
iface->can_clip_redraws = clutter_stage_x11_can_clip_redraws;
|
||||
iface->set_scale_factor = clutter_stage_x11_set_scale_factor;
|
||||
iface->get_scale_factor = clutter_stage_x11_get_scale_factor;
|
||||
iface->get_views = clutter_stage_x11_get_views;
|
||||
iface->get_frame_counter = clutter_stage_x11_get_frame_counter;
|
||||
}
|
||||
@ -1167,8 +1114,8 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
|
||||
stage_x11->xwin_height = xevent->xconfigure.height;
|
||||
}
|
||||
|
||||
stage_width = xevent->xconfigure.width / stage_x11->scale_factor;
|
||||
stage_height = xevent->xconfigure.height / stage_x11->scale_factor;
|
||||
stage_width = xevent->xconfigure.width;
|
||||
stage_height = xevent->xconfigure.height;
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (stage), stage_width, stage_height);
|
||||
|
||||
if (size_changed)
|
||||
@ -1335,10 +1282,10 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
|
||||
expose->width,
|
||||
expose->height);
|
||||
|
||||
clip.x = expose->x / stage_x11->scale_factor;
|
||||
clip.y = expose->y / stage_x11->scale_factor;
|
||||
clip.width = expose->width / stage_x11->scale_factor;
|
||||
clip.height = expose->height / stage_x11->scale_factor;
|
||||
clip.x = expose->x;
|
||||
clip.y = expose->y;
|
||||
clip.width = expose->width;
|
||||
clip.height = expose->height;
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
|
||||
}
|
||||
break;
|
||||
@ -1504,8 +1451,8 @@ set_foreign_window_callback (ClutterActor *actor,
|
||||
fwd->stage_x11->xwin = fwd->xwindow;
|
||||
fwd->stage_x11->is_foreign_xwin = TRUE;
|
||||
|
||||
fwd->stage_x11->xwin_width = fwd->geom.width * fwd->stage_x11->scale_factor;
|
||||
fwd->stage_x11->xwin_height = fwd->geom.height * fwd->stage_x11->scale_factor;
|
||||
fwd->stage_x11->xwin_width = fwd->geom.width;
|
||||
fwd->stage_x11->xwin_height = fwd->geom.height;
|
||||
|
||||
clutter_actor_set_size (actor, fwd->geom.width, fwd->geom.height);
|
||||
|
||||
@ -1599,8 +1546,8 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
|
||||
|
||||
fwd.geom.x = x;
|
||||
fwd.geom.y = y;
|
||||
fwd.geom.width = width / stage_x11->scale_factor;
|
||||
fwd.geom.height = height / stage_x11->scale_factor;
|
||||
fwd.geom.width = width;
|
||||
fwd.geom.height = height;
|
||||
|
||||
actor = CLUTTER_ACTOR (stage);
|
||||
|
||||
|
@ -69,8 +69,6 @@ struct _ClutterStageX11
|
||||
|
||||
ClutterStageX11State wm_state;
|
||||
|
||||
int scale_factor;
|
||||
|
||||
guint is_foreign_xwin : 1;
|
||||
guint fullscreening : 1;
|
||||
guint is_cursor_visible : 1;
|
||||
|
328
clutter/clutter/x11/clutter-xkb-a11y-x11.c
Normal file
328
clutter/clutter/x11/clutter-xkb-a11y-x11.c
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
*
|
||||
* Copyright © 2001 Ximian, Inc.
|
||||
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||
* Copyright (C) 2017 Red Hat
|
||||
*
|
||||
* 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 "clutter-device-manager-private.h"
|
||||
#include "clutter-xkb-a11y-x11.h"
|
||||
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XKBstr.h>
|
||||
|
||||
#define DEFAULT_XKB_SET_CONTROLS_MASK XkbSlowKeysMask | \
|
||||
XkbBounceKeysMask | \
|
||||
XkbStickyKeysMask | \
|
||||
XkbMouseKeysMask | \
|
||||
XkbMouseKeysAccelMask | \
|
||||
XkbAccessXKeysMask | \
|
||||
XkbAccessXTimeoutMask | \
|
||||
XkbAccessXFeedbackMask | \
|
||||
XkbControlsEnabledMask
|
||||
|
||||
static int _xkb_event_base;
|
||||
|
||||
static XkbDescRec *
|
||||
get_xkb_desc_rec (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
XkbDescRec *desc;
|
||||
Status status = Success;
|
||||
|
||||
clutter_x11_trap_x_errors ();
|
||||
desc = XkbGetMap (backend_x11->xdpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
|
||||
if (desc != NULL)
|
||||
{
|
||||
desc->ctrls = NULL;
|
||||
status = XkbGetControls (backend_x11->xdpy, XkbAllControlsMask, desc);
|
||||
}
|
||||
clutter_x11_untrap_x_errors ();
|
||||
|
||||
g_return_val_if_fail (desc != NULL, NULL);
|
||||
g_return_val_if_fail (desc->ctrls != NULL, NULL);
|
||||
g_return_val_if_fail (status == Success, NULL);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void
|
||||
set_xkb_desc_rec (ClutterBackendX11 *backend_x11,
|
||||
XkbDescRec *desc)
|
||||
{
|
||||
clutter_x11_trap_x_errors ();
|
||||
XkbSetControls (backend_x11->xdpy, DEFAULT_XKB_SET_CONTROLS_MASK, desc);
|
||||
XSync (backend_x11->xdpy, FALSE);
|
||||
clutter_x11_untrap_x_errors ();
|
||||
}
|
||||
|
||||
static void
|
||||
check_settings_changed (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
||||
ClutterKeyboardA11yFlags what_changed = 0;
|
||||
XkbDescRec *desc;
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
desc = get_xkb_desc_rec (backend_x11);
|
||||
if (!desc)
|
||||
return;
|
||||
|
||||
clutter_device_manager_get_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
|
||||
|
||||
if (desc->ctrls->enabled_ctrls & XkbSlowKeysMask &&
|
||||
!(kbd_a11y_settings.controls & CLUTTER_A11Y_SLOW_KEYS_ENABLED))
|
||||
{
|
||||
what_changed |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
||||
kbd_a11y_settings.controls |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
||||
}
|
||||
else if (!(desc->ctrls->enabled_ctrls & XkbSlowKeysMask) &&
|
||||
kbd_a11y_settings.controls & CLUTTER_A11Y_SLOW_KEYS_ENABLED)
|
||||
{
|
||||
what_changed |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
||||
kbd_a11y_settings.controls &= ~CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
||||
}
|
||||
|
||||
if (desc->ctrls->enabled_ctrls & XkbStickyKeysMask &&
|
||||
!(kbd_a11y_settings.controls & CLUTTER_A11Y_STICKY_KEYS_ENABLED))
|
||||
{
|
||||
what_changed |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
||||
kbd_a11y_settings.controls |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
||||
}
|
||||
else if (!(desc->ctrls->enabled_ctrls & XkbStickyKeysMask) &&
|
||||
kbd_a11y_settings.controls & CLUTTER_A11Y_STICKY_KEYS_ENABLED)
|
||||
{
|
||||
what_changed |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
||||
kbd_a11y_settings.controls &= ~CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
||||
}
|
||||
|
||||
if (what_changed)
|
||||
g_signal_emit_by_name (device_manager,
|
||||
"kbd-a11y-flags-changed",
|
||||
kbd_a11y_settings.controls,
|
||||
what_changed);
|
||||
|
||||
XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE);
|
||||
}
|
||||
|
||||
static ClutterX11FilterReturn
|
||||
xkb_a11y_event_filter (XEvent *xevent,
|
||||
ClutterEvent *clutter_event,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterDeviceManager *device_manager = CLUTTER_DEVICE_MANAGER (data);
|
||||
XkbEvent *xkbev = (XkbEvent *) xevent;
|
||||
|
||||
/* 'event_type' is set to zero on notifying us of updates in
|
||||
* response to client requests (including our own) and non-zero
|
||||
* to notify us of key/mouse events causing changes (like
|
||||
* pressing shift 5 times to enable sticky keys).
|
||||
*
|
||||
* We only want to update out settings when it's in response to an
|
||||
* explicit user input event, so require a non-zero event_type.
|
||||
*/
|
||||
if (xevent->xany.type == (_xkb_event_base + XkbEventCode) &&
|
||||
xkbev->any.xkb_type == XkbControlsNotify && xkbev->ctrls.event_type != 0)
|
||||
check_settings_changed (device_manager);
|
||||
|
||||
return CLUTTER_X11_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_xkb_available (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
gint opcode, error_base, event_base, major, minor;
|
||||
|
||||
if (_xkb_event_base)
|
||||
return TRUE;
|
||||
|
||||
if (!XkbQueryExtension (backend_x11->xdpy,
|
||||
&opcode,
|
||||
&event_base,
|
||||
&error_base,
|
||||
&major,
|
||||
&minor))
|
||||
return FALSE;
|
||||
|
||||
if (!XkbUseExtension (backend_x11->xdpy, &major, &minor))
|
||||
return FALSE;
|
||||
|
||||
_xkb_event_base = event_base;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
set_value_mask (gboolean flag,
|
||||
unsigned long value,
|
||||
unsigned long mask)
|
||||
{
|
||||
if (flag)
|
||||
return value | mask;
|
||||
|
||||
return value & ~mask;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_xkb_ctrl (XkbDescRec *desc,
|
||||
ClutterKeyboardA11yFlags settings,
|
||||
ClutterKeyboardA11yFlags flag,
|
||||
unsigned long mask)
|
||||
{
|
||||
gboolean result = (settings & flag) == flag;
|
||||
desc->ctrls->enabled_ctrls = set_value_mask (result, desc->ctrls->enabled_ctrls, mask);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *kbd_a11y_settings)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
XkbDescRec *desc;
|
||||
gboolean enable_accessX;
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
desc = get_xkb_desc_rec (backend_x11);
|
||||
if (!desc)
|
||||
return;
|
||||
|
||||
/* general */
|
||||
enable_accessX = kbd_a11y_settings->controls & CLUTTER_A11Y_KEYBOARD_ENABLED;
|
||||
|
||||
desc->ctrls->enabled_ctrls = set_value_mask (enable_accessX,
|
||||
desc->ctrls->enabled_ctrls,
|
||||
XkbAccessXKeysMask);
|
||||
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, CLUTTER_A11Y_TIMEOUT_ENABLED,
|
||||
XkbAccessXTimeoutMask))
|
||||
{
|
||||
desc->ctrls->ax_timeout = kbd_a11y_settings->timeout_delay;
|
||||
/* disable only the master flag via the server we will disable
|
||||
* the rest on the rebound without affecting settings state
|
||||
* don't change the option flags at all.
|
||||
*/
|
||||
desc->ctrls->axt_ctrls_mask = XkbAccessXKeysMask | XkbAccessXFeedbackMask;
|
||||
desc->ctrls->axt_ctrls_values = 0;
|
||||
desc->ctrls->axt_opts_mask = 0;
|
||||
}
|
||||
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP,
|
||||
desc->ctrls->ax_options,
|
||||
XkbAccessXFeedbackMask | XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask);
|
||||
|
||||
/* bounce keys */
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_BOUNCE_KEYS_ENABLED, XkbBounceKeysMask))
|
||||
{
|
||||
desc->ctrls->debounce_delay = kbd_a11y_settings->debounce_delay;
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT,
|
||||
desc->ctrls->ax_options,
|
||||
XkbAccessXFeedbackMask | XkbAX_BKRejectFBMask);
|
||||
}
|
||||
|
||||
/* mouse keys */
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
|
||||
{
|
||||
gint mk_max_speed;
|
||||
gint mk_accel_time;
|
||||
|
||||
desc->ctrls->mk_interval = 100; /* msec between mousekey events */
|
||||
desc->ctrls->mk_curve = 50;
|
||||
|
||||
/* We store pixels / sec, XKB wants pixels / event */
|
||||
mk_max_speed = kbd_a11y_settings->mousekeys_max_speed;
|
||||
desc->ctrls->mk_max_speed = mk_max_speed / (1000 / desc->ctrls->mk_interval);
|
||||
if (desc->ctrls->mk_max_speed <= 0)
|
||||
desc->ctrls->mk_max_speed = 1;
|
||||
|
||||
mk_accel_time = kbd_a11y_settings->mousekeys_accel_time;
|
||||
desc->ctrls->mk_time_to_max = mk_accel_time / desc->ctrls->mk_interval;
|
||||
|
||||
if (desc->ctrls->mk_time_to_max <= 0)
|
||||
desc->ctrls->mk_time_to_max = 1;
|
||||
|
||||
desc->ctrls->mk_delay = kbd_a11y_settings->mousekeys_init_delay;
|
||||
}
|
||||
|
||||
/* slow keys */
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_SLOW_KEYS_ENABLED, XkbSlowKeysMask))
|
||||
{
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKPressFBMask);
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKAcceptFBMask);
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKRejectFBMask);
|
||||
desc->ctrls->slow_keys_delay = kbd_a11y_settings->slowkeys_delay;
|
||||
/* anything larger than 500 seems to loose all keyboard input */
|
||||
if (desc->ctrls->slow_keys_delay > 500)
|
||||
desc->ctrls->slow_keys_delay = 500;
|
||||
}
|
||||
|
||||
/* sticky keys */
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_STICKY_KEYS_ENABLED, XkbStickyKeysMask))
|
||||
{
|
||||
desc->ctrls->ax_options |= XkbAX_LatchToLockMask;
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_TwoKeysMask);
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_STICKY_KEYS_BEEP,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_StickyKeysFBMask);
|
||||
}
|
||||
|
||||
/* toggle keys */
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_IndicatorFBMask);
|
||||
|
||||
set_xkb_desc_rec (backend_x11, desc);
|
||||
XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
guint event_mask;
|
||||
|
||||
backend_x11 =
|
||||
CLUTTER_BACKEND_X11 (_clutter_device_manager_get_backend (device_manager));
|
||||
|
||||
if (!is_xkb_available (backend_x11))
|
||||
return FALSE;
|
||||
|
||||
event_mask = XkbControlsNotifyMask | XkbAccessXNotifyMask;
|
||||
|
||||
XkbSelectEvents (backend_x11->xdpy, XkbUseCoreKbd, event_mask, event_mask);
|
||||
|
||||
clutter_x11_add_filter (xkb_a11y_event_filter, device_manager);
|
||||
|
||||
return TRUE;
|
||||
}
|
39
clutter/clutter/x11/clutter-xkb-a11y-x11.h
Normal file
39
clutter/clutter/x11/clutter-xkb-a11y-x11.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
*
|
||||
* Copyright © 2001 Ximian, Inc.
|
||||
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||
* Copyright (C) 2017 Red Hat
|
||||
*
|
||||
* 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 CLUTTER_XKB_A11Y_X11_H
|
||||
#define CLUTTER_XKB_A11Y_X11_H
|
||||
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-backend-x11.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
void
|
||||
clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *kbd_a11y_settings);
|
||||
|
||||
gboolean
|
||||
clutter_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager);
|
||||
|
||||
#endif /* CLUTTER_XKB_A11Y_X11_H */
|
@ -110,7 +110,7 @@ LT_LIB_M
|
||||
AC_HEADER_STDC
|
||||
|
||||
# required versions for dependencies
|
||||
m4_define([glib_req_version], [2.44.0])
|
||||
m4_define([glib_req_version], [2.53.2])
|
||||
m4_define([cogl_req_version], [1.21.2])
|
||||
m4_define([json_glib_req_version], [0.12.0])
|
||||
m4_define([atk_req_version], [2.5.3])
|
||||
|
@ -79,7 +79,7 @@ script_tests = \
|
||||
test-script-timeline-markers.json \
|
||||
test-state-1.json
|
||||
|
||||
TESTS_ENVIRONMENT += G_ENABLE_DIAGNOSTIC=0 CLUTTER_ENABLE_DIAGNOSTIC=0
|
||||
TESTS_ENVIRONMENT += G_ENABLE_DIAGNOSTIC=0 CLUTTER_ENABLE_DIAGNOSTIC=0 CLUTTER_SCALE=1
|
||||
|
||||
# simple rules for generating a Git ignore file for the conformance test suite
|
||||
$(srcdir)/.gitignore: Makefile
|
||||
|
@ -350,7 +350,8 @@ actor_replace_child (void)
|
||||
g_assert_cmpstr (clutter_actor_get_name (iter), ==, "qux");
|
||||
|
||||
clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
|
||||
"name", "foo"));
|
||||
"name", "foo",
|
||||
NULL));
|
||||
|
||||
clutter_actor_replace_child (actor, iter,
|
||||
g_object_new (CLUTTER_TYPE_ACTOR,
|
||||
|
@ -81,6 +81,19 @@
|
||||
#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
|
||||
#endif
|
||||
|
||||
/* These aren't defined in the GLES2 headers */
|
||||
#ifndef GL_GUILTY_CONTEXT_RESET_ARB
|
||||
#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
|
||||
#endif
|
||||
|
||||
#ifndef GL_INNOCENT_CONTEXT_RESET_ARB
|
||||
#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
|
||||
#endif
|
||||
|
||||
#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB
|
||||
#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
|
||||
#endif
|
||||
|
||||
static void _cogl_context_free (CoglContext *context);
|
||||
|
||||
COGL_OBJECT_DEFINE (Context, context);
|
||||
|
@ -55,6 +55,13 @@ struct _CoglDriverVtable
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype);
|
||||
CoglPixelFormat
|
||||
(* pixel_format_to_gl_with_target) (CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
CoglPixelFormat target_format,
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype);
|
||||
|
||||
CoglBool
|
||||
(* update_features) (CoglContext *context,
|
||||
|
@ -51,6 +51,9 @@ typedef struct _CoglGLXDisplay
|
||||
|
||||
CoglBool found_fbconfig;
|
||||
CoglBool fbconfig_has_rgba_visual;
|
||||
CoglBool is_direct;
|
||||
CoglBool have_vblank_counter;
|
||||
CoglBool can_vblank_wait;
|
||||
GLXFBConfig fbconfig;
|
||||
|
||||
/* Single context for all wins */
|
||||
|
@ -43,8 +43,6 @@ typedef struct _CoglGLXRenderer
|
||||
int glx_error_base;
|
||||
int glx_event_base;
|
||||
|
||||
CoglBool is_direct;
|
||||
|
||||
/* Vblank stuff */
|
||||
int dri_fd;
|
||||
|
||||
|
@ -169,7 +169,8 @@ check_qualcomm_vendor (const CoglGpuInfoStrings *strings)
|
||||
static CoglBool
|
||||
check_nvidia_vendor (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strcmp (strings->vendor_string, "NVIDIA") != 0)
|
||||
if (strcmp (strings->vendor_string, "NVIDIA") != 0 &&
|
||||
strcmp (strings->vendor_string, "NVIDIA Corporation") != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -1102,7 +1102,7 @@ upload_vertices (CoglJournal *journal,
|
||||
|
||||
attribute_buffer = create_attribute_buffer (journal, needed_vbo_len * 4);
|
||||
buffer = COGL_BUFFER (attribute_buffer);
|
||||
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_STATIC);
|
||||
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_DYNAMIC);
|
||||
|
||||
vout = _cogl_buffer_map_range_for_fill_or_fallback (buffer,
|
||||
0, /* offset */
|
||||
|
@ -42,7 +42,8 @@
|
||||
#include <cogl/winsys/cogl-winsys-egl-private.h>
|
||||
#include <cogl/winsys/cogl-winsys-private.h>
|
||||
|
||||
void cogl_renderer_set_custom_winsys (CoglRenderer *renderer,
|
||||
CoglWinsysVtableGetter winsys_vtable_getter);
|
||||
void cogl_renderer_set_custom_winsys (CoglRenderer *renderer,
|
||||
CoglCustomWinsysVtableGetter winsys_vtable_getter,
|
||||
void *user_data);
|
||||
|
||||
#endif /* __COGL_MUTTER_H___ */
|
||||
|
@ -77,6 +77,9 @@ typedef enum
|
||||
COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE,
|
||||
COGL_PRIVATE_FEATURE_GL_EMBEDDED,
|
||||
COGL_PRIVATE_FEATURE_GL_WEB,
|
||||
/* This is currently only implemented for GLX, but isn't actually
|
||||
* that winsys dependent */
|
||||
COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT,
|
||||
|
||||
COGL_N_PRIVATE_FEATURES
|
||||
} CoglPrivateFeature;
|
||||
|
@ -39,12 +39,13 @@
|
||||
#include "cogl-texture-driver.h"
|
||||
#include "cogl-context.h"
|
||||
#include "cogl-closure-list-private.h"
|
||||
#include "cogl-mutter.h"
|
||||
|
||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
typedef const CoglWinsysVtable *(*CoglCustomWinsysVtableGetter) (CoglRenderer *renderer);
|
||||
|
||||
struct _CoglRenderer
|
||||
{
|
||||
CoglObject _parent;
|
||||
@ -53,7 +54,8 @@ struct _CoglRenderer
|
||||
const CoglDriverVtable *driver_vtable;
|
||||
const CoglTextureDriver *texture_driver;
|
||||
const CoglWinsysVtable *winsys_vtable;
|
||||
CoglWinsysVtableGetter custom_winsys_vtable_getter;
|
||||
void *custom_winsys_user_data;
|
||||
CoglCustomWinsysVtableGetter custom_winsys_vtable_getter;
|
||||
CoglWinsysID winsys_id_override;
|
||||
GList *constraints;
|
||||
|
||||
@ -69,6 +71,7 @@ struct _CoglRenderer
|
||||
Display *foreign_xdpy;
|
||||
CoglBool xlib_enable_event_retrieval;
|
||||
CoglBool xlib_want_reset_on_video_memory_purge;
|
||||
CoglBool xlib_enable_threaded_swap_wait;
|
||||
#endif
|
||||
|
||||
CoglDriver driver;
|
||||
|
@ -285,6 +285,17 @@ cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer,
|
||||
|
||||
renderer->xlib_want_reset_on_video_memory_purge = enable;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_xlib_renderer_set_threaded_swap_wait_enabled (CoglRenderer *renderer,
|
||||
CoglBool enable)
|
||||
{
|
||||
_COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer));
|
||||
/* NB: Renderers are considered immutable once connected */
|
||||
_COGL_RETURN_IF_FAIL (!renderer->connected);
|
||||
|
||||
renderer->xlib_enable_threaded_swap_wait = enable;
|
||||
}
|
||||
#endif /* COGL_HAS_XLIB_SUPPORT */
|
||||
|
||||
CoglBool
|
||||
@ -554,9 +565,11 @@ _cogl_renderer_choose_driver (CoglRenderer *renderer,
|
||||
/* Final connection API */
|
||||
|
||||
void
|
||||
cogl_renderer_set_custom_winsys (CoglRenderer *renderer,
|
||||
CoglWinsysVtableGetter winsys_vtable_getter)
|
||||
cogl_renderer_set_custom_winsys (CoglRenderer *renderer,
|
||||
CoglCustomWinsysVtableGetter winsys_vtable_getter,
|
||||
void *user_data)
|
||||
{
|
||||
renderer->custom_winsys_user_data = user_data;
|
||||
renderer->custom_winsys_vtable_getter = winsys_vtable_getter;
|
||||
}
|
||||
|
||||
@ -564,10 +577,11 @@ static CoglBool
|
||||
connect_custom_winsys (CoglRenderer *renderer,
|
||||
CoglError **error)
|
||||
{
|
||||
const CoglWinsysVtable *winsys = renderer->custom_winsys_vtable_getter();
|
||||
const CoglWinsysVtable *winsys;
|
||||
CoglError *tmp_error = NULL;
|
||||
GString *error_message;
|
||||
|
||||
winsys = renderer->custom_winsys_vtable_getter (renderer);
|
||||
renderer->winsys_vtable = winsys;
|
||||
|
||||
error_message = g_string_new ("");
|
||||
|
@ -198,6 +198,7 @@ struct _CoglTextureDriver
|
||||
CoglPixelFormat
|
||||
(* find_best_gl_get_data_format) (CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
CoglPixelFormat target_format,
|
||||
GLenum *closest_gl_format,
|
||||
GLenum *closest_gl_type);
|
||||
};
|
||||
|
@ -1059,6 +1059,7 @@ cogl_texture_get_data (CoglTexture *texture,
|
||||
|
||||
closest_format =
|
||||
ctx->texture_driver->find_best_gl_get_data_format (ctx,
|
||||
texture_format,
|
||||
format,
|
||||
&closest_gl_format,
|
||||
&closest_gl_type);
|
||||
|
@ -167,6 +167,36 @@ void
|
||||
cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer,
|
||||
CoglBool enable);
|
||||
|
||||
/**
|
||||
* cogl_xlib_renderer_set_threaded_swap_wait_enabled:
|
||||
* @renderer: a #CoglRenderer
|
||||
* @enable: The new value
|
||||
*
|
||||
* Sets whether Cogl is allowed to use a separate threaded to wait for the
|
||||
* completion of glXSwapBuffers() and call the frame callback for the
|
||||
* corresponding #CoglOnscreen. This is a way of emulating the
|
||||
* INTEL_swap_event extension, and will only ever be used if
|
||||
* INTEL_swap_event is not present; it will also only be used for
|
||||
* specific white-listed drivers that are known to work correctly with
|
||||
* multiple contexts sharing state between threads.
|
||||
*
|
||||
* The advantage of enabling this is that it will allow your main loop
|
||||
* to do other work while waiting for the system to be ready to draw
|
||||
* the next frame, instead of blocking in glXSwapBuffers(). A disadvantage
|
||||
* is that the driver will be prevented from buffering up multiple frames
|
||||
* even if it thinks that it would be advantageous. In general, this
|
||||
* will work best for something like a system compositor that is doing
|
||||
* simple drawing but handling lots of other complex tasks.
|
||||
*
|
||||
* If you enable this, you must call XInitThreads() before any other
|
||||
* X11 calls in your program. (See the documentation for XInitThreads())
|
||||
*
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
cogl_xlib_renderer_set_threaded_swap_wait_enabled (CoglRenderer *renderer,
|
||||
CoglBool enable);
|
||||
|
||||
/**
|
||||
* cogl_xlib_renderer_get_display: (skip)
|
||||
*/
|
||||
|
@ -1417,6 +1417,17 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
|
||||
&gl_intformat,
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
#if HAVE_COGL_GL
|
||||
/* As we are reading pixels, we want to consider the bitmap according to
|
||||
* its real pixel format, not the swizzled channels we pretend face to the
|
||||
* pipeline.
|
||||
*/
|
||||
if ((ctx->driver == COGL_DRIVER_GL || ctx->driver == COGL_DRIVER_GL3) &&
|
||||
(format == COGL_PIXEL_FORMAT_BGRA_8888 ||
|
||||
format == COGL_PIXEL_FORMAT_BGRA_8888_PRE) &&
|
||||
_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
|
||||
gl_format = GL_BGRA;
|
||||
#endif
|
||||
|
||||
/* NB: All offscreen rendering is done upside down so there is no need
|
||||
* to flip in this case... */
|
||||
|
@ -772,11 +772,12 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
|
||||
|
||||
upload_format = cogl_bitmap_get_format (upload_bmp);
|
||||
|
||||
ctx->driver_vtable->pixel_format_to_gl (ctx,
|
||||
upload_format,
|
||||
NULL, /* internal format */
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
ctx->driver_vtable->pixel_format_to_gl_with_target (ctx,
|
||||
upload_format,
|
||||
_cogl_texture_get_format (tex),
|
||||
NULL, /* internal gl format */
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
|
||||
/* If this touches the first pixel then we'll update our copy */
|
||||
if (dst_x == 0 && dst_y == 0 &&
|
||||
|
@ -37,6 +37,11 @@
|
||||
#include "cogl-gl-header.h"
|
||||
#include "cogl-texture.h"
|
||||
|
||||
/* In OpenGL ES context, GL_CONTEXT_LOST has a _KHR prefix */
|
||||
#ifndef GL_CONTEXT_LOST
|
||||
#define GL_CONTEXT_LOST GL_CONTEXT_LOST_KHR
|
||||
#endif
|
||||
|
||||
#ifdef COGL_GL_DEBUG
|
||||
|
||||
const char *
|
||||
|
@ -96,11 +96,12 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
|
||||
}
|
||||
|
||||
static CoglPixelFormat
|
||||
_cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype)
|
||||
_cogl_driver_pixel_format_to_gl_with_target (CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
CoglPixelFormat target_format,
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype)
|
||||
{
|
||||
CoglPixelFormat required_format;
|
||||
GLenum glintformat = 0;
|
||||
@ -174,7 +175,16 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888:
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
|
||||
glintformat = GL_RGBA;
|
||||
glformat = GL_BGRA;
|
||||
/* If the driver has texture_swizzle, pretend internal
|
||||
* and buffer format are the same here, the pixels
|
||||
* will be flipped through this extension.
|
||||
*/
|
||||
if (target_format == format &&
|
||||
_cogl_has_private_feature
|
||||
(context, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
|
||||
glformat = GL_RGBA;
|
||||
else
|
||||
glformat = GL_BGRA;
|
||||
gltype = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
|
||||
@ -289,6 +299,20 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
return required_format;
|
||||
}
|
||||
|
||||
static CoglPixelFormat
|
||||
_cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype)
|
||||
{
|
||||
return _cogl_driver_pixel_format_to_gl_with_target (context,
|
||||
format, format,
|
||||
out_glintformat,
|
||||
out_glformat,
|
||||
out_gltype);
|
||||
}
|
||||
|
||||
static CoglBool
|
||||
_cogl_get_gl_version (CoglContext *ctx,
|
||||
int *major_out,
|
||||
@ -669,6 +693,7 @@ _cogl_driver_gl =
|
||||
{
|
||||
_cogl_driver_pixel_format_from_gl_internal,
|
||||
_cogl_driver_pixel_format_to_gl,
|
||||
_cogl_driver_pixel_format_to_gl_with_target,
|
||||
_cogl_driver_update_features,
|
||||
_cogl_offscreen_gl_allocate,
|
||||
_cogl_offscreen_gl_free,
|
||||
|
@ -114,6 +114,18 @@ _cogl_texture_driver_gen (CoglContext *ctx,
|
||||
red_swizzle) );
|
||||
}
|
||||
|
||||
/* If swizzle extension is available, prefer it to flip bgra buffers to rgba */
|
||||
if ((internal_format == COGL_PIXEL_FORMAT_BGRA_8888 ||
|
||||
internal_format == COGL_PIXEL_FORMAT_BGRA_8888_PRE) &&
|
||||
_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
|
||||
{
|
||||
static const GLint bgra_swizzle[] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
|
||||
|
||||
GE( ctx, glTexParameteriv (gl_target,
|
||||
GL_TEXTURE_SWIZZLE_RGBA,
|
||||
bgra_swizzle) );
|
||||
}
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
@ -521,14 +533,16 @@ static CoglPixelFormat
|
||||
_cogl_texture_driver_find_best_gl_get_data_format
|
||||
(CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
CoglPixelFormat target_format,
|
||||
GLenum *closest_gl_format,
|
||||
GLenum *closest_gl_type)
|
||||
{
|
||||
return context->driver_vtable->pixel_format_to_gl (context,
|
||||
format,
|
||||
NULL, /* don't need */
|
||||
closest_gl_format,
|
||||
closest_gl_type);
|
||||
return context->driver_vtable->pixel_format_to_gl_with_target (context,
|
||||
format,
|
||||
target_format,
|
||||
NULL, /* don't need */
|
||||
closest_gl_format,
|
||||
closest_gl_type);
|
||||
}
|
||||
|
||||
const CoglTextureDriver
|
||||
|
@ -67,11 +67,12 @@ _cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
|
||||
}
|
||||
|
||||
static CoglPixelFormat
|
||||
_cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype)
|
||||
_cogl_driver_pixel_format_to_gl_with_target (CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
CoglPixelFormat target_format,
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype)
|
||||
{
|
||||
CoglPixelFormat required_format;
|
||||
GLenum glintformat;
|
||||
@ -219,6 +220,20 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
return required_format;
|
||||
}
|
||||
|
||||
static CoglPixelFormat
|
||||
_cogl_driver_pixel_format_to_gl (CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype)
|
||||
{
|
||||
return _cogl_driver_pixel_format_to_gl_with_target (context,
|
||||
format, format,
|
||||
out_glintformat,
|
||||
out_glformat,
|
||||
out_gltype);
|
||||
}
|
||||
|
||||
static CoglBool
|
||||
_cogl_get_gl_version (CoglContext *ctx,
|
||||
int *major_out,
|
||||
@ -457,6 +472,7 @@ _cogl_driver_gles =
|
||||
{
|
||||
_cogl_driver_pixel_format_from_gl_internal,
|
||||
_cogl_driver_pixel_format_to_gl,
|
||||
_cogl_driver_pixel_format_to_gl_with_target,
|
||||
_cogl_driver_update_features,
|
||||
_cogl_offscreen_gl_allocate,
|
||||
_cogl_offscreen_gl_free,
|
||||
|
@ -615,6 +615,7 @@ static CoglPixelFormat
|
||||
_cogl_texture_driver_find_best_gl_get_data_format
|
||||
(CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
CoglPixelFormat target_format,
|
||||
GLenum *closest_gl_format,
|
||||
GLenum *closest_gl_type)
|
||||
{
|
||||
|
@ -61,6 +61,7 @@ _cogl_driver_nop =
|
||||
{
|
||||
NULL, /* pixel_format_from_gl_internal */
|
||||
NULL, /* pixel_format_to_gl */
|
||||
NULL, /* pixel_format_to_gl_with_target */
|
||||
_cogl_driver_update_features,
|
||||
_cogl_offscreen_nop_allocate,
|
||||
_cogl_offscreen_nop_free,
|
||||
|
@ -65,12 +65,16 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <GL/glx.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/* This is a relatively new extension */
|
||||
#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV
|
||||
#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
|
||||
@ -100,6 +104,14 @@ typedef struct _CoglOnscreenGLX
|
||||
CoglBool pending_sync_notify;
|
||||
CoglBool pending_complete_notify;
|
||||
CoglBool pending_resize_notify;
|
||||
|
||||
GThread *swap_wait_thread;
|
||||
GQueue *swap_wait_queue;
|
||||
GCond swap_wait_cond;
|
||||
GMutex swap_wait_mutex;
|
||||
int swap_wait_pipe[2];
|
||||
GLXContext swap_wait_context;
|
||||
CoglBool closing_down;
|
||||
} CoglOnscreenGLX;
|
||||
|
||||
typedef struct _CoglPixmapTextureEyeGLX
|
||||
@ -192,6 +204,15 @@ find_onscreen_for_xid (CoglContext *context, uint32_t xid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
get_monotonic_time_ns (void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
clock_gettime (CLOCK_MONOTONIC, &ts);
|
||||
return ts.tv_sec * G_GINT64_CONSTANT (1000000000) + ts.tv_nsec;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_ust_type (CoglRenderer *renderer,
|
||||
GLXDrawable drawable)
|
||||
@ -202,7 +223,6 @@ ensure_ust_type (CoglRenderer *renderer,
|
||||
int64_t msc;
|
||||
int64_t sbc;
|
||||
struct timeval tv;
|
||||
struct timespec ts;
|
||||
int64_t current_system_time;
|
||||
int64_t current_monotonic_time;
|
||||
|
||||
@ -232,9 +252,7 @@ ensure_ust_type (CoglRenderer *renderer,
|
||||
|
||||
/* This is the time source that the newer (fixed) linux drm
|
||||
* drivers use (Linux >= 3.8) */
|
||||
clock_gettime (CLOCK_MONOTONIC, &ts);
|
||||
current_monotonic_time = (ts.tv_sec * G_GINT64_CONSTANT (1000000)) +
|
||||
(ts.tv_nsec / G_GINT64_CONSTANT (1000));
|
||||
current_monotonic_time = get_monotonic_time_ns () / 1000;
|
||||
|
||||
if (current_monotonic_time > ust - 1000000 &&
|
||||
current_monotonic_time < ust + 1000000)
|
||||
@ -290,6 +308,9 @@ _cogl_winsys_get_clock_time (CoglContext *context)
|
||||
{
|
||||
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
|
||||
|
||||
if (!glx_renderer->glXWaitForMsc)
|
||||
return get_monotonic_time_ns ();
|
||||
|
||||
/* We don't call ensure_ust_type() because we don't have a drawable
|
||||
* to work with. cogl_get_clock_time() is documented to only work
|
||||
* once a valid, non-zero, timestamp has been retrieved from Cogl.
|
||||
@ -310,10 +331,7 @@ _cogl_winsys_get_clock_time (CoglContext *context)
|
||||
}
|
||||
case COGL_GLX_UST_IS_MONOTONIC_TIME:
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
clock_gettime (CLOCK_MONOTONIC, &ts);
|
||||
return ts.tv_sec * G_GINT64_CONSTANT (1000000000) + ts.tv_nsec;
|
||||
return get_monotonic_time_ns ();
|
||||
}
|
||||
}
|
||||
|
||||
@ -712,23 +730,25 @@ update_base_winsys_features (CoglRenderer *renderer)
|
||||
|
||||
g_strfreev (split_extensions);
|
||||
|
||||
/* Note: the GLX_SGI_video_sync spec explicitly states this extension
|
||||
* only works for direct contexts. */
|
||||
if (!glx_renderer->is_direct)
|
||||
{
|
||||
glx_renderer->glXGetVideoSync = NULL;
|
||||
glx_renderer->glXWaitVideoSync = NULL;
|
||||
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
|
||||
COGL_WINSYS_FEATURE_VBLANK_COUNTER,
|
||||
FALSE);
|
||||
}
|
||||
/* The GLX_SGI_video_sync spec explicitly states this extension
|
||||
* only works for direct contexts; we don't know per-renderer
|
||||
* if the context is direct or not, so we turn off the feature
|
||||
* flag; we still use the extension within this file looking
|
||||
* instead at glx_display->have_vblank_counter.
|
||||
*/
|
||||
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
|
||||
COGL_WINSYS_FEATURE_VBLANK_COUNTER,
|
||||
FALSE);
|
||||
|
||||
|
||||
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
|
||||
COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN,
|
||||
TRUE);
|
||||
|
||||
if (glx_renderer->glXWaitVideoSync ||
|
||||
glx_renderer->glXWaitForMsc)
|
||||
/* Because of the direct-context dependency, the VBLANK_WAIT feature
|
||||
* doesn't reflect the presence of GLX_SGI_video_sync.
|
||||
*/
|
||||
if (glx_renderer->glXWaitForMsc)
|
||||
COGL_FLAGS_SET (glx_renderer->base_winsys_features,
|
||||
COGL_WINSYS_FEATURE_VBLANK_WAIT,
|
||||
TRUE);
|
||||
@ -861,7 +881,7 @@ update_winsys_features (CoglContext *context, CoglError **error)
|
||||
* by the SwapInterval so we have to throttle swap_region requests
|
||||
* manually... */
|
||||
if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION) &&
|
||||
_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT))
|
||||
(glx_display->have_vblank_counter || glx_display->can_vblank_wait))
|
||||
COGL_FLAGS_SET (context->winsys_features,
|
||||
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
|
||||
|
||||
@ -877,6 +897,29 @@ update_winsys_features (CoglContext *context, CoglError **error)
|
||||
COGL_FEATURE_ID_PRESENTATION_TIME,
|
||||
TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoglGpuInfo *info = &context->gpu;
|
||||
if (glx_display->have_vblank_counter &&
|
||||
context->display->renderer->xlib_enable_threaded_swap_wait &&
|
||||
info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
|
||||
{
|
||||
COGL_FLAGS_SET (context->winsys_features,
|
||||
COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT, TRUE);
|
||||
COGL_FLAGS_SET (context->winsys_features,
|
||||
COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE);
|
||||
/* TODO: remove this deprecated feature */
|
||||
COGL_FLAGS_SET (context->features,
|
||||
COGL_FEATURE_ID_SWAP_BUFFERS_EVENT,
|
||||
TRUE);
|
||||
COGL_FLAGS_SET (context->features,
|
||||
COGL_FEATURE_ID_PRESENTATION_TIME,
|
||||
TRUE);
|
||||
COGL_FLAGS_SET (context->private_features,
|
||||
COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT,
|
||||
TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/* We'll manually handle queueing dirty events in response to
|
||||
* Expose events from X */
|
||||
@ -1139,11 +1182,13 @@ create_context (CoglDisplay *display, CoglError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
glx_renderer->is_direct =
|
||||
glx_display->is_direct =
|
||||
glx_renderer->glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context);
|
||||
glx_display->have_vblank_counter = glx_display->is_direct && glx_renderer->glXWaitVideoSync;
|
||||
glx_display->can_vblank_wait = glx_renderer->glXWaitForMsc || glx_display->have_vblank_counter;
|
||||
|
||||
COGL_NOTE (WINSYS, "Setting %s context",
|
||||
glx_renderer->is_direct ? "direct" : "indirect");
|
||||
glx_display->is_direct ? "direct" : "indirect");
|
||||
|
||||
/* XXX: GLX doesn't let us make a context current without a window
|
||||
* so we create a dummy window that we can use while no CoglOnscreen
|
||||
@ -1471,7 +1516,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
||||
}
|
||||
|
||||
#ifdef GLX_INTEL_swap_event
|
||||
if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT))
|
||||
if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT) &&
|
||||
!_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT))
|
||||
{
|
||||
GLXDrawable drawable =
|
||||
glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin;
|
||||
@ -1514,6 +1560,31 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
|
||||
xlib_onscreen->output = NULL;
|
||||
}
|
||||
|
||||
if (glx_onscreen->swap_wait_thread)
|
||||
{
|
||||
g_mutex_lock (&glx_onscreen->swap_wait_mutex);
|
||||
glx_onscreen->closing_down = TRUE;
|
||||
g_cond_signal (&glx_onscreen->swap_wait_cond);
|
||||
g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
|
||||
g_thread_join (glx_onscreen->swap_wait_thread);
|
||||
glx_onscreen->swap_wait_thread = NULL;
|
||||
|
||||
g_cond_clear (&glx_onscreen->swap_wait_cond);
|
||||
g_mutex_clear (&glx_onscreen->swap_wait_mutex);
|
||||
|
||||
g_queue_free (glx_onscreen->swap_wait_queue);
|
||||
glx_onscreen->swap_wait_queue = NULL;
|
||||
|
||||
_cogl_poll_renderer_remove_fd (context->display->renderer,
|
||||
glx_onscreen->swap_wait_pipe[0]);
|
||||
|
||||
close (glx_onscreen->swap_wait_pipe[0]);
|
||||
close (glx_onscreen->swap_wait_pipe[1]);
|
||||
|
||||
glx_renderer->glXDestroyContext (xlib_renderer->xdpy,
|
||||
glx_onscreen->swap_wait_context);
|
||||
}
|
||||
|
||||
_cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state);
|
||||
|
||||
drawable =
|
||||
@ -1655,12 +1726,13 @@ _cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen)
|
||||
CoglContext *ctx = framebuffer->context;
|
||||
CoglGLXRenderer *glx_renderer;
|
||||
CoglXlibRenderer *xlib_renderer;
|
||||
CoglGLXDisplay *glx_display;
|
||||
|
||||
glx_renderer = ctx->display->renderer->winsys;
|
||||
xlib_renderer = _cogl_xlib_renderer_get_data (ctx->display->renderer);
|
||||
glx_display = ctx->display->winsys;
|
||||
|
||||
if (glx_renderer->glXWaitForMsc ||
|
||||
glx_renderer->glXGetVideoSync)
|
||||
if (glx_display->can_vblank_wait)
|
||||
{
|
||||
CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
|
||||
|
||||
@ -1682,16 +1754,13 @@ _cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen)
|
||||
else
|
||||
{
|
||||
uint32_t current_count;
|
||||
struct timespec ts;
|
||||
|
||||
glx_renderer->glXGetVideoSync (¤t_count);
|
||||
glx_renderer->glXWaitVideoSync (2,
|
||||
(current_count + 1) % 2,
|
||||
¤t_count);
|
||||
|
||||
clock_gettime (CLOCK_MONOTONIC, &ts);
|
||||
info->presentation_time =
|
||||
ts.tv_sec * G_GINT64_CONSTANT (1000000000) + ts.tv_nsec;
|
||||
info->presentation_time = get_monotonic_time_ns ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1749,6 +1818,199 @@ set_frame_info_output (CoglOnscreen *onscreen,
|
||||
}
|
||||
}
|
||||
|
||||
static gpointer
|
||||
threaded_swap_wait (gpointer data)
|
||||
{
|
||||
CoglOnscreen *onscreen = data;
|
||||
|
||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
||||
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
CoglContext *context = framebuffer->context;
|
||||
CoglDisplay *display = context->display;
|
||||
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (display->renderer);
|
||||
CoglGLXDisplay *glx_display = display->winsys;
|
||||
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
|
||||
GLXDrawable dummy_drawable;
|
||||
|
||||
if (glx_display->dummy_glxwin)
|
||||
dummy_drawable = glx_display->dummy_glxwin;
|
||||
else
|
||||
dummy_drawable = glx_display->dummy_xwin;
|
||||
|
||||
glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
|
||||
dummy_drawable,
|
||||
dummy_drawable,
|
||||
glx_onscreen->swap_wait_context);
|
||||
|
||||
g_mutex_lock (&glx_onscreen->swap_wait_mutex);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
gpointer queue_element;
|
||||
uint32_t vblank_counter;
|
||||
|
||||
while (!glx_onscreen->closing_down && glx_onscreen->swap_wait_queue->length == 0)
|
||||
g_cond_wait (&glx_onscreen->swap_wait_cond, &glx_onscreen->swap_wait_mutex);
|
||||
|
||||
if (glx_onscreen->closing_down)
|
||||
break;
|
||||
|
||||
queue_element = g_queue_pop_tail (glx_onscreen->swap_wait_queue);
|
||||
vblank_counter = GPOINTER_TO_UINT(queue_element);
|
||||
|
||||
g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
|
||||
glx_renderer->glXWaitVideoSync (2,
|
||||
(vblank_counter + 1) % 2,
|
||||
&vblank_counter);
|
||||
g_mutex_lock (&glx_onscreen->swap_wait_mutex);
|
||||
|
||||
if (!glx_onscreen->closing_down)
|
||||
{
|
||||
int bytes_written = 0;
|
||||
|
||||
union {
|
||||
char bytes[8];
|
||||
int64_t presentation_time;
|
||||
} u;
|
||||
|
||||
u.presentation_time = get_monotonic_time_ns ();
|
||||
|
||||
while (bytes_written < 8)
|
||||
{
|
||||
int res = write (glx_onscreen->swap_wait_pipe[1], u.bytes + bytes_written, 8 - bytes_written);
|
||||
if (res == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
g_error ("Error writing to swap notification pipe: %s\n",
|
||||
g_strerror (errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_written += res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
|
||||
|
||||
glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
|
||||
None,
|
||||
None,
|
||||
NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
threaded_swap_wait_pipe_prepare (void *user_data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
threaded_swap_wait_pipe_dispatch (void *user_data, int revents)
|
||||
{
|
||||
CoglOnscreen *onscreen = user_data;
|
||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
||||
|
||||
CoglFrameInfo *info;
|
||||
|
||||
if ((revents & COGL_POLL_FD_EVENT_IN))
|
||||
{
|
||||
int bytes_read = 0;
|
||||
|
||||
union {
|
||||
char bytes[8];
|
||||
int64_t presentation_time;
|
||||
} u;
|
||||
|
||||
while (bytes_read < 8)
|
||||
{
|
||||
int res = read (glx_onscreen->swap_wait_pipe[0], u.bytes + bytes_read, 8 - bytes_read);
|
||||
if (res == -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
g_error ("Error reading from swap notification pipe: %s\n",
|
||||
g_strerror (errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_read += res;
|
||||
}
|
||||
}
|
||||
|
||||
set_sync_pending (onscreen);
|
||||
set_complete_pending (onscreen);
|
||||
|
||||
info = g_queue_peek_head (&onscreen->pending_frame_infos);
|
||||
info->presentation_time = u.presentation_time;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
start_threaded_swap_wait (CoglOnscreen *onscreen,
|
||||
uint32_t vblank_counter)
|
||||
{
|
||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
CoglContext *context = framebuffer->context;
|
||||
|
||||
if (glx_onscreen->swap_wait_thread == NULL)
|
||||
{
|
||||
CoglDisplay *display = context->display;
|
||||
CoglGLXRenderer *glx_renderer = display->renderer->winsys;
|
||||
CoglGLXDisplay *glx_display = display->winsys;
|
||||
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
|
||||
CoglXlibRenderer *xlib_renderer =
|
||||
_cogl_xlib_renderer_get_data (display->renderer);
|
||||
|
||||
GLXDrawable drawable =
|
||||
glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin;
|
||||
int i;
|
||||
|
||||
ensure_ust_type (display->renderer, drawable);
|
||||
|
||||
if ((pipe (glx_onscreen->swap_wait_pipe) == -1))
|
||||
g_error ("Couldn't create pipe for swap notification: %s\n",
|
||||
g_strerror (errno));
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (fcntl(glx_onscreen->swap_wait_pipe[i], F_SETFD,
|
||||
fcntl(glx_onscreen->swap_wait_pipe[i], F_GETFD, 0) | FD_CLOEXEC) == -1)
|
||||
g_error ("Couldn't set swap notification pipe CLOEXEC: %s\n",
|
||||
g_strerror (errno));
|
||||
}
|
||||
|
||||
_cogl_poll_renderer_add_fd (display->renderer,
|
||||
glx_onscreen->swap_wait_pipe[0],
|
||||
COGL_POLL_FD_EVENT_IN,
|
||||
threaded_swap_wait_pipe_prepare,
|
||||
threaded_swap_wait_pipe_dispatch,
|
||||
onscreen);
|
||||
|
||||
glx_onscreen->swap_wait_queue = g_queue_new ();
|
||||
g_mutex_init (&glx_onscreen->swap_wait_mutex);
|
||||
g_cond_init (&glx_onscreen->swap_wait_cond);
|
||||
glx_onscreen->swap_wait_context =
|
||||
glx_renderer->glXCreateNewContext (xlib_renderer->xdpy,
|
||||
glx_display->fbconfig,
|
||||
GLX_RGBA_TYPE,
|
||||
glx_display->glx_context,
|
||||
True);
|
||||
glx_onscreen->swap_wait_thread = g_thread_new ("cogl_glx_swap_wait",
|
||||
threaded_swap_wait,
|
||||
onscreen);
|
||||
}
|
||||
|
||||
g_mutex_lock (&glx_onscreen->swap_wait_mutex);
|
||||
g_queue_push_head (glx_onscreen->swap_wait_queue, GUINT_TO_POINTER(vblank_counter));
|
||||
g_cond_signal (&glx_onscreen->swap_wait_cond);
|
||||
g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
const int *user_rectangles,
|
||||
@ -1759,6 +2021,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
CoglXlibRenderer *xlib_renderer =
|
||||
_cogl_xlib_renderer_get_data (context->display->renderer);
|
||||
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
|
||||
CoglGLXDisplay *glx_display = context->display->winsys;
|
||||
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
|
||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
||||
GLXDrawable drawable =
|
||||
@ -1815,9 +2078,8 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
|
||||
if (framebuffer->config.swap_throttled)
|
||||
{
|
||||
have_counter =
|
||||
_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_COUNTER);
|
||||
can_wait = _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT);
|
||||
have_counter = glx_display->have_vblank_counter;
|
||||
can_wait = glx_display->can_vblank_wait;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1974,6 +2236,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
CoglXlibRenderer *xlib_renderer =
|
||||
_cogl_xlib_renderer_get_data (context->display->renderer);
|
||||
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
|
||||
CoglGLXDisplay *glx_display = context->display->winsys;
|
||||
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
|
||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
||||
CoglBool have_counter;
|
||||
@ -1991,21 +2254,38 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
|
||||
if (framebuffer->config.swap_throttled)
|
||||
{
|
||||
uint32_t end_frame_vsync_counter = 0;
|
||||
have_counter = glx_display->have_vblank_counter;
|
||||
|
||||
have_counter =
|
||||
_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_COUNTER);
|
||||
|
||||
/* If the swap_region API is also being used then we need to track
|
||||
* the vsync counter for each swap request so we can manually
|
||||
* throttle swap_region requests. */
|
||||
if (have_counter)
|
||||
end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context);
|
||||
|
||||
if (!glx_renderer->glXSwapInterval)
|
||||
if (glx_renderer->glXSwapInterval)
|
||||
{
|
||||
CoglBool can_wait =
|
||||
_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT);
|
||||
if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT))
|
||||
{
|
||||
/* If we didn't wait for the GPU here, then it's easy to get the case
|
||||
* where there is a VBlank between the point where we get the vsync counter
|
||||
* and the point where the GPU is ready to actually perform the glXSwapBuffers(),
|
||||
* and the swap wait terminates at the first VBlank rather than the one
|
||||
* where the swap buffers happens. Calling glFinish() here makes this a
|
||||
* rare race since the GPU is already ready to swap when we call glXSwapBuffers().
|
||||
* The glFinish() also prevents any serious damage if the rare race happens,
|
||||
* since it will wait for the preceding glXSwapBuffers() and prevent us from
|
||||
* getting premanently ahead. (For NVIDIA drivers, glFinish() after glXSwapBuffers()
|
||||
* waits for the buffer swap to happen.)
|
||||
*/
|
||||
_cogl_winsys_wait_for_gpu (onscreen);
|
||||
start_threaded_swap_wait (onscreen, _cogl_winsys_get_vsync_counter (context));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CoglBool can_wait = have_counter || glx_display->can_vblank_wait;
|
||||
|
||||
uint32_t end_frame_vsync_counter = 0;
|
||||
|
||||
/* If the swap_region API is also being used then we need to track
|
||||
* the vsync counter for each swap request so we can manually
|
||||
* throttle swap_region requests. */
|
||||
if (have_counter)
|
||||
end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context);
|
||||
|
||||
/* If we are going to wait for VBLANK manually, we not only
|
||||
* need to flush out pending drawing to the GPU before we
|
||||
|
58
configure.ac
58
configure.ac
@ -1,15 +1,15 @@
|
||||
AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [23])
|
||||
m4_define([mutter_micro_version], [90])
|
||||
m4_define([mutter_minor_version], [27])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
|
||||
m4_define([mutter_plugin_api_version], [3])
|
||||
|
||||
m4_define([libmutter_api_version], [0])
|
||||
m4_define([libmutter_api_version], [1])
|
||||
|
||||
AC_INIT([mutter], [mutter_version],
|
||||
[http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
|
||||
@ -57,6 +57,13 @@ AM_GNU_GETTEXT([external])
|
||||
|
||||
LT_PREREQ([2.2.6])
|
||||
LT_INIT([disable-static])
|
||||
|
||||
# Debian / Ubuntu set this flag to 'no' in libtool, causing linking errors
|
||||
# (i.e when linking against mutter-clutter). Not to explicitly redefine such
|
||||
# deps, we enable this flag for everybody.
|
||||
link_all_deplibs=yes
|
||||
link_all_deplibs_CXX=yes
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_C_O
|
||||
AC_PROG_INSTALL
|
||||
@ -65,7 +72,7 @@ AC_HEADER_STDC
|
||||
PKG_PROG_PKG_CONFIG([0.21])
|
||||
|
||||
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
|
||||
AM_PATH_GLIB_2_0([2.49.0])
|
||||
AM_PATH_GLIB_2_0([2.53.2])
|
||||
|
||||
CANBERRA_GTK=libcanberra-gtk3
|
||||
CANBERRA_GTK_VERSION=0.26
|
||||
@ -73,6 +80,7 @@ CANBERRA_GTK_VERSION=0.26
|
||||
LIBWACOM_VERSION=0.13
|
||||
|
||||
MUTTER_PC_MODULES="
|
||||
gl
|
||||
egl
|
||||
gtk+-3.0 >= 3.19.8
|
||||
gio-unix-2.0 >= 2.35.1
|
||||
@ -97,6 +105,7 @@ MUTTER_PC_MODULES="
|
||||
xcb-randr
|
||||
xcb-res
|
||||
"
|
||||
XWAYLAND_GRAB_DEFAULT_ACCESS_RULES="gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr"
|
||||
|
||||
GLIB_GSETTINGS
|
||||
|
||||
@ -218,10 +227,10 @@ AC_MSG_CHECKING([gudev])
|
||||
if test x$with_gudev = xno ; then
|
||||
AC_MSG_RESULT([disabled])
|
||||
else
|
||||
if $PKG_CONFIG --exists gudev-1.0; then
|
||||
if $PKG_CONFIG --exists "gudev-1.0 >= 232"; then
|
||||
have_gudev=yes
|
||||
AC_MSG_RESULT(yes)
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gudev-1.0"
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gudev-1.0 >= 232"
|
||||
AC_DEFINE([HAVE_LIBGUDEV], 1, [Building with gudev for device type detection])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
@ -231,6 +240,20 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(remote-desktop,
|
||||
AS_HELP_STRING([--enable-remote-desktop], [enable support for remote desktop and screen cast]),,
|
||||
enable_remote_desktop=no
|
||||
)
|
||||
AS_IF([test "$enable_remote_desktop" = "yes"], [
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES libpipewire-0.1 >= 0.1.4"
|
||||
PKG_CHECK_EXISTS([libpipewire-0.1], [
|
||||
pw_micro=`$PKG_CONFIG --modversion libpipewire-0.1 | cut -d. -f3`
|
||||
AC_DEFINE_UNQUOTED([PIPEWIRE_VERSION_MICRO],[$pw_micro], [Pipewire micro version used])
|
||||
])
|
||||
AC_DEFINE([HAVE_REMOTE_DESKTOP],[1], [Defined if screen cast and remote desktop support is enabled])
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_REMOTE_DESKTOP],[test "$enable_remote_desktop" = "yes"])
|
||||
|
||||
INTROSPECTION_VERSION=0.9.5
|
||||
GOBJECT_INTROSPECTION_CHECK([$INTROSPECTION_VERSION])
|
||||
|
||||
@ -260,15 +283,14 @@ AS_IF([test "$have_native_backend" = "yes"], [
|
||||
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test "$have_native_backend" = "yes"])
|
||||
|
||||
AC_ARG_ENABLE(egl-device,
|
||||
AS_HELP_STRING([--enable-egl-device], [enable support for EGLDevice on top of KMS]),
|
||||
enable_egl_device=yes,
|
||||
AS_HELP_STRING([--enable-egl-device], [enable support for EGLDevice on top of KMS]),,
|
||||
enable_egl_device=no
|
||||
)
|
||||
AS_IF([test "$enable_egl_device" = "yes"], [
|
||||
AC_DEFINE([HAVE_EGL_DEVICE],[1], [Defined if EGLDevice support is enabled])
|
||||
])
|
||||
|
||||
MUTTER_WAYLAND_MODULES="wayland-server >= 1.6.90"
|
||||
MUTTER_WAYLAND_MODULES="wayland-server >= 1.13.0"
|
||||
|
||||
AC_ARG_ENABLE(wayland,
|
||||
AS_HELP_STRING([--disable-wayland], [disable mutter on wayland support]),,
|
||||
@ -285,12 +307,27 @@ AS_IF([test "$have_wayland" = "yes"], [
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
|
||||
|
||||
PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.7],
|
||||
PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.10],
|
||||
[ac_wayland_protocols_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`])
|
||||
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $ac_wayland_protocols_pkgdatadir)
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_WAYLAND],[test "$have_wayland" = "yes"])
|
||||
|
||||
AC_ARG_WITH([xwayland-grab-default-access-rules],
|
||||
[AS_HELP_STRING([--with-xwayland-grab-default-access-rules="app-res1,app-res2,..."],
|
||||
[comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland"])],
|
||||
[with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES="$withval"],
|
||||
[with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES="$XWAYLAND_GRAB_DEFAULT_ACCESS_RULES"])
|
||||
|
||||
case "$with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES" in
|
||||
yes) with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES="$XWAYLAND_GRAB_DEFAULT_ACCESS_RULES" ;;
|
||||
no) with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES='' ;;
|
||||
esac
|
||||
AC_DEFINE_UNQUOTED([XWAYLAND_GRAB_DEFAULT_ACCESS_RULES],
|
||||
"$with_XWAYLAND_GRAB_DEFAULT_ACCESS_RULES",
|
||||
[Xwayland applications allowed to issue keyboard grabs])
|
||||
AC_SUBST(XWAYLAND_GRAB_DEFAULT_ACCESS_RULES)
|
||||
|
||||
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
|
||||
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
|
||||
|
||||
@ -506,6 +543,7 @@ mutter-$VERSION
|
||||
Wayland: ${have_wayland}
|
||||
Native (KMS) backend: ${have_native_backend}
|
||||
EGLDevice: ${enable_egl_device}
|
||||
Remote desktop: ${enable_remote_desktop}
|
||||
"
|
||||
|
||||
|
||||
|
10
data/50-mutter-wayland.xml
Normal file
10
data/50-mutter-wayland.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<KeyListEntries schema="org.gnome.mutter.wayland.keybindings"
|
||||
group="system"
|
||||
name="System"
|
||||
wm_name="Mutter"
|
||||
package="mutter">
|
||||
|
||||
<KeyListEntry name="restore-shortcuts" description="Restore the keyboard shortcuts"/>
|
||||
|
||||
</KeyListEntries>
|
@ -12,13 +12,19 @@ xml_DATA = \
|
||||
50-mutter-system.xml \
|
||||
50-mutter-windows.xml
|
||||
|
||||
if HAVE_WAYLAND
|
||||
xml_DATA += \
|
||||
50-mutter-wayland.xml
|
||||
endif
|
||||
|
||||
gschema_in_files = \
|
||||
org.gnome.mutter.gschema.xml.in \
|
||||
org.gnome.mutter.wayland.gschema.xml.in
|
||||
gsettings_SCHEMAS = $(gschema_in_files:.xml.in=.xml)
|
||||
|
||||
%.gschema.xml: %.gschema.xml.in Makefile
|
||||
$(AM_V_GEN) sed -e 's|@GETTEXT_DOMAIN[@]|$(GETTEXT_DOMAIN)|g' \
|
||||
$(AM_V_GEN) sed -e 's|@GETTEXT_DOMAIN[@]|$(GETTEXT_PACKAGE)|g' \
|
||||
-e 's|@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES[@]|$(XWAYLAND_GRAB_DEFAULT_ACCESS_RULES)|g' \
|
||||
$< > $@ || rm $@
|
||||
|
||||
@GSETTINGS_RULES@
|
||||
|
@ -1,16 +1,16 @@
|
||||
<schemalist>
|
||||
<schema id="org.gnome.mutter" path="/org/gnome/mutter/"
|
||||
gettext-domain="@GETTEXT_DOMAIN">
|
||||
gettext-domain="@GETTEXT_DOMAIN@">
|
||||
|
||||
<key name="overlay-key" type="s">
|
||||
<default>'Super_L'</default>
|
||||
<summary>Modifier to use for extended window management operations</summary>
|
||||
<description>
|
||||
This key will initiate the "overlay", which is a combination window
|
||||
This key will initiate the “overlay”, which is a combination window
|
||||
overview and application launching system. The default is intended
|
||||
to be the "Windows key" on PC hardware.
|
||||
to be the “Windows key” on PC hardware.
|
||||
|
||||
It's expected that this binding either the default or set to
|
||||
It’s expected that this binding either the default or set to
|
||||
the empty string.
|
||||
</description>
|
||||
</key>
|
||||
@ -40,7 +40,7 @@
|
||||
<summary>Workspaces are managed dynamically</summary>
|
||||
<description>
|
||||
Determines whether workspaces are managed dynamically or
|
||||
whether there's a static number of workspaces (determined
|
||||
whether there’s a static number of workspaces (determined
|
||||
by the num-workspaces key in org.gnome.desktop.wm.preferences).
|
||||
</description>
|
||||
</key>
|
||||
@ -67,7 +67,7 @@
|
||||
<default>false</default>
|
||||
<summary>Delay focus changes until the pointer stops moving</summary>
|
||||
<description>
|
||||
If set to true, and the focus mode is either "sloppy" or "mouse"
|
||||
If set to true, and the focus mode is either “sloppy” or “mouse”
|
||||
then the focus will not be changed immediately when entering a
|
||||
window, but only after the pointer stops moving.
|
||||
</description>
|
||||
@ -78,7 +78,7 @@
|
||||
<range min="0" max="64"/>
|
||||
<summary>Draggable border width</summary>
|
||||
<description>
|
||||
The amount of total draggable borders. If the theme's visible
|
||||
The amount of total draggable borders. If the theme’s visible
|
||||
borders are not enough, invisible borders will be added to meet
|
||||
this value.
|
||||
</description>
|
||||
@ -102,6 +102,31 @@
|
||||
</description>
|
||||
</key>
|
||||
|
||||
<key name="experimental-features" type="as">
|
||||
<default>[]</default>
|
||||
<summary>Enable experimental features</summary>
|
||||
<description>
|
||||
To enable experimental features, add the feature keyword to the list.
|
||||
Whether the feature requires restarting the compositor depends on the
|
||||
given feature. Any experimental feature is not required to still be
|
||||
available, or configurable. Don’t expect adding anything in this
|
||||
setting to be future proof.
|
||||
|
||||
Currently possible keywords:
|
||||
|
||||
• “scale-monitor-framebuffer” — makes mutter default to layout logical
|
||||
monitors in a logical pixel coordinate
|
||||
space, while scaling monitor
|
||||
framebuffers instead of window content,
|
||||
to manage HiDPI monitors. Does not
|
||||
require a restart.
|
||||
• “remote-desktop” — enables remote desktop support. To support
|
||||
remote desktop with screen sharing,
|
||||
“screen-cast” must also be enabled.
|
||||
• “screen-cast” — enables screen cast support.
|
||||
</description>
|
||||
</key>
|
||||
|
||||
<child name="keybindings" schema="org.gnome.mutter.keybindings"/>
|
||||
|
||||
</schema>
|
||||
@ -125,5 +150,15 @@
|
||||
<summary>Cancel tab popup</summary>
|
||||
</key>
|
||||
|
||||
<key name="switch-monitor" type="as">
|
||||
<default><![CDATA[['<Super>p','XF86Display']]]></default>
|
||||
<summary>Switch monitor configurations</summary>
|
||||
</key>
|
||||
|
||||
<key name="rotate-monitor" type="as">
|
||||
<default><![CDATA[['XF86RotateWindows']]]></default>
|
||||
<summary>Rotates the built-in monitor configuration</summary>
|
||||
</key>
|
||||
|
||||
</schema>
|
||||
</schemalist>
|
||||
|
@ -49,5 +49,53 @@
|
||||
<default><![CDATA[['<Primary><Alt>F12']]]></default>
|
||||
<summary>Switch to VT 12</summary>
|
||||
</key>
|
||||
<key name="restore-shortcuts" type="as">
|
||||
<default><![CDATA[['<Super>Escape']]]></default>
|
||||
<summary>Re-enable shortcuts</summary>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
|
||||
<schema id="org.gnome.mutter.wayland" path="/org/gnome/mutter/wayland/"
|
||||
gettext-domain="@GETTEXT_DOMAIN@">
|
||||
|
||||
<key name="xwayland-allow-grabs" type="b">
|
||||
<default>false</default>
|
||||
<summary>Allow grabs with Xwayland</summary>
|
||||
<description>
|
||||
Allow keyboard grabs issued by X11 applications running in Xwayland
|
||||
to be taken into account.
|
||||
|
||||
For a X11 grab to be taken into account under Wayland, the client must
|
||||
also either send a specific X11 ClientMessage to the root window or be
|
||||
among the applications white-listed in key “xwayland-grab-access-rules”.
|
||||
</description>
|
||||
</key>
|
||||
|
||||
<key name="xwayland-grab-access-rules" type="as">
|
||||
<default>[]</default>
|
||||
<summary>Xwayland applications allowed to issue keyboard grabs</summary>
|
||||
<description>
|
||||
List the resource names or resource class of X11 windows either
|
||||
allowed or not allowed to issue X11 keyboard grabs under Xwayland.
|
||||
|
||||
The resource name or resource class of a given X11 window can be
|
||||
obtained using the command “xprop WM_CLASS”.
|
||||
|
||||
Wildcards “*” and jokers “?” in the values are supported.
|
||||
|
||||
Values starting with “!” are blacklisted, which has precedence over
|
||||
the whitelist, to revoke applications from the default system list.
|
||||
|
||||
The default system list includes the following applications:
|
||||
|
||||
“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@”
|
||||
|
||||
Users can break an existing grab by using the specific keyboard
|
||||
shortcut defined by the keybinding key “restore-shortcuts”.
|
||||
</description>
|
||||
</key>
|
||||
|
||||
</schema>
|
||||
|
||||
</schemalist>
|
||||
|
@ -2,6 +2,7 @@
|
||||
# Please keep this file sorted alphabetically.
|
||||
data/50-mutter-navigation.xml
|
||||
data/50-mutter-system.xml
|
||||
data/50-mutter-wayland.xml
|
||||
data/50-mutter-windows.xml
|
||||
data/mutter.desktop.in
|
||||
data/org.gnome.mutter.gschema.xml.in
|
||||
@ -12,11 +13,11 @@ src/compositor/compositor.c
|
||||
src/compositor/meta-background.c
|
||||
src/core/bell.c
|
||||
src/core/core.c
|
||||
src/core/delete.c
|
||||
src/core/display.c
|
||||
src/core/errors.c
|
||||
src/core/keybindings.c
|
||||
src/core/main.c
|
||||
src/core/meta-close-dialog-default.c
|
||||
src/core/mutter.c
|
||||
src/core/prefs.c
|
||||
src/core/screen.c
|
||||
|
822
po/ar.po
822
po/ar.po
@ -4,14 +4,15 @@
|
||||
# Arafat Medini <lumina@silverpen.de>, 2003.
|
||||
# Abdulaziz Al-Arfaj <alarfaj0@yahoo.com>, 2004.
|
||||
# Djihed Afifi <djihed@gmail.com>, 2006.
|
||||
# Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015.
|
||||
# Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017.
|
||||
# Anas Afif Emad <anas.e87@gmail.com>, 2008.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: metacity.HEAD\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-03-23 21:38+0200\n"
|
||||
"PO-Revision-Date: 2015-03-23 21:45+0200\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&"
|
||||
"keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2017-11-03 10:20+0200\n"
|
||||
"PO-Revision-Date: 2017-11-03 10:22+0200\n"
|
||||
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
|
||||
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
||||
"Language: ar\n"
|
||||
@ -20,524 +21,130 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
|
||||
"X-Generator: Virtaal 0.7.1\n"
|
||||
"X-Generator: Virtaal 1.0.0-beta1\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:1
|
||||
msgid "Navigation"
|
||||
msgstr "الإبحار"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:2
|
||||
msgid "Move window to workspace 1"
|
||||
msgstr "انقل النافذة إلى مساحة العمل 1"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:3
|
||||
msgid "Move window to workspace 2"
|
||||
msgstr "انقل النافذة إلى مساحة العمل 2"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:4
|
||||
msgid "Move window to workspace 3"
|
||||
msgstr "انقل النافذة إلى مساحة العمل 3"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:5
|
||||
msgid "Move window to workspace 4"
|
||||
msgstr "انقل النافذة إلى مساحة العمل 4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:6
|
||||
msgid "Move window to last workspace"
|
||||
msgstr "انقل النافذة إلى مساحة العمل الأخيرة"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:7
|
||||
msgid "Move window one workspace to the left"
|
||||
msgstr "انقل النافذة مساحة عمل واحدة إلى اليسار"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:8
|
||||
msgid "Move window one workspace to the right"
|
||||
msgstr "انقل النافذة مساحة عمل واحدة إلى اليمين"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:9
|
||||
msgid "Move window one workspace up"
|
||||
msgstr "انقل النافذة مساحة عمل واحدة إلى الأعلى"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:10
|
||||
msgid "Move window one workspace down"
|
||||
msgstr "انقل النافذة مساحة عمل واحدة إلى الأسفل"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:11
|
||||
msgid "Move window one monitor to the left"
|
||||
msgstr "انقل النافذة شاشة واحدة إلى اليسار"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:12
|
||||
msgid "Move window one monitor to the right"
|
||||
msgstr "انقل النافذة شاشة واحدة إلى اليمين"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:13
|
||||
msgid "Move window one monitor up"
|
||||
msgstr "انقل النافذة شاشة واحدة إلى الأعلى"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:14
|
||||
msgid "Move window one monitor down"
|
||||
msgstr "انقل النافذة شاشة واحدة إلى الأسفل"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:15
|
||||
msgid "Switch applications"
|
||||
msgstr "تنقل بين التطبيقات"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:16
|
||||
msgid "Switch to previous application"
|
||||
msgstr "انتقل إلى التطبيق السابق"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:17
|
||||
msgid "Switch windows"
|
||||
msgstr "تنقل بين النوافذ"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:18
|
||||
msgid "Switch to previous window"
|
||||
msgstr "انتقل إلى النافذة السابقة"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:19
|
||||
msgid "Switch windows of an application"
|
||||
msgstr "تنقل بين نوافذ التطبيق"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:20
|
||||
msgid "Switch to previous window of an application"
|
||||
msgstr "انتقل إلى نافذة التطبيق السابقة"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:21
|
||||
msgid "Switch system controls"
|
||||
msgstr "تنقل بين تحكمات النظام"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:22
|
||||
msgid "Switch to previous system control"
|
||||
msgstr "انتقل إلى تحكم النظام السابق"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:23
|
||||
msgid "Switch windows directly"
|
||||
msgstr "تنقل مباشرة بين النوافذ"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:24
|
||||
msgid "Switch directly to previous window"
|
||||
msgstr "انتقل مباشرة إلى النافذة السابقة"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:25
|
||||
msgid "Switch windows of an app directly"
|
||||
msgstr "تنقل مباشرة بين نوافذ التطبيق"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:26
|
||||
msgid "Switch directly to previous window of an app"
|
||||
msgstr "انتقل مباشرة إلى نافذة التطبيق السابقة"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:27
|
||||
msgid "Switch system controls directly"
|
||||
msgstr "تنقل مباشرة بين تحكمات النظام"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:28
|
||||
msgid "Switch directly to previous system control"
|
||||
msgstr "انتقل مباشرة إلى تحكم النظام السابق"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:29
|
||||
msgid "Hide all normal windows"
|
||||
msgstr "أخفِ كل النوافذ العادية"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:30
|
||||
msgid "Switch to workspace 1"
|
||||
msgstr "انتقل إلى مساحة العمل 1"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:31
|
||||
msgid "Switch to workspace 2"
|
||||
msgstr "انتقل إلى مساحة العمل 2"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:32
|
||||
msgid "Switch to workspace 3"
|
||||
msgstr "انتقل إلى مساحة العمل 3"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:33
|
||||
msgid "Switch to workspace 4"
|
||||
msgstr "انتقل إلى مساحة العمل 4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:34
|
||||
msgid "Switch to last workspace"
|
||||
msgstr "انتقل إلى مساحة العمل الأخيرة"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:35
|
||||
msgid "Move to workspace left"
|
||||
msgstr "انقل لمساحة العمل على اليسار"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:36
|
||||
msgid "Move to workspace right"
|
||||
msgstr "انقل لمساحة العمل على اليمين"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:37
|
||||
msgid "Move to workspace above"
|
||||
msgstr "انقل لمساحة العمل أعلى"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:38
|
||||
msgid "Move to workspace below"
|
||||
msgstr "انقل لمساحة العمل أسفل"
|
||||
|
||||
#: ../data/50-mutter-system.xml.in.h:1
|
||||
msgid "System"
|
||||
msgstr "النظام"
|
||||
|
||||
#: ../data/50-mutter-system.xml.in.h:2
|
||||
msgid "Show the run command prompt"
|
||||
msgstr "أظهر محث تشغيل أمر"
|
||||
|
||||
#: ../data/50-mutter-system.xml.in.h:3
|
||||
msgid "Show the activities overview"
|
||||
msgstr "أظهر نظرة عامة على الأنشطة"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:1
|
||||
msgid "Windows"
|
||||
msgstr "النوافذ"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:2
|
||||
msgid "Activate the window menu"
|
||||
msgstr "فعّل قائمة النافذة"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:3
|
||||
msgid "Toggle fullscreen mode"
|
||||
msgstr "بدّل نمط ملء الشاشة"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:4
|
||||
msgid "Toggle maximization state"
|
||||
msgstr "بدّل حالة التكبير"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:5
|
||||
msgid "Maximize window"
|
||||
msgstr "كبّر النّافذة"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:6
|
||||
msgid "Restore window"
|
||||
msgstr "استعد النّافذة"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:7
|
||||
msgid "Toggle shaded state"
|
||||
msgstr "بدّل حالة الإخفاء"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:8
|
||||
msgid "Close window"
|
||||
msgstr "أغلق النّافذة"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:9
|
||||
msgid "Hide window"
|
||||
msgstr "أخفِ النّافذة"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:10
|
||||
msgid "Move window"
|
||||
msgstr "انقل النّافذة"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:11
|
||||
msgid "Resize window"
|
||||
msgstr "حجّم النّافذة"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:12
|
||||
msgid "Toggle window on all workspaces or one"
|
||||
msgstr "بدّل حالة ظهور النافذة على جميع مساحات العمل أو واحدة منها"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:13
|
||||
msgid "Raise window if covered, otherwise lower it"
|
||||
msgstr "ارفع النافذة إذا كانت أخرى تغطيها، أو أخفضها في ما عدا ذلك"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:14
|
||||
msgid "Raise window above other windows"
|
||||
msgstr "ارفع النافذة فوق النوافذ الأخرى"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:15
|
||||
msgid "Lower window below other windows"
|
||||
msgstr "اخفض النافذة تحت النوافذ الأخرى"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:16
|
||||
msgid "Maximize window vertically"
|
||||
msgstr "كبّر النافذة رأسيا"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:17
|
||||
msgid "Maximize window horizontally"
|
||||
msgstr "كبّر النافذة أفقيا"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:18
|
||||
msgid "View split on left"
|
||||
msgstr "المنظور مقسوم على اليمين"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:19
|
||||
msgid "View split on right"
|
||||
msgstr "المنظور مقسوم على اليسار"
|
||||
|
||||
#: ../data/mutter.desktop.in.h:1
|
||||
msgid "Mutter"
|
||||
msgstr "مَتَر"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:1
|
||||
msgid "Modifier to use for extended window management operations"
|
||||
msgstr "المغير الذي سيُستعمل لتمديد عمليات إدارة النوافذ "
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:2
|
||||
msgid ""
|
||||
"This key will initiate the \"overlay\", which is a combination window "
|
||||
"overview and application launching system. The default is intended to be the "
|
||||
"\"Windows key\" on PC hardware. It's expected that this binding either the "
|
||||
"default or set to the empty string."
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: ../src/backends/meta-input-settings.c:2167
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
|
||||
msgid "Attach modal dialogs"
|
||||
msgstr ""
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: ../src/backends/meta-input-settings.c:2190
|
||||
msgid "Switch monitor"
|
||||
msgstr "غيّر الشاشة"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:4
|
||||
msgid ""
|
||||
"When true, instead of having independent titlebars, modal dialogs appear "
|
||||
"attached to the titlebar of the parent window and are moved together with "
|
||||
"the parent window."
|
||||
msgstr ""
|
||||
#: ../src/backends/meta-input-settings.c:2192
|
||||
msgid "Show on-screen help"
|
||||
msgstr "اعرض المساعدة على الشاشة"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
|
||||
msgid "Enable edge tiling when dropping windows on screen edges"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:6
|
||||
msgid ""
|
||||
"If enabled, dropping windows on vertical screen edges maximizes them "
|
||||
"vertically and resizes them horizontally to cover half of the available "
|
||||
"area. Dropping windows on the top screen edge maximizes them completely."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:7
|
||||
msgid "Workspaces are managed dynamically"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:8
|
||||
msgid ""
|
||||
"Determines whether workspaces are managed dynamically or whether there's a "
|
||||
"static number of workspaces (determined by the num-workspaces key in org."
|
||||
"gnome.desktop.wm.preferences)."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
|
||||
msgid "Workspaces only on primary"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:10
|
||||
msgid ""
|
||||
"Determines whether workspace switching should happen for windows on all "
|
||||
"monitors or only for windows on the primary monitor."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:11
|
||||
msgid "No tab popup"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:12
|
||||
msgid ""
|
||||
"Determines whether the use of popup and highlight frame should be disabled "
|
||||
"for window cycling."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:13
|
||||
msgid "Delay focus changes until the pointer stops moving"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:14
|
||||
msgid ""
|
||||
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
|
||||
"the focus will not be changed immediately when entering a window, but only "
|
||||
"after the pointer stops moving."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
|
||||
msgid "Draggable border width"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:16
|
||||
msgid ""
|
||||
"The amount of total draggable borders. If the theme's visible borders are "
|
||||
"not enough, invisible borders will be added to meet this value."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:17
|
||||
msgid "Auto maximize nearly monitor sized windows"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:18
|
||||
msgid ""
|
||||
"If enabled, new windows that are initially the size of the monitor "
|
||||
"automatically get maximized."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:19
|
||||
msgid "Place new windows in the center"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:20
|
||||
msgid ""
|
||||
"When true, the new windows will always be put in the center of the active "
|
||||
"screen of the monitor."
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
|
||||
msgid "Select window from tab popup"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:22
|
||||
msgid "Cancel tab popup"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 1"
|
||||
msgstr "انتقل إلى مساحة العمل 1"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 2"
|
||||
msgstr "انتقل إلى مساحة العمل 2"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 3"
|
||||
msgstr "انتقل إلى مساحة العمل 3"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 4"
|
||||
msgstr "انتقل إلى مساحة العمل 4"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 5"
|
||||
msgstr "انتقل إلى مساحة العمل 5"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 6"
|
||||
msgstr "انتقل إلى مساحة العمل 6"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "انتقل إلى مساحة العمل 7"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 8"
|
||||
msgstr "انتقل إلى مساحة العمل 8"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 9"
|
||||
msgstr "انتقل إلى مساحة العمل 9"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 10"
|
||||
msgstr "انتقل إلى مساحة العمل 10"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 11"
|
||||
msgstr "انتقل إلى مساحة العمل 11"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
|
||||
#, fuzzy
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "انتقل إلى مساحة العمل 12"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
#: ../src/backends/meta-monitor-manager.c:900
|
||||
msgid "Built-in display"
|
||||
msgstr "شاشة مدمجة"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
#: ../src/backends/meta-monitor-manager.c:923
|
||||
msgid "Unknown"
|
||||
msgstr "غير معروفة"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
#: ../src/backends/meta-monitor-manager.c:925
|
||||
msgid "Unknown Display"
|
||||
msgstr "شاشة غير معروفة"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:401
|
||||
#: ../src/backends/meta-monitor-manager.c:933
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:456
|
||||
#: ../src/compositor/compositor.c:476
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
msgstr "يعمل مدير مزج آخر على الشاشة %i والعرض \"%s\"."
|
||||
"Another compositing manager is already running on screen %i on display “%s”."
|
||||
msgstr "يعمل مدير مزج آخر على الشاشة %i و العرض ”%s“."
|
||||
|
||||
#: ../src/core/bell.c:185
|
||||
#: ../src/core/bell.c:194
|
||||
msgid "Bell event"
|
||||
msgstr "حدث جرس"
|
||||
|
||||
#: ../src/core/delete.c:127
|
||||
#: ../src/core/display.c:608
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr "فشل فتح عرض نظام نوافذ إكس ”%s“\n"
|
||||
|
||||
#: ../src/core/main.c:189
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "عطّل الاتصال بمدير الجلسة"
|
||||
|
||||
#: ../src/core/main.c:195
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "استبدل بمدير النوافذ الذي يعمل"
|
||||
|
||||
#: ../src/core/main.c:201
|
||||
msgid "Specify session management ID"
|
||||
msgstr "حدّد رقم هويّة إدارة الجلسة"
|
||||
|
||||
#: ../src/core/main.c:206
|
||||
msgid "X Display to use"
|
||||
msgstr "معراض س الذي سيستعمل"
|
||||
|
||||
#: ../src/core/main.c:212
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "ابدأ الجلسة من ملف محفوظ"
|
||||
|
||||
#: ../src/core/main.c:218
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "اجعل نداءات س متزامنة"
|
||||
|
||||
#: ../src/core/main.c:225
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/core/main.c:231
|
||||
msgid "Run as a nested compositor"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/core/main.c:239
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: %s is a window title
|
||||
#: ../src/core/meta-close-dialog-default.c:147
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "”%s“ لا يستجيب."
|
||||
|
||||
#: ../src/core/delete.c:129
|
||||
#: ../src/core/meta-close-dialog-default.c:149
|
||||
msgid "Application is not responding."
|
||||
msgstr "لا يستجيب التطبيق"
|
||||
|
||||
#: ../src/core/delete.c:134
|
||||
#: ../src/core/meta-close-dialog-default.c:154
|
||||
msgid ""
|
||||
"You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely."
|
||||
msgstr "ربما ترغب في الانتظار قليلا ليُكمِل أو إجبار التطبيق على الإنهاء كُلّية."
|
||||
|
||||
#: ../src/core/delete.c:141
|
||||
msgid "_Wait"
|
||||
msgstr "ا_نتظر"
|
||||
|
||||
#: ../src/core/delete.c:141
|
||||
#: ../src/core/meta-close-dialog-default.c:161
|
||||
msgid "_Force Quit"
|
||||
msgstr "أ_جبر الإنهاء"
|
||||
|
||||
#: ../src/core/display.c:562
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "فشل فتح عرض نظام نوافذ إكس '%s'\n"
|
||||
|
||||
#: ../src/core/main.c:176
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "عطّل الاتصال بمدير الجلسة"
|
||||
|
||||
#: ../src/core/main.c:182
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "استبدل بمدير النوافذ الذي يعمل"
|
||||
|
||||
#: ../src/core/main.c:188
|
||||
msgid "Specify session management ID"
|
||||
msgstr "حدّد رقم هويّة إدارة الجلسة"
|
||||
|
||||
#: ../src/core/main.c:193
|
||||
msgid "X Display to use"
|
||||
msgstr "معراض س الذي سيستعمل"
|
||||
|
||||
#: ../src/core/main.c:199
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "ابدأ الجلسة من ملف محفوظ"
|
||||
|
||||
#: ../src/core/main.c:205
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "اجعل نداءات س متزامنة"
|
||||
|
||||
#: ../src/core/main.c:212
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/core/main.c:220
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr ""
|
||||
#: ../src/core/meta-close-dialog-default.c:161
|
||||
msgid "_Wait"
|
||||
msgstr "ا_نتظر"
|
||||
|
||||
#: ../src/core/mutter.c:39
|
||||
#, c-format
|
||||
msgid ""
|
||||
"mutter %s\n"
|
||||
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
|
||||
"Copyright © 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"
|
||||
@ -555,42 +162,281 @@ msgstr "اطبع الإصدارة"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "ملحق مَتَر الذي سيُستخدم"
|
||||
|
||||
#: ../src/core/prefs.c:2004
|
||||
#: ../src/core/prefs.c:1997
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "مساحة العمل %d"
|
||||
|
||||
#: ../src/core/screen.c:525
|
||||
#: ../src/core/screen.c:583
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
"Display “%s” already has a window manager; try using the --replace option to "
|
||||
"replace the current window manager."
|
||||
msgstr ""
|
||||
"الشاشة \"%s\" لها مدير نوافذ بالفعل، حاول استعمال خيار التبديل --replace "
|
||||
"لتحُلّ محلّ مدير النوافذ الحالي."
|
||||
"الشاشة ”%s“ لها مدير نوافذ بالفعل، حاول استعمال خيار التبديل --replace لتحُلّ"
|
||||
" محلّ مدير النوافذ الحالي."
|
||||
|
||||
#: ../src/core/screen.c:607
|
||||
#: ../src/core/screen.c:668
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "الشاشة %d على العرض '%s' غير صحيحة\n"
|
||||
msgid "Screen %d on display “%s” is invalid\n"
|
||||
msgstr "الشاشة %d على العرض ”%s“ غير صحيحة\n"
|
||||
|
||||
#: ../src/core/util.c:118
|
||||
#: ../src/core/util.c:120
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "جُمِّع مَتَر دون دعم للنمط المطنب\n"
|
||||
|
||||
#: ../src/wayland/meta-wayland-tablet-pad.c:563
|
||||
#, c-format
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/x11/session.c:1815
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
"These windows do not support “save current setup” and will have to be "
|
||||
"restarted manually next time you log in."
|
||||
msgstr ""
|
||||
"هذه النوافذ لا تدعم "احفظ الضبط الحالي" يجب إعادة تشغيلها يدويا "
|
||||
"عند الولوج المرة القادمة."
|
||||
"هذه النوافذ لا تدعم ” الضبط الحالي" إعادة تشغيلها يدويا عند الولوج "
|
||||
"المرة القادمة."
|
||||
|
||||
#: ../src/x11/window-props.c:549
|
||||
#: ../src/x11/window-props.c:559
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (على %s)"
|
||||
|
||||
#~ msgid "Navigation"
|
||||
#~ msgstr "الإبحار"
|
||||
|
||||
#~ msgid "Move window to workspace 1"
|
||||
#~ msgstr "انقل النافذة إلى مساحة العمل 1"
|
||||
|
||||
#~ msgid "Move window to workspace 2"
|
||||
#~ msgstr "انقل النافذة إلى مساحة العمل 2"
|
||||
|
||||
#~ msgid "Move window to workspace 3"
|
||||
#~ msgstr "انقل النافذة إلى مساحة العمل 3"
|
||||
|
||||
#~ msgid "Move window to workspace 4"
|
||||
#~ msgstr "انقل النافذة إلى مساحة العمل 4"
|
||||
|
||||
#~ msgid "Move window to last workspace"
|
||||
#~ msgstr "انقل النافذة إلى مساحة العمل الأخيرة"
|
||||
|
||||
#~ msgid "Move window one workspace to the left"
|
||||
#~ msgstr "انقل النافذة مساحة عمل واحدة إلى اليسار"
|
||||
|
||||
#~ msgid "Move window one workspace to the right"
|
||||
#~ msgstr "انقل النافذة مساحة عمل واحدة إلى اليمين"
|
||||
|
||||
#~ msgid "Move window one workspace up"
|
||||
#~ msgstr "انقل النافذة مساحة عمل واحدة إلى الأعلى"
|
||||
|
||||
#~ msgid "Move window one workspace down"
|
||||
#~ msgstr "انقل النافذة مساحة عمل واحدة إلى الأسفل"
|
||||
|
||||
#~ msgid "Move window one monitor to the left"
|
||||
#~ msgstr "انقل النافذة شاشة واحدة إلى اليسار"
|
||||
|
||||
#~ msgid "Move window one monitor to the right"
|
||||
#~ msgstr "انقل النافذة شاشة واحدة إلى اليمين"
|
||||
|
||||
#~ msgid "Move window one monitor up"
|
||||
#~ msgstr "انقل النافذة شاشة واحدة إلى الأعلى"
|
||||
|
||||
#~ msgid "Move window one monitor down"
|
||||
#~ msgstr "انقل النافذة شاشة واحدة إلى الأسفل"
|
||||
|
||||
#~ msgid "Switch applications"
|
||||
#~ msgstr "تنقل بين التطبيقات"
|
||||
|
||||
#~ msgid "Switch to previous application"
|
||||
#~ msgstr "انتقل إلى التطبيق السابق"
|
||||
|
||||
#~ msgid "Switch windows"
|
||||
#~ msgstr "تنقل بين النوافذ"
|
||||
|
||||
#~ msgid "Switch to previous window"
|
||||
#~ msgstr "انتقل إلى النافذة السابقة"
|
||||
|
||||
#~ msgid "Switch windows of an application"
|
||||
#~ msgstr "تنقل بين نوافذ التطبيق"
|
||||
|
||||
#~ msgid "Switch to previous window of an application"
|
||||
#~ msgstr "انتقل إلى نافذة التطبيق السابقة"
|
||||
|
||||
#~ msgid "Switch system controls"
|
||||
#~ msgstr "تنقل بين تحكمات النظام"
|
||||
|
||||
#~ msgid "Switch to previous system control"
|
||||
#~ msgstr "انتقل إلى تحكم النظام السابق"
|
||||
|
||||
#~ msgid "Switch windows directly"
|
||||
#~ msgstr "تنقل مباشرة بين النوافذ"
|
||||
|
||||
#~ msgid "Switch directly to previous window"
|
||||
#~ msgstr "انتقل مباشرة إلى النافذة السابقة"
|
||||
|
||||
#~ msgid "Switch windows of an app directly"
|
||||
#~ msgstr "تنقل مباشرة بين نوافذ التطبيق"
|
||||
|
||||
#~ msgid "Switch directly to previous window of an app"
|
||||
#~ msgstr "انتقل مباشرة إلى نافذة التطبيق السابقة"
|
||||
|
||||
#~ msgid "Switch system controls directly"
|
||||
#~ msgstr "تنقل مباشرة بين تحكمات النظام"
|
||||
|
||||
#~ msgid "Switch directly to previous system control"
|
||||
#~ msgstr "انتقل مباشرة إلى تحكم النظام السابق"
|
||||
|
||||
#~ msgid "Hide all normal windows"
|
||||
#~ msgstr "أخفِ كل النوافذ العادية"
|
||||
|
||||
#~ msgid "Switch to workspace 1"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 1"
|
||||
|
||||
#~ msgid "Switch to workspace 2"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 2"
|
||||
|
||||
#~ msgid "Switch to workspace 3"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 3"
|
||||
|
||||
#~ msgid "Switch to workspace 4"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 4"
|
||||
|
||||
#~ msgid "Switch to last workspace"
|
||||
#~ msgstr "انتقل إلى مساحة العمل الأخيرة"
|
||||
|
||||
#~ msgid "Move to workspace left"
|
||||
#~ msgstr "انقل لمساحة العمل على اليسار"
|
||||
|
||||
#~ msgid "Move to workspace right"
|
||||
#~ msgstr "انقل لمساحة العمل على اليمين"
|
||||
|
||||
#~ msgid "Move to workspace above"
|
||||
#~ msgstr "انقل لمساحة العمل أعلى"
|
||||
|
||||
#~ msgid "Move to workspace below"
|
||||
#~ msgstr "انقل لمساحة العمل أسفل"
|
||||
|
||||
#~ msgid "System"
|
||||
#~ msgstr "النظام"
|
||||
|
||||
#~ msgid "Show the run command prompt"
|
||||
#~ msgstr "أظهر محث تشغيل أمر"
|
||||
|
||||
#~ msgid "Show the activities overview"
|
||||
#~ msgstr "أظهر نظرة عامة على الأنشطة"
|
||||
|
||||
#~ msgid "Windows"
|
||||
#~ msgstr "النوافذ"
|
||||
|
||||
#~ msgid "Activate the window menu"
|
||||
#~ msgstr "فعّل قائمة النافذة"
|
||||
|
||||
#~ msgid "Toggle fullscreen mode"
|
||||
#~ msgstr "بدّل نمط ملء الشاشة"
|
||||
|
||||
#~ msgid "Toggle maximization state"
|
||||
#~ msgstr "بدّل حالة التكبير"
|
||||
|
||||
#~ msgid "Maximize window"
|
||||
#~ msgstr "كبّر النّافذة"
|
||||
|
||||
#~ msgid "Restore window"
|
||||
#~ msgstr "استعد النّافذة"
|
||||
|
||||
#~ msgid "Toggle shaded state"
|
||||
#~ msgstr "بدّل حالة الإخفاء"
|
||||
|
||||
#~ msgid "Close window"
|
||||
#~ msgstr "أغلق النّافذة"
|
||||
|
||||
#~ msgid "Hide window"
|
||||
#~ msgstr "أخفِ النّافذة"
|
||||
|
||||
#~ msgid "Move window"
|
||||
#~ msgstr "انقل النّافذة"
|
||||
|
||||
#~ msgid "Resize window"
|
||||
#~ msgstr "حجّم النّافذة"
|
||||
|
||||
#~ msgid "Toggle window on all workspaces or one"
|
||||
#~ msgstr "بدّل حالة ظهور النافذة على جميع مساحات العمل أو واحدة منها"
|
||||
|
||||
#~ msgid "Raise window if covered, otherwise lower it"
|
||||
#~ msgstr "ارفع النافذة إذا كانت أخرى تغطيها، أو أخفضها في ما عدا ذلك"
|
||||
|
||||
#~ msgid "Raise window above other windows"
|
||||
#~ msgstr "ارفع النافذة فوق النوافذ الأخرى"
|
||||
|
||||
#~ msgid "Lower window below other windows"
|
||||
#~ msgstr "اخفض النافذة تحت النوافذ الأخرى"
|
||||
|
||||
#~ msgid "Maximize window vertically"
|
||||
#~ msgstr "كبّر النافذة رأسيا"
|
||||
|
||||
#~ msgid "Maximize window horizontally"
|
||||
#~ msgstr "كبّر النافذة أفقيا"
|
||||
|
||||
#~ msgid "View split on left"
|
||||
#~ msgstr "المنظور مقسوم على اليمين"
|
||||
|
||||
#~ msgid "View split on right"
|
||||
#~ msgstr "المنظور مقسوم على اليسار"
|
||||
|
||||
#~ msgid "Mutter"
|
||||
#~ msgstr "مَتَر"
|
||||
|
||||
#~ msgid "Modifier to use for extended window management operations"
|
||||
#~ msgstr "المغير الذي سيُستعمل لتمديد عمليات إدارة النوافذ "
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 1"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 1"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 2"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 2"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 3"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 3"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 4"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 4"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 5"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 5"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 6"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 6"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 7"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 7"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 8"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 8"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 9"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 9"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 10"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 10"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 11"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 11"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Switch to VT 12"
|
||||
#~ msgstr "انتقل إلى مساحة العمل 12"
|
||||
|
||||
#~ msgid "Unknown window information request: %d"
|
||||
#~ msgstr "طلب معلومات نافذة مجهول: %d"
|
||||
|
||||
|
408
po/ca.po
408
po/ca.po
@ -5,283 +5,283 @@
|
||||
# Jesús Moreno <jmmolas@wanadoo.es>, 2002.
|
||||
# Jordi Mallach <jordi@sindominio.net>, 2003, 2004, 2005, 2006, 2007, 2008.
|
||||
# David Planella <david.planella@gmail.com>, 2008, 2009, 2011, 2012.
|
||||
# Jordi Serratosa <jordis@softcatala.cat>, 2012.
|
||||
# Jordi Serratosa <jordis@softcatala.cat>, 2012, 2017.
|
||||
# Gil Forcada <gilforcada@guifi.net>, 2012, 2013, 2014, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: metacity 2.24\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2016-03-13 01:36+0000\n"
|
||||
"PO-Revision-Date: 2016-03-13 14:45+0100\n"
|
||||
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
|
||||
"POT-Creation-Date: 2017-08-29 16:09+0000\n"
|
||||
"PO-Revision-Date: 2017-08-25 13:23+0200\n"
|
||||
"Last-Translator: Jordi Mas <jmas@softcatala.org>\n"
|
||||
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
|
||||
"Language: ca\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bits\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Gtranslator 2.91.6\n"
|
||||
"X-Generator: Poedit 2.0.1\n"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:1
|
||||
#: data/50-mutter-navigation.xml:6
|
||||
msgid "Navigation"
|
||||
msgstr "Navegació"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:2
|
||||
#: data/50-mutter-navigation.xml:9
|
||||
msgid "Move window to workspace 1"
|
||||
msgstr "Mou la finestra a l'espai de treball 1"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:3
|
||||
#: data/50-mutter-navigation.xml:12
|
||||
msgid "Move window to workspace 2"
|
||||
msgstr "Mou la finestra a l'espai de treball 2"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:4
|
||||
#: data/50-mutter-navigation.xml:15
|
||||
msgid "Move window to workspace 3"
|
||||
msgstr "Mou la finestra a l'espai de treball 3"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:5
|
||||
#: data/50-mutter-navigation.xml:18
|
||||
msgid "Move window to workspace 4"
|
||||
msgstr "Mou la finestra a l'espai de treball 4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:6
|
||||
#: data/50-mutter-navigation.xml:21
|
||||
msgid "Move window to last workspace"
|
||||
msgstr "Mou la finestra a l'últim espai de treball"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:7
|
||||
#: data/50-mutter-navigation.xml:24
|
||||
msgid "Move window one workspace to the left"
|
||||
msgstr "Mou la finestra un espai de treball a l'esquerra"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:8
|
||||
#: data/50-mutter-navigation.xml:27
|
||||
msgid "Move window one workspace to the right"
|
||||
msgstr "Mou la finestra un espai de treball a la dreta"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:9
|
||||
#: data/50-mutter-navigation.xml:30
|
||||
msgid "Move window one workspace up"
|
||||
msgstr "Mou la finestra un espai de treball amunt"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:10
|
||||
#: data/50-mutter-navigation.xml:33
|
||||
msgid "Move window one workspace down"
|
||||
msgstr "Mou la finestra un espai de treball avall"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:11
|
||||
#: data/50-mutter-navigation.xml:36
|
||||
msgid "Move window one monitor to the left"
|
||||
msgstr "Mou la finestra un monitor a l'esquerra"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:12
|
||||
#: data/50-mutter-navigation.xml:39
|
||||
msgid "Move window one monitor to the right"
|
||||
msgstr "Mou la finestra un monitor a la dreta"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:13
|
||||
#: data/50-mutter-navigation.xml:42
|
||||
msgid "Move window one monitor up"
|
||||
msgstr "Mou la finestra un monitor amunt"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:14
|
||||
#: data/50-mutter-navigation.xml:45
|
||||
msgid "Move window one monitor down"
|
||||
msgstr "Mou la finestra un monitor avall"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:15
|
||||
#: data/50-mutter-navigation.xml:49
|
||||
msgid "Switch applications"
|
||||
msgstr "Canvia d'aplicacions"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:16
|
||||
#: data/50-mutter-navigation.xml:54
|
||||
msgid "Switch to previous application"
|
||||
msgstr "Canvia a l'aplicació anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:17
|
||||
#: data/50-mutter-navigation.xml:58
|
||||
msgid "Switch windows"
|
||||
msgstr "Canvia de finestres"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:18
|
||||
#: data/50-mutter-navigation.xml:63
|
||||
msgid "Switch to previous window"
|
||||
msgstr "Canvia a la finestra anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:19
|
||||
#: data/50-mutter-navigation.xml:67
|
||||
msgid "Switch windows of an application"
|
||||
msgstr "Canvia entre les finestres d'una aplicació"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:20
|
||||
#: data/50-mutter-navigation.xml:72
|
||||
msgid "Switch to previous window of an application"
|
||||
msgstr "Canvia a la finestra anterior d'una aplicació"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:21
|
||||
#: data/50-mutter-navigation.xml:76
|
||||
msgid "Switch system controls"
|
||||
msgstr "Canvia entre els controls del sistema"
|
||||
msgstr "Canvia els controls del sistema"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:22
|
||||
#: data/50-mutter-navigation.xml:81
|
||||
msgid "Switch to previous system control"
|
||||
msgstr "Canvia al control del sistema anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:23
|
||||
#: data/50-mutter-navigation.xml:85
|
||||
msgid "Switch windows directly"
|
||||
msgstr "Canvia immediatament entre finestres"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:24
|
||||
#: data/50-mutter-navigation.xml:90
|
||||
msgid "Switch directly to previous window"
|
||||
msgstr "Canvia immediatament a la finestra anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:25
|
||||
#: data/50-mutter-navigation.xml:94
|
||||
msgid "Switch windows of an app directly"
|
||||
msgstr "Canvia immediatament entre les finestres d'una aplicació"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:26
|
||||
#: data/50-mutter-navigation.xml:99
|
||||
msgid "Switch directly to previous window of an app"
|
||||
msgstr "Canvia immediatament a la finestra anterior d'una aplicació"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:27
|
||||
#: data/50-mutter-navigation.xml:103
|
||||
msgid "Switch system controls directly"
|
||||
msgstr "Canvia immediatament entre els controls del sistema"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:28
|
||||
#: data/50-mutter-navigation.xml:108
|
||||
msgid "Switch directly to previous system control"
|
||||
msgstr "Canvia immediatament al control del sistema anterior"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:29
|
||||
#: data/50-mutter-navigation.xml:111
|
||||
msgid "Hide all normal windows"
|
||||
msgstr "Oculta totes les finestres normals"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:30
|
||||
#: data/50-mutter-navigation.xml:114
|
||||
msgid "Switch to workspace 1"
|
||||
msgstr "Canvia a l'espai de treball 1"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:31
|
||||
#: data/50-mutter-navigation.xml:117
|
||||
msgid "Switch to workspace 2"
|
||||
msgstr "Canvia a l'espai de treball 2"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:32
|
||||
#: data/50-mutter-navigation.xml:120
|
||||
msgid "Switch to workspace 3"
|
||||
msgstr "Canvia a l'espai de treball 3"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:33
|
||||
#: data/50-mutter-navigation.xml:123
|
||||
msgid "Switch to workspace 4"
|
||||
msgstr "Canvia a l'espai de treball 4"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:34
|
||||
#: data/50-mutter-navigation.xml:126
|
||||
msgid "Switch to last workspace"
|
||||
msgstr "Canvia a l'últim espai de treball"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:35
|
||||
#: data/50-mutter-navigation.xml:129
|
||||
msgid "Move to workspace left"
|
||||
msgstr "Mou a l'espai de treball de l'esquerra"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:36
|
||||
#: data/50-mutter-navigation.xml:132
|
||||
msgid "Move to workspace right"
|
||||
msgstr "Mou a l'espai de treball de la dreta"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:37
|
||||
#: data/50-mutter-navigation.xml:135
|
||||
msgid "Move to workspace above"
|
||||
msgstr "Mou a l'espai de treball de sobre"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:38
|
||||
#: data/50-mutter-navigation.xml:138
|
||||
msgid "Move to workspace below"
|
||||
msgstr "Mou a l'espai de treball de sota"
|
||||
|
||||
#: ../data/50-mutter-system.xml.in.h:1
|
||||
#: data/50-mutter-system.xml:6
|
||||
msgid "System"
|
||||
msgstr "Sistema"
|
||||
|
||||
#: ../data/50-mutter-system.xml.in.h:2
|
||||
#: data/50-mutter-system.xml:8
|
||||
msgid "Show the run command prompt"
|
||||
msgstr "Mostra l'indicador d'execució d'aplicacions"
|
||||
|
||||
#: ../data/50-mutter-system.xml.in.h:3
|
||||
#: data/50-mutter-system.xml:10
|
||||
msgid "Show the activities overview"
|
||||
msgstr "Mostra la vista general d'activitats"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:1
|
||||
#: data/50-mutter-windows.xml:6
|
||||
msgid "Windows"
|
||||
msgstr "Finestres"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:2
|
||||
#: data/50-mutter-windows.xml:8
|
||||
msgid "Activate the window menu"
|
||||
msgstr "Activa el menú de finestra"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:3
|
||||
#: data/50-mutter-windows.xml:10
|
||||
msgid "Toggle fullscreen mode"
|
||||
msgstr "Canvia entre el mode a pantalla completa"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:4
|
||||
#: data/50-mutter-windows.xml:12
|
||||
msgid "Toggle maximization state"
|
||||
msgstr "Canvia l'estat de maximització"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:5
|
||||
#: data/50-mutter-windows.xml:14
|
||||
msgid "Maximize window"
|
||||
msgstr "Maximitza la finestra"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:6
|
||||
#: data/50-mutter-windows.xml:16
|
||||
msgid "Restore window"
|
||||
msgstr "Restaura la finestra"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:7
|
||||
#: data/50-mutter-windows.xml:18
|
||||
msgid "Toggle shaded state"
|
||||
msgstr "Canvia l'estat d'ombrejat"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:8
|
||||
#: data/50-mutter-windows.xml:20
|
||||
msgid "Close window"
|
||||
msgstr "Tanca la finestra"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:9
|
||||
#: data/50-mutter-windows.xml:22
|
||||
msgid "Hide window"
|
||||
msgstr "Oculta la finestra"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:10
|
||||
#: data/50-mutter-windows.xml:24
|
||||
msgid "Move window"
|
||||
msgstr "Mou la finestra"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:11
|
||||
#: data/50-mutter-windows.xml:26
|
||||
msgid "Resize window"
|
||||
msgstr "Redimensiona la finestra"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:12
|
||||
#: data/50-mutter-windows.xml:29
|
||||
msgid "Toggle window on all workspaces or one"
|
||||
msgstr ""
|
||||
"Canvia la funció que fa que la finestra estigui en tots els espais de "
|
||||
"treball o només en un"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:13
|
||||
#: data/50-mutter-windows.xml:31
|
||||
msgid "Raise window if covered, otherwise lower it"
|
||||
msgstr "Alça la finestra si està coberta per una altra, o sinó baixa-la"
|
||||
msgstr "Alça la finestra si està coberta per una altra; altrament, baixa-la"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:14
|
||||
#: data/50-mutter-windows.xml:33
|
||||
msgid "Raise window above other windows"
|
||||
msgstr "Alça la finestra per damunt de les altres"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:15
|
||||
#: data/50-mutter-windows.xml:35
|
||||
msgid "Lower window below other windows"
|
||||
msgstr "Baixa la finestra sota les altres"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:16
|
||||
#: data/50-mutter-windows.xml:37
|
||||
msgid "Maximize window vertically"
|
||||
msgstr "Maximitza la finestra verticalment"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:17
|
||||
#: data/50-mutter-windows.xml:39
|
||||
msgid "Maximize window horizontally"
|
||||
msgstr "Maximitza la finestra horitzontalment"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:18
|
||||
#: data/50-mutter-windows.xml:43
|
||||
msgid "View split on left"
|
||||
msgstr "Mostra la partició a l'esquerra"
|
||||
|
||||
#: ../data/50-mutter-windows.xml.in.h:19
|
||||
#: data/50-mutter-windows.xml:47
|
||||
msgid "View split on right"
|
||||
msgstr "Mostra la partició a la dreta"
|
||||
|
||||
#: ../data/mutter.desktop.in.h:1
|
||||
#: data/mutter.desktop.in:4
|
||||
msgid "Mutter"
|
||||
msgstr "Mutter"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:1
|
||||
#: data/org.gnome.mutter.gschema.xml.in:7
|
||||
msgid "Modifier to use for extended window management operations"
|
||||
msgstr ""
|
||||
"Modificador que s'utilitzarà per les operacions ampliades de gestió de "
|
||||
"finestres"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:2
|
||||
#: data/org.gnome.mutter.gschema.xml.in:8
|
||||
msgid ""
|
||||
"This key will initiate the \"overlay\", which is a combination window "
|
||||
"overview and application launching system. The default is intended to be the "
|
||||
"\"Windows key\" on PC hardware. It's expected that this binding either the "
|
||||
"default or set to the empty string."
|
||||
"This key will initiate the “overlay”, which is a combination window overview "
|
||||
"and application launching system. The default is intended to be the “Windows "
|
||||
"key” on PC hardware. It’s expected that this binding either the default or "
|
||||
"set to the empty string."
|
||||
msgstr ""
|
||||
"Aquesta tecla iniciarà l'«overlay» (superposador), el qual és una combinació "
|
||||
"de visualització de finestres i sistema de llançament d'aplicacions. El "
|
||||
@ -289,11 +289,11 @@ msgstr ""
|
||||
"PC. El valor d'aquesta vinculació s'espera que sigui el predeterminat o text "
|
||||
"en blanc."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
|
||||
#: data/org.gnome.mutter.gschema.xml.in:20
|
||||
msgid "Attach modal dialogs"
|
||||
msgstr "Adjunta els diàlegs modals"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:4
|
||||
#: data/org.gnome.mutter.gschema.xml.in:21
|
||||
msgid ""
|
||||
"When true, instead of having independent titlebars, modal dialogs appear "
|
||||
"attached to the titlebar of the parent window and are moved together with "
|
||||
@ -303,13 +303,13 @@ msgstr ""
|
||||
"diàlegs modals apareixeran adjuntats a la barra de títol de la finestra mare "
|
||||
"i es mouran juntament amb aquesta."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
|
||||
#: data/org.gnome.mutter.gschema.xml.in:30
|
||||
msgid "Enable edge tiling when dropping windows on screen edges"
|
||||
msgstr ""
|
||||
"Habilita la tesselització a les vores en deixar anar les finestres a les "
|
||||
"Habilita la tessel·lització a les vores en deixar anar les finestres a les "
|
||||
"vores de la pantalla"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:6
|
||||
#: data/org.gnome.mutter.gschema.xml.in:31
|
||||
msgid ""
|
||||
"If enabled, dropping windows on vertical screen edges maximizes them "
|
||||
"vertically and resizes them horizontally to cover half of the available "
|
||||
@ -320,13 +320,13 @@ msgstr ""
|
||||
"deixar-les anar a les vores verticals de la pantalla. Si es deixen anar a la "
|
||||
"vora superior de la pantalla es maximitzaran completament."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:7
|
||||
#: data/org.gnome.mutter.gschema.xml.in:40
|
||||
msgid "Workspaces are managed dynamically"
|
||||
msgstr "Els espais de treball es gestionen dinàmicament"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:8
|
||||
#: data/org.gnome.mutter.gschema.xml.in:41
|
||||
msgid ""
|
||||
"Determines whether workspaces are managed dynamically or whether there's a "
|
||||
"Determines whether workspaces are managed dynamically or whether there’s a "
|
||||
"static number of workspaces (determined by the num-workspaces key in org."
|
||||
"gnome.desktop.wm.preferences)."
|
||||
msgstr ""
|
||||
@ -334,11 +334,11 @@ msgstr ""
|
||||
"nombre determinat d'espais de treball (determinat per la clau «num-"
|
||||
"workspaces» a «org.gnome.desktop.wm.preferences»)."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
|
||||
#: data/org.gnome.mutter.gschema.xml.in:50
|
||||
msgid "Workspaces only on primary"
|
||||
msgstr "Espais de treball només en el primari"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:10
|
||||
#: data/org.gnome.mutter.gschema.xml.in:51
|
||||
msgid ""
|
||||
"Determines whether workspace switching should happen for windows on all "
|
||||
"monitors or only for windows on the primary monitor."
|
||||
@ -346,11 +346,11 @@ msgstr ""
|
||||
"Determina si el canvi d'espai de treball hauria de ser per les finestres en "
|
||||
"tots els monitors o només en les finestres del monitor primari."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:11
|
||||
#: data/org.gnome.mutter.gschema.xml.in:59
|
||||
msgid "No tab popup"
|
||||
msgstr "Sense finestres emergents a les pestanyes"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:12
|
||||
#: data/org.gnome.mutter.gschema.xml.in:60
|
||||
msgid ""
|
||||
"Determines whether the use of popup and highlight frame should be disabled "
|
||||
"for window cycling."
|
||||
@ -358,40 +358,40 @@ msgstr ""
|
||||
"Determina si s'ha d'inhabilitar el quadre que es mostra a les finestres "
|
||||
"emergents i ressaltades en commutar entre finestres."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:13
|
||||
#: data/org.gnome.mutter.gschema.xml.in:68
|
||||
msgid "Delay focus changes until the pointer stops moving"
|
||||
msgstr "Retarda el canvi del focus fins que s'aturi el punter"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:14
|
||||
#: data/org.gnome.mutter.gschema.xml.in:69
|
||||
msgid ""
|
||||
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
|
||||
"the focus will not be changed immediately when entering a window, but only "
|
||||
"after the pointer stops moving."
|
||||
"If set to true, and the focus mode is either “sloppy” or “mouse” then the "
|
||||
"focus will not be changed immediately when entering a window, but only after "
|
||||
"the pointer stops moving."
|
||||
msgstr ""
|
||||
"Si és «true» (cert), i el mode del focus és «sloppy» o «mouse», no es "
|
||||
"canviarà el focus immediatament quan s'entri a una finestra, només es "
|
||||
"canviarà quan el punter deixi de moure's."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
|
||||
#: data/org.gnome.mutter.gschema.xml.in:79
|
||||
msgid "Draggable border width"
|
||||
msgstr "Amplada del contorn arrossegable"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:16
|
||||
#: data/org.gnome.mutter.gschema.xml.in:80
|
||||
msgid ""
|
||||
"The amount of total draggable borders. If the theme's visible borders are "
|
||||
"The amount of total draggable borders. If the theme’s visible borders are "
|
||||
"not enough, invisible borders will be added to meet this value."
|
||||
msgstr ""
|
||||
"La quantitat total de contorn arrossegable. Si els contorns visibles del "
|
||||
"tema no són suficients, s'afegiran contorns invisibles per aconseguir aquest "
|
||||
"valor."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:17
|
||||
#: data/org.gnome.mutter.gschema.xml.in:89
|
||||
msgid "Auto maximize nearly monitor sized windows"
|
||||
msgstr ""
|
||||
"Maximitza automàticament les finestres que gairebé facin la mida de la "
|
||||
"pantalla"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:18
|
||||
#: data/org.gnome.mutter.gschema.xml.in:90
|
||||
msgid ""
|
||||
"If enabled, new windows that are initially the size of the monitor "
|
||||
"automatically get maximized."
|
||||
@ -399,11 +399,11 @@ msgstr ""
|
||||
"Si s'habilita, les finestres que inicialment gairebé fan la mida de la "
|
||||
"pantalla es maximitzaran automàticament."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:19
|
||||
#: data/org.gnome.mutter.gschema.xml.in:98
|
||||
msgid "Place new windows in the center"
|
||||
msgstr "Posiciona les finestres noves al centre"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:20
|
||||
#: data/org.gnome.mutter.gschema.xml.in:99
|
||||
msgid ""
|
||||
"When true, the new windows will always be put in the center of the active "
|
||||
"screen of the monitor."
|
||||
@ -411,153 +411,177 @@ msgstr ""
|
||||
"Si és «true» (cert), les finestres noves seran posicionades al centre de la "
|
||||
"pantalla activa del monitor."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
|
||||
#: data/org.gnome.mutter.gschema.xml.in:107
|
||||
msgid "Enable experimental features"
|
||||
msgstr "Habilita les funcionalitats experimentals"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:108
|
||||
msgid ""
|
||||
"To enable experimental features, add the feature keyword to the list. "
|
||||
"Whether the feature requires restarting the compositor depends on the given "
|
||||
"feature. Any experimental feature is not required to still be available, or "
|
||||
"configurable. Don’t expect adding anything in this setting to be future "
|
||||
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
|
||||
"mutter default to layout logical monitors in a logical pixel coordinate "
|
||||
"space, while scaling monitor framebuffers instead of window content, to "
|
||||
"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — "
|
||||
"enables remote desktop support. To support remote desktop with screen "
|
||||
"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables "
|
||||
"screen cast support."
|
||||
msgstr ""
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:145
|
||||
msgid "Select window from tab popup"
|
||||
msgstr "Selecció de finestra entre les emergents d'una pestanya"
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:22
|
||||
#: data/org.gnome.mutter.gschema.xml.in:150
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Cancel·lació de les finestres emergents a les pestanyes"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1
|
||||
#: data/org.gnome.mutter.gschema.xml.in:155
|
||||
msgid "Switch monitor configurations"
|
||||
msgstr "Canvia configuracions de monitor"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:160
|
||||
msgid "Rotates the built-in monitor configuration"
|
||||
msgstr "Gira la configuració del monitor integrada"
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:6
|
||||
msgid "Switch to VT 1"
|
||||
msgstr "Canvia al terminal virtual 1"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:10
|
||||
msgid "Switch to VT 2"
|
||||
msgstr "Canvia al terminal virtual 2"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:14
|
||||
msgid "Switch to VT 3"
|
||||
msgstr "Canvia al terminal virtual 3"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:18
|
||||
msgid "Switch to VT 4"
|
||||
msgstr "Canvia al terminal virtual 4"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:22
|
||||
msgid "Switch to VT 5"
|
||||
msgstr "Canvia al terminal virtual 5"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:26
|
||||
msgid "Switch to VT 6"
|
||||
msgstr "Canvia al terminal virtual 6"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:30
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "Canvia al terminal virtual 7"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:34
|
||||
msgid "Switch to VT 8"
|
||||
msgstr "Canvia al terminal virtual 8"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:38
|
||||
msgid "Switch to VT 9"
|
||||
msgstr "Canvia al terminal virtual 9"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:42
|
||||
msgid "Switch to VT 10"
|
||||
msgstr "Canvia al terminal virtual 10"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:46
|
||||
msgid "Switch to VT 11"
|
||||
msgstr "Canvia al terminal virtual 11"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:50
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Canvia al terminal virtual 12"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:518
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:54
|
||||
msgid "Re-enable shortcuts"
|
||||
msgstr "Torna a habilitar les dreceres"
|
||||
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2151
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr "Mode de commutació (grup %d)"
|
||||
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2174
|
||||
msgid "Switch monitor"
|
||||
msgstr "Commuta el monitor"
|
||||
|
||||
#: src/backends/meta-input-settings.c:2176
|
||||
msgid "Show on-screen help"
|
||||
msgstr "Mostra l'ajuda en pantalla"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:903
|
||||
msgid "Built-in display"
|
||||
msgstr "Pantalla integrada"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:544
|
||||
#: src/backends/meta-monitor-manager.c:926
|
||||
msgid "Unknown"
|
||||
msgstr "Desconeguda"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:546
|
||||
#: src/backends/meta-monitor-manager.c:928
|
||||
msgid "Unknown Display"
|
||||
msgstr "Pantalla desconeguda"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:554
|
||||
#: src/backends/meta-monitor-manager.c:936
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:456
|
||||
#: src/compositor/compositor.c:476
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
"Another compositing manager is already running on screen %i on display “%s”."
|
||||
msgstr ""
|
||||
"Ja s'està executant un altre gestor de composició a la pantalla %i a la "
|
||||
"visualització «%s»."
|
||||
"Ja s'està executant un altre gestor de composició al monitor %i a la "
|
||||
"pantalla «%s»."
|
||||
|
||||
#: ../src/core/bell.c:192
|
||||
#: src/core/bell.c:194
|
||||
msgid "Bell event"
|
||||
msgstr "Esdeveniment de campana"
|
||||
|
||||
#: ../src/core/delete.c:127
|
||||
#: src/core/display.c:608
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "«%s» no està responent."
|
||||
|
||||
#: ../src/core/delete.c:129
|
||||
msgid "Application is not responding."
|
||||
msgstr "L'aplicació no està responent."
|
||||
|
||||
#: ../src/core/delete.c:134
|
||||
msgid ""
|
||||
"You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely."
|
||||
msgstr ""
|
||||
"Podeu esperar un moment perquè continuï o podeu forçar-ne la sortida "
|
||||
"completa."
|
||||
|
||||
#: ../src/core/delete.c:141
|
||||
msgid "_Wait"
|
||||
msgstr "_Espera"
|
||||
|
||||
#: ../src/core/delete.c:141
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Força'n la sortida"
|
||||
|
||||
#: ../src/core/display.c:555
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr ""
|
||||
"S'ha produït un error en obrir la pantalla del sistema de finestres X «%s»\n"
|
||||
|
||||
#: ../src/core/main.c:181
|
||||
#: src/core/main.c:189
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Inhabilita la connexió al gestor de sessions"
|
||||
|
||||
#: ../src/core/main.c:187
|
||||
#: src/core/main.c:195
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Reemplaça el gestor de finestres en execució"
|
||||
|
||||
#: ../src/core/main.c:193
|
||||
#: src/core/main.c:201
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Especifica l'ID de gestió de sessió"
|
||||
|
||||
#: ../src/core/main.c:198
|
||||
#: src/core/main.c:206
|
||||
msgid "X Display to use"
|
||||
msgstr "Visualització X per usar"
|
||||
|
||||
#: ../src/core/main.c:204
|
||||
#: src/core/main.c:212
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Inicialitza la sessió des del fitxer desat"
|
||||
|
||||
#: ../src/core/main.c:210
|
||||
#: src/core/main.c:218
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Fes que les crides a l'X siguin síncrones"
|
||||
|
||||
#: ../src/core/main.c:217
|
||||
#: src/core/main.c:225
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Funciona com a compositor de Wayland"
|
||||
|
||||
@ -566,20 +590,45 @@ msgstr "Funciona com a compositor de Wayland"
|
||||
#
|
||||
# Camins:
|
||||
# ../src/core/main.c:223
|
||||
#: ../src/core/main.c:223
|
||||
#| msgid "Run as a wayland compositor"
|
||||
#: src/core/main.c:231
|
||||
msgid "Run as a nested compositor"
|
||||
msgstr "Funciona com a compositor imbricat"
|
||||
|
||||
#: ../src/core/main.c:231
|
||||
#: src/core/main.c:239
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Funciona com a servidor de pantalla completa, en comptes d'imbricat"
|
||||
|
||||
#: ../src/core/mutter.c:39
|
||||
#. Translators: %s is a window title
|
||||
#: src/core/meta-close-dialog-default.c:147
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "«%s» no està responent."
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:149
|
||||
msgid "Application is not responding."
|
||||
msgstr "L'aplicació no està responent."
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:154
|
||||
msgid ""
|
||||
"You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely."
|
||||
msgstr ""
|
||||
"Podeu esperar un moment perquè continuï o podeu forçar-ne la sortida "
|
||||
"completa."
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:161
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Força'n la sortida"
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:161
|
||||
msgid "_Wait"
|
||||
msgstr "_Espera"
|
||||
|
||||
#: src/core/mutter.c:39
|
||||
#, c-format
|
||||
msgid ""
|
||||
"mutter %s\n"
|
||||
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
|
||||
"Copyright © 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"
|
||||
@ -591,46 +640,51 @@ msgstr ""
|
||||
"No hi ha CAP garantia; ni tan sols la garantia implícita de COMERCIABILITAT\n"
|
||||
"o ADEQUACIÓ A PER UN PROPÒSIT PARTICULAR.\n"
|
||||
|
||||
#: ../src/core/mutter.c:53
|
||||
#: src/core/mutter.c:53
|
||||
msgid "Print version"
|
||||
msgstr "Escriu versió"
|
||||
|
||||
#: ../src/core/mutter.c:59
|
||||
#: src/core/mutter.c:59
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Connector del Mutter a utilitzar"
|
||||
|
||||
#: ../src/core/prefs.c:1997
|
||||
#: src/core/prefs.c:1997
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Espai de treball %d"
|
||||
|
||||
#: ../src/core/screen.c:521
|
||||
#: src/core/screen.c:580
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
"Display “%s” already has a window manager; try using the --replace option to "
|
||||
"replace the current window manager."
|
||||
msgstr ""
|
||||
"La pantalla «%s» ja té un gestor de finestres; proveu l'opció --replace per "
|
||||
"reemplaçar el gestor de finestres actual."
|
||||
|
||||
#: ../src/core/screen.c:603
|
||||
#: src/core/screen.c:665
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "La pantalla %d en la visualització '%s' no és vàlida\n"
|
||||
msgid "Screen %d on display “%s” is invalid\n"
|
||||
msgstr "El monitor %d en la pantalla '%s' no és vàlida\n"
|
||||
|
||||
#: ../src/core/util.c:121
|
||||
#: src/core/util.c:120
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Mutter es va compilar sense compatibilitat per al mode detallat\n"
|
||||
|
||||
#: ../src/x11/session.c:1815
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:563
|
||||
#, c-format
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr "Mode de commutació: mode %d"
|
||||
|
||||
#: src/x11/session.c:1815
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
"These windows do not support “save current setup” and will have to be "
|
||||
"restarted manually next time you log in."
|
||||
msgstr ""
|
||||
"Aquestes finestres no implementen «desa la configuració actual» i s'hauran "
|
||||
"de reiniciar manualment la pròxima vegada que entreu."
|
||||
|
||||
#: ../src/x11/window-props.c:549
|
||||
#: src/x11/window-props.c:559
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (a %s)"
|
||||
|
1663
po/ca@valencia.po
1663
po/ca@valencia.po
File diff suppressed because it is too large
Load Diff
380
po/da.po
380
po/da.po
@ -1,5 +1,5 @@
|
||||
# Danish translation of Mutter.
|
||||
# Copyright (C) 2002-2009, 2012-2016.
|
||||
# Copyright (C) 2002-2009, 2012-2017.
|
||||
# This file is distributed under the same license as the metacity package.
|
||||
# Kjartan Maraas <kmaraas@gnome.org>, 2002
|
||||
# Keld simonsen <keld@dkuug.dk>, 2002
|
||||
@ -8,7 +8,7 @@
|
||||
# Lasse Bang Mikkelsen <lbm@fatalerror.dk>, 2006.
|
||||
# Kenneth Nielsen <k.nielsen81@gmail.com>, 2008.
|
||||
# Joe Hansen <joedalton2@yahoo.dk>, 2011.
|
||||
# Ask Hjorth Larsen <asklarsen@gmail.com>, 2007, 09, 10, 12, 13, 14, 15, 16.
|
||||
# Ask Hjorth Larsen <asklarsen@gmail.com>, 2007, 09, 10, 12, 13, 14, 15, 16, 17.
|
||||
#
|
||||
# Ordliste:
|
||||
#
|
||||
@ -19,10 +19,10 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2016-09-13 10:16+0000\n"
|
||||
"PO-Revision-Date: 2016-09-08 23:52+0200\n"
|
||||
"POT-Creation-Date: 2017-08-29 16:09+0000\n"
|
||||
"PO-Revision-Date: 2017-09-03 20:29+0200\n"
|
||||
"Last-Translator: Ask Hjorth Larsen <asklarsen@gmail.com>\n"
|
||||
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
|
||||
"Language: da\n"
|
||||
@ -188,7 +188,7 @@ msgstr "System"
|
||||
|
||||
#: data/50-mutter-system.xml:8
|
||||
msgid "Show the run command prompt"
|
||||
msgstr "Vis \"kør kommando\"-prompten"
|
||||
msgstr "Vis “kør kommando”-prompten"
|
||||
|
||||
#: data/50-mutter-system.xml:10
|
||||
msgid "Show the activities overview"
|
||||
@ -280,15 +280,15 @@ msgstr "Modifikationstast til brug for udvidede vindueshåndteringsoperationer"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:8
|
||||
msgid ""
|
||||
"This key will initiate the \"overlay\", which is a combination window "
|
||||
"overview and application launching system. The default is intended to be the "
|
||||
"\"Windows key\" on PC hardware. It's expected that this binding either the "
|
||||
"default or set to the empty string."
|
||||
"This key will initiate the “overlay”, which is a combination window overview "
|
||||
"and application launching system. The default is intended to be the “Windows "
|
||||
"key” on PC hardware. It’s expected that this binding either the default or "
|
||||
"set to the empty string."
|
||||
msgstr ""
|
||||
"Denne nøgle vil klargøre \"overlay\", som er en kombineret vinduesoversigt "
|
||||
"og programstartsystem. Standardværdien på PC-hardware er tiltænkt som "
|
||||
"\"Windows\"-tasten. Det forventes at denne binding enten har "
|
||||
"standardværdien, eller er sat til den tomme streng."
|
||||
"Denne nøgle vil klargøre “overlay”, som er en kombineret vinduesoversigt og "
|
||||
"programstartersystem. Standardværdien på PC-hardware er tiltænkt som "
|
||||
"“Windows”-tasten. Det forventes, at denne binding enten har standardværdien, "
|
||||
"eller er sat til den tomme streng."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:20
|
||||
msgid "Attach modal dialogs"
|
||||
@ -326,7 +326,7 @@ msgstr "Arbejdsområder håndteres dynamisk"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:41
|
||||
msgid ""
|
||||
"Determines whether workspaces are managed dynamically or whether there's a "
|
||||
"Determines whether workspaces are managed dynamically or whether there’s a "
|
||||
"static number of workspaces (determined by the num-workspaces key in org."
|
||||
"gnome.desktop.wm.preferences)."
|
||||
msgstr ""
|
||||
@ -364,13 +364,13 @@ msgstr "Lad fokusændringer vente indtil markøren holder op med at bevæge sig"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:69
|
||||
msgid ""
|
||||
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
|
||||
"the focus will not be changed immediately when entering a window, but only "
|
||||
"after the pointer stops moving."
|
||||
"If set to true, and the focus mode is either “sloppy” or “mouse” then the "
|
||||
"focus will not be changed immediately when entering a window, but only after "
|
||||
"the pointer stops moving."
|
||||
msgstr ""
|
||||
"Hvis sat til sand, og fokustilstanden er enten \"sloppy\" eller \"mouse\", "
|
||||
"vil fokus ikke blive ændret omgående når man går ind i et nyt vindue, men "
|
||||
"først efter markøren holder op med at bevæge sig."
|
||||
"Hvis sat til sand, og fokustilstanden er enten “sloppy” eller “mouse”, vil "
|
||||
"fokus ikke blive ændret omgående når man går ind i et nyt vindue, men først "
|
||||
"efter markøren holder op med at bevæge sig."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:79
|
||||
msgid "Draggable border width"
|
||||
@ -378,7 +378,7 @@ msgstr "Bredde af den trækbare kant"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:80
|
||||
msgid ""
|
||||
"The amount of total draggable borders. If the theme's visible borders are "
|
||||
"The amount of total draggable borders. If the theme’s visible borders are "
|
||||
"not enough, invisible borders will be added to meet this value."
|
||||
msgstr ""
|
||||
"Samlet mængde kant der kan trækkes. Hvis temaets synlige grænser ikke er "
|
||||
@ -407,14 +407,42 @@ msgid ""
|
||||
msgstr ""
|
||||
"Når sand, vil nye vinduer altid blive placeret i midten af den aktive skærm."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:120
|
||||
#: data/org.gnome.mutter.gschema.xml.in:107
|
||||
msgid "Enable experimental features"
|
||||
msgstr "Slå eksperimentelle funktioner til"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:108
|
||||
msgid ""
|
||||
"To enable experimental features, add the feature keyword to the list. "
|
||||
"Whether the feature requires restarting the compositor depends on the given "
|
||||
"feature. Any experimental feature is not required to still be available, or "
|
||||
"configurable. Don’t expect adding anything in this setting to be future "
|
||||
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
|
||||
"mutter default to layout logical monitors in a logical pixel coordinate "
|
||||
"space, while scaling monitor framebuffers instead of window content, to "
|
||||
"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — "
|
||||
"enables remote desktop support. To support remote desktop with screen "
|
||||
"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables "
|
||||
"screen cast support."
|
||||
msgstr "For at slå eksperimentelle funktioner til, skal du tilføje funktionsnøgleordet til listen. Om funktionen kræver genstart af kompositoren afhænger af den givne funktion. Der er ingen garanti for at eksperimentelle funktion forbliver tilgængelige eller mulige at konfigurere. Forvent ikke at noget i denne indstilling nødvendigvis fungerer i fremtiden. Mulige nøgleord i øjeblikket: • “scale-monitor-framebuffer” — får mutter til som standard at arrangere logiske skærme i et logisk pixelkoordinatrum, mens skærmes framebuffere skaleres frem for vinduesindholdet for at håndtere HiDPI-skærme. Fjernskrivebord med skærmdeling understøttes hvis “screen-cast” også er aktiveret. • “screen-cast” — aktiverer understøttelse af skærmoptagelse."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:145
|
||||
msgid "Select window from tab popup"
|
||||
msgstr "Vælg vindue fra tab-pop-op"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:125
|
||||
#: data/org.gnome.mutter.gschema.xml.in:150
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Annullér faneblads-pop-op"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:155
|
||||
msgid "Switch monitor configurations"
|
||||
msgstr "Skift skærmkonfiguration"
|
||||
|
||||
# Mærkelig ting at rotere. De mener nok at skifte cyclisk mellem nogle stykker, men "built-in"?
|
||||
#: data/org.gnome.mutter.gschema.xml.in:160
|
||||
msgid "Rotates the built-in monitor configuration"
|
||||
msgstr "Roterer den indbyggede skærmkonfiguration"
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:6
|
||||
msgid "Switch to VT 1"
|
||||
msgstr "Skift til VT 1"
|
||||
@ -463,61 +491,114 @@ msgstr "Skift til VT 11"
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Skift til VT 12"
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:54
|
||||
msgid "Re-enable shortcuts"
|
||||
msgstr "Genaktivér genveje"
|
||||
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2151
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr "Tilstandsskift (Gruppe %d)"
|
||||
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:1845
|
||||
#: src/backends/meta-input-settings.c:2174
|
||||
msgid "Switch monitor"
|
||||
msgstr "Skift skærm"
|
||||
|
||||
#: src/backends/meta-input-settings.c:1847
|
||||
#: src/backends/meta-input-settings.c:2176
|
||||
msgid "Show on-screen help"
|
||||
msgstr "Vis integreret hjælp"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:514
|
||||
#: src/backends/meta-monitor-manager.c:903
|
||||
msgid "Built-in display"
|
||||
msgstr "Indbygget terminal"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:537
|
||||
#: src/backends/meta-monitor-manager.c:926
|
||||
msgid "Unknown"
|
||||
msgstr "Ukendt"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:539
|
||||
#: src/backends/meta-monitor-manager.c:928
|
||||
msgid "Unknown Display"
|
||||
msgstr "Ukendt terminal"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: src/backends/meta-monitor-manager.c:547
|
||||
#: src/backends/meta-monitor-manager.c:936
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: src/compositor/compositor.c:463
|
||||
#: src/compositor/compositor.c:476
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
"Another compositing manager is already running on screen %i on display “%s”."
|
||||
msgstr ""
|
||||
"En anden komposithåndtering kører allerede på skærm %i på terminal \"%s\"."
|
||||
"En anden komposithåndtering kører allerede på skærm %i på terminal “%s”."
|
||||
|
||||
#: src/core/bell.c:194
|
||||
msgid "Bell event"
|
||||
msgstr "Bip-hændelse"
|
||||
|
||||
#: src/core/delete.c:127
|
||||
#: src/core/display.c:608
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr "Kunne ikke åbne X Window System-terminalen “%s”\n"
|
||||
|
||||
#: src/core/main.c:189
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Deaktivér forbindelse til sessionshåndtering"
|
||||
|
||||
#: src/core/main.c:195
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Erstat den kørende vindueshåndtering"
|
||||
|
||||
#: src/core/main.c:201
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Angiv sessionhåndterings-id"
|
||||
|
||||
#: src/core/main.c:206
|
||||
msgid "X Display to use"
|
||||
msgstr "X-terminal som bruges"
|
||||
|
||||
#: src/core/main.c:212
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Initialisér session fra gemt fil"
|
||||
|
||||
#: src/core/main.c:218
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Gør kald til X synkrone"
|
||||
|
||||
#: src/core/main.c:225
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Kør som en wayland-kompositor"
|
||||
|
||||
#: src/core/main.c:231
|
||||
msgid "Run as a nested compositor"
|
||||
msgstr "Kør som en indlejret kompositor"
|
||||
|
||||
#: src/core/main.c:239
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Kør som fuld terminalserver, frem for indlejret"
|
||||
|
||||
#. Translators: %s is a window title
|
||||
#: src/core/meta-close-dialog-default.c:147
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "“%s” svarer ikke."
|
||||
|
||||
#: src/core/delete.c:129
|
||||
#: src/core/meta-close-dialog-default.c:149
|
||||
msgid "Application is not responding."
|
||||
msgstr "Program svarer ikke."
|
||||
|
||||
#: src/core/delete.c:134
|
||||
#: src/core/meta-close-dialog-default.c:154
|
||||
msgid ""
|
||||
"You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely."
|
||||
@ -525,66 +606,25 @@ msgstr ""
|
||||
"Du kan vælge at vente et lille stykke tid på at programmet fortsætter, eller "
|
||||
"du kan tvinge programmet til at afslutte fuldstændigt."
|
||||
|
||||
#: src/core/delete.c:141
|
||||
msgid "_Wait"
|
||||
msgstr "_Vent"
|
||||
|
||||
#: src/core/delete.c:141
|
||||
#: src/core/meta-close-dialog-default.c:161
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Tving til at afslutte"
|
||||
|
||||
#: src/core/display.c:590
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Kunne ikke åbne X Window System-terminalen \"%s\"\n"
|
||||
|
||||
#: src/core/main.c:182
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Deaktivér forbindelse til sessionshåndtering"
|
||||
|
||||
#: src/core/main.c:188
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Erstat den kørende vindueshåndtering"
|
||||
|
||||
#: src/core/main.c:194
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Angiv sessionhåndterings-id"
|
||||
|
||||
#: src/core/main.c:199
|
||||
msgid "X Display to use"
|
||||
msgstr "X-terminal som bruges"
|
||||
|
||||
#: src/core/main.c:205
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Initialisér session fra gemt fil"
|
||||
|
||||
#: src/core/main.c:211
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Gør kald til X synkrone"
|
||||
|
||||
#: src/core/main.c:218
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Kør som en wayland-kompositor"
|
||||
|
||||
#: src/core/main.c:224
|
||||
msgid "Run as a nested compositor"
|
||||
msgstr "Kør som en indlejret kompositor"
|
||||
|
||||
#: src/core/main.c:232
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Kør som fuld terminalserver, frem for indlejret"
|
||||
#: src/core/meta-close-dialog-default.c:161
|
||||
msgid "_Wait"
|
||||
msgstr "_Vent"
|
||||
|
||||
#: src/core/mutter.c:39
|
||||
#, c-format
|
||||
msgid ""
|
||||
"mutter %s\n"
|
||||
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
|
||||
"Copyright © 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 © 2001-%d Havoc Pennington, Red Hat, Inc., og andre\n"
|
||||
"Copyright © 2001–%d Havoc Pennington, Red Hat, Inc., og andre\n"
|
||||
"Dette er frit programmel; se kildekoden for kopieringsbetingelser.\n"
|
||||
"Der er INGEN garanti; ikke engang for SALGBARHED eller EGNETHED TIL ET "
|
||||
"BESTEMT FORMÅL.\n"
|
||||
@ -602,39 +642,39 @@ msgstr "Mutter-udvidelsesmodul der skal bruges"
|
||||
msgid "Workspace %d"
|
||||
msgstr "Arbejdsområde %d"
|
||||
|
||||
#: src/core/screen.c:521
|
||||
#: src/core/screen.c:580
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
"Display “%s” already has a window manager; try using the --replace option to "
|
||||
"replace the current window manager."
|
||||
msgstr ""
|
||||
"Terminalen \"%s\" har allerede en vindueshåndtering; prøv tilvalget --"
|
||||
"replace for at erstatte den aktuelle vindueshåndtering."
|
||||
"Terminalen “%s” har allerede en vindueshåndtering; prøv tilvalget --replace "
|
||||
"for at erstatte den aktuelle vindueshåndtering."
|
||||
|
||||
#: src/core/screen.c:606
|
||||
#: src/core/screen.c:665
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Skærm %d på terminal \"%s\" er ugyldig\n"
|
||||
msgid "Screen %d on display “%s” is invalid\n"
|
||||
msgstr "Skærm %d på terminal “%s” er ugyldig\n"
|
||||
|
||||
#: src/core/util.c:120
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Mutter blev kompileret uden understøttelse for uddybende tilstand\n"
|
||||
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:595
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:563
|
||||
#, c-format
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr "Tilstandsskift: Tilstand %d"
|
||||
|
||||
#: src/x11/session.c:1815
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
"These windows do not support “save current setup” and will have to be "
|
||||
"restarted manually next time you log in."
|
||||
msgstr ""
|
||||
"Disse vinduer understøtter ikke gemning af deres opsætning og skal "
|
||||
"genstartes manuelt næste gang du logger på."
|
||||
"Disse vinduer understøtter ikke at gemme deres opsætning og skal genstartes "
|
||||
"manuelt næste gang, du logger på."
|
||||
|
||||
# Lad os håbe dette er rigtigt
|
||||
#: src/x11/window-props.c:548
|
||||
#: src/x11/window-props.c:559
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (på %s)"
|
||||
@ -664,10 +704,10 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "højre"
|
||||
|
||||
#~ msgid "frame geometry does not specify \"%s\" dimension"
|
||||
#~ msgstr "rammegeometri angiver ikke dimensionen \"%s\""
|
||||
#~ msgstr "rammegeometri angiver ikke dimensionen “%s”"
|
||||
|
||||
#~ msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
|
||||
#~ msgstr "rammegeometri angiver ikke dimensionen \"%s\" for kanten \"%s\""
|
||||
#~ msgstr "rammegeometri angiver ikke dimensionen “%s” for kanten “%s”"
|
||||
|
||||
#~ msgid "Button aspect ratio %g is not reasonable"
|
||||
#~ msgstr "Knapformatforholdet %g er ikke fornuftigt"
|
||||
@ -683,20 +723,20 @@ msgstr "%s (på %s)"
|
||||
#~ "parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
|
||||
#~ msgstr ""
|
||||
#~ "Specifikation for tilpasset GTK-farve skal have et farvenavn og standard "
|
||||
#~ "i parentes f.eks. gtk:custom(foo,bar); kunne ikke fortolke \"%s\""
|
||||
#~ "i parentes f.eks. gtk:custom(foo,bar); kunne ikke fortolke “%s”"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-"
|
||||
#~ "z0-9-_ are valid"
|
||||
#~ msgstr ""
|
||||
#~ "Ugyldigt tegn \"%c\" i parameteren color_name for gtk:custom, kun A-Za-"
|
||||
#~ "z0-9-_ er gyldig"
|
||||
#~ "Ugyldigt tegn “%c” i parameteren color_name for gtk:custom, kun A-Za-z0-9-"
|
||||
#~ "_ er gyldig"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||
#~ "fit the format"
|
||||
#~ msgstr ""
|
||||
#~ "Gtk:custom-formatet er \"gtk:custom(color_name,fallback)\", \"%s\" passer "
|
||||
#~ "Gtk:custom-formatet er “gtk:custom(color_name,fallback)”, “%s” passer "
|
||||
#~ "ikke med formatet"
|
||||
|
||||
#~ msgid ""
|
||||
@ -704,69 +744,67 @@ msgstr "%s (på %s)"
|
||||
#~ "fg[NORMAL] where NORMAL is the state; could not parse \"%s\""
|
||||
#~ msgstr ""
|
||||
#~ "GTK-farvespecifikation skal have tilstanden i firkantede klammer, f.eks. "
|
||||
#~ "gtk:fg[NORMAL] hvor NORMAL er tilstanden; kunne ikke fortolke \"%s\""
|
||||
#~ "gtk:fg[NORMAL] hvor NORMAL er tilstanden; kunne ikke fortolke “%s”"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "GTK color specification must have a close bracket after the state, e.g. "
|
||||
#~ "gtk:fg[NORMAL] where NORMAL is the state; could not parse \"%s\""
|
||||
#~ msgstr ""
|
||||
#~ "GTK-farvespecifikation skal have en afsluttende klamme efter tilstanden, "
|
||||
#~ "f.eks. gtk:fg[NORMAL] hvor NORMAL er tilstanden; kunne ikke fortolke \"%s"
|
||||
#~ "\""
|
||||
#~ "f.eks. gtk:fg[NORMAL] hvor NORMAL er tilstanden; kunne ikke fortolke “%s”"
|
||||
|
||||
#~ msgid "Did not understand state \"%s\" in color specification"
|
||||
#~ msgstr "Forstod ikke tilstanden \"%s\" i farvespecifikationen"
|
||||
#~ msgstr "Forstod ikke tilstanden “%s” i farvespecifikationen"
|
||||
|
||||
#~ msgid "Did not understand color component \"%s\" in color specification"
|
||||
#~ msgstr "Forstod ikke farvekomponenten \"%s\" i farvespecifikationen"
|
||||
#~ msgstr "Forstod ikke farvekomponenten “%s” i farvespecifikationen"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit "
|
||||
#~ "the format"
|
||||
#~ msgstr ""
|
||||
#~ "Blandingsformat er \"blend/bg_color/fg_color/alpha\", \"%s\" passer ikke "
|
||||
#~ "med formatet"
|
||||
#~ "Blandingsformat er “blend/bg_color/fg_color/alpha”, “%s” passer ikke med "
|
||||
#~ "formatet"
|
||||
|
||||
#~ msgid "Could not parse alpha value \"%s\" in blended color"
|
||||
#~ msgstr "Kunne ikke fortolke alfaværdien \"%s\" i blandet farve"
|
||||
#~ msgstr "Kunne ikke fortolke alfaværdien “%s” i blandet farve"
|
||||
|
||||
#~ msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
|
||||
#~ msgstr "Alfaværdien \"%s\" i blandet farve er ikke mellem 0,0 og 1,0"
|
||||
#~ msgstr "Alfaværdien “%s” i blandet farve er ikke mellem 0,0 og 1,0"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Shade format is \"shade/base_color/factor\", \"%s\" does not fit the "
|
||||
#~ "format"
|
||||
#~ msgstr ""
|
||||
#~ "Skyggeformat er \"shade/base_color/factor\", \"%s\" passer ikke med "
|
||||
#~ "formatet"
|
||||
#~ "Skyggeformat er “shade/base_color/factor”, “%s” passer ikke med formatet"
|
||||
|
||||
#~ msgid "Could not parse shade factor \"%s\" in shaded color"
|
||||
#~ msgstr "Kunne ikke fortolke skyggeværdien \"%s\" i skygget farve"
|
||||
#~ msgstr "Kunne ikke fortolke skyggeværdien “%s” i skygget farve"
|
||||
|
||||
#~ msgid "Shade factor \"%s\" in shaded color is negative"
|
||||
#~ msgstr "Skyggefaktoren \"%s\" i skygget farve er negativ"
|
||||
#~ msgstr "Skyggefaktoren “%s” i skygget farve er negativ"
|
||||
|
||||
#~ msgid "Could not parse color \"%s\""
|
||||
#~ msgstr "Kunne ikke fortolke farven \"%s\""
|
||||
#~ msgstr "Kunne ikke fortolke farven “%s”"
|
||||
|
||||
#~ msgid "Coordinate expression contains character '%s' which is not allowed"
|
||||
#~ msgstr "Koordinatudtryk indeholder tegnet \"%s\" som ikke er tilladt"
|
||||
#~ msgstr "Koordinatudtryk indeholder tegnet “%s” som ikke er tilladt"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Coordinate expression contains floating point number '%s' which could not "
|
||||
#~ "be parsed"
|
||||
#~ msgstr "Koordinatudtryk indeholder kommatallet \"%s\" som ikke kunne tolkes"
|
||||
#~ msgstr "Koordinatudtryk indeholder kommatallet “%s” som ikke kunne tolkes"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Coordinate expression contains integer '%s' which could not be parsed"
|
||||
#~ msgstr "Koordinatudtryk indeholder heltallet \"%s\" som ikke kunne tolkes"
|
||||
#~ msgstr "Koordinatudtryk indeholder heltallet “%s” som ikke kunne tolkes"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Coordinate expression contained unknown operator at the start of this "
|
||||
#~ "text: \"%s\""
|
||||
#~ msgstr ""
|
||||
#~ "Koordinatudtryk indeholdt en ukendt operator i begyndelsen af teksten: "
|
||||
#~ "\"%s\""
|
||||
#~ "“%s”"
|
||||
|
||||
#~ msgid "Coordinate expression was empty or not understood"
|
||||
#~ msgstr "Koordinatudtrykket var tomt eller blev ikke forstået"
|
||||
@ -780,8 +818,7 @@ msgstr "%s (på %s)"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Coordinate expression has an operator \"%s\" where an operand was expected"
|
||||
#~ msgstr ""
|
||||
#~ "Koordinatudtrykket har en operator \"%s\" hvor en operand var ventet"
|
||||
#~ msgstr "Koordinatudtrykket har en operator “%s” hvor en operand var ventet"
|
||||
|
||||
#~ msgid "Coordinate expression had an operand where an operator was expected"
|
||||
#~ msgstr "Koordinatudtrykket havde en operand hvor en operator var ventet"
|
||||
@ -793,11 +830,11 @@ msgstr "%s (på %s)"
|
||||
#~ "Coordinate expression has operator \"%c\" following operator \"%c\" with "
|
||||
#~ "no operand in between"
|
||||
#~ msgstr ""
|
||||
#~ "Koordinatudtrykket har en operator \"%c\" efter en operator \"%c\" og "
|
||||
#~ "ingen operand mellem dem"
|
||||
#~ "Koordinatudtrykket har en operator “%c” efter en operator “%c” og ingen "
|
||||
#~ "operand mellem dem"
|
||||
|
||||
#~ msgid "Coordinate expression had unknown variable or constant \"%s\""
|
||||
#~ msgstr "Koordinatudtrykket havde en ukendt variabel eller konstant \"%s\""
|
||||
#~ msgstr "Koordinatudtrykket havde en ukendt variabel eller konstant “%s”"
|
||||
|
||||
#~ msgid "Coordinate expression parser overflowed its buffer."
|
||||
#~ msgstr "Koordinatudtryksfortolkeren har fået bufferoverløb."
|
||||
@ -833,7 +870,7 @@ msgstr "%s (på %s)"
|
||||
#~ "andet\"/>"
|
||||
|
||||
#~ msgid "Failed to load theme \"%s\": %s\n"
|
||||
#~ msgstr "Kunne ikke indlæse temaet \"%s\": %s\n"
|
||||
#~ msgstr "Kunne ikke indlæse temaet “%s”: %s\n"
|
||||
|
||||
#~ msgid "No <%s> set for theme \"%s\""
|
||||
#~ msgstr "Ingen <%s> angivet for temaet \"%s\""
|
||||
@ -849,10 +886,10 @@ msgstr "%s (på %s)"
|
||||
#~ "User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
#~ msgstr ""
|
||||
#~ "Brugerdefinerede konstanter skal begynde med et stort bogstav; det gør "
|
||||
#~ "\"%s\" ikke"
|
||||
#~ "“%s” ikke"
|
||||
|
||||
#~ msgid "Constant \"%s\" has already been defined"
|
||||
#~ msgstr "Konstanten \"%s\" er allerede defineret"
|
||||
#~ msgstr "Konstanten “%s” er allerede defineret"
|
||||
|
||||
#~ msgid "No \"%s\" attribute on element <%s>"
|
||||
#~ msgstr "Ingen \"%s\"-egenskab i elementet <%s>"
|
||||
@ -867,10 +904,10 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Egenskaben \"%s\" er ugyldig i <%s>-elementet i denne sammenhæng"
|
||||
|
||||
#~ msgid "Could not parse \"%s\" as an integer"
|
||||
#~ msgstr "Kunne ikke fortolke \"%s\" som et heltal"
|
||||
#~ msgstr "Kunne ikke fortolke “%s” som et heltal"
|
||||
|
||||
#~ msgid "Did not understand trailing characters \"%s\" in string \"%s\""
|
||||
#~ msgstr "Forstod ikke de afsluttende tegn \"%s\" i tekststrengen \"%s\""
|
||||
#~ msgstr "Forstod ikke de afsluttende tegn “%s” i tekststrengen “%s”"
|
||||
|
||||
#~ msgid "Integer %ld must be positive"
|
||||
#~ msgstr "Heltallet %ld skal være positivt"
|
||||
@ -879,10 +916,10 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Heltallet %ld er for stort, det nuværende maksimum er %d"
|
||||
|
||||
#~ msgid "Could not parse \"%s\" as a floating point number"
|
||||
#~ msgstr "Kunne ikke fortolke \"%s\" som et kommatal"
|
||||
#~ msgstr "Kunne ikke fortolke “%s” som et kommatal"
|
||||
|
||||
#~ msgid "Boolean values must be \"true\" or \"false\" not \"%s\""
|
||||
#~ msgstr "Booleske værdier skal være \"true\" eller \"false\" ikke \"%s\""
|
||||
#~ msgstr "Booleske værdier skal være “true” eller “false” ikke “%s”"
|
||||
|
||||
#~ msgid "Angle must be between 0.0 and 360.0, was %g\n"
|
||||
#~ msgstr "Vinkel skal være mellem 0.0 og 360.0, var %g\n"
|
||||
@ -896,7 +933,7 @@ msgstr "%s (på %s)"
|
||||
#~ "Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,"
|
||||
#~ "large,x-large,xx-large)\n"
|
||||
#~ msgstr ""
|
||||
#~ "Ugyldig titelskalering \"%s\" (skal være en af xx-small,x-small,small,"
|
||||
#~ "Ugyldig titelskalering “%s” (skal være en af xx-small,x-small,small,"
|
||||
#~ "medium,large,x-large,xx-large)\n"
|
||||
|
||||
#~ msgid "<%s> name \"%s\" used a second time"
|
||||
@ -922,7 +959,7 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Ukendt style_set \"%s\" i <%s>-element"
|
||||
|
||||
#~ msgid "Window type \"%s\" has already been assigned a style set"
|
||||
#~ msgstr "Vinduestypen \"%s\" er allerede blevet tildelt et stilsæt"
|
||||
#~ msgstr "Vinduestypen “%s” er allerede blevet tildelt et stilsæt"
|
||||
|
||||
#~ msgid "Element <%s> is not allowed below <%s>"
|
||||
#~ msgstr "Elementet <%s> er ikke tilladt under <%s>"
|
||||
@ -931,17 +968,17 @@ msgstr "%s (på %s)"
|
||||
#~ "Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio"
|
||||
#~ "\" for buttons"
|
||||
#~ msgstr ""
|
||||
#~ "Kan ikke angive både \"button_width\"/\"button_height\" og \"aspect_ratio"
|
||||
#~ "\" for knapper"
|
||||
#~ "Kan ikke angive både “button_width”/“button_height” og “aspect_ratio” for "
|
||||
#~ "knapper"
|
||||
|
||||
#~ msgid "Distance \"%s\" is unknown"
|
||||
#~ msgstr "Afstanden \"%s\" er ukendt"
|
||||
#~ msgstr "Afstanden “%s” er ukendt"
|
||||
|
||||
#~ msgid "Aspect ratio \"%s\" is unknown"
|
||||
#~ msgstr "Formatforholdet \"%s\" er ukendt"
|
||||
#~ msgstr "Formatforholdet “%s” er ukendt"
|
||||
|
||||
#~ msgid "Border \"%s\" is unknown"
|
||||
#~ msgstr "Kanten \"%s\" er ukendt"
|
||||
#~ msgstr "Kanten “%s” er ukendt"
|
||||
|
||||
#~ msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
|
||||
#~ msgstr "Ingen \"start_angle\"- eller \"from\"-egenskab på elementet <%s>"
|
||||
@ -950,7 +987,7 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Ingen \"extent_angle\"- eller \"to\"-egenskab på elementet <%s>"
|
||||
|
||||
#~ msgid "Did not understand value \"%s\" for type of gradient"
|
||||
#~ msgstr "Forstod ikke værdien \"%s\" for farveovergangstypen"
|
||||
#~ msgstr "Forstod ikke værdien “%s” for farveovergangstypen"
|
||||
|
||||
#~ msgid "Did not understand fill type \"%s\" for <%s> element"
|
||||
#~ msgstr "Forstod ikke fyldtypen \"%s\" for <%s>-elementet"
|
||||
@ -968,10 +1005,10 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Ingen <draw_ops> med navnet \"%s\" er blevet defineret"
|
||||
|
||||
#~ msgid "Including draw_ops \"%s\" here would create a circular reference"
|
||||
#~ msgstr "Medtagelse af draw_ops \"%s\" ville skabe en cirkulær reference"
|
||||
#~ msgstr "Medtagelse af draw_ops “%s” ville skabe en cirkulær reference"
|
||||
|
||||
#~ msgid "Unknown position \"%s\" for frame piece"
|
||||
#~ msgstr "Ukendt position \"%s\" for rammestykke"
|
||||
#~ msgstr "Ukendt position “%s” for rammestykke"
|
||||
|
||||
#~ msgid "Frame style already has a piece at position %s"
|
||||
#~ msgstr "Rammestil har allerede et stykke på position %s"
|
||||
@ -980,28 +1017,28 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Ingen <draw_ops> med navnet \"%s\" er blevet defineret"
|
||||
|
||||
#~ msgid "Unknown function \"%s\" for button"
|
||||
#~ msgstr "Ukendt funktion \"%s\" for knap"
|
||||
#~ msgstr "Ukendt funktion “%s” for knap"
|
||||
|
||||
#~ msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
|
||||
#~ msgstr "Knapfunktionen \"%s\" findes ikke i denne version (%d, kræver %d)"
|
||||
#~ msgstr "Knapfunktionen “%s” findes ikke i denne version (%d, kræver %d)"
|
||||
|
||||
#~ msgid "Unknown state \"%s\" for button"
|
||||
#~ msgstr "Ukendt tilstand \"%s\" for knap"
|
||||
#~ msgstr "Ukendt tilstand “%s” for knap"
|
||||
|
||||
#~ msgid "Frame style already has a button for function %s state %s"
|
||||
#~ msgstr "Rammestil har allerede en knap for funktion %s tilstand %s"
|
||||
|
||||
#~ msgid "\"%s\" is not a valid value for focus attribute"
|
||||
#~ msgstr "\"%s\" er ikke en gyldig værdi for fokusegenskaben"
|
||||
#~ msgstr "“%s” er ikke en gyldig værdi for fokusegenskaben"
|
||||
|
||||
#~ msgid "\"%s\" is not a valid value for state attribute"
|
||||
#~ msgstr "\"%s\" er ikke en gyldig værdi for tilstandsegenskaben"
|
||||
#~ msgstr "“%s” er ikke en gyldig værdi for tilstandsegenskaben"
|
||||
|
||||
#~ msgid "A style called \"%s\" has not been defined"
|
||||
#~ msgstr "En stil ved navn \"%s\" er ikke blevet defineret"
|
||||
#~ msgstr "En stil ved navn “%s” er ikke blevet defineret"
|
||||
|
||||
#~ msgid "\"%s\" is not a valid value for resize attribute"
|
||||
#~ msgstr "\"%s\" er ikke en gyldig værdi for størrelsesændringsegenskaben"
|
||||
#~ msgstr "“%s” er ikke en gyldig værdi for størrelsesændringsegenskaben"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Should not have \"resize\" attribute on <%s> element for maximized/shaded "
|
||||
@ -1049,13 +1086,13 @@ msgstr "%s (på %s)"
|
||||
#~ "draw_ops egenskab og også et <draw_ops>-element, eller angav to elementer)"
|
||||
|
||||
#~ msgid "Bad version specification '%s'"
|
||||
#~ msgstr "Ugyldig versionsangivelse \"%s\""
|
||||
#~ msgstr "Ugyldig versionsangivelse “%s”"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
|
||||
#~ "theme-2.xml"
|
||||
#~ msgstr ""
|
||||
#~ "Egenskaben \"version\" kan ikke bruges i metacity-theme-1.xml eller "
|
||||
#~ "Egenskaben “version” kan ikke bruges i metacity-theme-1.xml eller "
|
||||
#~ "metacity-theme-2.xml"
|
||||
|
||||
#~ msgid ""
|
||||
@ -1119,7 +1156,7 @@ msgstr "%s (på %s)"
|
||||
#~ "binding\n"
|
||||
|
||||
#~ msgid "\"%s\" is not a valid accelerator\n"
|
||||
#~ msgstr "\"%s\" er ikke en gyldig genvej\n"
|
||||
#~ msgstr "“%s” er ikke en gyldig genvej\n"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Workarounds for broken applications disabled. Some applications may not "
|
||||
@ -1130,34 +1167,33 @@ msgstr "%s (på %s)"
|
||||
|
||||
#~ msgid "Could not parse font description \"%s\" from GSettings key %s\n"
|
||||
#~ msgstr ""
|
||||
#~ "Kunne ikke fortolke skrifttypebeskrivelsen \"%s\" fra GSettings-nøglen "
|
||||
#~ "%s\n"
|
||||
#~ "Kunne ikke fortolke skrifttypebeskrivelsen “%s” fra GSettings-nøglen %s\n"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\"%s\" found in configuration database is not a valid value for mouse "
|
||||
#~ "button modifier\n"
|
||||
#~ msgstr ""
|
||||
#~ "\"%s\" fundet i konfigurationsdatabasen er ikke en gyldig værdi som "
|
||||
#~ "“%s” fundet i konfigurationsdatabasen er ikke en gyldig værdi som "
|
||||
#~ "museknapsmodifikation\n"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\"%s\" found in configuration database is not a valid value for "
|
||||
#~ "keybinding \"%s\"\n"
|
||||
#~ msgstr ""
|
||||
#~ "\"%s\" fundet i konfigurationsdatabasen er ikke en gyldig værdi for "
|
||||
#~ "tastebindingen \"%s\"\n"
|
||||
#~ "“%s” fundet i konfigurationsdatabasen er ikke en gyldig værdi for "
|
||||
#~ "tastebindingen “%s”\n"
|
||||
|
||||
#~ msgid "Could not create directory '%s': %s\n"
|
||||
#~ msgstr "Kunne ikke oprette mappen \"%s\": %s\n"
|
||||
#~ msgstr "Kunne ikke oprette mappen “%s”: %s\n"
|
||||
|
||||
#~ msgid "Could not open session file '%s' for writing: %s\n"
|
||||
#~ msgstr "Kunne ikke åbne sessionsfilen \"%s\" til skrivning: %s\n"
|
||||
#~ msgstr "Kunne ikke åbne sessionsfilen “%s” til skrivning: %s\n"
|
||||
|
||||
#~ msgid "Error writing session file '%s': %s\n"
|
||||
#~ msgstr "Fejl under skrivning af sessionsfilen \"%s\": %s\n"
|
||||
#~ msgstr "Fejl under skrivning af sessionsfilen “%s”: %s\n"
|
||||
|
||||
#~ msgid "Error closing session file '%s': %s\n"
|
||||
#~ msgstr "Fejl under lukning af sessionsfilen \"%s\": %s\n"
|
||||
#~ msgstr "Fejl under lukning af sessionsfilen “%s”: %s\n"
|
||||
|
||||
#~ msgid "Failed to parse saved session file: %s\n"
|
||||
#~ msgstr "Kunne ikke fortolke den lagrede sessionsfil: %s\n"
|
||||
@ -1233,7 +1269,7 @@ msgstr "%s (på %s)"
|
||||
#~ "og faktisk har typen %s format %d n_items %d.\n"
|
||||
#~ "Dette er sandsynligvis en fejl i programmet og ikke i "
|
||||
#~ "vindueshåndteringen.\n"
|
||||
#~ "Vinduet har titlen \"%s\", klassen \"%s\" og navnet \"%s\"\n"
|
||||
#~ "Vinduet har titlen “%s”, klassen “%s” og navnet “%s”\n"
|
||||
|
||||
#~ msgid "Property %s on window 0x%lx contained invalid UTF-8\n"
|
||||
#~ msgstr "Egenskaben %s for vinduet 0x%lx indeholdt ugyldig UTF-8\n"
|
||||
@ -1372,10 +1408,10 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Åbn endnu et af disse vinduer"
|
||||
|
||||
#~ msgid "This is a demo button with an 'open' icon"
|
||||
#~ msgstr "Dette er en demoknap med et \"åbn\"-ikon"
|
||||
#~ msgstr "Dette er en demoknap med et “åbn”-ikon"
|
||||
|
||||
#~ msgid "This is a demo button with a 'quit' icon"
|
||||
#~ msgstr "Dette er en demoknap med et \"afslut\"-ikon"
|
||||
#~ msgstr "Dette er en demoknap med et “afslut”-ikon"
|
||||
|
||||
#~ msgid "This is a sample message in a sample dialog"
|
||||
#~ msgstr "Dette er en eksempelbesked i et eksempelmeddelelsevindue"
|
||||
@ -1420,7 +1456,7 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Fejl under indlæsning af tema: %s\n"
|
||||
|
||||
#~ msgid "Loaded theme \"%s\" in %g seconds\n"
|
||||
#~ msgstr "Indlæste tema \"%s\" på %g sekunder\n"
|
||||
#~ msgstr "Indlæste tema “%s” på %g sekunder\n"
|
||||
|
||||
#~ msgid "Normal Title Font"
|
||||
#~ msgstr "Normal titelskrifttype"
|
||||
@ -1593,7 +1629,7 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Vis panelets hovedmenu"
|
||||
|
||||
#~ msgid "Show the panel's \"Run Application\" dialog box"
|
||||
#~ msgstr "Vis panelets \"Kør program\"-vindue"
|
||||
#~ msgstr "Vis panelets “Kør program”-vindue"
|
||||
|
||||
#~ msgid "Start or stop recording the session"
|
||||
#~ msgstr "Start eller stop optagelse af sessionen"
|
||||
@ -1687,13 +1723,13 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Ingen terminal-kommando er blevet defineret.\n"
|
||||
|
||||
#~ msgid "GConf key '%s' is set to an invalid value\n"
|
||||
#~ msgstr "GConf-nøglen \"%s\" er sat til en ugyldig værdi\n"
|
||||
#~ msgstr "GConf-nøglen “%s” er sat til en ugyldig værdi\n"
|
||||
|
||||
#~ msgid "%d stored in GConf key %s is out of range %d to %d\n"
|
||||
#~ msgstr "%d lagret i GConf-nøgle %s er uden for intervallet %d til %d\n"
|
||||
|
||||
#~ msgid "GConf key \"%s\" is set to an invalid type\n"
|
||||
#~ msgstr "GConf-nøglen \"%s\" er sat til en ugyldig type\n"
|
||||
#~ msgstr "GConf-nøglen “%s” er sat til en ugyldig type\n"
|
||||
|
||||
#~ msgid "GConf key %s is already in use and can't be used to override %s\n"
|
||||
#~ msgstr ""
|
||||
@ -1707,11 +1743,11 @@ msgstr "%s (på %s)"
|
||||
#~ msgstr "Fejl under sætning af antallet af arbejdsområder til %d: %s\n"
|
||||
|
||||
#~ msgid "Error setting name for workspace %d to \"%s\": %s\n"
|
||||
#~ msgstr "Fejl under sætning af navnet for arbejdsområde %d til \"%s\": %s\n"
|
||||
#~ msgstr "Fejl under sætning af navnet for arbejdsområde %d til “%s”: %s\n"
|
||||
|
||||
#~ msgid "Error setting live hidden windows status status: %s\n"
|
||||
#~ msgstr "Fejl ved indstilling af status for skjulte levende vinduer: %s\n"
|
||||
|
||||
# (hvad taler de om?)
|
||||
#~ msgid "Error setting no tab popup status: %s\n"
|
||||
#~ msgstr "Fejl ved indstilling af \"intet faneblad\"-popup-status: %s\n"
|
||||
#~ msgstr "Fejl ved indstilling af “intet faneblad”-popup-status: %s\n"
|
||||
|
142
po/el.po
142
po/el.po
@ -18,18 +18,18 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: metacity.gnome-2-26\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2016-09-07 09:27+0000\n"
|
||||
"PO-Revision-Date: 2016-09-15 11:47+0300\n"
|
||||
"Last-Translator: Tom Tryfonidis <tomtryf@gmail.com>\n"
|
||||
"POT-Creation-Date: 2017-02-28 06:20+0000\n"
|
||||
"PO-Revision-Date: 2017-04-07 13:41+0300\n"
|
||||
"Last-Translator: Tom Tryfonidis <tomtryf@gnome.org>\n"
|
||||
"Language-Team: Greek, Modern (1453-) <opensuse-translation-el@opensuse.org>\n"
|
||||
"Language: el\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 1.8.9\n"
|
||||
"X-Generator: Poedit 1.8.11\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: data/50-mutter-navigation.xml:6
|
||||
@ -282,16 +282,15 @@ msgstr "Μετατροπέας για χρήση στις εκτεταμένες
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:8
|
||||
msgid ""
|
||||
"This key will initiate the \"overlay\", which is a combination window "
|
||||
"overview and application launching system. The default is intended to be the "
|
||||
"\"Windows key\" on PC hardware. It's expected that this binding either the "
|
||||
"default or set to the empty string."
|
||||
"This key will initiate the “overlay”, which is a combination window overview "
|
||||
"and application launching system. The default is intended to be the “Windows "
|
||||
"key” on PC hardware. It’s expected that this binding either the default or "
|
||||
"set to the empty string."
|
||||
msgstr ""
|
||||
"Αυτό το πλήκτρο θα ξεκινήσει την \"επικάλυψη\", που είναι συνδυασμένο "
|
||||
"σύστημα επισκόπησης παραθύρων και εκκίνησης εφαρμογών. Η προεπιλογή "
|
||||
"προτίθεται να είναι το \"πλήκτρο Windows\" σε μηχανήματα PC. Αναμένεται ότι "
|
||||
"αυτή η αντιστοίχιση θα είναι είτε η προεπιλογή ή θα ορίζεται στην κενή "
|
||||
"συμβολοσειρά."
|
||||
"Αυτό το πλήκτρο θα ξεκινήσει την «επικάλυψη», που είναι συνδυασμένο σύστημα "
|
||||
"επισκόπησης παραθύρων και εκκίνησης εφαρμογών. Η προεπιλογή προτίθεται να "
|
||||
"είναι το «πλήκτρο Windows» σε μηχανήματα PC. Αναμένεται ότι αυτή η "
|
||||
"αντιστοίχιση θα είναι είτε η προεπιλογή ή θα ορίζεται στην κενή συμβολοσειρά."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:20
|
||||
msgid "Attach modal dialogs"
|
||||
@ -330,7 +329,7 @@ msgstr "Οι χώροι εργασίας διαχειρίζονται δυναμ
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:41
|
||||
msgid ""
|
||||
"Determines whether workspaces are managed dynamically or whether there's a "
|
||||
"Determines whether workspaces are managed dynamically or whether there’s a "
|
||||
"static number of workspaces (determined by the num-workspaces key in org."
|
||||
"gnome.desktop.wm.preferences)."
|
||||
msgstr ""
|
||||
@ -369,13 +368,13 @@ msgstr ""
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:69
|
||||
msgid ""
|
||||
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
|
||||
"the focus will not be changed immediately when entering a window, but only "
|
||||
"after the pointer stops moving."
|
||||
"If set to true, and the focus mode is either “sloppy” or “mouse” then the "
|
||||
"focus will not be changed immediately when entering a window, but only after "
|
||||
"the pointer stops moving."
|
||||
msgstr ""
|
||||
"Αν οριστεί σε αληθής, και η λειτουργία της εστίασης είναι \"sloppy\" ή "
|
||||
"\"mouse\" τότε η εστίαση δεν θα αλλάξει αμέσως όταν ανοίγετε ένα παράθυρο, "
|
||||
"αλλά μόνο όταν ο δείκτης σταματήσει να κινείται."
|
||||
"Αν οριστεί σε αληθής, και η λειτουργία της εστίασης είναι «sloppy» ή «mouse» "
|
||||
"τότε η εστίαση δεν θα αλλάξει αμέσως όταν ανοίγετε ένα παράθυρο, αλλά μόνο "
|
||||
"όταν ο δείκτης σταματήσει να κινείται."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:79
|
||||
msgid "Draggable border width"
|
||||
@ -383,7 +382,7 @@ msgstr "Συρόμενο πλάτος περιγράμματος"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:80
|
||||
msgid ""
|
||||
"The amount of total draggable borders. If the theme's visible borders are "
|
||||
"The amount of total draggable borders. If the theme’s visible borders are "
|
||||
"not enough, invisible borders will be added to meet this value."
|
||||
msgstr ""
|
||||
"Το ποσό των συνολικών συρόμενων περιγραμμάτων. Αν τα περιγράμματα του "
|
||||
@ -472,48 +471,59 @@ msgstr "Εναλλαγή στο VT 11"
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Εναλλαγή στο VT 12"
|
||||
|
||||
#: src/backends/meta-input-settings.c:1707
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:1800
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr "Λειτουργία διακόπτη (ομάδα %d)"
|
||||
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:1822
|
||||
msgid "Switch monitor"
|
||||
msgstr "Εναλλαγή οθόνης"
|
||||
|
||||
#: src/backends/meta-input-settings.c:1709
|
||||
#: src/backends/meta-input-settings.c:1824
|
||||
msgid "Show on-screen help"
|
||||
msgstr "Εμφάνιση βοήθειας στην οθόνη"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:514
|
||||
#: src/backends/meta-monitor-manager.c:675
|
||||
msgid "Built-in display"
|
||||
msgstr "Ενσωματωμένη οθόνη"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:537
|
||||
#: src/backends/meta-monitor-manager.c:698
|
||||
msgid "Unknown"
|
||||
msgstr "Άγνωστη"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:539
|
||||
#: src/backends/meta-monitor-manager.c:700
|
||||
msgid "Unknown Display"
|
||||
msgstr "Άγνωστη οθόνη"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: src/backends/meta-monitor-manager.c:547
|
||||
#: src/backends/meta-monitor-manager.c:708
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: src/compositor/compositor.c:463
|
||||
#: src/compositor/compositor.c:471
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
"Another compositing manager is already running on screen %i on display “%s”."
|
||||
msgstr ""
|
||||
"Εκτελείται ένας άλλος διαχειριστής παραθύρων στην οθόνη %i προβολή \"%s\"."
|
||||
"Εκτελείται ένας άλλος διαχειριστής παραθύρων στην οθόνη %i προβολή «%s»."
|
||||
|
||||
#: src/core/bell.c:194
|
||||
msgid "Bell event"
|
||||
msgstr "Ηχητικό συμβάν κουδουνιού"
|
||||
|
||||
#. Translators: %s is a window title
|
||||
#: src/core/delete.c:127
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
@ -531,53 +541,53 @@ msgstr ""
|
||||
"Μπορείτε να επιλέξετε να περιμένετε λίγο για να συνεχίσει, ή να εξαναγκάσετε "
|
||||
"την εφαρμογή σε έξοδο."
|
||||
|
||||
#: src/core/delete.c:141
|
||||
msgid "_Wait"
|
||||
msgstr "_Αναμονή"
|
||||
|
||||
#: src/core/delete.c:141
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Εξαναγκασμός σε τερματισμό"
|
||||
|
||||
# gconf/gconf-internals.c:2416
|
||||
#: src/core/display.c:590
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Αποτυχία ανοίγματος οθόνης του συστήματος παραθύρων Χ '%s'\n"
|
||||
#: src/core/delete.c:141
|
||||
msgid "_Wait"
|
||||
msgstr "_Αναμονή"
|
||||
|
||||
#: src/core/main.c:182
|
||||
# gconf/gconf-internals.c:2416
|
||||
#: src/core/display.c:608
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr "Αποτυχία ανοίγματος οθόνης του συστήματος παραθύρων Χ «%s»\n"
|
||||
|
||||
#: src/core/main.c:189
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Απενεργοποίηση σύνδεσης στο διαχειριστή συνεδρίας"
|
||||
|
||||
#: src/core/main.c:188
|
||||
#: src/core/main.c:195
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Αντικατάσταση του τρέχοντος διαχειριστή παραθύρων"
|
||||
|
||||
#: src/core/main.c:194
|
||||
#: src/core/main.c:201
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Καθορισμός αναγνωριστικού διαχείρισης συνεδρίας"
|
||||
|
||||
#: src/core/main.c:199
|
||||
#: src/core/main.c:206
|
||||
msgid "X Display to use"
|
||||
msgstr "Εμφάνιση Χ για χρήση"
|
||||
|
||||
#: src/core/main.c:205
|
||||
#: src/core/main.c:212
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Εκκίνηση συνεδρίας από savefile"
|
||||
|
||||
#: src/core/main.c:211
|
||||
#: src/core/main.c:218
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Να καταστούν σύγχρονες οι κλήσεις του X"
|
||||
|
||||
#: src/core/main.c:218
|
||||
#: src/core/main.c:225
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Εκτέλεση ως wayland compositor"
|
||||
|
||||
#: src/core/main.c:224
|
||||
#: src/core/main.c:231
|
||||
msgid "Run as a nested compositor"
|
||||
msgstr "Εκτέλεση ως ενσωματωμένος compositor"
|
||||
|
||||
#: src/core/main.c:232
|
||||
#: src/core/main.c:239
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Εκτέλεση ως διακομιστής πλήρους οθόνης, αντί ενσωματωμένης"
|
||||
|
||||
@ -585,14 +595,13 @@ msgstr "Εκτέλεση ως διακομιστής πλήρους οθόνης
|
||||
#, c-format
|
||||
msgid ""
|
||||
"mutter %s\n"
|
||||
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
|
||||
"Copyright © 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"
|
||||
"Πνευματικά Δικαιώματα (C) 2001-%d Havoc Pennington, Red Hat, Inc., και "
|
||||
"άλλοι\n"
|
||||
"Πνευματικά Δικαιώματα © 2001-%d Havoc Pennington, Red Hat, Inc., και άλλοι\n"
|
||||
"Αυτό είναι ελεύθερο λογισμικό, βλ. τον πηγαίο κώδικα για όρους αντιγραφής.\n"
|
||||
"ΔΕΝ παρέχεται καμία εγγύηση, ούτε ΕΜΠΟΡΕΥΣΙΜΟΤΗΤΑΣ ούτε ΚΑΤΑΛΛΗΛΟΤΗΤΑΣ ΓΙΑ "
|
||||
"ΣΥΓΚΕΚΡΙΜΕΝΟ ΣΚΟΠΟ.\n"
|
||||
@ -610,20 +619,20 @@ msgstr "Πρόσθετα του Mutter για χρήση"
|
||||
msgid "Workspace %d"
|
||||
msgstr "Χώρος εργασίας %d"
|
||||
|
||||
#: src/core/screen.c:521
|
||||
#: src/core/screen.c:580
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
"Display “%s” already has a window manager; try using the --replace option to "
|
||||
"replace the current window manager."
|
||||
msgstr ""
|
||||
"Η προβολή \"%s\" έχει ήδη ένα διαχειριστή παραθύρων· προσπαθήστε να "
|
||||
"Η προβολή «%s» έχει ήδη ένα διαχειριστή παραθύρων· προσπαθήστε να "
|
||||
"χρησιμοποιήσετε την επιλογή --replace για να αντικαταστήσετε τον τρέχων "
|
||||
"διαχειριστή παραθύρων."
|
||||
|
||||
#: src/core/screen.c:606
|
||||
#: src/core/screen.c:665
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Η οθόνη %d στην προβολή '%s' δεν είναι έγκυρη\n"
|
||||
msgid "Screen %d on display “%s” is invalid\n"
|
||||
msgstr "Η οθόνη %d στην προβολή «%s» δεν είναι έγκυρη\n"
|
||||
|
||||
#: src/core/util.c:120
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
@ -631,21 +640,20 @@ msgstr ""
|
||||
"Το Mutter έχει μεταγλωττιστεί χωρίς υποστήριξη για λειτουργία εμφάνισης "
|
||||
"λεπτομερειών\n"
|
||||
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:595
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:563
|
||||
#, c-format
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr "Λειτουργία διακόπτη: Λειτουργία %d"
|
||||
|
||||
#: src/x11/session.c:1815
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
"These windows do not support “save current setup” and will have to be "
|
||||
"restarted manually next time you log in."
|
||||
msgstr ""
|
||||
"Αυτά τα παράθυρα δεν υποστηρίζουν "αποθήκευση της τρέχουσας "
|
||||
"εγκατάστασης" και θα πρέπει να επανεκκινηθούν χειροκίνητα στην επόμενη "
|
||||
"είσοδο σας."
|
||||
"Αυτά τα παράθυρα δεν υποστηρίζουν «αποθήκευση της τρέχουσας εγκατάστασης» "
|
||||
"και θα πρέπει να επανεκκινηθούν χειροκίνητα στην επόμενη είσοδο σας."
|
||||
|
||||
#: src/x11/window-props.c:548
|
||||
#: src/x11/window-props.c:559
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (σε %s)"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user