Compare commits
704 Commits
message-tr
...
2.31.5
Author | SHA1 | Date | |
---|---|---|---|
51caecc1b3 | |||
ef1d3c56d8 | |||
aa8f386b7d | |||
43b751e27a | |||
69fde6822c | |||
b28c4dcd81 | |||
5014d16647 | |||
a5f9039e12 | |||
d9eb4702b2 | |||
a19047fa3a | |||
edba3e843f | |||
e48d119801 | |||
643c7fdb3a | |||
174caf0016 | |||
ab0d57d6ca | |||
a45021bd60 | |||
7b79e2e35c | |||
fdbda8e731 | |||
4c6c6d8658 | |||
c405cce700 | |||
8ade2fc116 | |||
40c7d3763b | |||
71bbd4ed5c | |||
a2617fe06a | |||
d1e1afdaab | |||
a94978db36 | |||
97f883b10e | |||
3af4ca3fe9 | |||
c19c236dbf | |||
6873539846 | |||
d9275d3dda | |||
e8b72a2a59 | |||
a160e31c2a | |||
a84e2e3307 | |||
83689e494c | |||
7c4d4b8695 | |||
771648893f | |||
81aed78a1f | |||
9af979097d | |||
35764fa09e | |||
4b1fea2fa4 | |||
04ecde9f8e | |||
ee79579b2e | |||
0f52c924e2 | |||
9ef2a46e33 | |||
1f550dbc72 | |||
e63a0f3a13 | |||
62b07a5260 | |||
91bcca71c6 | |||
e8fc731fc1 | |||
91e2117708 | |||
4ccff179a5 | |||
bd4aa54e48 | |||
f8b142064b | |||
38f5e30162 | |||
2799327c84 | |||
da4e24555b | |||
7f8f0f2358 | |||
cae61e62fd | |||
ab61017041 | |||
792dc489ee | |||
9baf8e19ea | |||
362fc78dcf | |||
4800a80c3a | |||
d8f7629a4f | |||
7514dfaef9 | |||
c50e324366 | |||
6e09cc5fc8 | |||
eafd3848a9 | |||
942810e88e | |||
df13408973 | |||
bbfc980fe6 | |||
c30b1c9bea | |||
9e554097f3 | |||
302b892dbc | |||
c0134067d7 | |||
a691192ffa | |||
5616a0ae2a | |||
a4befeba53 | |||
e6a70e4676 | |||
016ab1afee | |||
748739ed9c | |||
7fbf8ae4c9 | |||
9914754458 | |||
5a94a1cf3f | |||
afadeef204 | |||
f866707101 | |||
49919acb7c | |||
f76dae5ec8 | |||
bf6d0dc808 | |||
e4a6bf994f | |||
3fe7b13959 | |||
79aeb44bf8 | |||
51478f16ec | |||
528930d0a9 | |||
88be8e87ac | |||
b83d5975b0 | |||
6ca2fd03bd | |||
87e5457095 | |||
cba49959c1 | |||
7c5343a9fb | |||
0e91a213f5 | |||
466f661436 | |||
dad80b3d20 | |||
d96d07af10 | |||
0e40782723 | |||
7cc1cf3b4a | |||
702f596c44 | |||
db45c0920b | |||
d4a8c64d22 | |||
0deffbaaf0 | |||
af3ca027a1 | |||
24a4ca0c6d | |||
e1a109b9be | |||
8aeadcdf9a | |||
68bc5baf12 | |||
8da5c5f50e | |||
084ef99d10 | |||
730681aabc | |||
efd30a0eef | |||
3d60245b18 | |||
ccbf247970 | |||
84efaac52b | |||
8f5aae6df6 | |||
35f27ae150 | |||
d387a2d531 | |||
63d84533c9 | |||
fe91f7fe9e | |||
cc163237cc | |||
4acb082b6e | |||
929bf7f989 | |||
e3eaa69948 | |||
155bee388d | |||
2ca70e9e76 | |||
d31e905978 | |||
a57a34c540 | |||
b3794f1c17 | |||
5b971a66ba | |||
77fcf68ea3 | |||
15dd1164b7 | |||
0eeb62794d | |||
07cfb8d524 | |||
3e2a9a57a1 | |||
a0be7fa455 | |||
a433a1c637 | |||
d05cf2445d | |||
764f5b62f0 | |||
03a0809e39 | |||
f0645d468c | |||
ea3b2a5707 | |||
25eaf2a294 | |||
7bf748c579 | |||
04f33e8dc7 | |||
01c493565f | |||
f1e3104128 | |||
2ace472100 | |||
fff04d51b7 | |||
a1bfaac5a2 | |||
d80c1af1a3 | |||
cbde065a01 | |||
0b1c7320ab | |||
ce3f003e46 | |||
9fca747ef4 | |||
9455554453 | |||
4859eb63c4 | |||
e7220591ba | |||
20d579e7d8 | |||
52a68eb24a | |||
bc57574094 | |||
e4e92a2b38 | |||
023a274e41 | |||
5d0536d732 | |||
08b8b39a5d | |||
c972ff3ab4 | |||
98c2247c1b | |||
a97b8c1947 | |||
1dd2f2c6bc | |||
a9a513c621 | |||
2ce746e7dd | |||
11cde53108 | |||
fe542f8732 | |||
91319d5da2 | |||
5bd7b0dc31 | |||
c8f4adde7f | |||
b6a47cdf76 | |||
8b242dd4bd | |||
9b3e16595b | |||
2179f5836e | |||
320adb316d | |||
db36a90c48 | |||
5cfd72ff8b | |||
1d721c9080 | |||
5de1a15d98 | |||
b02089c435 | |||
ccdc6264da | |||
b736f52037 | |||
1af392b5f0 | |||
84716bccd4 | |||
f438ccfc53 | |||
fdd819e9f6 | |||
a3a09e6b2e | |||
7160e8a137 | |||
016ad69550 | |||
42e9b21b24 | |||
b6e3bf198d | |||
5e3eb5e8c3 | |||
ed1dc4649b | |||
5b586fdf3e | |||
703b21cef0 | |||
c7ec84eb33 | |||
4ce2620b68 | |||
ec6bc8f216 | |||
47a92e7fc0 | |||
e835cd2c2d | |||
6098dca0f8 | |||
21ff050a40 | |||
508001bfde | |||
410dfb2da3 | |||
74ccdbf3a9 | |||
80fc55b8ea | |||
dc424280a1 | |||
7b7c34a399 | |||
865976cfe7 | |||
81a497b476 | |||
dc1a6c746d | |||
27bcce0888 | |||
fdcb73d93e | |||
47dae0832b | |||
78e3126f97 | |||
12e45f275b | |||
7b32888322 | |||
44c2027b40 | |||
a90c81b2c7 | |||
8a25d49319 | |||
014ac2d388 | |||
1e3bf0ea7e | |||
54d11b65a1 | |||
6318c8e95b | |||
8c5bb8655d | |||
75b52d36f2 | |||
5111edb80b | |||
c4406d4ace | |||
3bd2f75866 | |||
6360d8bba6 | |||
f104a329b0 | |||
0e9c47bd56 | |||
2ca1fe3254 | |||
88211ed4bb | |||
266a0fb7d6 | |||
e6b91414de | |||
62afd2ffa3 | |||
37692513cf | |||
35bf6b0d36 | |||
0d1ac8cb5b | |||
b09b30616d | |||
daf133dca8 | |||
ae7f30483d | |||
d6fc2cc36f | |||
082a15bbc5 | |||
2bd64b6cab | |||
b1486f54c8 | |||
39a24b9a6d | |||
6e2ec7291e | |||
b0ba40f812 | |||
50c453c54d | |||
b71afe55d8 | |||
dd0882aa8b | |||
31914ab23b | |||
1816a6339d | |||
e9e2786fa3 | |||
024ab39c6d | |||
1210a78193 | |||
c55dbd5fbd | |||
263261cc86 | |||
077f0c56f1 | |||
e83656969e | |||
7d7ed7ce7a | |||
929073882f | |||
0513297029 | |||
704354be2c | |||
3715109ebe | |||
9d21b2cb25 | |||
7f56d06546 | |||
cf0664fcc6 | |||
26c8227df5 | |||
df43352441 | |||
7d705d4de3 | |||
4a0fbf03a8 | |||
54168fcd31 | |||
5012d64580 | |||
10ac42d6ad | |||
a277dfa9ce | |||
3d6c12121f | |||
98a093a279 | |||
7467e9e3a5 | |||
a7cd294403 | |||
29d89467b9 | |||
dc5dcc6139 | |||
6aaf4b87d5 | |||
4392516713 | |||
a9aa89e858 | |||
58c0abe600 | |||
d42263c1bc | |||
1d2f0e0e15 | |||
752c25bb7d | |||
df09e199b0 | |||
ab75c8cacc | |||
e94d54bffb | |||
5bce103a40 | |||
5ab852bfa3 | |||
439203349d | |||
2320c393c9 | |||
887f0f554b | |||
46c210c314 | |||
b4c3ab6726 | |||
95a6353dee | |||
cfea0649d8 | |||
045faf3f12 | |||
44ede8c942 | |||
1ddb775d59 | |||
cbcbd11ba0 | |||
bae07700a1 | |||
ca13cec01c | |||
f2af295867 | |||
0dffec661a | |||
bab5a006d8 | |||
f89b95c2aa | |||
f262473a3f | |||
b571ad0760 | |||
750672061a | |||
2ca5cfd6f5 | |||
8dd572d1cc | |||
b8647cc00e | |||
a9bdffc9e6 | |||
68723f191c | |||
5eafb29332 | |||
c92ce5983d | |||
fe52a9e1a1 | |||
1a25cd98ea | |||
611ca3c161 | |||
1dd4c7140e | |||
b9e58947cc | |||
73ab59f1d6 | |||
df8b03398f | |||
feaaefd8ba | |||
04200a4281 | |||
c6f84cfa59 | |||
103d0cba20 | |||
095e15fc11 | |||
ca2a11c57d | |||
9423d2c9ac | |||
6461db9df6 | |||
5ff609ed49 | |||
4aa2473d18 | |||
3f5bb8f98d | |||
0487630e03 | |||
d173f9e19d | |||
f53bf17331 | |||
ac54fed8d4 | |||
6deee27d14 | |||
d9f43e27a0 | |||
d1a178301f | |||
8b3d4857aa | |||
8d3abea6ef | |||
5060081db5 | |||
a8fa8a498a | |||
5635797cb9 | |||
468f30e4ab | |||
68b943d8ea | |||
994b4c0007 | |||
f9e4385e02 | |||
909b5ec43c | |||
7c37e94eda | |||
874dd14ddc | |||
d39d7b45e0 | |||
23e11175f8 | |||
aefa8af60e | |||
14a53cc43c | |||
a6be7ad6bd | |||
af05a9e268 | |||
eab96c66fd | |||
2a740448e1 | |||
94472ba9fa | |||
dfb110cd0f | |||
57dd02f6ae | |||
0b1430058a | |||
f2172c088e | |||
b93cb4b976 | |||
6744433245 | |||
01cd42bd51 | |||
bc3b208f41 | |||
049fea477b | |||
0ec4c66f96 | |||
8ad1da0db2 | |||
bd0bd22c63 | |||
e3b839360a | |||
968679f68c | |||
5d0e33e267 | |||
52f1cc6d19 | |||
1b2377370b | |||
5a6c9f176e | |||
a9fea8248c | |||
47644cad6a | |||
b7c6ec4b46 | |||
908b0fb727 | |||
e21aea6e13 | |||
6c13ca817d | |||
38009309e9 | |||
d98db2bd59 | |||
1f274c04fb | |||
ddfe9442fa | |||
8b792f8942 | |||
db96437f18 | |||
a614d72b00 | |||
ec6a6727e0 | |||
cc8a95572e | |||
d1108e1e7d | |||
744bc996db | |||
22bf4c8a93 | |||
46bce04788 | |||
9a2d883cf5 | |||
690deeb502 | |||
367eaf9161 | |||
f0e531310d | |||
cdef8bf5aa | |||
e9a9a5243c | |||
ee57dab846 | |||
9f68786547 | |||
c02b57efc3 | |||
7183aac362 | |||
011db9f34d | |||
7d8c3f1ecd | |||
087ac8470e | |||
3ce89e3c80 | |||
543a41bfea | |||
cb80dc6834 | |||
b55fd735f4 | |||
32fd323153 | |||
3aea09b614 | |||
374fd35476 | |||
20d3b1f8b1 | |||
7de5e78977 | |||
2da6507a87 | |||
5ca665bdde | |||
46f8d913a1 | |||
858a6bf827 | |||
89173544d4 | |||
163b2d0403 | |||
c83883f1f7 | |||
f6cbb14393 | |||
ffd25fe9e4 | |||
524e2ca8e2 | |||
33dca51650 | |||
58bb0044b2 | |||
79865172d3 | |||
730e8ffdf9 | |||
d128cc5af3 | |||
b5c2e1c98c | |||
2016e08f7b | |||
e752193a54 | |||
88a4256ad5 | |||
62ca7fb268 | |||
765779272f | |||
3333f30c42 | |||
732ba8576d | |||
a4481b38d2 | |||
176487834a | |||
394e01850b | |||
5f8391314a | |||
d593877548 | |||
d2bf7ec66c | |||
fe0f4060c4 | |||
40b0459174 | |||
a0b5a44fe9 | |||
5ce1e3fe92 | |||
8b3258cb09 | |||
22948b3d39 | |||
aa7de264e6 | |||
046e0609ab | |||
1a0d507316 | |||
b5853fe7e5 | |||
0f81c7efe0 | |||
0f0e3d9644 | |||
f6b4fa6e7e | |||
fbb88da134 | |||
83f11870da | |||
c635cb7016 | |||
dd23a61dbb | |||
2e00bc4aed | |||
6423cbfc92 | |||
ed3e287d91 | |||
347196d35c | |||
2ab3d069fb | |||
21641d8925 | |||
499c5737da | |||
40a8e9c1a6 | |||
2e98aab2e7 | |||
760b6ad9ed | |||
14434601a3 | |||
ae3d1423e5 | |||
d56fbf6d6a | |||
b7c60b02d1 | |||
d7075d9913 | |||
72cb4bf346 | |||
bffadf1b6e | |||
8552721983 | |||
ec36a0070e | |||
216dafd5b1 | |||
a4feb91644 | |||
778fd72e22 | |||
ff01bf68fd | |||
edbfafc5bd | |||
c20a7d4b01 | |||
c4e0e4197d | |||
71f63962a8 | |||
ef4c9b6f1f | |||
4d43424efd | |||
1f1f4432f6 | |||
98e60eb7e9 | |||
16bdff4f48 | |||
565cdf502c | |||
2dc8d9b462 | |||
ce6dd21cd3 | |||
e7066d12cf | |||
09df6a3818 | |||
17d1e06c7c | |||
e6b80927ad | |||
f9c5202dd1 | |||
a21ba292eb | |||
5429104f04 | |||
bb0a977edc | |||
77ed621c74 | |||
fc39919856 | |||
d8800c095a | |||
e5ba414f2d | |||
b8a9eec14f | |||
059504ca70 | |||
b2db95380b | |||
b6bb26e9ae | |||
126d02ae90 | |||
8d76e362a0 | |||
004cf3da5c | |||
fb9fd6925a | |||
ec725cc6d4 | |||
79fe60e6fb | |||
c793d7d0a4 | |||
1b7c3580e6 | |||
3c3e0b6f20 | |||
fd6863dda4 | |||
690be611ee | |||
18c5405b79 | |||
cfd63c7d4c | |||
49a9335f68 | |||
5b1d52c5e7 | |||
9f43ed3f95 | |||
0770fd5be5 | |||
3c8ba348c2 | |||
b84a7042f1 | |||
8ef75524ea | |||
cec62a7ca5 | |||
77fe0db623 | |||
e86c821878 | |||
02f67af464 | |||
fd310bc7b9 | |||
94d3e27c53 | |||
6aa02c5edc | |||
97e19d7d4a | |||
94f32030e6 | |||
721e1ea863 | |||
5331d3e360 | |||
f52744cfbc | |||
4749393ab5 | |||
975603d608 | |||
99346522e9 | |||
090335ad8b | |||
d8af8f7305 | |||
2a2b597e09 | |||
da1d43fc61 | |||
03a750176b | |||
1d2bb5c51c | |||
60046aaa4f | |||
a6df234528 | |||
5ead0de7ca | |||
229cfd9f80 | |||
01c267b095 | |||
33a6c41810 | |||
7040e9a63b | |||
901eabb82d | |||
b11aa5f676 | |||
ccaa11bb6b | |||
dd0fba4270 | |||
3f6759061d | |||
abc7b1ff02 | |||
75a677701d | |||
11656ebd89 | |||
d62b4cf130 | |||
c4b3d18e26 | |||
38b7904f92 | |||
c89ee2f8f2 | |||
c21e692652 | |||
071efd826c | |||
d27f19a561 | |||
7642040fc0 | |||
67e70df0c9 | |||
fc0acc9e37 | |||
3a7dc32659 | |||
36e761b7a5 | |||
9a1cb9c3db | |||
32e2ff7573 | |||
ea4b1c6c29 | |||
2d574047e4 | |||
8ded91e975 | |||
0b2eeccd4b | |||
fa5b0efdb4 | |||
7555915441 | |||
3e1b1d5789 | |||
8e759d7f32 | |||
caaa543385 | |||
dce4b2f325 | |||
fb7ed1ee28 | |||
a74cef9d2f | |||
c88d21d487 | |||
6f83b39ee4 | |||
f5c4e23c9c | |||
f1fb0d32c6 | |||
ed129b40a3 | |||
fd1ce40ee7 | |||
2b15f38730 | |||
86515f3943 | |||
9afb09128b | |||
e40063fc34 | |||
d20d815b45 | |||
ed36517615 | |||
fa60165764 | |||
3c9d0fbca6 | |||
8d31c2f4dc | |||
eaa1f9a0f4 | |||
3e19f41cba | |||
e6902a1f1c | |||
b1007ed811 | |||
54d385a0a9 | |||
df48e9d1c0 | |||
e3be74a31a | |||
a8aa0c085f | |||
cd78f1158c | |||
d9668bd425 | |||
dc3ff10c6f | |||
31f9da7b8f | |||
05e3a747d0 | |||
8db212db99 | |||
2494cc1637 | |||
ee75355e71 | |||
863f9f285b | |||
d7e0051bc6 | |||
2aa305b51d | |||
4006d7d57f | |||
0a566f70b6 | |||
be2801d1fa | |||
648126e598 | |||
8184b2c57b | |||
337eab614e | |||
20abc4cb99 | |||
5aca0b7704 | |||
74446ce3e0 | |||
7bb14bd8da | |||
ed75f0da63 | |||
d9008054cf | |||
b10d9c9ad7 | |||
5f855045a2 | |||
88737b2083 | |||
a50d64e8e9 | |||
4deef2a9ef | |||
dd9a29633a | |||
4407f0bd65 | |||
73fd896f3c | |||
f8acd0f6f6 | |||
ccc6a23f68 | |||
c236c501e7 | |||
2a0e0ae66f | |||
11276a3505 | |||
c90371d9d5 | |||
038a32330f | |||
fa1fe4fdd1 | |||
59d6029f47 | |||
33b3d05039 | |||
7486c09fbb | |||
3f750a5637 | |||
e54fe59723 | |||
38b20ca0a4 | |||
8c178378ae | |||
341b9a80c5 | |||
45e89bf34a | |||
c17e1249d5 | |||
262f92e0be | |||
da797dff35 | |||
7043215f5e | |||
5202dd5157 | |||
7c4765d053 | |||
69c8aef6c2 | |||
71786e50cf | |||
e5647c4f83 | |||
98a8dd682d | |||
af3b965e00 | |||
2dfe113a42 |
9
.gitignore
vendored
@ -18,12 +18,19 @@ config
|
|||||||
configure
|
configure
|
||||||
data/gnome-shell.desktop
|
data/gnome-shell.desktop
|
||||||
data/gnome-shell.desktop.in
|
data/gnome-shell.desktop.in
|
||||||
|
data/gnome-shell-clock-preferences.desktop
|
||||||
|
data/gnome-shell-clock-preferences.desktop.in
|
||||||
|
data/gschemas.compiled
|
||||||
|
data/org.gnome.shell.gschema.xml
|
||||||
|
data/org.gnome.shell.gschema.valid
|
||||||
intltool-extract.in
|
intltool-extract.in
|
||||||
intltool-merge.in
|
intltool-merge.in
|
||||||
intltool-update.in
|
intltool-update.in
|
||||||
libtool
|
libtool
|
||||||
|
m4/
|
||||||
omf.make
|
omf.make
|
||||||
po/*.gmo
|
po/*.gmo
|
||||||
|
po/gnome-shell.pot
|
||||||
po/Makefile.in.in
|
po/Makefile.in.in
|
||||||
po/POTFILES
|
po/POTFILES
|
||||||
po/stamp-it
|
po/stamp-it
|
||||||
@ -36,9 +43,11 @@ src/Makefile
|
|||||||
src/Makefile.in
|
src/Makefile.in
|
||||||
src/gnomeshell-taskpanel
|
src/gnomeshell-taskpanel
|
||||||
src/gnome-shell
|
src/gnome-shell
|
||||||
|
src/gnome-shell-clock-preferences
|
||||||
src/test-recorder
|
src/test-recorder
|
||||||
src/test-recorder.ogg
|
src/test-recorder.ogg
|
||||||
src/test-theme
|
src/test-theme
|
||||||
|
src/st.h
|
||||||
stamp-h1
|
stamp-h1
|
||||||
tests/run-test.sh
|
tests/run-test.sh
|
||||||
xmldocs.make
|
xmldocs.make
|
||||||
|
20
Makefile.am
@ -1,9 +1,13 @@
|
|||||||
SUBDIRS = data js src tests po
|
# Point to our macro directory and pick up user flags from the environment
|
||||||
|
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||||
|
|
||||||
|
SUBDIRS = data js src tests po man
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
.project \
|
.project \
|
||||||
.settings \
|
.settings \
|
||||||
autogen.sh
|
autogen.sh \
|
||||||
|
tools/check-for-missing.py
|
||||||
|
|
||||||
# These are files checked into Git that we don't want to distribute
|
# These are files checked into Git that we don't want to distribute
|
||||||
DIST_EXCLUDE = \
|
DIST_EXCLUDE = \
|
||||||
@ -14,14 +18,4 @@ DIST_EXCLUDE = \
|
|||||||
|
|
||||||
distcheck-hook:
|
distcheck-hook:
|
||||||
@echo "Checking disted files against files in git"
|
@echo "Checking disted files against files in git"
|
||||||
@failed=false; \
|
@$(srcdir)/tools/check-for-missing.py $(srcdir) $(distdir) $(DIST_EXCLUDE)
|
||||||
exclude=`(for p in $(DIST_EXCLUDE) ; do echo --exclude=$$p ; done)`; \
|
|
||||||
for f in `cd $(srcdir) && git ls-files $$exclude` ; do \
|
|
||||||
if ! test -e $(distdir)/$$f ; then \
|
|
||||||
echo File missing from distribution: $$f ; \
|
|
||||||
failed=true ; \
|
|
||||||
fi \
|
|
||||||
done ; \
|
|
||||||
if $$failed ; then \
|
|
||||||
exit 1 ; \
|
|
||||||
fi
|
|
||||||
|
@ -5,7 +5,6 @@ srcdir=`dirname $0`
|
|||||||
test -z "$srcdir" && srcdir=.
|
test -z "$srcdir" && srcdir=.
|
||||||
|
|
||||||
PKG_NAME="gnome-shell"
|
PKG_NAME="gnome-shell"
|
||||||
REQUIRED_AUTOMAKE_VERSION=1.10
|
|
||||||
|
|
||||||
(test -f $srcdir/configure.ac \
|
(test -f $srcdir/configure.ac \
|
||||||
&& test -d $srcdir/src) || {
|
&& test -d $srcdir/src) || {
|
||||||
@ -15,7 +14,7 @@ REQUIRED_AUTOMAKE_VERSION=1.10
|
|||||||
}
|
}
|
||||||
|
|
||||||
which gnome-autogen.sh || {
|
which gnome-autogen.sh || {
|
||||||
echo "You need to install gnome-common from GNOME Subversion (or from"
|
echo "You need to install gnome-common from GNOME Git (or from"
|
||||||
echo "your OS vendor's package manager)."
|
echo "your OS vendor's package manager)."
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
90
configure.ac
@ -1,33 +1,40 @@
|
|||||||
AC_INIT(gnome-shell, 2.28.1)
|
AC_PREREQ(2.63)
|
||||||
|
AC_INIT([gnome-shell],[2.31.5],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||||
|
|
||||||
AC_CONFIG_AUX_DIR(config)
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
AC_CONFIG_AUX_DIR([config])
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip foreign])
|
AM_INIT_AUTOMAKE([1.10 dist-bzip2 no-dist-gzip foreign])
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
|
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS(config.h)
|
# Checks for programs.
|
||||||
|
|
||||||
AC_DISABLE_STATIC
|
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
# Needed for per-target cflags, like in gnomeshell-taskpanel
|
# Needed for per-target cflags, like in gnomeshell-taskpanel
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
AM_PROG_LIBTOOL
|
|
||||||
|
# Initialize libtool
|
||||||
|
LT_PREREQ([2.2.6])
|
||||||
|
LT_INIT([disable-static])
|
||||||
|
|
||||||
GETTEXT_PACKAGE=gnome-shell
|
GETTEXT_PACKAGE=gnome-shell
|
||||||
AC_SUBST(GETTEXT_PACKAGE)
|
AC_SUBST(GETTEXT_PACKAGE)
|
||||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
|
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
|
||||||
[The prefix for our gettext translation domains.])
|
[The prefix for our gettext translation domains.])
|
||||||
|
|
||||||
PKG_PROG_PKG_CONFIG(0.16)
|
|
||||||
|
|
||||||
IT_PROG_INTLTOOL(0.26)
|
IT_PROG_INTLTOOL(0.26)
|
||||||
AM_GLIB_GNU_GETTEXT
|
AM_GLIB_GNU_GETTEXT
|
||||||
|
|
||||||
|
PKG_PROG_PKG_CONFIG([0.22])
|
||||||
|
|
||||||
|
# GConf stuff
|
||||||
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
|
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
|
||||||
AM_GCONF_SOURCE_2
|
AM_GCONF_SOURCE_2
|
||||||
|
|
||||||
|
GLIB_GSETTINGS
|
||||||
|
|
||||||
# Get a value to substitute into gnome-shell.in
|
# Get a value to substitute into gnome-shell.in
|
||||||
AM_PATH_PYTHON([2.5])
|
AM_PATH_PYTHON([2.5])
|
||||||
AC_SUBST(PYTHON)
|
AC_SUBST(PYTHON)
|
||||||
@ -50,17 +57,40 @@ fi
|
|||||||
|
|
||||||
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
||||||
|
|
||||||
|
CLUTTER_MIN_VERSION=1.2.8
|
||||||
|
GOBJECT_INTROSPECTION_MIN_VERSION=0.6.11
|
||||||
|
GJS_MIN_VERSION=0.7
|
||||||
|
MUTTER_MIN_VERSION=2.31.4
|
||||||
|
GTK_MIN_VERSION=2.90.4
|
||||||
|
GIO_MIN_VERSION=2.25.9
|
||||||
|
|
||||||
# Collect more than 20 libraries for a prize!
|
# Collect more than 20 libraries for a prize!
|
||||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1 mutter-plugins
|
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION
|
||||||
gjs-gi-1.0 libgnome-menu $recorder_modules gconf-2.0
|
gio-unix-2.0 dbus-glib-1
|
||||||
gdk-x11-2.0 clutter-x11-1.0 clutter-glx-1.0
|
gtk+-3.0 >= $GTK_MIN_VERSION
|
||||||
gnome-desktop-2.0 >= 2.26 libstartup-notification-1.0
|
mutter-plugins >= $MUTTER_MIN_VERSION
|
||||||
gobject-introspection-1.0 >= 0.6.5)
|
gjs-gi-1.0 >= $GJS_MIN_VERSION
|
||||||
|
libgnome-menu $recorder_modules gconf-2.0
|
||||||
|
gdk-x11-3.0
|
||||||
|
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
||||||
|
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
||||||
|
libstartup-notification-1.0
|
||||||
|
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION)
|
||||||
|
|
||||||
|
# This is for the newly added application id bits, we can replace this with
|
||||||
|
# a version check later
|
||||||
|
saved_CFLAGS=$CFLAGS
|
||||||
|
saved_LIBS=$LIBS
|
||||||
|
CFLAGS=$MUTTER_PLUGIN_CFLAGS
|
||||||
|
LIBS=$MUTTER_PLUGIN_LIBS
|
||||||
|
AC_CHECK_FUNCS(sn_startup_sequence_get_application_id)
|
||||||
|
CFLAGS=$saved_CFLAGS
|
||||||
|
LIBS=$saved_LIBS
|
||||||
|
|
||||||
PKG_CHECK_MODULES(TIDY, clutter-1.0)
|
PKG_CHECK_MODULES(TIDY, clutter-1.0)
|
||||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-2.0 libcroco-0.6)
|
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 gnome-desktop-3.0 >= 2.90.0)
|
||||||
PKG_CHECK_MODULES(BIG, clutter-1.0 gtk+-2.0 librsvg-2.0)
|
PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-3.0)
|
||||||
PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-2.0)
|
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
||||||
PKG_CHECK_MODULES(TRAY, gtk+-2.0)
|
|
||||||
|
|
||||||
MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
|
MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
|
||||||
# FIXME: metacity-plugins.pc should point directly to its .gir file
|
# FIXME: metacity-plugins.pc should point directly to its .gir file
|
||||||
@ -72,10 +102,13 @@ AC_SUBST(MUTTER_PLUGIN_DIR)
|
|||||||
|
|
||||||
GJS_JS_DIR=`$PKG_CONFIG --variable=jsdir gjs-1.0`
|
GJS_JS_DIR=`$PKG_CONFIG --variable=jsdir gjs-1.0`
|
||||||
GJS_JS_NATIVE_DIR=`$PKG_CONFIG --variable=jsnativedir gjs-1.0`
|
GJS_JS_NATIVE_DIR=`$PKG_CONFIG --variable=jsnativedir gjs-1.0`
|
||||||
|
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
|
||||||
AC_SUBST(GJS_JS_DIR)
|
AC_SUBST(GJS_JS_DIR)
|
||||||
AC_SUBST(GJS_JS_NATIVE_DIR)
|
AC_SUBST(GJS_JS_NATIVE_DIR)
|
||||||
|
AC_SUBST(GJS_CONSOLE)
|
||||||
|
|
||||||
AC_CHECK_FUNCS(fdwalk)
|
AC_CHECK_FUNCS(fdwalk)
|
||||||
|
AC_CHECK_FUNCS(mallinfo)
|
||||||
AC_CHECK_HEADERS([sys/resource.h])
|
AC_CHECK_HEADERS([sys/resource.h])
|
||||||
|
|
||||||
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
|
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
|
||||||
@ -94,8 +127,7 @@ AC_SUBST(TYPELIBDIR)
|
|||||||
# Stay command-line compatible with the gnome-common configure option. Here
|
# Stay command-line compatible with the gnome-common configure option. Here
|
||||||
# minimum/yes/maximum are the same, however.
|
# minimum/yes/maximum are the same, however.
|
||||||
AC_ARG_ENABLE(compile_warnings,
|
AC_ARG_ENABLE(compile_warnings,
|
||||||
AC_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],
|
AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],[Turn on compiler warnings]),,
|
||||||
[Turn on compiler warnings]),,
|
|
||||||
enable_compile_warnings=error)
|
enable_compile_warnings=error)
|
||||||
|
|
||||||
changequote(,)dnl
|
changequote(,)dnl
|
||||||
@ -122,13 +154,25 @@ changequote([,])dnl
|
|||||||
AC_PATH_PROG(mutter, [mutter])
|
AC_PATH_PROG(mutter, [mutter])
|
||||||
AC_SUBST(mutter)
|
AC_SUBST(mutter)
|
||||||
|
|
||||||
AC_OUTPUT([
|
AC_MSG_CHECKING([if mutter was compiled with GTK+-3.0])
|
||||||
|
if $PKG_CONFIG --libs libmutter-private | grep gtk-x11-3 >/dev/null; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
AC_MSG_ERROR([GNOME Shell requires Mutter to be compiled against GTK+-3.0])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
data/Makefile
|
data/Makefile
|
||||||
js/Makefile
|
js/Makefile
|
||||||
js/misc/Makefile
|
js/misc/Makefile
|
||||||
js/ui/Makefile
|
js/ui/Makefile
|
||||||
|
js/perf/Makefile
|
||||||
|
js/prefs/Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
|
man/Makefile
|
||||||
])
|
])
|
||||||
|
AC_OUTPUT
|
||||||
|
@ -1,49 +1,88 @@
|
|||||||
desktopdir=$(datadir)/applications
|
desktopdir=$(datadir)/applications
|
||||||
desktop_DATA = gnome-shell.desktop
|
desktop_DATA = gnome-shell.desktop gnome-shell-clock-preferences.desktop
|
||||||
|
|
||||||
# We substitute in bindir so it works as an autostart
|
# We substitute in bindir so it works as an autostart
|
||||||
# file when built in a non-system prefix
|
# file when built in a non-system prefix
|
||||||
gnome-shell.desktop.in: gnome-shell.desktop.in.in
|
%.desktop.in:%.desktop.in.in
|
||||||
$(AM_V_GEN) sed -e "s|@bindir[@]|$(bindir)|" \
|
$(AM_V_GEN) sed -e "s|@bindir[@]|$(bindir)|" \
|
||||||
-e "s|@VERSION[@]|$(VERSION)|" \
|
-e "s|@VERSION[@]|$(VERSION)|" \
|
||||||
$< > $@ || rm $@
|
$< > $@ || rm $@
|
||||||
|
|
||||||
# Placeholder until we add intltool
|
# Placeholder until we add intltool
|
||||||
gnome-shell.desktop: gnome-shell.desktop.in
|
%.desktop:%.desktop.in
|
||||||
$(AM_V_GEN) sed s/^_// < $< > $@ || rm $@
|
$(AM_V_GEN) sed s/^_// < $< > $@ || rm $@
|
||||||
|
|
||||||
|
dist_pkgdata_DATA = clock-preferences.ui
|
||||||
|
|
||||||
imagesdir = $(pkgdatadir)/images
|
imagesdir = $(pkgdatadir)/images
|
||||||
dist_images_DATA = \
|
dist_images_DATA = \
|
||||||
add-workspace.svg \
|
|
||||||
app-well-glow.png \
|
|
||||||
close-black.svg \
|
close-black.svg \
|
||||||
magnifier.svg \
|
magnifier.svg
|
||||||
remove-workspace.svg
|
|
||||||
|
|
||||||
themedir = $(pkgdatadir)/theme
|
themedir = $(pkgdatadir)/theme
|
||||||
dist_theme_DATA = \
|
dist_theme_DATA = \
|
||||||
theme/gnome-shell.css \
|
theme/add-workspace.svg \
|
||||||
theme/close.svg \
|
|
||||||
theme/close-window.svg \
|
theme/close-window.svg \
|
||||||
theme/scroll-button-down.png \
|
theme/close.svg \
|
||||||
|
theme/corner-ripple.png \
|
||||||
|
theme/dialog-error.svg \
|
||||||
|
theme/gnome-shell.css \
|
||||||
|
theme/mosaic-view-active.svg \
|
||||||
|
theme/mosaic-view.svg \
|
||||||
|
theme/move-window-on-new.svg \
|
||||||
|
theme/process-working.png \
|
||||||
|
theme/remove-workspace.svg \
|
||||||
theme/scroll-button-down-hover.png \
|
theme/scroll-button-down-hover.png \
|
||||||
theme/scroll-button-up.png \
|
theme/scroll-button-down.png \
|
||||||
theme/scroll-button-up-hover.png \
|
theme/scroll-button-up-hover.png \
|
||||||
theme/scroll-vhandle.png \
|
theme/scroll-button-up.png \
|
||||||
theme/section-back.svg \
|
theme/scroll-hhandle.svg \
|
||||||
theme/section-more.svg
|
theme/scroll-vhandle.svg \
|
||||||
|
theme/section-more.svg \
|
||||||
|
theme/section-more-open.svg \
|
||||||
|
theme/separator-white.png \
|
||||||
|
theme/single-view-active.svg \
|
||||||
|
theme/single-view.svg \
|
||||||
|
theme/ws-switch-arrow-left.svg \
|
||||||
|
theme/ws-switch-arrow-right.svg
|
||||||
|
|
||||||
schemadir = @GCONF_SCHEMA_FILE_DIR@
|
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
|
||||||
schema_DATA = gnome-shell.schemas
|
@INTLTOOL_XML_NOMERGE_RULE@
|
||||||
|
@GSETTINGS_RULES@
|
||||||
|
|
||||||
|
# We need to compile schemas at make time
|
||||||
|
# to run from source tree
|
||||||
|
gschemas.compiled: $(gsettings_SCHEMAS:.xml=.valid)
|
||||||
|
$(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) --targetdir=. .
|
||||||
|
|
||||||
|
all-local: gschemas.compiled
|
||||||
|
|
||||||
|
|
||||||
|
# GConf schemas: provide defaults for keys from Metacity we are overriding
|
||||||
|
gconfschemadir = @GCONF_SCHEMA_FILE_DIR@
|
||||||
|
gconfschema_DATA = gnome-shell.schemas
|
||||||
|
|
||||||
|
menudir = $(sysconfdir)/xdg/menus
|
||||||
|
|
||||||
|
menu_DATA = \
|
||||||
|
gs-applications.menu
|
||||||
|
|
||||||
install-data-local:
|
install-data-local:
|
||||||
GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$(schema_DATA)
|
GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$(gconfschema_DATA)
|
||||||
|
|
||||||
EXTRA_DIST = \
|
|
||||||
gnome-shell.desktop.in.in \
|
|
||||||
$(schema_DATA)
|
|
||||||
|
|
||||||
CLEANFILES = \
|
|
||||||
gnome-shell.desktop.in \
|
EXTRA_DIST = \
|
||||||
$(desktop_DATA)
|
gnome-shell.desktop.in.in \
|
||||||
|
gnome-shell-clock-preferences.desktop.in.in \
|
||||||
|
$(menu_DATA) \
|
||||||
|
$(gconfschema_DATA) \
|
||||||
|
org.gnome.shell.gschema.xml.in
|
||||||
|
|
||||||
|
CLEANFILES = \
|
||||||
|
gnome-shell.desktop.in \
|
||||||
|
gnome-shell-clock-preferences.desktop.in \
|
||||||
|
$(desktop_DATA) \
|
||||||
|
$(gsettings_SCHEMAS) \
|
||||||
|
gschemas.compiled
|
||||||
|
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="59.995201"
|
|
||||||
height="59.995102"
|
|
||||||
id="svg3113"
|
|
||||||
sodipodi:version="0.32"
|
|
||||||
inkscape:version="0.46"
|
|
||||||
version="1.0"
|
|
||||||
sodipodi:docname="add-workspace.svg"
|
|
||||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
|
||||||
<defs
|
|
||||||
id="defs3115">
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 526.18109 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
|
||||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
|
||||||
id="perspective3121" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
gridtolerance="10000"
|
|
||||||
guidetolerance="10"
|
|
||||||
objecttolerance="10"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="0.35"
|
|
||||||
inkscape:cx="375"
|
|
||||||
inkscape:cy="520"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:window-width="641"
|
|
||||||
inkscape:window-height="683"
|
|
||||||
inkscape:window-x="4"
|
|
||||||
inkscape:window-y="54" />
|
|
||||||
<metadata
|
|
||||||
id="metadata3118">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-498.57383,-439.50749)">
|
|
||||||
<path
|
|
||||||
id="path3269"
|
|
||||||
d="M 528.57143,439.91129 C 512.23433,439.91129 498.97763,453.16795 498.97763,469.50504 C 498.97763,485.84214 512.23433,499.09881 528.57143,499.09879 C 544.90853,499.09879 558.16513,485.84215 558.16523,469.50504 C 558.16523,453.16794 544.90853,439.9113 528.57143,439.91129 z M 525.29023,451.16129 L 531.88393,451.16129 C 533.75363,451.16129 535.25893,452.66659 535.25893,454.53629 L 535.25893,462.84879 L 543.54023,462.84879 C 545.40973,462.84879 546.91523,464.35409 546.91523,466.22379 L 546.91523,472.81754 C 546.91523,474.68728 545.40993,476.19255 543.54023,476.19254 L 535.25893,476.19254 L 535.25893,484.47379 C 535.25893,486.34353 533.75363,487.8488 531.88393,487.84879 L 525.29023,487.84879 C 523.42053,487.84881 521.91523,486.34351 521.91523,484.47379 L 521.91523,476.19254 L 513.60263,476.19254 C 511.73313,476.19257 510.22773,474.68726 510.22763,472.81754 L 510.22763,466.22379 C 510.22763,464.35407 511.73303,462.8488 513.60263,462.84879 L 521.91523,462.84879 L 521.91523,454.53629 C 521.91523,452.66657 523.42043,451.1613 525.29023,451.16129 z"
|
|
||||||
style="opacity:0.30701785;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.807603px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.6 KiB |
188
data/clock-preferences.ui
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<interface domain="gnome-shell">
|
||||||
|
<requires lib="gtk+" version="2.16"/>
|
||||||
|
<!-- interface-naming-policy project-wide -->
|
||||||
|
<object class="GtkDialog" id="prefs-dialog">
|
||||||
|
<property name="border_width">5</property>
|
||||||
|
<property name="title" translatable="yes">Clock Preferences</property>
|
||||||
|
<property name="window_position">center</property>
|
||||||
|
<property name="type_hint">normal</property>
|
||||||
|
<property name="has_separator">False</property>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkVBox" id="dialog-vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">2</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">18</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkFrame" id="frame1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<property name="shadow_type">none</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkAlignment" id="alignment1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="top_padding">6</property>
|
||||||
|
<property name="left_padding">12</property>
|
||||||
|
<property name="right_padding">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHBox" id="hbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkRadioButton" id="12hr_radio">
|
||||||
|
<property name="label" translatable="yes">_12 hour format</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkRadioButton" id="24hr_radio">
|
||||||
|
<property name="label" translatable="yes">_24 hour format</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<property name="group">12hr_radio</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="label">
|
||||||
|
<object class="GtkLabel" id="label_format">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Clock Format</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="weight" value="bold"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkFrame" id="frame2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<property name="shadow_type">none</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkAlignment" id="alignment2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="top_padding">6</property>
|
||||||
|
<property name="left_padding">12</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="vbox2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="date_check">
|
||||||
|
<property name="label" translatable="yes">Show the _date</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="seconds_check">
|
||||||
|
<property name="label" translatable="yes">Show seco_nds</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="label">
|
||||||
|
<object class="GtkLabel" id="label_display">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Panel Display</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="weight" value="bold"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">6</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="prefs_close_button">
|
||||||
|
<property name="label">gtk-close</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<action-widgets>
|
||||||
|
<action-widget response="0">prefs_close_button</action-widget>
|
||||||
|
</action-widgets>
|
||||||
|
</object>
|
||||||
|
</interface>
|
@ -62,5 +62,5 @@
|
|||||||
clip-rule="evenodd"
|
clip-rule="evenodd"
|
||||||
d="M10.5,3.5l2,2L10,8l2.5,2.5l-2,2L8,10l-2.5,2.5l-2-2L6,8L3.5,5.5l2-2L8,6L10.5,3.5 z M0,8c0-4.418,3.582-8,8-8s8,3.582,8,8s-3.582,8-8,8S0,12.418,0,8z"
|
d="M10.5,3.5l2,2L10,8l2.5,2.5l-2,2L8,10l-2.5,2.5l-2-2L6,8L3.5,5.5l2-2L8,6L10.5,3.5 z M0,8c0-4.418,3.582-8,8-8s8,3.582,8,8s-3.582,8-8,8S0,12.418,0,8z"
|
||||||
id="path2394"
|
id="path2394"
|
||||||
style="fill-opacity:1;fill:#000000" />
|
style="fill-opacity:1;fill:#545454" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
15
data/gnome-shell-clock-preferences.desktop.in.in
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
_Name=Clock
|
||||||
|
_Comment=Customize the panel clock
|
||||||
|
Exec=@bindir@/gnome-shell-clock-preferences
|
||||||
|
Icon=gnome-panel-clock
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
StartupNotify=true
|
||||||
|
Categories=GNOME;GTK;Settings;DesktopSettings;
|
||||||
|
OnlyShowIn=GNOME;
|
||||||
|
X-GNOME-ShellOnly=true
|
||||||
|
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||||
|
X-GNOME-Bugzilla-Product=gnome-shell
|
||||||
|
X-GNOME-Bugzilla-Component=general
|
||||||
|
X-GNOME-Bugzilla-Version=@VERSION@
|
@ -1,108 +1,226 @@
|
|||||||
<gconfschemafile>
|
<gconfschemafile>
|
||||||
<schemalist>
|
<schemalist>
|
||||||
|
|
||||||
|
<!-- Metacity overrides -->
|
||||||
<schema>
|
<schema>
|
||||||
<key>/schemas/desktop/gnome/shell/development_tools</key>
|
<key>/schemas/desktop/gnome/shell/windows/button_layout</key>
|
||||||
<applyto>/desktop/gnome/shell/development_tools</applyto>
|
<applyto>/desktop/gnome/shell/windows/button_layout</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>string</type>
|
||||||
|
<default>:minimize,maximize,close</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Arrangement of buttons on the titlebar</short>
|
||||||
|
<long>
|
||||||
|
Arrangement of buttons on the titlebar. The
|
||||||
|
value should be a string, such as
|
||||||
|
"menu:minimize,maximize,spacer,close"; the colon separates the
|
||||||
|
left corner of the window from the right corner, and
|
||||||
|
the button names are comma-separated. Duplicate buttons
|
||||||
|
are not allowed. Unknown button names are silently ignored
|
||||||
|
so that buttons can be added in future gnome-shell versions
|
||||||
|
without breaking older versions.
|
||||||
|
A special spacer tag can be used to insert some space between
|
||||||
|
two adjacent buttons.
|
||||||
|
|
||||||
|
This key overrides /apps/metacity/general/button_layout when
|
||||||
|
running GNOME Shell.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<!-- Magnifier -->
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/show_magnifier</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/show_magnifier</applyto>
|
||||||
<owner>gnome-shell</owner>
|
<owner>gnome-shell</owner>
|
||||||
<type>bool</type>
|
<type>bool</type>
|
||||||
<default>true</default>
|
<default>false</default>
|
||||||
<locale name="C">
|
<locale name="C">
|
||||||
<short>Enable internal tools useful for developers and testers from Alt-F2</short>
|
<short>Show or hide the magnifier</short>
|
||||||
<long>
|
<long>
|
||||||
Allows access to internal debugging and monitoring tools using
|
Show or hide the magnifier and all of its zoom regions.
|
||||||
the Alt-F2 dialog.
|
|
||||||
</long>
|
</long>
|
||||||
</locale>
|
</locale>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
<schema>
|
<schema>
|
||||||
<key>/schemas/desktop/gnome/shell/app_monitor/enable_monitoring</key>
|
<key>/schemas/desktop/gnome/accessibility/magnifier/mouse_tracking</key>
|
||||||
<applyto>/desktop/gnome/shell/app_monitor/enable_monitoring</applyto>
|
<applyto>/desktop/gnome/accessibility/magnifier/mouse_tracking</applyto>
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>bool</type>
|
|
||||||
<default>true</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>Whether to collect stats about applications usage</short>
|
|
||||||
<long>
|
|
||||||
The shell normally monitors active applications in order to present the most used ones (e.g. in launchers). While this data will be kept private, you may want to disable this for privacy reasons. Please note that doing so won't remove already saved data.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/favorite_apps</key>
|
|
||||||
<applyto>/desktop/gnome/shell/favorite_apps</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>list</type>
|
|
||||||
<list_type>string</list_type>
|
|
||||||
<default>[mozilla-firefox.desktop,evolution.desktop,openoffice.org-writer.desktop]</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>List of desktop file IDs for favorite applications</short>
|
|
||||||
<long>
|
|
||||||
The applications corresponding to these identifiers will be displayed in the favorites area.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/sidebar/visible</key>
|
|
||||||
<applyto>/desktop/gnome/shell/sidebar/visible</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>bool</type>
|
|
||||||
<default>false</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>Whether or not to display the sidebar</short>
|
|
||||||
<long>
|
|
||||||
Determines whether or not the sidebar is visible.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/sidebar/expanded</key>
|
|
||||||
<applyto>/desktop/gnome/shell/sidebar/expanded</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>bool</type>
|
|
||||||
<default>true</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>Whether the sidebar should be in the expanded (wide) mode</short>
|
|
||||||
<long>
|
|
||||||
Controls the expanded/collapsed state of the sidebar.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/sidebar/widgets</key>
|
|
||||||
<applyto>/desktop/gnome/shell/sidebar/widgets</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>list</type>
|
|
||||||
<list_type>string</list_type>
|
|
||||||
<default>[imports.ui.widget.ClockWidget,imports.ui.widget.AppsWidget,imports.ui.widget.RecentDocsWidget]</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>The widgets to display in the sidebar</short>
|
|
||||||
<long>
|
|
||||||
The widgets to display in the sidebar, in order from top to bottom. Each widget "name" is actually a JavaScript expression referring to a widget constructor object.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/disabled_extensions</key>
|
|
||||||
<applyto>/desktop/gnome/shell/disabled_extensions</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
<owner>gnome-shell</owner>
|
||||||
<type>list</type>
|
<type>int</type>
|
||||||
<list_type>string</list_type>
|
<default>1</default>
|
||||||
<default>[]</default>
|
|
||||||
<locale name="C">
|
<locale name="C">
|
||||||
<short>Uuids of extensions to disable</short>
|
<short>Mouse Tracking Mode</short>
|
||||||
<long>
|
<long>
|
||||||
GNOME Shell extensions have a uuid property; this key lists extensions which should not be loaded.
|
Determines the position of the magnified mouse image within
|
||||||
</long>
|
the magnified view and how it reacts to system mouse movement.
|
||||||
|
The values are 0 - none: no mouse tracking; 1 - centered: the
|
||||||
|
mouse image is displayed at the center of the zoom region
|
||||||
|
(which also represents the point under the system mouse) and the
|
||||||
|
magnified contents are scrolled as the system mouse moves; 2 -
|
||||||
|
proportional: the position of the magnified mouse in the zoom
|
||||||
|
region is proportionally the same as the position of the system
|
||||||
|
mouse on screen; or 3 - push: when the magnified mouse
|
||||||
|
intersects a boundary of the zoom region, the contents are
|
||||||
|
scrolled into view.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/screen_position</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/screen_position</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>int</type>
|
||||||
|
<default>3</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Screen position</short>
|
||||||
|
<long>
|
||||||
|
The magnified view either fills the entire screen (1), or
|
||||||
|
occupies the top-half (2), bottom-half (3), left-half (4), or
|
||||||
|
right-half (5) of the screen.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/mag_factor</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/mag_factor</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>float</type>
|
||||||
|
<default>2.0</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Magnification factor</short>
|
||||||
|
<long>
|
||||||
|
The power of the magnification. A value of 1.0 means no
|
||||||
|
magnification. A value of 2.0 doubles the size.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/lens_mode</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/lens_mode</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>bool</type>
|
||||||
|
<default>false</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Enable lens mode</short>
|
||||||
|
<long>
|
||||||
|
Whether the magnified view should be centered over the location
|
||||||
|
of the system mouse and move with it.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/scroll_at_edges</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/scroll_at_edges</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>bool</type>
|
||||||
|
<default>false</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Scroll magnified contents beyond the edges of the desktop</short>
|
||||||
|
<long>
|
||||||
|
For centered mouse tracking, when the system pointer is at
|
||||||
|
or near the edge of the screen, the magnified contents continue
|
||||||
|
to scroll such that the screen edge moves into the magnified
|
||||||
|
view.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<!-- Magnifier: Crosshairs -->
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/show_cross_hairs</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/show_cross_hairs</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>bool</type>
|
||||||
|
<default>false</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Show or hide crosshairs</short>
|
||||||
|
<long>
|
||||||
|
Enables/disables display of crosshairs centered on the magnified mouse
|
||||||
|
sprite.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_thickness</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_thickness</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>int</type>
|
||||||
|
<default>8</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Thickness of the crosshairs</short>
|
||||||
|
<long>
|
||||||
|
Width of the vertical and horizontal lines that make up the
|
||||||
|
crosshairs.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_color</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_color</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>string</type>
|
||||||
|
<default>#ff0000</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Color of the crosshairs</short>
|
||||||
|
<long>
|
||||||
|
The color of the the vertical and horizontal lines that make up
|
||||||
|
the crosshairs.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_opacity</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_opacity</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>int</type>
|
||||||
|
<default>169</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Opacity of the crosshairs</short>
|
||||||
|
<long>
|
||||||
|
Determines the transparency of the crosshairs, from fully opaque
|
||||||
|
to fully transparent.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_length</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_length</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>int</type>
|
||||||
|
<default>4096</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Length of the crosshairs</short>
|
||||||
|
<long>
|
||||||
|
Determines the length of the vertical and horizontal lines that
|
||||||
|
make up the crosshairs.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_clip</key>
|
||||||
|
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_clip</applyto>
|
||||||
|
<owner>gnome-shell</owner>
|
||||||
|
<type>bool</type>
|
||||||
|
<default>false</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Clip the crosshairs at the center</short>
|
||||||
|
<long>
|
||||||
|
Determines whether the crosshairs intersect the magnified mouse
|
||||||
|
sprite, or are clipped such that the ends of the horizontal
|
||||||
|
and vertical lines surround the mouse image.
|
||||||
|
</long>
|
||||||
</locale>
|
</locale>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
</schemalist>
|
</schemalist>
|
||||||
|
|
||||||
</gconfschemafile>
|
</gconfschemafile>
|
||||||
|
44
data/gs-applications.menu
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<Menu>
|
||||||
|
<DefaultLayout>
|
||||||
|
<Menuname>Apps</Menuname>
|
||||||
|
<Menuname>Games</Menuname>
|
||||||
|
<Menuname>Tools</Menuname>
|
||||||
|
</DefaultLayout>
|
||||||
|
<Name>Applications</Name>
|
||||||
|
<DefaultAppDirs/>
|
||||||
|
<Menu>
|
||||||
|
<Name>Games</Name>
|
||||||
|
<Include>
|
||||||
|
<And>
|
||||||
|
<Category>Game</Category>
|
||||||
|
</And>
|
||||||
|
</Include>
|
||||||
|
</Menu>
|
||||||
|
<Menu>
|
||||||
|
<Name>Tools</Name>
|
||||||
|
<Include>
|
||||||
|
<Category>Development</Category>
|
||||||
|
<And>
|
||||||
|
<Category>System</Category>
|
||||||
|
<Not>
|
||||||
|
<Category>Settings</Category>
|
||||||
|
</Not>
|
||||||
|
</And>
|
||||||
|
<Category>Utility</Category>
|
||||||
|
</Include>
|
||||||
|
</Menu>
|
||||||
|
<Menu>
|
||||||
|
<Name>Apps</Name>
|
||||||
|
<OnlyUnallocated/>
|
||||||
|
<Include>
|
||||||
|
<And>
|
||||||
|
<Or>
|
||||||
|
<Category>Documentation</Category>
|
||||||
|
<Not><Category>Core</Category></Not>
|
||||||
|
</Or>
|
||||||
|
<Not><Category>Settings</Category></Not>
|
||||||
|
<Not><Category>Screensaver</Category></Not>
|
||||||
|
</And>
|
||||||
|
</Include>
|
||||||
|
</Menu>
|
||||||
|
</Menu>
|
158
data/org.gnome.shell.gschema.xml.in
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<schemalist>
|
||||||
|
<schema id="org.gnome.shell" path="/apps/gnome-shell/"
|
||||||
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
|
<key name="development-tools" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<_summary>
|
||||||
|
Enable internal tools useful for developers and testers from Alt-F2
|
||||||
|
</_summary>
|
||||||
|
<_description>
|
||||||
|
Allows access to internal debugging and monitoring tools
|
||||||
|
using the Alt-F2 dialog.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="disabled-extensions" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<_summary>Uuids of extensions to disable</_summary>
|
||||||
|
<_description>
|
||||||
|
GNOME Shell extensions have a uuid property;
|
||||||
|
this key lists extensions which should not be loaded.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="enable-app-monitoring" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<_summary>Whether to collect stats about applications usage</_summary>
|
||||||
|
<_description>
|
||||||
|
The shell normally monitors active applications in order to present
|
||||||
|
the most used ones (e.g. in launchers). While this data will be
|
||||||
|
kept private, you may want to disable this for privacy reasons.
|
||||||
|
Please note that doing so won't remove already saved data.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="favorite-apps" type="as">
|
||||||
|
<default>[ 'mozilla-firefox.desktop', 'evolution.desktop', 'openoffice.org-writer.desktop' ]</default>
|
||||||
|
<_summary>List of desktop file IDs for favorite applications</_summary>
|
||||||
|
<_description>
|
||||||
|
The applications corresponding to these identifiers
|
||||||
|
will be displayed in the favorites area.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="command-history" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<_summary>History for command (Alt-F2) dialog</_summary>
|
||||||
|
</key>
|
||||||
|
<key name="workspaces-view" type="s">
|
||||||
|
<default>'single'</default>
|
||||||
|
<_summary>Overview workspace view mode</_summary>
|
||||||
|
<_description>
|
||||||
|
The selected workspace view mode in the overview.
|
||||||
|
Supported values are "single" and "grid".
|
||||||
|
</_description>
|
||||||
|
<choices>
|
||||||
|
<choice value="single"/>
|
||||||
|
<choice value="grid"/>
|
||||||
|
</choices>
|
||||||
|
</key>
|
||||||
|
<child name="clock" schema="org.gnome.shell.clock"/>
|
||||||
|
<child name="calendar" schema="org.gnome.shell.calendar"/>
|
||||||
|
<child name="recorder" schema="org.gnome.shell.recorder"/>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema id="org.gnome.shell.calendar" path="/apps/gnome-shell/calendar/"
|
||||||
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
|
<key name="show-weekdate" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<_summary>Show the week date in the calendar</_summary>
|
||||||
|
<_description>
|
||||||
|
If true, display the ISO week date in the calendar.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema id="org.gnome.shell.clock" path="/apps/gnome-shell/clock/"
|
||||||
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
|
<key name="format" type="s">
|
||||||
|
<default l10n="messages" context="hour_format">
|
||||||
|
<!-- TRANSLATORS: This is the default hour format, choose ONLY '12-hour' or '24-hour'. -->
|
||||||
|
"12-hour"
|
||||||
|
</default>
|
||||||
|
<_summary>Hour format</_summary>
|
||||||
|
<_description>
|
||||||
|
This key specifies the hour format used by the panel clock.
|
||||||
|
Possible values are "12-hour", "24-hour", "unix" and "custom". If set
|
||||||
|
to "unix", the clock will display time in seconds since Epoch,
|
||||||
|
i.e. 1970-01-01. If set to "custom", the clock will display time
|
||||||
|
according to the format specified in the custom_format key. Note that
|
||||||
|
if set to either "unix" or "custom", the show_date and show_seconds
|
||||||
|
keys are ignored.
|
||||||
|
</_description>
|
||||||
|
<choices>
|
||||||
|
<choice value="12-hour"/>
|
||||||
|
<choice value="24-hour"/>
|
||||||
|
<choice value="unix"/>
|
||||||
|
<choice value="custom"/>
|
||||||
|
</choices>
|
||||||
|
</key>
|
||||||
|
<key name="custom-format" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<_summary>Custom format of the clock</_summary>
|
||||||
|
<_description>
|
||||||
|
This key specifies the format used by the panel clock when the format
|
||||||
|
key is set to "custom". You can use conversion specifiers understood
|
||||||
|
by strftime() to obtain a specific format. See the strftime() manual
|
||||||
|
for more information.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="show-seconds" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<_summary>Show time with seconds</_summary>
|
||||||
|
<_description>
|
||||||
|
If true and format is either "12-hour" or "24-hour", display seconds in time.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="show-date" type="b">
|
||||||
|
<default>false</default>
|
||||||
|
<_summary>Show date in clock</_summary>
|
||||||
|
<_description>
|
||||||
|
If true and format is either "12-hour" or "24-hour",
|
||||||
|
display date in the clock, in addition to time.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema id="org.gnome.shell.recorder" path="/apps/gnome-shell/recorder/"
|
||||||
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
|
<key name="framerate" type="i">
|
||||||
|
<default>15</default>
|
||||||
|
<_summary>Framerate used for recording screencasts.</_summary>
|
||||||
|
<_description>
|
||||||
|
The framerate of the resulting screencast recordered
|
||||||
|
by GNOME Shell's screencast recorder in frames-per-second.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="pipeline" type="s">
|
||||||
|
<default>''</default>
|
||||||
|
<_summary>The gstreamer pipeline used to encode the screencast</_summary>
|
||||||
|
<_description>
|
||||||
|
Sets the GStreamer pipeline used to encode recordings.
|
||||||
|
It follows the syntax used for gst-launch. The pipeline should have
|
||||||
|
an unconnected sink pad where the recorded video is recorded. It will
|
||||||
|
normally have a unconnected source pad; output from that pad
|
||||||
|
will be written into the output file. However the pipeline can also
|
||||||
|
take care of its own output - this might be used to send the output
|
||||||
|
to an icecast server via shout2send or similar. When unset or set
|
||||||
|
to an empty value, the default pipeline will be used. This is currently
|
||||||
|
'videorate ! theoraenc ! oggmux' and records to Ogg Theora.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
<key name="file-extension" type="s">
|
||||||
|
<default>'ogv'</default>
|
||||||
|
<_summary>File extension used for storing the screencast</_summary>
|
||||||
|
<_description>
|
||||||
|
The filename for recorded screencasts will be a unique filename
|
||||||
|
based on the current date, and use this extension. It should be
|
||||||
|
changed when recording to a different container format.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
@ -1,71 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="59.995201"
|
|
||||||
height="59.995102"
|
|
||||||
id="svg3113"
|
|
||||||
sodipodi:version="0.32"
|
|
||||||
inkscape:version="0.46"
|
|
||||||
version="1.0"
|
|
||||||
sodipodi:docname="remove-workspace.svg"
|
|
||||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
|
||||||
<defs
|
|
||||||
id="defs3115">
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 526.18109 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
|
||||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
|
||||||
id="perspective3121" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
gridtolerance="10000"
|
|
||||||
guidetolerance="10"
|
|
||||||
objecttolerance="10"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="4.5"
|
|
||||||
inkscape:cx="-8.1974244"
|
|
||||||
inkscape:cy="38.948933"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:window-width="1400"
|
|
||||||
inkscape:window-height="971"
|
|
||||||
inkscape:window-x="454"
|
|
||||||
inkscape:window-y="105" />
|
|
||||||
<metadata
|
|
||||||
id="metadata3118">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-498.57383,-439.50749)">
|
|
||||||
<path
|
|
||||||
style="opacity:0.30701785;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.807603px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
|
|
||||||
d="M 30 0.40625 C 13.662899 0.40624999 0.40625 13.66291 0.40625 30 C 0.40624999 46.337101 13.6629 59.59377 30 59.59375 C 46.337099 59.593749 59.59365 46.33711 59.59375 30 C 59.59375 13.662901 46.3371 0.40626 30 0.40625 z M 15.03125 23.34375 L 44.96875 23.34375 C 46.83825 23.343751 48.34375 24.84905 48.34375 26.71875 L 48.34375 33.3125 C 48.34375 35.182239 46.83845 36.68751 44.96875 36.6875 L 15.03125 36.6875 C 13.16175 36.687529 11.65635 35.18222 11.65625 33.3125 L 11.65625 26.71875 C 11.65625 24.849031 13.16165 23.34376 15.03125 23.34375 z "
|
|
||||||
transform="translate(498.57383,439.50749)"
|
|
||||||
id="path2382" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.8 KiB |
98
data/theme/add-workspace.svg
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="23"
|
||||||
|
height="15"
|
||||||
|
id="svg6375"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47pre4 r22446"
|
||||||
|
sodipodi:docname="New document 13">
|
||||||
|
<defs
|
||||||
|
id="defs6377">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 16 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="32 : 16 : 1"
|
||||||
|
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||||
|
id="perspective6383" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective6366"
|
||||||
|
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||||
|
inkscape:vp_z="1 : 0.5 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 0.5 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.197802"
|
||||||
|
inkscape:cx="16"
|
||||||
|
inkscape:cy="16"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1680"
|
||||||
|
inkscape:window-height="997"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata6380">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="translate(0,-17)">
|
||||||
|
<g
|
||||||
|
style="display:inline"
|
||||||
|
id="g6243"
|
||||||
|
transform="translate(-986.28859,-658.2796)">
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:0.98770495;stroke:#666666;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||||
|
id="rect5318"
|
||||||
|
width="22"
|
||||||
|
height="14"
|
||||||
|
x="986.89801"
|
||||||
|
y="675.86743"
|
||||||
|
rx="0.49999979"
|
||||||
|
ry="0.5" />
|
||||||
|
<g
|
||||||
|
id="g5320"
|
||||||
|
transform="translate(402.77304,-12.882544)">
|
||||||
|
<path
|
||||||
|
id="path5322"
|
||||||
|
d="m 595.125,692.53048 0,6.43903"
|
||||||
|
style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
id="path5324"
|
||||||
|
d="m 598.34451,695.75 -6.43902,0"
|
||||||
|
style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
BIN
data/theme/corner-ripple.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
222
data/theme/dialog-error.svg
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
id="svg4908"
|
||||||
|
sodipodi:version="0.32"
|
||||||
|
inkscape:version="0.47 r22583"
|
||||||
|
sodipodi:docname="dialog-error.svg"
|
||||||
|
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||||
|
inkscape:export-filename="/home/andreas/project/gnome-icon-theme/scalable/actions/process-stop.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90"
|
||||||
|
version="1.0">
|
||||||
|
<defs
|
||||||
|
id="defs4910">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 24 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="48 : 24 : 1"
|
||||||
|
inkscape:persp3d-origin="24 : 16 : 1"
|
||||||
|
id="perspective25" />
|
||||||
|
<radialGradient
|
||||||
|
gradientTransform="matrix(1.349881,0,0,1.349881,-3.498814,-1.810859)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
r="9.7183542"
|
||||||
|
fy="4.9892726"
|
||||||
|
fx="9.6893959"
|
||||||
|
cy="4.9892726"
|
||||||
|
cx="9.6893959"
|
||||||
|
id="radialGradient5177"
|
||||||
|
xlink:href="#linearGradient5171"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
gradientTransform="matrix(2.417917,0,0,2.417917,-14.17917,-4.903184)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
r="9.7785711"
|
||||||
|
fy="3.458019"
|
||||||
|
fx="10"
|
||||||
|
cy="3.458019"
|
||||||
|
cx="10"
|
||||||
|
id="radialGradient5157"
|
||||||
|
xlink:href="#linearGradient5151"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.928125,0,0,0.3143011,0.7718789,12.358015)"
|
||||||
|
r="9.0598059"
|
||||||
|
fy="18.022524"
|
||||||
|
fx="10.739184"
|
||||||
|
cy="18.022524"
|
||||||
|
cx="10.739184"
|
||||||
|
id="radialGradient5145"
|
||||||
|
xlink:href="#linearGradient5139"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient5139"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop5141"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:black;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop5143"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:black;stop-opacity:0;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient5151"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop5153"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:white;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop5155"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:white;stop-opacity:0;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient5171">
|
||||||
|
<stop
|
||||||
|
id="stop5173"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#fe3a00;stop-opacity:1" />
|
||||||
|
<stop
|
||||||
|
id="stop5175"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#c00;stop-opacity:1;" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="22.627417"
|
||||||
|
inkscape:cx="24.442987"
|
||||||
|
inkscape:cy="10.142308"
|
||||||
|
inkscape:current-layer="g7001"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:window-width="1674"
|
||||||
|
inkscape:window-height="970"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata4913">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title>Stop Process</dc:title>
|
||||||
|
<dc:date>December 2006</dc:date>
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Jakub Steiner</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:contributor>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Andreas Nilsson</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:contributor>
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
|
||||||
|
<dc:subject>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li>stop</rdf:li>
|
||||||
|
<rdf:li>halt</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</dc:subject>
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/Notice" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/ShareAlike" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/SourceCode" />
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="translate(0,-24)">
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
id="g7001"
|
||||||
|
transform="matrix(1.4566048,0,0,1.4455352,0.4112881,1.2324709)">
|
||||||
|
<path
|
||||||
|
transform="matrix(0.91468137,0,0,0.70055266,-1.8812476,17.474032)"
|
||||||
|
d="m 19.79899,18.022524 a 9.0598059,3.0935922 0 1 1 -18.1196115,0 9.0598059,3.0935922 0 1 1 18.1196115,0 z"
|
||||||
|
sodipodi:ry="3.0935922"
|
||||||
|
sodipodi:rx="9.0598059"
|
||||||
|
sodipodi:cy="18.022524"
|
||||||
|
sodipodi:cx="10.739184"
|
||||||
|
id="path5137"
|
||||||
|
style="color:#000000;fill:url(#radialGradient5145);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(0.87347736,0,0,0.83068052,-0.79308842,15.602788)"
|
||||||
|
d="m 19.25,9.625 a 9.25,9.25 0 1 1 -18.5,0 9.25,9.25 0 1 1 18.5,0 z"
|
||||||
|
sodipodi:ry="9.25"
|
||||||
|
sodipodi:rx="9.25"
|
||||||
|
sodipodi:cy="9.625"
|
||||||
|
sodipodi:cx="10"
|
||||||
|
id="path4262"
|
||||||
|
style="color:#000000;fill:url(#radialGradient5177);fill-opacity:1;fill-rule:nonzero;stroke:#a40000;stroke-width:0.47435912;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="opacity:0.35393258;color:#000000;fill:none;stroke:url(#radialGradient5157);stroke-width:0.49999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||||
|
id="path5149"
|
||||||
|
sodipodi:cx="10"
|
||||||
|
sodipodi:cy="9.625"
|
||||||
|
sodipodi:rx="9.25"
|
||||||
|
sodipodi:ry="9.25"
|
||||||
|
d="m 19.25,9.625 a 9.25,9.25 0 1 1 -18.5,0 9.25,9.25 0 1 1 18.5,0 z"
|
||||||
|
transform="matrix(0.82868359,0,0,0.78808147,-0.34515141,16.012803)" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
id="path5159"
|
||||||
|
d="m 4.834121,20.642783 6.215127,5.91061"
|
||||||
|
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.21219134;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.21219146;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||||
|
d="M 11.04925,20.622826 4.8159529,26.553393"
|
||||||
|
id="path5161"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.0 KiB |
113
data/theme/mosaic-view-active.svg
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="24"
|
||||||
|
height="16"
|
||||||
|
id="svg6503"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47pre4 r22446"
|
||||||
|
sodipodi:docname="mosaic-view-active.svg">
|
||||||
|
<defs
|
||||||
|
id="defs6505">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 16 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="32 : 16 : 1"
|
||||||
|
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||||
|
id="perspective6511" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective6494"
|
||||||
|
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||||
|
inkscape:vp_z="1 : 0.5 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 0.5 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.197802"
|
||||||
|
inkscape:cx="-15.97056"
|
||||||
|
inkscape:cy="16"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1680"
|
||||||
|
inkscape:window-height="997"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata6508">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="translate(0,-16)">
|
||||||
|
<g
|
||||||
|
style="display:inline;fill:#cbcbcb;fill-opacity:1"
|
||||||
|
transform="translate(-449.85476,-685.85869)"
|
||||||
|
id="g5306">
|
||||||
|
<rect
|
||||||
|
style="fill:#cbcbcb;fill-opacity:1;stroke:#000000;stroke-width:0.99999970000000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.44262299999999999;stroke-dasharray:none"
|
||||||
|
id="rect5308"
|
||||||
|
width="11"
|
||||||
|
height="7"
|
||||||
|
x="450.5"
|
||||||
|
y="710.5"
|
||||||
|
rx="0.99999958"
|
||||||
|
ry="1" />
|
||||||
|
<rect
|
||||||
|
style="fill:#cbcbcb;fill-opacity:1;stroke:#000000;stroke-width:0.99999970000000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.44262299999999999;stroke-dasharray:none;display:inline"
|
||||||
|
id="rect5310"
|
||||||
|
width="11"
|
||||||
|
height="7"
|
||||||
|
x="462.5"
|
||||||
|
y="702.5"
|
||||||
|
rx="0.99999958"
|
||||||
|
ry="1" />
|
||||||
|
<rect
|
||||||
|
style="fill:#cbcbcb;fill-opacity:1;stroke:#000000;stroke-width:0.99999976000000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.44262299999999999;stroke-dasharray:none;display:inline"
|
||||||
|
id="rect5312"
|
||||||
|
width="11"
|
||||||
|
height="7"
|
||||||
|
x="450.5"
|
||||||
|
y="702.5"
|
||||||
|
rx="0.99999958"
|
||||||
|
ry="1" />
|
||||||
|
<rect
|
||||||
|
style="fill:#cbcbcb;fill-opacity:1;stroke:#000000;stroke-width:0.99999970000000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.44262299999999999;stroke-dasharray:none;display:inline"
|
||||||
|
id="rect5314"
|
||||||
|
width="11"
|
||||||
|
height="7"
|
||||||
|
x="462.5"
|
||||||
|
y="710.5"
|
||||||
|
rx="0.99999958"
|
||||||
|
ry="1" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
113
data/theme/mosaic-view.svg
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="24"
|
||||||
|
height="16"
|
||||||
|
id="svg6503"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47pre4 r22446"
|
||||||
|
sodipodi:docname="New document 19">
|
||||||
|
<defs
|
||||||
|
id="defs6505">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 16 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="32 : 16 : 1"
|
||||||
|
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||||
|
id="perspective6511" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective6494"
|
||||||
|
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||||
|
inkscape:vp_z="1 : 0.5 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 0.5 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.197802"
|
||||||
|
inkscape:cx="16"
|
||||||
|
inkscape:cy="16"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1680"
|
||||||
|
inkscape:window-height="997"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata6508">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="translate(0,-16)">
|
||||||
|
<g
|
||||||
|
style="display:inline"
|
||||||
|
transform="translate(-449.85476,-685.85869)"
|
||||||
|
id="g5306">
|
||||||
|
<rect
|
||||||
|
style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:0.9999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.442623;stroke-dasharray:none"
|
||||||
|
id="rect5308"
|
||||||
|
width="11"
|
||||||
|
height="7"
|
||||||
|
x="450.5"
|
||||||
|
y="710.5"
|
||||||
|
rx="0.99999958"
|
||||||
|
ry="1" />
|
||||||
|
<rect
|
||||||
|
style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:0.9999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.442623;stroke-dasharray:none;display:inline"
|
||||||
|
id="rect5310"
|
||||||
|
width="11"
|
||||||
|
height="7"
|
||||||
|
x="462.5"
|
||||||
|
y="702.5"
|
||||||
|
rx="0.99999958"
|
||||||
|
ry="1" />
|
||||||
|
<rect
|
||||||
|
style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:0.99999976;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.442623;stroke-dasharray:none;display:inline"
|
||||||
|
id="rect5312"
|
||||||
|
width="11"
|
||||||
|
height="7"
|
||||||
|
x="450.5"
|
||||||
|
y="702.5"
|
||||||
|
rx="0.99999958"
|
||||||
|
ry="1" />
|
||||||
|
<rect
|
||||||
|
style="fill:#666666;fill-opacity:1;stroke:#000000;stroke-width:0.9999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.442623;stroke-dasharray:none;display:inline"
|
||||||
|
id="rect5314"
|
||||||
|
width="11"
|
||||||
|
height="7"
|
||||||
|
x="462.5"
|
||||||
|
y="710.5"
|
||||||
|
rx="0.99999958"
|
||||||
|
ry="1" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.6 KiB |
89
data/theme/move-window-on-new.svg
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="98"
|
||||||
|
height="98"
|
||||||
|
id="svg6375"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47 r22583"
|
||||||
|
sodipodi:docname="add-workspace.svg">
|
||||||
|
<defs
|
||||||
|
id="defs6377">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 16 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="32 : 16 : 1"
|
||||||
|
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||||
|
id="perspective6383" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective6366"
|
||||||
|
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||||
|
inkscape:vp_z="1 : 0.5 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 0.5 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="3.9590209"
|
||||||
|
inkscape:cx="56.650687"
|
||||||
|
inkscape:cy="20.635343"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1680"
|
||||||
|
inkscape:window-height="997"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata6380">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="translate(0,66)">
|
||||||
|
<g
|
||||||
|
id="g2824"
|
||||||
|
transform="matrix(11.568551,0,0,11.698271,-78.828159,-304.81518)">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
d="m 11.07363,21.36834 0,6.43903"
|
||||||
|
id="path5322" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||||
|
d="m 14.29314,24.58786 -6.43902,0"
|
||||||
|
id="path5324" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-opacity:0.98823529"
|
||||||
|
d="m 48.239516,97.908047 c -0.41677,-0.05102 -1.269253,-0.222408 -1.894408,-0.380859 -4.088493,-1.036262 -7.520781,-4.753234 -8.330163,-9.021094 -0.154947,-0.817026 -0.257819,-6.68112 -0.257819,-14.696556 l 0,-13.337088 -13.829177,-0.08909 C 10.802042,60.298796 10.026884,60.268266 8.6851548,59.783022 3.6288503,57.954375 0.62673331,53.828648 0.62673331,48.708554 c 0,-5.625522 4.25936019,-10.425065 9.97721469,-11.242548 0.987903,-0.141242 7.368912,-0.254994 14.460646,-0.257791 l 12.692532,-0.005 0,-13.586668 c 0,-14.6441583 0.03287,-15.0698926 1.364686,-17.6753047 2.185477,-4.2754229 6.938193,-6.75739913 11.687647,-6.10355607 3.382776,0.46569661 6.737962,2.72496967 8.414081,5.66577137 1.480816,2.5981315 1.519067,3.0522448 1.519067,18.0333334 l 0,13.666424 12.692533,0.005 c 7.091733,0.0028 13.472742,0.116549 14.460646,0.257791 6.395303,0.914337 10.804785,6.623716 9.941157,12.871766 -0.698243,5.051565 -4.792685,9.104635 -9.941157,9.840713 -0.987904,0.141242 -7.368913,0.254995 -14.460646,0.257791 l -12.692533,0.005 0,13.801945 c 0,13.031417 -0.02798,13.895893 -0.501177,15.484801 -1.526902,5.127058 -6.919246,8.802262 -12.001914,8.18002 z"
|
||||||
|
id="path2828"
|
||||||
|
transform="translate(0,-66)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.0 KiB |
BIN
data/theme/process-working.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
92
data/theme/remove-workspace.svg
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="23"
|
||||||
|
height="15"
|
||||||
|
id="svg5501"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47pre4 r22446"
|
||||||
|
sodipodi:docname="add-workspace.svg">
|
||||||
|
<defs
|
||||||
|
id="defs5503">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 16 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="32 : 16 : 1"
|
||||||
|
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||||
|
id="perspective5509" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective5314"
|
||||||
|
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||||
|
inkscape:vp_z="1 : 0.5 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 0.5 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.197802"
|
||||||
|
inkscape:cx="-0.074583208"
|
||||||
|
inkscape:cy="16"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1680"
|
||||||
|
inkscape:window-height="997"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:snap-grids="true"
|
||||||
|
inkscape:snap-bbox="true" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5506">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="translate(0,-17)">
|
||||||
|
<g
|
||||||
|
style="display:inline"
|
||||||
|
id="g6239"
|
||||||
|
transform="translate(-953.97989,-657.32287)">
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:0.98770495;stroke:#666666;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||||
|
id="rect5318-6"
|
||||||
|
width="22"
|
||||||
|
height="14"
|
||||||
|
x="954.5"
|
||||||
|
y="675"
|
||||||
|
rx="0.49999979"
|
||||||
|
ry="0.5" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||||
|
d="m 968.71951,682 -6.43902,0"
|
||||||
|
id="path5324-5" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
64
data/theme/scroll-hhandle.svg
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="10"
|
||||||
|
height="4"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47 r22583"
|
||||||
|
sodipodi:docname="scroll-hhandle.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
</defs>
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
id="rect3592"
|
||||||
|
width="2"
|
||||||
|
height="4"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
rx="0"
|
||||||
|
ry="0" />
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#rect3592"
|
||||||
|
id="use2825"
|
||||||
|
transform="translate(8,0)"
|
||||||
|
width="10"
|
||||||
|
height="4" />
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#use2825"
|
||||||
|
id="use2827"
|
||||||
|
transform="translate(-4,0)"
|
||||||
|
width="10"
|
||||||
|
height="4" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 323 B |
62
data/theme/scroll-vhandle.svg
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="4"
|
||||||
|
height="10"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47 r22583"
|
||||||
|
sodipodi:docname="scroll-hhandle.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#323232;fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
id="rect3592"
|
||||||
|
width="2"
|
||||||
|
height="4"
|
||||||
|
x="0"
|
||||||
|
y="-4"
|
||||||
|
rx="0"
|
||||||
|
ry="0"
|
||||||
|
transform="matrix(0,1,-1,0,0,0)" />
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#rect3592"
|
||||||
|
id="use3705"
|
||||||
|
transform="translate(0,4)"
|
||||||
|
width="4"
|
||||||
|
height="10" />
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#use3705"
|
||||||
|
id="use3707"
|
||||||
|
transform="translate(0,4)"
|
||||||
|
width="4"
|
||||||
|
height="10" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
|
||||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" id="Foreground" x="0px" y="0px" width="12" height="16" viewBox="0 0 12 16" enable-background="new 0 0 29 18" xml:space="preserve" sodipodi:version="0.32" inkscape:version="0.46+devel" sodipodi:docname="back.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata id="metadata16"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs14"><inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 9 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="29 : 9 : 1" inkscape:persp3d-origin="14.5 : 6 : 1" id="perspective18"/></defs><sodipodi:namedview inkscape:window-height="728" inkscape:window-width="1103" inkscape:pageshadow="2" inkscape:pageopacity="1" guidetolerance="10.0" gridtolerance="10.0" objecttolerance="10.0" borderopacity="1.0" bordercolor="#666666" pagecolor="#000000" id="base" showgrid="true" inkscape:zoom="27.260185" inkscape:cx="12.592456" inkscape:cy="8.2696842" inkscape:window-x="145" inkscape:window-y="38" inkscape:current-layer="Foreground" inkscape:snap-global="true" showguides="false"><inkscape:grid type="xygrid" id="grid2391" empspacing="5" visible="true" enabled="true" snapvisiblegridlinesonly="true"/></sodipodi:namedview>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<path style="fill: rgb(255, 255, 255); fill-opacity: 1; stroke: none;" d="M 10,2 10,14 2,8 10,2 z" id="path43"/></svg>
|
|
Before Width: | Height: | Size: 1.9 KiB |
87
data/theme/section-more-open.svg
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="5.8600588"
|
||||||
|
height="9"
|
||||||
|
id="svg3647"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47 r22583"
|
||||||
|
sodipodi:docname="section-more.svg">
|
||||||
|
<defs
|
||||||
|
id="defs3649">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 526.18109 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||||
|
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||||
|
id="perspective3655" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective3603"
|
||||||
|
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||||
|
inkscape:vp_z="1 : 0.5 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 0.5 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="82.777778"
|
||||||
|
inkscape:cx="2.9300294"
|
||||||
|
inkscape:cy="5.466443"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1680"
|
||||||
|
inkscape:window-height="997"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata3652">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-262.78425,-490.71933)">
|
||||||
|
<path
|
||||||
|
transform="matrix(0,-0.98149546,0.71467449,0,25.404986,578.15569)"
|
||||||
|
d="M 88.830127,340 80.169873,340 84.5,332.5 88.830127,340 z"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
sodipodi:arg2="1.5707963"
|
||||||
|
sodipodi:arg1="0.52359878"
|
||||||
|
sodipodi:r2="2.5"
|
||||||
|
sodipodi:r1="5"
|
||||||
|
sodipodi:cy="337.5"
|
||||||
|
sodipodi:cx="84.5"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
id="path5497-5"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.59699643;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||||
|
sodipodi:type="star" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
BIN
data/theme/separator-white.png
Normal file
After Width: | Height: | Size: 531 B |
81
data/theme/single-view-active.svg
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="24"
|
||||||
|
height="16"
|
||||||
|
id="svg6446"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47pre4 r22446"
|
||||||
|
sodipodi:docname="single-view-active.svg">
|
||||||
|
<defs
|
||||||
|
id="defs6448">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 16 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="32 : 16 : 1"
|
||||||
|
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||||
|
id="perspective6454" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective6441"
|
||||||
|
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||||
|
inkscape:vp_z="1 : 0.5 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 0.5 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.197802"
|
||||||
|
inkscape:cx="0.014720032"
|
||||||
|
inkscape:cy="16"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1680"
|
||||||
|
inkscape:window-height="997"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata6451">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="translate(0,-17)">
|
||||||
|
<rect
|
||||||
|
ry="0.5"
|
||||||
|
rx="0.49999979"
|
||||||
|
y="17.483809"
|
||||||
|
x="0.53483802"
|
||||||
|
height="15"
|
||||||
|
width="23"
|
||||||
|
id="rect5304"
|
||||||
|
style="fill:#cccccc;fill-opacity:1;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
81
data/theme/single-view.svg
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="24"
|
||||||
|
height="16"
|
||||||
|
id="svg6446"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.47pre4 r22446"
|
||||||
|
sodipodi:docname="single-view.svg">
|
||||||
|
<defs
|
||||||
|
id="defs6448">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 16 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="32 : 16 : 1"
|
||||||
|
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
||||||
|
id="perspective6454" />
|
||||||
|
<inkscape:perspective
|
||||||
|
id="perspective6441"
|
||||||
|
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||||
|
inkscape:vp_z="1 : 0.5 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_x="0 : 0.5 : 1"
|
||||||
|
sodipodi:type="inkscape:persp3d" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.197802"
|
||||||
|
inkscape:cx="0.014720032"
|
||||||
|
inkscape:cy="16"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1680"
|
||||||
|
inkscape:window-height="997"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata6451">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="translate(0,-17)">
|
||||||
|
<rect
|
||||||
|
ry="0.5"
|
||||||
|
rx="0.49999979"
|
||||||
|
y="17.483809"
|
||||||
|
x="0.53483802"
|
||||||
|
height="15"
|
||||||
|
width="23"
|
||||||
|
id="rect5304"
|
||||||
|
style="fill:#626262;fill-opacity:1;stroke:#cccccc;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
96
data/theme/ws-switch-arrow-left.svg
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="96" height="96" id="svg25070" version="1.1" inkscape:version="0.47 r22583" sodipodi:docname="dark-arrow-larger.svg">
|
||||||
|
<defs id="defs25072">
|
||||||
|
<inkscape:perspective sodipodi:type="inkscape:persp3d" inkscape:vp_x="0 : 24 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="48 : 24 : 1" inkscape:persp3d-origin="24 : 16 : 1" id="perspective25078"/>
|
||||||
|
<inkscape:perspective id="perspective24985" inkscape:persp3d-origin="0.5 : 0.33333333 : 1" inkscape:vp_z="1 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_x="0 : 0.5 : 1" sodipodi:type="inkscape:persp3d"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4034-0-4" id="linearGradient24957" gradientUnits="userSpaceOnUse" gradientTransform="translate(6)" x1="-86.552246" y1="185.439" x2="-83.37072" y2="197.31261"/>
|
||||||
|
<linearGradient inkscape:collect="always" id="linearGradient4034-0-4">
|
||||||
|
<stop style="stop-color: rgb(238, 238, 236); stop-opacity: 1;" offset="0" id="stop4036-5-7"/>
|
||||||
|
<stop style="stop-color: rgb(186, 189, 182); stop-opacity: 1;" offset="1" id="stop4038-9-6"/>
|
||||||
|
</linearGradient>
|
||||||
|
<filter id="filter24765" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||||
|
<feColorMatrix id="feColorMatrix24767" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||||
|
<feColorMatrix id="feColorMatrix24769" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||||
|
</filter>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4632-1-3-9-3-2" id="linearGradient24955" gradientUnits="userSpaceOnUse" gradientTransform="translate(-5)" x1="-74.520325" y1="169.06032" x2="-74.520325" y2="205.94189"/>
|
||||||
|
<linearGradient id="linearGradient4632-1-3-9-3-2">
|
||||||
|
<stop style="stop-color: rgb(238, 238, 236); stop-opacity: 1;" offset="0" id="stop4634-1-8-3-9-0"/>
|
||||||
|
<stop id="stop4636-1-9-9-8-8" offset="0.0274937" style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"/>
|
||||||
|
<stop id="stop4638-8-3-9-6-6" offset="0.274937" style="stop-color: rgb(242, 242, 242); stop-opacity: 1;"/>
|
||||||
|
<stop id="stop4640-8-5-7-8-9" offset="0.38707438" style="stop-color: rgb(238, 238, 236); stop-opacity: 1;"/>
|
||||||
|
<stop id="stop4642-5-41-9-6-9" offset="0.66528589" style="stop-color: rgb(217, 218, 216); stop-opacity: 1;"/>
|
||||||
|
<stop id="stop4644-5-2-7-9-2" offset="0.76745707" style="stop-color: rgb(223, 224, 221); stop-opacity: 1;"/>
|
||||||
|
<stop style="stop-color: rgb(240, 240, 240); stop-opacity: 1;" offset="1" id="stop4646-3-2-3-7-3"/>
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient4869-4-1" id="radialGradient24959" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0075, 0, 0, 1.0075, -5.4544, -1.25141)" cx="-33.412369" cy="185.74171" fx="-33.412369" fy="185.74171" r="2.3554697"/>
|
||||||
|
<linearGradient id="linearGradient4869-4-1">
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop4871-6-2"/>
|
||||||
|
<stop id="stop4879-7-4" offset="0.31807542" style="stop-color: rgb(238, 238, 236); stop-opacity: 1;"/>
|
||||||
|
<stop id="stop4877-6-1" offset="0.74691135" style="stop-color: rgb(200, 201, 198); stop-opacity: 1;"/>
|
||||||
|
<stop style="stop-color: rgb(211, 215, 207); stop-opacity: 1;" offset="1" id="stop4873-1-0"/>
|
||||||
|
</linearGradient>
|
||||||
|
<filter id="filter25011" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||||
|
<feColorMatrix id="feColorMatrix25013" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||||
|
<feColorMatrix id="feColorMatrix25015" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient4869-4-0" id="radialGradient24961" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.0075, 0, 0, 1.0075, -5.4544, -1.25141)" cx="-33.412369" cy="185.74171" fx="-33.412369" fy="185.74171" r="2.3554697"/>
|
||||||
|
<linearGradient id="linearGradient4869-4-0">
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop4871-6-8"/>
|
||||||
|
<stop id="stop4879-7-5" offset="0.31807542" style="stop-color: rgb(238, 238, 236); stop-opacity: 1;"/>
|
||||||
|
<stop id="stop4877-6-5" offset="0.74691135" style="stop-color: rgb(200, 201, 198); stop-opacity: 1;"/>
|
||||||
|
<stop style="stop-color: rgb(211, 215, 207); stop-opacity: 1;" offset="1" id="stop4873-1-4"/>
|
||||||
|
</linearGradient>
|
||||||
|
<filter id="filter25023" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||||
|
<feColorMatrix id="feColorMatrix25025" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||||
|
<feColorMatrix id="feColorMatrix25027" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||||
|
</filter>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4941" id="linearGradient24963" gradientUnits="userSpaceOnUse" x1="-39.858727" y1="184.61784" x2="-38.244785" y2="188.84898"/>
|
||||||
|
<linearGradient inkscape:collect="always" id="linearGradient4941">
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop4943"/>
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" offset="1" id="stop4945"/>
|
||||||
|
</linearGradient>
|
||||||
|
<filter id="filter25033" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||||
|
<feColorMatrix id="feColorMatrix25035" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||||
|
<feColorMatrix id="feColorMatrix25037" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||||
|
</filter>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4941-7" id="linearGradient24965" gradientUnits="userSpaceOnUse" x1="-39.858727" y1="184.61784" x2="-38.244785" y2="188.84898"/>
|
||||||
|
<linearGradient inkscape:collect="always" id="linearGradient4941-7">
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop4943-2"/>
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" offset="1" id="stop4945-5"/>
|
||||||
|
</linearGradient>
|
||||||
|
<filter id="filter25043" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||||
|
<feColorMatrix id="feColorMatrix25045" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||||
|
<feColorMatrix id="feColorMatrix25047" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter25049" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||||
|
<feColorMatrix id="feColorMatrix25051" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||||
|
<feColorMatrix id="feColorMatrix25053" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter25055" inkscape:label="Invert" x="0" y="0" width="1" height="1" inkscape:menu="Color" inkscape:menu-tooltip="Invert colors" color-interpolation-filters="sRGB">
|
||||||
|
<feColorMatrix id="feColorMatrix25057" type="saturate" values="1" result="fbSourceGraphic"/>
|
||||||
|
<feColorMatrix id="feColorMatrix25059" in="fbSourceGraphic" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2.8284271" inkscape:cx="48.631638" inkscape:cy="57.536221" inkscape:current-layer="layer1" showgrid="true" inkscape:grid-bbox="true" inkscape:document-units="px" inkscape:window-width="1200" inkscape:window-height="851" inkscape:window-x="0" inkscape:window-y="52" inkscape:window-maximized="0"/>
|
||||||
|
<metadata id="metadata25075">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||||
|
<dc:title/>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer" transform="translate(0, 48)">
|
||||||
|
<g id="g4030-1-8" transform="matrix(2, 0, 0, 2, 193.25, -374.967)" style="stroke: rgb(0, 0, 0); display: inline; stroke-opacity: 1;">
|
||||||
|
<path sodipodi:nodetypes="ccc" id="path3165-7-3" d="m -72.5,173.5 -14,14 14,14" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 7; stroke-linecap: round; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-dasharray: none; stroke-dashoffset: 0pt; visibility: visible; display: inline;"/>
|
||||||
|
</g>
|
||||||
|
<path sodipodi:type="arc" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: rgb(0, 0, 0); fill-opacity: 1; fill-rule: nonzero; stroke: none; stroke-width: 0.523439; visibility: visible; display: inline;" id="path4050-2-7-9-4" sodipodi:cx="-38.59375" sodipodi:cy="186.40625" sodipodi:rx="2.09375" sodipodi:ry="2.09375" d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z" transform="matrix(3.34328, 0, 0, 3.34328, 185.28, -623.176)"/>
|
||||||
|
<path sodipodi:type="arc" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: rgb(0, 0, 0); fill-opacity: 1; fill-rule: nonzero; stroke: none; stroke-width: 0.523439; visibility: visible; display: inline;" id="path4050-2-7-9-4-8" sodipodi:cx="-38.59375" sodipodi:cy="186.40625" sodipodi:rx="2.09375" sodipodi:ry="2.09375" d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z" transform="matrix(3.34328, 0, 0, 3.34328, 207.28, -623.176)"/>
|
||||||
|
<path sodipodi:type="arc" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 0.697921; stroke-linecap: round; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-dasharray: none; stroke-dashoffset: 0pt; visibility: visible; display: inline;" id="path4050-2-7-9-4-0" sodipodi:cx="-38.59375" sodipodi:cy="186.40625" sodipodi:rx="2.09375" sodipodi:ry="2.09375" d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z" transform="matrix(2.86565, 0, 0, 2.86565, 166.846, -534.143)"/>
|
||||||
|
<path sodipodi:type="arc" style="overflow: visible; marker: none; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 0.697921; stroke-linecap: round; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-dasharray: none; stroke-dashoffset: 0pt; visibility: visible; display: inline;" id="path4050-2-7-9-4-0-9" sodipodi:cx="-38.59375" sodipodi:cy="186.40625" sodipodi:rx="2.09375" sodipodi:ry="2.09375" d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z" transform="matrix(2.86565, 0, 0, 2.86565, 188.846, -534.143)"/>
|
||||||
|
<path style="overflow: visible; marker: none; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; text-indent: 0pt; text-align: start; text-decoration: none; line-height: normal; letter-spacing: normal; word-spacing: normal; text-transform: none; direction: ltr; text-anchor: start; opacity: 0.35; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 1; stroke-miterlimit: 4; stroke-dasharray: none; visibility: visible; display: inline; font-family: Bitstream Vera Sans; stroke-opacity: 1;" d="m 317.06251,365.96875 c -0.76948,0.0224 -1.52555,0.35464 -2.0625,0.90625 l -16.125,16.125 16.125,16.125 c 1.11265,1.11265 3.13735,1.11265 4.25,0 1.11265,-1.11264 1.11265,-3.13735 0,-4.25 l -11.875,-11.875 11.875,-11.875 c 0.86584,-0.83655 1.1475,-2.22114 0.6773,-3.32947 -0.47021,-1.10834 -1.66156,-1.86802 -2.8648,-1.82678 z" id="path3165-7-3-1" sodipodi:nodetypes="ccccscccsc" transform="matrix(2, 0, 0, 2, -586, -765.967)"/>
|
||||||
|
<path style="overflow: visible; marker: none; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; text-indent: 0pt; text-align: start; text-decoration: none; line-height: normal; letter-spacing: normal; word-spacing: normal; text-transform: none; direction: ltr; text-anchor: start; color: rgb(0, 0, 0); fill: none; stroke: rgb(0, 0, 0); stroke-width: 1; stroke-linecap: round; stroke-miterlimit: 4; stroke-dasharray: none; visibility: visible; display: inline; font-family: Bitstream Vera Sans; stroke-opacity: 1;" d="m 320.08435,397.03059 c 0.007,-0.79449 -0.27079,-1.59203 -0.83434,-2.15559 L 307.37501,383 m 12.5523,-15.20447 c -0.47021,-1.10834 -1.66156,-1.86802 -2.8648,-1.82678 -0.76948,0.0224 -1.52555,0.35464 -2.0625,0.90625 L 298.87501,383" id="path3165-7-3-1-9" sodipodi:nodetypes="ccccccc" transform="matrix(2, 0, 0, 2, -586, -765.967)"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 13 KiB |
331
data/theme/ws-switch-arrow-right.svg
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="1.1"
|
||||||
|
width="96"
|
||||||
|
height="96"
|
||||||
|
id="svg25070">
|
||||||
|
<defs
|
||||||
|
id="defs25072">
|
||||||
|
<linearGradient
|
||||||
|
x1="-86.552246"
|
||||||
|
y1="185.439"
|
||||||
|
x2="-83.37072"
|
||||||
|
y2="197.31261"
|
||||||
|
id="linearGradient24957"
|
||||||
|
xlink:href="#linearGradient4034-0-4"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(6,0)" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4034-0-4">
|
||||||
|
<stop
|
||||||
|
id="stop4036-5-7"
|
||||||
|
style="stop-color:#eeeeec;stop-opacity:1"
|
||||||
|
offset="0" />
|
||||||
|
<stop
|
||||||
|
id="stop4038-9-6"
|
||||||
|
style="stop-color:#babdb6;stop-opacity:1"
|
||||||
|
offset="1" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
id="filter24765">
|
||||||
|
<feColorMatrix
|
||||||
|
result="fbSourceGraphic"
|
||||||
|
values="1"
|
||||||
|
type="saturate"
|
||||||
|
id="feColorMatrix24767" />
|
||||||
|
<feColorMatrix
|
||||||
|
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||||
|
in="fbSourceGraphic"
|
||||||
|
id="feColorMatrix24769" />
|
||||||
|
</filter>
|
||||||
|
<linearGradient
|
||||||
|
x1="-74.520325"
|
||||||
|
y1="169.06032"
|
||||||
|
x2="-74.520325"
|
||||||
|
y2="205.94189"
|
||||||
|
id="linearGradient24955"
|
||||||
|
xlink:href="#linearGradient4632-1-3-9-3-2"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(-5,0)" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4632-1-3-9-3-2">
|
||||||
|
<stop
|
||||||
|
id="stop4634-1-8-3-9-0"
|
||||||
|
style="stop-color:#eeeeec;stop-opacity:1"
|
||||||
|
offset="0" />
|
||||||
|
<stop
|
||||||
|
id="stop4636-1-9-9-8-8"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1"
|
||||||
|
offset="0.0274937" />
|
||||||
|
<stop
|
||||||
|
id="stop4638-8-3-9-6-6"
|
||||||
|
style="stop-color:#f2f2f2;stop-opacity:1"
|
||||||
|
offset="0.274937" />
|
||||||
|
<stop
|
||||||
|
id="stop4640-8-5-7-8-9"
|
||||||
|
style="stop-color:#eeeeec;stop-opacity:1"
|
||||||
|
offset="0.38707438" />
|
||||||
|
<stop
|
||||||
|
id="stop4642-5-41-9-6-9"
|
||||||
|
style="stop-color:#d9dad8;stop-opacity:1"
|
||||||
|
offset="0.66528589" />
|
||||||
|
<stop
|
||||||
|
id="stop4644-5-2-7-9-2"
|
||||||
|
style="stop-color:#dfe0dd;stop-opacity:1"
|
||||||
|
offset="0.76745707" />
|
||||||
|
<stop
|
||||||
|
id="stop4646-3-2-3-7-3"
|
||||||
|
style="stop-color:#f0f0f0;stop-opacity:1"
|
||||||
|
offset="1" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
cx="-33.412369"
|
||||||
|
cy="185.74171"
|
||||||
|
r="2.3554697"
|
||||||
|
fx="-33.412369"
|
||||||
|
fy="185.74171"
|
||||||
|
id="radialGradient24959"
|
||||||
|
xlink:href="#linearGradient4869-4-1"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.0075,0,0,1.0075,-5.4544,-1.25141)" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4869-4-1">
|
||||||
|
<stop
|
||||||
|
id="stop4871-6-2"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1"
|
||||||
|
offset="0" />
|
||||||
|
<stop
|
||||||
|
id="stop4879-7-4"
|
||||||
|
style="stop-color:#eeeeec;stop-opacity:1"
|
||||||
|
offset="0.31807542" />
|
||||||
|
<stop
|
||||||
|
id="stop4877-6-1"
|
||||||
|
style="stop-color:#c8c9c6;stop-opacity:1"
|
||||||
|
offset="0.74691135" />
|
||||||
|
<stop
|
||||||
|
id="stop4873-1-0"
|
||||||
|
style="stop-color:#d3d7cf;stop-opacity:1"
|
||||||
|
offset="1" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
id="filter25011">
|
||||||
|
<feColorMatrix
|
||||||
|
result="fbSourceGraphic"
|
||||||
|
values="1"
|
||||||
|
type="saturate"
|
||||||
|
id="feColorMatrix25013" />
|
||||||
|
<feColorMatrix
|
||||||
|
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||||
|
in="fbSourceGraphic"
|
||||||
|
id="feColorMatrix25015" />
|
||||||
|
</filter>
|
||||||
|
<radialGradient
|
||||||
|
cx="-33.412369"
|
||||||
|
cy="185.74171"
|
||||||
|
r="2.3554697"
|
||||||
|
fx="-33.412369"
|
||||||
|
fy="185.74171"
|
||||||
|
id="radialGradient24961"
|
||||||
|
xlink:href="#linearGradient4869-4-0"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.0075,0,0,1.0075,-5.4544,-1.25141)" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4869-4-0">
|
||||||
|
<stop
|
||||||
|
id="stop4871-6-8"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1"
|
||||||
|
offset="0" />
|
||||||
|
<stop
|
||||||
|
id="stop4879-7-5"
|
||||||
|
style="stop-color:#eeeeec;stop-opacity:1"
|
||||||
|
offset="0.31807542" />
|
||||||
|
<stop
|
||||||
|
id="stop4877-6-5"
|
||||||
|
style="stop-color:#c8c9c6;stop-opacity:1"
|
||||||
|
offset="0.74691135" />
|
||||||
|
<stop
|
||||||
|
id="stop4873-1-4"
|
||||||
|
style="stop-color:#d3d7cf;stop-opacity:1"
|
||||||
|
offset="1" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
id="filter25023">
|
||||||
|
<feColorMatrix
|
||||||
|
result="fbSourceGraphic"
|
||||||
|
values="1"
|
||||||
|
type="saturate"
|
||||||
|
id="feColorMatrix25025" />
|
||||||
|
<feColorMatrix
|
||||||
|
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||||
|
in="fbSourceGraphic"
|
||||||
|
id="feColorMatrix25027" />
|
||||||
|
</filter>
|
||||||
|
<linearGradient
|
||||||
|
x1="-39.858727"
|
||||||
|
y1="184.61784"
|
||||||
|
x2="-38.244785"
|
||||||
|
y2="188.84898"
|
||||||
|
id="linearGradient24963"
|
||||||
|
xlink:href="#linearGradient4941"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4941">
|
||||||
|
<stop
|
||||||
|
id="stop4943"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1"
|
||||||
|
offset="0" />
|
||||||
|
<stop
|
||||||
|
id="stop4945"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0"
|
||||||
|
offset="1" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
id="filter25033">
|
||||||
|
<feColorMatrix
|
||||||
|
result="fbSourceGraphic"
|
||||||
|
values="1"
|
||||||
|
type="saturate"
|
||||||
|
id="feColorMatrix25035" />
|
||||||
|
<feColorMatrix
|
||||||
|
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||||
|
in="fbSourceGraphic"
|
||||||
|
id="feColorMatrix25037" />
|
||||||
|
</filter>
|
||||||
|
<linearGradient
|
||||||
|
x1="-39.858727"
|
||||||
|
y1="184.61784"
|
||||||
|
x2="-38.244785"
|
||||||
|
y2="188.84898"
|
||||||
|
id="linearGradient24965"
|
||||||
|
xlink:href="#linearGradient4941-7"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4941-7">
|
||||||
|
<stop
|
||||||
|
id="stop4943-2"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1"
|
||||||
|
offset="0" />
|
||||||
|
<stop
|
||||||
|
id="stop4945-5"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0"
|
||||||
|
offset="1" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
id="filter25043">
|
||||||
|
<feColorMatrix
|
||||||
|
result="fbSourceGraphic"
|
||||||
|
values="1"
|
||||||
|
type="saturate"
|
||||||
|
id="feColorMatrix25045" />
|
||||||
|
<feColorMatrix
|
||||||
|
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||||
|
in="fbSourceGraphic"
|
||||||
|
id="feColorMatrix25047" />
|
||||||
|
</filter>
|
||||||
|
<filter
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
id="filter25049">
|
||||||
|
<feColorMatrix
|
||||||
|
result="fbSourceGraphic"
|
||||||
|
values="1"
|
||||||
|
type="saturate"
|
||||||
|
id="feColorMatrix25051" />
|
||||||
|
<feColorMatrix
|
||||||
|
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||||
|
in="fbSourceGraphic"
|
||||||
|
id="feColorMatrix25053" />
|
||||||
|
</filter>
|
||||||
|
<filter
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1"
|
||||||
|
height="1"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
id="filter25055">
|
||||||
|
<feColorMatrix
|
||||||
|
result="fbSourceGraphic"
|
||||||
|
values="1"
|
||||||
|
type="saturate"
|
||||||
|
id="feColorMatrix25057" />
|
||||||
|
<feColorMatrix
|
||||||
|
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
|
||||||
|
in="fbSourceGraphic"
|
||||||
|
id="feColorMatrix25059" />
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
transform="translate(0,48)"
|
||||||
|
id="layer1">
|
||||||
|
<g
|
||||||
|
transform="matrix(-2,0,0,2,-97.2497,-374.967)"
|
||||||
|
id="g4030-1-8"
|
||||||
|
style="stroke:#000000;stroke-opacity:1;display:inline">
|
||||||
|
<path
|
||||||
|
d="m -72.5,173.5 -14,14 14,14"
|
||||||
|
id="path3165-7-3"
|
||||||
|
style="color:#000000;fill:none;stroke:#000000;stroke-width:7;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
|
||||||
|
transform="matrix(-3.34328,0,0,3.34328,-89.2797,-623.176)"
|
||||||
|
id="path4050-2-7-9-4"
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52343899;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||||
|
<path
|
||||||
|
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
|
||||||
|
transform="matrix(-3.34328,0,0,3.34328,-111.2797,-623.176)"
|
||||||
|
id="path4050-2-7-9-4-8"
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52343899;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||||
|
<path
|
||||||
|
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
|
||||||
|
transform="matrix(-2.86565,0,0,2.86565,-70.8457,-534.143)"
|
||||||
|
id="path4050-2-7-9-4-0"
|
||||||
|
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.69792098;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||||
|
<path
|
||||||
|
d="m -36.5,186.40625 a 2.09375,2.09375 0 1 1 -4.1875,0 2.09375,2.09375 0 1 1 4.1875,0 z"
|
||||||
|
transform="matrix(-2.86565,0,0,2.86565,-92.8457,-534.143)"
|
||||||
|
id="path4050-2-7-9-4-0-9"
|
||||||
|
style="color:#000000;fill:none;stroke:#000000;stroke-width:0.69792098;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
|
||||||
|
<path
|
||||||
|
d="m 47.87528,-34.0295 c 1.53896,0.0448 3.0511,0.70928 4.125,1.8125 l 32.25,32.25 -32.25,32.25 c -2.2253,2.2253 -6.2747,2.2253 -8.5,0 -2.2253,-2.22528 -2.2253,-6.2747 0,-8.5 l 23.75,-23.75 -23.75,-23.75 c -1.73168,-1.6731 -2.295,-4.44228 -1.3546,-6.65894 0.94042,-2.21668 3.32312,-3.73604 5.7296,-3.65356 z"
|
||||||
|
id="path3165-7-3-1"
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0pt;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;text-anchor:start;opacity:0.35;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
|
||||||
|
<path
|
||||||
|
d="m 41.8316,28.09418 c -0.014,-1.58898 0.54158,-3.18406 1.66868,-4.31118 l 23.75,-23.75 m -25.1046,-30.40894 c 0.94042,-2.21668 3.32312,-3.73604 5.7296,-3.65356 1.53896,0.0448 3.0511,0.70928 4.125,1.8125 l 32.25,32.25"
|
||||||
|
id="path3165-7-3-1-9"
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0pt;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;text-anchor:start;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 12 KiB |
@ -1 +1 @@
|
|||||||
SUBDIRS = misc ui
|
SUBDIRS = misc ui perf prefs
|
||||||
|
@ -3,4 +3,6 @@ jsmiscdir = $(pkgdatadir)/js/misc
|
|||||||
dist_jsmisc_DATA = \
|
dist_jsmisc_DATA = \
|
||||||
docInfo.js \
|
docInfo.js \
|
||||||
format.js \
|
format.js \
|
||||||
params.js
|
gnomeSession.js \
|
||||||
|
params.js \
|
||||||
|
telepathy.js
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
|
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Search = imports.ui.search;
|
const Search = imports.ui.search;
|
||||||
@ -22,7 +23,7 @@ DocInfo.prototype = {
|
|||||||
// We actually used get_modified() instead of get_visited()
|
// We actually used get_modified() instead of get_visited()
|
||||||
// here, as GtkRecentInfo doesn't updated get_visited()
|
// here, as GtkRecentInfo doesn't updated get_visited()
|
||||||
// correctly. See http://bugzilla.gnome.org/show_bug.cgi?id=567094
|
// correctly. See http://bugzilla.gnome.org/show_bug.cgi?id=567094
|
||||||
this.timestamp = recentInfo.get_modified().getTime() / 1000;
|
this.timestamp = recentInfo.get_modified();
|
||||||
this.name = recentInfo.get_display_name();
|
this.name = recentInfo.get_display_name();
|
||||||
this._lowerName = this.name.toLowerCase();
|
this._lowerName = this.name.toLowerCase();
|
||||||
this.uri = recentInfo.get_uri();
|
this.uri = recentInfo.get_uri();
|
||||||
@ -30,7 +31,7 @@ DocInfo.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
createIcon : function(size) {
|
createIcon : function(size) {
|
||||||
return Shell.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
|
return St.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
|
||||||
},
|
},
|
||||||
|
|
||||||
launch : function() {
|
launch : function() {
|
||||||
@ -147,6 +148,6 @@ DocManager.prototype = {
|
|||||||
}
|
}
|
||||||
return multipleMatches.concat(prefixMatches.concat(substringMatches));
|
return multipleMatches.concat(prefixMatches.concat(substringMatches));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Signals.addSignalMethods(DocManager.prototype);
|
Signals.addSignalMethods(DocManager.prototype);
|
||||||
|
@ -6,8 +6,10 @@
|
|||||||
* It has to be set up using String.prototype.format = Format.format;
|
* It has to be set up using String.prototype.format = Format.format;
|
||||||
* Usage:
|
* Usage:
|
||||||
* "somestring %s %d".format('hello', 5);
|
* "somestring %s %d".format('hello', 5);
|
||||||
* It supports %s, %d and %f, for %f it also support precisions like
|
* It supports %s, %d, %x and %f, for %f it also support precisions like
|
||||||
* "%.2f".format(1.526)
|
* "%.2f".format(1.526). All specifiers can be prefixed with a minimum
|
||||||
|
* field width, e.g. "%5s".format("foo"). Unless the width is prefixed
|
||||||
|
* with '0', the formatted string will be padded with spaces.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function format() {
|
function format() {
|
||||||
@ -15,30 +17,44 @@ function format() {
|
|||||||
let i = 0;
|
let i = 0;
|
||||||
let args = arguments;
|
let args = arguments;
|
||||||
|
|
||||||
return str.replace(/%(?:\.([0-9]+))?(.)/g, function (str, precisionGroup, genericGroup) {
|
return str.replace(/%([0-9]+)?(?:\.([0-9]+))?(.)/g, function (str, widthGroup, precisionGroup, genericGroup) {
|
||||||
|
|
||||||
if (precisionGroup != '' && genericGroup != 'f')
|
if (precisionGroup != '' && genericGroup != 'f')
|
||||||
throw new Error("Precision can only be specified for 'f'");
|
throw new Error("Precision can only be specified for 'f'");
|
||||||
|
|
||||||
|
let fillChar = (widthGroup[0] == '0') ? '0' : ' ';
|
||||||
|
let width = parseInt(widthGroup, 10) || 0;
|
||||||
|
|
||||||
|
function fillWidth(s, c, w) {
|
||||||
|
let fill = '';
|
||||||
|
for (let i = 0; i < w; i++)
|
||||||
|
fill += c;
|
||||||
|
return fill.substr(s.length) + s;
|
||||||
|
}
|
||||||
|
|
||||||
|
let s = '';
|
||||||
switch (genericGroup) {
|
switch (genericGroup) {
|
||||||
case '%':
|
case '%':
|
||||||
return '%';
|
return '%';
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
return args[i++].toString();
|
s = args[i++].toString();
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
return parseInt(args[i++]);
|
s = parseInt(args[i++]).toString();
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
s = parseInt(args[i++]).toString(16);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
if (precisionGroup == '')
|
if (precisionGroup == '')
|
||||||
return parseFloat(args[i++]);
|
s = parseFloat(args[i++]).toString();
|
||||||
else
|
else
|
||||||
return parseFloat(args[i++]).toFixed(parseInt(precisionGroup));
|
s = parseFloat(args[i++]).toFixed(parseInt(precisionGroup));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error('Unsupported conversion character %' + genericGroup);
|
throw new Error('Unsupported conversion character %' + genericGroup);
|
||||||
}
|
}
|
||||||
return ""; // Suppress warning
|
return fillWidth(s, fillChar, width);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
45
js/misc/gnomeSession.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const DBus = imports.dbus;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
|
||||||
|
const PresenceIface = {
|
||||||
|
name: 'org.gnome.SessionManager.Presence',
|
||||||
|
methods: [{ name: 'SetStatus',
|
||||||
|
inSignature: 'u' }],
|
||||||
|
properties: [{ name: 'status',
|
||||||
|
signature: 'u',
|
||||||
|
access: 'readwrite' }],
|
||||||
|
signals: [{ name: 'StatusChanged',
|
||||||
|
inSignature: 'u' }]
|
||||||
|
};
|
||||||
|
|
||||||
|
const PresenceStatus = {
|
||||||
|
AVAILABLE: 0,
|
||||||
|
INVISIBLE: 1,
|
||||||
|
BUSY: 2,
|
||||||
|
IDLE: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
function Presence() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
Presence.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager/Presence', this);
|
||||||
|
},
|
||||||
|
|
||||||
|
getStatus: function(callback) {
|
||||||
|
this.GetRemote('status', Lang.bind(this,
|
||||||
|
function(status, ex) {
|
||||||
|
if (!ex)
|
||||||
|
callback(this, status);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
setStatus: function(status) {
|
||||||
|
this.SetStatusRemote(status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
DBus.proxifyPrototype(Presence.prototype, PresenceIface);
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// parse:
|
// parse:
|
||||||
// @params: caller-provided parameter object, or %null
|
// @params: caller-provided parameter object, or %null
|
||||||
// @default: function-provided defaults object
|
// @defaults: function-provided defaults object
|
||||||
// @allowExtras: whether or not to allow properties not in @default
|
// @allowExtras: whether or not to allow properties not in @default
|
||||||
//
|
//
|
||||||
// Examines @params and fills in default values from @defaults for
|
// Examines @params and fills in default values from @defaults for
|
||||||
@ -10,24 +10,26 @@
|
|||||||
// @allowExtras is not %true, it will throw an error if @params
|
// @allowExtras is not %true, it will throw an error if @params
|
||||||
// contains any properties that aren't in @defaults.
|
// contains any properties that aren't in @defaults.
|
||||||
//
|
//
|
||||||
// If @params is %null, this returns @defaults.
|
// If @params is %null, this returns the values from @defaults.
|
||||||
//
|
//
|
||||||
// Return value: the updated params
|
// Return value: a new object, containing the merged parameters from
|
||||||
|
// @params and @defaults
|
||||||
function parse(params, defaults, allowExtras) {
|
function parse(params, defaults, allowExtras) {
|
||||||
|
let ret = {}, prop;
|
||||||
|
|
||||||
if (!params)
|
if (!params)
|
||||||
return defaults;
|
params = {};
|
||||||
|
|
||||||
if (!allowExtras) {
|
for (prop in params) {
|
||||||
for (let prop in params) {
|
if (!(prop in defaults) && !allowExtras)
|
||||||
if (!(prop in defaults))
|
throw new Error('Unrecognized parameter "' + prop + '"');
|
||||||
throw new Error('Unrecognized parameter "' + prop + '"');
|
ret[prop] = params[prop];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let prop in defaults) {
|
for (prop in defaults) {
|
||||||
if (!(prop in params))
|
if (!(prop in params))
|
||||||
params[prop] = defaults[prop];
|
ret[prop] = defaults[prop];
|
||||||
}
|
}
|
||||||
|
|
||||||
return params;
|
return ret;
|
||||||
}
|
}
|
372
js/misc/telepathy.js
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const DBus = imports.dbus;
|
||||||
|
|
||||||
|
// D-Bus utils; should eventually move to gjs.
|
||||||
|
// https://bugzilla.gnome.org/show_bug.cgi?id=610859
|
||||||
|
|
||||||
|
function makeProxyClass(iface) {
|
||||||
|
let constructor = function() { this._init.apply(this, arguments); };
|
||||||
|
|
||||||
|
constructor.prototype._init = function(bus, name, path) {
|
||||||
|
bus.proxifyObject(this, name, path);
|
||||||
|
};
|
||||||
|
|
||||||
|
DBus.proxifyPrototype(constructor.prototype, iface);
|
||||||
|
return constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
function nameToPath(name) {
|
||||||
|
return '/' + name.replace('.', '/', 'g');
|
||||||
|
};
|
||||||
|
|
||||||
|
function pathToName(path) {
|
||||||
|
if (path[0] != '/')
|
||||||
|
throw new Error('not a D-Bus path: ' + path);
|
||||||
|
return path.substr(1).replace('/', '.', 'g');
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is tp_escape_as_identifier() from telepathy-glib
|
||||||
|
function escapeAsIdentifier(name) {
|
||||||
|
if (!name)
|
||||||
|
return '_';
|
||||||
|
|
||||||
|
// first char is replaced with _XX if it's non-alpha,
|
||||||
|
// later chars are replaced with _XX if they're non-alphanumeric
|
||||||
|
if (name.length == 1) {
|
||||||
|
return name.replace(/[^a-zA-Z]/, _hexEscape);
|
||||||
|
} else {
|
||||||
|
return (name[0].replace(/[^a-zA-Z]/, _hexEscape) +
|
||||||
|
name.substring(1).replace(/[^a-zA-Z0-9]/g, _hexEscape));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _hexEscape(ch) {
|
||||||
|
return '_' + ch.charCodeAt(0).toString(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Telepathy D-Bus interface definitions. Note that most of these are
|
||||||
|
// incomplete, and only cover the methods/properties/signals that
|
||||||
|
// we're currently using.
|
||||||
|
|
||||||
|
const TELEPATHY = 'org.freedesktop.Telepathy';
|
||||||
|
|
||||||
|
const CLIENT_NAME = TELEPATHY + '.Client';
|
||||||
|
const ClientIface = {
|
||||||
|
name: CLIENT_NAME,
|
||||||
|
properties: [
|
||||||
|
{ name: 'Interfaces',
|
||||||
|
signature: 'as',
|
||||||
|
access: 'read' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const CLIENT_APPROVER_NAME = TELEPATHY + '.Client.Approver';
|
||||||
|
const ClientApproverIface = {
|
||||||
|
name: CLIENT_APPROVER_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'AddDispatchOperation',
|
||||||
|
inSignature: 'a(oa{sv})oa{sv}',
|
||||||
|
outSignature: '' }
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{ name: 'ApproverChannelFilter',
|
||||||
|
signature: 'aa{sv}',
|
||||||
|
access: 'read' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const CLIENT_HANDLER_NAME = TELEPATHY + '.Client.Handler';
|
||||||
|
const ClientHandlerIface = {
|
||||||
|
name: CLIENT_HANDLER_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'HandleChannels',
|
||||||
|
inSignature: 'ooa(oa{sv})aota{sv}',
|
||||||
|
outSignature: '' }
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{ name: 'HandlerChannelFilter',
|
||||||
|
signature: 'aa{sv}',
|
||||||
|
access: 'read' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const CLIENT_OBSERVER_NAME = TELEPATHY + '.Client.Observer';
|
||||||
|
const ClientObserverIface = {
|
||||||
|
name: CLIENT_OBSERVER_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'ObserveChannels',
|
||||||
|
inSignature: 'ooa(oa{sv})oaoa{sv}',
|
||||||
|
outSignature: '' }
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{ name: 'ObserverChannelFilter',
|
||||||
|
signature: 'aa{sv}',
|
||||||
|
access: 'read' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const CHANNEL_DISPATCH_OPERATION_NAME = TELEPATHY + '.ChannelDispatchOperation';
|
||||||
|
const ChannelDispatchOperationIface = {
|
||||||
|
name: CHANNEL_DISPATCH_OPERATION_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'HandleWith',
|
||||||
|
inSignature: 's',
|
||||||
|
outSignature: '' },
|
||||||
|
{ name: 'Claim',
|
||||||
|
inSignature: '',
|
||||||
|
outSignature: '' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ChannelDispatchOperation = makeProxyClass(ChannelDispatchOperationIface);
|
||||||
|
|
||||||
|
const CONNECTION_NAME = TELEPATHY + '.Connection';
|
||||||
|
const ConnectionIface = {
|
||||||
|
name: CONNECTION_NAME,
|
||||||
|
signals: [
|
||||||
|
{ name: 'StatusChanged',
|
||||||
|
inSignature: 'uu' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let Connection = makeProxyClass(ConnectionIface);
|
||||||
|
|
||||||
|
const ConnectionStatus = {
|
||||||
|
CONNECTED: 0,
|
||||||
|
CONNECTING: 1,
|
||||||
|
DISCONNECTED: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
const CONNECTION_ALIASING_NAME = CONNECTION_NAME + '.Interface.Aliasing';
|
||||||
|
const ConnectionAliasingIface = {
|
||||||
|
name: CONNECTION_ALIASING_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'RequestAliases',
|
||||||
|
inSignature: 'au',
|
||||||
|
outSignature: 'as'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
signals: [
|
||||||
|
{ name: 'AliasesChanged',
|
||||||
|
inSignature: 'a(us)' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ConnectionAliasing = makeProxyClass(ConnectionAliasingIface);
|
||||||
|
|
||||||
|
const CONNECTION_AVATARS_NAME = CONNECTION_NAME + '.Interface.Avatars';
|
||||||
|
const ConnectionAvatarsIface = {
|
||||||
|
name: CONNECTION_AVATARS_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'GetKnownAvatarTokens',
|
||||||
|
inSignature: 'au',
|
||||||
|
outSignature: 'a{us}'
|
||||||
|
},
|
||||||
|
{ name: 'RequestAvatars',
|
||||||
|
inSignature: 'au',
|
||||||
|
outSignature: ''
|
||||||
|
}
|
||||||
|
],
|
||||||
|
signals: [
|
||||||
|
{ name: 'AvatarRetrieved',
|
||||||
|
inSignature: 'usays'
|
||||||
|
},
|
||||||
|
{ name: 'AvatarUpdated',
|
||||||
|
inSignature: 'us'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ConnectionAvatars = makeProxyClass(ConnectionAvatarsIface);
|
||||||
|
|
||||||
|
const CONNECTION_CONTACTS_NAME = CONNECTION_NAME + '.Interface.Contacts';
|
||||||
|
const ConnectionContactsIface = {
|
||||||
|
name: CONNECTION_CONTACTS_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'GetContactAttributes',
|
||||||
|
inSignature: 'auasb',
|
||||||
|
outSignature: 'a{ua{sv}}'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ConnectionContacts = makeProxyClass(ConnectionContactsIface);
|
||||||
|
|
||||||
|
const CONNECTION_REQUESTS_NAME = CONNECTION_NAME + '.Interface.Requests';
|
||||||
|
const ConnectionRequestsIface = {
|
||||||
|
name: CONNECTION_REQUESTS_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'CreateChannel',
|
||||||
|
inSignature: 'a{sv}',
|
||||||
|
outSignature: 'oa{sv}'
|
||||||
|
},
|
||||||
|
{ name: 'EnsureChannel',
|
||||||
|
inSignature: 'a{sv}',
|
||||||
|
outSignature: 'boa{sv}'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
properties: [
|
||||||
|
{ name: 'Channels',
|
||||||
|
signature: 'a(oa{sv})',
|
||||||
|
access: 'read' }
|
||||||
|
],
|
||||||
|
signals: [
|
||||||
|
{ name: 'NewChannels',
|
||||||
|
inSignature: 'a(oa{sv})'
|
||||||
|
},
|
||||||
|
{ name: 'ChannelClosed',
|
||||||
|
inSignature: 'o'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ConnectionRequests = makeProxyClass(ConnectionRequestsIface);
|
||||||
|
|
||||||
|
const CONNECTION_SIMPLE_PRESENCE_NAME = CONNECTION_NAME + '.Interface.SimplePresence';
|
||||||
|
const ConnectionSimplePresenceIface = {
|
||||||
|
name: CONNECTION_SIMPLE_PRESENCE_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'SetPresence',
|
||||||
|
inSignature: 'ss'
|
||||||
|
},
|
||||||
|
{ name: 'GetPresences',
|
||||||
|
inSignature: 'au',
|
||||||
|
outSignature: 'a{u(uss)}'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
signals: [
|
||||||
|
{ name: 'PresencesChanged',
|
||||||
|
inSignature: 'a{u(uss)}' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ConnectionSimplePresence = makeProxyClass(ConnectionSimplePresenceIface);
|
||||||
|
|
||||||
|
const ConnectionPresenceType = {
|
||||||
|
UNSET: 0,
|
||||||
|
OFFLINE: 1,
|
||||||
|
AVAILABLE: 2,
|
||||||
|
AWAY: 3,
|
||||||
|
EXTENDED_AWAY: 4,
|
||||||
|
HIDDEN: 5,
|
||||||
|
BUSY: 6,
|
||||||
|
UNKNOWN: 7,
|
||||||
|
ERROR: 8
|
||||||
|
};
|
||||||
|
|
||||||
|
const HandleType = {
|
||||||
|
NONE: 0,
|
||||||
|
CONTACT: 1,
|
||||||
|
ROOM: 2,
|
||||||
|
LIST: 3,
|
||||||
|
GROUP: 4
|
||||||
|
};
|
||||||
|
|
||||||
|
const CHANNEL_NAME = TELEPATHY + '.Channel';
|
||||||
|
const ChannelIface = {
|
||||||
|
name: CHANNEL_NAME,
|
||||||
|
signals: [
|
||||||
|
{ name: 'Closed',
|
||||||
|
inSignature: '' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let Channel = makeProxyClass(ChannelIface);
|
||||||
|
|
||||||
|
const CHANNEL_TEXT_NAME = CHANNEL_NAME + '.Type.Text';
|
||||||
|
const ChannelTextIface = {
|
||||||
|
name: CHANNEL_TEXT_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'ListPendingMessages',
|
||||||
|
inSignature: 'b',
|
||||||
|
outSignature: 'a(uuuuus)'
|
||||||
|
},
|
||||||
|
{ name: 'AcknowledgePendingMessages',
|
||||||
|
inSignature: 'au',
|
||||||
|
outSignature: ''
|
||||||
|
},
|
||||||
|
{ name: 'Send',
|
||||||
|
inSignature: 'us',
|
||||||
|
outSignature: ''
|
||||||
|
}
|
||||||
|
],
|
||||||
|
signals: [
|
||||||
|
{ name: 'Received',
|
||||||
|
inSignature: 'uuuuus' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ChannelText = makeProxyClass(ChannelTextIface);
|
||||||
|
|
||||||
|
const ChannelTextMessageType = {
|
||||||
|
NORMAL: 0,
|
||||||
|
ACTION: 1,
|
||||||
|
NOTICE: 2,
|
||||||
|
AUTO_REPLY: 3,
|
||||||
|
DELIVERY_REPORT: 4
|
||||||
|
};
|
||||||
|
|
||||||
|
const CHANNEL_CONTACT_LIST_NAME = CHANNEL_NAME + '.Type.ContactList';
|
||||||
|
// There is no interface associated with ContactList; it's just a
|
||||||
|
// special kind of Channel.Interface.Group
|
||||||
|
|
||||||
|
const CHANNEL_GROUP_NAME = CHANNEL_NAME + '.Interface.Group';
|
||||||
|
const ChannelGroupIface = {
|
||||||
|
name: CHANNEL_GROUP_NAME,
|
||||||
|
properties: [
|
||||||
|
{ name: 'Members',
|
||||||
|
signature: 'au',
|
||||||
|
access: 'read' }
|
||||||
|
],
|
||||||
|
signals: [
|
||||||
|
{ name: 'MembersChanged',
|
||||||
|
inSignature: 'sauauauauuu' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ChannelGroup = makeProxyClass(ChannelGroupIface);
|
||||||
|
|
||||||
|
const ACCOUNT_MANAGER_NAME = TELEPATHY + '.AccountManager';
|
||||||
|
const AccountManagerIface = {
|
||||||
|
name: ACCOUNT_MANAGER_NAME,
|
||||||
|
properties: [
|
||||||
|
{ name: 'ValidAccounts',
|
||||||
|
signature: 'ao',
|
||||||
|
access: 'read' }
|
||||||
|
],
|
||||||
|
signals: [
|
||||||
|
{ name: 'AccountValidityChanged',
|
||||||
|
inSignature: 'ob' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let AccountManager = makeProxyClass(AccountManagerIface);
|
||||||
|
|
||||||
|
const ACCOUNT_NAME = TELEPATHY + '.Account';
|
||||||
|
const AccountIface = {
|
||||||
|
name: ACCOUNT_NAME,
|
||||||
|
properties: [
|
||||||
|
{ name: 'Connection',
|
||||||
|
signature: 'o',
|
||||||
|
access: 'read' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let Account = makeProxyClass(AccountIface);
|
||||||
|
|
||||||
|
const CHANNEL_DISPATCHER_NAME = TELEPATHY + '.ChannelDispatcher';
|
||||||
|
const ChannelDispatcherIface = {
|
||||||
|
name: CHANNEL_DISPATCHER_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'EnsureChannel',
|
||||||
|
inSignature: 'oa{sv}xs',
|
||||||
|
outSignature: 'o' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ChannelDispatcher = makeProxyClass(ChannelDispatcherIface);
|
||||||
|
|
||||||
|
const CHANNEL_REQUEST_NAME = TELEPATHY + '.ChannelRequest';
|
||||||
|
const ChannelRequestIface = {
|
||||||
|
name: CHANNEL_REQUEST_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'Proceed',
|
||||||
|
inSignature: '',
|
||||||
|
outSignature: '' }
|
||||||
|
],
|
||||||
|
signals: [
|
||||||
|
{ name: 'Failed',
|
||||||
|
signature: 'ss' },
|
||||||
|
{ name: 'Succeeded',
|
||||||
|
signature: '' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let ChannelRequest = makeProxyClass(ChannelRequestIface);
|
4
js/perf/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
jsperfdir = $(pkgdatadir)/js/perf
|
||||||
|
|
||||||
|
dist_jsperf_DATA = \
|
||||||
|
core.js
|
140
js/perf/core.js
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const Scripting = imports.ui.scripting;
|
||||||
|
|
||||||
|
// This performance script measure the most important (core) performance
|
||||||
|
// metrics for the shell. By looking at the output metrics of this script
|
||||||
|
// someone should be able to get an idea of how well the shell is performing
|
||||||
|
// on a particular system.
|
||||||
|
|
||||||
|
let METRICS = {
|
||||||
|
overviewLatencyFirst:
|
||||||
|
{ description: "Time to first frame after triggering overview, first time",
|
||||||
|
units: "us" },
|
||||||
|
overviewFpsFirst:
|
||||||
|
{ description: "Frame rate when going to the overview, first time",
|
||||||
|
units: "frames / s" },
|
||||||
|
overviewLatencySubsequent:
|
||||||
|
{ description: "Time to first frame after triggering overview, second time",
|
||||||
|
units: "us"},
|
||||||
|
overviewFpsSubsequent:
|
||||||
|
{ description: "Frames rate when going to the overview, second time",
|
||||||
|
units: "frames / s" },
|
||||||
|
usedAfterOverview:
|
||||||
|
{ description: "Malloc'ed bytes after the overview is shown once",
|
||||||
|
units: "B" },
|
||||||
|
leakedAfterOverview:
|
||||||
|
{ description: "Additional malloc'ed bytes the second time the overview is shown",
|
||||||
|
units: "B" }
|
||||||
|
};
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
|
||||||
|
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
|
||||||
|
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
|
||||||
|
|
||||||
|
Main.overview.connect('shown', function() {
|
||||||
|
Scripting.scriptEvent('overviewShowDone');
|
||||||
|
});
|
||||||
|
|
||||||
|
yield Scripting.sleep(1000);
|
||||||
|
yield Scripting.waitLeisure();
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
Scripting.scriptEvent('overviewShowStart');
|
||||||
|
Main.overview.show();
|
||||||
|
|
||||||
|
yield Scripting.waitLeisure();
|
||||||
|
Main.overview.hide();
|
||||||
|
yield Scripting.waitLeisure();
|
||||||
|
|
||||||
|
global.gc();
|
||||||
|
yield Scripting.sleep(1000);
|
||||||
|
Scripting.collectStatistics();
|
||||||
|
Scripting.scriptEvent('afterShowHide');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let showingOverview = false;
|
||||||
|
let finishedShowingOverview = false;
|
||||||
|
let overviewShowStart;
|
||||||
|
let overviewFrames;
|
||||||
|
let overviewLatency;
|
||||||
|
let mallocUsedSize = 0;
|
||||||
|
let overviewShowCount = 0;
|
||||||
|
let firstOverviewUsedSize;
|
||||||
|
let haveSwapComplete = false;
|
||||||
|
|
||||||
|
function script_overviewShowStart(time) {
|
||||||
|
showingOverview = true;
|
||||||
|
finishedShowingOverview = false;
|
||||||
|
overviewShowStart = time;
|
||||||
|
overviewFrames = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function script_overviewShowDone(time) {
|
||||||
|
// We've set up the state at the end of the zoom out, but we
|
||||||
|
// need to wait for one more frame to paint before we count
|
||||||
|
// ourselves as done.
|
||||||
|
finishedShowingOverview = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function script_afterShowHide(time) {
|
||||||
|
if (overviewShowCount == 1) {
|
||||||
|
METRICS.usedAfterOverview.value = mallocUsedSize;
|
||||||
|
} else {
|
||||||
|
METRICS.leakedAfterOverview.value = mallocUsedSize - METRICS.usedAfterOverview.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function malloc_usedSize(time, bytes) {
|
||||||
|
mallocUsedSize = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _frameDone(time) {
|
||||||
|
if (showingOverview) {
|
||||||
|
if (overviewFrames == 0)
|
||||||
|
overviewLatency = time - overviewShowStart;
|
||||||
|
|
||||||
|
overviewFrames++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (finishedShowingOverview) {
|
||||||
|
showingOverview = false;
|
||||||
|
finishedShowingOverview = false;
|
||||||
|
overviewShowCount++;
|
||||||
|
|
||||||
|
let dt = (time - (overviewShowStart + overviewLatency)) / 1000000;
|
||||||
|
|
||||||
|
// If we see a start frame and an end frame, that would
|
||||||
|
// be 1 frame for a FPS computation, hence the '- 1'
|
||||||
|
let fps = (overviewFrames - 1) / dt;
|
||||||
|
|
||||||
|
if (overviewShowCount == 1) {
|
||||||
|
METRICS.overviewLatencyFirst.value = overviewLatency;
|
||||||
|
METRICS.overviewFpsFirst.value = fps;
|
||||||
|
} else {
|
||||||
|
METRICS.overviewLatencySubsequent.value = overviewLatency;
|
||||||
|
METRICS.overviewFpsSubsequent.value = fps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function glx_swapComplete(time, swapTime) {
|
||||||
|
haveSwapComplete = true;
|
||||||
|
|
||||||
|
_frameDone(swapTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clutter_stagePaintDone(time) {
|
||||||
|
// If we aren't receiving GLXBufferSwapComplete events, then we approximate
|
||||||
|
// the time the user sees a frame with the time we finished doing drawing
|
||||||
|
// commands for the frame. This doesn't take into account the time for
|
||||||
|
// the GPU to finish painting, and the time for waiting for the buffer
|
||||||
|
// swap, but if this are uniform - every frame takes the same time to draw -
|
||||||
|
// then it won't upset our FPS calculation, though the latency value
|
||||||
|
// will be slightly too low.
|
||||||
|
|
||||||
|
if (!haveSwapComplete)
|
||||||
|
_frameDone(time);
|
||||||
|
}
|
4
js/prefs/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
jsprefsdir = $(pkgdatadir)/js/prefs
|
||||||
|
|
||||||
|
dist_jsprefs_DATA = \
|
||||||
|
clockPreferences.js
|
97
js/prefs/clockPreferences.js
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
const Gettext = imports.gettext;
|
||||||
|
|
||||||
|
const FORMAT_KEY = 'format';
|
||||||
|
const SHOW_DATE_KEY = 'show-date';
|
||||||
|
const SHOW_SECONDS_KEY = 'show-seconds';
|
||||||
|
|
||||||
|
|
||||||
|
function ClockPreferences(uiFile) {
|
||||||
|
this._init(uiFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
ClockPreferences.prototype = {
|
||||||
|
_init: function(uiFile) {
|
||||||
|
let builder = new Gtk.Builder();
|
||||||
|
builder.add_from_file(uiFile);
|
||||||
|
|
||||||
|
this._dialog = builder.get_object('prefs-dialog');
|
||||||
|
this._dialog.connect('response', Lang.bind(this, this._onResponse));
|
||||||
|
|
||||||
|
this._12hrRadio = builder.get_object('12hr_radio');
|
||||||
|
this._24hrRadio = builder.get_object('24hr_radio');
|
||||||
|
this._dateCheck = builder.get_object('date_check');
|
||||||
|
this._secondsCheck = builder.get_object('seconds_check');
|
||||||
|
|
||||||
|
delete builder;
|
||||||
|
|
||||||
|
this._settings = new Gio.Settings({ schema: 'org.gnome.shell.clock' });
|
||||||
|
this._notifyId = this._settings.connect('changed',
|
||||||
|
Lang.bind(this,
|
||||||
|
this._updateDialog));
|
||||||
|
|
||||||
|
this._12hrRadio.connect('toggled', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
let format = this._12hrRadio.active ? '12-hour' : '24-hour';
|
||||||
|
this._settings.set_string(FORMAT_KEY, format);
|
||||||
|
}));
|
||||||
|
this._dateCheck.connect('toggled', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._settings.set_boolean(SHOW_DATE_KEY,
|
||||||
|
this._dateCheck.active);
|
||||||
|
}));
|
||||||
|
this._secondsCheck.connect('toggled', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._settings.set_boolean(SHOW_SECONDS_KEY,
|
||||||
|
this._secondsCheck.active);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._updateDialog();
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
this._dialog.show_all();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateDialog: function() {
|
||||||
|
let format = this._settings.get_string(FORMAT_KEY);
|
||||||
|
this._12hrRadio.active = (format == "12-hour");
|
||||||
|
this._24hrRadio.active = (format == "24-hour");
|
||||||
|
|
||||||
|
this._dateCheck.active = this._settings.get_boolean(SHOW_DATE_KEY);
|
||||||
|
this._secondsCheck.active = this._settings.get_boolean(SHOW_SECONDS_KEY);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onResponse: function() {
|
||||||
|
this._dialog.destroy();
|
||||||
|
this._settings.disconnect(this._notifyId);
|
||||||
|
this.emit('destroy');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Signals.addSignalMethods(ClockPreferences.prototype);
|
||||||
|
|
||||||
|
function main(params) {
|
||||||
|
if ('progName' in params)
|
||||||
|
GLib.set_prgname(params['progName']);
|
||||||
|
if ('localeDir' in params)
|
||||||
|
Gettext.bindtextdomain('gnome-shell', params['localeDir']);
|
||||||
|
|
||||||
|
Gtk.init(null, null);
|
||||||
|
|
||||||
|
let clockPrefs = new ClockPreferences(params['uiFile']);
|
||||||
|
clockPrefs.connect('destroy',
|
||||||
|
function() {
|
||||||
|
Gtk.main_quit();
|
||||||
|
});
|
||||||
|
clockPrefs.show();
|
||||||
|
|
||||||
|
Gtk.main();
|
||||||
|
}
|
@ -4,30 +4,36 @@ dist_jsui_DATA = \
|
|||||||
altTab.js \
|
altTab.js \
|
||||||
appDisplay.js \
|
appDisplay.js \
|
||||||
appFavorites.js \
|
appFavorites.js \
|
||||||
|
boxpointer.js \
|
||||||
calendar.js \
|
calendar.js \
|
||||||
chrome.js \
|
chrome.js \
|
||||||
dash.js \
|
dash.js \
|
||||||
dnd.js \
|
dnd.js \
|
||||||
docDisplay.js \
|
docDisplay.js \
|
||||||
environment.js \
|
environment.js \
|
||||||
extensionSystem.js \
|
extensionSystem.js \
|
||||||
genericDisplay.js \
|
genericDisplay.js \
|
||||||
lightbox.js \
|
lightbox.js \
|
||||||
link.js \
|
link.js \
|
||||||
lookingGlass.js \
|
lookingGlass.js \
|
||||||
|
magnifier.js \
|
||||||
|
magnifierDBus.js \
|
||||||
main.js \
|
main.js \
|
||||||
messageTray.js \
|
messageTray.js \
|
||||||
notificationDaemon.js \
|
notificationDaemon.js \
|
||||||
overview.js \
|
overview.js \
|
||||||
panel.js \
|
panel.js \
|
||||||
placeDisplay.js \
|
placeDisplay.js \
|
||||||
|
popupMenu.js \
|
||||||
runDialog.js \
|
runDialog.js \
|
||||||
search.js \
|
scripting.js \
|
||||||
|
search.js \
|
||||||
shellDBus.js \
|
shellDBus.js \
|
||||||
sidebar.js \
|
|
||||||
statusMenu.js \
|
statusMenu.js \
|
||||||
|
telepathyClient.js \
|
||||||
tweener.js \
|
tweener.js \
|
||||||
widget.js \
|
windowAttentionHandler.js \
|
||||||
widgetBox.js \
|
|
||||||
windowManager.js \
|
windowManager.js \
|
||||||
workspaces.js
|
workspacesView.js \
|
||||||
|
workspaceSwitcherPopup.js \
|
||||||
|
workspace.js
|
||||||
|
502
js/ui/altTab.js
@ -1,6 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
@ -14,21 +13,17 @@ const St = imports.gi.St;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const POPUP_ARROW_COLOR = new Clutter.Color();
|
|
||||||
POPUP_ARROW_COLOR.from_pixel(0xffffffff);
|
|
||||||
const POPUP_UNFOCUSED_ARROW_COLOR = new Clutter.Color();
|
|
||||||
POPUP_UNFOCUSED_ARROW_COLOR.from_pixel(0x808080ff);
|
|
||||||
const TRANSPARENT_COLOR = new Clutter.Color();
|
|
||||||
TRANSPARENT_COLOR.from_pixel(0x00000000);
|
|
||||||
|
|
||||||
const POPUP_APPICON_SIZE = 96;
|
const POPUP_APPICON_SIZE = 96;
|
||||||
const POPUP_LIST_SPACING = 8;
|
const POPUP_SCROLL_TIME = 0.10; // seconds
|
||||||
|
const POPUP_FADE_TIME = 0.1; // seconds
|
||||||
|
|
||||||
const DISABLE_HOVER_TIMEOUT = 500; // milliseconds
|
const DISABLE_HOVER_TIMEOUT = 500; // milliseconds
|
||||||
|
|
||||||
const THUMBNAIL_SIZE = 256;
|
const THUMBNAIL_DEFAULT_SIZE = 256;
|
||||||
const THUMBNAIL_POPUP_TIME = 500; // milliseconds
|
const THUMBNAIL_POPUP_TIME = 500; // milliseconds
|
||||||
const THUMBNAIL_FADE_TIME = 0.2; // seconds
|
const THUMBNAIL_FADE_TIME = 0.1; // seconds
|
||||||
|
|
||||||
|
const iconSizes = [96, 64, 48, 32, 22];
|
||||||
|
|
||||||
function mod(a, b) {
|
function mod(a, b) {
|
||||||
return (a + b) % b;
|
return (a + b) % b;
|
||||||
@ -40,18 +35,19 @@ function AltTabPopup() {
|
|||||||
|
|
||||||
AltTabPopup.prototype = {
|
AltTabPopup.prototype = {
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this.actor = new Clutter.Group({ reactive: true,
|
this.actor = new Shell.GenericContainer({ name: 'altTabPopup',
|
||||||
x: 0,
|
reactive: true });
|
||||||
y: 0,
|
|
||||||
width: global.screen_width,
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
height: global.screen_height });
|
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
|
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
this._haveModal = false;
|
this._haveModal = false;
|
||||||
|
|
||||||
this._currentApp = 0;
|
this._currentApp = 0;
|
||||||
this._currentWindow = 0;
|
this._currentWindow = -1;
|
||||||
this._thumbnailTimeoutId = 0;
|
this._thumbnailTimeoutId = 0;
|
||||||
this._motionTimeoutId = 0;
|
this._motionTimeoutId = 0;
|
||||||
|
|
||||||
@ -59,12 +55,73 @@ AltTabPopup.prototype = {
|
|||||||
// the switcher appears underneath the current pointer location
|
// the switcher appears underneath the current pointer location
|
||||||
this._disableHover();
|
this._disableHover();
|
||||||
|
|
||||||
global.stage.add_actor(this.actor);
|
Main.uiGroup.add_actor(this.actor);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredWidth: function (actor, forHeight, alloc) {
|
||||||
|
alloc.min_size = global.screen_width;
|
||||||
|
alloc.natural_size = global.screen_width;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||||
|
alloc.min_size = global.screen_height;
|
||||||
|
alloc.natural_size = global.screen_height;
|
||||||
|
},
|
||||||
|
|
||||||
|
_allocate: function (actor, box, flags) {
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
let primary = global.get_primary_monitor();
|
||||||
|
|
||||||
|
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
||||||
|
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||||
|
let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||||
|
let vPadding = this.actor.get_theme_node().get_vertical_padding();
|
||||||
|
let hPadding = leftPadding + rightPadding;
|
||||||
|
|
||||||
|
// Allocate the appSwitcher
|
||||||
|
// We select a size based on an icon size that does not overflow the screen
|
||||||
|
let [childMinHeight, childNaturalHeight] = this._appSwitcher.actor.get_preferred_height(primary.width - hPadding);
|
||||||
|
let [childMinWidth, childNaturalWidth] = this._appSwitcher.actor.get_preferred_width(childNaturalHeight);
|
||||||
|
childBox.x1 = Math.max(primary.x + leftPadding, primary.x + Math.floor((primary.width - childNaturalWidth) / 2));
|
||||||
|
childBox.x2 = Math.min(childBox.x1 + primary.width - hPadding, childBox.x1 + childNaturalWidth);
|
||||||
|
childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
|
||||||
|
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||||
|
this._appSwitcher.actor.allocate(childBox, flags);
|
||||||
|
|
||||||
|
// Allocate the thumbnails
|
||||||
|
// We try to avoid overflowing the screen so we base the resulting size on
|
||||||
|
// those calculations
|
||||||
|
if (this._thumbnails) {
|
||||||
|
let icon = this._appIcons[this._currentApp].actor;
|
||||||
|
// Force a stage relayout to make sure we get the correct position
|
||||||
|
global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, 0, 0);
|
||||||
|
let [posX, posY] = icon.get_transformed_position();
|
||||||
|
let thumbnailCenter = posX + icon.width / 2;
|
||||||
|
let [childMinWidth, childNaturalWidth] = this._thumbnails.actor.get_preferred_width(-1);
|
||||||
|
childBox.x1 = Math.max(primary.x + leftPadding, Math.floor(thumbnailCenter - childNaturalWidth / 2));
|
||||||
|
if (childBox.x1 + childNaturalWidth > primary.x + primary.width - hPadding) {
|
||||||
|
let offset = childBox.x1 + childNaturalWidth - primary.width + hPadding;
|
||||||
|
childBox.x1 = Math.max(primary.x + leftPadding, childBox.x1 - offset - hPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
let [found, spacing] = this.actor.get_theme_node().get_length('spacing', false);
|
||||||
|
if (!found)
|
||||||
|
spacing = 0;
|
||||||
|
|
||||||
|
childBox.x2 = childBox.x1 + childNaturalWidth;
|
||||||
|
if (childBox.x2 > primary.x + primary.width - rightPadding)
|
||||||
|
childBox.x2 = primary.x + primary.width - rightPadding;
|
||||||
|
childBox.y1 = this._appSwitcher.actor.allocation.y2 + spacing;
|
||||||
|
this._thumbnails.addClones(primary.height - bottomPadding - childBox.y1);
|
||||||
|
let [childMinHeight, childNaturalHeight] = this._thumbnails.actor.get_preferred_height(-1);
|
||||||
|
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||||
|
this._thumbnails.actor.allocate(childBox, flags);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
show : function(backward) {
|
show : function(backward) {
|
||||||
let tracker = Shell.WindowTracker.get_default();
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
let apps = tracker.get_running_apps ("");
|
let apps = tracker.get_running_apps ('');
|
||||||
|
|
||||||
if (!apps.length)
|
if (!apps.length)
|
||||||
return false;
|
return false;
|
||||||
@ -84,10 +141,6 @@ AltTabPopup.prototype = {
|
|||||||
this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
|
this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
|
||||||
this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
|
this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
|
||||||
|
|
||||||
let primary = global.get_primary_monitor();
|
|
||||||
this._appSwitcher.actor.x = primary.x + Math.floor((primary.width - this._appSwitcher.actor.width) / 2);
|
|
||||||
this._appSwitcher.actor.y = primary.y + Math.floor((primary.height - this._appSwitcher.actor.height) / 2);
|
|
||||||
|
|
||||||
this._appIcons = this._appSwitcher.icons;
|
this._appIcons = this._appSwitcher.icons;
|
||||||
|
|
||||||
// Make the initial selection
|
// Make the initial selection
|
||||||
@ -112,8 +165,9 @@ AltTabPopup.prototype = {
|
|||||||
this._select(0, 1, true);
|
this._select(0, 1, true);
|
||||||
else
|
else
|
||||||
this._select(1);
|
this._select(1);
|
||||||
} else
|
} else {
|
||||||
this._select(1);
|
this._select(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// There's a race condition; if the user released Alt before
|
// There's a race condition; if the user released Alt before
|
||||||
@ -121,12 +175,20 @@ AltTabPopup.prototype = {
|
|||||||
// https://bugzilla.gnome.org/show_bug.cgi?id=596695 for
|
// https://bugzilla.gnome.org/show_bug.cgi?id=596695 for
|
||||||
// details.) So we check now. (Have to do this after updating
|
// details.) So we check now. (Have to do this after updating
|
||||||
// selection.)
|
// selection.)
|
||||||
let mods = global.get_modifier_keys();
|
let [x, y, mods] = global.get_pointer();
|
||||||
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
|
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
|
||||||
this._finish();
|
this._finish();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.actor.opacity = 0;
|
||||||
|
this.actor.show();
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: POPUP_FADE_TIME,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -138,10 +200,16 @@ AltTabPopup.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_nextWindow : function() {
|
_nextWindow : function() {
|
||||||
|
// We actually want the second window if we're in the unset state
|
||||||
|
if (this._currentWindow == -1)
|
||||||
|
this._currentWindow = 0;
|
||||||
return mod(this._currentWindow + 1,
|
return mod(this._currentWindow + 1,
|
||||||
this._appIcons[this._currentApp].cachedWindows.length);
|
this._appIcons[this._currentApp].cachedWindows.length);
|
||||||
},
|
},
|
||||||
_previousWindow : function() {
|
_previousWindow : function() {
|
||||||
|
// Also assume second window here
|
||||||
|
if (this._currentWindow == -1)
|
||||||
|
this._currentWindow = 1;
|
||||||
return mod(this._currentWindow - 1,
|
return mod(this._currentWindow - 1,
|
||||||
this._appIcons[this._currentApp].cachedWindows.length);
|
this._appIcons[this._currentApp].cachedWindows.length);
|
||||||
},
|
},
|
||||||
@ -161,7 +229,7 @@ AltTabPopup.prototype = {
|
|||||||
this.destroy();
|
this.destroy();
|
||||||
else if (this._thumbnailsFocused) {
|
else if (this._thumbnailsFocused) {
|
||||||
if (keysym == Clutter.Tab) {
|
if (keysym == Clutter.Tab) {
|
||||||
if (shift && this._currentWindow == 0)
|
if (shift && (this._currentWindow == 0 || this._currentWindow == -1))
|
||||||
this._select(this._previousApp());
|
this._select(this._previousApp());
|
||||||
else if (!shift && this._currentWindow == this._appIcons[this._currentApp].cachedWindows.length - 1)
|
else if (!shift && this._currentWindow == this._appIcons[this._currentApp].cachedWindows.length - 1)
|
||||||
this._select(this._nextApp());
|
this._select(this._nextApp());
|
||||||
@ -181,7 +249,7 @@ AltTabPopup.prototype = {
|
|||||||
else if (keysym == Clutter.Right || keysym == Clutter.d)
|
else if (keysym == Clutter.Right || keysym == Clutter.d)
|
||||||
this._select(this._nextApp());
|
this._select(this._nextApp());
|
||||||
else if (keysym == Clutter.Down || keysym == Clutter.s)
|
else if (keysym == Clutter.Down || keysym == Clutter.s)
|
||||||
this._select(this._currentApp, this._currentWindow);
|
this._select(this._currentApp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -200,7 +268,7 @@ AltTabPopup.prototype = {
|
|||||||
let direction = event.get_scroll_direction();
|
let direction = event.get_scroll_direction();
|
||||||
if (direction == Clutter.ScrollDirection.UP) {
|
if (direction == Clutter.ScrollDirection.UP) {
|
||||||
if (this._thumbnailsFocused) {
|
if (this._thumbnailsFocused) {
|
||||||
if (this._currentWindow == 0)
|
if (this._currentWindow == 0 || this._currentWindow == -1)
|
||||||
this._select(this._previousApp());
|
this._select(this._previousApp());
|
||||||
else
|
else
|
||||||
this._select(this._currentApp, this._previousWindow());
|
this._select(this._currentApp, this._previousWindow());
|
||||||
@ -234,10 +302,17 @@ AltTabPopup.prototype = {
|
|||||||
_appActivated : function(appSwitcher, n) {
|
_appActivated : function(appSwitcher, n) {
|
||||||
// If the user clicks on the selected app, activate the
|
// If the user clicks on the selected app, activate the
|
||||||
// selected window; otherwise (eg, they click on an app while
|
// selected window; otherwise (eg, they click on an app while
|
||||||
// !mouseActive) activate the first window of the clicked-on
|
// !mouseActive) activate the the clicked-on app.
|
||||||
// app.
|
if (n == this._currentApp) {
|
||||||
let window = (n == this._currentApp) ? this._currentWindow : 0;
|
let window;
|
||||||
Main.activateWindow(this._appIcons[n].cachedWindows[window]);
|
if (this._currentWindow >= 0)
|
||||||
|
window = this._appIcons[this._currentApp].cachedWindows[this._currentWindow];
|
||||||
|
else
|
||||||
|
window = null;
|
||||||
|
this._appIcons[this._currentApp].app.activate_window(window, global.get_current_time());
|
||||||
|
} else {
|
||||||
|
this._appIcons[n].app.activate_window(null, global.get_current_time());
|
||||||
|
}
|
||||||
this.destroy();
|
this.destroy();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -249,7 +324,8 @@ AltTabPopup.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_windowActivated : function(thumbnailList, n) {
|
_windowActivated : function(thumbnailList, n) {
|
||||||
Main.activateWindow(this._appIcons[this._currentApp].cachedWindows[n]);
|
let appIcon = this._appIcons[this._currentApp];
|
||||||
|
Main.activateWindow(appIcon.cachedWindows[n]);
|
||||||
this.destroy();
|
this.destroy();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -276,19 +352,33 @@ AltTabPopup.prototype = {
|
|||||||
|
|
||||||
_finish : function() {
|
_finish : function() {
|
||||||
let app = this._appIcons[this._currentApp];
|
let app = this._appIcons[this._currentApp];
|
||||||
let window = app.cachedWindows[this._currentWindow];
|
if (this._currentWindow >= 0) {
|
||||||
Main.activateWindow(window);
|
Main.activateWindow(app.cachedWindows[this._currentWindow]);
|
||||||
|
} else {
|
||||||
|
app.app.activate_window(null, global.get_current_time());
|
||||||
|
}
|
||||||
this.destroy();
|
this.destroy();
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy : function() {
|
destroy : function() {
|
||||||
this.actor.destroy();
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: POPUP_FADE_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this.actor.destroy();
|
||||||
|
})
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy : function() {
|
_onDestroy : function() {
|
||||||
if (this._haveModal)
|
if (this._haveModal)
|
||||||
Main.popModal(this.actor);
|
Main.popModal(this.actor);
|
||||||
|
|
||||||
|
if (this._thumbnails)
|
||||||
|
this._destroyThumbnails();
|
||||||
|
|
||||||
if (this._keyPressEventId)
|
if (this._keyPressEventId)
|
||||||
global.stage.disconnect(this._keyPressEventId);
|
global.stage.disconnect(this._keyPressEventId);
|
||||||
if (this._keyReleaseEventId)
|
if (this._keyReleaseEventId)
|
||||||
@ -339,7 +429,7 @@ AltTabPopup.prototype = {
|
|||||||
this._thumbnailsFocused = (window != null) && !forceAppFocus;
|
this._thumbnailsFocused = (window != null) && !forceAppFocus;
|
||||||
|
|
||||||
this._currentApp = app;
|
this._currentApp = app;
|
||||||
this._currentWindow = window ? window : 0;
|
this._currentWindow = window ? window : -1;
|
||||||
this._appSwitcher.highlight(app, this._thumbnailsFocused);
|
this._appSwitcher.highlight(app, this._thumbnailsFocused);
|
||||||
|
|
||||||
if (window != null) {
|
if (window != null) {
|
||||||
@ -351,18 +441,23 @@ AltTabPopup.prototype = {
|
|||||||
!forceAppFocus) {
|
!forceAppFocus) {
|
||||||
this._thumbnailTimeoutId = Mainloop.timeout_add (
|
this._thumbnailTimeoutId = Mainloop.timeout_add (
|
||||||
THUMBNAIL_POPUP_TIME,
|
THUMBNAIL_POPUP_TIME,
|
||||||
Lang.bind(this, function () {
|
Lang.bind(this, this._timeoutPopupThumbnails));
|
||||||
this._select(this._currentApp, 0, true);
|
|
||||||
return false;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_timeoutPopupThumbnails: function() {
|
||||||
|
if (!this._thumbnails)
|
||||||
|
this._createThumbnails();
|
||||||
|
this._thumbnailTimeoutId = 0;
|
||||||
|
this._thumbnailsFocused = false;
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
_destroyThumbnails : function() {
|
_destroyThumbnails : function() {
|
||||||
Tweener.addTween(this._thumbnails.actor,
|
Tweener.addTween(this._thumbnails.actor,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
time: THUMBNAIL_FADE_TIME,
|
time: THUMBNAIL_FADE_TIME,
|
||||||
transition: "easeOutQuad",
|
transition: 'easeOutQuad',
|
||||||
onComplete: function() { this.destroy(); }
|
onComplete: function() { this.destroy(); }
|
||||||
});
|
});
|
||||||
this._thumbnails = null;
|
this._thumbnails = null;
|
||||||
@ -375,38 +470,11 @@ AltTabPopup.prototype = {
|
|||||||
|
|
||||||
this.actor.add_actor(this._thumbnails.actor);
|
this.actor.add_actor(this._thumbnails.actor);
|
||||||
|
|
||||||
let thumbnailCenter;
|
|
||||||
if (this._thumbnails.actor.width < this._appSwitcher.actor.width) {
|
|
||||||
// Center the thumbnails under the corresponding AppIcon.
|
|
||||||
// If this is being called when the switcher is first
|
|
||||||
// being brought up, then nothing will have been assigned
|
|
||||||
// an allocation yet, and the get_transformed_position()
|
|
||||||
// call will return 0,0.
|
|
||||||
// (http://bugzilla.openedhand.com/show_bug.cgi?id=1115).
|
|
||||||
// Calling clutter_actor_get_allocation_box() would force
|
|
||||||
// it to properly allocate itself, but we can't call that
|
|
||||||
// because it has an out-caller-allocates arg. So we use
|
|
||||||
// clutter_stage_get_actor_at_pos(), which will force a
|
|
||||||
// reallocation as a side effect.
|
|
||||||
global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, 0, 0);
|
|
||||||
|
|
||||||
let icon = this._appIcons[this._currentApp].actor;
|
|
||||||
let [stageX, stageY] = icon.get_transformed_position();
|
|
||||||
thumbnailCenter = stageX + icon.width / 2;
|
|
||||||
} else {
|
|
||||||
// Center the thumbnails on the monitor
|
|
||||||
let primary = global.get_primary_monitor();
|
|
||||||
thumbnailCenter = primary.x + primary.width / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._thumbnails.actor.x = Math.floor(thumbnailCenter - this._thumbnails.actor.width / 2);
|
|
||||||
this._thumbnails.actor.y = this._appSwitcher.actor.y + this._appSwitcher.actor.height + POPUP_LIST_SPACING;
|
|
||||||
|
|
||||||
this._thumbnails.actor.opacity = 0;
|
this._thumbnails.actor.opacity = 0;
|
||||||
Tweener.addTween(this._thumbnails.actor,
|
Tweener.addTween(this._thumbnails.actor,
|
||||||
{ opacity: 255,
|
{ opacity: 255,
|
||||||
time: THUMBNAIL_FADE_TIME,
|
time: THUMBNAIL_FADE_TIME,
|
||||||
transition: "easeOutQuad"
|
transition: 'easeOutQuad'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -417,23 +485,100 @@ function SwitcherList(squareItems) {
|
|||||||
|
|
||||||
SwitcherList.prototype = {
|
SwitcherList.prototype = {
|
||||||
_init : function(squareItems) {
|
_init : function(squareItems) {
|
||||||
this.actor = new St.Bin({ style_class: 'switcher-list' });
|
this.actor = new Shell.GenericContainer({ style_class: 'switcher-list' });
|
||||||
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
|
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
|
this.actor.connect('allocate', Lang.bind(this, this._allocateTop));
|
||||||
|
|
||||||
// Here we use a GenericContainer so that we can force all the
|
// Here we use a GenericContainer so that we can force all the
|
||||||
// children except the separator to have the same width.
|
// children except the separator to have the same width.
|
||||||
this._list = new Shell.GenericContainer();
|
this._list = new Shell.GenericContainer({ style_class: 'switcher-list-item-container' });
|
||||||
this._list.spacing = POPUP_LIST_SPACING;
|
this._list.spacing = 0;
|
||||||
|
this._list.connect('style-changed', Lang.bind(this, function() {
|
||||||
|
let [found, spacing] = this._list.get_theme_node().get_length('spacing', false);
|
||||||
|
this._list.spacing = (found) ? spacing : 0;
|
||||||
|
}));
|
||||||
|
|
||||||
this._list.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
this._list.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
this._list.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
this._list.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
this._list.connect('allocate', Lang.bind(this, this._allocate));
|
this._list.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
|
|
||||||
this.actor.add_actor(this._list);
|
this._clipBin = new St.Bin({style_class: 'cbin'});
|
||||||
|
this._clipBin.child = this._list;
|
||||||
|
this.actor.add_actor(this._clipBin);
|
||||||
|
|
||||||
|
this._leftGradient = new St.BoxLayout({style_class: 'thumbnail-scroll-gradient-left', vertical: true});
|
||||||
|
this._rightGradient = new St.BoxLayout({style_class: 'thumbnail-scroll-gradient-right', vertical: true});
|
||||||
|
this.actor.add_actor(this._leftGradient);
|
||||||
|
this.actor.add_actor(this._rightGradient);
|
||||||
|
|
||||||
|
// Those arrows indicate whether scrolling in one direction is possible
|
||||||
|
this._leftArrow = new St.DrawingArea({ style_class: 'switcher-arrow',
|
||||||
|
pseudo_class: 'highlighted' });
|
||||||
|
this._leftArrow.connect('repaint', Lang.bind(this,
|
||||||
|
function (area) {
|
||||||
|
Shell.draw_box_pointer(area, Shell.PointerDirection.LEFT);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._rightArrow = new St.DrawingArea({ style_class: 'switcher-arrow',
|
||||||
|
pseudo_class: 'highlighted' });
|
||||||
|
this._rightArrow.connect('repaint', Lang.bind(this,
|
||||||
|
function (area) {
|
||||||
|
Shell.draw_box_pointer(area, Shell.PointerDirection.RIGHT);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.actor.add_actor(this._leftArrow);
|
||||||
|
this.actor.add_actor(this._rightArrow);
|
||||||
|
|
||||||
this._items = [];
|
this._items = [];
|
||||||
this._highlighted = -1;
|
this._highlighted = -1;
|
||||||
this._separator = null;
|
this._separator = null;
|
||||||
this._squareItems = squareItems;
|
this._squareItems = squareItems;
|
||||||
|
this._minSize = 0;
|
||||||
|
this._scrollableRight = true;
|
||||||
|
this._scrollableLeft = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_allocateTop: function(actor, box, flags) {
|
||||||
|
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
||||||
|
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||||
|
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
let scrollable = this._minSize > box.x2 - box.x1;
|
||||||
|
|
||||||
|
this._clipBin.allocate(box, flags);
|
||||||
|
|
||||||
|
childBox.x1 = 0;
|
||||||
|
childBox.y1 = 0;
|
||||||
|
childBox.x2 = this._leftGradient.width;
|
||||||
|
childBox.y2 = this.actor.height;
|
||||||
|
this._leftGradient.allocate(childBox, flags);
|
||||||
|
this._leftGradient.opacity = (this._scrollableLeft && scrollable) ? 255 : 0;
|
||||||
|
|
||||||
|
childBox.x1 = (this.actor.allocation.x2 - this.actor.allocation.x1) - this._rightGradient.width;
|
||||||
|
childBox.y1 = 0;
|
||||||
|
childBox.x2 = childBox.x1 + this._rightGradient.width;
|
||||||
|
childBox.y2 = this.actor.height;
|
||||||
|
this._rightGradient.allocate(childBox, flags);
|
||||||
|
this._rightGradient.opacity = (this._scrollableRight && scrollable) ? 255 : 0;
|
||||||
|
|
||||||
|
let arrowWidth = Math.floor(leftPadding / 3);
|
||||||
|
let arrowHeight = arrowWidth * 2;
|
||||||
|
childBox.x1 = leftPadding / 2;
|
||||||
|
childBox.y1 = this.actor.height / 2 - arrowWidth;
|
||||||
|
childBox.x2 = childBox.x1 + arrowWidth;
|
||||||
|
childBox.y2 = childBox.y1 + arrowHeight;
|
||||||
|
this._leftArrow.allocate(childBox, flags);
|
||||||
|
this._leftArrow.opacity = this._leftGradient.opacity;
|
||||||
|
|
||||||
|
arrowWidth = Math.floor(rightPadding / 3);
|
||||||
|
arrowHeight = arrowWidth * 2;
|
||||||
|
childBox.x1 = this.actor.width - arrowWidth - rightPadding / 2;
|
||||||
|
childBox.y1 = this.actor.height / 2 - arrowWidth;
|
||||||
|
childBox.x2 = childBox.x1 + arrowWidth;
|
||||||
|
childBox.y2 = childBox.y1 + arrowHeight;
|
||||||
|
this._rightArrow.allocate(childBox, flags);
|
||||||
|
this._rightArrow.opacity = this._rightGradient.opacity;
|
||||||
},
|
},
|
||||||
|
|
||||||
addItem : function(item) {
|
addItem : function(item) {
|
||||||
@ -455,7 +600,7 @@ SwitcherList.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
addSeparator: function () {
|
addSeparator: function () {
|
||||||
let box = new St.Bin({ style_class: 'separator' })
|
let box = new St.Bin({ style_class: 'separator' });
|
||||||
this._separator = box;
|
this._separator = box;
|
||||||
this._list.add_actor(box);
|
this._list.add_actor(box);
|
||||||
},
|
},
|
||||||
@ -472,6 +617,49 @@ SwitcherList.prototype = {
|
|||||||
else
|
else
|
||||||
this._items[this._highlighted].style_class = 'selected-item-box';
|
this._items[this._highlighted].style_class = 'selected-item-box';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let monitor = global.get_primary_monitor();
|
||||||
|
let itemSize = this._items[index].allocation.x2 - this._items[index].allocation.x1;
|
||||||
|
let [posX, posY] = this._items[index].get_transformed_position();
|
||||||
|
posX += this.actor.x;
|
||||||
|
if (posX + itemSize > monitor.width + monitor.x)
|
||||||
|
this._scrollToRight();
|
||||||
|
else if (posX < 0)
|
||||||
|
this._scrollToLeft();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
_scrollToLeft : function() {
|
||||||
|
let x = this._items[this._highlighted].allocation.x1;
|
||||||
|
this._scrollableRight = true;
|
||||||
|
Tweener.addTween(this._list, { anchor_x: x,
|
||||||
|
time: POPUP_SCROLL_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this, function () {
|
||||||
|
if (this._highlighted == 0) {
|
||||||
|
this._scrollableLeft = false;
|
||||||
|
this.actor.queue_relayout();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_scrollToRight : function() {
|
||||||
|
this._scrollableLeft = true;
|
||||||
|
let monitor = global.get_primary_monitor();
|
||||||
|
let padding = this.actor.get_theme_node().get_horizontal_padding();
|
||||||
|
let parentPadding = this.actor.get_parent().get_theme_node().get_horizontal_padding();
|
||||||
|
let x = this._items[this._highlighted].allocation.x2 - monitor.width + padding + parentPadding;
|
||||||
|
Tweener.addTween(this._list, { anchor_x: x,
|
||||||
|
time: POPUP_SCROLL_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this, function () {
|
||||||
|
if (this._highlighted == this._items.length - 1) {
|
||||||
|
this._scrollableRight = false;
|
||||||
|
this.actor.queue_relayout();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_itemActivated: function(n) {
|
_itemActivated: function(n) {
|
||||||
@ -512,7 +700,8 @@ SwitcherList.prototype = {
|
|||||||
|
|
||||||
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
||||||
alloc.min_size = this._items.length * maxChildMin + separatorWidth + totalSpacing;
|
alloc.min_size = this._items.length * maxChildMin + separatorWidth + totalSpacing;
|
||||||
alloc.nat_size = this._items.length * maxChildNat + separatorWidth + totalSpacing;
|
alloc.natural_size = alloc.min_size;
|
||||||
|
this._minSize = alloc.min_size;
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredHeight: function (actor, forWidth, alloc) {
|
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||||
@ -528,11 +717,11 @@ SwitcherList.prototype = {
|
|||||||
if (this._squareItems) {
|
if (this._squareItems) {
|
||||||
let [childMin, childNat] = this._maxChildWidth(-1);
|
let [childMin, childNat] = this._maxChildWidth(-1);
|
||||||
maxChildMin = Math.max(childMin, maxChildMin);
|
maxChildMin = Math.max(childMin, maxChildMin);
|
||||||
maxChildNat = Math.max(childNat, maxChildNat);
|
maxChildNat = maxChildMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc.min_size = maxChildMin;
|
alloc.min_size = maxChildMin;
|
||||||
alloc.nat_size = maxChildNat;
|
alloc.natural_size = maxChildNat;
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function (actor, box, flags) {
|
_allocate: function (actor, box, flags) {
|
||||||
@ -553,6 +742,18 @@ SwitcherList.prototype = {
|
|||||||
let x = 0;
|
let x = 0;
|
||||||
let children = this._list.get_children();
|
let children = this._list.get_children();
|
||||||
let childBox = new Clutter.ActorBox();
|
let childBox = new Clutter.ActorBox();
|
||||||
|
|
||||||
|
let primary = global.get_primary_monitor();
|
||||||
|
let parentRightPadding = this.actor.get_parent().get_theme_node().get_padding(St.Side.RIGHT);
|
||||||
|
if (this.actor.allocation.x2 == primary.x + primary.width - parentRightPadding) {
|
||||||
|
if (this._squareItems)
|
||||||
|
childWidth = childHeight;
|
||||||
|
else {
|
||||||
|
let [childMin, childNat] = children[0].get_preferred_width(childHeight);
|
||||||
|
childWidth = childMin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
if (this._items.indexOf(children[i]) != -1) {
|
if (this._items.indexOf(children[i]) != -1) {
|
||||||
let [childMin, childNat] = children[i].get_preferred_height(childWidth);
|
let [childMin, childNat] = children[i].get_preferred_height(childWidth);
|
||||||
@ -577,6 +778,14 @@ SwitcherList.prototype = {
|
|||||||
// we don't allocate it.
|
// we don't allocate it.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
||||||
|
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||||
|
let topPadding = this.actor.get_theme_node().get_padding(St.Side.TOP);
|
||||||
|
let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||||
|
|
||||||
|
// Clip the area for scrolling
|
||||||
|
this._clipBin.set_clip(0, -topPadding, (this.actor.allocation.x2 - this.actor.allocation.x1) - leftPadding - rightPadding, this.actor.height + bottomPadding);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -589,14 +798,22 @@ function AppIcon(app) {
|
|||||||
AppIcon.prototype = {
|
AppIcon.prototype = {
|
||||||
_init: function(app) {
|
_init: function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.actor = new St.BoxLayout({ style_class: "alt-tab-app",
|
this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
this._icon = this.app.create_icon_texture(POPUP_APPICON_SIZE);
|
this.icon = null;
|
||||||
this.actor.add(this._icon, { x_fill: false, y_fill: false } );
|
this._iconBin = new St.Bin();
|
||||||
this._label = new St.Label({ text: this.app.get_name() });
|
|
||||||
this.actor.add(this._label, { x_fill: false });
|
this.actor.add(this._iconBin, { x_fill: false, y_fill: false } );
|
||||||
|
this.label = new St.Label({ text: this.app.get_name() });
|
||||||
|
this.actor.add(this.label, { x_fill: false });
|
||||||
|
},
|
||||||
|
|
||||||
|
set_size: function(size) {
|
||||||
|
this.icon = this.app.create_icon_texture(size);
|
||||||
|
this._iconBin.set_size(size, size);
|
||||||
|
this._iconBin.child = this.icon;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function AppSwitcher(apps) {
|
function AppSwitcher(apps) {
|
||||||
this._init(apps);
|
this._init(apps);
|
||||||
@ -636,6 +853,48 @@ AppSwitcher.prototype = {
|
|||||||
this._addIcon(otherIcons[i]);
|
this._addIcon(otherIcons[i]);
|
||||||
|
|
||||||
this._curApp = -1;
|
this._curApp = -1;
|
||||||
|
this._iconSize = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||||
|
let j = 0;
|
||||||
|
while(this._items.length > 1 && this._items[j].style_class != 'item-box') {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
let iconPadding = this._items[j].get_theme_node().get_horizontal_padding();
|
||||||
|
let [iconMinHeight, iconNaturalHeight] = this.icons[j].label.get_preferred_height(-1);
|
||||||
|
let iconSpacing = iconNaturalHeight + iconPadding;
|
||||||
|
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
||||||
|
if (this._separator)
|
||||||
|
totalSpacing += this._separator.width + this._list.spacing;
|
||||||
|
|
||||||
|
// We just assume the whole screen here due to weirdness happing with the passed width
|
||||||
|
let focus = global.get_focus_monitor();
|
||||||
|
let parentPadding = this.actor.get_parent().get_theme_node().get_horizontal_padding();
|
||||||
|
let availWidth = focus.width - parentPadding - this.actor.get_theme_node().get_horizontal_padding();
|
||||||
|
let height = 0;
|
||||||
|
|
||||||
|
for(let i = 0; i < iconSizes.length; i++) {
|
||||||
|
this._iconSize = iconSizes[i];
|
||||||
|
height = iconSizes[i] + iconSpacing;
|
||||||
|
let w = height * this._items.length + totalSpacing;
|
||||||
|
if (w <= availWidth)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._items.length == 1) {
|
||||||
|
this._iconSize = iconSizes[0];
|
||||||
|
height = iconSizes[0] + iconSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let i = 0; i < this.icons.length; i++) {
|
||||||
|
if (this.icons[i].icon != null)
|
||||||
|
break;
|
||||||
|
this.icons[i].set_size(this._iconSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc.min_size = height;
|
||||||
|
alloc.natural_size = height;
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function (actor, box, flags) {
|
_allocate: function (actor, box, flags) {
|
||||||
@ -663,16 +922,13 @@ AppSwitcher.prototype = {
|
|||||||
// thumbnails are visible (ie, when the app icon is supposed to be
|
// thumbnails are visible (ie, when the app icon is supposed to be
|
||||||
// in justOutline mode). Apps with multiple windows will normally
|
// in justOutline mode). Apps with multiple windows will normally
|
||||||
// show a dim arrow, but show a bright arrow when they are
|
// show a dim arrow, but show a bright arrow when they are
|
||||||
// highlighted; their redraw handler will use the right color
|
// highlighted.
|
||||||
// based on this._curApp; we just need to do a queue_relayout() to
|
|
||||||
// force it to redraw. (queue_redraw() doesn't work because
|
|
||||||
// ShellDrawingArea only redraws on allocate.)
|
|
||||||
highlight : function(n, justOutline) {
|
highlight : function(n, justOutline) {
|
||||||
if (this._curApp != -1) {
|
if (this._curApp != -1) {
|
||||||
if (this.icons[this._curApp].cachedWindows.length == 1)
|
if (this.icons[this._curApp].cachedWindows.length == 1)
|
||||||
this._arrows[this._curApp].hide();
|
this._arrows[this._curApp].hide();
|
||||||
else
|
else
|
||||||
this._arrows[this._curApp].queue_relayout();
|
this._arrows[this._curApp].remove_style_pseudo_class('highlighted');
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherList.prototype.highlight.call(this, n, justOutline);
|
SwitcherList.prototype.highlight.call(this, n, justOutline);
|
||||||
@ -682,7 +938,7 @@ AppSwitcher.prototype = {
|
|||||||
if (justOutline && this.icons[this._curApp].cachedWindows.length == 1)
|
if (justOutline && this.icons[this._curApp].cachedWindows.length == 1)
|
||||||
this._arrows[this._curApp].show();
|
this._arrows[this._curApp].show();
|
||||||
else
|
else
|
||||||
this._arrows[this._curApp].queue_relayout();
|
this._arrows[this._curApp].add_style_pseudo_class('highlighted');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -691,12 +947,10 @@ AppSwitcher.prototype = {
|
|||||||
this.addItem(appIcon.actor);
|
this.addItem(appIcon.actor);
|
||||||
|
|
||||||
let n = this._arrows.length;
|
let n = this._arrows.length;
|
||||||
let arrow = new St.DrawingArea();
|
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
|
||||||
arrow.connect('redraw', Lang.bind(this,
|
arrow.connect('repaint', Lang.bind(this,
|
||||||
function (area, texture) {
|
function (area) {
|
||||||
Shell.draw_box_pointer(texture, Shell.PointerDirection.DOWN,
|
Shell.draw_box_pointer(area, Shell.PointerDirection.DOWN);
|
||||||
TRANSPARENT_COLOR,
|
|
||||||
this._curApp == n ? POPUP_ARROW_COLOR : POPUP_UNFOCUSED_ARROW_COLOR);
|
|
||||||
}));
|
}));
|
||||||
this._list.add_actor(arrow);
|
this._list.add_actor(arrow);
|
||||||
this._arrows.push(arrow);
|
this._arrows.push(arrow);
|
||||||
@ -731,44 +985,74 @@ ThumbnailList.prototype = {
|
|||||||
|
|
||||||
let activeWorkspace = global.screen.get_active_workspace();
|
let activeWorkspace = global.screen.get_active_workspace();
|
||||||
|
|
||||||
// We fake the value of "separatorAdded" when the app has no window
|
// We fake the value of 'separatorAdded' when the app has no window
|
||||||
// on the current workspace, to avoid displaying a useless separator in
|
// on the current workspace, to avoid displaying a useless separator in
|
||||||
// that case.
|
// that case.
|
||||||
let separatorAdded = windows.length == 0 || windows[0].get_workspace() != activeWorkspace;
|
let separatorAdded = windows.length == 0 || windows[0].get_workspace() != activeWorkspace;
|
||||||
|
|
||||||
|
this._labels = new Array();
|
||||||
|
this._thumbnailBins = new Array();
|
||||||
|
this._clones = new Array();
|
||||||
|
this._windows = windows;
|
||||||
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
if (!separatorAdded && windows[i].get_workspace() != activeWorkspace) {
|
if (!separatorAdded && windows[i].get_workspace() != activeWorkspace) {
|
||||||
this.addSeparator();
|
this.addSeparator();
|
||||||
separatorAdded = true;
|
separatorAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mutterWindow = windows[i].get_compositor_private();
|
let box = new St.BoxLayout({ style_class: 'thumbnail-box',
|
||||||
let windowTexture = mutterWindow.get_texture ();
|
|
||||||
let [width, height] = windowTexture.get_size();
|
|
||||||
let scale = Math.min(1.0, THUMBNAIL_SIZE / width, THUMBNAIL_SIZE / height);
|
|
||||||
|
|
||||||
let box = new St.BoxLayout({ style_class: "thumbnail-box",
|
|
||||||
vertical: true });
|
vertical: true });
|
||||||
|
|
||||||
let bin = new St.Bin({ style_class: "thumbnail" });
|
let bin = new St.Bin({ style_class: 'thumbnail' });
|
||||||
let clone = new Clutter.Clone ({ source: windowTexture,
|
|
||||||
reactive: true,
|
|
||||||
width: width * scale,
|
|
||||||
height: height * scale });
|
|
||||||
|
|
||||||
bin.add_actor(clone);
|
|
||||||
box.add_actor(bin);
|
box.add_actor(bin);
|
||||||
|
this._thumbnailBins.push(bin);
|
||||||
|
|
||||||
let title = windows[i].get_title();
|
let title = windows[i].get_title();
|
||||||
if (title) {
|
if (title) {
|
||||||
let name = new St.Label({ text: title });
|
let name = new St.Label({ text: title });
|
||||||
// St.Label doesn't support text-align so use a Bin
|
// St.Label doesn't support text-align so use a Bin
|
||||||
let bin = new St.Bin({ x_align: St.Align.MIDDLE });
|
let bin = new St.Bin({ x_align: St.Align.MIDDLE });
|
||||||
|
this._labels.push(bin);
|
||||||
bin.add_actor(name);
|
bin.add_actor(name);
|
||||||
box.add_actor(bin);
|
box.add_actor(bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addItem(box);
|
this.addItem(box);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addClones : function (availHeight) {
|
||||||
|
if (!this._thumbnailBins.length)
|
||||||
|
return;
|
||||||
|
let totalPadding = this._items[0].get_theme_node().get_horizontal_padding() + this._items[0].get_theme_node().get_vertical_padding();
|
||||||
|
totalPadding += this.actor.get_theme_node().get_horizontal_padding() + this.actor.get_theme_node().get_vertical_padding();
|
||||||
|
let [labelMinHeight, labelNaturalHeight] = this._labels[0].get_preferred_height(-1);
|
||||||
|
let [found, spacing] = this._items[0].child.get_theme_node().get_length('spacing', false);
|
||||||
|
if (!found)
|
||||||
|
spacing = 0;
|
||||||
|
|
||||||
|
availHeight = Math.min(availHeight - labelNaturalHeight - totalPadding - spacing, THUMBNAIL_DEFAULT_SIZE);
|
||||||
|
let binHeight = availHeight + this._items[0].get_theme_node().get_vertical_padding() + this.actor.get_theme_node().get_vertical_padding() - spacing;
|
||||||
|
binHeight = Math.min(THUMBNAIL_DEFAULT_SIZE, binHeight);
|
||||||
|
|
||||||
|
for (let i = 0; i < this._thumbnailBins.length; i++) {
|
||||||
|
let mutterWindow = this._windows[i].get_compositor_private();
|
||||||
|
let windowTexture = mutterWindow.get_texture ();
|
||||||
|
let [width, height] = windowTexture.get_size();
|
||||||
|
let scale = Math.min(1.0, THUMBNAIL_DEFAULT_SIZE / width, availHeight / height);
|
||||||
|
let clone = new Clutter.Clone ({ source: windowTexture,
|
||||||
|
reactive: true,
|
||||||
|
width: width * scale,
|
||||||
|
height: height * scale });
|
||||||
|
|
||||||
|
this._thumbnailBins[i].set_height(binHeight);
|
||||||
|
this._thumbnailBins[i].add_actor(clone);
|
||||||
|
this._clones.push(clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we only do this once
|
||||||
|
this._thumbnailBins = new Array();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
1017
js/ui/appDisplay.js
@ -3,19 +3,21 @@
|
|||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
function AppFavorites() {
|
function AppFavorites() {
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
|
|
||||||
AppFavorites.prototype = {
|
AppFavorites.prototype = {
|
||||||
FAVORITE_APPS_KEY: 'favorite_apps',
|
FAVORITE_APPS_KEY: 'favorite-apps',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._favorites = {};
|
this._favorites = {};
|
||||||
this._gconf = Shell.GConf.get_default();
|
global.settings.connect('changed::' + this.FAVORITE_APPS_KEY, Lang.bind(this, this._onFavsChanged));
|
||||||
this._gconf.connect('changed::' + this.FAVORITE_APPS_KEY, Lang.bind(this, this._onFavsChanged));
|
|
||||||
this._reload();
|
this._reload();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -25,7 +27,7 @@ AppFavorites.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_reload: function() {
|
_reload: function() {
|
||||||
let ids = Shell.GConf.get_default().get_string_list('favorite_apps');
|
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
|
||||||
let appSys = Shell.AppSystem.get_default();
|
let appSys = Shell.AppSystem.get_default();
|
||||||
let apps = ids.map(function (id) {
|
let apps = ids.map(function (id) {
|
||||||
return appSys.get_app(id);
|
return appSys.get_app(id);
|
||||||
@ -61,23 +63,50 @@ AppFavorites.prototype = {
|
|||||||
return appId in this._favorites;
|
return appId in this._favorites;
|
||||||
},
|
},
|
||||||
|
|
||||||
addFavorite: function(appId) {
|
_addFavorite: function(appId) {
|
||||||
if (appId in this._favorites)
|
if (appId in this._favorites)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
let app = Shell.AppSystem.get_default().get_app(appId);
|
let app = Shell.AppSystem.get_default().get_app(appId);
|
||||||
|
|
||||||
if (!app)
|
if (!app)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
let ids = this._getIds();
|
let ids = this._getIds();
|
||||||
ids.push(appId);
|
ids.push(appId);
|
||||||
this._gconf.set_string_list(this.FAVORITE_APPS_KEY, ids);
|
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
||||||
this._favorites[appId] = app;
|
this._favorites[appId] = app;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
addFavorite: function(appId) {
|
||||||
|
if (!this._addFavorite(appId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let app = Shell.AppSystem.get_default().get_app(appId);
|
||||||
|
|
||||||
|
Main.overview.infoBar.setMessage(_("%s has been added to your favorites.").format(app.get_name()), Lang.bind(this, function () {
|
||||||
|
this._removeFavorite(appId);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeFavorite: function(appId) {
|
||||||
|
if (!appId in this._favorites)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let ids = this._getIds().filter(function (id) { return id != appId; });
|
||||||
|
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
removeFavorite: function(appId) {
|
removeFavorite: function(appId) {
|
||||||
if (!appId in this._favorites)
|
if (!this._removeFavorite(appId))
|
||||||
return;
|
return;
|
||||||
let ids = this._getIds().filter(function (id) { return id != appId; });
|
|
||||||
this._gconf.set_string_list(this.FAVORITE_APPS_KEY, ids);
|
Main.overview.infoBar.setMessage(_("%s has been removed from your favorites.").format(this._favorites[appId].get_name()),
|
||||||
|
Lang.bind(this, function () {
|
||||||
|
this._addFavorite(appId);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(AppFavorites.prototype);
|
Signals.addSignalMethods(AppFavorites.prototype);
|
||||||
|
591
js/ui/appIcon.js
@ -1,591 +0,0 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Mainloop = imports.mainloop;
|
|
||||||
const Pango = imports.gi.Pango;
|
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const Signals = imports.signals;
|
|
||||||
const St = imports.gi.St;
|
|
||||||
const Gettext = imports.gettext.domain('gnome-shell');
|
|
||||||
const _ = Gettext.gettext;
|
|
||||||
|
|
||||||
const GenericDisplay = imports.ui.genericDisplay;
|
|
||||||
const AppFavorites = imports.ui.appFavorites;
|
|
||||||
const Main = imports.ui.main;
|
|
||||||
const Workspaces = imports.ui.workspaces;
|
|
||||||
|
|
||||||
const GLOW_COLOR = new Clutter.Color();
|
|
||||||
GLOW_COLOR.from_pixel(0x4f6ba4ff);
|
|
||||||
const GLOW_PADDING_HORIZONTAL = 3;
|
|
||||||
const GLOW_PADDING_VERTICAL = 3;
|
|
||||||
|
|
||||||
const APPICON_DEFAULT_ICON_SIZE = 48;
|
|
||||||
|
|
||||||
const APPICON_PADDING = 1;
|
|
||||||
const APPICON_BORDER_WIDTH = 1;
|
|
||||||
const APPICON_CORNER_RADIUS = 4;
|
|
||||||
|
|
||||||
const APPICON_MENU_POPUP_TIMEOUT_MS = 600;
|
|
||||||
|
|
||||||
const APPICON_DEFAULT_BORDER_COLOR = new Clutter.Color();
|
|
||||||
APPICON_DEFAULT_BORDER_COLOR.from_pixel(0x787878ff);
|
|
||||||
const APPICON_MENU_BACKGROUND_COLOR = new Clutter.Color();
|
|
||||||
APPICON_MENU_BACKGROUND_COLOR.from_pixel(0x292929ff);
|
|
||||||
const APPICON_MENU_FONT = 'Sans 14px';
|
|
||||||
const APPICON_MENU_COLOR = new Clutter.Color();
|
|
||||||
APPICON_MENU_COLOR.from_pixel(0xffffffff);
|
|
||||||
const APPICON_MENU_SELECTED_COLOR = new Clutter.Color();
|
|
||||||
APPICON_MENU_SELECTED_COLOR.from_pixel(0x005b97ff);
|
|
||||||
const APPICON_MENU_SEPARATOR_COLOR = new Clutter.Color();
|
|
||||||
APPICON_MENU_SEPARATOR_COLOR.from_pixel(0x787878ff);
|
|
||||||
const APPICON_MENU_BORDER_WIDTH = 1;
|
|
||||||
const APPICON_MENU_ARROW_SIZE = 12;
|
|
||||||
const APPICON_MENU_CORNER_RADIUS = 4;
|
|
||||||
const APPICON_MENU_PADDING = 4;
|
|
||||||
|
|
||||||
const TRANSPARENT_COLOR = new Clutter.Color();
|
|
||||||
TRANSPARENT_COLOR.from_pixel(0x00000000);
|
|
||||||
|
|
||||||
const MenuType = { NONE: 0, ON_RIGHT: 1, BELOW: 2 };
|
|
||||||
|
|
||||||
function AppIcon(params) {
|
|
||||||
this._init(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppIcon.prototype = {
|
|
||||||
_init : function(params) {
|
|
||||||
this.app = params.app;
|
|
||||||
if (!this.app)
|
|
||||||
throw new Error('AppIcon constructor requires "app" param');
|
|
||||||
|
|
||||||
this._menuType = ('menuType' in params) ? params.menuType : MenuType.NONE;
|
|
||||||
this._iconSize = ('size' in params) ? params.size : APPICON_DEFAULT_ICON_SIZE;
|
|
||||||
this._showGlow = ('glow' in params) ? params.glow : false;
|
|
||||||
|
|
||||||
this.actor = new Shell.ButtonBox({ orientation: Big.BoxOrientation.VERTICAL,
|
|
||||||
border: APPICON_BORDER_WIDTH,
|
|
||||||
corner_radius: APPICON_CORNER_RADIUS,
|
|
||||||
padding: APPICON_PADDING,
|
|
||||||
reactive: true });
|
|
||||||
this.actor._delegate = this;
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
|
||||||
|
|
||||||
this.highlight_border_color = APPICON_DEFAULT_BORDER_COLOR;
|
|
||||||
|
|
||||||
if (this._menuType != MenuType.NONE) {
|
|
||||||
this.actor.connect('button-press-event', Lang.bind(this, this._updateMenuOnButtonPress));
|
|
||||||
this.actor.connect('notify::hover', Lang.bind(this, this._updateMenuOnHoverChanged));
|
|
||||||
this.actor.connect('activate', Lang.bind(this, this._updateMenuOnActivate));
|
|
||||||
|
|
||||||
this._menuTimeoutId = 0;
|
|
||||||
this._menu = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let iconBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
|
||||||
x_align: Big.BoxAlignment.CENTER,
|
|
||||||
y_align: Big.BoxAlignment.CENTER,
|
|
||||||
width: this._iconSize,
|
|
||||||
height: this._iconSize });
|
|
||||||
this.icon = this.app.create_icon_texture(this._iconSize);
|
|
||||||
iconBox.append(this.icon, Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
this.actor.append(iconBox, Big.BoxPackFlags.EXPAND);
|
|
||||||
|
|
||||||
let nameBox = new Shell.GenericContainer();
|
|
||||||
nameBox.connect('get-preferred-width', Lang.bind(this, this._nameBoxGetPreferredWidth));
|
|
||||||
nameBox.connect('get-preferred-height', Lang.bind(this, this._nameBoxGetPreferredHeight));
|
|
||||||
nameBox.connect('allocate', Lang.bind(this, this._nameBoxAllocate));
|
|
||||||
this._nameBox = nameBox;
|
|
||||||
|
|
||||||
this._name = new St.Label({ style_class: "app-icon-label",
|
|
||||||
text: this.app.get_name() });
|
|
||||||
this._name.clutter_text.line_alignment = Pango.Alignment.CENTER;
|
|
||||||
nameBox.add_actor(this._name);
|
|
||||||
if (this._showGlow) {
|
|
||||||
this._glowBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
|
|
||||||
this._nameBox.add_actor(this._glowBox);
|
|
||||||
this._glowBox.lower(this._name);
|
|
||||||
this._appWindowChangedId = this.app.connect('windows-changed', Lang.bind(this, this._rerenderGlow));
|
|
||||||
this._rerenderGlow();
|
|
||||||
} else {
|
|
||||||
this._glowBox = null;
|
|
||||||
this._appWindowChangedId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.actor.append(nameBox, Big.BoxPackFlags.NONE);
|
|
||||||
},
|
|
||||||
|
|
||||||
_nameBoxGetPreferredWidth: function (nameBox, forHeight, alloc) {
|
|
||||||
let [min, natural] = this._name.get_preferred_width(forHeight);
|
|
||||||
alloc.min_size = min + GLOW_PADDING_HORIZONTAL * 2;
|
|
||||||
alloc.natural_size = natural + GLOW_PADDING_HORIZONTAL * 2;
|
|
||||||
},
|
|
||||||
|
|
||||||
_nameBoxGetPreferredHeight: function (nameBox, forWidth, alloc) {
|
|
||||||
let [min, natural] = this._name.get_preferred_height(forWidth);
|
|
||||||
alloc.min_size = min + GLOW_PADDING_VERTICAL * 2;
|
|
||||||
alloc.natural_size = natural + GLOW_PADDING_VERTICAL * 2;
|
|
||||||
},
|
|
||||||
|
|
||||||
_nameBoxAllocate: function (nameBox, box, flags) {
|
|
||||||
let childBox = new Clutter.ActorBox();
|
|
||||||
let [minWidth, naturalWidth] = this._name.get_preferred_width(-1);
|
|
||||||
let [minHeight, naturalHeight] = this._name.get_preferred_height(-1);
|
|
||||||
let availWidth = box.x2 - box.x1;
|
|
||||||
let availHeight = box.y2 - box.y1;
|
|
||||||
let targetWidth = availWidth;
|
|
||||||
let xPadding = 0;
|
|
||||||
if (naturalWidth < availWidth) {
|
|
||||||
xPadding = Math.floor((availWidth - naturalWidth) / 2);
|
|
||||||
}
|
|
||||||
childBox.x1 = xPadding;
|
|
||||||
childBox.x2 = availWidth - xPadding;
|
|
||||||
childBox.y1 = GLOW_PADDING_VERTICAL;
|
|
||||||
childBox.y2 = availHeight - GLOW_PADDING_VERTICAL;
|
|
||||||
this._name.allocate(childBox, flags);
|
|
||||||
|
|
||||||
// Now the glow
|
|
||||||
if (this._glowBox != null) {
|
|
||||||
let glowPaddingHoriz = Math.max(0, xPadding - GLOW_PADDING_HORIZONTAL);
|
|
||||||
glowPaddingHoriz = Math.max(GLOW_PADDING_HORIZONTAL, glowPaddingHoriz);
|
|
||||||
childBox.x1 = glowPaddingHoriz;
|
|
||||||
childBox.x2 = availWidth - glowPaddingHoriz;
|
|
||||||
childBox.y1 = 0;
|
|
||||||
childBox.y2 = availHeight;
|
|
||||||
this._glowBox.allocate(childBox, flags);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onDestroy: function() {
|
|
||||||
if (this._appWindowChangedId > 0)
|
|
||||||
this.app.disconnect(this._appWindowChangedId);
|
|
||||||
},
|
|
||||||
|
|
||||||
_rerenderGlow: function() {
|
|
||||||
if (!this._showGlow)
|
|
||||||
return;
|
|
||||||
this._glowBox.get_children().forEach(function (a) { a.destroy(); });
|
|
||||||
let glowPath = GLib.filename_to_uri(global.imagedir + 'app-well-glow.png', '');
|
|
||||||
let windows = this.app.get_windows();
|
|
||||||
for (let i = 0; i < windows.length && i < 3; i++) {
|
|
||||||
let glow = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
|
||||||
glowPath, -1, -1);
|
|
||||||
glow.keep_aspect_ratio = false;
|
|
||||||
this._glowBox.append(glow, Big.BoxPackFlags.EXPAND);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// AppIcon itself is not a draggable, but if you want to make
|
|
||||||
// a subclass of it draggable, you can use this method to create
|
|
||||||
// a drag actor
|
|
||||||
createDragActor: function() {
|
|
||||||
return this.app.create_icon_texture(this._iconSize);
|
|
||||||
},
|
|
||||||
|
|
||||||
setHighlight: function(highlight) {
|
|
||||||
if (highlight) {
|
|
||||||
this.actor.border_color = this.highlight_border_color;
|
|
||||||
} else {
|
|
||||||
this.actor.border_color = TRANSPARENT_COLOR;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateMenuOnActivate: function(actor, event) {
|
|
||||||
if (this._menuTimeoutId != 0) {
|
|
||||||
Mainloop.source_remove(this._menuTimeoutId);
|
|
||||||
this._menuTimeoutId = 0;
|
|
||||||
}
|
|
||||||
this.emit('activate');
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateMenuOnHoverChanged: function() {
|
|
||||||
if (!this.actor.hover && this._menuTimeoutId != 0) {
|
|
||||||
Mainloop.source_remove(this._menuTimeoutId);
|
|
||||||
this._menuTimeoutId = 0;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateMenuOnButtonPress: function(actor, event) {
|
|
||||||
let button = event.get_button();
|
|
||||||
if (button == 1) {
|
|
||||||
if (this._menuTimeoutId != 0)
|
|
||||||
Mainloop.source_remove(this._menuTimeoutId);
|
|
||||||
this._menuTimeoutId = Mainloop.timeout_add(APPICON_MENU_POPUP_TIMEOUT_MS,
|
|
||||||
Lang.bind(this, function () { this.popupMenu(button); }));
|
|
||||||
} else if (button == 3) {
|
|
||||||
this.popupMenu(button);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
popupMenu: function(activatingButton) {
|
|
||||||
if (this._menuTimeoutId != 0) {
|
|
||||||
Mainloop.source_remove(this._menuTimeoutId);
|
|
||||||
this._menuTimeoutId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.actor.fake_release();
|
|
||||||
|
|
||||||
if (!this._menu) {
|
|
||||||
this._menu = new AppIconMenu(this, this._menuType);
|
|
||||||
this._menu.connect('highlight-window', Lang.bind(this, function (menu, window) {
|
|
||||||
this.highlightWindow(window);
|
|
||||||
}));
|
|
||||||
this._menu.connect('activate-window', Lang.bind(this, function (menu, window) {
|
|
||||||
this.activateWindow(window);
|
|
||||||
}));
|
|
||||||
this._menu.connect('popup', Lang.bind(this, function (menu, isPoppedUp) {
|
|
||||||
if (isPoppedUp)
|
|
||||||
this.menuPoppedUp();
|
|
||||||
else
|
|
||||||
this.menuPoppedDown();
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
this._menu.popup(activatingButton);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Default implementations; AppDisplay.RunningWellItem overrides these
|
|
||||||
highlightWindow: function(window) {
|
|
||||||
this.emit('highlight-window', window);
|
|
||||||
},
|
|
||||||
|
|
||||||
activateWindow: function(window) {
|
|
||||||
this.emit('activate-window', window);
|
|
||||||
},
|
|
||||||
|
|
||||||
menuPoppedUp: function() {
|
|
||||||
this.emit('menu-popped-up', this._menu);
|
|
||||||
},
|
|
||||||
|
|
||||||
menuPoppedDown: function() {
|
|
||||||
this.emit('menu-popped-down', this._menu);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Signals.addSignalMethods(AppIcon.prototype);
|
|
||||||
|
|
||||||
function AppIconMenu(source, type) {
|
|
||||||
this._init(source, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppIconMenu.prototype = {
|
|
||||||
_init: function(source, type) {
|
|
||||||
this._source = source;
|
|
||||||
this._type = type;
|
|
||||||
|
|
||||||
this.actor = new Shell.GenericContainer({ reactive: true });
|
|
||||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
|
||||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
|
||||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
|
||||||
|
|
||||||
this._windowContainer = new Shell.Menu({ orientation: Big.BoxOrientation.VERTICAL,
|
|
||||||
border_color: source.highlight_border_color,
|
|
||||||
border: APPICON_MENU_BORDER_WIDTH,
|
|
||||||
background_color: APPICON_MENU_BACKGROUND_COLOR,
|
|
||||||
padding: 4,
|
|
||||||
corner_radius: APPICON_MENU_CORNER_RADIUS,
|
|
||||||
width: Main.overview._dash.actor.width * 0.75 });
|
|
||||||
this._windowContainer.connect('unselected', Lang.bind(this, this._onItemUnselected));
|
|
||||||
this._windowContainer.connect('selected', Lang.bind(this, this._onItemSelected));
|
|
||||||
this._windowContainer.connect('cancelled', Lang.bind(this, this._onWindowSelectionCancelled));
|
|
||||||
this._windowContainer.connect('activate', Lang.bind(this, this._onItemActivate));
|
|
||||||
this.actor.add_actor(this._windowContainer);
|
|
||||||
|
|
||||||
// Stay popped up on release over application icon
|
|
||||||
this._windowContainer.set_persistent_source(this._source.actor);
|
|
||||||
|
|
||||||
// Intercept events while the menu has the pointer grab to do window-related effects
|
|
||||||
this._windowContainer.connect('enter-event', Lang.bind(this, this._onMenuEnter));
|
|
||||||
this._windowContainer.connect('leave-event', Lang.bind(this, this._onMenuLeave));
|
|
||||||
this._windowContainer.connect('button-release-event', Lang.bind(this, this._onMenuButtonRelease));
|
|
||||||
|
|
||||||
this._arrow = new St.DrawingArea();
|
|
||||||
this._arrow.connect('redraw', Lang.bind(this, function (area, texture) {
|
|
||||||
Shell.draw_box_pointer(texture,
|
|
||||||
this._type == MenuType.ON_RIGHT ? Shell.PointerDirection.LEFT : Shell.PointerDirection.UP,
|
|
||||||
source.highlight_border_color,
|
|
||||||
APPICON_MENU_BACKGROUND_COLOR);
|
|
||||||
}));
|
|
||||||
this.actor.add_actor(this._arrow);
|
|
||||||
|
|
||||||
// Chain our visibility and lifecycle to that of the source
|
|
||||||
source.actor.connect('notify::mapped', Lang.bind(this, function () {
|
|
||||||
if (!source.actor.mapped)
|
|
||||||
this._windowContainer.popdown();
|
|
||||||
}));
|
|
||||||
source.actor.connect('destroy', Lang.bind(this, function () { this.actor.destroy(); }));
|
|
||||||
|
|
||||||
global.stage.add_actor(this.actor);
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
|
||||||
let [min, natural] = this._windowContainer.get_preferred_width(forHeight);
|
|
||||||
if (this._type == MenuType.ON_RIGHT) {
|
|
||||||
min += APPICON_MENU_ARROW_SIZE;
|
|
||||||
natural += APPICON_MENU_ARROW_SIZE;
|
|
||||||
}
|
|
||||||
alloc.min_size = min;
|
|
||||||
alloc.natural_size = natural;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
|
||||||
let [min, natural] = this._windowContainer.get_preferred_height(forWidth);
|
|
||||||
if (this._type == MenuType.BELOW) {
|
|
||||||
min += APPICON_MENU_ARROW_SIZE;
|
|
||||||
natural += APPICON_MENU_ARROW_SIZE;
|
|
||||||
}
|
|
||||||
alloc.min_size = min;
|
|
||||||
alloc.natural_size = natural;
|
|
||||||
},
|
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
|
||||||
let childBox = new Clutter.ActorBox();
|
|
||||||
|
|
||||||
let width = box.x2 - box.x1;
|
|
||||||
let height = box.y2 - box.y1;
|
|
||||||
|
|
||||||
if (this._type == MenuType.ON_RIGHT) {
|
|
||||||
childBox.x1 = 0;
|
|
||||||
childBox.x2 = APPICON_MENU_ARROW_SIZE;
|
|
||||||
childBox.y1 = Math.floor((height / 2) - (APPICON_MENU_ARROW_SIZE / 2));
|
|
||||||
childBox.y2 = childBox.y1 + APPICON_MENU_ARROW_SIZE;
|
|
||||||
this._arrow.allocate(childBox, flags);
|
|
||||||
|
|
||||||
childBox.x1 = APPICON_MENU_ARROW_SIZE - APPICON_MENU_BORDER_WIDTH;
|
|
||||||
childBox.x2 = width;
|
|
||||||
childBox.y1 = 0;
|
|
||||||
childBox.y2 = height;
|
|
||||||
this._windowContainer.allocate(childBox, flags);
|
|
||||||
} else /* MenuType.BELOW */ {
|
|
||||||
childBox.x1 = Math.floor((width / 2) - (APPICON_MENU_ARROW_SIZE / 2));
|
|
||||||
childBox.x2 = childBox.x1 + APPICON_MENU_ARROW_SIZE;
|
|
||||||
childBox.y1 = 0;
|
|
||||||
childBox.y2 = APPICON_MENU_ARROW_SIZE;
|
|
||||||
this._arrow.allocate(childBox, flags);
|
|
||||||
|
|
||||||
childBox.x1 = 0;
|
|
||||||
childBox.x2 = width;
|
|
||||||
childBox.y1 = APPICON_MENU_ARROW_SIZE - APPICON_MENU_BORDER_WIDTH;
|
|
||||||
childBox.y2 = height;
|
|
||||||
this._windowContainer.allocate(childBox, flags);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_redisplay: function() {
|
|
||||||
this._windowContainer.remove_all();
|
|
||||||
|
|
||||||
let windows = this._source.app.get_windows();
|
|
||||||
|
|
||||||
this._windowContainer.show();
|
|
||||||
|
|
||||||
let iconsDiffer = false;
|
|
||||||
let texCache = Shell.TextureCache.get_default();
|
|
||||||
if (windows.length > 0) {
|
|
||||||
let firstIcon = windows[0].mini_icon;
|
|
||||||
for (let i = 1; i < windows.length; i++) {
|
|
||||||
if (!texCache.pixbuf_equal(windows[i].mini_icon, firstIcon)) {
|
|
||||||
iconsDiffer = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the app windows menu items and the separator between windows
|
|
||||||
// of the current desktop and other windows.
|
|
||||||
let activeWorkspace = global.screen.get_active_workspace();
|
|
||||||
let separatorShown = windows.length > 0 && windows[0].get_workspace() != activeWorkspace;
|
|
||||||
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
|
||||||
if (!separatorShown && windows[i].get_workspace() != activeWorkspace) {
|
|
||||||
this._appendSeparator();
|
|
||||||
separatorShown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let icon = null;
|
|
||||||
if (iconsDiffer)
|
|
||||||
icon = Shell.TextureCache.get_default().bind_pixbuf_property(windows[i], "mini-icon");
|
|
||||||
|
|
||||||
let box = this._appendMenuItem(icon, windows[i].title);
|
|
||||||
box._window = windows[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (windows.length > 0)
|
|
||||||
this._appendSeparator();
|
|
||||||
|
|
||||||
let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._source.app.get_id());
|
|
||||||
|
|
||||||
this._newWindowMenuItem = windows.length > 0 ? this._appendMenuItem(null, _("New Window")) : null;
|
|
||||||
|
|
||||||
if (windows.length > 0)
|
|
||||||
this._appendSeparator();
|
|
||||||
this._toggleFavoriteMenuItem = this._appendMenuItem(null, isFavorite ? _("Remove from Favorites")
|
|
||||||
: _("Add to Favorites"));
|
|
||||||
|
|
||||||
this._highlightedItem = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
_appendSeparator: function () {
|
|
||||||
let box = new Big.Box({ padding_top: 2, padding_bottom: 2 });
|
|
||||||
box.append(new Clutter.Rectangle({ height: 1,
|
|
||||||
color: APPICON_MENU_SEPARATOR_COLOR }),
|
|
||||||
Big.BoxPackFlags.EXPAND);
|
|
||||||
this._windowContainer.append_separator(box, Big.BoxPackFlags.NONE);
|
|
||||||
},
|
|
||||||
|
|
||||||
_appendMenuItem: function(iconTexture, labelText) {
|
|
||||||
/* Use padding here rather than spacing in the box above so that
|
|
||||||
* we have a larger reactive area.
|
|
||||||
*/
|
|
||||||
let box = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
|
||||||
padding_top: 4,
|
|
||||||
padding_bottom: 4,
|
|
||||||
spacing: 4,
|
|
||||||
reactive: true });
|
|
||||||
let vCenter;
|
|
||||||
if (iconTexture != null) {
|
|
||||||
vCenter = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
|
|
||||||
vCenter.append(iconTexture, Big.BoxPackFlags.NONE);
|
|
||||||
box.append(vCenter, Big.BoxPackFlags.NONE);
|
|
||||||
}
|
|
||||||
vCenter = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
|
|
||||||
let label = new Clutter.Text({ text: labelText,
|
|
||||||
font_name: APPICON_MENU_FONT,
|
|
||||||
ellipsize: Pango.EllipsizeMode.END,
|
|
||||||
color: APPICON_MENU_COLOR });
|
|
||||||
vCenter.append(label, Big.BoxPackFlags.NONE);
|
|
||||||
box.append(vCenter, Big.BoxPackFlags.NONE);
|
|
||||||
this._windowContainer.append(box, Big.BoxPackFlags.NONE);
|
|
||||||
return box;
|
|
||||||
},
|
|
||||||
|
|
||||||
popup: function(activatingButton) {
|
|
||||||
let [stageX, stageY] = this._source.actor.get_transformed_position();
|
|
||||||
let [stageWidth, stageHeight] = this._source.actor.get_transformed_size();
|
|
||||||
|
|
||||||
this._redisplay();
|
|
||||||
|
|
||||||
this._windowContainer.popup(activatingButton, global.get_current_time());
|
|
||||||
|
|
||||||
this.emit('popup', true);
|
|
||||||
|
|
||||||
let x, y;
|
|
||||||
if (this._type == MenuType.ON_RIGHT) {
|
|
||||||
x = Math.floor(stageX + stageWidth);
|
|
||||||
y = Math.floor(stageY + (stageHeight / 2) - (this.actor.height / 2));
|
|
||||||
} else {
|
|
||||||
x = Math.floor(stageX + (stageWidth / 2) - (this.actor.width / 2));
|
|
||||||
y = Math.floor(stageY + stageHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.actor.set_position(x, y);
|
|
||||||
this.actor.show();
|
|
||||||
},
|
|
||||||
|
|
||||||
popdown: function() {
|
|
||||||
this._windowContainer.popdown();
|
|
||||||
this.emit('popup', false);
|
|
||||||
this.actor.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
selectWindow: function(metaWindow) {
|
|
||||||
this._selectMenuItemForWindow(metaWindow);
|
|
||||||
},
|
|
||||||
|
|
||||||
_findMetaWindowForActor: function (actor) {
|
|
||||||
if (actor._delegate instanceof Workspaces.WindowClone)
|
|
||||||
return actor._delegate.metaWindow;
|
|
||||||
else if (actor.get_meta_window)
|
|
||||||
return actor.get_meta_window();
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
// This function is called while the menu has a pointer grab; what we want
|
|
||||||
// to do is see if the mouse was released over a window representation
|
|
||||||
_onMenuButtonRelease: function (actor, event) {
|
|
||||||
let metaWindow = this._findMetaWindowForActor(event.get_source());
|
|
||||||
if (metaWindow) {
|
|
||||||
this.emit('activate-window', metaWindow);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateHighlight: function (item) {
|
|
||||||
if (this._highlightedItem) {
|
|
||||||
this._highlightedItem.background_color = TRANSPARENT_COLOR;
|
|
||||||
this.emit('highlight-window', null);
|
|
||||||
}
|
|
||||||
this._highlightedItem = item;
|
|
||||||
if (this._highlightedItem) {
|
|
||||||
this._highlightedItem.background_color = APPICON_MENU_SELECTED_COLOR;
|
|
||||||
let window = this._highlightedItem._window;
|
|
||||||
if (window)
|
|
||||||
this.emit('highlight-window', window);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_selectMenuItemForWindow: function (metaWindow) {
|
|
||||||
let children = this._windowContainer.get_children();
|
|
||||||
for (let i = 0; i < children.length; i++) {
|
|
||||||
let child = children[i];
|
|
||||||
let menuMetaWindow = child._window;
|
|
||||||
if (menuMetaWindow == metaWindow)
|
|
||||||
this._updateHighlight(child);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Called while menu has a pointer grab
|
|
||||||
_onMenuEnter: function (actor, event) {
|
|
||||||
let metaWindow = this._findMetaWindowForActor(event.get_source());
|
|
||||||
if (metaWindow) {
|
|
||||||
this._selectMenuItemForWindow(metaWindow);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Called while menu has a pointer grab
|
|
||||||
_onMenuLeave: function (actor, event) {
|
|
||||||
let metaWindow = this._findMetaWindowForActor(event.get_source());
|
|
||||||
if (metaWindow) {
|
|
||||||
this._updateHighlight(null);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onItemUnselected: function (actor, child) {
|
|
||||||
this._updateHighlight(null);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onItemSelected: function (actor, child) {
|
|
||||||
this._updateHighlight(child);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onItemActivate: function (actor, child) {
|
|
||||||
if (child._window) {
|
|
||||||
let metaWindow = child._window;
|
|
||||||
this.emit('activate-window', metaWindow);
|
|
||||||
} else if (child == this._newWindowMenuItem) {
|
|
||||||
this._source.app.launch();
|
|
||||||
this.emit('activate-window', null);
|
|
||||||
} else if (child == this._toggleFavoriteMenuItem) {
|
|
||||||
let favs = AppFavorites.getAppFavorites();
|
|
||||||
let isFavorite = favs.isFavorite(this._source.app.get_id());
|
|
||||||
if (isFavorite)
|
|
||||||
favs.removeFavorite(this._source.app.get_id());
|
|
||||||
else
|
|
||||||
favs.addFavorite(this._source.app.get_id());
|
|
||||||
}
|
|
||||||
this.popdown();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onWindowSelectionCancelled: function () {
|
|
||||||
this.emit('highlight-window', null);
|
|
||||||
this.popdown();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Signals.addSignalMethods(AppIconMenu.prototype);
|
|
199
js/ui/boxpointer.js
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Cairo = imports.cairo;
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BoxPointer:
|
||||||
|
* @side: A St.Side type; currently only St.Side.TOP is implemented
|
||||||
|
* @binProperties: Properties to set on contained bin
|
||||||
|
*
|
||||||
|
* An actor which displays a triangle "arrow" pointing to a given
|
||||||
|
* side. The .bin property is a container in which content can be
|
||||||
|
* placed. The arrow position may be controlled via setArrowOrigin().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function BoxPointer(side, binProperties) {
|
||||||
|
this._init(side, binProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxPointer.prototype = {
|
||||||
|
_init: function(arrowSide, binProperties) {
|
||||||
|
this._arrowSide = arrowSide;
|
||||||
|
this._arrowOrigin = 0;
|
||||||
|
this.actor = new St.Bin({ x_fill: true,
|
||||||
|
y_fill: true });
|
||||||
|
this._container = new Shell.GenericContainer();
|
||||||
|
this.actor.set_child(this._container);
|
||||||
|
this._container.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
|
this._container.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
|
this._container.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
|
this.bin = new St.Bin(binProperties);
|
||||||
|
this._container.add_actor(this.bin);
|
||||||
|
this._border = new St.DrawingArea();
|
||||||
|
this._border.connect('repaint', Lang.bind(this, this._drawBorder));
|
||||||
|
this._container.add_actor(this._border);
|
||||||
|
this.bin.raise(this._border);
|
||||||
|
},
|
||||||
|
|
||||||
|
_adjustAllocationForArrow: function(isWidth, alloc) {
|
||||||
|
let themeNode = this.actor.get_theme_node();
|
||||||
|
let found, borderWidth, base, rise;
|
||||||
|
[found, borderWidth] = themeNode.get_length('-arrow-border-width', false);
|
||||||
|
alloc.min_size += borderWidth * 2;
|
||||||
|
alloc.natural_size += borderWidth * 2;
|
||||||
|
if ((!isWidth && (this._arrowSide == St.Side.TOP || this._arrowSide == St.Side.BOTTOM))
|
||||||
|
|| (isWidth && (this._arrowSide == St.Side.LEFT || this._arrowSide == St.Side.RIGHT))) {
|
||||||
|
let [found, rise] = themeNode.get_length('-arrow-rise', false);
|
||||||
|
alloc.min_size += rise;
|
||||||
|
alloc.natural_size += rise;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||||
|
let [minInternalSize, natInternalSize] = this.bin.get_preferred_width(forHeight);
|
||||||
|
alloc.min_size = minInternalSize;
|
||||||
|
alloc.natural_size = natInternalSize;
|
||||||
|
this._adjustAllocationForArrow(true, alloc);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||||
|
let [minSize, naturalSize] = this.bin.get_preferred_height(forWidth);
|
||||||
|
alloc.min_size = minSize;
|
||||||
|
alloc.natural_size = naturalSize;
|
||||||
|
this._adjustAllocationForArrow(false, alloc);
|
||||||
|
},
|
||||||
|
|
||||||
|
_allocate: function(actor, box, flags) {
|
||||||
|
let themeNode = this.actor.get_theme_node();
|
||||||
|
let found, borderWidth, borderRadius, rise, base;
|
||||||
|
[found, borderWidth] = themeNode.get_length('-arrow-border-width', false);
|
||||||
|
[found, rise] = themeNode.get_length('-arrow-rise', false);
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
let availWidth = box.x2 - box.x1;
|
||||||
|
let availHeight = box.y2 - box.y1;
|
||||||
|
|
||||||
|
childBox.x1 = 0;
|
||||||
|
childBox.y1 = 0;
|
||||||
|
childBox.x2 = availWidth;
|
||||||
|
childBox.y2 = availHeight;
|
||||||
|
this._border.allocate(childBox, flags);
|
||||||
|
|
||||||
|
childBox.x1 = borderWidth;
|
||||||
|
childBox.y1 = borderWidth;
|
||||||
|
childBox.x2 = availWidth - borderWidth;
|
||||||
|
childBox.y2 = availHeight - borderWidth;
|
||||||
|
switch (this._arrowSide) {
|
||||||
|
case St.Side.TOP:
|
||||||
|
childBox.y1 += rise;
|
||||||
|
break;
|
||||||
|
case St.Side.BOTTOM:
|
||||||
|
childBox.y2 -= rise;
|
||||||
|
break;
|
||||||
|
case St.Side.LEFT:
|
||||||
|
childBox.x1 += rise;
|
||||||
|
break;
|
||||||
|
case St.Side.RIGHT:
|
||||||
|
childBox.x2 -= rise;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.bin.allocate(childBox, flags);
|
||||||
|
},
|
||||||
|
|
||||||
|
_drawBorder: function(area) {
|
||||||
|
let themeNode = this.actor.get_theme_node();
|
||||||
|
|
||||||
|
let found, borderWidth, borderRadius, rise, base;
|
||||||
|
[found, borderWidth] = themeNode.get_length('-arrow-border-width', false);
|
||||||
|
[found, base] = themeNode.get_length('-arrow-base', false);
|
||||||
|
[found, rise] = themeNode.get_length('-arrow-rise', false);
|
||||||
|
[found, borderRadius] = themeNode.get_length('-arrow-border-radius', false);
|
||||||
|
|
||||||
|
let halfBorder = borderWidth / 2;
|
||||||
|
let halfBase = Math.floor(base/2);
|
||||||
|
|
||||||
|
let borderColor = new Clutter.Color();
|
||||||
|
themeNode.get_color('-arrow-border-color', false, borderColor);
|
||||||
|
let backgroundColor = new Clutter.Color();
|
||||||
|
themeNode.get_color('-arrow-background-color', false, backgroundColor);
|
||||||
|
|
||||||
|
let [width, height] = area.get_surface_size();
|
||||||
|
let [boxWidth, boxHeight] = [width, height];
|
||||||
|
if (this._arrowSide == St.Side.TOP || this._arrowSide == St.Side.BOTTOM) {
|
||||||
|
boxHeight -= rise;
|
||||||
|
} else {
|
||||||
|
boxWidth -= rise;
|
||||||
|
}
|
||||||
|
let cr = area.get_context();
|
||||||
|
Clutter.cairo_set_source_color(cr, borderColor);
|
||||||
|
|
||||||
|
// Translate so that box goes from 0,0 to boxWidth,boxHeight,
|
||||||
|
// with the arrow poking out of that
|
||||||
|
if (this._arrowSide == St.Side.TOP) {
|
||||||
|
cr.translate(0, rise);
|
||||||
|
} else if (this._arrowSide == St.Side.LEFT) {
|
||||||
|
cr.translate(rise, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cr.moveTo(borderRadius, halfBorder);
|
||||||
|
|
||||||
|
if (this._arrowSide == St.Side.TOP) {
|
||||||
|
cr.lineTo(this._arrowOrigin - halfBase, halfBorder);
|
||||||
|
cr.lineTo(this._arrowOrigin, halfBorder - rise);
|
||||||
|
cr.lineTo(this._arrowOrigin + halfBase, halfBorder);
|
||||||
|
}
|
||||||
|
cr.lineTo(boxWidth - borderRadius, halfBorder);
|
||||||
|
|
||||||
|
cr.arc(boxWidth - borderRadius - halfBorder, borderRadius + halfBorder, borderRadius,
|
||||||
|
3*Math.PI/2, Math.PI*2);
|
||||||
|
|
||||||
|
if (this._arrowSide == St.Side.RIGHT) {
|
||||||
|
cr.lineTo(boxWidth - halfBorder, this._arrowOrigin - halfBase);
|
||||||
|
cr.lineTo(boxWidth - halfBorder + rise, this._arrowOrigin);
|
||||||
|
cr.lineTo(boxWidth - halfBorder, this._arrowOrigin + halfBase);
|
||||||
|
}
|
||||||
|
cr.lineTo(boxWidth - halfBorder, boxHeight - borderRadius);
|
||||||
|
|
||||||
|
cr.arc(boxWidth - borderRadius - halfBorder, boxHeight - borderRadius - halfBorder, borderRadius,
|
||||||
|
0, Math.PI/2);
|
||||||
|
|
||||||
|
if (this._arrowSide == St.Side.BOTTOM) {
|
||||||
|
cr.lineTo(this._arrowOrigin + halfBase, boxHeight - halfBorder);
|
||||||
|
cr.lineTo(this._arrowOrigin, boxHeight - halfBorder + rise);
|
||||||
|
cr.lineTo(this._arrowOrigin - halfBase, boxHeight - halfBorder);
|
||||||
|
}
|
||||||
|
cr.lineTo(borderRadius, boxHeight - halfBorder);
|
||||||
|
|
||||||
|
cr.arc(borderRadius + halfBorder, boxHeight - borderRadius - halfBorder, borderRadius,
|
||||||
|
Math.PI/2, Math.PI);
|
||||||
|
|
||||||
|
if (this._arrowSide == St.Side.LEFT) {
|
||||||
|
cr.lineTo(halfBorder, this._arrowOrigin + halfBase);
|
||||||
|
cr.lineTo(halfBorder - rise, this._arrowOrigin);
|
||||||
|
cr.lineTo(halfBorder, this._arrowOrigin - halfBase);
|
||||||
|
}
|
||||||
|
cr.lineTo(halfBorder, borderRadius);
|
||||||
|
|
||||||
|
cr.arc(borderRadius + halfBorder, borderRadius + halfBorder, borderRadius,
|
||||||
|
Math.PI, 3*Math.PI/2);
|
||||||
|
|
||||||
|
Clutter.cairo_set_source_color(cr, backgroundColor);
|
||||||
|
cr.fillPreserve();
|
||||||
|
Clutter.cairo_set_source_color(cr, borderColor);
|
||||||
|
cr.setLineWidth(borderWidth);
|
||||||
|
cr.stroke();
|
||||||
|
},
|
||||||
|
|
||||||
|
// @origin: Coordinate specifying middle of the arrow, along
|
||||||
|
// the Y axis for St.Side.LEFT, St.Side.RIGHT from the top and X axis from
|
||||||
|
// the left for St.Side.TOP and St.Side.BOTTOM.
|
||||||
|
setArrowOrigin: function(origin) {
|
||||||
|
if (this._arrowOrigin != origin) {
|
||||||
|
this._arrowOrigin = origin;
|
||||||
|
this._border.queue_repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -1,12 +1,16 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Pango = imports.gi.Pango;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
const Gettext_gtk20 = imports.gettext.domain('gtk20');
|
const Gettext_gtk20 = imports.gettext.domain('gtk20');
|
||||||
|
|
||||||
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||||
|
const WEEKDATE_HEADER_WIDTH_DIGITS = 3;
|
||||||
|
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||||
|
|
||||||
function _sameDay(dateA, dateB) {
|
function _sameDay(dateA, dateB) {
|
||||||
return (dateA.getDate() == dateB.getDate() &&
|
return (dateA.getDate() == dateB.getDate() &&
|
||||||
@ -14,9 +18,35 @@ function _sameDay(dateA, dateB) {
|
|||||||
dateA.getYear() == dateB.getYear());
|
dateA.getYear() == dateB.getYear());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _getCalendarWeekForDate(date) {
|
||||||
|
// Based on the algorithms found here:
|
||||||
|
// http://en.wikipedia.org/wiki/Talk:ISO_week_date
|
||||||
|
let midnightDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||||||
|
// Need to get Monday to be 1 ... Sunday to be 7
|
||||||
|
let dayOfWeek = 1 + ((midnightDate.getDay() + 6) % 7);
|
||||||
|
let nearestThursday = new Date(midnightDate.getFullYear(), midnightDate.getMonth(),
|
||||||
|
midnightDate.getDate() + (4 - dayOfWeek));
|
||||||
|
|
||||||
|
let jan1st = new Date(nearestThursday.getFullYear(), 0, 1);
|
||||||
|
let diffDate = nearestThursday - jan1st;
|
||||||
|
let dayNumber = Math.floor(Math.abs(diffDate) / MSECS_IN_DAY);
|
||||||
|
let weekNumber = Math.floor(dayNumber / 7) + 1;
|
||||||
|
|
||||||
|
return weekNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getDigitWidth(actor){
|
||||||
|
let context = actor.get_pango_context();
|
||||||
|
let themeNode = actor.get_theme_node();
|
||||||
|
let font = themeNode.get_font();
|
||||||
|
let metrics = context.get_metrics(font, context.get_language());
|
||||||
|
let width = metrics.get_approximate_digit_width();
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
function Calendar() {
|
function Calendar() {
|
||||||
this._init();
|
this._init();
|
||||||
};
|
}
|
||||||
|
|
||||||
Calendar.prototype = {
|
Calendar.prototype = {
|
||||||
_init: function() {
|
_init: function() {
|
||||||
@ -24,27 +54,34 @@ Calendar.prototype = {
|
|||||||
// GTK+ by preference uses nl_langinfo (NL_TIME_FIRST_WEEKDAY). We probably
|
// GTK+ by preference uses nl_langinfo (NL_TIME_FIRST_WEEKDAY). We probably
|
||||||
// should add a C function so we can do the full handling.
|
// should add a C function so we can do the full handling.
|
||||||
this._weekStart = NaN;
|
this._weekStart = NaN;
|
||||||
let weekStartString = Gettext_gtk20.gettext("calendar:week_start:0");
|
this._weekdate = NaN;
|
||||||
if (weekStartString.indexOf("calendar:week_start:") == 0) {
|
this._digitWidth = NaN;
|
||||||
|
this._settings = new Gio.Settings({ schema: 'org.gnome.shell.calendar' });
|
||||||
|
|
||||||
|
this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
|
||||||
|
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
|
||||||
|
|
||||||
|
let weekStartString = Gettext_gtk20.gettext('calendar:week_start:0');
|
||||||
|
if (weekStartString.indexOf('calendar:week_start:') == 0) {
|
||||||
this._weekStart = parseInt(weekStartString.substring(20));
|
this._weekStart = parseInt(weekStartString.substring(20));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNaN(this._weekStart) || this._weekStart < 0 || this._weekStart > 6) {
|
if (isNaN(this._weekStart) || this._weekStart < 0 || this._weekStart > 6) {
|
||||||
log("Translation of 'calendar:week_start:0' in GTK+ is not correct");
|
log('Translation of "calendar:week_start:0" in GTK+ is not correct');
|
||||||
this.weekStart = 0;
|
this._weekStart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the ordering for month/year in the calendar heading
|
// Find the ordering for month/year in the calendar heading
|
||||||
switch (Gettext_gtk20.gettext("calendar:MY")) {
|
switch (Gettext_gtk20.gettext('calendar:MY')) {
|
||||||
case "calendar:MY":
|
case 'calendar:MY':
|
||||||
this._headerFormat = "%B %Y";
|
this._headerFormat = '%B %Y';
|
||||||
break;
|
break;
|
||||||
case "calendar:YM":
|
case 'calendar:YM':
|
||||||
this._headerFormat = "%Y %B";
|
this._headerFormat = '%Y %B';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log("Translation of 'calendar:MY' in GTK+ is not correct");
|
log('Translation of "calendar:MY" in GTK+ is not correct');
|
||||||
this._headerFormat = "%B %Y";
|
this._headerFormat = '%B %Y';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,45 +89,13 @@ Calendar.prototype = {
|
|||||||
this.date = new Date();
|
this.date = new Date();
|
||||||
|
|
||||||
this.actor = new St.Table({ homogeneous: false,
|
this.actor = new St.Table({ homogeneous: false,
|
||||||
style_class: "calendar",
|
style_class: 'calendar',
|
||||||
reactive: true });
|
reactive: true });
|
||||||
|
|
||||||
this.actor.connect('scroll-event',
|
this.actor.connect('scroll-event',
|
||||||
Lang.bind(this, this._onScroll));
|
Lang.bind(this, this._onScroll));
|
||||||
|
|
||||||
// Top line of the calendar '<| September 2009 |>'
|
this._buildHeader ();
|
||||||
this._topBox = new St.BoxLayout();
|
|
||||||
this.actor.add(this._topBox,
|
|
||||||
{ row: 0, col: 0, col_span: 7 });
|
|
||||||
|
|
||||||
let back = new St.Button({ label: "<", style_class: 'calendar-change-month' });
|
|
||||||
this._topBox.add(back);
|
|
||||||
back.connect("clicked", Lang.bind(this, this._prevMonth));
|
|
||||||
|
|
||||||
this._dateLabel = new St.Label();
|
|
||||||
this._topBox.add(this._dateLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE });
|
|
||||||
|
|
||||||
let forward = new St.Button({ label: ">", style_class: 'calendar-change-month' });
|
|
||||||
this._topBox.add(forward);
|
|
||||||
forward.connect("clicked", Lang.bind(this, this._nextMonth));
|
|
||||||
|
|
||||||
// We need to figure out the abbreviated localized names for the days of the week;
|
|
||||||
// we do this by just getting the next 7 days starting from right now and then putting
|
|
||||||
// them in the right cell in the table. It doesn't matter if we add them in order
|
|
||||||
let iter = new Date(this.date);
|
|
||||||
iter.setSeconds(0); // Leap second protection. Hah!
|
|
||||||
iter.setHours(12);
|
|
||||||
for (let i = 0; i < 7; i++) {
|
|
||||||
this.actor.add(new St.Label({ text: iter.toLocaleFormat("%a") }),
|
|
||||||
{ row: 1,
|
|
||||||
col: (7 + iter.getDay() - this._weekStart) % 7,
|
|
||||||
x_fill: false, x_align: 1.0 });
|
|
||||||
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// All the children after this are days, and get removed when we update the calendar
|
|
||||||
this._firstDayIndex = this.actor.get_children().length;
|
|
||||||
|
|
||||||
this._update();
|
this._update();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -102,6 +107,74 @@ Calendar.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_buildHeader: function() {
|
||||||
|
let offsetCols = this._useWeekdate ? 1 : 0;
|
||||||
|
this.actor.destroy_children();
|
||||||
|
|
||||||
|
// Top line of the calendar '<| September 2009 |>'
|
||||||
|
this._topBox = new St.BoxLayout();
|
||||||
|
this.actor.add(this._topBox,
|
||||||
|
{ row: 0, col: 0, col_span: offsetCols + 7 });
|
||||||
|
|
||||||
|
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChange));
|
||||||
|
let [backlabel, forwardlabel] = ['<', '>'];
|
||||||
|
if (St.Widget.get_default_direction () == St.TextDirection.RTL) {
|
||||||
|
[backlabel, forwardlabel] = [forwardlabel, backlabel];
|
||||||
|
}
|
||||||
|
|
||||||
|
let back = new St.Button({ label: backlabel, style_class: 'calendar-change-month' });
|
||||||
|
this._topBox.add(back);
|
||||||
|
back.connect('clicked', Lang.bind(this, this._prevMonth));
|
||||||
|
|
||||||
|
this._dateLabel = new St.Label();
|
||||||
|
this._topBox.add(this._dateLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
|
let forward = new St.Button({ label: forwardlabel, style_class: 'calendar-change-month' });
|
||||||
|
this._topBox.add(forward);
|
||||||
|
forward.connect('clicked', Lang.bind(this, this._nextMonth));
|
||||||
|
|
||||||
|
// We need to figure out the abbreviated localized names for the days of the week;
|
||||||
|
// we do this by just getting the next 7 days starting from right now and then putting
|
||||||
|
// them in the right cell in the table. It doesn't matter if we add them in order
|
||||||
|
let iter = new Date(this.date);
|
||||||
|
iter.setSeconds(0); // Leap second protection. Hah!
|
||||||
|
iter.setHours(12);
|
||||||
|
|
||||||
|
if (this._useWeekdate) {
|
||||||
|
this._weekdateHeader = new St.Label();
|
||||||
|
this.actor.add(this._weekdateHeader,
|
||||||
|
{ row: 1,
|
||||||
|
col: 0,
|
||||||
|
x_fill: false, x_align: St.Align.MIDDLE });
|
||||||
|
this._setWeekdateHeaderWidth();
|
||||||
|
} else {
|
||||||
|
this._weekdateHeader = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
this.actor.add(new St.Label({ text: iter.toLocaleFormat('%a') }),
|
||||||
|
{ row: 1,
|
||||||
|
col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7,
|
||||||
|
x_fill: false, x_align: St.Align.END });
|
||||||
|
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// All the children after this are days, and get removed when we update the calendar
|
||||||
|
this._firstDayIndex = this.actor.get_children().length;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onStyleChange: function(actor, event) {
|
||||||
|
// width of a digit in pango units
|
||||||
|
this._digitWidth = _getDigitWidth(this.actor) / Pango.SCALE;
|
||||||
|
this._setWeekdateHeaderWidth();
|
||||||
|
},
|
||||||
|
|
||||||
|
_setWeekdateHeaderWidth: function() {
|
||||||
|
if (this.digitWidth != NaN && this._useWeekdate && this._weekdateHeader) {
|
||||||
|
this._weekdateHeader.set_width (this._digitWidth * WEEKDATE_HEADER_WIDTH_DIGITS);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_onScroll : function(actor, event) {
|
_onScroll : function(actor, event) {
|
||||||
switch (event.get_scroll_direction()) {
|
switch (event.get_scroll_direction()) {
|
||||||
case Clutter.ScrollDirection.UP:
|
case Clutter.ScrollDirection.UP:
|
||||||
@ -135,6 +208,12 @@ Calendar.prototype = {
|
|||||||
this._update();
|
this._update();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onSettingsChange: function() {
|
||||||
|
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
|
||||||
|
this._buildHeader();
|
||||||
|
this._update();
|
||||||
|
},
|
||||||
|
|
||||||
_update: function() {
|
_update: function() {
|
||||||
this._dateLabel.text = this.date.toLocaleFormat(this._headerFormat);
|
this._dateLabel.text = this.date.toLocaleFormat(this._headerFormat);
|
||||||
|
|
||||||
@ -156,14 +235,24 @@ Calendar.prototype = {
|
|||||||
while (true) {
|
while (true) {
|
||||||
let label = new St.Label({ text: iter.getDate().toString() });
|
let label = new St.Label({ text: iter.getDate().toString() });
|
||||||
if (_sameDay(now, iter))
|
if (_sameDay(now, iter))
|
||||||
label.style_class = "calendar-day calendar-today";
|
label.style_class = 'calendar-day calendar-today';
|
||||||
else if (iter.getMonth() != this.date.getMonth())
|
else if (iter.getMonth() != this.date.getMonth())
|
||||||
label.style_class = "calendar-day calendar-other-month-day";
|
label.style_class = 'calendar-day calendar-other-month-day';
|
||||||
else
|
else
|
||||||
label.style_class = "calendar-day";
|
label.style_class = 'calendar-day';
|
||||||
|
|
||||||
|
let offsetCols = this._useWeekdate ? 1 : 0;
|
||||||
this.actor.add(label,
|
this.actor.add(label,
|
||||||
{ row: row, col: (7 + iter.getDay() - this._weekStart) % 7,
|
{ row: row, col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7,
|
||||||
x_fill: false, x_align: 1.0 });
|
x_fill: false, x_align: St.Align.END });
|
||||||
|
|
||||||
|
if (this._useWeekdate && iter.getDay() == 4) {
|
||||||
|
let label = new St.Label({ text: _getCalendarWeekForDate(iter).toString(),
|
||||||
|
style_class: 'calendar-day calendar-calendarweek'});
|
||||||
|
this.actor.add(label,
|
||||||
|
{ row: row, col: 0,
|
||||||
|
x_fill: false, x_align: St.Align.MIDDLE });
|
||||||
|
}
|
||||||
|
|
||||||
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
||||||
if (iter.getDay() == this._weekStart) {
|
if (iter.getDay() == this._weekStart) {
|
||||||
|
173
js/ui/chrome.js
@ -5,6 +5,7 @@ const Lang = imports.lang;
|
|||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
@ -13,6 +14,19 @@ const Params = imports.misc.params;
|
|||||||
// normal mode (ie, outside the Overview), that surrounds the main
|
// normal mode (ie, outside the Overview), that surrounds the main
|
||||||
// workspace content.
|
// workspace content.
|
||||||
|
|
||||||
|
const Visibility = {
|
||||||
|
FULL: 1,
|
||||||
|
FULLSCREEN: 2,
|
||||||
|
OVERVIEW: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultParams = {
|
||||||
|
visibleInOverview: false,
|
||||||
|
visibleInFullscreen: false,
|
||||||
|
affectsStruts: true,
|
||||||
|
affectsInputRegion: true
|
||||||
|
};
|
||||||
|
|
||||||
function Chrome() {
|
function Chrome() {
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
@ -20,12 +34,13 @@ function Chrome() {
|
|||||||
Chrome.prototype = {
|
Chrome.prototype = {
|
||||||
_init: function() {
|
_init: function() {
|
||||||
// The group itself has zero size so it doesn't interfere with DND
|
// The group itself has zero size so it doesn't interfere with DND
|
||||||
this.actor = new Clutter.Group({ width: 0, height: 0 });
|
this.actor = new Shell.GenericContainer({ width: 0, height: 0 });
|
||||||
global.stage.add_actor(this.actor);
|
Main.uiGroup.add_actor(this.actor);
|
||||||
this.nonOverviewActor = new Clutter.Group();
|
this.actor.connect('allocate', Lang.bind(this, this._allocated));
|
||||||
this.actor.add_actor(this.nonOverviewActor);
|
|
||||||
|
|
||||||
this._obscuredByFullscreen = false;
|
this._inFullscreen = false;
|
||||||
|
this._inOverview = false;
|
||||||
|
this.visibility = Visibility.FULL;
|
||||||
|
|
||||||
this._trackedActors = [];
|
this._trackedActors = [];
|
||||||
|
|
||||||
@ -44,13 +59,10 @@ Chrome.prototype = {
|
|||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
},
|
},
|
||||||
|
|
||||||
_verifyAncestry: function(actor, ancestor) {
|
_allocated: function(actor, box, flags) {
|
||||||
while (actor) {
|
let children = this.actor.get_children();
|
||||||
if (actor == ancestor)
|
for (let i = 0; i < children.length; i++)
|
||||||
return true;
|
children[i].allocate_preferred_size(flags);
|
||||||
actor = actor.get_parent();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// addActor:
|
// addActor:
|
||||||
@ -67,19 +79,15 @@ Chrome.prototype = {
|
|||||||
//
|
//
|
||||||
// If %visibleInOverview is %true in @params, @actor will remain
|
// If %visibleInOverview is %true in @params, @actor will remain
|
||||||
// visible when the overview is brought up. Otherwise it will
|
// visible when the overview is brought up. Otherwise it will
|
||||||
// automatically be hidden. If %affectsStruts or %affectsInputRegion
|
// automatically be hidden. Likewise, if %visibleInFullscreen is
|
||||||
// is %false, the actor will not have the indicated effect.
|
// %true, the actor will be visible even when a fullscreen window
|
||||||
|
// should be covering it.
|
||||||
|
//
|
||||||
|
// If %affectsStruts or %affectsInputRegion is %false, the actor
|
||||||
|
// will not have the indicated effect.
|
||||||
addActor: function(actor, params) {
|
addActor: function(actor, params) {
|
||||||
params = Params.parse(params, { visibleInOverview: false,
|
this.actor.add_actor(actor);
|
||||||
affectsStruts: true,
|
this._trackActor(actor, params);
|
||||||
affectsInputRegion: true });
|
|
||||||
|
|
||||||
if (params.visibleInOverview)
|
|
||||||
this.actor.add_actor(actor);
|
|
||||||
else
|
|
||||||
this.nonOverviewActor.add_actor(actor);
|
|
||||||
|
|
||||||
this._trackActor(actor, params.affectsInputRegion, params.affectsStruts);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// trackActor:
|
// trackActor:
|
||||||
@ -89,13 +97,32 @@ Chrome.prototype = {
|
|||||||
// Tells the chrome to track @actor, which must be a descendant
|
// Tells the chrome to track @actor, which must be a descendant
|
||||||
// of an actor added via addActor(). This can be used to extend the
|
// of an actor added via addActor(). This can be used to extend the
|
||||||
// struts or input region to cover specific children.
|
// struts or input region to cover specific children.
|
||||||
|
//
|
||||||
|
// @params can have any of the same values as in addActor(), though
|
||||||
|
// some possibilities don't make sense (eg, trying to have a
|
||||||
|
// %visibleInOverview child of a non-%visibleInOverview parent).
|
||||||
|
// By default, @actor has the same params as its chrome ancestor.
|
||||||
trackActor: function(actor, params) {
|
trackActor: function(actor, params) {
|
||||||
if (!this._verifyAncestry(actor, this.actor))
|
let ancestor = actor.get_parent();
|
||||||
|
let index = this._findActor(ancestor);
|
||||||
|
while (ancestor && index == -1) {
|
||||||
|
ancestor = ancestor.get_parent();
|
||||||
|
index = this._findActor(ancestor);
|
||||||
|
}
|
||||||
|
if (!ancestor)
|
||||||
throw new Error('actor is not a descendent of the chrome layer');
|
throw new Error('actor is not a descendent of the chrome layer');
|
||||||
|
|
||||||
params = Params.parse(params, { affectsStruts: true,
|
let ancestorData = this._trackedActors[index];
|
||||||
affectsInputRegion: true });
|
if (!params)
|
||||||
this._trackActor(actor, params.affectsInputRegion, params.affectsStruts);
|
params = {};
|
||||||
|
// We can't use Params.parse here because we want to drop
|
||||||
|
// the extra values like ancestorData.actor
|
||||||
|
for (let prop in defaultParams) {
|
||||||
|
if (!params[prop])
|
||||||
|
params[prop] = ancestorData[prop];
|
||||||
|
}
|
||||||
|
|
||||||
|
this._trackActor(actor, params);
|
||||||
},
|
},
|
||||||
|
|
||||||
// untrackActor:
|
// untrackActor:
|
||||||
@ -111,10 +138,7 @@ Chrome.prototype = {
|
|||||||
//
|
//
|
||||||
// Removes @actor from the chrome layer
|
// Removes @actor from the chrome layer
|
||||||
removeActor: function(actor) {
|
removeActor: function(actor) {
|
||||||
if (actor.get_parent() == this.nonOverviewActor)
|
this.actor.remove_actor(actor);
|
||||||
this.nonOverviewActor.remove_actor(actor);
|
|
||||||
else
|
|
||||||
this.actor.remove_actor(actor);
|
|
||||||
this._untrackActor(actor);
|
this._untrackActor(actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -127,16 +151,12 @@ Chrome.prototype = {
|
|||||||
return -1;
|
return -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
_trackActor: function(actor, inputRegion, strut) {
|
_trackActor: function(actor, params) {
|
||||||
let actorData;
|
|
||||||
|
|
||||||
if (this._findActor(actor) != -1)
|
if (this._findActor(actor) != -1)
|
||||||
throw new Error('trying to re-track existing chrome actor');
|
throw new Error('trying to re-track existing chrome actor');
|
||||||
|
|
||||||
actorData = { actor: actor,
|
let actorData = Params.parse(params, defaultParams);
|
||||||
inputRegion: inputRegion,
|
actorData.actor = actor;
|
||||||
strut: strut };
|
|
||||||
|
|
||||||
actorData.visibleId = actor.connect('notify::visible',
|
actorData.visibleId = actor.connect('notify::visible',
|
||||||
Lang.bind(this, this._queueUpdateRegions));
|
Lang.bind(this, this._queueUpdateRegions));
|
||||||
actorData.allocationId = actor.connect('notify::allocation',
|
actorData.allocationId = actor.connect('notify::allocation',
|
||||||
@ -166,20 +186,44 @@ Chrome.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_actorReparented: function(actor, oldParent) {
|
_actorReparented: function(actor, oldParent) {
|
||||||
if (!this._verifyAncestry(actor, this.actor))
|
if (!this.actor.contains(actor))
|
||||||
this._untrackActor(actor);
|
this._untrackActor(actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateVisibility: function() {
|
||||||
|
for (let i = 0; i < this._trackedActors.length; i++) {
|
||||||
|
let actorData = this._trackedActors[i];
|
||||||
|
if (this._inOverview && !actorData.visibleInOverview)
|
||||||
|
this.actor.set_skip_paint(actorData.actor, true);
|
||||||
|
else if (!this._inOverview && this._inFullscreen && !actorData.visibleInFullscreen)
|
||||||
|
this.actor.set_skip_paint(actorData.actor, true);
|
||||||
|
else
|
||||||
|
this.actor.set_skip_paint(actorData.actor, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
let newVisibility;
|
||||||
|
if (this._inOverview)
|
||||||
|
newVisibility = Visibility.OVERVIEW;
|
||||||
|
else if (this._inFullscreen)
|
||||||
|
newVisibility = Visibility.FULLSCREEN;
|
||||||
|
else
|
||||||
|
newVisibility = Visibility.FULL;
|
||||||
|
|
||||||
|
if (newVisibility != this.visibility) {
|
||||||
|
this.visibility = newVisibility;
|
||||||
|
this.emit('visibility-changed', this.visibility);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_overviewShowing: function() {
|
_overviewShowing: function() {
|
||||||
this.actor.show();
|
this._inOverview = true;
|
||||||
this.nonOverviewActor.hide();
|
this._updateVisibility();
|
||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
},
|
},
|
||||||
|
|
||||||
_overviewHidden: function() {
|
_overviewHidden: function() {
|
||||||
if (this._obscuredByFullscreen)
|
this._inOverview = false;
|
||||||
this.actor.hide();
|
this._updateVisibility();
|
||||||
this.nonOverviewActor.show();
|
|
||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -196,7 +240,7 @@ Chrome.prototype = {
|
|||||||
// The chrome layer should be visible unless there is a window
|
// The chrome layer should be visible unless there is a window
|
||||||
// with layer FULLSCREEN, or a window with layer
|
// with layer FULLSCREEN, or a window with layer
|
||||||
// OVERRIDE_REDIRECT that covers the whole screen.
|
// OVERRIDE_REDIRECT that covers the whole screen.
|
||||||
// ("override_redirect" is not actually a layer above all
|
// ('override_redirect' is not actually a layer above all
|
||||||
// other windows, but this seems to be how mutter treats it
|
// other windows, but this seems to be how mutter treats it
|
||||||
// currently...) If we wanted to be extra clever, we could
|
// currently...) If we wanted to be extra clever, we could
|
||||||
// figure out when an OVERRIDE_REDIRECT window was trying to
|
// figure out when an OVERRIDE_REDIRECT window was trying to
|
||||||
@ -205,26 +249,40 @@ Chrome.prototype = {
|
|||||||
|
|
||||||
// @windows is sorted bottom to top.
|
// @windows is sorted bottom to top.
|
||||||
|
|
||||||
this._obscuredByFullscreen = false;
|
let wasInFullscreen = this._inFullscreen;
|
||||||
|
this._inFullscreen = false;
|
||||||
for (let i = windows.length - 1; i > -1; i--) {
|
for (let i = windows.length - 1; i > -1; i--) {
|
||||||
let layer = windows[i].get_meta_window().get_layer();
|
let layer = windows[i].get_meta_window().get_layer();
|
||||||
|
|
||||||
if (layer == Meta.StackLayer.OVERRIDE_REDIRECT ||
|
// There are 3 cases we check here for:
|
||||||
layer == Meta.StackLayer.FULLSCREEN) {
|
// 1.) Monitor sized window
|
||||||
|
// 2.) Window with a position somewhere on the primary screen having the _NET_WM_FULLSCREEN flag set
|
||||||
|
// 3.) Window that is partly off screen (tries to hide its decorations) which might have negative coords
|
||||||
|
// We check for 1.) and 2.) by checking if the upper right corner is on the primary monitor, but avoid the case
|
||||||
|
// where it overlaps with the secondary screen (like window.x + window.width == primary.x + primary.width)
|
||||||
|
// For 3.) we just ignore negative values as they don't really make sense
|
||||||
|
|
||||||
|
if (layer == Meta.StackLayer.FULLSCREEN) {
|
||||||
|
if (Math.max(windows[i].x, 0) >= primary.x && Math.max(windows[i].x, 0) < primary.x + primary.width &&
|
||||||
|
Math.max(windows[i].y, 0) >= primary.y && Math.max(windows[i].y, 0) < primary.y + primary.height) {
|
||||||
|
this._inFullscreen = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (layer == Meta.StackLayer.OVERRIDE_REDIRECT) {
|
||||||
if (windows[i].x <= primary.x &&
|
if (windows[i].x <= primary.x &&
|
||||||
windows[i].x + windows[i].width >= primary.x + primary.width &&
|
windows[i].x + windows[i].width >= primary.x + primary.width &&
|
||||||
windows[i].y <= primary.y &&
|
windows[i].y <= primary.y &&
|
||||||
windows[i].y + windows[i].height >= primary.y + primary.height) {
|
windows[i].y + windows[i].height >= primary.y + primary.height) {
|
||||||
this._obscuredByFullscreen = true;
|
this._inFullscreen = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let shouldBeVisible = !this._obscuredByFullscreen || Main.overview.visible;
|
if (this._inFullscreen != wasInFullscreen) {
|
||||||
if (this.actor.visible != shouldBeVisible) {
|
this._updateVisibility();
|
||||||
this.actor.visible = shouldBeVisible;
|
|
||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -236,7 +294,7 @@ Chrome.prototype = {
|
|||||||
|
|
||||||
for (i = 0; i < this._trackedActors.length; i++) {
|
for (i = 0; i < this._trackedActors.length; i++) {
|
||||||
let actorData = this._trackedActors[i];
|
let actorData = this._trackedActors[i];
|
||||||
if (!actorData.inputRegion && !actorData.strut)
|
if (!actorData.affectsInputRegion && !actorData.affectsStruts)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
let [x, y] = actorData.actor.get_transformed_position();
|
let [x, y] = actorData.actor.get_transformed_position();
|
||||||
@ -247,10 +305,12 @@ Chrome.prototype = {
|
|||||||
h = Math.round(h);
|
h = Math.round(h);
|
||||||
let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h});
|
let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h});
|
||||||
|
|
||||||
if (actorData.inputRegion && actorData.actor.get_paint_visibility())
|
if (actorData.affectsInputRegion &&
|
||||||
|
actorData.actor.get_paint_visibility() &&
|
||||||
|
!this.actor.get_skip_paint(actorData.actor))
|
||||||
rects.push(rect);
|
rects.push(rect);
|
||||||
|
|
||||||
if (!actorData.strut)
|
if (!actorData.affectsStruts)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Metacity wants to know what side of the screen the
|
// Metacity wants to know what side of the screen the
|
||||||
@ -302,3 +362,4 @@ Chrome.prototype = {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Signals.addSignalMethods(Chrome.prototype);
|
||||||
|
632
js/ui/dash.js
@ -1,6 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
@ -13,47 +12,18 @@ const Gettext = imports.gettext.domain('gnome-shell');
|
|||||||
const _ = Gettext.gettext;
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
const AppDisplay = imports.ui.appDisplay;
|
const AppDisplay = imports.ui.appDisplay;
|
||||||
|
const DND = imports.ui.dnd;
|
||||||
const DocDisplay = imports.ui.docDisplay;
|
const DocDisplay = imports.ui.docDisplay;
|
||||||
const PlaceDisplay = imports.ui.placeDisplay;
|
const PlaceDisplay = imports.ui.placeDisplay;
|
||||||
const GenericDisplay = imports.ui.genericDisplay;
|
const GenericDisplay = imports.ui.genericDisplay;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const Overview = imports.ui.overview;
|
||||||
const Search = imports.ui.search;
|
const Search = imports.ui.search;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
// 25 search results (per result type) should be enough for everyone
|
// 25 search results (per result type) should be enough for everyone
|
||||||
const MAX_RENDERED_SEARCH_RESULTS = 25;
|
const MAX_RENDERED_SEARCH_RESULTS = 25;
|
||||||
|
|
||||||
const DEFAULT_PADDING = 4;
|
|
||||||
const DEFAULT_SPACING = 4;
|
|
||||||
|
|
||||||
const BACKGROUND_COLOR = new Clutter.Color();
|
|
||||||
BACKGROUND_COLOR.from_pixel(0x000000c0);
|
|
||||||
|
|
||||||
const PRELIGHT_COLOR = new Clutter.Color();
|
|
||||||
PRELIGHT_COLOR.from_pixel(0x4f6fadaa);
|
|
||||||
|
|
||||||
const TEXT_COLOR = new Clutter.Color();
|
|
||||||
TEXT_COLOR.from_pixel(0x5f5f5fff);
|
|
||||||
const BRIGHTER_TEXT_COLOR = new Clutter.Color();
|
|
||||||
BRIGHTER_TEXT_COLOR.from_pixel(0xbbbbbbff);
|
|
||||||
const BRIGHT_TEXT_COLOR = new Clutter.Color();
|
|
||||||
BRIGHT_TEXT_COLOR.from_pixel(0xffffffff);
|
|
||||||
const SEARCH_TEXT_COLOR = new Clutter.Color();
|
|
||||||
SEARCH_TEXT_COLOR.from_pixel(0x333333ff);
|
|
||||||
|
|
||||||
const SEARCH_CURSOR_COLOR = BRIGHT_TEXT_COLOR;
|
|
||||||
const HIGHLIGHTED_SEARCH_CURSOR_COLOR = SEARCH_TEXT_COLOR;
|
|
||||||
|
|
||||||
const SEARCH_BORDER_BOTTOM_COLOR = new Clutter.Color();
|
|
||||||
SEARCH_BORDER_BOTTOM_COLOR.from_pixel(0x191919ff);
|
|
||||||
|
|
||||||
const BROWSE_ACTIVATED_BG = new Clutter.Color();
|
|
||||||
BROWSE_ACTIVATED_BG.from_pixel(0x303030f0);
|
|
||||||
|
|
||||||
const APPS = "apps";
|
|
||||||
const PREFS = "prefs";
|
|
||||||
const DOCS = "docs";
|
|
||||||
const PLACES = "places";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the index in an array of a given length that is obtained
|
* Returns the index in an array of a given length that is obtained
|
||||||
* if the provided index is incremented by an increment and the array
|
* if the provided index is incremented by an increment and the array
|
||||||
@ -67,18 +37,6 @@ function _getIndexWrapped(index, increment, length) {
|
|||||||
return (index + increment + length) % length;
|
return (index + increment + length) % length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _createDisplay(displayType, flags) {
|
|
||||||
if (displayType == APPS)
|
|
||||||
return new AppDisplay.AppDisplay(false, flags);
|
|
||||||
else if (displayType == PREFS)
|
|
||||||
return new AppDisplay.AppDisplay(true, flags);
|
|
||||||
else if (displayType == DOCS)
|
|
||||||
return new DocDisplay.DocDisplay(flags);
|
|
||||||
else if (displayType == PLACES)
|
|
||||||
return new PlaceDisplay.PlaceDisplay(flags);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Pane() {
|
function Pane() {
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
@ -87,7 +45,7 @@ Pane.prototype = {
|
|||||||
_init: function () {
|
_init: function () {
|
||||||
this._open = false;
|
this._open = false;
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ style_class: "dash-pane",
|
this.actor = new St.BoxLayout({ style_class: 'dash-pane',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
reactive: true });
|
reactive: true });
|
||||||
this.actor.connect('button-press-event', Lang.bind(this, function (a, e) {
|
this.actor.connect('button-press-event', Lang.bind(this, function (a, e) {
|
||||||
@ -95,20 +53,6 @@ Pane.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let chromeTop = new St.BoxLayout();
|
|
||||||
|
|
||||||
let closeIcon = new St.Button({ style_class: "dash-pane-close" });
|
|
||||||
closeIcon.connect('clicked', Lang.bind(this, function (b, e) {
|
|
||||||
this.close();
|
|
||||||
}));
|
|
||||||
let dummy = new St.Bin();
|
|
||||||
chromeTop.add(dummy, { expand: true });
|
|
||||||
chromeTop.add(closeIcon, { x_align: St.Align.END });
|
|
||||||
this.actor.add(chromeTop);
|
|
||||||
|
|
||||||
this.content = new St.BoxLayout({ vertical: true });
|
|
||||||
this.actor.add(this.content, { expand: true });
|
|
||||||
|
|
||||||
// Hidden by default
|
// Hidden by default
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
},
|
},
|
||||||
@ -117,20 +61,33 @@ Pane.prototype = {
|
|||||||
if (this._open)
|
if (this._open)
|
||||||
return;
|
return;
|
||||||
this._open = true;
|
this._open = true;
|
||||||
this.actor.show();
|
|
||||||
this.emit('open-state-changed', this._open);
|
this.emit('open-state-changed', this._open);
|
||||||
|
this.actor.opacity = 0;
|
||||||
|
this.actor.show();
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: Overview.PANE_FADE_TIME,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
close: function () {
|
close: function () {
|
||||||
if (!this._open)
|
if (!this._open)
|
||||||
return;
|
return;
|
||||||
this._open = false;
|
this._open = false;
|
||||||
this.actor.hide();
|
Tweener.addTween(this.actor,
|
||||||
this.emit('open-state-changed', this._open);
|
{ opacity: 0,
|
||||||
|
time: Overview.PANE_FADE_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this, function() {
|
||||||
|
this.actor.hide();
|
||||||
|
this.emit('open-state-changed', this._open);
|
||||||
|
})
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyContent: function() {
|
destroyContent: function() {
|
||||||
let children = this.content.get_children();
|
let children = this.actor.get_children();
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
children[i].destroy();
|
children[i].destroy();
|
||||||
}
|
}
|
||||||
@ -142,55 +99,24 @@ Pane.prototype = {
|
|||||||
else
|
else
|
||||||
this.open();
|
this.open();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Signals.addSignalMethods(Pane.prototype);
|
Signals.addSignalMethods(Pane.prototype);
|
||||||
|
|
||||||
function ResultArea(displayType, flags) {
|
function ResultArea() {
|
||||||
this._init(displayType, flags);
|
this._init();
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultArea.prototype = {
|
ResultArea.prototype = {
|
||||||
_init : function(displayType, flags) {
|
_init : function() {
|
||||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
|
this.actor = new St.BoxLayout({ vertical: true });
|
||||||
this.resultsContainer = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
this.resultsContainer = new St.BoxLayout({ style_class: 'dash-results-container' });
|
||||||
spacing: DEFAULT_PADDING
|
this.actor.add(this.resultsContainer, { expand: true });
|
||||||
});
|
|
||||||
this.actor.append(this.resultsContainer, Big.BoxPackFlags.EXPAND);
|
|
||||||
|
|
||||||
this.display = _createDisplay(displayType, flags);
|
this.display = new DocDisplay.DocDisplay();
|
||||||
this.resultsContainer.append(this.display.actor, Big.BoxPackFlags.EXPAND);
|
this.resultsContainer.add(this.display.actor, { expand: true });
|
||||||
this.display.load();
|
this.display.load();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Utility function shared between ResultPane and the DocDisplay in the main dash.
|
|
||||||
// Connects to the detail signal of the display, and on-demand creates a new
|
|
||||||
// pane.
|
|
||||||
function createPaneForDetails(dash, display) {
|
|
||||||
let detailPane = null;
|
|
||||||
display.connect('show-details', Lang.bind(this, function(display, index) {
|
|
||||||
if (detailPane == null) {
|
|
||||||
detailPane = new Pane();
|
|
||||||
detailPane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) {
|
|
||||||
if (!isOpen) {
|
|
||||||
/* Ensure we don't keep around large preview textures */
|
|
||||||
detailPane.destroyContent();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
dash._addPane(detailPane);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= 0) {
|
|
||||||
detailPane.destroyContent();
|
|
||||||
let details = display.createDetailsForIndex(index);
|
|
||||||
detailPane.content.add(details, { expand: true });
|
|
||||||
detailPane.open();
|
|
||||||
} else {
|
|
||||||
detailPane.close();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ResultPane(dash) {
|
function ResultPane(dash) {
|
||||||
this._init(dash);
|
this._init(dash);
|
||||||
@ -201,23 +127,14 @@ ResultPane.prototype = {
|
|||||||
|
|
||||||
_init: function(dash) {
|
_init: function(dash) {
|
||||||
Pane.prototype._init.call(this);
|
Pane.prototype._init.call(this);
|
||||||
this._dash = dash;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Create a display of displayType and pack it into this pane's
|
let resultArea = new ResultArea();
|
||||||
// content area. Return the display.
|
this.actor.add(resultArea.actor, { expand: true });
|
||||||
packResults: function(displayType) {
|
|
||||||
let resultArea = new ResultArea(displayType);
|
|
||||||
|
|
||||||
createPaneForDetails(this._dash, resultArea.display);
|
|
||||||
|
|
||||||
this.content.add(resultArea.actor, { expand: true });
|
|
||||||
this.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
|
this.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
|
||||||
resultArea.display.resetState();
|
resultArea.display.resetState();
|
||||||
}));
|
}));
|
||||||
return resultArea.display;
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function SearchEntry() {
|
function SearchEntry() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -225,113 +142,144 @@ function SearchEntry() {
|
|||||||
|
|
||||||
SearchEntry.prototype = {
|
SearchEntry.prototype = {
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this.actor = new St.BoxLayout({ name: "searchEntry",
|
this.actor = new St.Entry({ name: 'searchEntry',
|
||||||
reactive: true });
|
hint_text: _("Find") });
|
||||||
let box = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
this.entry = this.actor.clutter_text;
|
||||||
y_align: Big.BoxAlignment.CENTER });
|
|
||||||
this.actor.add(box, { expand: true });
|
this.actor.clutter_text.connect('text-changed', Lang.bind(this,
|
||||||
this.actor.connect('button-press-event', Lang.bind(this, function () {
|
function() {
|
||||||
this._resetTextState(true);
|
if (this.isActive())
|
||||||
return false;
|
this.actor.set_secondary_icon_from_file(global.imagedir +
|
||||||
}));
|
'close-black.svg');
|
||||||
|
else
|
||||||
|
this.actor.set_secondary_icon_from_file(null);
|
||||||
|
}));
|
||||||
|
this.actor.connect('secondary-icon-clicked', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this.reset();
|
||||||
|
}));
|
||||||
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
|
global.stage.connect('notify::key-focus', Lang.bind(this, this._updateCursorVisibility));
|
||||||
|
|
||||||
this.pane = null;
|
this.pane = null;
|
||||||
|
|
||||||
this._defaultText = _("Find...");
|
this._capturedEventId = 0;
|
||||||
|
|
||||||
let textProperties = { font_name: "Sans 16px" };
|
|
||||||
let entryProperties = { editable: true,
|
|
||||||
activatable: true,
|
|
||||||
single_line_mode: true,
|
|
||||||
color: SEARCH_TEXT_COLOR,
|
|
||||||
cursor_color: SEARCH_CURSOR_COLOR };
|
|
||||||
Lang.copyProperties(textProperties, entryProperties);
|
|
||||||
this.entry = new Clutter.Text(entryProperties);
|
|
||||||
|
|
||||||
this.entry.connect('notify::text', Lang.bind(this, function () {
|
|
||||||
this._resetTextState(false);
|
|
||||||
}));
|
|
||||||
box.append(this.entry, Big.BoxPackFlags.EXPAND);
|
|
||||||
|
|
||||||
// Mark as editable just to get a cursor
|
|
||||||
let defaultTextProperties = { ellipsize: Pango.EllipsizeMode.END,
|
|
||||||
text: this._defaultText,
|
|
||||||
editable: true,
|
|
||||||
color: TEXT_COLOR,
|
|
||||||
cursor_visible: false,
|
|
||||||
single_line_mode: true };
|
|
||||||
Lang.copyProperties(textProperties, defaultTextProperties);
|
|
||||||
this._defaultText = new Clutter.Text(defaultTextProperties);
|
|
||||||
box.add_actor(this._defaultText);
|
|
||||||
this.entry.connect('notify::allocation', Lang.bind(this, function () {
|
|
||||||
this._repositionDefaultText();
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._iconBox = new Big.Box({ x_align: Big.BoxAlignment.CENTER,
|
|
||||||
y_align: Big.BoxAlignment.CENTER,
|
|
||||||
padding_right: 4 });
|
|
||||||
box.append(this._iconBox, Big.BoxPackFlags.END);
|
|
||||||
|
|
||||||
let magnifierUri = "file://" + global.imagedir + "magnifier.svg";
|
|
||||||
this._magnifierIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
|
||||||
magnifierUri, 18, 18);
|
|
||||||
let closeUri = "file://" + global.imagedir + "close-black.svg";
|
|
||||||
this._closeIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
|
||||||
closeUri, 18, 18);
|
|
||||||
this._closeIcon.reactive = true;
|
|
||||||
this._closeIcon.connect('button-press-event', Lang.bind(this, function () {
|
|
||||||
// Resetting this.entry.text will trigger notify::text signal which will
|
|
||||||
// result in this._resetTextState() being called, but we should not rely
|
|
||||||
// on that not short-circuiting if the text was already empty, so we call
|
|
||||||
// this._resetTextState() explicitly in that case.
|
|
||||||
if (this.entry.text == '')
|
|
||||||
this._resetTextState(false);
|
|
||||||
else
|
|
||||||
this.entry.text = '';
|
|
||||||
|
|
||||||
// Return true to stop the signal emission, so that this.actor doesn't get
|
|
||||||
// the button-press-event and re-highlight itself.
|
|
||||||
return true;
|
|
||||||
}));
|
|
||||||
this._repositionDefaultText();
|
|
||||||
this._resetTextState();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setPane: function (pane) {
|
_updateCursorVisibility: function() {
|
||||||
this._pane = pane;
|
let focus = global.stage.get_key_focus();
|
||||||
|
if (focus == global.stage || focus == this.entry)
|
||||||
|
this.entry.set_cursor_visible(true);
|
||||||
|
else
|
||||||
|
this.entry.set_cursor_visible(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
reset: function () {
|
show: function() {
|
||||||
this.entry.text = '';
|
if (this._capturedEventId == 0)
|
||||||
|
this._capturedEventId = global.stage.connect('captured-event',
|
||||||
|
Lang.bind(this, this._onCapturedEvent));
|
||||||
|
this.entry.set_cursor_visible(true);
|
||||||
|
this.entry.set_selection(0, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
getText: function () {
|
hide: function() {
|
||||||
return this.entry.text;
|
if (this.isActive())
|
||||||
},
|
this.reset();
|
||||||
|
if (this._capturedEventId > 0) {
|
||||||
_resetTextState: function (searchEntryClicked) {
|
global.stage.disconnect(this._capturedEventId);
|
||||||
let text = this.getText();
|
this._capturedEventId = 0;
|
||||||
this._iconBox.remove_all();
|
|
||||||
// We highlight the search box if the user starts typing in it
|
|
||||||
// or just clicks in it to indicate that the search is active.
|
|
||||||
if (text != '' || searchEntryClicked) {
|
|
||||||
if (!searchEntryClicked)
|
|
||||||
this._defaultText.hide();
|
|
||||||
this._iconBox.append(this._closeIcon, Big.BoxPackFlags.NONE);
|
|
||||||
this.actor.set_style_pseudo_class('active');
|
|
||||||
this.entry.cursor_color = HIGHLIGHTED_SEARCH_CURSOR_COLOR;
|
|
||||||
} else {
|
|
||||||
this._defaultText.show();
|
|
||||||
this._iconBox.append(this._magnifierIcon, Big.BoxPackFlags.NONE);
|
|
||||||
this.actor.set_style_pseudo_class(null);
|
|
||||||
this.entry.cursor_color = SEARCH_CURSOR_COLOR;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_repositionDefaultText: function () {
|
reset: function () {
|
||||||
// Offset a little to show the cursor
|
let [x, y, mask] = global.get_pointer();
|
||||||
this._defaultText.set_position(this.entry.x + 4, this.entry.y);
|
let actor = global.stage.get_actor_at_pos (Clutter.PickMode.REACTIVE,
|
||||||
this._defaultText.set_size(this.entry.width, this.entry.height);
|
x, y);
|
||||||
|
// this.actor is never hovered directly, only its clutter_text and icon
|
||||||
|
let hovered = this.actor == actor.get_parent();
|
||||||
|
|
||||||
|
this.actor.set_hover(hovered);
|
||||||
|
|
||||||
|
this.entry.text = '';
|
||||||
|
global.stage.set_key_focus(null);
|
||||||
|
this.entry.set_cursor_visible(true);
|
||||||
|
this.entry.set_selection(0, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
getText: function () {
|
||||||
|
return this.entry.get_text().replace(/^\s+/g, '').replace(/\s+$/g, '');
|
||||||
|
},
|
||||||
|
|
||||||
|
// some search term has been entered
|
||||||
|
isActive: function() {
|
||||||
|
return this.actor.get_text() != '';
|
||||||
|
},
|
||||||
|
|
||||||
|
// the entry does not show the hint
|
||||||
|
_isActivated: function() {
|
||||||
|
return this.entry.text == this.actor.get_text();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onCapturedEvent: function(actor, event) {
|
||||||
|
let source = event.get_source();
|
||||||
|
let panelEvent = source && Main.panel.actor.contains(source);
|
||||||
|
|
||||||
|
switch (event.type()) {
|
||||||
|
case Clutter.EventType.BUTTON_PRESS:
|
||||||
|
// the user clicked outside after activating the entry, but
|
||||||
|
// with no search term entered - cancel the search
|
||||||
|
if (source != this.entry && this.entry.text == '') {
|
||||||
|
this.reset();
|
||||||
|
// allow only panel events to continue
|
||||||
|
return !panelEvent;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case Clutter.EventType.KEY_PRESS:
|
||||||
|
// If neither the stage nor our entry have key focus, some
|
||||||
|
// "special" actor grabbed the focus (run dialog, looking
|
||||||
|
// glass); we don't want to interfere with that
|
||||||
|
let focus = global.stage.get_key_focus();
|
||||||
|
if (focus != global.stage && focus != this.entry)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let sym = event.get_key_symbol();
|
||||||
|
|
||||||
|
// If we have an active search, Escape cancels it - if we
|
||||||
|
// haven't, the key is ignored
|
||||||
|
if (sym == Clutter.Escape)
|
||||||
|
if (this._isActivated()) {
|
||||||
|
this.reset();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore non-printable keys
|
||||||
|
if (!Clutter.keysym_to_unicode(sym))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Search started - move the key focus to the entry and
|
||||||
|
// "repeat" the event
|
||||||
|
if (!this._isActivated()) {
|
||||||
|
global.stage.set_key_focus(this.entry);
|
||||||
|
this.entry.event(event, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
// Suppress all other events outside the panel while the entry
|
||||||
|
// is activated and no search has been entered - any click
|
||||||
|
// outside the entry will cancel the search
|
||||||
|
return (this.entry.text == '' && !panelEvent);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDestroy: function() {
|
||||||
|
if (this._capturedEventId > 0) {
|
||||||
|
global.stage.disconnect(this._capturedEventId);
|
||||||
|
this._capturedEventId = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(SearchEntry.prototype);
|
Signals.addSignalMethods(SearchEntry.prototype);
|
||||||
@ -363,10 +311,23 @@ SearchResult.prototype = {
|
|||||||
this.actor.set_child(content);
|
this.actor.set_child(content);
|
||||||
|
|
||||||
this.actor.connect('clicked', Lang.bind(this, this._onResultClicked));
|
this.actor.connect('clicked', Lang.bind(this, this._onResultClicked));
|
||||||
|
|
||||||
|
let draggable = DND.makeDraggable(this.actor);
|
||||||
|
draggable.connect('drag-begin',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
Main.overview.beginItemDrag(this);
|
||||||
|
}));
|
||||||
|
draggable.connect('drag-end',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
Main.overview.endItemDrag(this);
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
setSelected: function(selected) {
|
setSelected: function(selected) {
|
||||||
this._content.set_style_pseudo_class(selected ? 'selected' : null);
|
if (selected)
|
||||||
|
this._content.add_style_pseudo_class('selected');
|
||||||
|
else
|
||||||
|
this._content.remove_style_pseudo_class('selected');
|
||||||
},
|
},
|
||||||
|
|
||||||
activate: function() {
|
activate: function() {
|
||||||
@ -376,8 +337,23 @@ SearchResult.prototype = {
|
|||||||
|
|
||||||
_onResultClicked: function(actor, event) {
|
_onResultClicked: function(actor, event) {
|
||||||
this.activate();
|
this.activate();
|
||||||
|
},
|
||||||
|
|
||||||
|
getDragActorSource: function() {
|
||||||
|
return this.metaInfo['icon'];
|
||||||
|
},
|
||||||
|
|
||||||
|
getDragActor: function(stageX, stageY) {
|
||||||
|
return new Clutter.Clone({ source: this.metaInfo['icon'] });
|
||||||
|
},
|
||||||
|
|
||||||
|
shellWorkspaceLaunch: function() {
|
||||||
|
if (this.provider.dragActivateResult)
|
||||||
|
this.provider.dragActivateResult(this.metaInfo.id);
|
||||||
|
else
|
||||||
|
this.provider.activateResult(this.metaInfo.id);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function OverflowSearchResults(provider) {
|
function OverflowSearchResults(provider) {
|
||||||
this._init(provider);
|
this._init(provider);
|
||||||
@ -391,6 +367,10 @@ OverflowSearchResults.prototype = {
|
|||||||
this.actor = new St.OverflowBox({ style_class: 'dash-search-section-list-results' });
|
this.actor = new St.OverflowBox({ style_class: 'dash-search-section-list-results' });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getVisibleResultCount: function() {
|
||||||
|
return this.actor.get_n_visible();
|
||||||
|
},
|
||||||
|
|
||||||
renderResults: function(results, terms) {
|
renderResults: function(results, terms) {
|
||||||
for (let i = 0; i < results.length && i < MAX_RENDERED_SEARCH_RESULTS; i++) {
|
for (let i = 0; i < results.length && i < MAX_RENDERED_SEARCH_RESULTS; i++) {
|
||||||
let result = results[i];
|
let result = results[i];
|
||||||
@ -400,10 +380,6 @@ OverflowSearchResults.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getVisibleCount: function() {
|
|
||||||
return this.actor.get_n_visible();
|
|
||||||
},
|
|
||||||
|
|
||||||
selectIndex: function(index) {
|
selectIndex: function(index) {
|
||||||
let nVisible = this.actor.get_n_visible();
|
let nVisible = this.actor.get_n_visible();
|
||||||
let children = this.actor.get_children();
|
let children = this.actor.get_children();
|
||||||
@ -420,8 +396,14 @@ OverflowSearchResults.prototype = {
|
|||||||
targetActor._delegate.setSelected(true);
|
targetActor._delegate.setSelected(true);
|
||||||
this.selectionIndex = index;
|
this.selectionIndex = index;
|
||||||
return true;
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
activateSelected: function() {
|
||||||
|
let children = this.actor.get_children();
|
||||||
|
let targetActor = children[this.selectionIndex];
|
||||||
|
targetActor._delegate.activate();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function SearchResults(searchSystem) {
|
function SearchResults(searchSystem) {
|
||||||
this._init(searchSystem);
|
this._init(searchSystem);
|
||||||
@ -433,9 +415,8 @@ SearchResults.prototype = {
|
|||||||
|
|
||||||
this.actor = new St.BoxLayout({ name: 'dashSearchResults',
|
this.actor = new St.BoxLayout({ name: 'dashSearchResults',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
this._searchingNotice = new St.Label({ style_class: 'dash-search-starting',
|
this._statusText = new St.Label({ style_class: 'dash-search-statustext' });
|
||||||
text: _("Searching...") });
|
this.actor.add(this._statusText);
|
||||||
this.actor.add(this._searchingNotice);
|
|
||||||
this._selectedProvider = -1;
|
this._selectedProvider = -1;
|
||||||
this._providers = this._searchSystem.getProviders();
|
this._providers = this._searchSystem.getProviders();
|
||||||
this._providerMeta = [];
|
this._providerMeta = [];
|
||||||
@ -485,13 +466,14 @@ SearchResults.prototype = {
|
|||||||
|
|
||||||
reset: function() {
|
reset: function() {
|
||||||
this._searchSystem.reset();
|
this._searchSystem.reset();
|
||||||
this._searchingNotice.hide();
|
this._statusText.hide();
|
||||||
this._clearDisplay();
|
this._clearDisplay();
|
||||||
},
|
},
|
||||||
|
|
||||||
startingSearch: function() {
|
startingSearch: function() {
|
||||||
this.reset();
|
this.reset();
|
||||||
this._searchingNotice.show();
|
this._statusText.set_text(_("Searching..."));
|
||||||
|
this._statusText.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
_metaForProvider: function(provider) {
|
_metaForProvider: function(provider) {
|
||||||
@ -501,9 +483,16 @@ SearchResults.prototype = {
|
|||||||
updateSearch: function (searchString) {
|
updateSearch: function (searchString) {
|
||||||
let results = this._searchSystem.updateSearch(searchString);
|
let results = this._searchSystem.updateSearch(searchString);
|
||||||
|
|
||||||
this._searchingNotice.hide();
|
|
||||||
this._clearDisplay();
|
this._clearDisplay();
|
||||||
|
|
||||||
|
if (results.length == 0) {
|
||||||
|
this._statusText.set_text(_("No matching results."));
|
||||||
|
this._statusText.show();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
this._statusText.hide();
|
||||||
|
}
|
||||||
|
|
||||||
let terms = this._searchSystem.getTerms();
|
let terms = this._searchSystem.getTerms();
|
||||||
|
|
||||||
for (let i = 0; i < results.length; i++) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
@ -511,7 +500,7 @@ SearchResults.prototype = {
|
|||||||
let meta = this._metaForProvider(provider);
|
let meta = this._metaForProvider(provider);
|
||||||
meta.actor.show();
|
meta.actor.show();
|
||||||
meta.resultDisplay.renderResults(providerResults, terms);
|
meta.resultDisplay.renderResults(providerResults, terms);
|
||||||
meta.count.set_text(""+providerResults.length);
|
meta.count.set_text('' + providerResults.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selectDown(false);
|
this.selectDown(false);
|
||||||
@ -527,7 +516,7 @@ SearchResults.prototype = {
|
|||||||
let success;
|
let success;
|
||||||
let index = resultDisplay.getSelectionIndex();
|
let index = resultDisplay.getSelectionIndex();
|
||||||
if (up && index == -1)
|
if (up && index == -1)
|
||||||
index = resultDisplay.getVisibleCount() - 1;
|
index = resultDisplay.getVisibleResultCount() - 1;
|
||||||
else if (up)
|
else if (up)
|
||||||
index = index - 1;
|
index = index - 1;
|
||||||
else
|
else
|
||||||
@ -578,11 +567,10 @@ SearchResults.prototype = {
|
|||||||
return;
|
return;
|
||||||
let meta = this._providerMeta[current];
|
let meta = this._providerMeta[current];
|
||||||
let resultDisplay = meta.resultDisplay;
|
let resultDisplay = meta.resultDisplay;
|
||||||
let children = resultDisplay.actor.get_children();
|
resultDisplay.activateSelected();
|
||||||
let targetActor = children[resultDisplay.getSelectionIndex()];
|
Main.overview.hide();
|
||||||
targetActor._delegate.activate();
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function MoreLink() {
|
function MoreLink() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -590,12 +578,12 @@ function MoreLink() {
|
|||||||
|
|
||||||
MoreLink.prototype = {
|
MoreLink.prototype = {
|
||||||
_init : function () {
|
_init : function () {
|
||||||
this.actor = new St.BoxLayout({ style_class: "more-link",
|
this.actor = new St.BoxLayout({ style_class: 'more-link',
|
||||||
reactive: true });
|
reactive: true });
|
||||||
this.pane = null;
|
this.pane = null;
|
||||||
|
|
||||||
let expander = new St.Bin({ style_class: "more-link-expander" });
|
this._expander = new St.Bin({ style_class: 'more-link-expander' });
|
||||||
this.actor.add(expander, { expand: true, y_fill: false });
|
this.actor.add(this._expander, { expand: true, y_fill: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
activate: function() {
|
activate: function() {
|
||||||
@ -610,54 +598,35 @@ MoreLink.prototype = {
|
|||||||
setPane: function (pane) {
|
setPane: function (pane) {
|
||||||
this._pane = pane;
|
this._pane = pane;
|
||||||
this._pane.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
|
this._pane.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
|
||||||
|
if (isOpen)
|
||||||
|
this._expander.add_style_class_name('open');
|
||||||
|
else
|
||||||
|
this._expander.remove_style_class_name('open');
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Signals.addSignalMethods(MoreLink.prototype);
|
Signals.addSignalMethods(MoreLink.prototype);
|
||||||
|
|
||||||
function BackLink() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
BackLink.prototype = {
|
|
||||||
_init : function () {
|
|
||||||
this.actor = new St.Button({ style_class: "section-header-back",
|
|
||||||
reactive: true });
|
|
||||||
this.actor.set_child(new St.Bin({ style_class: "section-header-back-image" }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function SectionHeader(title, suppressBrowse) {
|
function SectionHeader(title, suppressBrowse) {
|
||||||
this._init(title, suppressBrowse);
|
this._init(title, suppressBrowse);
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionHeader.prototype = {
|
SectionHeader.prototype = {
|
||||||
_init : function (title, suppressBrowse) {
|
_init : function (title, suppressBrowse) {
|
||||||
this.actor = new St.Bin({ style_class: "section-header",
|
this.actor = new St.Bin({ style_class: 'section-header',
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_fill: true,
|
y_fill: true,
|
||||||
reactive: !suppressBrowse });
|
reactive: !suppressBrowse });
|
||||||
this._innerBox = new St.BoxLayout({ style_class: "section-header-inner" });
|
this._innerBox = new St.BoxLayout({ style_class: 'section-header-inner' });
|
||||||
this.actor.set_child(this._innerBox);
|
this.actor.set_child(this._innerBox);
|
||||||
|
|
||||||
this.backLink = new BackLink();
|
let textBox = new St.BoxLayout({ style_class: 'section-text-content' });
|
||||||
this._innerBox.add(this.backLink.actor);
|
this.text = new St.Label({ style_class: 'section-title',
|
||||||
this.backLink.actor.hide();
|
|
||||||
this.backLink.actor.connect('clicked', Lang.bind(this, function (actor) {
|
|
||||||
this.emit('back-link-activated');
|
|
||||||
}));
|
|
||||||
|
|
||||||
let textBox = new St.BoxLayout({ style_class: "section-text-content" });
|
|
||||||
this.text = new St.Label({ style_class: "section-title",
|
|
||||||
text: title });
|
text: title });
|
||||||
textBox.add(this.text, { x_align: St.Align.START });
|
textBox.add(this.text, { x_align: St.Align.START });
|
||||||
|
|
||||||
this.countText = new St.Label({ style_class: "section-count" });
|
|
||||||
textBox.add(this.countText, { expand: true, x_fill: false, x_align: St.Align.END });
|
|
||||||
this.countText.hide();
|
|
||||||
|
|
||||||
this._innerBox.add(textBox, { expand: true });
|
this._innerBox.add(textBox, { expand: true });
|
||||||
|
|
||||||
if (!suppressBrowse) {
|
if (!suppressBrowse) {
|
||||||
@ -671,33 +640,13 @@ SectionHeader.prototype = {
|
|||||||
this.moreLink.activate();
|
this.moreLink.activate();
|
||||||
},
|
},
|
||||||
|
|
||||||
setTitle : function(title) {
|
|
||||||
this.text.text = title;
|
|
||||||
},
|
|
||||||
|
|
||||||
setBackLinkVisible : function(visible) {
|
|
||||||
if (visible)
|
|
||||||
this.backLink.actor.show();
|
|
||||||
else
|
|
||||||
this.backLink.actor.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
setMoreLinkVisible : function(visible) {
|
setMoreLinkVisible : function(visible) {
|
||||||
if (visible)
|
if (visible)
|
||||||
this.moreLink.actor.show();
|
this.moreLink.actor.show();
|
||||||
else
|
else
|
||||||
this.moreLink.actor.hide();
|
this.moreLink.actor.hide();
|
||||||
},
|
|
||||||
|
|
||||||
setCountText : function(countText) {
|
|
||||||
if (countText == "") {
|
|
||||||
this.countText.hide();
|
|
||||||
} else {
|
|
||||||
this.countText.show();
|
|
||||||
this.countText.text = countText;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Signals.addSignalMethods(SectionHeader.prototype);
|
Signals.addSignalMethods(SectionHeader.prototype);
|
||||||
|
|
||||||
@ -707,21 +656,21 @@ function SearchSectionHeader(title, onClick) {
|
|||||||
|
|
||||||
SearchSectionHeader.prototype = {
|
SearchSectionHeader.prototype = {
|
||||||
_init : function(title, onClick) {
|
_init : function(title, onClick) {
|
||||||
this.actor = new St.Button({ style_class: "dash-search-section-header",
|
this.actor = new St.Button({ style_class: 'dash-search-section-header',
|
||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
let box = new St.BoxLayout();
|
let box = new St.BoxLayout();
|
||||||
this.actor.set_child(box);
|
this.actor.set_child(box);
|
||||||
let titleText = new St.Label({ style_class: "dash-search-section-title",
|
let titleText = new St.Label({ style_class: 'dash-search-section-title',
|
||||||
text: title });
|
text: title });
|
||||||
this.countText = new St.Label({ style_class: "dash-search-section-count" });
|
this.countText = new St.Label({ style_class: 'dash-search-section-count' });
|
||||||
|
|
||||||
box.add(titleText);
|
box.add(titleText);
|
||||||
box.add(this.countText, { expand: true, x_fill: false, x_align: St.Align.END });
|
box.add(this.countText, { expand: true, x_fill: false, x_align: St.Align.END });
|
||||||
|
|
||||||
this.actor.connect('clicked', onClick);
|
this.actor.connect('clicked', onClick);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function Section(titleString, suppressBrowse) {
|
function Section(titleString, suppressBrowse) {
|
||||||
this._init(titleString, suppressBrowse);
|
this._init(titleString, suppressBrowse);
|
||||||
@ -737,7 +686,7 @@ Section.prototype = {
|
|||||||
vertical: true });
|
vertical: true });
|
||||||
this.actor.add(this.content);
|
this.actor.add(this.content);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function Dash() {
|
function Dash() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -754,14 +703,14 @@ Dash.prototype = {
|
|||||||
// of the Group actor ends up including the width of its hidden children, so we were getting a reactive object as
|
// of the Group actor ends up including the width of its hidden children, so we were getting a reactive object as
|
||||||
// wide as the details pane that was blocking the clicks to the workspaces underneath it even when the details pane
|
// wide as the details pane that was blocking the clicks to the workspaces underneath it even when the details pane
|
||||||
// was actually hidden.
|
// was actually hidden.
|
||||||
this.actor = new St.BoxLayout({ name: "dash",
|
this.actor = new St.BoxLayout({ name: 'dash',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
reactive: true });
|
reactive: true });
|
||||||
|
|
||||||
// The searchArea just holds the entry
|
// The searchArea just holds the entry
|
||||||
this.searchArea = new St.BoxLayout({ name: "dashSearchArea",
|
this.searchArea = new St.BoxLayout({ name: 'dashSearchArea',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
this.sectionArea = new St.BoxLayout({ name: "dashSections",
|
this.sectionArea = new St.BoxLayout({ name: 'dashSections',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
|
|
||||||
this.actor.add(this.searchArea);
|
this.actor.add(this.searchArea);
|
||||||
@ -787,12 +736,11 @@ Dash.prototype = {
|
|||||||
this.actor.add(this.searchResults.actor);
|
this.actor.add(this.searchResults.actor);
|
||||||
this.searchResults.actor.hide();
|
this.searchResults.actor.hide();
|
||||||
|
|
||||||
|
this._keyPressId = 0;
|
||||||
this._searchTimeoutId = 0;
|
this._searchTimeoutId = 0;
|
||||||
this._searchEntry.entry.connect('text-changed', Lang.bind(this, function (se, prop) {
|
this._searchEntry.entry.connect('text-changed', Lang.bind(this, function (se, prop) {
|
||||||
let text = this._searchEntry.getText();
|
|
||||||
text = text.replace(/^\s+/g, "").replace(/\s+$/g, "");
|
|
||||||
let searchPreviouslyActive = this._searchActive;
|
let searchPreviouslyActive = this._searchActive;
|
||||||
this._searchActive = text != '';
|
this._searchActive = this._searchEntry.isActive();
|
||||||
this._searchPending = this._searchActive && !searchPreviouslyActive;
|
this._searchPending = this._searchActive && !searchPreviouslyActive;
|
||||||
if (this._searchPending) {
|
if (this._searchPending) {
|
||||||
this.searchResults.startingSearch();
|
this.searchResults.startingSearch();
|
||||||
@ -823,35 +771,6 @@ Dash.prototype = {
|
|||||||
this.searchResults.activateSelected();
|
this.searchResults.activateSelected();
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
this._searchEntry.entry.connect('key-press-event', Lang.bind(this, function (se, e) {
|
|
||||||
let symbol = e.get_key_symbol();
|
|
||||||
if (symbol == Clutter.Escape) {
|
|
||||||
// Escape will keep clearing things back to the desktop.
|
|
||||||
// If we have an active search, we remove it.
|
|
||||||
if (this._searchActive)
|
|
||||||
this._searchEntry.reset();
|
|
||||||
// Next, if we're in one of the "more" modes or showing the details pane, close them
|
|
||||||
else if (this._activePane != null)
|
|
||||||
this._activePane.close();
|
|
||||||
// Finally, just close the Overview entirely
|
|
||||||
else
|
|
||||||
Main.overview.hide();
|
|
||||||
return true;
|
|
||||||
} else if (symbol == Clutter.Up) {
|
|
||||||
if (!this._searchActive)
|
|
||||||
return true;
|
|
||||||
this.searchResults.selectUp(false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else if (symbol == Clutter.Down) {
|
|
||||||
if (!this._searchActive)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
this.searchResults.selectDown(false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}));
|
|
||||||
|
|
||||||
/***** Applications *****/
|
/***** Applications *****/
|
||||||
|
|
||||||
@ -859,13 +778,12 @@ Dash.prototype = {
|
|||||||
let appWell = new AppDisplay.AppWell();
|
let appWell = new AppDisplay.AppWell();
|
||||||
this._appsSection.content.add(appWell.actor, { expand: true });
|
this._appsSection.content.add(appWell.actor, { expand: true });
|
||||||
|
|
||||||
this._moreAppsPane = null;
|
this._allApps = null;
|
||||||
this._appsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) {
|
this._appsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) {
|
||||||
if (this._moreAppsPane == null) {
|
if (this._allApps == null) {
|
||||||
this._moreAppsPane = new ResultPane(this);
|
this._allApps = new AppDisplay.AllAppDisplay();
|
||||||
this._moreAppsPane.packResults(APPS);
|
this._addPane(this._allApps, St.Align.START);
|
||||||
this._addPane(this._moreAppsPane);
|
link.setPane(this._allApps);
|
||||||
link.setPane(this._moreAppsPane);
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -875,14 +793,14 @@ Dash.prototype = {
|
|||||||
|
|
||||||
/* Translators: This is in the sense of locations for documents,
|
/* Translators: This is in the sense of locations for documents,
|
||||||
network locations, etc. */
|
network locations, etc. */
|
||||||
this._placesSection = new Section(_("PLACES"), true);
|
this._placesSection = new Section(_("PLACES & DEVICES"), true);
|
||||||
let placesDisplay = new PlaceDisplay.DashPlaceDisplay();
|
let placesDisplay = new PlaceDisplay.DashPlaceDisplay();
|
||||||
this._placesSection.content.add(placesDisplay.actor, { expand: true });
|
this._placesSection.content.add(placesDisplay.actor, { expand: true });
|
||||||
this.sectionArea.add(this._placesSection.actor);
|
this.sectionArea.add(this._placesSection.actor);
|
||||||
|
|
||||||
/***** Documents *****/
|
/***** Documents *****/
|
||||||
|
|
||||||
this._docsSection = new Section(_("RECENT DOCUMENTS"));
|
this._docsSection = new Section(_("RECENT ITEMS"));
|
||||||
|
|
||||||
this._docDisplay = new DocDisplay.DashDocDisplay();
|
this._docDisplay = new DocDisplay.DashDocDisplay();
|
||||||
this._docsSection.content.add(this._docDisplay.actor, { expand: true });
|
this._docsSection.content.add(this._docDisplay.actor, { expand: true });
|
||||||
@ -891,8 +809,7 @@ Dash.prototype = {
|
|||||||
this._docsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) {
|
this._docsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) {
|
||||||
if (this._moreDocsPane == null) {
|
if (this._moreDocsPane == null) {
|
||||||
this._moreDocsPane = new ResultPane(this);
|
this._moreDocsPane = new ResultPane(this);
|
||||||
this._moreDocsPane.packResults(DOCS);
|
this._addPane(this._moreDocsPane, St.Align.END);
|
||||||
this._addPane(this._moreDocsPane);
|
|
||||||
link.setPane(this._moreDocsPane);
|
link.setPane(this._moreDocsPane);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@ -906,6 +823,40 @@ Dash.prototype = {
|
|||||||
this.sectionArea.add(this._docsSection.actor, { expand: true });
|
this.sectionArea.add(this._docsSection.actor, { expand: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onKeyPress: function(stage, event) {
|
||||||
|
// If neither the stage nor the search entry have key focus, some
|
||||||
|
// "special" actor grabbed the focus (run dialog, looking glass);
|
||||||
|
// we don't want to interfere with that
|
||||||
|
let focus = stage.get_key_focus();
|
||||||
|
if (focus != stage && focus != this._searchEntry.entry)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let symbol = event.get_key_symbol();
|
||||||
|
if (symbol == Clutter.Escape) {
|
||||||
|
// If we're in one of the "more" modes or showing the
|
||||||
|
// details pane, close them
|
||||||
|
if (this._activePane != null)
|
||||||
|
this._activePane.close();
|
||||||
|
// Otherwise, just close the Overview entirely
|
||||||
|
else
|
||||||
|
Main.overview.hide();
|
||||||
|
return true;
|
||||||
|
} else if (symbol == Clutter.Up) {
|
||||||
|
if (!this._searchActive)
|
||||||
|
return true;
|
||||||
|
this.searchResults.selectUp(false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if (symbol == Clutter.Down) {
|
||||||
|
if (!this._searchActive)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
this.searchResults.selectDown(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
_doSearch: function () {
|
_doSearch: function () {
|
||||||
this._searchTimeoutId = 0;
|
this._searchTimeoutId = 0;
|
||||||
let text = this._searchEntry.getText();
|
let text = this._searchEntry.getText();
|
||||||
@ -915,14 +866,21 @@ Dash.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
show: function() {
|
show: function() {
|
||||||
global.stage.set_key_focus(this._searchEntry.entry);
|
this._searchEntry.show();
|
||||||
|
if (this._keyPressId == 0)
|
||||||
|
this._keyPressId = global.stage.connect('key-press-event',
|
||||||
|
Lang.bind(this, this._onKeyPress));
|
||||||
},
|
},
|
||||||
|
|
||||||
hide: function() {
|
hide: function() {
|
||||||
this._firstSelectAfterOverlayShow = true;
|
this._firstSelectAfterOverlayShow = true;
|
||||||
this._searchEntry.reset();
|
this._searchEntry.hide();
|
||||||
if (this._activePane != null)
|
if (this._activePane != null)
|
||||||
this._activePane.close();
|
this._activePane.close();
|
||||||
|
if (this._keyPressId > 0) {
|
||||||
|
global.stage.disconnect(this._keyPressId);
|
||||||
|
this._keyPressId = 0;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
closePanes: function () {
|
closePanes: function () {
|
||||||
@ -930,7 +888,7 @@ Dash.prototype = {
|
|||||||
this._activePane.close();
|
this._activePane.close();
|
||||||
},
|
},
|
||||||
|
|
||||||
_addPane: function(pane) {
|
_addPane: function(pane, align) {
|
||||||
pane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) {
|
pane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
if (pane != this._activePane && this._activePane != null) {
|
if (pane != this._activePane && this._activePane != null) {
|
||||||
@ -941,7 +899,7 @@ Dash.prototype = {
|
|||||||
this._activePane = null;
|
this._activePane = null;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
Main.overview.addPane(pane);
|
Main.overview.addPane(pane, align);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(Dash.prototype);
|
Signals.addSignalMethods(Dash.prototype);
|
||||||
|
290
js/ui/dnd.js
@ -1,22 +1,45 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const St = imports.gi.St;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
|
const Params = imports.misc.params;
|
||||||
|
|
||||||
|
// Time to scale down to maxDragActorSize
|
||||||
|
const SCALE_ANIMATION_TIME = 0.25;
|
||||||
|
// Time to animate to original position on cancel
|
||||||
const SNAP_BACK_ANIMATION_TIME = 0.25;
|
const SNAP_BACK_ANIMATION_TIME = 0.25;
|
||||||
|
// Time to animate to original position on success
|
||||||
|
const REVERT_ANIMATION_TIME = 0.75;
|
||||||
|
|
||||||
|
const DragMotionResult = {
|
||||||
|
NO_DROP: 0,
|
||||||
|
COPY_DROP: 1,
|
||||||
|
MOVE_DROP: 2,
|
||||||
|
CONTINUE: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
const DragDropResult = {
|
||||||
|
FAILURE: 0,
|
||||||
|
SUCCESS: 1,
|
||||||
|
CONTINUE: 2
|
||||||
|
};
|
||||||
|
|
||||||
let eventHandlerActor = null;
|
let eventHandlerActor = null;
|
||||||
let currentDraggable = null;
|
let currentDraggable = null;
|
||||||
|
let dragMonitors = [];
|
||||||
|
|
||||||
function _getEventHandlerActor() {
|
function _getEventHandlerActor() {
|
||||||
if (!eventHandlerActor) {
|
if (!eventHandlerActor) {
|
||||||
eventHandlerActor = new Clutter.Rectangle();
|
eventHandlerActor = new Clutter.Rectangle();
|
||||||
eventHandlerActor.width = 0;
|
eventHandlerActor.width = 0;
|
||||||
eventHandlerActor.height = 0;
|
eventHandlerActor.height = 0;
|
||||||
global.stage.add_actor(eventHandlerActor);
|
Main.uiGroup.add_actor(eventHandlerActor);
|
||||||
// We connect to 'event' rather than 'captured-event' because the capturing phase doesn't happen
|
// We connect to 'event' rather than 'captured-event' because the capturing phase doesn't happen
|
||||||
// when you've grabbed the pointer.
|
// when you've grabbed the pointer.
|
||||||
eventHandlerActor.connect('event',
|
eventHandlerActor.connect('event',
|
||||||
@ -27,31 +50,63 @@ function _getEventHandlerActor() {
|
|||||||
return eventHandlerActor;
|
return eventHandlerActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _Draggable(actor, manualMode) {
|
function addDragMonitor(monitor) {
|
||||||
this._init(actor, manualMode);
|
dragMonitors.push(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeMonitor(monitor) {
|
||||||
|
for (let i = 0; i < dragMonitors.length; i++)
|
||||||
|
if (dragMonitors[i] == monitor) {
|
||||||
|
dragMonitors.splice(i, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _Draggable(actor, params) {
|
||||||
|
this._init(actor, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
_Draggable.prototype = {
|
_Draggable.prototype = {
|
||||||
_init : function(actor, manualMode) {
|
_init : function(actor, params) {
|
||||||
|
params = Params.parse(params, { manualMode: false,
|
||||||
|
restoreOnSuccess: false,
|
||||||
|
dragActorMaxSize: undefined,
|
||||||
|
dragActorOpacity: undefined });
|
||||||
|
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
if (!manualMode)
|
if (!params.manualMode)
|
||||||
this.actor.connect('button-press-event',
|
this.actor.connect('button-press-event',
|
||||||
Lang.bind(this, this._onButtonPress));
|
Lang.bind(this, this._onButtonPress));
|
||||||
|
|
||||||
|
this.actor.connect('destroy', Lang.bind(this, function() {
|
||||||
|
this.disconnectAll();
|
||||||
|
}));
|
||||||
this._onEventId = null;
|
this._onEventId = null;
|
||||||
|
|
||||||
|
this._restoreOnSuccess = params.restoreOnSuccess;
|
||||||
|
this._dragActorMaxSize = params.dragActorMaxSize;
|
||||||
|
this._dragActorOpacity = params.dragActorOpacity;
|
||||||
|
|
||||||
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
||||||
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
|
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
|
||||||
this._snapBackInProgress = false; // The drag has been cancelled and the item is in the process of snapping back.
|
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
||||||
},
|
},
|
||||||
|
|
||||||
_onButtonPress : function (actor, event) {
|
_onButtonPress : function (actor, event) {
|
||||||
// FIXME: we should make sure it's button 1, but we can't currently
|
if (event.get_button() != 1)
|
||||||
// check that from JavaScript
|
return false;
|
||||||
|
|
||||||
if (Tweener.getTweenCount(actor))
|
if (Tweener.getTweenCount(actor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
this._buttonDown = true;
|
this._buttonDown = true;
|
||||||
this._grabActor();
|
// special case St.Clickable: grabbing the pointer would mess up the
|
||||||
|
// internal state, so we start the drag manually on hover change
|
||||||
|
if (this.actor instanceof St.Clickable)
|
||||||
|
this.actor.connect('notify::hover',
|
||||||
|
Lang.bind(this, this._onClickableHoverChanged));
|
||||||
|
else
|
||||||
|
this._grabActor();
|
||||||
|
|
||||||
let [stageX, stageY] = event.get_coords();
|
let [stageX, stageY] = event.get_coords();
|
||||||
this._dragStartX = stageX;
|
this._dragStartX = stageX;
|
||||||
@ -59,7 +114,16 @@ _Draggable.prototype = {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onClickableHoverChanged: function(button) {
|
||||||
|
if (button.hover || !button.held)
|
||||||
|
return;
|
||||||
|
|
||||||
|
button.fake_release();
|
||||||
|
this.startDrag(this._dragStartX, this._dragStartY,
|
||||||
|
global.get_current_time());
|
||||||
|
},
|
||||||
|
|
||||||
_grabActor: function() {
|
_grabActor: function() {
|
||||||
Clutter.grab_pointer(this.actor);
|
Clutter.grab_pointer(this.actor);
|
||||||
this._onEventId = this.actor.connect('event',
|
this._onEventId = this.actor.connect('event',
|
||||||
@ -91,7 +155,7 @@ _Draggable.prototype = {
|
|||||||
this._buttonDown = false;
|
this._buttonDown = false;
|
||||||
if (this._dragInProgress) {
|
if (this._dragInProgress) {
|
||||||
return this._dragActorDropped(event);
|
return this._dragActorDropped(event);
|
||||||
} else if (this._dragActor != null && !this._snapBackInProgress) {
|
} else if (this._dragActor != null && !this._animationInProgress) {
|
||||||
// Drag must have been cancelled with Esc.
|
// Drag must have been cancelled with Esc.
|
||||||
this._dragComplete();
|
this._dragComplete();
|
||||||
return true;
|
return true;
|
||||||
@ -140,8 +204,8 @@ _Draggable.prototype = {
|
|||||||
this._ungrabActor();
|
this._ungrabActor();
|
||||||
this._grabEvents();
|
this._grabEvents();
|
||||||
|
|
||||||
this._dragStartX = stageX;
|
this._dragX = this._dragStartX = stageX;
|
||||||
this._dragStartY = stageY;
|
this._dragY = this._dragStartY = stageY;
|
||||||
|
|
||||||
if (this.actor._delegate && this.actor._delegate.getDragActor) {
|
if (this.actor._delegate && this.actor._delegate.getDragActor) {
|
||||||
this._dragActor = this.actor._delegate.getDragActor(this._dragStartX, this._dragStartY);
|
this._dragActor = this.actor._delegate.getDragActor(this._dragStartX, this._dragStartY);
|
||||||
@ -154,10 +218,9 @@ _Draggable.prototype = {
|
|||||||
// the dragActor over it. Otherwise, center it
|
// the dragActor over it. Otherwise, center it
|
||||||
// around the pointer
|
// around the pointer
|
||||||
let [sourceX, sourceY] = this._dragActorSource.get_transformed_position();
|
let [sourceX, sourceY] = this._dragActorSource.get_transformed_position();
|
||||||
let [sourceWidth, sourceHeight] = this._dragActorSource.get_transformed_size();
|
|
||||||
let x, y;
|
let x, y;
|
||||||
if (stageX > sourceX && stageX <= sourceX + sourceWidth &&
|
if (stageX > sourceX && stageX <= sourceX + this._dragActor.width &&
|
||||||
stageY > sourceY && stageY <= sourceY + sourceHeight) {
|
stageY > sourceY && stageY <= sourceY + this._dragActor.height) {
|
||||||
x = sourceX;
|
x = sourceX;
|
||||||
y = sourceY;
|
y = sourceY;
|
||||||
} else {
|
} else {
|
||||||
@ -193,6 +256,45 @@ _Draggable.prototype = {
|
|||||||
|
|
||||||
this._dragActor.reparent(this.actor.get_stage());
|
this._dragActor.reparent(this.actor.get_stage());
|
||||||
this._dragActor.raise_top();
|
this._dragActor.raise_top();
|
||||||
|
|
||||||
|
this._dragOrigOpacity = this._dragActor.opacity;
|
||||||
|
if (this._dragActorOpacity != undefined)
|
||||||
|
this._dragActor.opacity = this._dragActorOpacity;
|
||||||
|
|
||||||
|
this._snapBackX = this._dragStartX + this._dragOffsetX;
|
||||||
|
this._snapBackY = this._dragStartY + this._dragOffsetY;
|
||||||
|
this._snapBackScale = this._dragActor.scale_x;
|
||||||
|
|
||||||
|
if (this._dragActorMaxSize != undefined) {
|
||||||
|
let [scaledWidth, scaledHeight] = this._dragActor.get_transformed_size();
|
||||||
|
let currentSize = Math.max(scaledWidth, scaledHeight);
|
||||||
|
if (currentSize > this._dragActorMaxSize) {
|
||||||
|
let scale = this._dragActorMaxSize / currentSize;
|
||||||
|
let origScale = this._dragActor.scale_x;
|
||||||
|
let origDragOffsetX = this._dragOffsetX;
|
||||||
|
let origDragOffsetY = this._dragOffsetY;
|
||||||
|
|
||||||
|
// The position of the actor changes as we scale
|
||||||
|
// around the drag position, but we can't just tween
|
||||||
|
// to the final position because that tween would
|
||||||
|
// fight with updates as the user continues dragging
|
||||||
|
// the mouse; instead we do the position computations in
|
||||||
|
// an onUpdate() function.
|
||||||
|
Tweener.addTween(this._dragActor,
|
||||||
|
{ scale_x: scale * origScale,
|
||||||
|
scale_y: scale * origScale,
|
||||||
|
time: SCALE_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onUpdate: function() {
|
||||||
|
let currentScale = this._dragActor.scale_x / origScale;
|
||||||
|
this._dragOffsetX = currentScale * origDragOffsetX;
|
||||||
|
this._dragOffsetY = currentScale * origDragOffsetY;
|
||||||
|
this._dragActor.set_position(this._dragX + this._dragOffsetX,
|
||||||
|
this._dragY + this._dragOffsetY);
|
||||||
|
},
|
||||||
|
onUpdateScope: this });
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_maybeStartDrag: function(event) {
|
_maybeStartDrag: function(event) {
|
||||||
@ -211,27 +313,54 @@ _Draggable.prototype = {
|
|||||||
|
|
||||||
_updateDragPosition : function (event) {
|
_updateDragPosition : function (event) {
|
||||||
let [stageX, stageY] = event.get_coords();
|
let [stageX, stageY] = event.get_coords();
|
||||||
|
this._dragX = stageX;
|
||||||
|
this._dragY = stageY;
|
||||||
|
|
||||||
// If we are dragging, update the position
|
// If we are dragging, update the position
|
||||||
if (this._dragActor) {
|
if (this._dragActor) {
|
||||||
this._dragActor.set_position(stageX + this._dragOffsetX,
|
this._dragActor.set_position(stageX + this._dragOffsetX,
|
||||||
stageY + this._dragOffsetY);
|
stageY + this._dragOffsetY);
|
||||||
|
|
||||||
// Because we want to find out what other actor is located at the current position of this._dragActor,
|
// Because we want to find out what other actor is located at the current position of this._dragActor,
|
||||||
// we have to temporarily hide this._dragActor.
|
// we have to temporarily hide this._dragActor.
|
||||||
this._dragActor.hide();
|
this._dragActor.hide();
|
||||||
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||||
stageX + this._dragOffsetX,
|
stageX, stageY);
|
||||||
stageY + this._dragOffsetY);
|
|
||||||
this._dragActor.show();
|
this._dragActor.show();
|
||||||
|
|
||||||
|
// We call observers only once per motion with the innermost
|
||||||
|
// target actor. If necessary, the observer can walk the
|
||||||
|
// parent itself.
|
||||||
|
let dragEvent = {
|
||||||
|
x: stageX,
|
||||||
|
y: stageY,
|
||||||
|
dragActor: this._dragActor,
|
||||||
|
targetActor: target
|
||||||
|
};
|
||||||
|
for (let i = 0; i < dragMonitors.length; i++) {
|
||||||
|
let motionFunc = dragMonitors[i].dragMotion;
|
||||||
|
if (motionFunc)
|
||||||
|
switch (motionFunc(dragEvent)) {
|
||||||
|
case DragMotionResult.NO_DROP:
|
||||||
|
case DragMotionResult.COPY_DROP:
|
||||||
|
case DragMotionResult.MOVE_DROP:
|
||||||
|
// TODO: set a special cursor or something ;)
|
||||||
|
return true;
|
||||||
|
case DragMotionResult.CONTINUE:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (target) {
|
while (target) {
|
||||||
if (target._delegate && target._delegate.handleDragOver) {
|
if (target._delegate && target._delegate.handleDragOver) {
|
||||||
let [targX, targY] = target.get_transformed_position();
|
let [r, targX, targY] = target.transform_stage_point(stageX, stageY);
|
||||||
// We currently loop through all parents on drag-over even if one of the children has handled it.
|
// We currently loop through all parents on drag-over even if one of the children has handled it.
|
||||||
// We can check the return value of the function and break the loop if it's true if we don't want
|
// We can check the return value of the function and break the loop if it's true if we don't want
|
||||||
// to continue checking the parents.
|
// to continue checking the parents.
|
||||||
target._delegate.handleDragOver(this.actor._delegate, this._dragActor,
|
target._delegate.handleDragOver(this.actor._delegate,
|
||||||
(stageX + this._dragOffsetX - targX) / target.scale_x,
|
this._dragActor,
|
||||||
(stageY + this._dragOffsetY - targY) / target.scale_y,
|
targX,
|
||||||
|
targY,
|
||||||
event.get_time());
|
event.get_time());
|
||||||
}
|
}
|
||||||
target = target.get_parent();
|
target = target.get_parent();
|
||||||
@ -249,17 +378,44 @@ _Draggable.prototype = {
|
|||||||
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||||
dropX, dropY);
|
dropX, dropY);
|
||||||
this._dragActor.show();
|
this._dragActor.show();
|
||||||
|
|
||||||
|
// We call observers only once per motion with the innermost
|
||||||
|
// target actor. If necessary, the observer can walk the
|
||||||
|
// parent itself.
|
||||||
|
let dropEvent = {
|
||||||
|
dropActor: this._dragActor,
|
||||||
|
targetActor: target,
|
||||||
|
clutterEvent: event
|
||||||
|
};
|
||||||
|
for (let i = 0; i < dragMonitors.length; i++) {
|
||||||
|
let dropFunc = dragMonitors[i].dragDrop;
|
||||||
|
if (dropFunc)
|
||||||
|
switch (dropFunc(dropEvent)) {
|
||||||
|
case DragDropResult.FAILURE:
|
||||||
|
case DragDropResult.SUCCESS:
|
||||||
|
return true;
|
||||||
|
case DragDropResult.CONTINUE:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (target) {
|
while (target) {
|
||||||
if (target._delegate && target._delegate.acceptDrop) {
|
if (target._delegate && target._delegate.acceptDrop) {
|
||||||
let [targX, targY] = target.get_transformed_position();
|
let [r, targX, targY] = target.transform_stage_point(dropX, dropY);
|
||||||
if (target._delegate.acceptDrop(this.actor._delegate, this._dragActor,
|
if (target._delegate.acceptDrop(this.actor._delegate,
|
||||||
(dropX - targX) / target.scale_x,
|
this._dragActor,
|
||||||
(dropY - targY) / target.scale_y,
|
targX,
|
||||||
|
targY,
|
||||||
event.get_time())) {
|
event.get_time())) {
|
||||||
// If it accepted the drop without taking the actor,
|
// If it accepted the drop without taking the actor,
|
||||||
// destroy it.
|
// handle it ourselves.
|
||||||
if (this._dragActor.get_parent() == this._dragActor.get_stage())
|
if (this._dragActor.get_parent() == this._dragActor.get_stage()) {
|
||||||
this._dragActor.destroy();
|
if (this._restoreOnSuccess) {
|
||||||
|
this._restoreDragActor(event.get_time());
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
this._dragActor.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
this._dragInProgress = false;
|
this._dragInProgress = false;
|
||||||
this.emit('drag-end', event.get_time(), true);
|
this.emit('drag-end', event.get_time(), true);
|
||||||
@ -275,31 +431,59 @@ _Draggable.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Get position of the drag actor's source if the source is still around,
|
||||||
|
// or return the original location if the actor itself was being dragged
|
||||||
|
// or the source is no longer around.
|
||||||
|
_getRestoreLocation: function() {
|
||||||
|
let locX = this._snapBackX;
|
||||||
|
let locY = this._snapBackY;
|
||||||
|
|
||||||
|
if (this._dragActorSource && this._dragActorSource.visible)
|
||||||
|
[locX, locY] = this._dragActorSource.get_transformed_position();
|
||||||
|
return [locX, locY];
|
||||||
|
},
|
||||||
|
|
||||||
_cancelDrag: function(eventTime) {
|
_cancelDrag: function(eventTime) {
|
||||||
this._dragInProgress = false;
|
this._dragInProgress = false;
|
||||||
// Snap back to the actor source if the source is still around, snap back
|
let [snapBackX, snapBackY] = this._getRestoreLocation();
|
||||||
// to the original location if the actor itself was being dragged or the
|
|
||||||
// source is no longer around.
|
|
||||||
let snapBackX = this._dragStartX + this._dragOffsetX;
|
|
||||||
let snapBackY = this._dragStartY + this._dragOffsetY;
|
|
||||||
if (this._dragActorSource && this._dragActorSource.visible) {
|
|
||||||
[snapBackX, snapBackY] = this._dragActorSource.get_transformed_position();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._snapBackInProgress = true;
|
this._animationInProgress = true;
|
||||||
// No target, so snap back
|
// No target, so snap back
|
||||||
Tweener.addTween(this._dragActor,
|
Tweener.addTween(this._dragActor,
|
||||||
{ x: snapBackX,
|
{ x: snapBackX,
|
||||||
y: snapBackY,
|
y: snapBackY,
|
||||||
|
scale_x: this._snapBackScale,
|
||||||
|
scale_y: this._snapBackScale,
|
||||||
|
opacity: this._dragOrigOpacity,
|
||||||
time: SNAP_BACK_ANIMATION_TIME,
|
time: SNAP_BACK_ANIMATION_TIME,
|
||||||
transition: "easeOutQuad",
|
transition: 'easeOutQuad',
|
||||||
onComplete: this._onSnapBackComplete,
|
onComplete: this._onAnimationComplete,
|
||||||
onCompleteScope: this,
|
onCompleteScope: this,
|
||||||
onCompleteParams: [this._dragActor, eventTime]
|
onCompleteParams: [this._dragActor, eventTime]
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onSnapBackComplete : function (dragActor, eventTime) {
|
_restoreDragActor: function(eventTime) {
|
||||||
|
this._dragInProgress = false;
|
||||||
|
[restoreX, restoreY] = this._getRestoreLocation();
|
||||||
|
|
||||||
|
// fade the actor back in at its original location
|
||||||
|
this._dragActor.set_position(restoreX, restoreY);
|
||||||
|
this._dragActor.set_scale(this._snapBackScale, this._snapBackScale);
|
||||||
|
this._dragActor.opacity = 0;
|
||||||
|
|
||||||
|
this._animationInProgress = true;
|
||||||
|
Tweener.addTween(this._dragActor,
|
||||||
|
{ opacity: this._dragOrigOpacity,
|
||||||
|
time: REVERT_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: this._onAnimationComplete,
|
||||||
|
onCompleteScope: this,
|
||||||
|
onCompleteParams: [this._dragActor, eventTime]
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_onAnimationComplete : function (dragActor, eventTime) {
|
||||||
if (this._dragOrigParent) {
|
if (this._dragOrigParent) {
|
||||||
dragActor.reparent(this._dragOrigParent);
|
dragActor.reparent(this._dragOrigParent);
|
||||||
dragActor.set_scale(this._dragOrigScale, this._dragOrigScale);
|
dragActor.set_scale(this._dragOrigScale, this._dragOrigScale);
|
||||||
@ -309,7 +493,7 @@ _Draggable.prototype = {
|
|||||||
}
|
}
|
||||||
this.emit('drag-end', eventTime, false);
|
this.emit('drag-end', eventTime, false);
|
||||||
|
|
||||||
this._snapBackInProgress = false;
|
this._animationInProgress = false;
|
||||||
if (!this._buttonDown)
|
if (!this._buttonDown)
|
||||||
this._dragComplete();
|
this._dragComplete();
|
||||||
},
|
},
|
||||||
@ -326,10 +510,24 @@ Signals.addSignalMethods(_Draggable.prototype);
|
|||||||
/**
|
/**
|
||||||
* makeDraggable:
|
* makeDraggable:
|
||||||
* @actor: Source actor
|
* @actor: Source actor
|
||||||
* @manualMode: If given, do not automatically start drag and drop on click
|
* @params: (optional) Additional parameters
|
||||||
*
|
*
|
||||||
* Create an object which controls drag and drop for the given actor.
|
* Create an object which controls drag and drop for the given actor.
|
||||||
|
*
|
||||||
|
* If %manualMode is %true in @params, do not automatically start
|
||||||
|
* drag and drop on click
|
||||||
|
*
|
||||||
|
* If %dragActorMaxSize is present in @params, the drag actor will
|
||||||
|
* be scaled down to be no larger than that size in pixels.
|
||||||
|
*
|
||||||
|
* If %dragActorOpacity is present in @params, the drag actor will
|
||||||
|
* will be set to have that opacity during the drag.
|
||||||
|
*
|
||||||
|
* Note that when the drag actor is the source actor and the drop
|
||||||
|
* succeeds, the actor scale and opacity aren't reset; if the drop
|
||||||
|
* target wants to reuse the actor, it's up to the drop target to
|
||||||
|
* reset these values.
|
||||||
*/
|
*/
|
||||||
function makeDraggable(actor, manualMode) {
|
function makeDraggable(actor, params) {
|
||||||
return new _Draggable(actor, manualMode);
|
return new _Draggable(actor, params);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
@ -42,7 +41,7 @@ DocDisplayItem.prototype = {
|
|||||||
GenericDisplay.GenericDisplayItem.prototype._init.call(this);
|
GenericDisplay.GenericDisplayItem.prototype._init.call(this);
|
||||||
this._docInfo = docInfo;
|
this._docInfo = docInfo;
|
||||||
|
|
||||||
this._setItemInfo(docInfo.name, "");
|
this._setItemInfo(docInfo.name, '');
|
||||||
|
|
||||||
this._timeoutTime = -1;
|
this._timeoutTime = -1;
|
||||||
this._resetTimeDisplay(currentSecs);
|
this._resetTimeDisplay(currentSecs);
|
||||||
@ -81,12 +80,12 @@ DocDisplayItem.prototype = {
|
|||||||
// Creates and returns a large preview icon, but only if this._docInfo is an image file
|
// Creates and returns a large preview icon, but only if this._docInfo is an image file
|
||||||
// and we were able to generate a pixbuf from it successfully.
|
// and we were able to generate a pixbuf from it successfully.
|
||||||
_createLargePreviewIcon : function() {
|
_createLargePreviewIcon : function() {
|
||||||
if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf("image/") != 0)
|
if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf('image/') != 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.NONE,
|
return St.TextureCache.get_default().load_uri_sync(St.TextureCachePolicy.NONE,
|
||||||
this._docInfo.uri, -1, -1);
|
this._docInfo.uri, -1, -1);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// An exception will be raised when the image format isn't know
|
// An exception will be raised when the image format isn't know
|
||||||
/* FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=591480: should
|
/* FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=591480: should
|
||||||
@ -116,15 +115,15 @@ DocDisplayItem.prototype = {
|
|||||||
/* This class represents a display containing a collection of document items.
|
/* This class represents a display containing a collection of document items.
|
||||||
* The documents are sorted by how recently they were last visited.
|
* The documents are sorted by how recently they were last visited.
|
||||||
*/
|
*/
|
||||||
function DocDisplay(flags) {
|
function DocDisplay() {
|
||||||
this._init(flags);
|
this._init();
|
||||||
}
|
}
|
||||||
|
|
||||||
DocDisplay.prototype = {
|
DocDisplay.prototype = {
|
||||||
__proto__: GenericDisplay.GenericDisplay.prototype,
|
__proto__: GenericDisplay.GenericDisplay.prototype,
|
||||||
|
|
||||||
_init : function(flags) {
|
_init : function() {
|
||||||
GenericDisplay.GenericDisplay.prototype._init.call(this, flags);
|
GenericDisplay.GenericDisplay.prototype._init.call(this);
|
||||||
// We keep a single timeout callback for updating last visited times
|
// We keep a single timeout callback for updating last visited times
|
||||||
// for all the items in the display. This avoids creating individual
|
// for all the items in the display. This avoids creating individual
|
||||||
// callbacks for each item in the display. So proper time updates
|
// callbacks for each item in the display. So proper time updates
|
||||||
@ -267,25 +266,35 @@ function DashDocDisplayItem(docInfo) {
|
|||||||
DashDocDisplayItem.prototype = {
|
DashDocDisplayItem.prototype = {
|
||||||
_init: function(docInfo) {
|
_init: function(docInfo) {
|
||||||
this._info = docInfo;
|
this._info = docInfo;
|
||||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
this._icon = docInfo.createIcon(DASH_DOCS_ICON_SIZE);
|
||||||
spacing: DEFAULT_SPACING,
|
|
||||||
reactive: true });
|
this.actor = new St.Clickable({ style_class: 'recent-docs-item',
|
||||||
this.actor.connect('button-release-event', Lang.bind(this, function () {
|
reactive: true,
|
||||||
|
x_align: St.Align.START });
|
||||||
|
|
||||||
|
let box = new St.BoxLayout({ style_class: 'recent-docs-item-box' });
|
||||||
|
this.actor.set_child(box);
|
||||||
|
|
||||||
|
box.add(this._icon);
|
||||||
|
|
||||||
|
let text = new St.Label({ text: docInfo.name });
|
||||||
|
box.add(text);
|
||||||
|
|
||||||
|
this.actor.connect('clicked', Lang.bind(this, function () {
|
||||||
docInfo.launch();
|
docInfo.launch();
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
|
|
||||||
this._icon = docInfo.createIcon(DASH_DOCS_ICON_SIZE);
|
|
||||||
let iconBox = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
|
|
||||||
iconBox.append(this._icon, Big.BoxPackFlags.NONE);
|
|
||||||
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
|
|
||||||
let name = new St.Label({ style_class: 'dash-recent-docs-item',
|
|
||||||
text: docInfo.name });
|
|
||||||
this.actor.append(name, Big.BoxPackFlags.EXPAND);
|
|
||||||
|
|
||||||
let draggable = DND.makeDraggable(this.actor);
|
let draggable = DND.makeDraggable(this.actor);
|
||||||
|
draggable.connect('drag-begin',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
Main.overview.beginItemDrag(this);
|
||||||
|
}));
|
||||||
|
draggable.connect('drag-end',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
Main.overview.endItemDrag(this);
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
getUri: function() {
|
getUri: function() {
|
||||||
@ -357,34 +366,37 @@ DashDocDisplay.prototype = {
|
|||||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||||
let children = actor.get_children();
|
let children = actor.get_children();
|
||||||
|
|
||||||
// Two columns, where we go vertically down first. So just take
|
// The width of an item is our allocated width, minus spacing, divided in half.
|
||||||
// the height of half of the children as our preferred height.
|
this._itemWidth = Math.floor((forWidth - DEFAULT_SPACING) / 2);
|
||||||
|
|
||||||
|
let maxNatural = 0;
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
let child = children[i];
|
||||||
|
let [minSize, naturalSize] = child.get_preferred_height(this._itemWidth);
|
||||||
|
maxNatural = Math.max(maxNatural, naturalSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._itemHeight = maxNatural;
|
||||||
|
|
||||||
let firstColumnChildren = Math.ceil(children.length / 2);
|
let firstColumnChildren = Math.ceil(children.length / 2);
|
||||||
|
alloc.natural_size = (firstColumnChildren * maxNatural +
|
||||||
let natural = 0;
|
(firstColumnChildren - 1) * DEFAULT_SPACING);
|
||||||
for (let i = 0; i < firstColumnChildren; i++) {
|
|
||||||
let child = children[i];
|
|
||||||
let [minSize, naturalSize] = child.get_preferred_height(-1);
|
|
||||||
natural += naturalSize;
|
|
||||||
|
|
||||||
if (i > 0 && i < children.length - 1) {
|
|
||||||
natural += DEFAULT_SPACING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
alloc.natural_size = natural;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
_allocate: function(actor, box, flags) {
|
||||||
let width = box.x2 - box.x1;
|
let width = box.x2 - box.x1;
|
||||||
let height = box.y2 - box.y1;
|
let height = box.y2 - box.y1;
|
||||||
|
|
||||||
|
// Make sure this._itemWidth/Height have been computed, even
|
||||||
|
// if the parent actor didn't check our size before allocating.
|
||||||
|
// (Not clear if that is required or not as a Clutter
|
||||||
|
// invariant; this is safe and cheap because of caching.)
|
||||||
|
actor.get_preferred_height(width);
|
||||||
|
|
||||||
let children = actor.get_children();
|
let children = actor.get_children();
|
||||||
|
|
||||||
// The width of an item is our allocated width, minus spacing, divided in half.
|
let x = 0;
|
||||||
let itemWidth = Math.floor((width - DEFAULT_SPACING) / 2);
|
let y = 0;
|
||||||
let x = box.x1;
|
|
||||||
let y = box.y1;
|
|
||||||
let columnIndex = 0;
|
let columnIndex = 0;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
// Loop over the children, going vertically down first. When we run
|
// Loop over the children, going vertically down first. When we run
|
||||||
@ -393,9 +405,7 @@ DashDocDisplay.prototype = {
|
|||||||
while (i < children.length) {
|
while (i < children.length) {
|
||||||
let child = children[i];
|
let child = children[i];
|
||||||
|
|
||||||
let [minSize, naturalSize] = child.get_preferred_height(-1);
|
if (y + this._itemHeight > box.y2) {
|
||||||
|
|
||||||
if (y + naturalSize > box.y2) {
|
|
||||||
// Is this the second column, or we're in
|
// Is this the second column, or we're in
|
||||||
// the first column and can't even fit one
|
// the first column and can't even fit one
|
||||||
// item? In that case, break.
|
// item? In that case, break.
|
||||||
@ -404,9 +414,9 @@ DashDocDisplay.prototype = {
|
|||||||
}
|
}
|
||||||
// Set x to the halfway point.
|
// Set x to the halfway point.
|
||||||
columnIndex += 1;
|
columnIndex += 1;
|
||||||
x = x + itemWidth + DEFAULT_SPACING;
|
x = x + this._itemWidth + DEFAULT_SPACING;
|
||||||
// And y is back to the top.
|
// And y is back to the top.
|
||||||
y = box.y1;
|
y = 0;
|
||||||
// Retry this same item, now that we're in the second column.
|
// Retry this same item, now that we're in the second column.
|
||||||
// By looping back to the top here, we re-test the size
|
// By looping back to the top here, we re-test the size
|
||||||
// again for the second column.
|
// again for the second column.
|
||||||
@ -416,13 +426,13 @@ DashDocDisplay.prototype = {
|
|||||||
let childBox = new Clutter.ActorBox();
|
let childBox = new Clutter.ActorBox();
|
||||||
childBox.x1 = x;
|
childBox.x1 = x;
|
||||||
childBox.y1 = y;
|
childBox.y1 = y;
|
||||||
childBox.x2 = childBox.x1 + itemWidth;
|
childBox.x2 = childBox.x1 + this._itemWidth;
|
||||||
childBox.y2 = y + naturalSize;
|
childBox.y2 = y + this._itemHeight;
|
||||||
|
|
||||||
y = childBox.y2 + DEFAULT_SPACING;
|
y = childBox.y2 + DEFAULT_SPACING;
|
||||||
|
|
||||||
child.show();
|
|
||||||
child.allocate(childBox, flags);
|
child.allocate(childBox, flags);
|
||||||
|
this.actor.set_skip_paint(child, false);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -438,7 +448,6 @@ DashDocDisplay.prototype = {
|
|||||||
this._checkDocExistence = false;
|
this._checkDocExistence = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let skipPaint = [];
|
|
||||||
for (; i < children.length; i++)
|
for (; i < children.length; i++)
|
||||||
this.actor.set_skip_paint(children[i], true);
|
this.actor.set_skip_paint(children[i], true);
|
||||||
},
|
},
|
||||||
@ -485,7 +494,7 @@ DocSearchProvider.prototype = {
|
|||||||
__proto__: Search.SearchProvider.prototype,
|
__proto__: Search.SearchProvider.prototype,
|
||||||
|
|
||||||
_init: function(name) {
|
_init: function(name) {
|
||||||
Search.SearchProvider.prototype._init.call(this, _("DOCUMENTS"));
|
Search.SearchProvider.prototype._init.call(this, _("RECENT ITEMS"));
|
||||||
this._docManager = DocInfo.getDocManager();
|
this._docManager = DocInfo.getDocManager();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -512,6 +521,6 @@ DocSearchProvider.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
expandSearch: function(terms) {
|
expandSearch: function(terms) {
|
||||||
log("TODO expand docs search");
|
log('TODO expand docs search');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Gettext_gtk20 = imports.gettext.domain('gtk20');
|
const Gettext_gtk20 = imports.gettext.domain('gtk20');
|
||||||
|
|
||||||
@ -28,15 +31,73 @@ function _patchContainerClass(containerClass) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_patchContainerClass(St.BoxLayout);
|
// Replace @method with something that throws an error instead
|
||||||
_patchContainerClass(St.Table);
|
function _blockMethod(method, replacement, reason) {
|
||||||
|
let match = method.match(/^(.+)\.([^.]+)$/);
|
||||||
|
if (!match)
|
||||||
|
throw new Error('Bad method name "' + method + '"');
|
||||||
|
let proto = 'imports.gi.' + match[1] + '.prototype';
|
||||||
|
let property = match[2];
|
||||||
|
|
||||||
|
if (!global.set_property_mutable(proto, property, true))
|
||||||
|
throw new Error('Bad method name "' + method + '"');
|
||||||
|
|
||||||
|
// eval() is evil in general, but we know it's safe here since
|
||||||
|
// set_property_mutable() would have failed if proto was
|
||||||
|
// malformed.
|
||||||
|
let node = eval(proto);
|
||||||
|
|
||||||
|
let msg = 'Do not use "' + method + '".';
|
||||||
|
if (replacement)
|
||||||
|
msg += ' Use "' + replacement + '" instead.';
|
||||||
|
if (reason)
|
||||||
|
msg += ' (' + reason + ')';
|
||||||
|
|
||||||
|
node[property] = function() {
|
||||||
|
throw new Error(msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
global.set_property_mutable(proto, property, false);
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
Tweener.init();
|
Tweener.init();
|
||||||
String.prototype.format = Format.format;
|
String.prototype.format = Format.format;
|
||||||
|
|
||||||
// Set the default direction for St widgets (this needs to be done before any use of St)
|
// Set the default direction for St widgets (this needs to be done before any use of St)
|
||||||
if (Gettext_gtk20.gettext("default:LTR") == "default:RTL") {
|
if (Gettext_gtk20.gettext('default:LTR') == 'default:RTL') {
|
||||||
St.Widget.set_default_direction(St.TextDirection.RTL);
|
St.Widget.set_default_direction(St.TextDirection.RTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let slowdownEnv = GLib.getenv('GNOME_SHELL_SLOWDOWN_FACTOR');
|
||||||
|
if (slowdownEnv) {
|
||||||
|
let factor = parseFloat(slowdownEnv);
|
||||||
|
if (!isNaN(factor) && factor > 0.0)
|
||||||
|
St.set_slow_down_factor(factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
_patchContainerClass(St.BoxLayout);
|
||||||
|
_patchContainerClass(St.Table);
|
||||||
|
|
||||||
|
Clutter.Actor.prototype.toString = function() {
|
||||||
|
return St.describe_actor(this);
|
||||||
|
};
|
||||||
|
Clutter.Actor.prototype.contains = function(child) {
|
||||||
|
while (child != null && child != this)
|
||||||
|
child = child.get_parent();
|
||||||
|
return child != null;
|
||||||
|
};
|
||||||
|
|
||||||
|
_blockMethod('Clutter.Event.get_state', 'Shell.get_event_state',
|
||||||
|
'gjs\'s handling of Clutter.ModifierType is broken. See bug 597292.');
|
||||||
|
_blockMethod('Gdk.Display.get_device_state', 'global.get_pointer',
|
||||||
|
'gjs\'s handling of Gdk.ModifierType is broken. See bug 597292.');
|
||||||
|
_blockMethod('Gdk.Window.get_device_position', 'global.get_pointer',
|
||||||
|
'gjs\'s handling of Gdk.ModifierType is broken. See bug 597292.');
|
||||||
|
|
||||||
|
// Now close the back door to prevent extensions from trying to
|
||||||
|
// abuse it. We can't actually delete it since
|
||||||
|
// Shell.Global.prototype itself is read-only.
|
||||||
|
global.set_property_mutable('imports.gi.Shell.Global.prototype', 'set_property_mutable', true);
|
||||||
|
Shell.Global.prototype.set_property_mutable = undefined;
|
||||||
}
|
}
|
||||||
|
@ -119,16 +119,15 @@ function loadExtension(dir, enabled, type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
let userConfigPath = GLib.get_user_config_dir();
|
let userExtensionsPath = GLib.build_filenamev([global.userdatadir, 'extensions']);
|
||||||
let userExtensionsPath = GLib.build_filenamev([userConfigPath, 'gnome-shell', 'extensions']);
|
|
||||||
userExtensionsDir = Gio.file_new_for_path(userExtensionsPath);
|
userExtensionsDir = Gio.file_new_for_path(userExtensionsPath);
|
||||||
try {
|
try {
|
||||||
userExtensionsDir.make_directory_with_parents(null);
|
userExtensionsDir.make_directory_with_parents(null);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
global.logError(""+e);
|
global.logError('' + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
disabledExtensions = Shell.GConf.get_default().get_string_list('disabled_extensions');
|
disabledExtensions = global.settings.get_strv('disabled-extensions', -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _loadExtensionsIn(dir, type) {
|
function _loadExtensionsIn(dir, type) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
@ -21,25 +20,9 @@ const RedisplayFlags = { NONE: 0,
|
|||||||
SUBSEARCH: 1 << 2,
|
SUBSEARCH: 1 << 2,
|
||||||
IMMEDIATE: 1 << 3 };
|
IMMEDIATE: 1 << 3 };
|
||||||
|
|
||||||
const ITEM_DISPLAY_DESCRIPTION_COLOR = new Clutter.Color();
|
// Used by subclasses
|
||||||
ITEM_DISPLAY_DESCRIPTION_COLOR.from_pixel(0xffffffbb);
|
|
||||||
const DISPLAY_CONTROL_SELECTED_COLOR = new Clutter.Color();
|
|
||||||
DISPLAY_CONTROL_SELECTED_COLOR.from_pixel(0x112288ff);
|
|
||||||
const PREVIEW_BOX_BACKGROUND_COLOR = new Clutter.Color();
|
|
||||||
PREVIEW_BOX_BACKGROUND_COLOR.from_pixel(0xADADADf0);
|
|
||||||
|
|
||||||
const DEFAULT_PADDING = 4;
|
|
||||||
|
|
||||||
const ITEM_DISPLAY_ICON_SIZE = 48;
|
const ITEM_DISPLAY_ICON_SIZE = 48;
|
||||||
const DEFAULT_COLUMN_GAP = 6;
|
|
||||||
|
|
||||||
const PREVIEW_ICON_SIZE = 96;
|
const PREVIEW_ICON_SIZE = 96;
|
||||||
const PREVIEW_BOX_PADDING = 6;
|
|
||||||
const PREVIEW_BOX_SPACING = DEFAULT_PADDING;
|
|
||||||
const PREVIEW_BOX_CORNER_RADIUS = 10;
|
|
||||||
// how far relative to the full item width the preview box should be placed
|
|
||||||
const PREVIEW_PLACING = 3/4;
|
|
||||||
const PREVIEW_DETAILS_MIN_WIDTH = PREVIEW_ICON_SIZE * 2;
|
|
||||||
|
|
||||||
/* This is a virtual class that represents a single display item containing
|
/* This is a virtual class that represents a single display item containing
|
||||||
* a name, a description, and an icon. It allows selecting an item and represents
|
* a name, a description, and an icon. It allows selecting an item and represents
|
||||||
@ -51,7 +34,7 @@ function GenericDisplayItem() {
|
|||||||
|
|
||||||
GenericDisplayItem.prototype = {
|
GenericDisplayItem.prototype = {
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.actor = new St.BoxLayout({ style_class: "generic-display-item",
|
this.actor = new St.BoxLayout({ style_class: 'generic-display-item',
|
||||||
reactive: true });
|
reactive: true });
|
||||||
|
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
@ -64,6 +47,14 @@ GenericDisplayItem.prototype = {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
let draggable = DND.makeDraggable(this.actor);
|
let draggable = DND.makeDraggable(this.actor);
|
||||||
|
draggable.connect('drag-begin',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
Main.overview.beginItemDrag(this);
|
||||||
|
}));
|
||||||
|
draggable.connect('drag-end',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
Main.overview.endItemDrag(this);
|
||||||
|
}));
|
||||||
|
|
||||||
this._iconBin = new St.Bin();
|
this._iconBin = new St.Bin();
|
||||||
this.actor.add(this._iconBin);
|
this.actor.add(this._iconBin);
|
||||||
@ -105,7 +96,10 @@ GenericDisplayItem.prototype = {
|
|||||||
// Highlights the item by setting a different background color than the default
|
// Highlights the item by setting a different background color than the default
|
||||||
// if isSelected is true, removes the highlighting otherwise.
|
// if isSelected is true, removes the highlighting otherwise.
|
||||||
markSelected: function(isSelected) {
|
markSelected: function(isSelected) {
|
||||||
this.actor.set_style_pseudo_class(isSelected ? "selected" : null);
|
if (isSelected)
|
||||||
|
this.actor.add_style_pseudo_class('selected');
|
||||||
|
else
|
||||||
|
this.actor.remove_style_pseudo_class('selected');
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -114,11 +108,10 @@ GenericDisplayItem.prototype = {
|
|||||||
*/
|
*/
|
||||||
createDetailsActor: function() {
|
createDetailsActor: function() {
|
||||||
|
|
||||||
let details = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
let details = new St.BoxLayout({ style_class: 'generic-display-container',
|
||||||
spacing: PREVIEW_BOX_SPACING });
|
vertical: true });
|
||||||
|
|
||||||
let mainDetails = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
let mainDetails = new St.BoxLayout({ style_class: 'generic-display-container' });
|
||||||
spacing: PREVIEW_BOX_SPACING });
|
|
||||||
|
|
||||||
// Inner box with name and description
|
// Inner box with name and description
|
||||||
let textDetails = new St.BoxLayout({ style_class: 'generic-display-details',
|
let textDetails = new St.BoxLayout({ style_class: 'generic-display-details',
|
||||||
@ -132,21 +125,19 @@ GenericDisplayItem.prototype = {
|
|||||||
|
|
||||||
this._detailsDescriptions.push(detailsDescription);
|
this._detailsDescriptions.push(detailsDescription);
|
||||||
|
|
||||||
mainDetails.append(textDetails, Big.BoxPackFlags.EXPAND);
|
mainDetails.add(textDetails, { expand: true });
|
||||||
|
|
||||||
let previewIcon = this._createPreviewIcon();
|
let previewIcon = this._createPreviewIcon();
|
||||||
let largePreviewIcon = this._createLargePreviewIcon();
|
let largePreviewIcon = this._createLargePreviewIcon();
|
||||||
|
|
||||||
if (previewIcon != null && largePreviewIcon == null) {
|
if (previewIcon != null && largePreviewIcon == null) {
|
||||||
mainDetails.prepend(previewIcon, Big.BoxPackFlags.NONE);
|
mainDetails.insert_actor(previewIcon, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
details.append(mainDetails, Big.BoxPackFlags.NONE);
|
details.add(mainDetails);
|
||||||
|
|
||||||
if (largePreviewIcon != null) {
|
if (largePreviewIcon != null) {
|
||||||
let largePreview = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
|
details.add(largePreviewIcon);
|
||||||
largePreview.append(largePreviewIcon, Big.BoxPackFlags.NONE);
|
|
||||||
details.append(largePreview, Big.BoxPackFlags.NONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return details;
|
return details;
|
||||||
@ -161,7 +152,7 @@ GenericDisplayItem.prototype = {
|
|||||||
|
|
||||||
// Performes an action associated with launching this item, such as opening a file or an application.
|
// Performes an action associated with launching this item, such as opening a file or an application.
|
||||||
launch: function() {
|
launch: function() {
|
||||||
throw new Error("Not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
//// Protected methods ////
|
//// Protected methods ////
|
||||||
@ -193,12 +184,12 @@ GenericDisplayItem.prototype = {
|
|||||||
this._icon = this._createIcon();
|
this._icon = this._createIcon();
|
||||||
this._iconBin.set_child(this._icon);
|
this._iconBin.set_child(this._icon);
|
||||||
|
|
||||||
this._name = new St.Label({ style_class: "generic-display-item-name",
|
this._name = new St.Label({ style_class: 'generic-display-item-name',
|
||||||
text: nameText });
|
text: nameText });
|
||||||
this._infoText.add(this._name);
|
this._infoText.add(this._name);
|
||||||
|
|
||||||
this._description = new St.Label({ style_class: "generic-display-item-description",
|
this._description = new St.Label({ style_class: 'generic-display-item-description',
|
||||||
text: descriptionText ? descriptionText : "" });
|
text: descriptionText ? descriptionText : '' });
|
||||||
this._infoText.add(this._description);
|
this._infoText.add(this._description);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -225,12 +216,12 @@ GenericDisplayItem.prototype = {
|
|||||||
|
|
||||||
// Returns an icon for the item.
|
// Returns an icon for the item.
|
||||||
_createIcon: function() {
|
_createIcon: function() {
|
||||||
throw new Error("Not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
// Returns a preview icon for the item.
|
// Returns a preview icon for the item.
|
||||||
_createPreviewIcon: function() {
|
_createPreviewIcon: function() {
|
||||||
throw new Error("Not implemented");
|
throw new Error('Not implemented');
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Private methods ////
|
//// Private methods ////
|
||||||
@ -238,33 +229,25 @@ GenericDisplayItem.prototype = {
|
|||||||
|
|
||||||
Signals.addSignalMethods(GenericDisplayItem.prototype);
|
Signals.addSignalMethods(GenericDisplayItem.prototype);
|
||||||
|
|
||||||
const GenericDisplayFlags = {
|
|
||||||
DISABLE_VSCROLLING: 1 << 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is a virtual class that represents a display containing a collection of items
|
/* This is a virtual class that represents a display containing a collection of items
|
||||||
* that can be filtered with a search string.
|
* that can be filtered with a search string.
|
||||||
*/
|
*/
|
||||||
function GenericDisplay(flags) {
|
function GenericDisplay() {
|
||||||
this._init(flags);
|
this._init();
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericDisplay.prototype = {
|
GenericDisplay.prototype = {
|
||||||
_init : function(flags) {
|
_init : function() {
|
||||||
let disableVScrolling = (flags & GenericDisplayFlags.DISABLE_VSCROLLING) != 0;
|
|
||||||
this._search = '';
|
this._search = '';
|
||||||
this._expanded = false;
|
this._expanded = false;
|
||||||
|
|
||||||
if (disableVScrolling) {
|
this.actor = new St.ScrollView({ x_fill: true,
|
||||||
this.actor = this._list = new Shell.OverflowList({ spacing: 6,
|
y_fill: false,
|
||||||
item_height: 50 });
|
vshadows: true });
|
||||||
} else {
|
this._list = new St.BoxLayout({ style_class: 'generic-display-container',
|
||||||
this.actor = new St.ScrollView({ x_fill: true, y_fill: true });
|
vertical: true });
|
||||||
this.actor.get_hscroll_bar().hide();
|
this.actor.add_actor(this._list);
|
||||||
this._list = new St.BoxLayout({ style_class: 'generic-display-container',
|
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||||
vertical: true });
|
|
||||||
this.actor.add_actor(this._list);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._pendingRedisplay = RedisplayFlags.NONE;
|
this._pendingRedisplay = RedisplayFlags.NONE;
|
||||||
this.actor.connect('notify::mapped', Lang.bind(this, this._onMappedNotify));
|
this.actor.connect('notify::mapped', Lang.bind(this, this._onMappedNotify));
|
||||||
@ -371,7 +354,7 @@ GenericDisplay.prototype = {
|
|||||||
// TODO: figure out why this._list.displayedCount is returning a
|
// TODO: figure out why this._list.displayedCount is returning a
|
||||||
// positive number when this._mathedItems.length is 0
|
// positive number when this._mathedItems.length is 0
|
||||||
// This can be triggered if a search string is entered for which there are no matches.
|
// This can be triggered if a search string is entered for which there are no matches.
|
||||||
// log("this._mathedItems.length: " + this._matchedItems.length + " this._list.displayedCount " + this._list.displayedCount);
|
// log('this._mathedItems.length: ' + this._matchedItems.length + ' this._list.displayedCount ' + this._list.displayedCount);
|
||||||
return this._matchedItemKeys.length > 0;
|
return this._matchedItemKeys.length > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -388,8 +371,7 @@ GenericDisplay.prototype = {
|
|||||||
resetState: function() {
|
resetState: function() {
|
||||||
this._filterReset();
|
this._filterReset();
|
||||||
this._openDetailIndex = -1;
|
this._openDetailIndex = -1;
|
||||||
if (!(this.actor instanceof Shell.OverflowList))
|
this.actor.get_vscroll_bar().get_adjustment().value = 0;
|
||||||
this.actor.get_vscroll_bar().get_adjustment().value = 0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Returns an actor which acts as a sidebar; this is used for
|
// Returns an actor which acts as a sidebar; this is used for
|
||||||
@ -417,7 +399,7 @@ GenericDisplay.prototype = {
|
|||||||
// and adds it to the list of displayed items, but does not yet display it.
|
// and adds it to the list of displayed items, but does not yet display it.
|
||||||
_addDisplayItem : function(itemId) {
|
_addDisplayItem : function(itemId) {
|
||||||
if (this._displayedItems.hasOwnProperty(itemId)) {
|
if (this._displayedItems.hasOwnProperty(itemId)) {
|
||||||
log("Tried adding a display item for " + itemId + ", but an item with this item id is already among displayed items.");
|
log('Tried adding a display item for ' + itemId + ', but an item with this item id is already among displayed items.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +458,7 @@ GenericDisplay.prototype = {
|
|||||||
// Return true if there's an active search or other constraint
|
// Return true if there's an active search or other constraint
|
||||||
// on the list
|
// on the list
|
||||||
_filterActive: function() {
|
_filterActive: function() {
|
||||||
return this._search != "";
|
return this._search != '';
|
||||||
},
|
},
|
||||||
|
|
||||||
// Called when we are resetting state
|
// Called when we are resetting state
|
||||||
@ -599,32 +581,32 @@ GenericDisplay.prototype = {
|
|||||||
// Implementation should return %true if we are up to date, and %false
|
// Implementation should return %true if we are up to date, and %false
|
||||||
// if a full reload occurred.
|
// if a full reload occurred.
|
||||||
_refreshCache: function() {
|
_refreshCache: function() {
|
||||||
throw new Error("Not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
// Sets the list of the displayed items based on the default sorting order.
|
// Sets the list of the displayed items based on the default sorting order.
|
||||||
// The default sorting order is specific to each implementing class.
|
// The default sorting order is specific to each implementing class.
|
||||||
_setDefaultList: function() {
|
_setDefaultList: function() {
|
||||||
throw new Error("Not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
// Compares items associated with the item ids based on the order in which the
|
// Compares items associated with the item ids based on the order in which the
|
||||||
// items should be displayed.
|
// items should be displayed.
|
||||||
// Intended to be used as a compareFunction for array.sort().
|
// Intended to be used as a compareFunction for array.sort().
|
||||||
// Returns an integer value indicating the result of the comparison.
|
// Returns an integer value indicating the result of the comparison.
|
||||||
_compareItems: function(itemIdA, itemIdB) {
|
_compareItems: function(itemIdA, itemIdB) {
|
||||||
throw new Error("Not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
// Checks if the item info can be a match for the search string.
|
// Checks if the item info can be a match for the search string.
|
||||||
// Returns a boolean flag indicating if that's the case.
|
// Returns a boolean flag indicating if that's the case.
|
||||||
_isInfoMatching: function(itemInfo, search) {
|
_isInfoMatching: function(itemInfo, search) {
|
||||||
throw new Error("Not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
// Creates a display item based on itemInfo.
|
// Creates a display item based on itemInfo.
|
||||||
_createDisplayItem: function(itemInfo) {
|
_createDisplayItem: function(itemInfo) {
|
||||||
throw new Error("Not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
//// Private methods ////
|
//// Private methods ////
|
||||||
@ -668,11 +650,7 @@ GenericDisplay.prototype = {
|
|||||||
// Returns a display item based on its index in the ordering of the
|
// Returns a display item based on its index in the ordering of the
|
||||||
// display children.
|
// display children.
|
||||||
_findDisplayedByIndex: function(index) {
|
_findDisplayedByIndex: function(index) {
|
||||||
let actor;
|
let actor = this._list.get_children()[index];
|
||||||
if (this.actor instanceof Shell.OverflowList)
|
|
||||||
actor = this.actor.get_displayed_actor(index);
|
|
||||||
else
|
|
||||||
actor = this._list.get_children()[index];
|
|
||||||
return this._findDisplayedByActor(actor);
|
return this._findDisplayedByActor(actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -698,7 +676,7 @@ GenericDisplay.prototype = {
|
|||||||
|
|
||||||
this._selectedIndex = index;
|
this._selectedIndex = index;
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return
|
return;
|
||||||
|
|
||||||
// Mark the new item as selected and create its details pane
|
// Mark the new item as selected and create its details pane
|
||||||
let item = this._findDisplayedByIndex(index);
|
let item = this._findDisplayedByIndex(index);
|
||||||
@ -707,8 +685,6 @@ GenericDisplay.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_getVisibleCount: function() {
|
_getVisibleCount: function() {
|
||||||
if (this.actor instanceof Shell.OverflowList)
|
|
||||||
return this._list.displayed_count;
|
|
||||||
return this._list.get_n_children();
|
return this._list.get_n_children();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2,18 +2,20 @@
|
|||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Params = imports.misc.params;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const SHADE_COLOR = new Clutter.Color();
|
|
||||||
SHADE_COLOR.from_pixel(0x00000044);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lightbox:
|
* Lightbox:
|
||||||
* @container: parent Clutter.Container
|
* @container: parent Clutter.Container
|
||||||
* @width: (optional) shade actor width
|
* @params: (optional) additional parameters:
|
||||||
* @height: (optional) shade actor height
|
* - inhibitEvents: whether to inhibit events for @container
|
||||||
|
* - width: shade actor width
|
||||||
|
* - height: shade actor height
|
||||||
|
* - fadeTime: seconds used to fade in/out
|
||||||
*
|
*
|
||||||
* Lightbox creates a dark translucent "shade" actor to hide the
|
* Lightbox creates a dark translucent "shade" actor to hide the
|
||||||
* contents of @container, and allows you to specify particular actors
|
* contents of @container, and allows you to specify particular actors
|
||||||
@ -27,30 +29,37 @@ SHADE_COLOR.from_pixel(0x00000044);
|
|||||||
*
|
*
|
||||||
* By default, the shade window will have the height and width of
|
* By default, the shade window will have the height and width of
|
||||||
* @container and will track any changes in its size. You can override
|
* @container and will track any changes in its size. You can override
|
||||||
* this by passing an explicit width and height
|
* this by passing an explicit width and height in @params.
|
||||||
*/
|
*/
|
||||||
function Lightbox(container, width, height) {
|
function Lightbox(container, params) {
|
||||||
this._init(container, width, height);
|
this._init(container, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lightbox.prototype = {
|
Lightbox.prototype = {
|
||||||
_init : function(container, width, height) {
|
_init : function(container, params) {
|
||||||
|
params = Params.parse(params, { inhibitEvents: false,
|
||||||
|
width: null,
|
||||||
|
height: null,
|
||||||
|
fadeTime: null
|
||||||
|
});
|
||||||
|
|
||||||
this._container = container;
|
this._container = container;
|
||||||
this._children = container.get_children();
|
this._children = container.get_children();
|
||||||
this.actor = new Clutter.Rectangle({ color: SHADE_COLOR,
|
this._fadeTime = params.fadeTime;
|
||||||
x: 0,
|
this.actor = new St.Bin({ x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
border_width: 0,
|
style_class: 'lightbox',
|
||||||
reactive: true });
|
reactive: params.inhibitEvents });
|
||||||
|
|
||||||
container.add_actor(this.actor);
|
container.add_actor(this.actor);
|
||||||
this.actor.raise_top();
|
this.actor.raise_top();
|
||||||
|
this.actor.hide();
|
||||||
|
|
||||||
this._destroySignalId = this.actor.connect('destroy', Lang.bind(this, this.destroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
if (width && height) {
|
if (params.width && params.height) {
|
||||||
this.actor.width = width;
|
this.actor.width = params.width;
|
||||||
this.actor.height = height;
|
this.actor.height = params.height;
|
||||||
this._allocationChangedSignalId = 0;
|
this._allocationChangedSignalId = 0;
|
||||||
} else {
|
} else {
|
||||||
this.actor.width = container.width;
|
this.actor.width = container.width;
|
||||||
@ -65,8 +74,13 @@ Lightbox.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_allocationChanged : function(container, box, flags) {
|
_allocationChanged : function(container, box, flags) {
|
||||||
this.actor.width = this._container.width;
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
||||||
this.actor.height = this._container.height;
|
this.actor.width = this.width;
|
||||||
|
this.actor.height = this.height;
|
||||||
|
return false;
|
||||||
|
}));
|
||||||
|
this.width = this._container.width;
|
||||||
|
this.height = this._container.height;
|
||||||
},
|
},
|
||||||
|
|
||||||
_actorAdded : function(container, newChild) {
|
_actorAdded : function(container, newChild) {
|
||||||
@ -91,6 +105,35 @@ Lightbox.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
if (this._fadeTime) {
|
||||||
|
this.actor.opacity = 0;
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: this._fadeTime,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.actor.opacity = 255;
|
||||||
|
}
|
||||||
|
this.actor.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function() {
|
||||||
|
if (this._fadeTime) {
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: this._fadeTime,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this, function() {
|
||||||
|
this.actor.hide();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.actor.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_actorRemoved : function(container, child) {
|
_actorRemoved : function(container, child) {
|
||||||
let index = this._children.indexOf(child);
|
let index = this._children.indexOf(child);
|
||||||
if (index != -1) // paranoia
|
if (index != -1) // paranoia
|
||||||
@ -134,18 +177,24 @@ Lightbox.prototype = {
|
|||||||
/**
|
/**
|
||||||
* destroy:
|
* destroy:
|
||||||
*
|
*
|
||||||
* Destroys the lightbox. This is called automatically if the
|
* Destroys the lightbox.
|
||||||
* lightbox's container is destroyed.
|
|
||||||
*/
|
*/
|
||||||
destroy : function() {
|
destroy : function() {
|
||||||
|
this.actor.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _onDestroy:
|
||||||
|
*
|
||||||
|
* This is called when the lightbox' actor is destroyed, either
|
||||||
|
* by destroying its container or by explicitly calling this.destroy().
|
||||||
|
*/
|
||||||
|
_onDestroy: function() {
|
||||||
if (this._allocationChangedSignalId != 0)
|
if (this._allocationChangedSignalId != 0)
|
||||||
this._container.disconnect(this._allocationChangedSignalId);
|
this._container.disconnect(this._allocationChangedSignalId);
|
||||||
this._container.disconnect(this._actorAddedSignalId);
|
this._container.disconnect(this._actorAddedSignalId);
|
||||||
this._container.disconnect(this._actorRemovedSignalId);
|
this._container.disconnect(this._actorRemovedSignalId);
|
||||||
|
|
||||||
this.actor.disconnect(this._destroySignalId);
|
|
||||||
|
|
||||||
this.highlight(null);
|
this.highlight(null);
|
||||||
this.actor.destroy();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,7 @@ function Link(props) {
|
|||||||
Link.prototype = {
|
Link.prototype = {
|
||||||
_init : function(props) {
|
_init : function(props) {
|
||||||
let realProps = { reactive: true,
|
let realProps = { reactive: true,
|
||||||
|
track_hover: true,
|
||||||
style_class: 'shell-link' };
|
style_class: 'shell-link' };
|
||||||
// The user can pass in reactive: false to override the above and get
|
// The user can pass in reactive: false to override the above and get
|
||||||
// a non-reactive link (a link to the current page, perhaps)
|
// a non-reactive link (a link to the current page, perhaps)
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const GConf = imports.gi.GConf;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@ -18,22 +19,22 @@ const Tweener = imports.ui.tweener;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
/* Imports...feel free to add here as needed */
|
/* Imports...feel free to add here as needed */
|
||||||
var commandHeader = "const Clutter = imports.gi.Clutter; " +
|
var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
|
||||||
"const GLib = imports.gi.GLib; " +
|
'const GLib = imports.gi.GLib; ' +
|
||||||
"const Gtk = imports.gi.Gtk; " +
|
'const Gtk = imports.gi.Gtk; ' +
|
||||||
"const Mainloop = imports.mainloop; " +
|
'const Mainloop = imports.mainloop; ' +
|
||||||
"const Meta = imports.gi.Meta; " +
|
'const Meta = imports.gi.Meta; ' +
|
||||||
"const Shell = imports.gi.Shell; " +
|
'const Shell = imports.gi.Shell; ' +
|
||||||
"const Main = imports.ui.main; " +
|
'const Main = imports.ui.main; ' +
|
||||||
"const Lang = imports.lang; " +
|
'const Lang = imports.lang; ' +
|
||||||
"const Tweener = imports.ui.tweener; " +
|
'const Tweener = imports.ui.tweener; ' +
|
||||||
/* Utility functions...we should probably be able to use these
|
/* Utility functions...we should probably be able to use these
|
||||||
* in the shell core code too. */
|
* in the shell core code too. */
|
||||||
"const stage = global.stage; " +
|
'const stage = global.stage; ' +
|
||||||
"const color = function(pixel) { let c= new Clutter.Color(); c.from_pixel(pixel); return c; }; " +
|
'const color = function(pixel) { let c= new Clutter.Color(); c.from_pixel(pixel); return c; }; ' +
|
||||||
/* Special lookingGlass functions */
|
/* Special lookingGlass functions */
|
||||||
"const it = Main.lookingGlass.getIt(); " +
|
'const it = Main.lookingGlass.getIt(); ' +
|
||||||
"const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ";
|
'const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ';
|
||||||
|
|
||||||
function Notebook() {
|
function Notebook() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -43,14 +44,16 @@ Notebook.prototype = {
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
this.actor = new St.BoxLayout({ vertical: true });
|
this.actor = new St.BoxLayout({ vertical: true });
|
||||||
|
|
||||||
this.tabControls = new St.BoxLayout({ style_class: "labels" });
|
this.tabControls = new St.BoxLayout({ style_class: 'labels' });
|
||||||
|
|
||||||
this._selectedIndex = -1;
|
this._selectedIndex = -1;
|
||||||
this._tabs = [];
|
this._tabs = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
appendPage: function(name, child) {
|
appendPage: function(name, child) {
|
||||||
let labelBox = new St.BoxLayout({ style_class: "notebook-tab" });
|
let labelBox = new St.BoxLayout({ style_class: 'notebook-tab',
|
||||||
|
reactive: true,
|
||||||
|
track_hover: true });
|
||||||
let label = new St.Button({ label: name });
|
let label = new St.Button({ label: name });
|
||||||
label.connect('clicked', Lang.bind(this, function () {
|
label.connect('clicked', Lang.bind(this, function () {
|
||||||
this.selectChild(child);
|
this.selectChild(child);
|
||||||
@ -84,7 +87,7 @@ Notebook.prototype = {
|
|||||||
if (this._selectedIndex < 0)
|
if (this._selectedIndex < 0)
|
||||||
return;
|
return;
|
||||||
let tabData = this._tabs[this._selectedIndex];
|
let tabData = this._tabs[this._selectedIndex];
|
||||||
tabData.labelBox.set_style_pseudo_class(null);
|
tabData.labelBox.remove_style_pseudo_class('selected');
|
||||||
tabData.scrollView.hide();
|
tabData.scrollView.hide();
|
||||||
this._selectedIndex = -1;
|
this._selectedIndex = -1;
|
||||||
},
|
},
|
||||||
@ -98,7 +101,7 @@ Notebook.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let tabData = this._tabs[index];
|
let tabData = this._tabs[index];
|
||||||
tabData.labelBox.set_style_pseudo_class('selected');
|
tabData.labelBox.add_style_pseudo_class('selected');
|
||||||
tabData.scrollView.show();
|
tabData.scrollView.show();
|
||||||
this._selectedIndex = index;
|
this._selectedIndex = index;
|
||||||
this.emit('selection', tabData.child);
|
this.emit('selection', tabData.child);
|
||||||
@ -136,9 +139,43 @@ Notebook.prototype = {
|
|||||||
let vAdjust = tabData.scrollView.vscroll.adjustment;
|
let vAdjust = tabData.scrollView.vscroll.adjustment;
|
||||||
vAdjust.value = vAdjust.upper - vAdjust.page_size;
|
vAdjust.value = vAdjust.upper - vAdjust.page_size;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Signals.addSignalMethods(Notebook.prototype);
|
Signals.addSignalMethods(Notebook.prototype);
|
||||||
|
|
||||||
|
function objectToString(o) {
|
||||||
|
if (typeof(o) == typeof(objectToString)) {
|
||||||
|
// special case this since the default is way, way too verbose
|
||||||
|
return "<js function>";
|
||||||
|
} else {
|
||||||
|
return "" + o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ObjLink(o, title) {
|
||||||
|
this._init(o, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjLink.prototype = {
|
||||||
|
__proto__: Link.Link,
|
||||||
|
|
||||||
|
_init: function(o, title) {
|
||||||
|
let text;
|
||||||
|
if (title)
|
||||||
|
text = title;
|
||||||
|
else
|
||||||
|
text = objectToString(o);
|
||||||
|
text = GLib.markup_escape_text(text, -1);
|
||||||
|
this._obj = o;
|
||||||
|
Link.Link.prototype._init.call(this, { label: text });
|
||||||
|
this.actor.get_child().single_line_mode = true;
|
||||||
|
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onClicked: function (link) {
|
||||||
|
Main.lookingGlass.inspectObject(this._obj, this.actor);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function Result(command, o, index) {
|
function Result(command, o, index) {
|
||||||
this._init(command, o, index);
|
this._init(command, o, index);
|
||||||
}
|
}
|
||||||
@ -148,109 +185,180 @@ Result.prototype = {
|
|||||||
this.index = index;
|
this.index = index;
|
||||||
this.o = o;
|
this.o = o;
|
||||||
|
|
||||||
this.actor = new Big.Box();
|
this.actor = new St.BoxLayout({ vertical: true });
|
||||||
|
|
||||||
let cmdTxt = new St.Label({ text: command });
|
let cmdTxt = new St.Label({ text: command });
|
||||||
cmdTxt.ellipsize = Pango.EllipsizeMode.END;
|
cmdTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||||
|
this.actor.add(cmdTxt);
|
||||||
this.actor.append(cmdTxt, Big.BoxPackFlags.NONE);
|
let box = new St.BoxLayout({});
|
||||||
let resultTxt = new St.Label({ text: "r(" + index + ") = " + o });
|
this.actor.add(box);
|
||||||
resultTxt.ellipsize = Pango.EllipsizeMode.END;
|
let resultTxt = new St.Label({ text: 'r(' + index + ') = ' });
|
||||||
|
resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||||
this.actor.append(resultTxt, Big.BoxPackFlags.NONE);
|
box.add(resultTxt);
|
||||||
let line = new Clutter.Rectangle({ name: "Separator",
|
let objLink = new ObjLink(o);
|
||||||
height: 1 });
|
box.add(objLink.actor);
|
||||||
let padBin = new St.Bin({ name: "Separator", x_fill: true, y_fill: true });
|
let line = new Clutter.Rectangle({ name: 'Separator' });
|
||||||
|
let padBin = new St.Bin({ name: 'Separator', x_fill: true, y_fill: true });
|
||||||
padBin.add_actor(line);
|
padBin.add_actor(line);
|
||||||
this.actor.append(padBin, Big.BoxPackFlags.NONE);
|
this.actor.add(padBin);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function ActorHierarchy() {
|
function WindowList() {
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
|
|
||||||
ActorHierarchy.prototype = {
|
WindowList.prototype = {
|
||||||
_init : function () {
|
_init : function () {
|
||||||
this._previousTarget = null;
|
this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
|
||||||
this._target = null;
|
let display = global.screen.get_display();
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
this._parentList = [];
|
this._updateId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._updateWindowList));
|
||||||
|
display.connect('window-created', Lang.bind(this, this._updateWindowList));
|
||||||
this.actor = new St.BoxLayout({ name: "ActorHierarchy", vertical: true });
|
tracker.connect('tracked-windows-changed', Lang.bind(this, this._updateWindowList));
|
||||||
},
|
},
|
||||||
|
|
||||||
setTarget: function(actor) {
|
_updateWindowList: function() {
|
||||||
this._previousTarget = this._target;
|
this.actor.get_children().forEach(function (actor) { actor.destroy(); });
|
||||||
this.target = actor;
|
let windows = global.get_windows();
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
this.actor.get_children().forEach(function (child) { child.destroy(); });
|
for (let i = 0; i < windows.length; i++) {
|
||||||
|
let metaWindow = windows[i].metaWindow;
|
||||||
if (!(actor instanceof Clutter.Actor))
|
// Avoid multiple connections
|
||||||
return;
|
if (!metaWindow._lookingGlassManaged) {
|
||||||
|
metaWindow.connect('unmanaged', Lang.bind(this, this._updateWindowList));
|
||||||
if (this.target == null)
|
metaWindow._lookingGlassManaged = true;
|
||||||
return;
|
}
|
||||||
|
let box = new St.BoxLayout({ vertical: true });
|
||||||
this._parentList = [];
|
this.actor.add(box);
|
||||||
let parent = actor;
|
let windowLink = new ObjLink(metaWindow, metaWindow.title);
|
||||||
while ((parent = parent.get_parent()) != null) {
|
box.add(windowLink.actor, { x_align: St.Align.START, x_fill: false });
|
||||||
this._parentList.push(parent);
|
let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
|
||||||
|
box.add(propsBox);
|
||||||
let link = new St.Label({ reactive: true,
|
propsBox.add(new St.Label({ text: 'wmclass: ' + metaWindow.get_wm_class() }));
|
||||||
text: "" + parent });
|
let app = tracker.get_window_app(metaWindow);
|
||||||
this.actor.add_actor(link);
|
if (app != null && !app.is_transient()) {
|
||||||
let parentTarget = parent;
|
let icon = app.create_icon_texture(22);
|
||||||
link.connect('button-press-event', Lang.bind(this, function () {
|
let propBox = new St.BoxLayout({ style: 'spacing: 6px; ' });
|
||||||
this._selectByActor(parentTarget);
|
propsBox.add(propBox);
|
||||||
return true;
|
propBox.add(new St.Label({ text: 'app: ' }), { y_fill: false });
|
||||||
}));
|
let appLink = new ObjLink(app, app.get_id());
|
||||||
}
|
propBox.add(appLink.actor, { y_fill: false });
|
||||||
this.emit('selection', actor);
|
propBox.add(icon, { y_fill: false });
|
||||||
},
|
} else {
|
||||||
|
propsBox.add(new St.Label({ text: '<untracked>' }));
|
||||||
_selectByActor: function(actor) {
|
|
||||||
let idx = this._parentList.indexOf(actor);
|
|
||||||
let children = this.actor.get_children();
|
|
||||||
let link = children[idx];
|
|
||||||
this.emit('selection', actor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Signals.addSignalMethods(ActorHierarchy.prototype);
|
|
||||||
|
|
||||||
function PropertyInspector() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyInspector.prototype = {
|
|
||||||
_init : function () {
|
|
||||||
this._target = null;
|
|
||||||
|
|
||||||
this._parentList = [];
|
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ name: "PropertyInspector", vertical: true });
|
|
||||||
},
|
|
||||||
|
|
||||||
setTarget: function(actor) {
|
|
||||||
this.target = actor;
|
|
||||||
|
|
||||||
this.actor.get_children().forEach(function (child) { child.destroy(); });
|
|
||||||
|
|
||||||
for (let propName in actor) {
|
|
||||||
let valueStr;
|
|
||||||
try {
|
|
||||||
valueStr = "" + actor[propName];
|
|
||||||
} catch (e) {
|
|
||||||
valueStr = '<error>';
|
|
||||||
}
|
}
|
||||||
let propText = propName + ": " + valueStr;
|
|
||||||
let propDisplay = new St.Label({ reactive: true,
|
|
||||||
text: propText });
|
|
||||||
this.actor.add_actor(propDisplay);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
Signals.addSignalMethods(WindowList.prototype);
|
||||||
|
|
||||||
|
function ObjInspector() {
|
||||||
|
this._init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjInspector.prototype = {
|
||||||
|
_init : function () {
|
||||||
|
this._obj = null;
|
||||||
|
this._previousObj = null;
|
||||||
|
|
||||||
|
this._parentList = [];
|
||||||
|
|
||||||
|
this.actor = new St.ScrollView({ x_fill: true, y_fill: true });
|
||||||
|
this.actor.get_hscroll_bar().hide();
|
||||||
|
this._container = new St.BoxLayout({ name: 'LookingGlassPropertyInspector',
|
||||||
|
style_class: 'lg-dialog',
|
||||||
|
vertical: true });
|
||||||
|
this.actor.add_actor(this._container);
|
||||||
|
},
|
||||||
|
|
||||||
|
selectObject: function(obj, skipPrevious) {
|
||||||
|
if (!skipPrevious)
|
||||||
|
this._previousObj = this._obj;
|
||||||
|
else
|
||||||
|
this._previousObj = null;
|
||||||
|
this._obj = obj;
|
||||||
|
|
||||||
|
this._container.get_children().forEach(function (child) { child.destroy(); });
|
||||||
|
|
||||||
|
let hbox = new St.BoxLayout({ style_class: 'lg-obj-inspector-title' });
|
||||||
|
this._container.add_actor(hbox);
|
||||||
|
let label = new St.Label({ text: 'Inspecting: %s: %s'.format(typeof(obj),
|
||||||
|
objectToString(obj)) });
|
||||||
|
label.single_line_mode = true;
|
||||||
|
hbox.add(label, { expand: true, y_fill: false });
|
||||||
|
let button = new St.Button({ label: 'Insert', style_class: 'lg-obj-inspector-button' });
|
||||||
|
button.connect('clicked', Lang.bind(this, this._onInsert));
|
||||||
|
hbox.add(button);
|
||||||
|
|
||||||
|
if (this._previousObj != null) {
|
||||||
|
button = new St.Button({ label: 'Back', style_class: 'lg-obj-inspector-button' });
|
||||||
|
button.connect('clicked', Lang.bind(this, this._onBack));
|
||||||
|
hbox.add(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
button = new St.Button({ style_class: 'window-close' });
|
||||||
|
button.connect('clicked', Lang.bind(this, this.close));
|
||||||
|
hbox.add(button);
|
||||||
|
if (typeof(obj) == typeof({})) {
|
||||||
|
for (let propName in obj) {
|
||||||
|
let valueStr;
|
||||||
|
let link;
|
||||||
|
try {
|
||||||
|
let prop = obj[propName];
|
||||||
|
link = new ObjLink(prop).actor;
|
||||||
|
} catch (e) {
|
||||||
|
link = new St.Label({ text: '<error>' });
|
||||||
|
}
|
||||||
|
let hbox = new St.BoxLayout();
|
||||||
|
let propText = propName + ": " + valueStr;
|
||||||
|
hbox.add(new St.Label({ text: propName + ': ' }));
|
||||||
|
hbox.add(link);
|
||||||
|
this._container.add_actor(hbox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function(sourceActor) {
|
||||||
|
if (this._open)
|
||||||
|
return;
|
||||||
|
this._previousObj = null;
|
||||||
|
this._open = true;
|
||||||
|
this.actor.show();
|
||||||
|
if (sourceActor) {
|
||||||
|
this.actor.set_scale(0, 0);
|
||||||
|
let [sourceX, sourceY] = sourceActor.get_transformed_position();
|
||||||
|
let [sourceWidth, sourceHeight] = sourceActor.get_transformed_size();
|
||||||
|
this.actor.move_anchor_point(Math.floor(sourceX + sourceWidth / 2),
|
||||||
|
Math.floor(sourceY + sourceHeight / 2));
|
||||||
|
Tweener.addTween(this.actor, { scale_x: 1, scale_y: 1,
|
||||||
|
transition: "easeOutQuad",
|
||||||
|
time: 0.2 });
|
||||||
|
} else {
|
||||||
|
this.actor.set_scale(1, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
close: function() {
|
||||||
|
if (!this._open)
|
||||||
|
return;
|
||||||
|
this._open = false;
|
||||||
|
this.actor.hide();
|
||||||
|
this._previousObj = null;
|
||||||
|
this._obj = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onInsert: function() {
|
||||||
|
let obj = this._obj;
|
||||||
|
this.close();
|
||||||
|
Main.lookingGlass.insertObject(obj);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onBack: function() {
|
||||||
|
this.selectObject(this._previousObj, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function Inspector() {
|
function Inspector() {
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
@ -259,14 +367,14 @@ Inspector.prototype = {
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
let width = 150;
|
let width = 150;
|
||||||
let primary = global.get_primary_monitor();
|
let primary = global.get_primary_monitor();
|
||||||
let eventHandler = new St.BoxLayout({ name: "LookingGlassDialog",
|
let eventHandler = new St.BoxLayout({ name: 'LookingGlassDialog',
|
||||||
vertical: false,
|
vertical: false,
|
||||||
y: primary.y + Math.floor(primary.height / 2),
|
y: primary.y + Math.floor(primary.height / 2),
|
||||||
reactive: true });
|
reactive: true });
|
||||||
eventHandler.connect('notify::allocation', Lang.bind(this, function () {
|
eventHandler.connect('notify::allocation', Lang.bind(this, function () {
|
||||||
eventHandler.x = primary.x + Math.floor((primary.width - eventHandler.width) / 2);
|
eventHandler.x = primary.x + Math.floor((primary.width - eventHandler.width) / 2);
|
||||||
}));
|
}));
|
||||||
global.stage.add_actor(eventHandler);
|
Main.uiGroup.add_actor(eventHandler);
|
||||||
let displayText = new St.Label();
|
let displayText = new St.Label();
|
||||||
eventHandler.add(displayText, { expand: true });
|
eventHandler.add(displayText, { expand: true });
|
||||||
|
|
||||||
@ -295,7 +403,9 @@ Inspector.prototype = {
|
|||||||
let target = global.stage.get_actor_at_pos(Clutter.PickMode.ALL,
|
let target = global.stage.get_actor_at_pos(Clutter.PickMode.ALL,
|
||||||
stageX,
|
stageX,
|
||||||
stageY);
|
stageY);
|
||||||
displayText.text = '<inspect x: ' + stageX + ' y: ' + stageY + '> ' + target;
|
let position = '[inspect x: ' + stageX + ' y: ' + stageY + ']';
|
||||||
|
displayText.text = '';
|
||||||
|
displayText.text = position + ' ' + target;
|
||||||
if (borderPaintTarget != null)
|
if (borderPaintTarget != null)
|
||||||
borderPaintTarget.disconnect(borderPaintId);
|
borderPaintTarget.disconnect(borderPaintId);
|
||||||
borderPaintTarget = target;
|
borderPaintTarget = target;
|
||||||
@ -304,7 +414,7 @@ Inspector.prototype = {
|
|||||||
}));
|
}));
|
||||||
Clutter.grab_pointer(eventHandler);
|
Clutter.grab_pointer(eventHandler);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Signals.addSignalMethods(Inspector.prototype);
|
Signals.addSignalMethods(Inspector.prototype);
|
||||||
|
|
||||||
@ -317,18 +427,23 @@ ErrorLog.prototype = {
|
|||||||
this.actor = new St.BoxLayout();
|
this.actor = new St.BoxLayout();
|
||||||
this.text = new St.Label();
|
this.text = new St.Label();
|
||||||
this.actor.add(this.text);
|
this.actor.add(this.text);
|
||||||
|
// We need to override StLabel's default ellipsization when
|
||||||
|
// using line_wrap; otherwise ClutterText's layout is going
|
||||||
|
// to constrain both the width and height, which prevents
|
||||||
|
// scrolling.
|
||||||
|
this.text.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
this.text.clutter_text.line_wrap = true;
|
this.text.clutter_text.line_wrap = true;
|
||||||
this.actor.connect('notify::mapped', Lang.bind(this, this._renderText));
|
this.actor.connect('notify::mapped', Lang.bind(this, this._renderText));
|
||||||
},
|
},
|
||||||
|
|
||||||
_formatTime: function(d){
|
_formatTime: function(d){
|
||||||
function pad(n) { return n < 10 ? '0' + n : n };
|
function pad(n) { return n < 10 ? '0' + n : n; }
|
||||||
return d.getUTCFullYear()+'-'
|
return d.getUTCFullYear()+'-'
|
||||||
+ pad(d.getUTCMonth()+1)+'-'
|
+ pad(d.getUTCMonth()+1)+'-'
|
||||||
+ pad(d.getUTCDate())+'T'
|
+ pad(d.getUTCDate())+'T'
|
||||||
+ pad(d.getUTCHours())+':'
|
+ pad(d.getUTCHours())+':'
|
||||||
+ pad(d.getUTCMinutes())+':'
|
+ pad(d.getUTCMinutes())+':'
|
||||||
+ pad(d.getUTCSeconds())+'Z'
|
+ pad(d.getUTCSeconds())+'Z';
|
||||||
},
|
},
|
||||||
|
|
||||||
_renderText: function() {
|
_renderText: function() {
|
||||||
@ -338,11 +453,11 @@ ErrorLog.prototype = {
|
|||||||
let stack = Main._getAndClearErrorStack();
|
let stack = Main._getAndClearErrorStack();
|
||||||
for (let i = 0; i < stack.length; i++) {
|
for (let i = 0; i < stack.length; i++) {
|
||||||
let logItem = stack[i];
|
let logItem = stack[i];
|
||||||
text += logItem.category + " t=" + this._formatTime(new Date(logItem.timestamp)) + " " + logItem.message + "\n";
|
text += logItem.category + ' t=' + this._formatTime(new Date(logItem.timestamp)) + ' ' + logItem.message + '\n';
|
||||||
}
|
}
|
||||||
this.text.text = text;
|
this.text.text = text;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function Extensions() {
|
function Extensions() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -398,7 +513,7 @@ Extensions.prototype = {
|
|||||||
case ExtensionSystem.ExtensionState.OUT_OF_DATE:
|
case ExtensionSystem.ExtensionState.OUT_OF_DATE:
|
||||||
return _("Out of date");
|
return _("Out of date");
|
||||||
}
|
}
|
||||||
return "Unknown"; // Not translated, shouldn't appear
|
return 'Unknown'; // Not translated, shouldn't appear
|
||||||
},
|
},
|
||||||
|
|
||||||
_createExtensionDisplay: function(meta) {
|
_createExtensionDisplay: function(meta) {
|
||||||
@ -444,7 +559,7 @@ function LookingGlass() {
|
|||||||
LookingGlass.prototype = {
|
LookingGlass.prototype = {
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this._idleHistorySaveId = 0;
|
this._idleHistorySaveId = 0;
|
||||||
let historyPath = global.configdir + "/lookingglass-history.txt";
|
let historyPath = global.userdatadir + '/lookingglass-history.txt';
|
||||||
this._historyFile = Gio.file_new_for_path(historyPath);
|
this._historyFile = Gio.file_new_for_path(historyPath);
|
||||||
this._savedText = null;
|
this._savedText = null;
|
||||||
this._historyNavIndex = -1;
|
this._historyNavIndex = -1;
|
||||||
@ -463,22 +578,27 @@ LookingGlass.prototype = {
|
|||||||
// Sort of magic, but...eh.
|
// Sort of magic, but...eh.
|
||||||
this._maxItems = 150;
|
this._maxItems = 150;
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ name: "LookingGlassDialog",
|
this.actor = new St.BoxLayout({ name: 'LookingGlassDialog',
|
||||||
|
style_class: 'lg-dialog',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
visible: false });
|
visible: false });
|
||||||
|
|
||||||
let gconf = Shell.GConf.get_default();
|
let gconf = GConf.Client.get_default();
|
||||||
gconf.watch_directory("/desktop/gnome/interface");
|
gconf.add_dir('/desktop/gnome/interface', GConf.ClientPreloadType.PRELOAD_NONE);
|
||||||
gconf.connect("changed::/desktop/gnome/interface/monospace_font_name",
|
gconf.notify_add('/desktop/gnome/interface/monospace_font_name',
|
||||||
Lang.bind(this, this._updateFont));
|
Lang.bind(this, this._updateFont));
|
||||||
this._updateFont();
|
this._updateFont();
|
||||||
|
|
||||||
global.stage.add_actor(this.actor);
|
Main.uiGroup.add_actor(this.actor);
|
||||||
|
|
||||||
let toolbar = new St.BoxLayout({ name: "Toolbar" });
|
this._objInspector = new ObjInspector();
|
||||||
|
Main.uiGroup.add_actor(this._objInspector.actor);
|
||||||
|
this._objInspector.actor.hide();
|
||||||
|
|
||||||
|
let toolbar = new St.BoxLayout({ name: 'Toolbar' });
|
||||||
this.actor.add_actor(toolbar);
|
this.actor.add_actor(toolbar);
|
||||||
let inspectIcon = Shell.TextureCache.get_default().load_gicon(new Gio.ThemedIcon({ name: 'gtk-color-picker' }),
|
let inspectIcon = St.TextureCache.get_default().load_gicon(new Gio.ThemedIcon({ name: 'gtk-color-picker' }),
|
||||||
24);
|
24);
|
||||||
toolbar.add_actor(inspectIcon);
|
toolbar.add_actor(inspectIcon);
|
||||||
inspectIcon.reactive = true;
|
inspectIcon.reactive = true;
|
||||||
inspectIcon.connect('button-press-event', Lang.bind(this, function () {
|
inspectIcon.connect('button-press-event', Lang.bind(this, function () {
|
||||||
@ -486,7 +606,6 @@ LookingGlass.prototype = {
|
|||||||
inspector.connect('target', Lang.bind(this, function(i, target, stageX, stageY) {
|
inspector.connect('target', Lang.bind(this, function(i, target, stageX, stageY) {
|
||||||
this._pushResult('<inspect x:' + stageX + ' y:' + stageY + '>',
|
this._pushResult('<inspect x:' + stageX + ' y:' + stageY + '>',
|
||||||
target);
|
target);
|
||||||
this._hierarchy.setTarget(target);
|
|
||||||
}));
|
}));
|
||||||
inspector.connect('closed', Lang.bind(this, function() {
|
inspector.connect('closed', Lang.bind(this, function() {
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
@ -504,18 +623,17 @@ LookingGlass.prototype = {
|
|||||||
toolbar.add(emptyBox, { expand: true });
|
toolbar.add(emptyBox, { expand: true });
|
||||||
toolbar.add_actor(notebook.tabControls);
|
toolbar.add_actor(notebook.tabControls);
|
||||||
|
|
||||||
this._evalBox = new St.BoxLayout({ name: "EvalBox", vertical: true });
|
this._evalBox = new St.BoxLayout({ name: 'EvalBox', vertical: true });
|
||||||
notebook.appendPage('Evaluator', this._evalBox);
|
notebook.appendPage('Evaluator', this._evalBox);
|
||||||
|
|
||||||
this._resultsArea = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
this._resultsArea = new St.BoxLayout({ name: 'ResultsArea', vertical: true });
|
||||||
spacing: 4 });
|
|
||||||
this._evalBox.add(this._resultsArea, { expand: true });
|
this._evalBox.add(this._resultsArea, { expand: true });
|
||||||
|
|
||||||
let entryArea = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
|
let entryArea = new St.BoxLayout({ name: 'EntryArea' });
|
||||||
this._evalBox.add_actor(entryArea);
|
this._evalBox.add_actor(entryArea);
|
||||||
|
|
||||||
let label = new St.Label({ text: 'js>>> ' });
|
let label = new St.Label({ text: 'js>>> ' });
|
||||||
entryArea.append(label, Big.BoxPackFlags.NONE);
|
entryArea.add(label);
|
||||||
|
|
||||||
this._entry = new St.Entry();
|
this._entry = new St.Entry();
|
||||||
/* unmapping the edit box will un-focus it, undo that */
|
/* unmapping the edit box will un-focus it, undo that */
|
||||||
@ -523,17 +641,14 @@ LookingGlass.prototype = {
|
|||||||
if (child == this._evalBox)
|
if (child == this._evalBox)
|
||||||
global.stage.set_key_focus(this._entry);
|
global.stage.set_key_focus(this._entry);
|
||||||
}));
|
}));
|
||||||
entryArea.append(this._entry, Big.BoxPackFlags.EXPAND);
|
entryArea.add(this._entry, { expand: true });
|
||||||
|
|
||||||
this._hierarchy = new ActorHierarchy();
|
this._windowList = new WindowList();
|
||||||
notebook.appendPage('Hierarchy', this._hierarchy.actor);
|
this._windowList.connect('selected', Lang.bind(this, function(list, window) {
|
||||||
|
|
||||||
this._propInspector = new PropertyInspector();
|
|
||||||
notebook.appendPage('Properties', this._propInspector.actor);
|
|
||||||
this._hierarchy.connect('selection', Lang.bind(this, function (h, actor) {
|
|
||||||
this._pushResult('<parent selection>', actor);
|
|
||||||
notebook.selectIndex(0);
|
notebook.selectIndex(0);
|
||||||
|
this._pushResult('<window selection>', window);
|
||||||
}));
|
}));
|
||||||
|
notebook.appendPage('Windows', this._windowList.actor);
|
||||||
|
|
||||||
this._errorLog = new ErrorLog();
|
this._errorLog = new ErrorLog();
|
||||||
notebook.appendPage('Errors', this._errorLog.actor);
|
notebook.appendPage('Errors', this._errorLog.actor);
|
||||||
@ -547,7 +662,7 @@ LookingGlass.prototype = {
|
|||||||
// newline-separated.
|
// newline-separated.
|
||||||
text.replace('\n', ' ');
|
text.replace('\n', ' ');
|
||||||
// Strip leading and trailing whitespace
|
// Strip leading and trailing whitespace
|
||||||
text = text.replace(/^\s+/g, "").replace(/\s+$/g, "");
|
text = text.replace(/^\s+/g, '').replace(/\s+$/g, '');
|
||||||
if (text == '')
|
if (text == '')
|
||||||
return true;
|
return true;
|
||||||
this._evaluate(text);
|
this._evaluate(text);
|
||||||
@ -582,8 +697,8 @@ LookingGlass.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateFont: function() {
|
_updateFont: function() {
|
||||||
let gconf = Shell.GConf.get_default();
|
let gconf = GConf.Client.get_default();
|
||||||
let fontName = gconf.get_string("/desktop/gnome/interface/monospace_font_name");
|
let fontName = gconf.get_string('/desktop/gnome/interface/monospace_font_name');
|
||||||
// This is mishandled by the scanner - should by Pango.FontDescription_from_string(fontName);
|
// This is mishandled by the scanner - should by Pango.FontDescription_from_string(fontName);
|
||||||
// https://bugzilla.gnome.org/show_bug.cgi?id=595889
|
// https://bugzilla.gnome.org/show_bug.cgi?id=595889
|
||||||
let fontDesc = Pango.Font.description_from_string(fontName);
|
let fontDesc = Pango.Font.description_from_string(fontName);
|
||||||
@ -621,8 +736,7 @@ LookingGlass.prototype = {
|
|||||||
let index = this._results.length + this._offset;
|
let index = this._results.length + this._offset;
|
||||||
let result = new Result('>>> ' + command, obj, index);
|
let result = new Result('>>> ' + command, obj, index);
|
||||||
this._results.push(result);
|
this._results.push(result);
|
||||||
this._resultsArea.append(result.actor, Big.BoxPackFlags.NONE);
|
this._resultsArea.add(result.actor);
|
||||||
this._propInspector.setTarget(obj);
|
|
||||||
if (this._borderPaintTarget != null) {
|
if (this._borderPaintTarget != null) {
|
||||||
this._borderPaintTarget.disconnect(this._borderPaintId);
|
this._borderPaintTarget.disconnect(this._borderPaintId);
|
||||||
this._borderPaintTarget = null;
|
this._borderPaintTarget = null;
|
||||||
@ -657,11 +771,10 @@ LookingGlass.prototype = {
|
|||||||
try {
|
try {
|
||||||
resultObj = eval(fullCmd);
|
resultObj = eval(fullCmd);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
resultObj = "<exception " + e + ">";
|
resultObj = '<exception ' + e + '>';
|
||||||
}
|
}
|
||||||
|
|
||||||
this._pushResult(command, resultObj);
|
this._pushResult(command, resultObj);
|
||||||
this._hierarchy.setTarget(null);
|
|
||||||
this._entry.text = '';
|
this._entry.text = '';
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -691,6 +804,9 @@ LookingGlass.prototype = {
|
|||||||
this.actor.y = this._hiddenY;
|
this.actor.y = this._hiddenY;
|
||||||
this.actor.width = myWidth;
|
this.actor.width = myWidth;
|
||||||
this.actor.height = myHeight;
|
this.actor.height = myHeight;
|
||||||
|
this._objInspector.actor.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8));
|
||||||
|
this._objInspector.actor.set_position(this.actor.x + Math.floor(myWidth * 0.1),
|
||||||
|
this._targetY + Math.floor(myHeight * 0.1));
|
||||||
},
|
},
|
||||||
|
|
||||||
slaveTo: function(actor) {
|
slaveTo: function(actor) {
|
||||||
@ -701,11 +817,24 @@ LookingGlass.prototype = {
|
|||||||
this._resizeTo(actor);
|
this._resizeTo(actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
insertObject: function(obj) {
|
||||||
|
this._pushResult('<insert>', obj);
|
||||||
|
},
|
||||||
|
|
||||||
|
inspectObject: function(obj, sourceActor) {
|
||||||
|
this._objInspector.open(sourceActor);
|
||||||
|
this._objInspector.selectObject(obj);
|
||||||
|
},
|
||||||
|
|
||||||
// Handle key events which are relevant for all tabs of the LookingGlass
|
// Handle key events which are relevant for all tabs of the LookingGlass
|
||||||
_globalKeyPressEvent : function(actor, event) {
|
_globalKeyPressEvent : function(actor, event) {
|
||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
if (symbol == Clutter.Escape) {
|
if (symbol == Clutter.Escape) {
|
||||||
this.close();
|
if (this._objInspector.actor.visible) {
|
||||||
|
this._objInspector.close();
|
||||||
|
} else {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -730,7 +859,7 @@ LookingGlass.prototype = {
|
|||||||
global.stage.set_key_focus(this._entry);
|
global.stage.set_key_focus(this._entry);
|
||||||
|
|
||||||
Tweener.addTween(this.actor, { time: 0.5,
|
Tweener.addTween(this.actor, { time: 0.5,
|
||||||
transition: "easeOutQuad",
|
transition: 'easeOutQuad',
|
||||||
y: this._targetY
|
y: this._targetY
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -742,6 +871,8 @@ LookingGlass.prototype = {
|
|||||||
if (this._keyPressEventId)
|
if (this._keyPressEventId)
|
||||||
global.stage.disconnect(this._keyPressEventId);
|
global.stage.disconnect(this._keyPressEventId);
|
||||||
|
|
||||||
|
this._objInspector.actor.hide();
|
||||||
|
|
||||||
this._historyNavIndex = -1;
|
this._historyNavIndex = -1;
|
||||||
this._open = false;
|
this._open = false;
|
||||||
Tweener.removeTweens(this.actor);
|
Tweener.removeTweens(this.actor);
|
||||||
@ -755,7 +886,7 @@ LookingGlass.prototype = {
|
|||||||
Main.popModal(this.actor);
|
Main.popModal(this.actor);
|
||||||
|
|
||||||
Tweener.addTween(this.actor, { time: 0.5,
|
Tweener.addTween(this.actor, { time: 0.5,
|
||||||
transition: "easeOutQuad",
|
transition: 'easeOutQuad',
|
||||||
y: this._hiddenY,
|
y: this._hiddenY,
|
||||||
onComplete: Lang.bind(this, function () {
|
onComplete: Lang.bind(this, function () {
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
|
1480
js/ui/magnifier.js
Normal file
375
js/ui/magnifierDBus.js
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const DBus = imports.dbus;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
|
const MAG_SERVICE_NAME = 'org.gnome.Magnifier';
|
||||||
|
const MAG_SERVICE_PATH = '/org/gnome/Magnifier';
|
||||||
|
const ZOOM_SERVICE_NAME = 'org.gnome.Magnifier.ZoomRegion';
|
||||||
|
const ZOOM_SERVICE_PATH = '/org/gnome/Magnifier/ZoomRegion';
|
||||||
|
|
||||||
|
// Subset of gnome-mag's Magnifier dbus interface -- to be expanded. See:
|
||||||
|
// http://git.gnome.org/browse/gnome-mag/tree/xml/...Magnifier.xml
|
||||||
|
const MagnifierIface = {
|
||||||
|
name: MAG_SERVICE_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'setActive', inSignature: 'b', outSignature: '' },
|
||||||
|
{ name: 'isActive', inSignature: '', outSignature: 'b' },
|
||||||
|
{ name: 'showCursor', inSignature: '', outSignature: '' },
|
||||||
|
{ name: 'hideCursor', inSignature: '', outSignature: '' },
|
||||||
|
{ name: 'createZoomRegion', inSignature: 'ddaiai', outSignature: 'o' },
|
||||||
|
{ name: 'addZoomRegion', inSignature: 'o', outSignature: 'b' },
|
||||||
|
{ name: 'getZoomRegions', inSignature: '', outSignature: 'ao' },
|
||||||
|
{ name: 'clearAllZoomRegions', inSignature: '', outSignature: '' },
|
||||||
|
{ name: 'fullScreenCapable', inSignature: '', outSignature: 'b' },
|
||||||
|
|
||||||
|
{ name: 'setCrosswireSize', inSignature: 'i', outSignature: '' },
|
||||||
|
{ name: 'getCrosswireSize', inSignature: '', outSignature: 'i' },
|
||||||
|
{ name: 'setCrosswireLength', inSignature: 'i', outSignature: '' },
|
||||||
|
{ name: 'getCrosswireLength', inSignature: '', outSignature: 'i' },
|
||||||
|
{ name: 'setCrosswireClip', inSignature: 'b', outSignature: '' },
|
||||||
|
{ name: 'getCrosswireClip', inSignature: '', outSignature: 'b' },
|
||||||
|
{ name: 'setCrosswireColor', inSignature: 'u', outSignature: '' },
|
||||||
|
{ name: 'getCrosswireColor', inSignature: '', outSignature: 'u' }
|
||||||
|
],
|
||||||
|
signals: [],
|
||||||
|
properties: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// Subset of gnome-mag's ZoomRegion dbus interface -- to be expanded. See:
|
||||||
|
// http://git.gnome.org/browse/gnome-mag/tree/xml/...ZoomRegion.xml
|
||||||
|
const ZoomRegionIface = {
|
||||||
|
name: ZOOM_SERVICE_NAME,
|
||||||
|
methods: [
|
||||||
|
{ name: 'setMagFactor', inSignature: 'dd', outSignature: ''},
|
||||||
|
{ name: 'getMagFactor', inSignature: '', outSignature: 'dd' },
|
||||||
|
{ name: 'setRoi', inSignature: 'ai', outSignature: '' },
|
||||||
|
{ name: 'getRoi', inSignature: '', outSignature: 'ai' },
|
||||||
|
{ name: 'shiftContentsTo', inSignature: 'ii', outSignature: 'b' },
|
||||||
|
{ name: 'moveResize', inSignature: 'ai', outSignature: '' }
|
||||||
|
],
|
||||||
|
signals: [],
|
||||||
|
properties: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// For making unique ZoomRegion DBus proxy object paths of the form:
|
||||||
|
// '/org/gnome/Magnifier/ZoomRegion/zoomer0',
|
||||||
|
// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc.
|
||||||
|
let _zoomRegionInstanceCount = 0;
|
||||||
|
|
||||||
|
function ShellMagnifier() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShellMagnifier.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
this._zoomers = {};
|
||||||
|
DBus.session.exportObject(MAG_SERVICE_PATH, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setActive:
|
||||||
|
* @activate: Boolean to activate or de-activate the magnifier.
|
||||||
|
*/
|
||||||
|
setActive: function(activate) {
|
||||||
|
Main.magnifier.setActive(activate);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isActive:
|
||||||
|
* @return Whether the magnifier is active (boolean).
|
||||||
|
*/
|
||||||
|
isActive: function() {
|
||||||
|
return Main.magnifier.isActive();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* showCursor:
|
||||||
|
* Show the system mouse pointer.
|
||||||
|
*/
|
||||||
|
showCursor: function() {
|
||||||
|
Main.magnifier.showSystemCursor();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hideCursor:
|
||||||
|
* Hide the system mouse pointer.
|
||||||
|
*/
|
||||||
|
hideCursor: function() {
|
||||||
|
Main.magnifier.hideSystemCursor();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* createZoomRegion:
|
||||||
|
* Create a new ZoomRegion and return its object path.
|
||||||
|
* @xMagFactor: The power to set horizontal magnification of the
|
||||||
|
* ZoomRegion. A value of 1.0 means no magnification. A
|
||||||
|
* value of 2.0 doubles the size.
|
||||||
|
* @yMagFactor: The power to set the vertical magnification of the
|
||||||
|
* ZoomRegion.
|
||||||
|
* @roi Array of integers defining the region of the
|
||||||
|
* screen/desktop to magnify. The array has the form
|
||||||
|
* [x, y, width, height].
|
||||||
|
* @viewPort Array of integers, [ x, y, width, height ] that defines
|
||||||
|
* the position of the ZoomRegion on screen.
|
||||||
|
* @return The newly created ZoomRegion.
|
||||||
|
*/
|
||||||
|
createZoomRegion: function(xMagFactor, yMagFactor, roi, viewPort) {
|
||||||
|
let ROI = { x: roi[0], y: roi[1], width: roi[2], height: roi[3] };
|
||||||
|
let viewBox = { x: viewPort[0], y: viewPort[1], width: viewPort[2], height: viewPort[3] };
|
||||||
|
let realZoomRegion = Main.magnifier.createZoomRegion(xMagFactor, yMagFactor, ROI, viewBox);
|
||||||
|
let objectPath = ZOOM_SERVICE_PATH + '/zoomer' + _zoomRegionInstanceCount;
|
||||||
|
_zoomRegionInstanceCount++;
|
||||||
|
|
||||||
|
let zoomRegionProxy = new ShellMagnifierZoomRegion(objectPath, realZoomRegion);
|
||||||
|
let proxyAndZoomRegion = {};
|
||||||
|
proxyAndZoomRegion.proxy = zoomRegionProxy;
|
||||||
|
proxyAndZoomRegion.zoomRegion = realZoomRegion;
|
||||||
|
this._zoomers[objectPath] = proxyAndZoomRegion;
|
||||||
|
return objectPath;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addZoomRegion:
|
||||||
|
* Append the given ZoomRegion to the magnifier's list of ZoomRegions.
|
||||||
|
* @zoomerObjectPath: The object path for the zoom region proxy.
|
||||||
|
*/
|
||||||
|
addZoomRegion: function(zoomerObjectPath) {
|
||||||
|
let proxyAndZoomRegion = this._zoomers[zoomerObjectPath];
|
||||||
|
if (proxyAndZoomRegion && proxyAndZoomRegion.zoomRegion) {
|
||||||
|
Main.magnifier.addZoomRegion(proxyAndZoomRegion.zoomRegion);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getZoomRegions:
|
||||||
|
* Return a list of ZoomRegion object paths for this Magnifier.
|
||||||
|
* @return: The Magnifier's zoom region list as an array of DBus object
|
||||||
|
* paths.
|
||||||
|
*/
|
||||||
|
getZoomRegions: function() {
|
||||||
|
// There may be more ZoomRegions in the magnifier itself than have
|
||||||
|
// been added through dbus. Make sure all of them are associated with
|
||||||
|
// an object path and proxy.
|
||||||
|
let zoomRegions = Main.magnifier.getZoomRegions();
|
||||||
|
let objectPaths = [];
|
||||||
|
let thoseZoomers = this._zoomers;
|
||||||
|
zoomRegions.forEach (function(aZoomRegion, index, array) {
|
||||||
|
let found = false;
|
||||||
|
for (let objectPath in thoseZoomers) {
|
||||||
|
let proxyAndZoomRegion = thoseZoomers[objectPath];
|
||||||
|
if (proxyAndZoomRegion.zoomRegion === aZoomRegion) {
|
||||||
|
objectPaths.push(objectPath);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
// Got a ZoomRegion with no DBus proxy, make one.
|
||||||
|
let newPath = ZOOM_SERVICE_PATH + '/zoomer' + _zoomRegionInstanceCount;
|
||||||
|
_zoomRegionInstanceCount++;
|
||||||
|
let zoomRegionProxy = new ShellMagnifierZoomRegion(newPath, aZoomRegion);
|
||||||
|
let proxyAndZoomer = {};
|
||||||
|
proxyAndZoomer.proxy = zoomRegionProxy;
|
||||||
|
proxyAndZoomer.zoomRegion = aZoomRegion;
|
||||||
|
thoseZoomers[newPath] = proxyAndZoomer;
|
||||||
|
objectPaths.push(newPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return objectPaths;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clearAllZoomRegions:
|
||||||
|
* Remove all the zoom regions from this Magnfier's ZoomRegion list.
|
||||||
|
*/
|
||||||
|
clearAllZoomRegions: function() {
|
||||||
|
Main.magnifier.clearAllZoomRegions();
|
||||||
|
for (let objectPath in this._zoomers) {
|
||||||
|
let proxyAndZoomer = this._zoomers[objectPath];
|
||||||
|
proxyAndZoomer.proxy = null;
|
||||||
|
proxyAndZoomer.zoomRegion = null;
|
||||||
|
delete this._zoomers[objectPath];
|
||||||
|
DBus.session.unexportObject(proxyAndZoomer);
|
||||||
|
}
|
||||||
|
this._zoomers = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fullScreenCapable:
|
||||||
|
* Consult if the Magnifier can magnify in full-screen mode.
|
||||||
|
* @return Always return true.
|
||||||
|
*/
|
||||||
|
fullScreenCapable: function() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setCrosswireSize:
|
||||||
|
* Set the crosswire size of all ZoomRegions.
|
||||||
|
* @size: The thickness of each line in the cross wire.
|
||||||
|
*/
|
||||||
|
setCrosswireSize: function(size) {
|
||||||
|
Main.magnifier.setCrosshairsThickness(size);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getCrosswireSize:
|
||||||
|
* Get the crosswire size of all ZoomRegions.
|
||||||
|
* @return: The thickness of each line in the cross wire.
|
||||||
|
*/
|
||||||
|
getCrosswireSize: function() {
|
||||||
|
return Main.magnifier.getCrosshairsThickness();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setCrosswireLength:
|
||||||
|
* Set the crosswire length of all zoom-regions..
|
||||||
|
* @size: The length of each line in the cross wire.
|
||||||
|
*/
|
||||||
|
setCrosswireLength: function(length) {
|
||||||
|
Main.magnifier.setCrosshairsLength(length);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setCrosswireSize:
|
||||||
|
* Set the crosswire size of all zoom-regions.
|
||||||
|
* @size: The thickness of each line in the cross wire.
|
||||||
|
*/
|
||||||
|
getCrosswireLength: function() {
|
||||||
|
return Main.magnifier.getCrosshairsLength();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setCrosswireClip:
|
||||||
|
* Set if the crosswire will be clipped by the cursor image..
|
||||||
|
* @clip: Flag to indicate whether to clip the crosswire.
|
||||||
|
*/
|
||||||
|
setCrosswireClip: function(clip) {
|
||||||
|
Main.magnifier.setCrosshairsClip(clip);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getCrosswireClip:
|
||||||
|
* Get the crosswire clip value.
|
||||||
|
* @return: Whether the crosswire is clipped by the cursor image.
|
||||||
|
*/
|
||||||
|
getCrosswireClip: function() {
|
||||||
|
return Main.magnifier.getCrosshairsClip();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setCrosswireColor:
|
||||||
|
* Set the crosswire color of all ZoomRegions.
|
||||||
|
* @color: Unsigned int of the form rrggbbaa.
|
||||||
|
*/
|
||||||
|
setCrosswireColor: function(color) {
|
||||||
|
Main.magnifier.setCrosshairsColor('#%08x'.format(color));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getCrosswireClip:
|
||||||
|
* Get the crosswire color of all ZoomRegions.
|
||||||
|
* @return: The crosswire color as an unsigned int in the form rrggbbaa.
|
||||||
|
*/
|
||||||
|
getCrosswireColor: function() {
|
||||||
|
let colorString = Main.magnifier.getCrosshairsColor();
|
||||||
|
// Drop the leading '#'.
|
||||||
|
return parseInt(colorString.slice(1), 16);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ShellMagnifierZoomRegion:
|
||||||
|
* Object that implements the DBus ZoomRegion interface.
|
||||||
|
* @zoomerObjectPath: String that is the path to a DBus ZoomRegion.
|
||||||
|
* @zoomRegion: The actual zoom region associated with the object path.
|
||||||
|
*/
|
||||||
|
function ShellMagnifierZoomRegion(zoomerObjectPath, zoomRegion) {
|
||||||
|
this._init(zoomerObjectPath, zoomRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShellMagnifierZoomRegion.prototype = {
|
||||||
|
_init: function(zoomerObjectPath, zoomRegion) {
|
||||||
|
this._zoomRegion = zoomRegion;
|
||||||
|
DBus.session.proxifyObject(this, ZOOM_SERVICE_NAME, zoomerObjectPath);
|
||||||
|
DBus.session.exportObject(zoomerObjectPath, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setMagFactor:
|
||||||
|
* @xMagFactor: The power to set the horizontal magnification factor to
|
||||||
|
* of the magnified view. A value of 1.0 means no
|
||||||
|
* magnification. A value of 2.0 doubles the size.
|
||||||
|
* @yMagFactor: The power to set the vertical magnification factor to
|
||||||
|
* of the magnified view.
|
||||||
|
*/
|
||||||
|
setMagFactor: function(xMagFactor, yMagFactor) {
|
||||||
|
this._zoomRegion.setMagFactor(xMagFactor, yMagFactor);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getMagFactor:
|
||||||
|
* @return an array, [xMagFactor, yMagFactor], containing the horizontal
|
||||||
|
* and vertical magnification powers. A value of 1.0 means no
|
||||||
|
* magnification. A value of 2.0 means the contents are doubled
|
||||||
|
* in size, and so on.
|
||||||
|
*/
|
||||||
|
getMagFactor: function() {
|
||||||
|
return this._zoomRegion.getMagFactor();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setRoi:
|
||||||
|
* Sets the "region of interest" that the ZoomRegion is magnifying.
|
||||||
|
* @roi Array, [x, y, width, height], defining the region of the screen to
|
||||||
|
* magnify. The values are in screen (unmagnified) coordinate
|
||||||
|
* space.
|
||||||
|
*/
|
||||||
|
setRoi: function(roi) {
|
||||||
|
let roiObject = { x: roi[0], y: roi[1], width: roi[2], height: roi[3] };
|
||||||
|
this._zoomRegion.setROI(roiObject);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getRoi:
|
||||||
|
* Retrieves the "region of interest" -- the rectangular bounds of that part
|
||||||
|
* of the desktop that the magnified view is showing (x, y, width, height).
|
||||||
|
* The bounds are given in non-magnified coordinates.
|
||||||
|
* @return an array, [x, y, width, height], representing the bounding
|
||||||
|
* rectangle of what is shown in the magnified view.
|
||||||
|
*/
|
||||||
|
getRoi: function() {
|
||||||
|
return this._zoomRegion.getROI();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the "region of interest" by centering the given screen coordinate
|
||||||
|
* within the zoom region.
|
||||||
|
* @x The x-coord of the point to place at the center of the zoom region.
|
||||||
|
* @y The y-coord.
|
||||||
|
* @return Whether the shift was successful (for GS-mag, this is always
|
||||||
|
* true).
|
||||||
|
*/
|
||||||
|
shiftContentsTo: function(x, y) {
|
||||||
|
this._zoomRegion.scrollContentsTo(x, y);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* moveResize
|
||||||
|
* Sets the position and size of the ZoomRegion on screen.
|
||||||
|
* @viewPort Array, [x, y, width, height], defining the position and size
|
||||||
|
* on screen to place the zoom region.
|
||||||
|
*/
|
||||||
|
moveResize: function(viewPort) {
|
||||||
|
let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2], height: viewPort[3] };
|
||||||
|
this._zoomRegion.setViewPort(viewRect);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DBus.conformExport(ShellMagnifier.prototype, MagnifierIface);
|
||||||
|
DBus.conformExport(ShellMagnifierZoomRegion.prototype, ZoomRegionIface);
|
152
js/ui/main.js
@ -1,10 +1,17 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
imports.gi.versions.Clutter = '1.0';
|
||||||
|
imports.gi.versions.Gio = '2.0';
|
||||||
|
imports.gi.versions.Gdk = '3.0';
|
||||||
|
imports.gi.versions.GdkPixbuf = '2.0';
|
||||||
|
imports.gi.versions.Gtk = '3.0';
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const DBus = imports.dbus;
|
const DBus = imports.dbus;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
const GConf = imports.gi.GConf;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
@ -22,35 +29,42 @@ const PlaceDisplay = imports.ui.placeDisplay;
|
|||||||
const RunDialog = imports.ui.runDialog;
|
const RunDialog = imports.ui.runDialog;
|
||||||
const LookingGlass = imports.ui.lookingGlass;
|
const LookingGlass = imports.ui.lookingGlass;
|
||||||
const NotificationDaemon = imports.ui.notificationDaemon;
|
const NotificationDaemon = imports.ui.notificationDaemon;
|
||||||
|
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
||||||
|
const Scripting = imports.ui.scripting;
|
||||||
const ShellDBus = imports.ui.shellDBus;
|
const ShellDBus = imports.ui.shellDBus;
|
||||||
const Sidebar = imports.ui.sidebar;
|
const TelepathyClient = imports.ui.telepathyClient;
|
||||||
const WindowManager = imports.ui.windowManager;
|
const WindowManager = imports.ui.windowManager;
|
||||||
|
const Magnifier = imports.ui.magnifier;
|
||||||
|
|
||||||
const DEFAULT_BACKGROUND_COLOR = new Clutter.Color();
|
const DEFAULT_BACKGROUND_COLOR = new Clutter.Color();
|
||||||
DEFAULT_BACKGROUND_COLOR.from_pixel(0x2266bbff);
|
DEFAULT_BACKGROUND_COLOR.from_pixel(0x2266bbff);
|
||||||
|
|
||||||
let chrome = null;
|
let chrome = null;
|
||||||
let panel = null;
|
let panel = null;
|
||||||
let sidebar = null;
|
|
||||||
let placesManager = null;
|
let placesManager = null;
|
||||||
let overview = null;
|
let overview = null;
|
||||||
let runDialog = null;
|
let runDialog = null;
|
||||||
let lookingGlass = null;
|
let lookingGlass = null;
|
||||||
let wm = null;
|
let wm = null;
|
||||||
let notificationDaemon = null;
|
|
||||||
let notificationPopup = null;
|
|
||||||
let messageTray = null;
|
let messageTray = null;
|
||||||
|
let notificationDaemon = null;
|
||||||
|
let windowAttentionHandler = null;
|
||||||
|
let telepathyClient = null;
|
||||||
let recorder = null;
|
let recorder = null;
|
||||||
let shellDBusService = null;
|
let shellDBusService = null;
|
||||||
let modalCount = 0;
|
let modalCount = 0;
|
||||||
let modalActorFocusStack = [];
|
let modalActorFocusStack = [];
|
||||||
|
let uiGroup = null;
|
||||||
|
let magnifier = null;
|
||||||
let _errorLogStack = [];
|
let _errorLogStack = [];
|
||||||
let _startDate;
|
let _startDate;
|
||||||
|
|
||||||
|
let background = null;
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
// Add a binding for "global" in the global JS namespace; (gjs
|
// Add a binding for 'global' in the global JS namespace; (gjs
|
||||||
// keeps the web browser convention of having that namespace be
|
// keeps the web browser convention of having that namespace be
|
||||||
// called "window".)
|
// called 'window'.)
|
||||||
window.global = Shell.Global.get();
|
window.global = Shell.Global.get();
|
||||||
|
|
||||||
// Now monkey patch utility functions into the global proxy;
|
// Now monkey patch utility functions into the global proxy;
|
||||||
@ -59,7 +73,7 @@ function start() {
|
|||||||
global.logError = _logError;
|
global.logError = _logError;
|
||||||
global.log = _logDebug;
|
global.log = _logDebug;
|
||||||
|
|
||||||
Gio.DesktopAppInfo.set_desktop_env("GNOME");
|
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
||||||
|
|
||||||
global.grab_dbus_service();
|
global.grab_dbus_service();
|
||||||
shellDBusService = new ShellDBus.GnomeShell();
|
shellDBusService = new ShellDBus.GnomeShell();
|
||||||
@ -87,43 +101,41 @@ function start() {
|
|||||||
// when we are running inside Xephyr.
|
// when we are running inside Xephyr.
|
||||||
global.stage.color = DEFAULT_BACKGROUND_COLOR;
|
global.stage.color = DEFAULT_BACKGROUND_COLOR;
|
||||||
|
|
||||||
// Mutter currently hardcodes putting "Yessir. The compositor is running""
|
|
||||||
// in the Overview. Clear that out.
|
|
||||||
let children = global.overlay_group.get_children();
|
|
||||||
for (let i = 0; i < children.length; i++)
|
|
||||||
children[i].destroy();
|
|
||||||
|
|
||||||
let themeContext = St.ThemeContext.get_for_stage (global.stage);
|
let themeContext = St.ThemeContext.get_for_stage (global.stage);
|
||||||
let stylesheetPath = global.datadir + "/theme/gnome-shell.css";
|
let stylesheetPath = global.datadir + '/theme/gnome-shell.css';
|
||||||
let theme = new St.Theme ({ application_stylesheet: stylesheetPath });
|
let theme = new St.Theme ({ application_stylesheet: stylesheetPath });
|
||||||
themeContext.set_theme (theme);
|
themeContext.set_theme (theme);
|
||||||
|
|
||||||
global.connect('panel-run-dialog', function(panel) {
|
|
||||||
// Make sure not more than one run dialog is shown.
|
|
||||||
getRunDialog().open();
|
|
||||||
});
|
|
||||||
let shellwm = global.window_manager;
|
let shellwm = global.window_manager;
|
||||||
shellwm.takeover_keybinding("panel_main_menu");
|
shellwm.takeover_keybinding('panel_main_menu');
|
||||||
shellwm.connect("keybinding::panel_main_menu", function () {
|
shellwm.connect('keybinding::panel_main_menu', function () {
|
||||||
overview.toggle();
|
overview.toggle();
|
||||||
});
|
});
|
||||||
shellwm.takeover_keybinding("panel_run_dialog");
|
shellwm.takeover_keybinding('panel_run_dialog');
|
||||||
shellwm.connect("keybinding::panel_run_dialog", function () {
|
shellwm.connect('keybinding::panel_run_dialog', function () {
|
||||||
getRunDialog().open();
|
getRunDialog().open();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set up stage hierarchy to group all UI actors under one container.
|
||||||
|
uiGroup = new Clutter.Group();
|
||||||
|
global.window_group.reparent(uiGroup);
|
||||||
|
global.overlay_group.reparent(uiGroup);
|
||||||
|
global.stage.add_actor(uiGroup);
|
||||||
|
|
||||||
placesManager = new PlaceDisplay.PlacesManager();
|
placesManager = new PlaceDisplay.PlacesManager();
|
||||||
overview = new Overview.Overview();
|
overview = new Overview.Overview();
|
||||||
chrome = new Chrome.Chrome();
|
chrome = new Chrome.Chrome();
|
||||||
panel = new Panel.Panel();
|
panel = new Panel.Panel();
|
||||||
sidebar = new Sidebar.Sidebar();
|
|
||||||
wm = new WindowManager.WindowManager();
|
wm = new WindowManager.WindowManager();
|
||||||
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
|
||||||
notificationPopup = new MessageTray.Notification();
|
|
||||||
messageTray = new MessageTray.MessageTray();
|
messageTray = new MessageTray.MessageTray();
|
||||||
|
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
||||||
|
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||||
|
telepathyClient = new TelepathyClient.Client();
|
||||||
|
|
||||||
_startDate = new Date();
|
_startDate = new Date();
|
||||||
|
|
||||||
|
let recorderSettings = new Gio.Settings({ schema: 'org.gnome.shell.recorder' });
|
||||||
|
|
||||||
global.screen.connect('toggle-recording', function() {
|
global.screen.connect('toggle-recording', function() {
|
||||||
if (recorder == null) {
|
if (recorder == null) {
|
||||||
recorder = new Shell.Recorder({ stage: global.stage });
|
recorder = new Shell.Recorder({ stage: global.stage });
|
||||||
@ -132,11 +144,25 @@ function start() {
|
|||||||
if (recorder.is_recording()) {
|
if (recorder.is_recording()) {
|
||||||
recorder.pause();
|
recorder.pause();
|
||||||
} else {
|
} else {
|
||||||
|
// read the parameters from GSettings always in case they have changed
|
||||||
|
recorder.set_framerate(recorderSettings.get_int('framerate'));
|
||||||
|
recorder.set_filename('shell-%d%u-%c.' + recorderSettings.get_string('file-extension'));
|
||||||
|
let pipeline = recorderSettings.get_string('pipeline');
|
||||||
|
|
||||||
|
if (!pipeline.match(/^\s*$/))
|
||||||
|
recorder.set_pipeline(pipeline);
|
||||||
|
else
|
||||||
|
recorder.set_pipeline(null);
|
||||||
|
|
||||||
recorder.record();
|
recorder.record();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_relayout();
|
background = global.create_root_pixmap_actor();
|
||||||
|
global.stage.add_actor(background);
|
||||||
|
background.lower_bottom();
|
||||||
|
|
||||||
|
global.gdk_screen.connect('monitors-changed', _relayout);
|
||||||
|
|
||||||
ExtensionSystem.init();
|
ExtensionSystem.init();
|
||||||
ExtensionSystem.loadExtensions();
|
ExtensionSystem.loadExtensions();
|
||||||
@ -145,13 +171,26 @@ function start() {
|
|||||||
|
|
||||||
let display = global.screen.get_display();
|
let display = global.screen.get_display();
|
||||||
display.connect('overlay-key', Lang.bind(overview, overview.toggle));
|
display.connect('overlay-key', Lang.bind(overview, overview.toggle));
|
||||||
global.connect('panel-main-menu', Lang.bind(overview, overview.toggle));
|
|
||||||
|
|
||||||
global.stage.connect('captured-event', _globalKeyPressHandler);
|
global.stage.connect('captured-event', _globalKeyPressHandler);
|
||||||
|
|
||||||
|
// Install magnifier.
|
||||||
|
magnifier = new Magnifier.Magnifier();
|
||||||
|
|
||||||
|
// Perform initial relayout here
|
||||||
|
_relayout();
|
||||||
|
|
||||||
_log('info', 'loaded at ' + _startDate);
|
_log('info', 'loaded at ' + _startDate);
|
||||||
|
log('GNOME Shell started at ' + _startDate);
|
||||||
|
|
||||||
Mainloop.idle_add(_removeUnusedWorkspaces);
|
Mainloop.idle_add(_removeUnusedWorkspaces);
|
||||||
|
|
||||||
|
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
|
||||||
|
if (perfModuleName) {
|
||||||
|
let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT");
|
||||||
|
let module = eval('imports.perf.' + perfModuleName + ';');
|
||||||
|
Scripting.runPerfScript(module, perfOutput);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,7 +211,7 @@ function _log(category, msg) {
|
|||||||
for (let i = 2; i < arguments.length; i++) {
|
for (let i = 2; i < arguments.length; i++) {
|
||||||
text += JSON.stringify(arguments[i]);
|
text += JSON.stringify(arguments[i]);
|
||||||
if (i < arguments.length - 1)
|
if (i < arguments.length - 1)
|
||||||
text += " ";
|
text += ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_errorLogStack.push({timestamp: new Date().getTime(),
|
_errorLogStack.push({timestamp: new Date().getTime(),
|
||||||
@ -200,6 +239,15 @@ function _relayout() {
|
|||||||
panel.actor.set_position(primary.x, primary.y);
|
panel.actor.set_position(primary.x, primary.y);
|
||||||
panel.actor.set_size(primary.width, Panel.PANEL_HEIGHT);
|
panel.actor.set_size(primary.width, Panel.PANEL_HEIGHT);
|
||||||
overview.relayout();
|
overview.relayout();
|
||||||
|
|
||||||
|
background.set_size(global.screen_width, global.screen_height);
|
||||||
|
|
||||||
|
// To avoid updating the position and size of the workspaces
|
||||||
|
// in the overview, we just hide the overview. The positions
|
||||||
|
// will be updated when it is next shown. We do the same for
|
||||||
|
// the calendar popdown.
|
||||||
|
overview.hide();
|
||||||
|
panel.hideCalendar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// metacity-clutter currently uses the same prefs as plain metacity,
|
// metacity-clutter currently uses the same prefs as plain metacity,
|
||||||
@ -251,9 +299,9 @@ function _globalKeyPressHandler(actor, event) {
|
|||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
if (symbol == Clutter.Print) {
|
if (symbol == Clutter.Print) {
|
||||||
// We want to be able to take screenshots of the shell at all times
|
// We want to be able to take screenshots of the shell at all times
|
||||||
let gconf = Shell.GConf.get_default();
|
let gconf = GConf.Client.get_default();
|
||||||
let command = gconf.get_string("/apps/metacity/keybinding_commands/command_screenshot");
|
let command = gconf.get_string('/apps/metacity/keybinding_commands/command_screenshot');
|
||||||
if (command != null && command != "") {
|
if (command != null && command != '') {
|
||||||
let [ok, len, args] = GLib.shell_parse_argv(command);
|
let [ok, len, args] = GLib.shell_parse_argv(command);
|
||||||
let p = new Shell.Process({'args' : args});
|
let p = new Shell.Process({'args' : args});
|
||||||
p.run();
|
p.run();
|
||||||
@ -263,6 +311,9 @@ function _globalKeyPressHandler(actor, event) {
|
|||||||
}
|
}
|
||||||
} else if (type == Clutter.EventType.KEY_RELEASE) {
|
} else if (type == Clutter.EventType.KEY_RELEASE) {
|
||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
|
let keyCode = event.get_key_code();
|
||||||
|
let modifierState = Shell.get_event_state(event);
|
||||||
|
// Check the overview key first, this isn't a Meta.KeyBindingAction yet
|
||||||
if (symbol == Clutter.Super_L || symbol == Clutter.Super_R) {
|
if (symbol == Clutter.Super_L || symbol == Clutter.Super_R) {
|
||||||
// The super key is the default for triggering the overview, and should
|
// The super key is the default for triggering the overview, and should
|
||||||
// get us out of the overview when we are already in it.
|
// get us out of the overview when we are already in it.
|
||||||
@ -270,8 +321,25 @@ function _globalKeyPressHandler(actor, event) {
|
|||||||
overview.hide();
|
overview.hide();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (symbol == Clutter.F2 && (Shell.get_event_state(event) & Clutter.ModifierType.MOD1_MASK)) {
|
}
|
||||||
getRunDialog().open();
|
|
||||||
|
// Whitelist some of the Metacity actions
|
||||||
|
let display = global.screen.get_display();
|
||||||
|
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||||
|
|
||||||
|
// This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
|
||||||
|
let action = display.get_keybinding_action(symbol, keyCode, modifierState);
|
||||||
|
switch (action) {
|
||||||
|
case Meta.KeyBindingAction.WORKSPACE_LEFT:
|
||||||
|
wm.actionMoveWorkspaceLeft();
|
||||||
|
return true;
|
||||||
|
case Meta.KeyBindingAction.WORKSPACE_RIGHT:
|
||||||
|
wm.actionMoveWorkspaceRight();
|
||||||
|
return true;
|
||||||
|
case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
|
||||||
|
case Meta.KeyBindingAction.COMMAND_2:
|
||||||
|
getRunDialog().open();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +374,7 @@ function _findModal(actor) {
|
|||||||
function pushModal(actor) {
|
function pushModal(actor) {
|
||||||
if (modalCount == 0) {
|
if (modalCount == 0) {
|
||||||
if (!global.begin_modal(global.get_current_time())) {
|
if (!global.begin_modal(global.get_current_time())) {
|
||||||
log("pushModal: invocation of begin_modal failed");
|
log('pushModal: invocation of begin_modal failed');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,12 +449,14 @@ function getRunDialog() {
|
|||||||
* activateWindow:
|
* activateWindow:
|
||||||
* @window: the Meta.Window to activate
|
* @window: the Meta.Window to activate
|
||||||
* @time: (optional) current event time
|
* @time: (optional) current event time
|
||||||
|
* @workspaceNum: (optional) window's workspace number
|
||||||
*
|
*
|
||||||
* Activates @window, switching to its workspace first if necessary
|
* Activates @window, switching to its workspace first if necessary,
|
||||||
|
* and switching out of the overview if it's currently active
|
||||||
*/
|
*/
|
||||||
function activateWindow(window, time) {
|
function activateWindow(window, time, workspaceNum) {
|
||||||
let activeWorkspaceNum = global.screen.get_active_workspace_index();
|
let activeWorkspaceNum = global.screen.get_active_workspace_index();
|
||||||
let windowWorkspaceNum = window.get_workspace().index();
|
let windowWorkspaceNum = (workspaceNum !== undefined) ? workspaceNum : window.get_workspace().index();
|
||||||
|
|
||||||
if (!time)
|
if (!time)
|
||||||
time = global.get_current_time();
|
time = global.get_current_time();
|
||||||
@ -397,6 +467,8 @@ function activateWindow(window, time) {
|
|||||||
} else {
|
} else {
|
||||||
window.activate(time);
|
window.activate(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overview.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - replace this timeout with some system to guess when the user might
|
// TODO - replace this timeout with some system to guess when the user might
|
||||||
@ -445,7 +517,7 @@ function _queueBeforeRedraw(workId) {
|
|||||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, function () {
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, function () {
|
||||||
_runBeforeRedrawQueue();
|
_runBeforeRedrawQueue();
|
||||||
return false;
|
return false;
|
||||||
}, null);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,7 +541,7 @@ function _queueBeforeRedraw(workId) {
|
|||||||
*/
|
*/
|
||||||
function initializeDeferredWork(actor, callback, props) {
|
function initializeDeferredWork(actor, callback, props) {
|
||||||
// Turn into a string so we can use as an object property
|
// Turn into a string so we can use as an object property
|
||||||
let workId = "" + (++_deferredWorkSequence);
|
let workId = '' + (++_deferredWorkSequence);
|
||||||
_deferredWorkData[workId] = { 'actor': actor,
|
_deferredWorkData[workId] = { 'actor': actor,
|
||||||
'callback': callback };
|
'callback': callback };
|
||||||
actor.connect('notify::mapped', function () {
|
actor.connect('notify::mapped', function () {
|
||||||
@ -499,7 +571,7 @@ function initializeDeferredWork(actor, callback, props) {
|
|||||||
function queueDeferredWork(workId) {
|
function queueDeferredWork(workId) {
|
||||||
let data = _deferredWorkData[workId];
|
let data = _deferredWorkData[workId];
|
||||||
if (!data) {
|
if (!data) {
|
||||||
global.logError("invalid work id ", workId);
|
global.logError('invalid work id ', workId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_deferredWorkQueue.indexOf(workId) < 0)
|
if (_deferredWorkQueue.indexOf(workId) < 0)
|
||||||
|
1205
js/ui/messageTray.js
@ -5,6 +5,7 @@ const GLib = imports.gi.GLib;
|
|||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
@ -12,6 +13,26 @@ const Params = imports.misc.params;
|
|||||||
|
|
||||||
let nextNotificationId = 1;
|
let nextNotificationId = 1;
|
||||||
|
|
||||||
|
// Should really be defined in dbus.js
|
||||||
|
const BusIface = {
|
||||||
|
name: 'org.freedesktop.DBus',
|
||||||
|
methods: [{ name: 'GetConnectionUnixProcessID',
|
||||||
|
inSignature: 's',
|
||||||
|
outSignature: 'i' }]
|
||||||
|
};
|
||||||
|
|
||||||
|
const Bus = function () {
|
||||||
|
this._init();
|
||||||
|
};
|
||||||
|
|
||||||
|
Bus.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
DBus.session.proxifyObject(this, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DBus.proxifyPrototype(Bus.prototype, BusIface);
|
||||||
|
|
||||||
const NotificationDaemonIface = {
|
const NotificationDaemonIface = {
|
||||||
name: 'org.freedesktop.Notifications',
|
name: 'org.freedesktop.Notifications',
|
||||||
methods: [{ name: 'Notify',
|
methods: [{ name: 'Notify',
|
||||||
@ -49,6 +70,25 @@ const Urgency = {
|
|||||||
CRITICAL: 2
|
CRITICAL: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rewriteRules = {
|
||||||
|
'XChat': [
|
||||||
|
{ pattern: /^XChat: Private message from: (\S*) \(.*\)$/,
|
||||||
|
replacement: '<$1>' },
|
||||||
|
{ pattern: /^XChat: New public message from: (\S*) \((.*)\)$/,
|
||||||
|
replacement: '$2 <$1>' },
|
||||||
|
{ pattern: /^XChat: Highlighted message from: (\S*) \((.*)\)$/,
|
||||||
|
replacement: '$2 <$1>' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// The notification spec stipulates using formal names for the appName the applications
|
||||||
|
// pass in. However, not all applications do that. Here is a list of the offenders we
|
||||||
|
// encountered so far.
|
||||||
|
const appNameMap = {
|
||||||
|
'evolution-mail-notification': 'Evolution Mail',
|
||||||
|
'rhythmbox': 'Rhythmbox'
|
||||||
|
};
|
||||||
|
|
||||||
function NotificationDaemon() {
|
function NotificationDaemon() {
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
@ -66,6 +106,13 @@ NotificationDaemon.prototype = {
|
|||||||
DBus.MANY_INSTANCES,
|
DBus.MANY_INSTANCES,
|
||||||
Lang.bind(this, this._acquiredName),
|
Lang.bind(this, this._acquiredName),
|
||||||
Lang.bind(this, this._lostName));
|
Lang.bind(this, this._lostName));
|
||||||
|
|
||||||
|
this._currentNotifications = {};
|
||||||
|
|
||||||
|
Shell.WindowTracker.get_default().connect('notify::focus-app',
|
||||||
|
Lang.bind(this, this._onFocusAppChanged));
|
||||||
|
Main.overview.connect('hidden',
|
||||||
|
Lang.bind(this, this._onFocusAppChanged));
|
||||||
},
|
},
|
||||||
|
|
||||||
_acquiredName: function() {
|
_acquiredName: function() {
|
||||||
@ -83,10 +130,10 @@ NotificationDaemon.prototype = {
|
|||||||
// kill the notification-daemon. pkill is more portable
|
// kill the notification-daemon. pkill is more portable
|
||||||
// than killall, but on Linux at least it won't match if
|
// than killall, but on Linux at least it won't match if
|
||||||
// you pass more than 15 characters of the process name...
|
// you pass more than 15 characters of the process name...
|
||||||
// However, if you use the "-f" flag to match the entire
|
// However, if you use the '-f' flag to match the entire
|
||||||
// command line, it will work, but we have to be careful
|
// command line, it will work, but we have to be careful
|
||||||
// in that case that we don't match "gedit
|
// in that case that we don't match 'gedit
|
||||||
// notification-daemon.c" or whatever...
|
// notification-daemon.c' or whatever...
|
||||||
let p = new Shell.Process({ args: ['pkill', '-f',
|
let p = new Shell.Process({ args: ['pkill', '-f',
|
||||||
'^([^ ]*/)?(notification-daemon|notify-osd)$']});
|
'^([^ ]*/)?(notification-daemon|notify-osd)$']});
|
||||||
p.run();
|
p.run();
|
||||||
@ -94,58 +141,113 @@ NotificationDaemon.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_sourceId: function(id) {
|
_sourceId: function(id) {
|
||||||
return 'notification-' + id;
|
return 'source-' + id;
|
||||||
},
|
},
|
||||||
|
|
||||||
Notify: function(appName, replacesId, icon, summary, body,
|
Notify: function(appName, replacesId, icon, summary, body,
|
||||||
actions, hints, timeout) {
|
actions, hints, timeout) {
|
||||||
let id, source = null;
|
let source = Main.messageTray.getSource(this._sourceId(appName));
|
||||||
|
let id = null;
|
||||||
|
|
||||||
if (replacesId != 0) {
|
// Filter out notifications from Empathy, since we
|
||||||
id = replacesId;
|
// handle that information from telepathyClient.js
|
||||||
source = Main.messageTray.getSource(this._sourceId(id));
|
if (appName == 'Empathy') {
|
||||||
// source may be null if the current source was destroyed
|
id = nextNotificationId++;
|
||||||
// right as the client sent the new notification
|
Mainloop.idle_add(Lang.bind(this,
|
||||||
|
function () {
|
||||||
|
this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED);
|
||||||
|
}));
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source == null) {
|
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
||||||
id = nextNotificationId++;
|
|
||||||
|
|
||||||
source = new Source(this._sourceId(id), icon, hints);
|
// Source may be null if we have never received a notification
|
||||||
|
// from this app or if all notifications from this app have
|
||||||
|
// been acknowledged.
|
||||||
|
if (source == null) {
|
||||||
|
let title = appNameMap[appName] || appName;
|
||||||
|
source = new Source(this._sourceId(appName), title, icon, hints);
|
||||||
Main.messageTray.add(source);
|
Main.messageTray.add(source);
|
||||||
|
|
||||||
source.connect('clicked', Lang.bind(this,
|
source.connect('clicked', Lang.bind(this,
|
||||||
function() {
|
function() {
|
||||||
source.destroy();
|
source.destroy();
|
||||||
this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED);
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
let sender = DBus.getCurrentMessageContext().sender;
|
||||||
|
let busProxy = new Bus();
|
||||||
|
busProxy.GetConnectionUnixProcessIDRemote(sender, function (result, excp) {
|
||||||
|
let app = Shell.WindowTracker.get_default().get_app_from_pid(result);
|
||||||
|
if (app)
|
||||||
|
source.setApp(app);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
source.update(icon, hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
summary = GLib.markup_escape_text(summary, -1);
|
summary = GLib.markup_escape_text(summary, -1);
|
||||||
if (body)
|
|
||||||
source.notify('<b>' + summary + '</b>: ' + body);
|
let rewrites = rewriteRules[appName];
|
||||||
else
|
if (rewrites) {
|
||||||
source.notify('<b>' + summary + '</b>');
|
for (let i = 0; i < rewrites.length; i++) {
|
||||||
|
let rule = rewrites[i];
|
||||||
|
if (summary.search(rule.pattern) != -1)
|
||||||
|
summary = summary.replace(rule.pattern, rule.replacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let notification;
|
||||||
|
if (replacesId != 0) {
|
||||||
|
id = replacesId;
|
||||||
|
notification = this._currentNotifications[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notification == null) {
|
||||||
|
id = nextNotificationId++;
|
||||||
|
notification = new MessageTray.Notification(id, source, summary, body, true);
|
||||||
|
this._currentNotifications[id] = notification;
|
||||||
|
notification.connect('dismissed', Lang.bind(this,
|
||||||
|
function(n) {
|
||||||
|
n.destroy();
|
||||||
|
this._emitNotificationClosed(n.id, NotificationClosedReason.DISMISSED);
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
// passing in true as the last parameter will clear out extra actors,
|
||||||
|
// such as actions
|
||||||
|
notification.update(summary, body, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actions.length) {
|
||||||
|
for (let i = 0; i < actions.length - 1; i += 2)
|
||||||
|
notification.addButton(actions[i], actions[i + 1]);
|
||||||
|
notification.connect('action-invoked', Lang.bind(this, this._actionInvoked, source, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.setUrgent(hints.urgency == Urgency.CRITICAL);
|
||||||
|
|
||||||
|
source.notify(notification);
|
||||||
return id;
|
return id;
|
||||||
},
|
},
|
||||||
|
|
||||||
CloseNotification: function(id) {
|
CloseNotification: function(id) {
|
||||||
let source = Main.messageTray.getSource(this._sourceId(id));
|
let notification = this._currentNotifications[id];
|
||||||
if (source)
|
if (notification)
|
||||||
source.destroy();
|
notification.destroy();
|
||||||
this._emitNotificationClosed(id, NotificationClosedReason.APP_CLOSED);
|
this._emitNotificationClosed(id, NotificationClosedReason.APP_CLOSED);
|
||||||
},
|
},
|
||||||
|
|
||||||
GetCapabilities: function() {
|
GetCapabilities: function() {
|
||||||
return [
|
return [
|
||||||
// 'actions',
|
'actions',
|
||||||
'body',
|
'body',
|
||||||
// 'body-hyperlinks',
|
// 'body-hyperlinks',
|
||||||
// 'body-images',
|
// 'body-images',
|
||||||
'body-markup',
|
'body-markup',
|
||||||
// 'icon-multi',
|
// 'icon-multi',
|
||||||
'icon-static'
|
'icon-static',
|
||||||
// 'sound',
|
// 'sound',
|
||||||
|
'x-gnome-icon-buttons'
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -158,35 +260,59 @@ NotificationDaemon.prototype = {
|
|||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onFocusAppChanged: function() {
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
|
if (tracker.focus_app)
|
||||||
|
Main.messageTray.removeSourceByApp(tracker.focus_app);
|
||||||
|
},
|
||||||
|
|
||||||
|
_actionInvoked: function(notification, action, source, id) {
|
||||||
|
this._emitActionInvoked(id, action);
|
||||||
|
source.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
_emitNotificationClosed: function(id, reason) {
|
_emitNotificationClosed: function(id, reason) {
|
||||||
|
delete this._currentNotifications[id];
|
||||||
DBus.session.emit_signal('/org/freedesktop/Notifications',
|
DBus.session.emit_signal('/org/freedesktop/Notifications',
|
||||||
'org.freedesktop.Notifications',
|
'org.freedesktop.Notifications',
|
||||||
'NotificationClosed', 'uu',
|
'NotificationClosed', 'uu',
|
||||||
[id, reason]);
|
[id, reason]);
|
||||||
|
},
|
||||||
|
|
||||||
|
_emitActionInvoked: function(id, action) {
|
||||||
|
DBus.session.emit_signal('/org/freedesktop/Notifications',
|
||||||
|
'org.freedesktop.Notifications',
|
||||||
|
'ActionInvoked', 'us',
|
||||||
|
[id, action]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DBus.conformExport(NotificationDaemon.prototype, NotificationDaemonIface);
|
DBus.conformExport(NotificationDaemon.prototype, NotificationDaemonIface);
|
||||||
|
|
||||||
function Source(sourceId, icon, hints) {
|
function Source(sourceId, title, icon, hints) {
|
||||||
this._init(sourceId, icon, hints);
|
this._init(sourceId, title, icon, hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
Source.prototype = {
|
Source.prototype = {
|
||||||
__proto__: MessageTray.Source.prototype,
|
__proto__: MessageTray.Source.prototype,
|
||||||
|
|
||||||
_init: function(sourceId, icon, hints) {
|
_init: function(sourceId, title, icon, hints) {
|
||||||
MessageTray.Source.prototype._init.call(this, sourceId);
|
MessageTray.Source.prototype._init.call(this, sourceId, title);
|
||||||
|
|
||||||
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
this.app = null;
|
||||||
|
this._openAppRequested = false;
|
||||||
|
|
||||||
|
this.update(icon, hints);
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function(icon, hints) {
|
||||||
this._icon = icon;
|
this._icon = icon;
|
||||||
this._iconData = hints.icon_data;
|
this._iconData = hints.icon_data;
|
||||||
this._urgency = hints.urgency;
|
this._urgency = hints.urgency;
|
||||||
},
|
},
|
||||||
|
|
||||||
createIcon: function(size) {
|
createIcon: function(size) {
|
||||||
let textureCache = Shell.TextureCache.get_default();
|
let textureCache = St.TextureCache.get_default();
|
||||||
|
|
||||||
if (this._icon) {
|
if (this._icon) {
|
||||||
if (this._icon.substr(0, 7) == 'file://')
|
if (this._icon.substr(0, 7) == 'file://')
|
||||||
@ -214,5 +340,29 @@ Source.prototype = {
|
|||||||
}
|
}
|
||||||
return textureCache.load_icon_name(stockIcon, size);
|
return textureCache.load_icon_name(stockIcon, size);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clicked: function() {
|
||||||
|
this.openApp();
|
||||||
|
MessageTray.Source.prototype.clicked.call(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
setApp: function(app) {
|
||||||
|
this.app = app;
|
||||||
|
if (this._openAppRequested)
|
||||||
|
this.openApp();
|
||||||
|
},
|
||||||
|
|
||||||
|
openApp: function() {
|
||||||
|
if (this.app == null) {
|
||||||
|
this._openAppRequested = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let windows = this.app.get_windows();
|
||||||
|
if (windows.length > 0) {
|
||||||
|
let mostRecentWindow = windows[0];
|
||||||
|
Main.activateWindow(mostRecentWindow);
|
||||||
|
}
|
||||||
|
this._openAppRequested = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
@ -8,22 +7,26 @@ const Mainloop = imports.mainloop;
|
|||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
const AppDisplay = imports.ui.appDisplay;
|
const AppDisplay = imports.ui.appDisplay;
|
||||||
const DocDisplay = imports.ui.docDisplay;
|
const DocDisplay = imports.ui.docDisplay;
|
||||||
const GenericDisplay = imports.ui.genericDisplay;
|
const GenericDisplay = imports.ui.genericDisplay;
|
||||||
|
const Lightbox = imports.ui.lightbox;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Panel = imports.ui.panel;
|
const Panel = imports.ui.panel;
|
||||||
const Dash = imports.ui.dash;
|
const Dash = imports.ui.dash;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const Workspaces = imports.ui.workspaces;
|
const WorkspacesView = imports.ui.workspacesView;
|
||||||
|
|
||||||
const ROOT_OVERVIEW_COLOR = new Clutter.Color();
|
|
||||||
ROOT_OVERVIEW_COLOR.from_pixel(0x000000ff);
|
|
||||||
|
|
||||||
// Time for initial animation going into Overview mode
|
// Time for initial animation going into Overview mode
|
||||||
const ANIMATION_TIME = 0.25;
|
const ANIMATION_TIME = 0.25;
|
||||||
|
|
||||||
|
// Time for pane menus to fade in/out
|
||||||
|
const PANE_FADE_TIME = 0.1;
|
||||||
|
|
||||||
// We divide the screen into a grid of rows and columns, which we use
|
// We divide the screen into a grid of rows and columns, which we use
|
||||||
// to help us position the Overview components, such as the side panel
|
// to help us position the Overview components, such as the side panel
|
||||||
// that lists applications and documents, the workspaces display, and
|
// that lists applications and documents, the workspaces display, and
|
||||||
@ -73,10 +76,101 @@ const SHADOW_WIDTH = 6;
|
|||||||
|
|
||||||
const NUMBER_OF_SECTIONS_IN_SEARCH = 2;
|
const NUMBER_OF_SECTIONS_IN_SEARCH = 2;
|
||||||
|
|
||||||
|
const INFO_BAR_HIDE_TIMEOUT = 10;
|
||||||
|
|
||||||
let wideScreen = false;
|
let wideScreen = false;
|
||||||
let displayGridColumnWidth = null;
|
let displayGridColumnWidth = null;
|
||||||
let displayGridRowHeight = null;
|
let displayGridRowHeight = null;
|
||||||
let addRemoveButtonSize = null;
|
|
||||||
|
function InfoBar() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoBar.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
this.actor = new St.Bin({ style_class: 'info-bar-panel',
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: false });
|
||||||
|
this._label = new St.Label();
|
||||||
|
this._undo = new St.Button({ style_class: 'info-bar-link-button' });
|
||||||
|
|
||||||
|
let bin = new St.Bin({ x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.MIDDLE,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
this.actor.set_child(bin);
|
||||||
|
|
||||||
|
let box = new St.BoxLayout({ style_class: 'info-bar' });
|
||||||
|
bin.set_child(box);
|
||||||
|
this._timeoutId = 0;
|
||||||
|
|
||||||
|
box.add(this._label, {'y-fill' : false, 'y-align' : St.Align.MIDDLE});
|
||||||
|
box.add(this._undo);
|
||||||
|
|
||||||
|
this.actor.set_opacity(0);
|
||||||
|
|
||||||
|
this._undoCallback = null;
|
||||||
|
this._undo.connect('clicked', Lang.bind(this, this._onUndoClicked));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onUndoClicked: function() {
|
||||||
|
Mainloop.source_remove(this._timeoutId);
|
||||||
|
this._timeoutId = 0;
|
||||||
|
|
||||||
|
if (this._undoCallback)
|
||||||
|
this._undoCallback();
|
||||||
|
this.actor.set_opacity(0);
|
||||||
|
this._undoCallback = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_hideDone: function() {
|
||||||
|
this._undoCallback = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_hide: function() {
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 0,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
time: ANIMATION_TIME,
|
||||||
|
onComplete: this._hideDone,
|
||||||
|
onCompleteScope: this
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_onTimeout: function() {
|
||||||
|
this._timeoutId = 0;
|
||||||
|
this._hide();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
setMessage: function(text, undoCallback, undoLabel) {
|
||||||
|
if (this._timeoutId)
|
||||||
|
Mainloop.source_remove(this._timeoutId);
|
||||||
|
|
||||||
|
this._timeout = false;
|
||||||
|
|
||||||
|
this._label.text = text;
|
||||||
|
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
time: ANIMATION_TIME
|
||||||
|
});
|
||||||
|
|
||||||
|
this._timeoutId = Mainloop.timeout_add_seconds(INFO_BAR_HIDE_TIMEOUT, Lang.bind(this, this._onTimeout));
|
||||||
|
|
||||||
|
if (undoLabel)
|
||||||
|
this._undo.label = undoLabel;
|
||||||
|
else
|
||||||
|
this._undo.label = _("Undo");
|
||||||
|
|
||||||
|
this._undoCallback = undoCallback;
|
||||||
|
if (undoCallback)
|
||||||
|
this._undo.show();
|
||||||
|
else
|
||||||
|
this._undo.hide();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function Overview() {
|
function Overview() {
|
||||||
this._init();
|
this._init();
|
||||||
@ -84,8 +178,21 @@ function Overview() {
|
|||||||
|
|
||||||
Overview.prototype = {
|
Overview.prototype = {
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this._group = new Clutter.Group();
|
this._group = new St.Group({ style_class: 'overview' });
|
||||||
this._group._delegate = this;
|
this._group._delegate = this;
|
||||||
|
this._group.connect('destroy', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
if (this._lightbox) {
|
||||||
|
this._lightbox.destroy();
|
||||||
|
this._lightbox = null;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.infoBar = new InfoBar();
|
||||||
|
this._group.add_actor(this.infoBar.actor);
|
||||||
|
|
||||||
|
this._workspacesManager = null;
|
||||||
|
this._lightbox = null;
|
||||||
|
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
@ -110,7 +217,7 @@ Overview.prototype = {
|
|||||||
this._group.add_actor(this._transparentBackground);
|
this._group.add_actor(this._transparentBackground);
|
||||||
|
|
||||||
// Background color for the Overview
|
// Background color for the Overview
|
||||||
this._backOver = new Clutter.Rectangle({ color: ROOT_OVERVIEW_COLOR });
|
this._backOver = new St.Label();
|
||||||
this._group.add_actor(this._backOver);
|
this._group.add_actor(this._backOver);
|
||||||
|
|
||||||
this._group.hide();
|
this._group.hide();
|
||||||
@ -121,8 +228,7 @@ Overview.prototype = {
|
|||||||
this._group.add_actor(this._dash.actor);
|
this._group.add_actor(this._dash.actor);
|
||||||
|
|
||||||
// Container to hold popup pane chrome.
|
// Container to hold popup pane chrome.
|
||||||
this._paneContainer = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
this._paneContainer = new St.BoxLayout({ style_class: 'overview-pane' });
|
||||||
spacing: 6 });
|
|
||||||
// Note here we explicitly don't set the paneContainer to be reactive yet; that's done
|
// Note here we explicitly don't set the paneContainer to be reactive yet; that's done
|
||||||
// inside the notify::visible handler on panes.
|
// inside the notify::visible handler on panes.
|
||||||
this._paneContainer.connect('button-release-event', Lang.bind(this, function(background) {
|
this._paneContainer.connect('button-release-event', Lang.bind(this, function(background) {
|
||||||
@ -132,11 +238,23 @@ Overview.prototype = {
|
|||||||
this._group.add_actor(this._paneContainer);
|
this._group.add_actor(this._paneContainer);
|
||||||
|
|
||||||
this._transparentBackground.lower_bottom();
|
this._transparentBackground.lower_bottom();
|
||||||
this._paneContainer.lower_bottom();
|
this._paneContainer.hide();
|
||||||
|
|
||||||
this._coverPane.lower_bottom();
|
this._coverPane.lower_bottom();
|
||||||
|
|
||||||
this._workspaces = null;
|
this.workspaces = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onViewChanged: function() {
|
||||||
|
if (!this.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.workspaces = this._workspacesManager.workspacesView;
|
||||||
|
|
||||||
|
// Show new workspacesView
|
||||||
|
this._group.add_actor(this.workspaces.actor);
|
||||||
|
this._workspacesBar.raise(this.workspaces.actor);
|
||||||
|
this._dash.actor.raise(this.workspaces.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
_recalculateGridSizes: function () {
|
_recalculateGridSizes: function () {
|
||||||
@ -157,8 +275,12 @@ Overview.prototype = {
|
|||||||
|
|
||||||
relayout: function () {
|
relayout: function () {
|
||||||
let primary = global.get_primary_monitor();
|
let primary = global.get_primary_monitor();
|
||||||
|
let rtl = (St.Widget.get_default_direction () == St.TextDirection.RTL);
|
||||||
|
|
||||||
|
this._recalculateGridSizes();
|
||||||
|
|
||||||
this._group.set_position(primary.x, primary.y);
|
this._group.set_position(primary.x, primary.y);
|
||||||
|
this._group.set_size(primary.width, primary.height);
|
||||||
|
|
||||||
let contentY = Panel.PANEL_HEIGHT;
|
let contentY = Panel.PANEL_HEIGHT;
|
||||||
let contentHeight = primary.height - contentY;
|
let contentHeight = primary.height - contentY;
|
||||||
@ -176,19 +298,32 @@ Overview.prototype = {
|
|||||||
this._workspacesHeight = Math.floor(displayGridRowHeight * workspaceRowsUsed
|
this._workspacesHeight = Math.floor(displayGridRowHeight * workspaceRowsUsed
|
||||||
- WORKSPACE_GRID_PADDING * (primary.height / primary.width) * 2);
|
- WORKSPACE_GRID_PADDING * (primary.height / primary.width) * 2);
|
||||||
|
|
||||||
this._workspacesX = displayGridColumnWidth + WORKSPACE_GRID_PADDING;
|
if (rtl) {
|
||||||
|
this._workspacesX = WORKSPACE_GRID_PADDING;
|
||||||
|
} else {
|
||||||
|
this._workspacesX = displayGridColumnWidth + WORKSPACE_GRID_PADDING;
|
||||||
|
}
|
||||||
this._workspacesY = Math.floor(displayGridRowHeight + WORKSPACE_GRID_PADDING * (primary.height / primary.width));
|
this._workspacesY = Math.floor(displayGridRowHeight + WORKSPACE_GRID_PADDING * (primary.height / primary.width));
|
||||||
|
|
||||||
this._dash.actor.set_position(0, contentY);
|
if (rtl) {
|
||||||
|
this._dash.actor.set_position(primary.width - displayGridColumnWidth, contentY);
|
||||||
|
} else {
|
||||||
|
this._dash.actor.set_position(0, contentY);
|
||||||
|
}
|
||||||
|
|
||||||
this._dash.actor.set_size(displayGridColumnWidth, contentHeight);
|
this._dash.actor.set_size(displayGridColumnWidth, contentHeight);
|
||||||
this._dash.searchArea.height = this._workspacesY - contentY;
|
this._dash.searchArea.height = this._workspacesY - contentY;
|
||||||
this._dash.sectionArea.height = this._workspacesHeight;
|
this._dash.sectionArea.height = this._workspacesHeight;
|
||||||
this._dash.searchResults.actor.height = this._workspacesHeight;
|
this._dash.searchResults.actor.height = this._workspacesHeight;
|
||||||
|
|
||||||
|
this.infoBar.actor.set_position(displayGridColumnWidth, Panel.PANEL_HEIGHT);
|
||||||
|
this.infoBar.actor.set_size(primary.width - displayGridColumnWidth, this._workspacesY - Panel.PANEL_HEIGHT);
|
||||||
|
this.infoBar.actor.raise_top();
|
||||||
|
|
||||||
// place the 'Add Workspace' button in the bottom row of the grid
|
// place the 'Add Workspace' button in the bottom row of the grid
|
||||||
addRemoveButtonSize = Math.floor(displayGridRowHeight * 3/5);
|
this._workspacesBarX = this._workspacesX;
|
||||||
this._addButtonX = this._workspacesX + this._workspacesWidth - addRemoveButtonSize;
|
this._workspacesBarWidth = this._workspacesWidth;
|
||||||
this._addButtonY = primary.height - Math.floor(displayGridRowHeight * 4/5);
|
this._workspacesBarY = primary.height - displayGridRowHeight;
|
||||||
|
|
||||||
// The parent (this._group) is positioned at the top left of the primary monitor
|
// The parent (this._group) is positioned at the top left of the primary monitor
|
||||||
// while this._backOver occupies the entire screen.
|
// while this._backOver occupies the entire screen.
|
||||||
@ -199,17 +334,22 @@ Overview.prototype = {
|
|||||||
this._workspacesY);
|
this._workspacesY);
|
||||||
// Dynamic width
|
// Dynamic width
|
||||||
this._paneContainer.height = this._workspacesHeight;
|
this._paneContainer.height = this._workspacesHeight;
|
||||||
|
if (rtl) {
|
||||||
|
this._paneContainer.connect('notify::width', Lang.bind(this, function (paneContainer) {
|
||||||
|
paneContainer.x = this._dash.actor.x - (DEFAULT_PADDING + paneContainer.width);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
this._transparentBackground.set_position(this._paneContainer.x, this._paneContainer.y);
|
this._transparentBackground.set_position(primary.x, primary.y);
|
||||||
this._transparentBackground.set_size(primary.width - this._paneContainer.x,
|
this._transparentBackground.set_size(primary.width, primary.height);
|
||||||
this._paneContainer.height);
|
|
||||||
|
|
||||||
if (this._activeDisplayPane != null)
|
|
||||||
this._activeDisplayPane.actor.width = displayGridColumnWidth * 2;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addPane: function (pane) {
|
addPane: function (pane, align) {
|
||||||
this._paneContainer.append(pane.actor, Big.BoxPackFlags.NONE);
|
pane.actor.height = .9 * this._workspacesHeight;
|
||||||
|
this._paneContainer.add(pane.actor, { expand: true,
|
||||||
|
y_fill: false,
|
||||||
|
y_align: align });
|
||||||
// When a pane is displayed, we raise the transparent background to the top
|
// When a pane is displayed, we raise the transparent background to the top
|
||||||
// and connect to button-release-event on it, then raise the pane above that.
|
// and connect to button-release-event on it, then raise the pane above that.
|
||||||
// The idea here is that clicking anywhere outside the pane should close it.
|
// The idea here is that clicking anywhere outside the pane should close it.
|
||||||
@ -217,17 +357,28 @@ Overview.prototype = {
|
|||||||
let backgroundEventId = null;
|
let backgroundEventId = null;
|
||||||
pane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) {
|
pane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) {
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
pane.actor.width = displayGridColumnWidth * 2;
|
|
||||||
this._activeDisplayPane = pane;
|
this._activeDisplayPane = pane;
|
||||||
this._transparentBackground.raise_top();
|
this._transparentBackground.raise_top();
|
||||||
this._paneContainer.raise_top();
|
this._paneContainer.raise_top();
|
||||||
|
this._paneContainer.show();
|
||||||
|
this._paneReady = false;
|
||||||
if (backgroundEventId != null)
|
if (backgroundEventId != null)
|
||||||
this._transparentBackground.disconnect(backgroundEventId);
|
this._transparentBackground.disconnect(backgroundEventId);
|
||||||
backgroundEventId = this._transparentBackground.connect('button-release-event', Lang.bind(this, function () {
|
backgroundEventId = this._transparentBackground.connect('captured-event', Lang.bind(this, function (actor, event) {
|
||||||
this._activeDisplayPane.close();
|
if (event.get_source() != this._transparentBackground)
|
||||||
|
return false;
|
||||||
|
if (event.type() == Clutter.EventType.BUTTON_PRESS)
|
||||||
|
this._paneReady = true;
|
||||||
|
if (event.type() == Clutter.EventType.BUTTON_RELEASE
|
||||||
|
&& this._paneReady)
|
||||||
|
this._activeDisplayPane.close();
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
this._workspaces.actor.opacity = 64;
|
if (!this._lightbox)
|
||||||
|
this._lightbox = new Lightbox.Lightbox(this._group,
|
||||||
|
{ fadeTime: PANE_FADE_TIME });
|
||||||
|
this._lightbox.show();
|
||||||
|
this._lightbox.highlight(this._paneContainer);
|
||||||
} else if (pane == this._activeDisplayPane) {
|
} else if (pane == this._activeDisplayPane) {
|
||||||
this._activeDisplayPane = null;
|
this._activeDisplayPane = null;
|
||||||
if (backgroundEventId != null) {
|
if (backgroundEventId != null) {
|
||||||
@ -235,40 +386,37 @@ Overview.prototype = {
|
|||||||
backgroundEventId = null;
|
backgroundEventId = null;
|
||||||
}
|
}
|
||||||
this._transparentBackground.lower_bottom();
|
this._transparentBackground.lower_bottom();
|
||||||
this._paneContainer.lower_bottom();
|
this._paneContainer.hide();
|
||||||
this._workspaces.actor.opacity = 255;
|
this._lightbox.hide();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
//// Draggable target interface ////
|
//// Public methods ////
|
||||||
|
|
||||||
// Closes any active panes if a GenericDisplayItem is being
|
beginItemDrag: function(source) {
|
||||||
// dragged over the Overview, i.e. as soon as it starts being dragged.
|
// Close any active panes if @source is a GenericDisplayItem.
|
||||||
// This allows the user to place the item on any workspace.
|
// This allows the user to place the item on any workspace.
|
||||||
handleDragOver : function(source, actor, x, y, time) {
|
if (source instanceof GenericDisplay.GenericDisplayItem)
|
||||||
if (source instanceof GenericDisplay.GenericDisplayItem
|
|
||||||
|| source instanceof AppDisplay.AppIcon) {
|
|
||||||
if (this._activeDisplayPane != null)
|
if (this._activeDisplayPane != null)
|
||||||
this._activeDisplayPane.close();
|
this._activeDisplayPane.close();
|
||||||
return true;
|
this.emit('item-drag-begin');
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//// Public methods ////
|
endItemDrag: function(source) {
|
||||||
|
this.emit('item-drag-end');
|
||||||
|
},
|
||||||
|
|
||||||
// Returns the scale the Overview has when we just start zooming out
|
// Returns the scale the Overview has when we just start zooming out
|
||||||
// to overview mode. That is, when just the active workspace is showing.
|
// to overview mode. That is, when just the active workspace is showing.
|
||||||
getZoomedInScale : function() {
|
getZoomedInScale : function() {
|
||||||
return 1 / this._workspaces.getScale();
|
return 1 / this.workspaces.getScale();
|
||||||
},
|
},
|
||||||
|
|
||||||
// Returns the position the Overview has when we just start zooming out
|
// Returns the position the Overview has when we just start zooming out
|
||||||
// to overview mode. That is, when just the active workspace is showing.
|
// to overview mode. That is, when just the active workspace is showing.
|
||||||
getZoomedInPosition : function() {
|
getZoomedInPosition : function() {
|
||||||
let [posX, posY] = this._workspaces.getActiveWorkspacePosition();
|
let [posX, posY] = this.workspaces.getActiveWorkspacePosition();
|
||||||
let scale = this.getZoomedInScale();
|
let scale = this.getZoomedInScale();
|
||||||
|
|
||||||
return [- posX * scale, - posY * scale];
|
return [- posX * scale, - posY * scale];
|
||||||
@ -296,20 +444,28 @@ Overview.prototype = {
|
|||||||
this._dash.show();
|
this._dash.show();
|
||||||
|
|
||||||
/* TODO: make this stuff dynamic */
|
/* TODO: make this stuff dynamic */
|
||||||
this._workspaces = new Workspaces.Workspaces(this._workspacesWidth, this._workspacesHeight,
|
this._workspacesManager =
|
||||||
this._workspacesX, this._workspacesY);
|
new WorkspacesView.WorkspacesManager(this._workspacesWidth,
|
||||||
this._group.add_actor(this._workspaces.actor);
|
this._workspacesHeight,
|
||||||
|
this._workspacesX,
|
||||||
|
this._workspacesY);
|
||||||
|
this._workspacesManager.connect('view-changed',
|
||||||
|
Lang.bind(this, this._onViewChanged));
|
||||||
|
this.workspaces = this._workspacesManager.workspacesView;
|
||||||
|
this._group.add_actor(this.workspaces.actor);
|
||||||
|
|
||||||
// The workspaces actor is as big as the screen, so we have to raise the dash above it
|
// The workspaces actor is as big as the screen, so we have to raise the dash above it
|
||||||
// for drag and drop to work. In the future we should fix the workspaces to not
|
// for drag and drop to work. In the future we should fix the workspaces to not
|
||||||
// be as big as the screen.
|
// be as big as the screen.
|
||||||
this._dash.actor.raise(this._workspaces.actor);
|
this._dash.actor.raise(this.workspaces.actor);
|
||||||
|
|
||||||
// Create (+) button
|
this._workspacesBar = this._workspacesManager.controlsBar.actor;
|
||||||
this._addButton = new AddWorkspaceButton(addRemoveButtonSize, this._addButtonX, this._addButtonY, Lang.bind(this, this._acceptNewWorkspaceDrop));
|
this._workspacesBar.set_position(this._workspacesBarX,
|
||||||
this._addButton.actor.connect('button-release-event', Lang.bind(this, this._addNewWorkspace));
|
this._workspacesBarY);
|
||||||
this._group.add_actor(this._addButton.actor);
|
this._workspacesBar.width = this._workspacesBarWidth;
|
||||||
this._addButton.actor.raise(this._workspaces.actor);
|
|
||||||
|
this._group.add_actor(this._workspacesBar);
|
||||||
|
this._workspacesBar.raise(this.workspaces.actor);
|
||||||
|
|
||||||
// All the the actors in the window group are completely obscured,
|
// All the the actors in the window group are completely obscured,
|
||||||
// hiding the group holding them while the Overview is displayed greatly
|
// hiding the group holding them while the Overview is displayed greatly
|
||||||
@ -339,7 +495,7 @@ Overview.prototype = {
|
|||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
|
|
||||||
// Make Dash fade in so that it doesn't appear to big.
|
// Make Dash fade in so that it doesn't appear too big.
|
||||||
this._dash.actor.opacity = 0;
|
this._dash.actor.opacity = 0;
|
||||||
Tweener.addTween(this._dash.actor,
|
Tweener.addTween(this._dash.actor,
|
||||||
{ opacity: 255,
|
{ opacity: 255,
|
||||||
@ -359,11 +515,7 @@ Overview.prototype = {
|
|||||||
this._hideInProgress = true;
|
this._hideInProgress = true;
|
||||||
if (this._activeDisplayPane != null)
|
if (this._activeDisplayPane != null)
|
||||||
this._activeDisplayPane.close();
|
this._activeDisplayPane.close();
|
||||||
this._workspaces.hide();
|
this.workspaces.hide();
|
||||||
|
|
||||||
this._addButton.actor.destroy();
|
|
||||||
this._addButton.actor = null;
|
|
||||||
this._addButton = null;
|
|
||||||
|
|
||||||
// Create a zoom in effect by transforming the Overview group so that
|
// Create a zoom in effect by transforming the Overview group so that
|
||||||
// the active workspace fills up the whole screen. The opposite
|
// the active workspace fills up the whole screen. The opposite
|
||||||
@ -408,21 +560,7 @@ Overview.prototype = {
|
|||||||
* and will return %null.
|
* and will return %null.
|
||||||
*/
|
*/
|
||||||
getWorkspacesForWindow: function(metaWindow) {
|
getWorkspacesForWindow: function(metaWindow) {
|
||||||
return this._workspaces;
|
return this.workspaces;
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* activateWindow:
|
|
||||||
* @metaWindow: A #MetaWindow
|
|
||||||
* @time: Event timestamp integer
|
|
||||||
*
|
|
||||||
* Make the given MetaWindow be the focus window, switching
|
|
||||||
* to the workspace it's on if necessary. This function
|
|
||||||
* should only be used when the Overview is currently active;
|
|
||||||
* outside of that, use the relevant methods on MetaDisplay.
|
|
||||||
*/
|
|
||||||
activateWindow: function (metaWindow, time) {
|
|
||||||
this._workspaces.activateWindowFromOverview(metaWindow, time);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//// Private methods ////
|
//// Private methods ////
|
||||||
@ -440,13 +578,18 @@ Overview.prototype = {
|
|||||||
_hideDone: function() {
|
_hideDone: function() {
|
||||||
global.window_group.show();
|
global.window_group.show();
|
||||||
|
|
||||||
this._workspaces.destroy();
|
this.workspaces.destroy();
|
||||||
this._workspaces = null;
|
this.workspaces = null;
|
||||||
|
|
||||||
|
this._workspacesBar.destroy();
|
||||||
|
this._workspacesBar = null;
|
||||||
|
|
||||||
|
this._workspacesManager = null;
|
||||||
|
|
||||||
this._dash.hide();
|
this._dash.hide();
|
||||||
this._group.hide();
|
this._group.hide();
|
||||||
|
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
this._hideInProgress = false;
|
this._hideInProgress = false;
|
||||||
|
|
||||||
@ -454,43 +597,6 @@ Overview.prototype = {
|
|||||||
|
|
||||||
Main.popModal(this._dash.actor);
|
Main.popModal(this._dash.actor);
|
||||||
this.emit('hidden');
|
this.emit('hidden');
|
||||||
},
|
|
||||||
|
|
||||||
_addNewWorkspace: function() {
|
|
||||||
global.screen.append_new_workspace(false, global.get_current_time());
|
|
||||||
},
|
|
||||||
|
|
||||||
_acceptNewWorkspaceDrop: function(source, dropActor, x, y, time) {
|
|
||||||
this._addNewWorkspace();
|
|
||||||
return this._workspaces.acceptNewWorkspaceDrop(source, dropActor, x, y, time);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(Overview.prototype);
|
Signals.addSignalMethods(Overview.prototype);
|
||||||
|
|
||||||
function AddWorkspaceButton(buttonSize, buttonX, buttonY, acceptDropCallback) {
|
|
||||||
this._init(buttonSize, buttonX, buttonY, acceptDropCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddWorkspaceButton.prototype = {
|
|
||||||
_init: function(buttonSize, buttonX, buttonY, acceptDropCallback) {
|
|
||||||
this.actor = new Clutter.Group({ x: buttonX,
|
|
||||||
y: buttonY,
|
|
||||||
width: global.screen_width - buttonX,
|
|
||||||
height: global.screen_height - buttonY,
|
|
||||||
reactive: true });
|
|
||||||
this.actor._delegate = this;
|
|
||||||
this._acceptDropCallback = acceptDropCallback;
|
|
||||||
|
|
||||||
let plus = new Clutter.Texture({ x: 0,
|
|
||||||
y: 0,
|
|
||||||
width: buttonSize,
|
|
||||||
height: buttonSize });
|
|
||||||
plus.set_from_file(global.imagedir + 'add-workspace.svg');
|
|
||||||
this.actor.add_actor(plus);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Draggable target interface
|
|
||||||
acceptDrop: function(source, actor, x, y, time) {
|
|
||||||
return this._acceptDropCallback(source, actor, x, y, time);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
927
js/ui/panel.js
@ -1,8 +1,8 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
|
const GConf = imports.gi.GConf;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
@ -59,7 +59,7 @@ PlaceInfo.prototype = {
|
|||||||
isRemovable: function() {
|
isRemovable: function() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function PlaceDeviceInfo(mount) {
|
function PlaceDeviceInfo(mount) {
|
||||||
this._init(mount);
|
this._init(mount);
|
||||||
@ -72,12 +72,12 @@ PlaceDeviceInfo.prototype = {
|
|||||||
this._mount = mount;
|
this._mount = mount;
|
||||||
this.name = mount.get_name();
|
this.name = mount.get_name();
|
||||||
this._lowerName = this.name.toLowerCase();
|
this._lowerName = this.name.toLowerCase();
|
||||||
this.id = "mount:" + mount.get_root().get_uri();
|
this.id = 'mount:' + mount.get_root().get_uri();
|
||||||
},
|
},
|
||||||
|
|
||||||
iconFactory: function(size) {
|
iconFactory: function(size) {
|
||||||
let icon = this._mount.get_icon();
|
let icon = this._mount.get_icon();
|
||||||
return Shell.TextureCache.get_default().load_gicon(icon, size);
|
return St.TextureCache.get_default().load_gicon(icon, size);
|
||||||
},
|
},
|
||||||
|
|
||||||
launch: function() {
|
launch: function() {
|
||||||
@ -93,13 +93,26 @@ PlaceDeviceInfo.prototype = {
|
|||||||
if (!this.isRemovable())
|
if (!this.isRemovable())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._mount.unmount(0, null, Lang.bind(this, this._removeFinish), null);
|
if (this._mount.can_eject())
|
||||||
|
this._mount.eject(0, null, Lang.bind(this, this._removeFinish));
|
||||||
|
else
|
||||||
|
this._mount.unmount(0, null, Lang.bind(this, this._removeFinish));
|
||||||
},
|
},
|
||||||
|
|
||||||
_removeFinish: function(o, res, data) {
|
_removeFinish: function(o, res, data) {
|
||||||
this._mount.unmount_finish(res);
|
try {
|
||||||
|
if (this._mount.can_eject())
|
||||||
|
this._mount.eject_finish(res);
|
||||||
|
else
|
||||||
|
this._mount.unmount_finish(res);
|
||||||
|
} catch (e) {
|
||||||
|
let message = _("Failed to unmount '%s'").format(o.get_name());
|
||||||
|
Main.overview.infoBar.setMessage(message,
|
||||||
|
Lang.bind(this, this.remove),
|
||||||
|
_("Retry"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
function PlacesManager() {
|
function PlacesManager() {
|
||||||
@ -108,13 +121,13 @@ function PlacesManager() {
|
|||||||
|
|
||||||
PlacesManager.prototype = {
|
PlacesManager.prototype = {
|
||||||
_init: function() {
|
_init: function() {
|
||||||
let gconf = Shell.GConf.get_default();
|
let gconf = GConf.Client.get_default();
|
||||||
gconf.watch_directory(NAUTILUS_PREFS_DIR);
|
gconf.add_dir(NAUTILUS_PREFS_DIR, GConf.ClientPreloadType.PRELOAD_NONE);
|
||||||
|
|
||||||
this._defaultPlaces = [];
|
this._defaultPlaces = [];
|
||||||
this._mounts = [];
|
this._mounts = [];
|
||||||
this._bookmarks = [];
|
this._bookmarks = [];
|
||||||
this._isDesktopHome = false;
|
this._isDesktopHome = gconf.get_bool(DESKTOP_IS_HOME_KEY);
|
||||||
|
|
||||||
let homeFile = Gio.file_new_for_path (GLib.get_home_dir());
|
let homeFile = Gio.file_new_for_path (GLib.get_home_dir());
|
||||||
let homeUri = homeFile.get_uri();
|
let homeUri = homeFile.get_uri();
|
||||||
@ -122,7 +135,7 @@ PlacesManager.prototype = {
|
|||||||
let homeIcon = Shell.util_get_icon_for_uri (homeUri);
|
let homeIcon = Shell.util_get_icon_for_uri (homeUri);
|
||||||
this._home = new PlaceInfo('special:home', homeLabel,
|
this._home = new PlaceInfo('special:home', homeLabel,
|
||||||
function(size) {
|
function(size) {
|
||||||
return Shell.TextureCache.get_default().load_gicon(homeIcon, size);
|
return St.TextureCache.get_default().load_gicon(homeIcon, size);
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
Gio.app_info_launch_default_for_uri(homeUri, global.create_app_launch_context());
|
Gio.app_info_launch_default_for_uri(homeUri, global.create_app_launch_context());
|
||||||
@ -135,7 +148,7 @@ PlacesManager.prototype = {
|
|||||||
let desktopIcon = Shell.util_get_icon_for_uri (desktopUri);
|
let desktopIcon = Shell.util_get_icon_for_uri (desktopUri);
|
||||||
this._desktopMenu = new PlaceInfo('special:desktop', desktopLabel,
|
this._desktopMenu = new PlaceInfo('special:desktop', desktopLabel,
|
||||||
function(size) {
|
function(size) {
|
||||||
return Shell.TextureCache.get_default().load_gicon(desktopIcon, size);
|
return St.TextureCache.get_default().load_gicon(desktopIcon, size);
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
Gio.app_info_launch_default_for_uri(desktopUri, global.create_app_launch_context());
|
Gio.app_info_launch_default_for_uri(desktopUri, global.create_app_launch_context());
|
||||||
@ -143,7 +156,7 @@ PlacesManager.prototype = {
|
|||||||
|
|
||||||
this._connect = new PlaceInfo('special:connect', _("Connect to..."),
|
this._connect = new PlaceInfo('special:connect', _("Connect to..."),
|
||||||
function (size) {
|
function (size) {
|
||||||
return Shell.TextureCache.get_default().load_icon_name("applications-internet", size);
|
return St.TextureCache.get_default().load_icon_name('applications-internet', size);
|
||||||
},
|
},
|
||||||
function () {
|
function () {
|
||||||
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
|
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
|
||||||
@ -156,7 +169,7 @@ PlacesManager.prototype = {
|
|||||||
try {
|
try {
|
||||||
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('network-scheme.desktop');
|
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('network-scheme.desktop');
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
log("Cannot create \"Network\" item, .desktop file not found or corrupt.");
|
log('Cannot create "Network" item, .desktop file not found or corrupt.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,6 +185,7 @@ PlacesManager.prototype = {
|
|||||||
|
|
||||||
this._defaultPlaces.push(this._home);
|
this._defaultPlaces.push(this._home);
|
||||||
|
|
||||||
|
this._desktopMenuIndex = this._defaultPlaces.length;
|
||||||
if (!this._isDesktopHome)
|
if (!this._isDesktopHome)
|
||||||
this._defaultPlaces.push(this._desktopMenu);
|
this._defaultPlaces.push(this._desktopMenu);
|
||||||
|
|
||||||
@ -195,7 +209,7 @@ PlacesManager.prototype = {
|
|||||||
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
|
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
|
||||||
this._updateDevices();
|
this._updateDevices();
|
||||||
|
|
||||||
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), ".gtk-bookmarks"]);
|
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), '.gtk-bookmarks']);
|
||||||
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
||||||
let monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
|
let monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
|
||||||
this._bookmarkTimeoutId = 0;
|
this._bookmarkTimeoutId = 0;
|
||||||
@ -211,9 +225,8 @@ PlacesManager.prototype = {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
this._reloadBookmarks();
|
this._reloadBookmarks();
|
||||||
this._updateDesktopMenuVisibility();
|
|
||||||
|
|
||||||
gconf.connect('changed::' + DESKTOP_IS_HOME_KEY, Lang.bind(this, this._updateDesktopMenuVisibility));
|
gconf.notify_add(DESKTOP_IS_HOME_KEY, Lang.bind(this, this._updateDesktopMenuVisibility));
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -310,7 +323,7 @@ PlacesManager.prototype = {
|
|||||||
|
|
||||||
let item = new PlaceInfo('bookmark:' + bookmark, label,
|
let item = new PlaceInfo('bookmark:' + bookmark, label,
|
||||||
function(size) {
|
function(size) {
|
||||||
return Shell.TextureCache.get_default().load_gicon(icon, size);
|
return St.TextureCache.get_default().load_gicon(icon, size);
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
Gio.app_info_launch_default_for_uri(bookmark, global.create_app_launch_context());
|
Gio.app_info_launch_default_for_uri(bookmark, global.create_app_launch_context());
|
||||||
@ -324,9 +337,15 @@ PlacesManager.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateDesktopMenuVisibility: function() {
|
_updateDesktopMenuVisibility: function() {
|
||||||
let gconf = Shell.GConf.get_default();
|
let gconf = GConf.Client.get_default();
|
||||||
this._isDesktopHome = gconf.get_boolean(DESKTOP_IS_HOME_KEY);
|
this._isDesktopHome = gconf.get_boolean(DESKTOP_IS_HOME_KEY);
|
||||||
|
|
||||||
|
if (this._isDesktopHome)
|
||||||
|
this._removeById(this._defaultPlaces, 'special:desktop');
|
||||||
|
else
|
||||||
|
this._defaultPlaces.splice(this._desktopMenuIndex, 0,
|
||||||
|
this._desktopMenu);
|
||||||
|
|
||||||
/* See comment in _updateDevices for explanation why there are two signals. */
|
/* See comment in _updateDevices for explanation why there are two signals. */
|
||||||
this.emit('defaults-updated');
|
this.emit('defaults-updated');
|
||||||
this.emit('places-updated');
|
this.emit('places-updated');
|
||||||
@ -353,13 +372,13 @@ PlacesManager.prototype = {
|
|||||||
return this._mounts;
|
return this._mounts;
|
||||||
},
|
},
|
||||||
|
|
||||||
_lookupById: function(sourceArray, id) {
|
_lookupIndexById: function(sourceArray, id) {
|
||||||
for (let i = 0; i < sourceArray.length; i++) {
|
for (let i = 0; i < sourceArray.length; i++) {
|
||||||
let place = sourceArray[i];
|
let place = sourceArray[i];
|
||||||
if (place.id == id)
|
if (place.id == id)
|
||||||
return place;
|
return i;
|
||||||
}
|
}
|
||||||
return null;
|
return -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
lookupPlaceById: function(id) {
|
lookupPlaceById: function(id) {
|
||||||
@ -372,7 +391,11 @@ PlacesManager.prototype = {
|
|||||||
sourceArray = this._mounts;
|
sourceArray = this._mounts;
|
||||||
else if (type == 'bookmark')
|
else if (type == 'bookmark')
|
||||||
sourceArray = this._bookmarks;
|
sourceArray = this._bookmarks;
|
||||||
return this._lookupById(sourceArray, id);
|
return sourceArray[this._lookupIndexById(sourceArray, id)];
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeById: function(sourceArray, id) {
|
||||||
|
sourceArray.splice(this._lookupIndexById(sourceArray, id), 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -391,31 +414,44 @@ DashPlaceDisplayItem.prototype = {
|
|||||||
this.name = info.name;
|
this.name = info.name;
|
||||||
this._info = info;
|
this._info = info;
|
||||||
this._icon = info.iconFactory(PLACES_ICON_SIZE);
|
this._icon = info.iconFactory(PLACES_ICON_SIZE);
|
||||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
|
||||||
spacing: 4 });
|
this.actor = new St.Clickable({ style_class: 'places-item',
|
||||||
let text = new St.Button({ style_class: 'places-item',
|
reactive: true,
|
||||||
label: info.name,
|
x_align: St.Align.START,
|
||||||
x_align: St.Align.START });
|
x_fill: true });
|
||||||
text.connect('clicked', Lang.bind(this, this._onClicked));
|
|
||||||
let iconBox = new St.Bin({ child: this._icon, reactive: true });
|
let box = new St.BoxLayout({ style_class: 'places-item-box' });
|
||||||
iconBox.connect('button-release-event',
|
this.actor.set_child(box);
|
||||||
Lang.bind(this, this._onClicked));
|
|
||||||
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
|
let bin = new St.Bin({ child: this._icon });
|
||||||
this.actor.append(text, Big.BoxPackFlags.EXPAND);
|
box.add(bin);
|
||||||
|
|
||||||
|
let text = new St.Label({ text: info.name });
|
||||||
|
box.add(text, { expand: true, x_fill: true });
|
||||||
|
|
||||||
if (info.isRemovable()) {
|
if (info.isRemovable()) {
|
||||||
let removeIcon = Shell.TextureCache.get_default().load_icon_name ('media-eject', PLACES_ICON_SIZE);
|
let removeIcon = St.TextureCache.get_default().load_icon_name ('media-eject', PLACES_ICON_SIZE);
|
||||||
let removeIconBox = new St.Button({ child: removeIcon,
|
let removeIconBox = new St.Clickable({ child: removeIcon,
|
||||||
reactive: true });
|
reactive: true });
|
||||||
this.actor.append(removeIconBox, Big.BoxPackFlags.NONE);
|
box.add(removeIconBox);
|
||||||
removeIconBox.connect('clicked',
|
removeIconBox.connect('clicked',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this._info.remove();
|
this._info.remove();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||||
|
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
let draggable = DND.makeDraggable(this.actor);
|
this._draggable = DND.makeDraggable(this.actor);
|
||||||
|
this._draggable.connect('drag-begin',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
Main.overview.beginItemDrag(this);
|
||||||
|
}));
|
||||||
|
this._draggable.connect('drag-end',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
Main.overview.endItemDrag(this);
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onClicked: function(b) {
|
_onClicked: function(b) {
|
||||||
@ -449,28 +485,12 @@ DashPlaceDisplay.prototype = {
|
|||||||
// look better in that there would be an even number of items left+right,
|
// look better in that there would be an even number of items left+right,
|
||||||
// but it seems like we want some sort of differentiation between actions
|
// but it seems like we want some sort of differentiation between actions
|
||||||
// like "Connect to server..." and regular folders
|
// like "Connect to server..." and regular folders
|
||||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
this.actor = new St.Table({ style_class: 'places-section',
|
||||||
spacing: 4 });
|
homogeneous: true });
|
||||||
this._leftBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
|
|
||||||
this.actor.append(this._leftBox, Big.BoxPackFlags.EXPAND);
|
|
||||||
this._rightBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
|
|
||||||
this.actor.append(this._rightBox, Big.BoxPackFlags.EXPAND);
|
|
||||||
|
|
||||||
// Subdivide left into actions and devices
|
this._defaultsList = [];
|
||||||
this._actionsBox = new St.BoxLayout({ style_class: 'places-actions',
|
this._bookmarksList = [];
|
||||||
vertical: true });
|
this._mountsList = [];
|
||||||
|
|
||||||
this._devBox = new St.BoxLayout({ style_class: 'places-actions',
|
|
||||||
name: 'placesDevices',
|
|
||||||
vertical: true });
|
|
||||||
|
|
||||||
this._dirsBox = new St.BoxLayout({ style_class: 'places-actions',
|
|
||||||
vertical: true });
|
|
||||||
|
|
||||||
this._leftBox.append(this._actionsBox, Big.BoxPackFlags.NONE);
|
|
||||||
this._leftBox.append(this._devBox, Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
this._rightBox.append(this._dirsBox, Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
Main.placesManager.connect('defaults-updated', Lang.bind(this, this._updateDefaults));
|
Main.placesManager.connect('defaults-updated', Lang.bind(this, this._updateDefaults));
|
||||||
Main.placesManager.connect('bookmarks-updated', Lang.bind(this, this._updateBookmarks));
|
Main.placesManager.connect('bookmarks-updated', Lang.bind(this, this._updateBookmarks));
|
||||||
@ -482,27 +502,40 @@ DashPlaceDisplay.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateDefaults: function() {
|
_updateDefaults: function() {
|
||||||
this._actionsBox.destroy_children();
|
for (let i = 0; i < this._defaultsList.length; i++)
|
||||||
|
this._defaultsList[i].destroy();
|
||||||
|
|
||||||
|
this._defaultsList = [];
|
||||||
let places = Main.placesManager.getDefaultPlaces();
|
let places = Main.placesManager.getDefaultPlaces();
|
||||||
for (let i = 0; i < places.length; i++)
|
for (let i = 0; i < places.length; i++) {
|
||||||
this._actionsBox.add(new DashPlaceDisplayItem(places[i]).actor);
|
this._defaultsList[i] = new DashPlaceDisplayItem(places[i]).actor;
|
||||||
|
this.actor.add(this._defaultsList[i], {row: i, col: 0});
|
||||||
|
}
|
||||||
|
this._updateMounts();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateMounts: function() {
|
_updateMounts: function() {
|
||||||
this._devBox.destroy_children();
|
for (let i = 0; i < this._mountsList.length; i++)
|
||||||
|
this._mountsList[i].destroy();
|
||||||
|
|
||||||
|
this._mountsList = [];
|
||||||
let places = Main.placesManager.getMounts();
|
let places = Main.placesManager.getMounts();
|
||||||
for (let i = 0; i < places.length; i++)
|
for (let i = 0; i < places.length; i++) {
|
||||||
this._devBox.add(new DashPlaceDisplayItem(places[i]).actor);
|
this._mountsList[i] = new DashPlaceDisplayItem(places[i]).actor;
|
||||||
|
this.actor.add(this._mountsList[i], {row: this._defaultsList.length + i, col: 0});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateBookmarks: function() {
|
_updateBookmarks: function() {
|
||||||
this._dirsBox.destroy_children();
|
for (let i = 0; i < this._bookmarksList.length; i++)
|
||||||
|
this._bookmarksList[i].destroy();
|
||||||
|
|
||||||
|
this._bookmarksList = [];
|
||||||
let places = Main.placesManager.getBookmarks();
|
let places = Main.placesManager.getBookmarks();
|
||||||
for (let i = 0; i < places.length; i ++)
|
for (let i = 0; i < places.length; i ++) {
|
||||||
this._dirsBox.add(new DashPlaceDisplayItem(places[i]).actor);
|
this._bookmarksList[i] = new DashPlaceDisplayItem(places[i]).actor;
|
||||||
|
this.actor.add(this._bookmarksList[i], {row: i, col: 1});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -516,7 +549,7 @@ PlaceSearchProvider.prototype = {
|
|||||||
__proto__: Search.SearchProvider.prototype,
|
__proto__: Search.SearchProvider.prototype,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
Search.SearchProvider.prototype._init.call(this, _("PLACES"));
|
Search.SearchProvider.prototype._init.call(this, _("PLACES & DEVICES"));
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMeta: function(resultId) {
|
getResultMeta: function(resultId) {
|
||||||
@ -571,4 +604,4 @@ PlaceSearchProvider.prototype = {
|
|||||||
let places = previousResults.map(function (id) { return Main.placesManager.lookupPlaceById(id); });
|
let places = previousResults.map(function (id) { return Main.placesManager.lookupPlaceById(id); });
|
||||||
return this._searchPlaces(places, terms);
|
return this._searchPlaces(places, terms);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
564
js/ui/popupMenu.js
Normal file
@ -0,0 +1,564 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Cairo = imports.cairo;
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const BoxPointer = imports.ui.boxpointer;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const POPUP_ANIMATION_TIME = 0.1;
|
||||||
|
|
||||||
|
function PopupBaseMenuItem(reactive) {
|
||||||
|
this._init(reactive);
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupBaseMenuItem.prototype = {
|
||||||
|
_init: function (reactive) {
|
||||||
|
this.actor = new St.Bin({ style_class: 'popup-menu-item',
|
||||||
|
reactive: reactive,
|
||||||
|
track_hover: reactive,
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: true,
|
||||||
|
x_align: St.Align.START });
|
||||||
|
this.actor._delegate = this;
|
||||||
|
this.active = false;
|
||||||
|
|
||||||
|
if (reactive) {
|
||||||
|
this.actor.connect('button-release-event', Lang.bind(this, function (actor, event) {
|
||||||
|
this.emit('activate', event);
|
||||||
|
}));
|
||||||
|
this.actor.connect('notify::hover', Lang.bind(this, this._hoverChanged));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_hoverChanged: function (actor) {
|
||||||
|
this.setActive(actor.hover);
|
||||||
|
},
|
||||||
|
|
||||||
|
activate: function (event) {
|
||||||
|
this.emit('activate', event);
|
||||||
|
},
|
||||||
|
|
||||||
|
setActive: function (active) {
|
||||||
|
let activeChanged = active != this.active;
|
||||||
|
|
||||||
|
if (activeChanged) {
|
||||||
|
this.active = active;
|
||||||
|
if (active)
|
||||||
|
this.actor.add_style_pseudo_class('active');
|
||||||
|
else
|
||||||
|
this.actor.remove_style_pseudo_class('active');
|
||||||
|
this.emit('active-changed', active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Signals.addSignalMethods(PopupBaseMenuItem.prototype);
|
||||||
|
|
||||||
|
function PopupMenuItem(text) {
|
||||||
|
this._init(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupMenuItem.prototype = {
|
||||||
|
__proto__: PopupBaseMenuItem.prototype,
|
||||||
|
|
||||||
|
_init: function (text) {
|
||||||
|
PopupBaseMenuItem.prototype._init.call(this, true);
|
||||||
|
|
||||||
|
this.label = new St.Label({ text: text });
|
||||||
|
this.actor.set_child(this.label);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function PopupSeparatorMenuItem() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupSeparatorMenuItem.prototype = {
|
||||||
|
__proto__: PopupBaseMenuItem.prototype,
|
||||||
|
|
||||||
|
_init: function () {
|
||||||
|
PopupBaseMenuItem.prototype._init.call(this, false);
|
||||||
|
|
||||||
|
this._drawingArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' });
|
||||||
|
this.actor.set_child(this._drawingArea);
|
||||||
|
this._drawingArea.connect('repaint', Lang.bind(this, this._onRepaint));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onRepaint: function(area) {
|
||||||
|
let cr = area.get_context();
|
||||||
|
let themeNode = area.get_theme_node();
|
||||||
|
let [width, height] = area.get_surface_size();
|
||||||
|
let found, margin, gradientHeight;
|
||||||
|
[found, margin] = themeNode.get_length('-margin-horizontal', false);
|
||||||
|
[found, gradientHeight] = themeNode.get_length('-gradient-height', false);
|
||||||
|
let startColor = new Clutter.Color();
|
||||||
|
themeNode.get_color('-gradient-start', false, startColor);
|
||||||
|
let endColor = new Clutter.Color();
|
||||||
|
themeNode.get_color('-gradient-end', false, endColor);
|
||||||
|
|
||||||
|
let gradientWidth = (width - margin * 2);
|
||||||
|
let gradientOffset = (height - gradientHeight) / 2;
|
||||||
|
let pattern = new Cairo.LinearGradient(margin, gradientOffset, width - margin, gradientOffset + gradientHeight);
|
||||||
|
pattern.addColorStopRGBA(0, startColor.red / 255, startColor.green / 255, startColor.blue / 255, startColor.alpha / 255);
|
||||||
|
pattern.addColorStopRGBA(0.5, endColor.red / 255, endColor.green / 255, endColor.blue / 255, endColor.alpha / 255);
|
||||||
|
pattern.addColorStopRGBA(1, startColor.red / 255, startColor.green / 255, startColor.blue / 255, startColor.alpha / 255);
|
||||||
|
cr.setSource(pattern);
|
||||||
|
cr.rectangle(margin, gradientOffset, gradientWidth, gradientHeight);
|
||||||
|
cr.fill();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function PopupImageMenuItem(text, iconName, alwaysShowImage) {
|
||||||
|
this._init(text, iconName, alwaysShowImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to instantiate a GtkImageMenuItem so it
|
||||||
|
// hooks up its properties on the GtkSettings
|
||||||
|
var _gtkImageMenuItemCreated = false;
|
||||||
|
|
||||||
|
PopupImageMenuItem.prototype = {
|
||||||
|
__proto__: PopupBaseMenuItem.prototype,
|
||||||
|
|
||||||
|
_init: function (text, iconName, alwaysShowImage) {
|
||||||
|
PopupBaseMenuItem.prototype._init.call(this, true);
|
||||||
|
|
||||||
|
if (!_gtkImageMenuItemCreated) {
|
||||||
|
let menuItem = new Gtk.ImageMenuItem();
|
||||||
|
menuItem.destroy();
|
||||||
|
_gtkImageMenuItemCreated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._alwaysShowImage = alwaysShowImage;
|
||||||
|
this._iconName = iconName;
|
||||||
|
this._size = 16;
|
||||||
|
|
||||||
|
let box = new St.BoxLayout({ style_class: 'popup-image-menu-item' });
|
||||||
|
this.actor.set_child(box);
|
||||||
|
this._imageBin = new St.Bin({ width: this._size, height: this._size });
|
||||||
|
box.add(this._imageBin, { y_fill: false });
|
||||||
|
box.add(new St.Label({ text: text }), { expand: true });
|
||||||
|
|
||||||
|
if (!alwaysShowImage) {
|
||||||
|
let settings = Gtk.Settings.get_default();
|
||||||
|
settings.connect('notify::gtk-menu-images', Lang.bind(this, this._onMenuImagesChanged));
|
||||||
|
}
|
||||||
|
this._onMenuImagesChanged();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMenuImagesChanged: function() {
|
||||||
|
let show;
|
||||||
|
if (this._alwaysShowImage) {
|
||||||
|
show = true;
|
||||||
|
} else {
|
||||||
|
let settings = Gtk.Settings.get_default();
|
||||||
|
show = settings.gtk_menu_images;
|
||||||
|
}
|
||||||
|
if (!show) {
|
||||||
|
this._imageBin.hide();
|
||||||
|
} else {
|
||||||
|
let img = St.TextureCache.get_default().load_icon_name(this._iconName, this._size);
|
||||||
|
this._imageBin.set_child(img);
|
||||||
|
this._imageBin.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function mod(a, b) {
|
||||||
|
return (a + b) % b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findNextInCycle(items, current, direction) {
|
||||||
|
let cur;
|
||||||
|
|
||||||
|
if (items.length == 0)
|
||||||
|
return current;
|
||||||
|
else if (items.length == 1)
|
||||||
|
return items[0];
|
||||||
|
|
||||||
|
if (current)
|
||||||
|
cur = items.indexOf(current);
|
||||||
|
else if (direction == 1)
|
||||||
|
cur = items.length - 1;
|
||||||
|
else
|
||||||
|
cur = 0;
|
||||||
|
|
||||||
|
return items[mod(cur + direction, items.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
function PopupMenu(sourceActor, alignment, arrowSide, gap) {
|
||||||
|
this._init(sourceActor, alignment, arrowSide, gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupMenu.prototype = {
|
||||||
|
_init: function(sourceActor, alignment, arrowSide, gap) {
|
||||||
|
this.sourceActor = sourceActor;
|
||||||
|
this._alignment = alignment;
|
||||||
|
this._arrowSide = arrowSide;
|
||||||
|
this._gap = gap;
|
||||||
|
|
||||||
|
this._boxPointer = new BoxPointer.BoxPointer(arrowSide,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: true,
|
||||||
|
x_align: St.Align.START });
|
||||||
|
this.actor = this._boxPointer.actor;
|
||||||
|
this.actor.style_class = 'popup-menu-boxpointer';
|
||||||
|
this._box = new St.BoxLayout({ style_class: 'popup-menu-content',
|
||||||
|
vertical: true });
|
||||||
|
this._boxPointer.bin.set_child(this._box);
|
||||||
|
this.actor.add_style_class_name('popup-menu');
|
||||||
|
|
||||||
|
this.isOpen = false;
|
||||||
|
this._activeMenuItem = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
addAction: function(title, callback) {
|
||||||
|
var menuItem = new PopupMenuItem(title);
|
||||||
|
this.addMenuItem(menuItem);
|
||||||
|
menuItem.connect('activate', Lang.bind(this, function (menuItem, event) {
|
||||||
|
callback(event);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
addMenuItem: function(menuItem) {
|
||||||
|
this._box.add(menuItem.actor);
|
||||||
|
menuItem._activeChangeId = menuItem.connect('active-changed', Lang.bind(this, function (menuItem, active) {
|
||||||
|
if (active && this._activeMenuItem != menuItem) {
|
||||||
|
if (this._activeMenuItem)
|
||||||
|
this._activeMenuItem.setActive(false);
|
||||||
|
this._activeMenuItem = menuItem;
|
||||||
|
this.emit('active-changed', menuItem);
|
||||||
|
} else if (!active && this._activeMenuItem == menuItem) {
|
||||||
|
this._activeMenuItem = null;
|
||||||
|
this.emit('active-changed', null);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
menuItem._activateId = menuItem.connect('activate', Lang.bind(this, function (menuItem, event) {
|
||||||
|
this.emit('activate', menuItem);
|
||||||
|
this.close();
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
addActor: function(actor) {
|
||||||
|
this._box.add(actor);
|
||||||
|
},
|
||||||
|
|
||||||
|
getMenuItems: function() {
|
||||||
|
return this._box.get_children().map(function (actor) { return actor._delegate; });
|
||||||
|
},
|
||||||
|
|
||||||
|
removeAll: function() {
|
||||||
|
let children = this.getMenuItems();
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
let item = children[i];
|
||||||
|
if (item._activeChangeId != 0)
|
||||||
|
item.disconnect(item._activeChangeId);
|
||||||
|
if (item._activateId != 0)
|
||||||
|
item.disconnect(item._activateId);
|
||||||
|
item.actor.destroy();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setArrowOrigin: function(origin) {
|
||||||
|
this._boxPointer.setArrowOrigin(origin);
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function() {
|
||||||
|
if (this.isOpen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.emit('opening');
|
||||||
|
|
||||||
|
let primary = global.get_primary_monitor();
|
||||||
|
|
||||||
|
// We need to show it now to force an allocation,
|
||||||
|
// so that we can query the correct size.
|
||||||
|
this.actor.show();
|
||||||
|
|
||||||
|
// Position correctly relative to the sourceActor
|
||||||
|
let [sourceX, sourceY] = this.sourceActor.get_transformed_position();
|
||||||
|
let [sourceWidth, sourceHeight] = this.sourceActor.get_transformed_size();
|
||||||
|
|
||||||
|
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
||||||
|
|
||||||
|
let menuX, menuY;
|
||||||
|
let menuWidth = natWidth, menuHeight = natHeight;
|
||||||
|
|
||||||
|
// Position the non-pointing axis
|
||||||
|
switch (this._arrowSide) {
|
||||||
|
case St.Side.TOP:
|
||||||
|
menuY = sourceY + sourceHeight + this._gap;
|
||||||
|
break;
|
||||||
|
case St.Side.BOTTOM:
|
||||||
|
menuY = sourceY - menuHeight - this._gap;
|
||||||
|
break;
|
||||||
|
case St.Side.LEFT:
|
||||||
|
menuX = sourceX + sourceWidth + this._gap;
|
||||||
|
break;
|
||||||
|
case St.Side.RIGHT:
|
||||||
|
menuX = sourceX - menuWidth - this._gap;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now align and position the pointing axis, making sure
|
||||||
|
// it fits on screen
|
||||||
|
switch (this._arrowSide) {
|
||||||
|
case St.Side.TOP:
|
||||||
|
case St.Side.BOTTOM:
|
||||||
|
switch (this._alignment) {
|
||||||
|
case St.Align.START:
|
||||||
|
menuX = sourceX;
|
||||||
|
break;
|
||||||
|
case St.Align.MIDDLE:
|
||||||
|
menuX = sourceX - Math.floor((menuWidth - sourceWidth) / 2);
|
||||||
|
break;
|
||||||
|
case St.Align.END:
|
||||||
|
menuX = sourceX - (menuWidth - sourceWidth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
menuX = Math.min(menuX, primary.x + primary.width - menuWidth);
|
||||||
|
menuX = Math.max(menuX, primary.x);
|
||||||
|
|
||||||
|
this._boxPointer.setArrowOrigin((sourceX - menuX) + Math.floor(sourceWidth / 2));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case St.Side.LEFT:
|
||||||
|
case St.Side.RIGHT:
|
||||||
|
switch (this._alignment) {
|
||||||
|
case St.Align.START:
|
||||||
|
menuY = sourceY;
|
||||||
|
break;
|
||||||
|
case St.Align.MIDDLE:
|
||||||
|
menuY = sourceY - Math.floor((menuHeight - sourceHeight) / 2);
|
||||||
|
break;
|
||||||
|
case St.Align.END:
|
||||||
|
menuY = sourceY - (menuHeight - sourceHeight);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
menuY = Math.min(menuY, primary.y + primary.height - menuHeight);
|
||||||
|
menuY = Math.max(menuY, primary.y);
|
||||||
|
|
||||||
|
this._boxPointer.setArrowOrigin((sourceY - menuY) + Math.floor(sourceHeight / 2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually set the position
|
||||||
|
this.actor.x = Math.floor(menuX);
|
||||||
|
this.actor.y = Math.floor(menuY);
|
||||||
|
|
||||||
|
// Now show it
|
||||||
|
this.actor.opacity = 0;
|
||||||
|
this.actor.reactive = true;
|
||||||
|
Tweener.addTween(this.actor, { opacity: 255,
|
||||||
|
transition: "easeOutQuad",
|
||||||
|
time: POPUP_ANIMATION_TIME });
|
||||||
|
this.isOpen = true;
|
||||||
|
this.emit('open-state-changed', true);
|
||||||
|
},
|
||||||
|
|
||||||
|
close: function() {
|
||||||
|
if (!this.isOpen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.actor.reactive = false;
|
||||||
|
Tweener.addTween(this.actor, { opacity: 0,
|
||||||
|
transition: "easeOutQuad",
|
||||||
|
time: POPUP_ANIMATION_TIME,
|
||||||
|
onComplete: Lang.bind(this, function () { this.actor.hide(); })});
|
||||||
|
if (this._activeMenuItem)
|
||||||
|
this._activeMenuItem.setActive(false);
|
||||||
|
this.isOpen = false;
|
||||||
|
this.emit('open-state-changed', false);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
toggle: function() {
|
||||||
|
if (this.isOpen)
|
||||||
|
this.close();
|
||||||
|
else
|
||||||
|
this.open();
|
||||||
|
},
|
||||||
|
|
||||||
|
handleKeyPress: function(event) {
|
||||||
|
if (event.get_key_symbol() == Clutter.space ||
|
||||||
|
event.get_key_symbol() == Clutter.Return) {
|
||||||
|
if (this._activeMenuItem)
|
||||||
|
this._activeMenuItem.activate(event);
|
||||||
|
return true;
|
||||||
|
} else if (event.get_key_symbol() == Clutter.Down
|
||||||
|
|| event.get_key_symbol() == Clutter.Up) {
|
||||||
|
let items = this._box.get_children().filter(function (child) { return child.visible && child.reactive; });
|
||||||
|
let current = this._activeMenuItem ? this._activeMenuItem.actor : null;
|
||||||
|
let direction = event.get_key_symbol() == Clutter.Down ? 1 : -1;
|
||||||
|
|
||||||
|
let next = findNextInCycle(items, current, direction);
|
||||||
|
if (next) {
|
||||||
|
next._delegate.setActive(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Signals.addSignalMethods(PopupMenu.prototype);
|
||||||
|
|
||||||
|
/* Basic implementation of a menu manager.
|
||||||
|
* Call addMenu to add menus
|
||||||
|
*/
|
||||||
|
function PopupMenuManager(owner) {
|
||||||
|
this._init(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupMenuManager.prototype = {
|
||||||
|
_init: function(owner) {
|
||||||
|
this._owner = owner;
|
||||||
|
this.grabbed = false;
|
||||||
|
|
||||||
|
this._eventCaptureId = 0;
|
||||||
|
this._enterEventId = 0;
|
||||||
|
this._leaveEventId = 0;
|
||||||
|
this._activeMenu = null;
|
||||||
|
this._menus = [];
|
||||||
|
this._delayedMenus = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
addMenu: function(menu, noGrab) {
|
||||||
|
this._menus.push(menu);
|
||||||
|
menu.connect('open-state-changed', Lang.bind(this, this._onMenuOpenState));
|
||||||
|
menu.connect('activate', Lang.bind(this, this._onMenuActivated));
|
||||||
|
|
||||||
|
let source = menu.sourceActor;
|
||||||
|
if (source) {
|
||||||
|
source.connect('enter-event', Lang.bind(this, this._onMenuSourceEnter, menu));
|
||||||
|
if (!noGrab)
|
||||||
|
source.connect('button-press-event', Lang.bind(this, this._onMenuSourcePress, menu));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
grab: function() {
|
||||||
|
Main.pushModal(this._owner.actor);
|
||||||
|
|
||||||
|
this._eventCaptureId = global.stage.connect('captured-event', Lang.bind(this, this._onEventCapture));
|
||||||
|
// captured-event doesn't see enter/leave events
|
||||||
|
this._enterEventId = global.stage.connect('enter-event', Lang.bind(this, this._onEventCapture));
|
||||||
|
this._leaveEventId = global.stage.connect('leave-event', Lang.bind(this, this._onEventCapture));
|
||||||
|
|
||||||
|
this.grabbed = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
ungrab: function() {
|
||||||
|
global.stage.disconnect(this._eventCaptureId);
|
||||||
|
this._eventCaptureId = 0;
|
||||||
|
global.stage.disconnect(this._enterEventId);
|
||||||
|
this._enterEventId = 0;
|
||||||
|
global.stage.disconnect(this._leaveEventId);
|
||||||
|
this._leaveEventId = 0;
|
||||||
|
|
||||||
|
Main.popModal(this._owner.actor);
|
||||||
|
|
||||||
|
this.grabbed = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMenuOpenState: function(menu, open) {
|
||||||
|
if (!open && menu == this._activeMenu)
|
||||||
|
this._activeMenu = null;
|
||||||
|
else if (open)
|
||||||
|
this._activeMenu = menu;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMenuSourceEnter: function(actor, event, menu) {
|
||||||
|
if (!this.grabbed || menu == this._activeMenu)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (this._activeMenu != null)
|
||||||
|
this._activeMenu.close();
|
||||||
|
menu.open();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMenuSourcePress: function(actor, event, menu) {
|
||||||
|
if (this.grabbed)
|
||||||
|
return false;
|
||||||
|
this.grab();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMenuActivated: function(menu, item) {
|
||||||
|
if (this.grabbed)
|
||||||
|
this.ungrab();
|
||||||
|
},
|
||||||
|
|
||||||
|
_eventIsOnActiveMenu: function(event) {
|
||||||
|
let src = event.get_source();
|
||||||
|
return this._activeMenu != null
|
||||||
|
&& (this._activeMenu.actor.contains(src) ||
|
||||||
|
this._activeMenu.sourceActor.contains(src));
|
||||||
|
},
|
||||||
|
|
||||||
|
_eventIsOnAnyMenuSource: function(event) {
|
||||||
|
let src = event.get_source();
|
||||||
|
for (let i = 0; i < this._menus.length; i++) {
|
||||||
|
if (this._menus[i].sourceActor.contains(src))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onEventCapture: function(actor, event) {
|
||||||
|
if (!this.grabbed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (this._owner.menuEventFilter &&
|
||||||
|
this._owner.menuEventFilter(event))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
let activeMenuContains = this._eventIsOnActiveMenu(event);
|
||||||
|
let eventType = event.type();
|
||||||
|
if (eventType == Clutter.EventType.BUTTON_RELEASE) {
|
||||||
|
if (activeMenuContains) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this._closeMenu();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if ((eventType == Clutter.EventType.BUTTON_PRESS && !activeMenuContains)
|
||||||
|
|| (eventType == Clutter.EventType.KEY_PRESS && event.get_key_symbol() == Clutter.Escape)) {
|
||||||
|
this._closeMenu();
|
||||||
|
return true;
|
||||||
|
} else if (eventType == Clutter.EventType.KEY_PRESS
|
||||||
|
&& this._activeMenu != null
|
||||||
|
&& this._activeMenu.handleKeyPress(event)) {
|
||||||
|
return true;
|
||||||
|
} else if (eventType == Clutter.EventType.KEY_PRESS
|
||||||
|
&& this._activeMenu != null
|
||||||
|
&& (event.get_key_symbol() == Clutter.Left
|
||||||
|
|| event.get_key_symbol() == Clutter.Right)) {
|
||||||
|
let direction = event.get_key_symbol() == Clutter.Right ? 1 : -1;
|
||||||
|
let next = findNextInCycle(this._menus, this._activeMenu, direction);
|
||||||
|
if (next != this._activeMenu) {
|
||||||
|
this._activeMenu.close();
|
||||||
|
next.open();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else if (activeMenuContains || this._eventIsOnAnyMenuSource(event)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_closeMenu: function() {
|
||||||
|
if (this._activeMenu != null)
|
||||||
|
this._activeMenu.close();
|
||||||
|
this.ungrab();
|
||||||
|
}
|
||||||
|
};
|
@ -1,12 +1,12 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
|
const St = imports.gi.St;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Gettext = imports.gettext.domain('gnome-shell');
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
@ -14,19 +14,15 @@ const _ = Gettext.gettext;
|
|||||||
|
|
||||||
const Lightbox = imports.ui.lightbox;
|
const Lightbox = imports.ui.lightbox;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const BOX_BACKGROUND_COLOR = new Clutter.Color();
|
|
||||||
BOX_BACKGROUND_COLOR.from_pixel(0x000000cc);
|
|
||||||
|
|
||||||
const BOX_TEXT_COLOR = new Clutter.Color();
|
|
||||||
BOX_TEXT_COLOR.from_pixel(0xffffffff);
|
|
||||||
|
|
||||||
const DIALOG_WIDTH = 320;
|
|
||||||
const DIALOG_PADDING = 6;
|
|
||||||
const ICON_SIZE = 24;
|
|
||||||
const ICON_BOX_SIZE = 36;
|
|
||||||
const MAX_FILE_DELETED_BEFORE_INVALID = 10;
|
const MAX_FILE_DELETED_BEFORE_INVALID = 10;
|
||||||
|
|
||||||
|
const HISTORY_KEY = 'command-history';
|
||||||
|
const HISTORY_LIMIT = 512;
|
||||||
|
|
||||||
|
const DIALOG_FADE_TIME = 0.1;
|
||||||
|
|
||||||
function CommandCompleter() {
|
function CommandCompleter() {
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
@ -35,6 +31,7 @@ CommandCompleter.prototype = {
|
|||||||
_init : function() {
|
_init : function() {
|
||||||
this._changedCount = 0;
|
this._changedCount = 0;
|
||||||
this._paths = GLib.getenv('PATH').split(':');
|
this._paths = GLib.getenv('PATH').split(':');
|
||||||
|
this._paths.push(GLib.get_home_dir());
|
||||||
this._valid = false;
|
this._valid = false;
|
||||||
this._updateInProgress = false;
|
this._updateInProgress = false;
|
||||||
this._childs = new Array(this._paths.length);
|
this._childs = new Array(this._paths.length);
|
||||||
@ -42,7 +39,14 @@ CommandCompleter.prototype = {
|
|||||||
for (let i = 0; i < this._paths.length; i++) {
|
for (let i = 0; i < this._paths.length; i++) {
|
||||||
this._childs[i] = [];
|
this._childs[i] = [];
|
||||||
let file = Gio.file_new_for_path(this._paths[i]);
|
let file = Gio.file_new_for_path(this._paths[i]);
|
||||||
let info = file.query_info(Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE, null);
|
let info;
|
||||||
|
try {
|
||||||
|
info = file.query_info(Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE, null);
|
||||||
|
} catch (e) {
|
||||||
|
// FIXME catchall
|
||||||
|
this._paths[i] = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (info.get_attribute_uint32(Gio.FILE_ATTRIBUTE_STANDARD_TYPE) != Gio.FileType.DIRECTORY)
|
if (info.get_attribute_uint32(Gio.FILE_ATTRIBUTE_STANDARD_TYPE) != Gio.FileType.DIRECTORY)
|
||||||
continue;
|
continue;
|
||||||
@ -50,15 +54,18 @@ CommandCompleter.prototype = {
|
|||||||
this._paths[i] = file.get_path();
|
this._paths[i] = file.get_path();
|
||||||
this._monitors[i] = file.monitor_directory(Gio.FileMonitorFlags.NONE, null);
|
this._monitors[i] = file.monitor_directory(Gio.FileMonitorFlags.NONE, null);
|
||||||
if (this._monitors[i] != null) {
|
if (this._monitors[i] != null) {
|
||||||
this._monitors[i].connect("changed", Lang.bind(this, this._onChanged));
|
this._monitors[i].connect('changed', Lang.bind(this, this._onChanged));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this._paths = this._paths.filter(function(a) {
|
||||||
|
return a != null;
|
||||||
|
});
|
||||||
this._update(0);
|
this._update(0);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onGetEnumerateComplete : function(obj, res) {
|
_onGetEnumerateComplete : function(obj, res) {
|
||||||
this._enumerator = obj.enumerate_children_finish(res);
|
this._enumerator = obj.enumerate_children_finish(res);
|
||||||
this._enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, Lang.bind(this, this._onNextFileComplete), null);
|
this._enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, Lang.bind(this, this._onNextFileComplete));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onNextFileComplete : function(obj, res) {
|
_onNextFileComplete : function(obj, res) {
|
||||||
@ -67,7 +74,7 @@ CommandCompleter.prototype = {
|
|||||||
this._childs[this._i].push(files[i].get_name());
|
this._childs[this._i].push(files[i].get_name());
|
||||||
}
|
}
|
||||||
if (files.length) {
|
if (files.length) {
|
||||||
this._enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, Lang.bind(this, this._onNextFileComplete), null);
|
this._enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, Lang.bind(this, this._onNextFileComplete));
|
||||||
} else {
|
} else {
|
||||||
this._enumerator.close(null);
|
this._enumerator.close(null);
|
||||||
this._enumerator = null;
|
this._enumerator = null;
|
||||||
@ -94,7 +101,7 @@ CommandCompleter.prototype = {
|
|||||||
}
|
}
|
||||||
let file = Gio.file_new_for_path(this._paths[i]);
|
let file = Gio.file_new_for_path(this._paths[i]);
|
||||||
this._childs[this._i] = [];
|
this._childs[this._i] = [];
|
||||||
file.enumerate_children_async(Gio.FILE_ATTRIBUTE_STANDARD_NAME, Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_LOW, null, Lang.bind(this, this._onGetEnumerateComplete), null);
|
file.enumerate_children_async(Gio.FILE_ATTRIBUTE_STANDARD_NAME, Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_LOW, null, Lang.bind(this, this._onGetEnumerateComplete));
|
||||||
},
|
},
|
||||||
|
|
||||||
_onChanged : function(m, f, of, type) {
|
_onChanged : function(m, f, of, type) {
|
||||||
@ -128,7 +135,7 @@ CommandCompleter.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getCompletion: function(text) {
|
getCompletion: function(text) {
|
||||||
let common = "";
|
let common = '';
|
||||||
let notInit = true;
|
let notInit = true;
|
||||||
if (!this._valid) {
|
if (!this._valid) {
|
||||||
this._update(0);
|
this._update(0);
|
||||||
@ -141,7 +148,7 @@ CommandCompleter.prototype = {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (k == 0)
|
if (k == 0)
|
||||||
return "";
|
return '';
|
||||||
return s1.substr(0, k);
|
return s1.substr(0, k);
|
||||||
}
|
}
|
||||||
function _hasPrefix(s1, prefix) {
|
function _hasPrefix(s1, prefix) {
|
||||||
@ -166,17 +173,24 @@ CommandCompleter.prototype = {
|
|||||||
|
|
||||||
function RunDialog() {
|
function RunDialog() {
|
||||||
this._init();
|
this._init();
|
||||||
};
|
}
|
||||||
|
|
||||||
RunDialog.prototype = {
|
RunDialog.prototype = {
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this._isOpen = false;
|
this._isOpen = false;
|
||||||
|
|
||||||
let gconf = Shell.GConf.get_default();
|
global.settings.connect('changed::development-tools', Lang.bind(this, function () {
|
||||||
gconf.connect('changed::development_tools', Lang.bind(this, function () {
|
this._enableInternalCommands = global.settings.get_boolean('development-tools');
|
||||||
this._enableInternalCommands = gconf.get_boolean('development_tools');
|
}));
|
||||||
|
this._enableInternalCommands = global.settings.get_boolean('development-tools');
|
||||||
|
|
||||||
|
this._history = global.settings.get_strv(HISTORY_KEY);
|
||||||
|
this._historyIndex = -1;
|
||||||
|
|
||||||
|
global.settings.connect('changed::' + HISTORY_KEY, Lang.bind(this, function() {
|
||||||
|
this._history = global.settings.get_strv(HISTORY_KEY);
|
||||||
|
this._historyIndex = this._history.length;
|
||||||
}));
|
}));
|
||||||
this._enableInternalCommands = gconf.get_boolean('development_tools');
|
|
||||||
|
|
||||||
this._internalCommands = { 'lg':
|
this._internalCommands = { 'lg':
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
@ -200,87 +214,70 @@ RunDialog.prototype = {
|
|||||||
// All actors are inside _group. We create it initially
|
// All actors are inside _group. We create it initially
|
||||||
// hidden then show it in show()
|
// hidden then show it in show()
|
||||||
this._group = new Clutter.Group({ visible: false,
|
this._group = new Clutter.Group({ visible: false,
|
||||||
x: 0,
|
x: 0, y: 0 });
|
||||||
y: 0,
|
Main.uiGroup.add_actor(this._group);
|
||||||
width: global.screen_width,
|
|
||||||
height: global.screen_height });
|
|
||||||
global.stage.add_actor(this._group);
|
|
||||||
|
|
||||||
let lightbox = new Lightbox.Lightbox(this._group);
|
this._lightbox = new Lightbox.Lightbox(this._group,
|
||||||
|
{ inhibitEvents: true });
|
||||||
|
|
||||||
this._boxH = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
this._box = new St.Bin({ x_align: St.Align.MIDDLE,
|
||||||
x_align: Big.BoxAlignment.CENTER,
|
y_align: St.Align.MIDDLE });
|
||||||
y_align: Big.BoxAlignment.CENTER });
|
|
||||||
|
|
||||||
this._group.add_actor(this._boxH);
|
this._group.add_actor(this._box);
|
||||||
lightbox.highlight(this._boxH);
|
this._lightbox.highlight(this._box);
|
||||||
|
|
||||||
let boxV = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
let dialogBox = new St.BoxLayout({ style_class: 'run-dialog', vertical: true });
|
||||||
y_align: Big.BoxAlignment.CENTER });
|
|
||||||
|
|
||||||
this._boxH.append(boxV, Big.BoxPackFlags.NONE);
|
this._box.set_child(dialogBox);
|
||||||
|
|
||||||
|
let label = new St.Label({ style_class: 'run-dialog-label',
|
||||||
|
text: _("Please enter a command:") });
|
||||||
|
|
||||||
let dialogBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
dialogBox.add(label, { expand: true, y_fill: false });
|
||||||
background_color: BOX_BACKGROUND_COLOR,
|
|
||||||
corner_radius: 4,
|
|
||||||
reactive: false,
|
|
||||||
padding: DIALOG_PADDING,
|
|
||||||
width: DIALOG_WIDTH });
|
|
||||||
|
|
||||||
this._boxH.append(dialogBox, Big.BoxPackFlags.NONE);
|
let entry = new St.Entry({ style_class: 'run-dialog-entry' });
|
||||||
|
|
||||||
let label = new Clutter.Text({ color: BOX_TEXT_COLOR,
|
this._entryText = entry.clutter_text;
|
||||||
font_name: '18px Sans',
|
dialogBox.add(entry, { expand: true });
|
||||||
text: _("Please enter a command:") });
|
|
||||||
|
|
||||||
dialogBox.append(label, Big.BoxPackFlags.EXPAND);
|
this._errorBox = new St.BoxLayout();
|
||||||
|
|
||||||
this._entry = new Clutter.Text({ color: BOX_TEXT_COLOR,
|
dialogBox.add(this._errorBox, { expand: true });
|
||||||
font_name: '20px Sans Bold',
|
|
||||||
editable: true,
|
|
||||||
activatable: true,
|
|
||||||
singleLineMode: true });
|
|
||||||
|
|
||||||
dialogBox.append(this._entry, Big.BoxPackFlags.EXPAND);
|
let errorIcon = new St.Button({ style_class: 'run-dialog-error-icon' });
|
||||||
|
|
||||||
this._errorBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
this._errorBox.add(errorIcon);
|
||||||
padding_top: DIALOG_PADDING });
|
|
||||||
|
|
||||||
dialogBox.append(this._errorBox, Big.BoxPackFlags.EXPAND);
|
|
||||||
|
|
||||||
let iconBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
|
||||||
y_align: Big.BoxAlignment.CENTER,
|
|
||||||
x_align: Big.BoxAlignment.CENTER,
|
|
||||||
width: ICON_BOX_SIZE,
|
|
||||||
height: ICON_BOX_SIZE });
|
|
||||||
|
|
||||||
this._errorBox.append(iconBox, Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
this._commandError = false;
|
this._commandError = false;
|
||||||
|
|
||||||
let errorIcon = Shell.TextureCache.get_default().load_icon_name("gtk-dialog-error", ICON_SIZE);
|
this._errorMessage = new St.Label({ style_class: 'run-dialog-error-label' });
|
||||||
iconBox.append(errorIcon, Big.BoxPackFlags.EXPAND);
|
this._errorMessage.clutter_text.line_wrap = true;
|
||||||
|
|
||||||
this._errorMessage = new Clutter.Text({ color: BOX_TEXT_COLOR,
|
this._errorBox.add(this._errorMessage, { expand: true });
|
||||||
font_name: '18px Sans Bold',
|
|
||||||
line_wrap: true });
|
|
||||||
|
|
||||||
this._errorBox.append(this._errorMessage, Big.BoxPackFlags.EXPAND);
|
|
||||||
|
|
||||||
this._errorBox.hide();
|
this._errorBox.hide();
|
||||||
|
|
||||||
this._entry.connect('activate', Lang.bind(this, function (o, e) {
|
|
||||||
this._run(o.get_text());
|
|
||||||
if (!this._commandError)
|
|
||||||
this.close();
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._pathCompleter = new Gio.FilenameCompleter();
|
this._pathCompleter = new Gio.FilenameCompleter();
|
||||||
this._commandCompleter = new CommandCompleter();
|
this._commandCompleter = new CommandCompleter();
|
||||||
this._group.connect('notify::visible', Lang.bind(this._commandCompleter, this._commandCompleter.update));
|
this._group.connect('notify::visible', Lang.bind(this._commandCompleter, this._commandCompleter.update));
|
||||||
this._entry.connect('key-press-event', Lang.bind(this, function(o, e) {
|
this._entryText.connect('key-press-event', Lang.bind(this, function(o, e) {
|
||||||
let symbol = e.get_key_symbol();
|
let symbol = e.get_key_symbol();
|
||||||
|
if (symbol == Clutter.Down) {
|
||||||
|
this._setCommandFromHistory(this._historyIndex++);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (symbol == Clutter.Up) {
|
||||||
|
this._setCommandFromHistory(this._historyIndex--);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
|
||||||
|
if (Shell.get_event_state(e) & Clutter.ModifierType.CONTROL_MASK)
|
||||||
|
this._run(o.get_text(), true);
|
||||||
|
else
|
||||||
|
this._run(o.get_text(), false);
|
||||||
|
if (!this._commandError)
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
if (symbol == Clutter.Escape) {
|
if (symbol == Clutter.Escape) {
|
||||||
this.close();
|
this.close();
|
||||||
return true;
|
return true;
|
||||||
@ -325,36 +322,85 @@ RunDialog.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_run : function(command) {
|
_saveHistory : function() {
|
||||||
|
if (this._history.length > HISTORY_LIMIT) {
|
||||||
|
this._history.splice(0, this._history.length - HISTORY_LIMIT);
|
||||||
|
}
|
||||||
|
global.settings.set_strv(HISTORY_KEY, this._history);
|
||||||
|
},
|
||||||
|
|
||||||
|
_run : function(input, inTerminal) {
|
||||||
|
let command = input;
|
||||||
|
|
||||||
|
if (this._history.length == 0 ||
|
||||||
|
this._history[this._history.length - 1] != input) {
|
||||||
|
this._history.push(input);
|
||||||
|
this._saveHistory();
|
||||||
|
}
|
||||||
|
|
||||||
this._commandError = false;
|
this._commandError = false;
|
||||||
let f;
|
let f;
|
||||||
if (this._enableInternalCommands)
|
if (this._enableInternalCommands)
|
||||||
f = this._internalCommands[command];
|
f = this._internalCommands[input];
|
||||||
else
|
else
|
||||||
f = null;
|
f = null;
|
||||||
if (f) {
|
if (f) {
|
||||||
f();
|
f();
|
||||||
} else if (command) {
|
} else if (input) {
|
||||||
try {
|
try {
|
||||||
|
if (inTerminal)
|
||||||
|
command = 'gnome-terminal -x ' + input;
|
||||||
let [ok, len, args] = GLib.shell_parse_argv(command);
|
let [ok, len, args] = GLib.shell_parse_argv(command);
|
||||||
let p = new Shell.Process({'args' : args});
|
let p = new Shell.Process({ 'args' : args });
|
||||||
p.run();
|
p.run();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this._commandError = true;
|
// Mmmh, that failed - see if @input matches an existing file
|
||||||
/*
|
let path = null;
|
||||||
* The exception contains an error string like:
|
if (input.charAt(0) == '/') {
|
||||||
* Error invoking Shell.run: Failed to execute child process "foo"
|
path = input;
|
||||||
* (No such file or directory)
|
} else {
|
||||||
* We are only interested in the actual error, so parse that out.
|
if (input.charAt(0) == '~')
|
||||||
*/
|
input = input.slice(1);
|
||||||
let m = /.+\((.+)\)/.exec(e);
|
path = GLib.get_home_dir() + '/' + input;
|
||||||
let errorStr = _("Execution of '%s' failed:").format(command) + "\n" + m[1];
|
}
|
||||||
this._errorMessage.set_text(errorStr);
|
|
||||||
this._errorBox.show();
|
if (GLib.file_test(path, GLib.FileTest.EXISTS)) {
|
||||||
|
let file = Gio.file_new_for_path(path);
|
||||||
|
Gio.app_info_launch_default_for_uri(file.get_uri(),
|
||||||
|
global.create_app_launch_context());
|
||||||
|
} else {
|
||||||
|
this._commandError = true;
|
||||||
|
// The exception contains an error string like:
|
||||||
|
// Error invoking Shell.run: Failed to execute child
|
||||||
|
// process "foo" (No such file or directory)
|
||||||
|
// We are only interested in the actual error, so parse
|
||||||
|
//that out.
|
||||||
|
let m = /.+\((.+)\)/.exec(e);
|
||||||
|
let errorStr = _("Execution of '%s' failed:").format(command) + '\n' + m[1];
|
||||||
|
this._errorMessage.set_text(errorStr);
|
||||||
|
|
||||||
|
this._errorBox.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_setCommandFromHistory: function(lastI) {
|
||||||
|
if (this._historyIndex < 0)
|
||||||
|
this._historyIndex = 0;
|
||||||
|
if (this._historyIndex > this._history.length)
|
||||||
|
this._historyIndex = this._history.length;
|
||||||
|
|
||||||
|
let text = this._entryText.get_text();
|
||||||
|
if (text) {
|
||||||
|
this._history[lastI] = text;
|
||||||
|
}
|
||||||
|
if (this._history[this._historyIndex]) {
|
||||||
|
this._entryText.set_text(this._history[this._historyIndex]);
|
||||||
|
} else
|
||||||
|
this._entryText.set_text('');
|
||||||
|
},
|
||||||
|
|
||||||
open : function() {
|
open : function() {
|
||||||
if (this._isOpen) // Already shown
|
if (this._isOpen) // Already shown
|
||||||
return;
|
return;
|
||||||
@ -365,13 +411,22 @@ RunDialog.prototype = {
|
|||||||
// Position the dialog on the current monitor
|
// Position the dialog on the current monitor
|
||||||
let monitor = global.get_focus_monitor();
|
let monitor = global.get_focus_monitor();
|
||||||
|
|
||||||
this._boxH.set_position(monitor.x, monitor.y);
|
this._historyIndex = this._history.length;
|
||||||
this._boxH.set_size(monitor.width, monitor.height);
|
|
||||||
|
this._box.set_position(monitor.x, monitor.y);
|
||||||
|
this._box.set_size(monitor.width, monitor.height);
|
||||||
|
|
||||||
this._isOpen = true;
|
this._isOpen = true;
|
||||||
|
this._lightbox.show();
|
||||||
|
this._group.opacity = 0;
|
||||||
this._group.show();
|
this._group.show();
|
||||||
|
Tweener.addTween(this._group,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: DIALOG_FADE_TIME,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
|
|
||||||
global.stage.set_key_focus(this._entry);
|
global.stage.set_key_focus(this._entryText);
|
||||||
},
|
},
|
||||||
|
|
||||||
close : function() {
|
close : function() {
|
||||||
@ -379,14 +434,20 @@ RunDialog.prototype = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this._isOpen = false;
|
this._isOpen = false;
|
||||||
|
|
||||||
this._errorBox.hide();
|
|
||||||
this._commandError = false;
|
this._commandError = false;
|
||||||
|
|
||||||
this._group.hide();
|
|
||||||
this._entry.set_text('');
|
|
||||||
|
|
||||||
Main.popModal(this._group);
|
Main.popModal(this._group);
|
||||||
|
|
||||||
|
Tweener.addTween(this._group,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: DIALOG_FADE_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this, function() {
|
||||||
|
this._errorBox.hide();
|
||||||
|
this._group.hide();
|
||||||
|
this._entryText.set_text('');
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(RunDialog.prototype);
|
Signals.addSignalMethods(RunDialog.prototype);
|
||||||
|
261
js/ui/scripting.js
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
|
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
// This module provides functionality for driving the shell user interface
|
||||||
|
// in an automated fashion. The primary current use case for this is
|
||||||
|
// automated performance testing (see runPerfScript()), but it could
|
||||||
|
// be applied to other forms of automation, such as testing for
|
||||||
|
// correctness as well.
|
||||||
|
//
|
||||||
|
// When scripting an automated test we want to make a series of calls
|
||||||
|
// in a linear fashion, but we also want to be able to let the main
|
||||||
|
// loop run so actions can finish. For this reason we write the script
|
||||||
|
// as a generator function that yields when it want to let the main
|
||||||
|
// loop run.
|
||||||
|
//
|
||||||
|
// yield Scripting.sleep(1000);
|
||||||
|
// main.overview.show();
|
||||||
|
// yield Scripting.waitLeisure();
|
||||||
|
//
|
||||||
|
// While it isn't important to the person writing the script, the actual
|
||||||
|
// yielded result is a function that the caller uses to provide the
|
||||||
|
// callback for resuming the script.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sleep:
|
||||||
|
* @milliseconds: number of milliseconds to wait
|
||||||
|
*
|
||||||
|
* Used within an automation script to pause the the execution of the
|
||||||
|
* current script for the specified amount of time. Use as
|
||||||
|
* 'yield Scripting.sleep(500);'
|
||||||
|
*/
|
||||||
|
function sleep(milliseconds) {
|
||||||
|
let cb;
|
||||||
|
|
||||||
|
Mainloop.timeout_add(milliseconds, function() {
|
||||||
|
if (cb)
|
||||||
|
cb();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return function(callback) {
|
||||||
|
cb = callback;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* waitLeisure:
|
||||||
|
*
|
||||||
|
* Used within an automation script to pause the the execution of the
|
||||||
|
* current script until the shell is completely idle. Use as
|
||||||
|
* 'yield Scripting.waitLeisure();'
|
||||||
|
*/
|
||||||
|
function waitLeisure() {
|
||||||
|
let cb;
|
||||||
|
|
||||||
|
global.run_at_leisure(function() {
|
||||||
|
if (cb)
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
|
||||||
|
return function(callback) {
|
||||||
|
cb = callback;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defineScriptEvent
|
||||||
|
* @name: The event will be called script.<name>
|
||||||
|
* @description: Short human-readable description of the event
|
||||||
|
*
|
||||||
|
* Convenience function to define a zero-argument performance event
|
||||||
|
* within the 'script' namespace that is reserved for events defined locally
|
||||||
|
* within a performance automation script
|
||||||
|
*/
|
||||||
|
function defineScriptEvent(name, description) {
|
||||||
|
Shell.PerfLog.get_default().define_event("script." + name,
|
||||||
|
description,
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scriptEvent
|
||||||
|
* @name: Name registered with defineScriptEvent()
|
||||||
|
*
|
||||||
|
* Convenience function to record a script-local performance event
|
||||||
|
* previously defined with defineScriptEvent
|
||||||
|
*/
|
||||||
|
function scriptEvent(name) {
|
||||||
|
Shell.PerfLog.get_default().event("script." + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* collectStatistics
|
||||||
|
*
|
||||||
|
* Convenience function to trigger statistics collection
|
||||||
|
*/
|
||||||
|
function collectStatistics() {
|
||||||
|
Shell.PerfLog.get_default().collect_statistics();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _step(g, finish, onError) {
|
||||||
|
try {
|
||||||
|
let waitFunction = g.next();
|
||||||
|
waitFunction(function() {
|
||||||
|
_step(g, finish, onError);
|
||||||
|
});
|
||||||
|
} catch (err if err instanceof StopIteration) {
|
||||||
|
if (finish)
|
||||||
|
finish();
|
||||||
|
} catch (err) {
|
||||||
|
if (onError)
|
||||||
|
onError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _collect(scriptModule, outputFile) {
|
||||||
|
let eventHandlers = {};
|
||||||
|
|
||||||
|
for (let f in scriptModule) {
|
||||||
|
let m = /([A-Za-z]+)_([A-Za-z]+)/.exec(f);
|
||||||
|
if (m)
|
||||||
|
eventHandlers[m[1] + "." + m[2]] = scriptModule[f];
|
||||||
|
}
|
||||||
|
|
||||||
|
Shell.PerfLog.get_default().replay(
|
||||||
|
function(time, eventName, signature, arg) {
|
||||||
|
if (eventName in eventHandlers)
|
||||||
|
eventHandlers[eventName](time, arg);
|
||||||
|
});
|
||||||
|
|
||||||
|
if ('finish' in scriptModule)
|
||||||
|
scriptModule.finish();
|
||||||
|
|
||||||
|
if (outputFile) {
|
||||||
|
let f = Gio.file_new_for_path(outputFile);
|
||||||
|
let raw = f.replace(null, false,
|
||||||
|
Gio.FileCreateFlags.NONE,
|
||||||
|
null);
|
||||||
|
let out = Gio.BufferedOutputStream.new_sized (raw, 4096);
|
||||||
|
Shell.write_string_to_stream (out, "{\n");
|
||||||
|
|
||||||
|
Shell.write_string_to_stream(out, '"events":\n');
|
||||||
|
Shell.PerfLog.get_default().dump_events(out);
|
||||||
|
|
||||||
|
let monitors = global.get_monitors()
|
||||||
|
let primary = global.get_primary_monitor()
|
||||||
|
Shell.write_string_to_stream(out, ',\n"monitors":\n[');
|
||||||
|
for (let i = 0; i < monitors.length; i++) {
|
||||||
|
let monitor = monitors[i];
|
||||||
|
let is_primary = (monitor.x == primary.x &&
|
||||||
|
monitor.y == primary.y &&
|
||||||
|
monitor.width == primary.width &&
|
||||||
|
monitor.height == primary.height);
|
||||||
|
if (i != 0)
|
||||||
|
Shell.write_string_to_stream(out, ', ');
|
||||||
|
Shell.write_string_to_stream(out, '"%s%dx%d+%d+%d"'.format(is_primary ? "*" : "",
|
||||||
|
monitor.width, monitor.height,
|
||||||
|
monitor.x, monitor.y));
|
||||||
|
}
|
||||||
|
Shell.write_string_to_stream(out, ' ]');
|
||||||
|
|
||||||
|
Shell.write_string_to_stream(out, ',\n"metrics":\n[ ');
|
||||||
|
let first = true;
|
||||||
|
for (let name in scriptModule.METRICS) {
|
||||||
|
let metric = scriptModule.METRICS[name];
|
||||||
|
|
||||||
|
if (!first)
|
||||||
|
Shell.write_string_to_stream(out, ',\n ');
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
Shell.write_string_to_stream(out,
|
||||||
|
'{ "name": ' + JSON.stringify(name) + ',\n' +
|
||||||
|
' "description": ' + JSON.stringify(metric.description) + ',\n' +
|
||||||
|
' "units": ' + JSON.stringify(metric.units) + ',\n' +
|
||||||
|
' "value": ' + JSON.stringify(metric.value) + ' }');
|
||||||
|
}
|
||||||
|
Shell.write_string_to_stream(out, ' ]');
|
||||||
|
|
||||||
|
Shell.write_string_to_stream (out, ',\n"log":\n');
|
||||||
|
Shell.PerfLog.get_default().dump_log(out);
|
||||||
|
|
||||||
|
Shell.write_string_to_stream (out, '\n}\n');
|
||||||
|
out.close(null);
|
||||||
|
} else {
|
||||||
|
let metrics = [];
|
||||||
|
for (let metric in scriptModule.METRICS)
|
||||||
|
metrics.push(metric);
|
||||||
|
|
||||||
|
metrics.sort();
|
||||||
|
|
||||||
|
print ('------------------------------------------------------------');
|
||||||
|
for (let i = 0; i < metrics.length; i++) {
|
||||||
|
let metric = metrics[i];
|
||||||
|
print ('# ' + scriptModule.METRIC_DESCRIPTIONS[metric]);
|
||||||
|
print (metric + ': ' + scriptModule.METRICS[metric]);
|
||||||
|
}
|
||||||
|
print ('------------------------------------------------------------');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* runPerfScript
|
||||||
|
* @scriptModule: module object with run and finish functions
|
||||||
|
* and event handlers
|
||||||
|
*
|
||||||
|
* Runs a script for automated collection of performance data. The
|
||||||
|
* script is defined as a Javascript module with specified contents.
|
||||||
|
*
|
||||||
|
* First the run() function within the module will be called as a
|
||||||
|
* generator to automate a series of actions. These actions will
|
||||||
|
* trigger performance events and the script can also record its
|
||||||
|
* own performance events.
|
||||||
|
*
|
||||||
|
* Then the recorded event log is replayed using handler functions
|
||||||
|
* within the module. The handler for the event 'foo.bar' is called
|
||||||
|
* foo_bar().
|
||||||
|
*
|
||||||
|
* Finally if the module has a function called finish(), that will
|
||||||
|
* be called.
|
||||||
|
*
|
||||||
|
* The event handler and finish functions are expected to fill in
|
||||||
|
* metrics to an object within the module called METRICS. Each
|
||||||
|
* property of this object represents an individual metric. The
|
||||||
|
* name of the property is the name of the metric, the value
|
||||||
|
* of the property is an object with the following properties:
|
||||||
|
*
|
||||||
|
* description: human readable description of the metric
|
||||||
|
* units: a string representing the units of the metric. It has
|
||||||
|
* the form '<unit> <unit> ... / <unit> / <unit> ...'. Certain
|
||||||
|
* unit values are recognized: s, ms, us, B, KiB, MiB. Other
|
||||||
|
* values can appear but are uninterpreted. Examples 's',
|
||||||
|
* '/ s', 'frames', 'frames / s', 'MiB / s / frame'
|
||||||
|
* value: computed value of the metric
|
||||||
|
*
|
||||||
|
* The resulting metrics will be written to @outputFile as JSON, or,
|
||||||
|
* if @outputFile is not provided, logged.
|
||||||
|
*
|
||||||
|
* After running the script and collecting statistics from the
|
||||||
|
* event log, GNOME Shell will exit.
|
||||||
|
**/
|
||||||
|
function runPerfScript(scriptModule, outputFile) {
|
||||||
|
Shell.PerfLog.get_default().set_enabled(true);
|
||||||
|
|
||||||
|
let g = scriptModule.run();
|
||||||
|
|
||||||
|
_step(g,
|
||||||
|
function() {
|
||||||
|
_collect(scriptModule, outputFile);
|
||||||
|
Meta.exit(Meta.ExitCode.SUCCESS);
|
||||||
|
},
|
||||||
|
function(err) {
|
||||||
|
log("Script failed: " + err + "\n" + err.stack);
|
||||||
|
Meta.exit(Meta.ExitCode.ERROR);
|
||||||
|
});
|
||||||
|
}
|
@ -40,7 +40,7 @@ SearchResultDisplay.prototype = {
|
|||||||
* The terms are useful for search match highlighting.
|
* The terms are useful for search match highlighting.
|
||||||
*/
|
*/
|
||||||
renderResults: function(results, terms) {
|
renderResults: function(results, terms) {
|
||||||
throw new Error("not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,7 +67,7 @@ SearchResultDisplay.prototype = {
|
|||||||
* Returns: The number of actors visible.
|
* Returns: The number of actors visible.
|
||||||
*/
|
*/
|
||||||
getVisibleResultCount: function() {
|
getVisibleResultCount: function() {
|
||||||
throw new Error("not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,7 +79,14 @@ SearchResultDisplay.prototype = {
|
|||||||
* available.
|
* available.
|
||||||
*/
|
*/
|
||||||
selectIndex: function() {
|
selectIndex: function() {
|
||||||
throw new Error("not implemented");
|
throw new Error('Not implemented');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate the currently selected search result.
|
||||||
|
*/
|
||||||
|
activateSelected: function() {
|
||||||
|
throw new Error('Not implemented');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,7 +127,7 @@ SearchProvider.prototype = {
|
|||||||
* or network queries.
|
* or network queries.
|
||||||
*/
|
*/
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
throw new Error("not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,7 +144,7 @@ SearchProvider.prototype = {
|
|||||||
* result set, rather than possibly performing a full re-query.
|
* result set, rather than possibly performing a full re-query.
|
||||||
*/
|
*/
|
||||||
getSubsearchResultSet: function(previousResults, newTerms) {
|
getSubsearchResultSet: function(previousResults, newTerms) {
|
||||||
throw new Error("not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,7 +155,7 @@ SearchProvider.prototype = {
|
|||||||
* properties which describe the given search result.
|
* properties which describe the given search result.
|
||||||
*/
|
*/
|
||||||
getResultMeta: function(id) {
|
getResultMeta: function(id) {
|
||||||
throw new Error("not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,7 +194,7 @@ SearchProvider.prototype = {
|
|||||||
* Called when the user chooses a given result.
|
* Called when the user chooses a given result.
|
||||||
*/
|
*/
|
||||||
activateResult: function(id) {
|
activateResult: function(id) {
|
||||||
throw new Error("not implemented");
|
throw new Error('Not implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,9 +205,9 @@ SearchProvider.prototype = {
|
|||||||
* displaying search results for that item type.
|
* displaying search results for that item type.
|
||||||
*/
|
*/
|
||||||
expandSearch: function(terms) {
|
expandSearch: function(terms) {
|
||||||
throw new Error("not implemented");
|
throw new Error('Not implemented');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Signals.addSignalMethods(SearchProvider.prototype);
|
Signals.addSignalMethods(SearchProvider.prototype);
|
||||||
|
|
||||||
function SearchSystem() {
|
function SearchSystem() {
|
||||||
@ -231,7 +238,7 @@ SearchSystem.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateSearch: function(searchString) {
|
updateSearch: function(searchString) {
|
||||||
searchString = searchString.replace(/^\s+/g, "").replace(/\s+$/g, "");
|
searchString = searchString.replace(/^\s+/g, '').replace(/\s+$/g, '');
|
||||||
if (searchString == '')
|
if (searchString == '')
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -268,5 +275,5 @@ SearchSystem.prototype = {
|
|||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
Signals.addSignalMethods(SearchSystem.prototype);
|
Signals.addSignalMethods(SearchSystem.prototype);
|
||||||
|
@ -8,16 +8,16 @@ const Mainloop = imports.mainloop;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
const GnomeShellIface = {
|
const GnomeShellIface = {
|
||||||
name: "org.gnome.Shell",
|
name: 'org.gnome.Shell',
|
||||||
methods: [{ name: "Eval",
|
methods: [{ name: 'Eval',
|
||||||
inSignature: "s",
|
inSignature: 's',
|
||||||
outSignature: "bs"
|
outSignature: 'bs'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
signals: [],
|
signals: [],
|
||||||
properties: [{ name: "OverviewActive",
|
properties: [{ name: 'OverviewActive',
|
||||||
signature: "b",
|
signature: 'b',
|
||||||
access: "readwrite" }]
|
access: 'readwrite' }]
|
||||||
};
|
};
|
||||||
|
|
||||||
function GnomeShell() {
|
function GnomeShell() {
|
||||||
@ -50,7 +50,7 @@ GnomeShell.prototype = {
|
|||||||
returnValue = JSON.stringify(eval(code));
|
returnValue = JSON.stringify(eval(code));
|
||||||
// A hack; DBus doesn't have null/undefined
|
// A hack; DBus doesn't have null/undefined
|
||||||
if (returnValue == undefined)
|
if (returnValue == undefined)
|
||||||
returnValue = "";
|
returnValue = '';
|
||||||
success = true;
|
success = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
returnValue = JSON.stringify(e);
|
returnValue = JSON.stringify(e);
|
||||||
|
186
js/ui/sidebar.js
@ -1,186 +0,0 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
|
||||||
const Panel = imports.ui.panel;
|
|
||||||
const Tweener = imports.ui.tweener;
|
|
||||||
const Widget = imports.ui.widget;
|
|
||||||
const WidgetBox = imports.ui.widgetBox;
|
|
||||||
|
|
||||||
const SIDEBAR_SPACING = 4;
|
|
||||||
const SIDEBAR_PADDING = 4;
|
|
||||||
|
|
||||||
// The total sidebar width is the widget width plus the widget padding
|
|
||||||
// (counted twice for the widget box, and once again for the
|
|
||||||
// out-of-screen padding), plus the empty space between the border of
|
|
||||||
// the bar and of the windows
|
|
||||||
const SIDEBAR_COLLAPSED_WIDTH = Widget.COLLAPSED_WIDTH + 3 * WidgetBox.WIDGETBOX_PADDING + SIDEBAR_PADDING;
|
|
||||||
const SIDEBAR_EXPANDED_WIDTH = Widget.EXPANDED_WIDTH + 3 * WidgetBox.WIDGETBOX_PADDING + SIDEBAR_PADDING;
|
|
||||||
|
|
||||||
function Sidebar() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
Sidebar.prototype = {
|
|
||||||
_init : function() {
|
|
||||||
// The top-left corner of the sidebar is fixed at:
|
|
||||||
// x = -WidgetBox.WIDGETBOX_PADDING, y = Panel.PANEL_HEIGHT.
|
|
||||||
// (The negative X is so that we don't see the rounded
|
|
||||||
// WidgetBox corners on the screen edge side.)
|
|
||||||
this.actor = new Clutter.Group({ x: -WidgetBox.WIDGETBOX_PADDING,
|
|
||||||
y: Panel.PANEL_HEIGHT,
|
|
||||||
width: SIDEBAR_EXPANDED_WIDTH });
|
|
||||||
|
|
||||||
// The actual widgets go into a Big.Box inside this.actor. The
|
|
||||||
// box's width will vary during the expand/collapse animations,
|
|
||||||
// but this.actor's width will remain constant until we adjust
|
|
||||||
// it at the end of the animation, because we don't want the
|
|
||||||
// wm strut to move and cause windows to move multiple times
|
|
||||||
// during the animation.
|
|
||||||
this.box = new Big.Box ({ padding_top: SIDEBAR_PADDING,
|
|
||||||
padding_bottom: SIDEBAR_PADDING,
|
|
||||||
padding_right: 0,
|
|
||||||
padding_left: 0,
|
|
||||||
spacing: SIDEBAR_SPACING });
|
|
||||||
this.actor.add_actor(this.box);
|
|
||||||
|
|
||||||
this._gconf = Shell.GConf.get_default();
|
|
||||||
|
|
||||||
this._expanded = this._gconf.get_boolean ("sidebar/expanded");
|
|
||||||
if (!this._expanded)
|
|
||||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
|
||||||
|
|
||||||
this._visible = this._gconf.get_boolean ("sidebar/visible");
|
|
||||||
if (this._visible)
|
|
||||||
Main.chrome.addActor(this.actor);
|
|
||||||
|
|
||||||
this._widgets = [];
|
|
||||||
this.addWidget(new ToggleWidget());
|
|
||||||
|
|
||||||
let default_widgets = this._gconf.get_string_list("sidebar/widgets");
|
|
||||||
for (let i = 0; i < default_widgets.length; i++)
|
|
||||||
this.addWidget(default_widgets[i]);
|
|
||||||
|
|
||||||
this._gconf.connect('changed::sidebar/expanded',
|
|
||||||
Lang.bind(this, this._expandedChanged));
|
|
||||||
this._gconf.connect('changed::sidebar/visible',
|
|
||||||
Lang.bind(this, this._visibleChanged));
|
|
||||||
|
|
||||||
this._adjustPosition();
|
|
||||||
},
|
|
||||||
|
|
||||||
addWidget: function(widget) {
|
|
||||||
let widgetBox;
|
|
||||||
try {
|
|
||||||
widgetBox = new WidgetBox.WidgetBox(widget, this._expanded);
|
|
||||||
} catch(e) {
|
|
||||||
logError(e, "Failed to add widget '" + widget + "'");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.box.append(widgetBox.actor, Big.BoxPackFlags.NONE);
|
|
||||||
this._widgets.push(widgetBox);
|
|
||||||
this._adjustPosition();
|
|
||||||
},
|
|
||||||
|
|
||||||
_adjustPosition: function() {
|
|
||||||
let primary=global.get_primary_monitor();
|
|
||||||
|
|
||||||
this.actor.y = Math.max(primary.y + Panel.PANEL_HEIGHT,primary.height/2 - this.actor.height/2);
|
|
||||||
this.actor.x = primary.x;
|
|
||||||
},
|
|
||||||
|
|
||||||
_visibleChanged: function() {
|
|
||||||
let visible = this._gconf.get_boolean("sidebar/visible");
|
|
||||||
if (visible == this._visible)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._visible = visible;
|
|
||||||
if (visible)
|
|
||||||
Main.chrome.addActor(this.actor);
|
|
||||||
else
|
|
||||||
Main.chrome.removeActor(this.actor);
|
|
||||||
},
|
|
||||||
|
|
||||||
_expandedChanged: function() {
|
|
||||||
let expanded = this._gconf.get_boolean("sidebar/expanded");
|
|
||||||
if (expanded == this._expanded)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._expanded = expanded;
|
|
||||||
if (expanded)
|
|
||||||
this._expand();
|
|
||||||
else
|
|
||||||
this._collapse();
|
|
||||||
},
|
|
||||||
|
|
||||||
_expand: function() {
|
|
||||||
this._expanded = true;
|
|
||||||
for (let i = 0; i < this._widgets.length; i++)
|
|
||||||
this._widgets[i].expand();
|
|
||||||
|
|
||||||
// Updated the strut/stage area after the animation completes
|
|
||||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME,
|
|
||||||
onComplete: function () {
|
|
||||||
this.actor.width = SIDEBAR_EXPANDED_WIDTH;
|
|
||||||
} });
|
|
||||||
},
|
|
||||||
|
|
||||||
_collapse: function() {
|
|
||||||
this._expanded = false;
|
|
||||||
for (let i = 0; i < this._widgets.length; i++)
|
|
||||||
this._widgets[i].collapse();
|
|
||||||
|
|
||||||
// Updated the strut/stage area after the animation completes
|
|
||||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME,
|
|
||||||
onComplete: function () {
|
|
||||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
|
||||||
} });
|
|
||||||
},
|
|
||||||
|
|
||||||
destroy: function() {
|
|
||||||
this.hide();
|
|
||||||
|
|
||||||
for (let i = 0; i < this._widgets.length; i++)
|
|
||||||
this._widgets[i].destroy();
|
|
||||||
this.actor.destroy();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const LEFT_DOUBLE_ARROW = "\u00AB";
|
|
||||||
const RIGHT_DOUBLE_ARROW = "\u00BB";
|
|
||||||
|
|
||||||
function ToggleWidget() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
ToggleWidget.prototype = {
|
|
||||||
__proto__ : Widget.Widget.prototype,
|
|
||||||
|
|
||||||
_init : function() {
|
|
||||||
this._gconf = Shell.GConf.get_default();
|
|
||||||
|
|
||||||
this.actor = new Clutter.Text({ font_name: "Sans Bold 16px",
|
|
||||||
text: LEFT_DOUBLE_ARROW,
|
|
||||||
reactive: true });
|
|
||||||
this.actor.connect('button-release-event',
|
|
||||||
Lang.bind(this, this._collapse));
|
|
||||||
this.collapsedActor = new Clutter.Text({ font_name: "Sans Bold 16px",
|
|
||||||
text: RIGHT_DOUBLE_ARROW,
|
|
||||||
reactive: true });
|
|
||||||
this.collapsedActor.connect('button-release-event',
|
|
||||||
Lang.bind(this, this._expand));
|
|
||||||
},
|
|
||||||
|
|
||||||
_collapse : function () {
|
|
||||||
this._gconf.set_boolean ("sidebar/expanded", false);
|
|
||||||
},
|
|
||||||
|
|
||||||
_expand : function () {
|
|
||||||
this._gconf.set_boolean ("sidebar/expanded", true);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,53 +1,55 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
|
||||||
const Gdm = imports.gi.Gdm;
|
const Gdm = imports.gi.Gdm;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const Gtk = imports.gi.Gtk;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Signals = imports.signals;
|
|
||||||
const Gettext = imports.gettext.domain('gnome-shell');
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
const _ = Gettext.gettext;
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
|
const GnomeSession = imports.misc.gnomeSession;
|
||||||
|
const Main = imports.ui.main;
|
||||||
const Panel = imports.ui.panel;
|
const Panel = imports.ui.panel;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
// Adapted from gdm/gui/user-switch-applet/applet.c
|
// Adapted from gdm/gui/user-switch-applet/applet.c
|
||||||
//
|
//
|
||||||
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
|
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
|
||||||
// Copyright (C) 2008,2009 Red Hat, Inc.
|
// Copyright (C) 2008,2009 Red Hat, Inc.
|
||||||
|
|
||||||
const SIDEBAR_VISIBLE_KEY = 'sidebar/visible';
|
function StatusMenuButton() {
|
||||||
|
|
||||||
function StatusMenu() {
|
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusMenu.prototype = {
|
StatusMenuButton.prototype = {
|
||||||
|
__proto__: Panel.PanelMenuButton.prototype,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
|
Panel.PanelMenuButton.prototype._init.call(this, St.Align.START);
|
||||||
|
let box = new St.BoxLayout({ name: 'panelStatusMenu' });
|
||||||
|
this.actor.set_child(box);
|
||||||
|
|
||||||
this._gdm = Gdm.UserManager.ref_default();
|
this._gdm = Gdm.UserManager.ref_default();
|
||||||
this._user = this._gdm.get_user(GLib.get_user_name());
|
this._user = this._gdm.get_user(GLib.get_user_name());
|
||||||
this._presence = new GnomeSessionPresence();
|
this._presence = new GnomeSession.Presence();
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ name: 'StatusMenu' });
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
this._iconBox = new St.Bin();
|
this._iconBox = new St.Bin();
|
||||||
this.actor.add(this._iconBox, { y_align: St.Align.MIDDLE });
|
box.add(this._iconBox, { y_align: St.Align.MIDDLE, y_fill: false });
|
||||||
|
|
||||||
let textureCache = Shell.TextureCache.get_default();
|
let textureCache = St.TextureCache.get_default();
|
||||||
// FIXME: these icons are all wrong (likewise in createSubMenu)
|
this._availableIcon = textureCache.load_icon_name('user-available', 16);
|
||||||
this._availableIcon = textureCache.load_icon_name('gtk-yes', 16);
|
this._busyIcon = textureCache.load_icon_name('user-busy', 16);
|
||||||
this._busyIcon = textureCache.load_icon_name('gtk-no', 16);
|
this._invisibleIcon = textureCache.load_icon_name('user-invisible', 16);
|
||||||
this._invisibleIcon = textureCache.load_icon_name('gtk-close', 16);
|
this._idleIcon = textureCache.load_icon_name('user-idle', 16);
|
||||||
this._idleIcon = textureCache.load_icon_name('gtk-media-pause', 16);
|
|
||||||
|
|
||||||
this._presence.connect('StatusChanged', Lang.bind(this, this._updatePresenceIcon));
|
this._presence.connect('StatusChanged', Lang.bind(this, this._updatePresenceIcon));
|
||||||
this._presence.getStatus(Lang.bind(this, this._updatePresenceIcon));
|
this._presence.getStatus(Lang.bind(this, this._updatePresenceIcon));
|
||||||
|
|
||||||
this._name = new St.Label({ text: this._user.get_real_name() });
|
this._name = new St.Label({ text: this._user.get_real_name() });
|
||||||
this.actor.add(this._name, { expand: true, y_align: St.Align.MIDDLE });
|
box.add(this._name, { y_align: St.Align.MIDDLE, y_fill: false });
|
||||||
this._userNameChangedId = this._user.connect('notify::display-name', Lang.bind(this, this._updateUserName));
|
this._userNameChangedId = this._user.connect('notify::display-name', Lang.bind(this, this._updateUserName));
|
||||||
|
|
||||||
this._createSubMenu();
|
this._createSubMenu();
|
||||||
@ -67,135 +69,101 @@ StatusMenu.prototype = {
|
|||||||
_updateSwitchUser: function() {
|
_updateSwitchUser: function() {
|
||||||
let users = this._gdm.list_users();
|
let users = this._gdm.list_users();
|
||||||
if (users.length > 1)
|
if (users.length > 1)
|
||||||
this._loginScreenItem.show();
|
this._loginScreenItem.actor.show();
|
||||||
else
|
else
|
||||||
this._loginScreenItem.hide();
|
this._loginScreenItem.actor.hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updatePresenceIcon: function(presence, status) {
|
_updatePresenceIcon: function(presence, status) {
|
||||||
if (status == GnomeSessionPresenceStatus.AVAILABLE)
|
if (status == GnomeSession.PresenceStatus.AVAILABLE)
|
||||||
this._iconBox.child = this._availableIcon;
|
this._iconBox.child = this._availableIcon;
|
||||||
else if (status == GnomeSessionPresenceStatus.BUSY)
|
else if (status == GnomeSession.PresenceStatus.BUSY)
|
||||||
this._iconBox.child = this._busyIcon;
|
this._iconBox.child = this._busyIcon;
|
||||||
else if (status == GnomeSessionPresenceStatus.INVISIBLE)
|
else if (status == GnomeSession.PresenceStatus.INVISIBLE)
|
||||||
this._iconBox.child = this._invisibleIcon;
|
this._iconBox.child = this._invisibleIcon;
|
||||||
else
|
else
|
||||||
this._iconBox.child = this._idleIcon;
|
this._iconBox.child = this._idleIcon;
|
||||||
},
|
},
|
||||||
|
|
||||||
// The menu
|
|
||||||
|
|
||||||
_createImageMenuItem: function(label, iconName, forceIcon) {
|
|
||||||
let image = new Gtk.Image();
|
|
||||||
let item = new Gtk.ImageMenuItem({ label: label,
|
|
||||||
image: image,
|
|
||||||
always_show_image: forceIcon == true });
|
|
||||||
item.connect('style-set', Lang.bind(this,
|
|
||||||
function() {
|
|
||||||
image.set_from_icon_name(iconName, Gtk.IconSize.MENU);
|
|
||||||
}));
|
|
||||||
|
|
||||||
return item;
|
|
||||||
},
|
|
||||||
|
|
||||||
_createSubMenu: function() {
|
_createSubMenu: function() {
|
||||||
this._menu = new Gtk.Menu();
|
|
||||||
this._menu.connect('deactivate', Lang.bind(this, function() { this.emit('deactivated'); }));
|
|
||||||
|
|
||||||
let item;
|
let item;
|
||||||
|
|
||||||
item = this._createImageMenuItem(_('Available'), 'gtk-yes', true);
|
item = new PopupMenu.PopupImageMenuItem(_("Available"), 'user-available', true);
|
||||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSessionPresenceStatus.AVAILABLE));
|
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.AVAILABLE));
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
|
|
||||||
item = this._createImageMenuItem(_('Busy'), 'gtk-no', true);
|
item = new PopupMenu.PopupImageMenuItem(_("Busy"), 'user-busy', true);
|
||||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSessionPresenceStatus.BUSY));
|
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.BUSY));
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
|
|
||||||
item = this._createImageMenuItem(_('Invisible'), 'gtk-close', true);
|
item = new PopupMenu.PopupImageMenuItem(_("Invisible"), 'user-invisible', true);
|
||||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSessionPresenceStatus.INVISIBLE));
|
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.INVISIBLE));
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
|
|
||||||
item = new Gtk.SeparatorMenuItem();
|
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
|
|
||||||
item = this._createImageMenuItem(_('Account Information...'), 'user-info');
|
item = new PopupMenu.PopupImageMenuItem(_("Account Information..."), 'user-info');
|
||||||
item.connect('activate', Lang.bind(this, this._onAccountInformationActivate));
|
item.connect('activate', Lang.bind(this, this._onAccountInformationActivate));
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
|
|
||||||
let gconf = Shell.GConf.get_default();
|
item = new PopupMenu.PopupImageMenuItem(_("System Preferences..."), 'preferences-desktop');
|
||||||
item = new Gtk.CheckMenuItem({ label: _('Sidebar'),
|
|
||||||
active: gconf.get_boolean(SIDEBAR_VISIBLE_KEY) });
|
|
||||||
item.connect('activate', Lang.bind(this,
|
|
||||||
function() {
|
|
||||||
gconf.set_boolean(SIDEBAR_VISIBLE_KEY, this._sidebarItem.active);
|
|
||||||
}));
|
|
||||||
this._menu.append(item);
|
|
||||||
item.show();
|
|
||||||
this._sidebarItem = item;
|
|
||||||
|
|
||||||
item = this._createImageMenuItem(_('System Preferences...'), 'preferences-desktop');
|
|
||||||
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
|
|
||||||
item = new Gtk.SeparatorMenuItem();
|
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
|
|
||||||
item = this._createImageMenuItem(_('Lock Screen'), 'system-lock-screen');
|
item = new PopupMenu.PopupImageMenuItem(_("Lock Screen"), 'system-lock-screen');
|
||||||
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
|
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
|
|
||||||
item = this._createImageMenuItem(_('Switch User'), 'system-users');
|
item = new PopupMenu.PopupImageMenuItem(_("Switch User"), 'system-users');
|
||||||
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
|
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
this._loginScreenItem = item;
|
this._loginScreenItem = item;
|
||||||
|
|
||||||
item = this._createImageMenuItem(_('Log Out...'), 'system-log-out');
|
item = new PopupMenu.PopupImageMenuItem(_("Log Out..."), 'system-log-out');
|
||||||
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
|
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
|
|
||||||
item = this._createImageMenuItem(_('Shut Down...'), 'system-shutdown');
|
item = new PopupMenu.PopupImageMenuItem(_("Shut Down..."), 'system-shutdown');
|
||||||
item.connect('activate', Lang.bind(this, this._onShutDownActivate));
|
item.connect('activate', Lang.bind(this, this._onShutDownActivate));
|
||||||
this._menu.append(item);
|
this.menu.addMenuItem(item);
|
||||||
item.show();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_setPresenceStatus: function(item, status) {
|
_setPresenceStatus: function(item, event, status) {
|
||||||
this._presence.setStatus(status);
|
this._presence.setStatus(status);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAccountInformationActivate: function() {
|
_onAccountInformationActivate: function() {
|
||||||
|
Main.overview.hide();
|
||||||
this._spawn(['gnome-about-me']);
|
this._spawn(['gnome-about-me']);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onPreferencesActivate: function() {
|
_onPreferencesActivate: function() {
|
||||||
|
Main.overview.hide();
|
||||||
this._spawn(['gnome-control-center']);
|
this._spawn(['gnome-control-center']);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onLockScreenActivate: function() {
|
_onLockScreenActivate: function() {
|
||||||
|
Main.overview.hide();
|
||||||
this._spawn(['gnome-screensaver-command', '--lock']);
|
this._spawn(['gnome-screensaver-command', '--lock']);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onLoginScreenActivate: function() {
|
_onLoginScreenActivate: function() {
|
||||||
|
Main.overview.hide();
|
||||||
this._gdm.goto_login_session();
|
this._gdm.goto_login_session();
|
||||||
this._onLockScreenActivate();
|
this._onLockScreenActivate();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onQuitSessionActivate: function() {
|
_onQuitSessionActivate: function() {
|
||||||
|
Main.overview.hide();
|
||||||
this._spawn(['gnome-session-save', '--logout-dialog']);
|
this._spawn(['gnome-session-save', '--logout-dialog']);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onShutDownActivate: function() {
|
_onShutDownActivate: function() {
|
||||||
|
Main.overview.hide();
|
||||||
this._spawn(['gnome-session-save', '--shutdown-dialog']);
|
this._spawn(['gnome-session-save', '--shutdown-dialog']);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -205,93 +173,5 @@ StatusMenu.prototype = {
|
|||||||
// on failure
|
// on failure
|
||||||
let p = new Shell.Process({'args' : args});
|
let p = new Shell.Process({'args' : args});
|
||||||
p.run();
|
p.run();
|
||||||
},
|
|
||||||
|
|
||||||
// shell_status_menu_toggle:
|
|
||||||
// @event: event causing the toggle
|
|
||||||
//
|
|
||||||
// If the menu is not currently up, pops it up. Otherwise, hides it.
|
|
||||||
// Popping up may fail if another grab is already active; check with
|
|
||||||
// isActive().
|
|
||||||
toggle: function(event) {
|
|
||||||
if (this._menu.visible)
|
|
||||||
this._menu.popdown();
|
|
||||||
else {
|
|
||||||
// We don't want to overgrab a Mutter grab with the grab
|
|
||||||
// that GTK+ uses on menus.
|
|
||||||
if (global.display_is_grabbed())
|
|
||||||
return;
|
|
||||||
|
|
||||||
let [menuWidth, menuHeight] = this._menu.get_size_request ();
|
|
||||||
|
|
||||||
let panel;
|
|
||||||
for (panel = this.actor; panel; panel = panel.get_parent()) {
|
|
||||||
if (panel._delegate instanceof Panel.Panel)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let [panelX, panelY] = panel.get_transformed_position();
|
|
||||||
let [panelWidth, panelHeight] = panel.get_transformed_size();
|
|
||||||
|
|
||||||
let menuX = Math.round(panelX + panelWidth - menuWidth);
|
|
||||||
let menuY = Math.round(panelY + panelHeight);
|
|
||||||
|
|
||||||
Shell.popup_menu(this._menu, event.get_button(), event.get_time(),
|
|
||||||
menuX, menuY);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// isActive:
|
|
||||||
//
|
|
||||||
// Gets whether the menu is currently popped up
|
|
||||||
//
|
|
||||||
// Return value: %true if the menu is currently popped up
|
|
||||||
isActive: function() {
|
|
||||||
return this._menu.visible;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(StatusMenu.prototype);
|
|
||||||
|
|
||||||
|
|
||||||
const GnomeSessionPresenceIface = {
|
|
||||||
name: 'org.gnome.SessionManager.Presence',
|
|
||||||
methods: [{ name: 'SetStatus',
|
|
||||||
inSignature: 'u' }],
|
|
||||||
properties: [{ name: 'status',
|
|
||||||
signature: 'u',
|
|
||||||
access: 'readwrite' }],
|
|
||||||
signals: [{ name: 'StatusChanged',
|
|
||||||
inSignature: 'u' }]
|
|
||||||
};
|
|
||||||
|
|
||||||
const GnomeSessionPresenceStatus = {
|
|
||||||
AVAILABLE: 0,
|
|
||||||
INVISIBLE: 1,
|
|
||||||
BUSY: 2,
|
|
||||||
IDLE: 3
|
|
||||||
};
|
|
||||||
|
|
||||||
function GnomeSessionPresence() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
GnomeSessionPresence.prototype = {
|
|
||||||
_init: function() {
|
|
||||||
DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager/Presence', this);
|
|
||||||
this.connect('StatusChanged', Lang.bind(this, function (proxy, status) { this.status = status; }));
|
|
||||||
},
|
|
||||||
|
|
||||||
getStatus: function(callback) {
|
|
||||||
this.GetRemote('status', Lang.bind(this,
|
|
||||||
function(status, ex) {
|
|
||||||
if (!ex)
|
|
||||||
callback(this, status);
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
setStatus: function(status) {
|
|
||||||
this.SetStatusRemote(status);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
DBus.proxifyPrototype(GnomeSessionPresence.prototype, GnomeSessionPresenceIface);
|
|
||||||
|
|
||||||
|
682
js/ui/telepathyClient.js
Normal file
@ -0,0 +1,682 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const DBus = imports.dbus;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const MessageTray = imports.ui.messageTray;
|
||||||
|
const Telepathy = imports.misc.telepathy;
|
||||||
|
|
||||||
|
let contactManager;
|
||||||
|
let channelDispatcher;
|
||||||
|
|
||||||
|
// See Notification.appendMessage
|
||||||
|
const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
||||||
|
const SCROLLBACK_RECENT_LENGTH = 20;
|
||||||
|
const SCROLLBACK_IDLE_LENGTH = 5;
|
||||||
|
|
||||||
|
// A 'Qualified_Property_Value_Map' that represents a single-user
|
||||||
|
// text-based chat.
|
||||||
|
let singleUserTextChannel = {};
|
||||||
|
singleUserTextChannel[Telepathy.CHANNEL_NAME + '.ChannelType'] = Telepathy.CHANNEL_TEXT_NAME;
|
||||||
|
singleUserTextChannel[Telepathy.CHANNEL_NAME + '.TargetHandleType'] = Telepathy.HandleType.CONTACT;
|
||||||
|
|
||||||
|
// Some protocols only support 'multi-user' chats, and single-user
|
||||||
|
// chats are just treated as multi-user chats with only one other
|
||||||
|
// participant. Telepathy uses HandleType.NONE for all chats in these
|
||||||
|
// protocols; there's no good way for us to tell if the channel is
|
||||||
|
// single- or multi-user.
|
||||||
|
let oneOrMoreUserTextChannel = {};
|
||||||
|
oneOrMoreUserTextChannel[Telepathy.CHANNEL_NAME + '.ChannelType'] = Telepathy.CHANNEL_TEXT_NAME;
|
||||||
|
oneOrMoreUserTextChannel[Telepathy.CHANNEL_NAME + '.TargetHandleType'] = Telepathy.HandleType.NONE;
|
||||||
|
|
||||||
|
// The (non-chat) channel indicating the users whose presence
|
||||||
|
// information we subscribe to
|
||||||
|
let subscribedContactsChannel = {};
|
||||||
|
subscribedContactsChannel[Telepathy.CHANNEL_NAME + '.ChannelType'] = Telepathy.CHANNEL_CONTACT_LIST_NAME;
|
||||||
|
subscribedContactsChannel[Telepathy.CHANNEL_NAME + '.TargetHandleType'] = Telepathy.HandleType.LIST;
|
||||||
|
subscribedContactsChannel[Telepathy.CHANNEL_NAME + '.TargetID'] = 'subscribe';
|
||||||
|
|
||||||
|
|
||||||
|
// This is GNOME Shell's implementation of the Telepathy 'Client'
|
||||||
|
// interface. Specifically, the shell is a Telepathy 'Observer', which
|
||||||
|
// lets us see messages even if they belong to another app (eg,
|
||||||
|
// Empathy).
|
||||||
|
|
||||||
|
function Client() {
|
||||||
|
this._init();
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype = {
|
||||||
|
_init : function() {
|
||||||
|
let name = Telepathy.CLIENT_NAME + '.GnomeShell';
|
||||||
|
DBus.session.exportObject(Telepathy.nameToPath(name), this);
|
||||||
|
DBus.session.acquire_name(name, DBus.SINGLE_INSTANCE,
|
||||||
|
function (name) { /* FIXME: acquired */ },
|
||||||
|
function (name) { /* FIXME: lost */ });
|
||||||
|
|
||||||
|
this._accounts = {};
|
||||||
|
this._sources = {};
|
||||||
|
|
||||||
|
contactManager = new ContactManager();
|
||||||
|
contactManager.connect('presence-changed', Lang.bind(this, this._presenceChanged));
|
||||||
|
|
||||||
|
channelDispatcher = new Telepathy.ChannelDispatcher(DBus.session,
|
||||||
|
Telepathy.CHANNEL_DISPATCHER_NAME,
|
||||||
|
Telepathy.nameToPath(Telepathy.CHANNEL_DISPATCHER_NAME));
|
||||||
|
|
||||||
|
// Acquire existing connections. (Needed to make things work
|
||||||
|
// through a restart.)
|
||||||
|
let accountManager = new Telepathy.AccountManager(DBus.session,
|
||||||
|
Telepathy.ACCOUNT_MANAGER_NAME,
|
||||||
|
Telepathy.nameToPath(Telepathy.ACCOUNT_MANAGER_NAME));
|
||||||
|
accountManager.GetRemote('ValidAccounts', Lang.bind(this,
|
||||||
|
function (accounts, err) {
|
||||||
|
if (!accounts)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let i = 0; i < accounts.length; i++)
|
||||||
|
this._gotAccount(accounts[i]);
|
||||||
|
}));
|
||||||
|
accountManager.connect('AccountValidityChanged', Lang.bind(this, this._accountValidityChanged));
|
||||||
|
},
|
||||||
|
|
||||||
|
_accountValidityChanged: function(accountManager, accountPath, valid) {
|
||||||
|
if (!valid) {
|
||||||
|
delete this._accounts[accountPath];
|
||||||
|
// We don't need to clean up connections, sources, etc; they'll
|
||||||
|
// get Closed and cleaned up independently.
|
||||||
|
} else
|
||||||
|
this._gotAccount(accountPath);
|
||||||
|
},
|
||||||
|
|
||||||
|
_gotAccount: function(accountPath) {
|
||||||
|
let account = new Telepathy.Account(DBus.session,
|
||||||
|
Telepathy.ACCOUNT_MANAGER_NAME,
|
||||||
|
accountPath);
|
||||||
|
this._accounts[accountPath] = account;
|
||||||
|
account.GetRemote('Connection', Lang.bind(this,
|
||||||
|
function (connPath, err) {
|
||||||
|
if (!connPath || connPath == '/')
|
||||||
|
return;
|
||||||
|
|
||||||
|
let connReq = new Telepathy.ConnectionRequests(DBus.session,
|
||||||
|
Telepathy.pathToName(connPath),
|
||||||
|
connPath);
|
||||||
|
connReq.GetRemote('Channels', Lang.bind(this,
|
||||||
|
function(channels, err) {
|
||||||
|
if (!channels)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._addChannels(accountPath, connPath, channels);
|
||||||
|
}));
|
||||||
|
|
||||||
|
contactManager.addConnection(connPath);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
get Interfaces() {
|
||||||
|
return [ Telepathy.CLIENT_OBSERVER_NAME ];
|
||||||
|
},
|
||||||
|
|
||||||
|
get ObserverChannelFilter() {
|
||||||
|
return [ singleUserTextChannel, oneOrMoreUserTextChannel ];
|
||||||
|
},
|
||||||
|
|
||||||
|
ObserveChannels: function(accountPath, connPath, channels,
|
||||||
|
dispatchOperation, requestsSatisfied,
|
||||||
|
observerInfo) {
|
||||||
|
this._addChannels(accountPath, connPath, channels);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addChannels: function(accountPath, connPath, channelDetailsList) {
|
||||||
|
for (let i = 0; i < channelDetailsList.length; i++) {
|
||||||
|
let [channelPath, props] = channelDetailsList[i];
|
||||||
|
|
||||||
|
// If this is being called from the startup code then it
|
||||||
|
// won't have passed through our filters, so we need to
|
||||||
|
// check the channel/targetHandle type ourselves.
|
||||||
|
|
||||||
|
let channelType = props[Telepathy.CHANNEL_NAME + '.ChannelType'];
|
||||||
|
if (channelType != Telepathy.CHANNEL_TEXT_NAME)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let targetHandleType = props[Telepathy.CHANNEL_NAME + '.TargetHandleType'];
|
||||||
|
if (targetHandleType != Telepathy.HandleType.CONTACT &&
|
||||||
|
targetHandleType != Telepathy.HandleType.NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let targetHandle = props[Telepathy.CHANNEL_NAME + '.TargetHandle'];
|
||||||
|
let targetId = props[Telepathy.CHANNEL_NAME + '.TargetID'];
|
||||||
|
|
||||||
|
if (this._sources[connPath + ':' + targetHandle])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let source = new Source(accountPath, connPath, channelPath,
|
||||||
|
targetHandle, targetHandleType, targetId);
|
||||||
|
this._sources[connPath + ':' + targetHandle] = source;
|
||||||
|
source.connect('destroy', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
delete this._sources[connPath + ':' + targetHandle];
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_presenceChanged: function(contactManager, connPath, handle,
|
||||||
|
type, message) {
|
||||||
|
let source = this._sources[connPath + ':' + handle];
|
||||||
|
if (!source)
|
||||||
|
return;
|
||||||
|
|
||||||
|
source.setPresence(type, message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
DBus.conformExport(Client.prototype, Telepathy.ClientIface);
|
||||||
|
DBus.conformExport(Client.prototype, Telepathy.ClientObserverIface);
|
||||||
|
|
||||||
|
|
||||||
|
function ContactManager() {
|
||||||
|
this._init();
|
||||||
|
};
|
||||||
|
|
||||||
|
ContactManager.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
this._connections = {};
|
||||||
|
// Note that if we changed this to '/telepathy/avatars' then
|
||||||
|
// we would share cache files with empathy. But since this is
|
||||||
|
// not documented/guaranteed, it seems a little sketchy
|
||||||
|
this._cacheDir = GLib.get_user_cache_dir() + '/gnome-shell/avatars';
|
||||||
|
},
|
||||||
|
|
||||||
|
addConnection: function(connPath) {
|
||||||
|
let info = this._connections[connPath];
|
||||||
|
if (info)
|
||||||
|
return info;
|
||||||
|
|
||||||
|
info = {};
|
||||||
|
|
||||||
|
// Figure out the cache subdirectory for this connection by
|
||||||
|
// parsing the connection manager name (eg, 'gabble') and
|
||||||
|
// protocol name (eg, 'jabber') from the Connection's path.
|
||||||
|
// Telepathy requires the D-Bus path for a connection to have
|
||||||
|
// a specific form, and explicitly says that clients are
|
||||||
|
// allowed to parse it.
|
||||||
|
let match = connPath.match(/\/org\/freedesktop\/Telepathy\/Connection\/([^\/]*\/[^\/]*)\/.*/);
|
||||||
|
if (!match)
|
||||||
|
throw new Error('Could not parse connection path ' + connPath);
|
||||||
|
|
||||||
|
info.cacheDir = this._cacheDir + '/' + match[1];
|
||||||
|
GLib.mkdir_with_parents(info.cacheDir, 0700);
|
||||||
|
|
||||||
|
// info.names[handle] is @handle's real name
|
||||||
|
// info.tokens[handle] is the token for @handle's avatar
|
||||||
|
info.names = {};
|
||||||
|
info.tokens = {};
|
||||||
|
|
||||||
|
// info.icons[handle] is an array of the icon actors currently
|
||||||
|
// being displayed for @handle. These will be updated
|
||||||
|
// automatically if @handle's avatar changes.
|
||||||
|
info.icons = {};
|
||||||
|
|
||||||
|
let connName = Telepathy.pathToName(connPath);
|
||||||
|
|
||||||
|
info.connectionAvatars = new Telepathy.ConnectionAvatars(DBus.session, connName, connPath);
|
||||||
|
info.updatedId = info.connectionAvatars.connect(
|
||||||
|
'AvatarUpdated', Lang.bind(this, this._avatarUpdated));
|
||||||
|
info.retrievedId = info.connectionAvatars.connect(
|
||||||
|
'AvatarRetrieved', Lang.bind(this, this._avatarRetrieved));
|
||||||
|
|
||||||
|
info.connectionContacts = new Telepathy.ConnectionContacts(DBus.session, connName, connPath);
|
||||||
|
|
||||||
|
info.connectionPresence = new Telepathy.ConnectionSimplePresence(DBus.session, connName, connPath);
|
||||||
|
info.presenceChangedId = info.connectionPresence.connect(
|
||||||
|
'PresencesChanged', Lang.bind(this, this._presencesChanged));
|
||||||
|
|
||||||
|
let conn = new Telepathy.Connection(DBus.session, connName, connPath);
|
||||||
|
info.statusChangedId = conn.connect('StatusChanged', Lang.bind(this,
|
||||||
|
function (status, reason) {
|
||||||
|
if (status == Telepathy.ConnectionStatus.DISCONNECTED)
|
||||||
|
this._removeConnection(conn);
|
||||||
|
}));
|
||||||
|
|
||||||
|
let connReq = new Telepathy.ConnectionRequests(DBus.session,
|
||||||
|
connName, connPath);
|
||||||
|
connReq.EnsureChannelRemote(subscribedContactsChannel, Lang.bind(this,
|
||||||
|
function (result, err) {
|
||||||
|
if (!result)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let [mine, channelPath, props] = result;
|
||||||
|
this._gotContactsChannel(connPath, channelPath, props);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._connections[connPath] = info;
|
||||||
|
return info;
|
||||||
|
},
|
||||||
|
|
||||||
|
_gotContactsChannel: function(connPath, channelPath, props) {
|
||||||
|
let info = this._connections[connPath];
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
info.contactsGroup = new Telepathy.ChannelGroup(DBus.session,
|
||||||
|
Telepathy.pathToName(connPath),
|
||||||
|
channelPath);
|
||||||
|
info.contactsListChangedId =
|
||||||
|
info.contactsGroup.connect('MembersChanged', Lang.bind(this, this._contactsListChanged, info));
|
||||||
|
|
||||||
|
info.contactsGroup.GetRemote('Members', Lang.bind(this,
|
||||||
|
function(contacts, err) {
|
||||||
|
if (!contacts)
|
||||||
|
return;
|
||||||
|
|
||||||
|
info.connectionContacts.GetContactAttributesRemote(
|
||||||
|
contacts, [Telepathy.CONNECTION_ALIASING_NAME], false,
|
||||||
|
Lang.bind(this, this._gotContactAttributes, info));
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_contactsListChanged: function(group, message, added, removed,
|
||||||
|
local_pending, remote_pending,
|
||||||
|
actor, reason, info) {
|
||||||
|
for (let i = 0; i < removed.length; i++)
|
||||||
|
delete info.names[removed[i]];
|
||||||
|
|
||||||
|
info.connectionContacts.GetContactAttributesRemote(
|
||||||
|
added, [Telepathy.CONNECTION_ALIASING_NAME], false,
|
||||||
|
Lang.bind(this, this._gotContactAttributes, info));
|
||||||
|
},
|
||||||
|
|
||||||
|
_gotContactAttributes: function(attrs, err, info) {
|
||||||
|
if (!attrs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let handle in attrs)
|
||||||
|
info.names[handle] = attrs[handle][Telepathy.CONNECTION_ALIASING_NAME + '/alias'];
|
||||||
|
},
|
||||||
|
|
||||||
|
_presencesChanged: function(conn, presences, err) {
|
||||||
|
if (!presences)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let info = this._connections[conn.getPath()];
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let handle in presences) {
|
||||||
|
let [type, status, message] = presences[handle];
|
||||||
|
this.emit('presence-changed', conn.getPath(), handle, type, message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeConnection: function(conn) {
|
||||||
|
let info = this._connections[conn.getPath()];
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
conn.disconnect(info.statusChangedId);
|
||||||
|
info.connectionAvatars.disconnect(info.updatedId);
|
||||||
|
info.connectionAvatars.disconnect(info.retrievedId);
|
||||||
|
info.connectionPresence.disconnect(info.presenceChangedId);
|
||||||
|
info.contactsGroup.disconnect(info.contactsListChangedId);
|
||||||
|
|
||||||
|
delete this._connections[conn.getPath()];
|
||||||
|
},
|
||||||
|
|
||||||
|
_getFileForToken: function(info, token) {
|
||||||
|
return info.cacheDir + '/' + Telepathy.escapeAsIdentifier(token);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setIcon: function(iconBox, info, handle) {
|
||||||
|
let textureCache = St.TextureCache.get_default();
|
||||||
|
let token = info.tokens[handle];
|
||||||
|
let file;
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
file = this._getFileForToken(info, token);
|
||||||
|
if (!GLib.file_test(file, GLib.FileTest.EXISTS))
|
||||||
|
file = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
let uri = GLib.filename_to_uri(file, null);
|
||||||
|
iconBox.child = textureCache.load_uri_async(uri, iconBox._size, iconBox._size);
|
||||||
|
} else {
|
||||||
|
iconBox.child = textureCache.load_icon_name('stock_person', iconBox._size);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateIcons: function(info, handle) {
|
||||||
|
if (!info.icons[handle])
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let i = 0; i < info.icons[handle].length; i++) {
|
||||||
|
let iconBox = info.icons[handle][i];
|
||||||
|
this._setIcon(iconBox, info, handle);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_avatarUpdated: function(conn, handle, token) {
|
||||||
|
let info = this._connections[conn.getPath()];
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (info.tokens[handle] == token)
|
||||||
|
return;
|
||||||
|
|
||||||
|
info.tokens[handle] = token;
|
||||||
|
if (token != '') {
|
||||||
|
let file = this._getFileForToken(info, token);
|
||||||
|
if (!GLib.file_test(file, GLib.FileTest.EXISTS)) {
|
||||||
|
info.connectionAvatars.RequestAvatarsRemote([handle]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateIcons(info, handle);
|
||||||
|
},
|
||||||
|
|
||||||
|
_avatarRetrieved: function(conn, handle, token, avatarData, mimeType) {
|
||||||
|
let info = this._connections[conn.getPath()];
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let file = this._getFileForToken(info, token);
|
||||||
|
let success = false;
|
||||||
|
try {
|
||||||
|
success = GLib.file_set_contents(file, avatarData, avatarData.length);
|
||||||
|
} catch (e) {
|
||||||
|
logError(e, 'Error caching avatar data');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
this._updateIcons(info, handle);
|
||||||
|
},
|
||||||
|
|
||||||
|
createAvatar: function(conn, handle, size) {
|
||||||
|
let iconBox = new St.Bin({ style_class: 'avatar-box' });
|
||||||
|
iconBox._size = size;
|
||||||
|
|
||||||
|
let info = this._connections[conn.getPath()];
|
||||||
|
if (!info)
|
||||||
|
info = this.addConnection(conn.getPath());
|
||||||
|
|
||||||
|
if (!info.icons[handle])
|
||||||
|
info.icons[handle] = [];
|
||||||
|
info.icons[handle].push(iconBox);
|
||||||
|
|
||||||
|
iconBox.connect('destroy', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
let i = info.icons[handle].indexOf(iconBox);
|
||||||
|
if (i != -1)
|
||||||
|
info.icons[handle].splice(i, 1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
// If we already have the icon cached and know its token, this
|
||||||
|
// will fill it in. Otherwise it will fill in the default
|
||||||
|
// icon.
|
||||||
|
this._setIcon(iconBox, info, handle);
|
||||||
|
|
||||||
|
// Asynchronously load the real avatar if we don't have it yet.
|
||||||
|
if (info.tokens[handle] == null) {
|
||||||
|
info.connectionAvatars.GetKnownAvatarTokensRemote([handle], Lang.bind(this,
|
||||||
|
function (tokens, err) {
|
||||||
|
let token = tokens && tokens[handle] ? tokens[handle] : '';
|
||||||
|
this._avatarUpdated(conn, handle, token);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return iconBox;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Signals.addSignalMethods(ContactManager.prototype);
|
||||||
|
|
||||||
|
|
||||||
|
function Source(accountPath, connPath, channelPath, targetHandle, targetHandleType, targetId) {
|
||||||
|
this._init(accountPath, connPath, channelPath, targetHandle, targetHandleType, targetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Source.prototype = {
|
||||||
|
__proto__: MessageTray.Source.prototype,
|
||||||
|
|
||||||
|
_init: function(accountPath, connPath, channelPath, targetHandle, targetHandleType, targetId) {
|
||||||
|
MessageTray.Source.prototype._init.call(this, targetId, targetId);
|
||||||
|
|
||||||
|
this._accountPath = accountPath;
|
||||||
|
|
||||||
|
let connName = Telepathy.pathToName(connPath);
|
||||||
|
this._conn = new Telepathy.Connection(DBus.session, connName, connPath);
|
||||||
|
this._channel = new Telepathy.Channel(DBus.session, connName, channelPath);
|
||||||
|
this._closedId = this._channel.connect('Closed', Lang.bind(this, this._channelClosed));
|
||||||
|
|
||||||
|
this._targetHandle = targetHandle;
|
||||||
|
this._targetHandleType = targetHandleType;
|
||||||
|
this._targetId = targetId;
|
||||||
|
|
||||||
|
if (targetHandleType == Telepathy.HandleType.CONTACT) {
|
||||||
|
let aliasing = new Telepathy.ConnectionAliasing(DBus.session, connName, connPath);
|
||||||
|
aliasing.RequestAliasesRemote([this._targetHandle], Lang.bind(this,
|
||||||
|
function (aliases, err) {
|
||||||
|
if (aliases && aliases.length)
|
||||||
|
this.title = aliases[0];
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since we only create sources when receiving a message, this
|
||||||
|
// is a plausible default
|
||||||
|
this._presence = Telepathy.ConnectionPresenceType.AVAILABLE;
|
||||||
|
|
||||||
|
this._channelText = new Telepathy.ChannelText(DBus.session, connName, channelPath);
|
||||||
|
this._receivedId = this._channelText.connect('Received', Lang.bind(this, this._messageReceived));
|
||||||
|
|
||||||
|
this._channelText.ListPendingMessagesRemote(false, Lang.bind(this, this._gotPendingMessages));
|
||||||
|
},
|
||||||
|
|
||||||
|
createIcon: function(size) {
|
||||||
|
return contactManager.createAvatar(this._conn, this._targetHandle, size);
|
||||||
|
},
|
||||||
|
|
||||||
|
clicked: function() {
|
||||||
|
channelDispatcher.EnsureChannelRemote(this._accountPath,
|
||||||
|
{ 'org.freedesktop.Telepathy.Channel.ChannelType': Telepathy.CHANNEL_TEXT_NAME,
|
||||||
|
'org.freedesktop.Telepathy.Channel.TargetHandle': this._targetHandle,
|
||||||
|
'org.freedesktop.Telepathy.Channel.TargetHandleType': this._targetHandleType },
|
||||||
|
global.get_current_time(),
|
||||||
|
'',
|
||||||
|
Lang.bind(this, this._gotChannelRequest));
|
||||||
|
|
||||||
|
MessageTray.Source.prototype.clicked.call(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
_gotChannelRequest: function (chanReqPath, ex) {
|
||||||
|
if (ex) {
|
||||||
|
log ('EnsureChannelRemote failed? ' + ex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let chanReq = new Telepathy.ChannelRequest(DBus.session, Telepathy.CHANNEL_DISPATCHER_NAME, chanReqPath);
|
||||||
|
chanReq.ProceedRemote();
|
||||||
|
},
|
||||||
|
|
||||||
|
_gotPendingMessages: function(msgs, err) {
|
||||||
|
if (!msgs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let i = 0; i < msgs.length; i++)
|
||||||
|
this._messageReceived.apply(this, [this._channel].concat(msgs[i]));
|
||||||
|
},
|
||||||
|
|
||||||
|
_channelClosed: function() {
|
||||||
|
this._channel.disconnect(this._closedId);
|
||||||
|
this._channelText.disconnect(this._receivedId);
|
||||||
|
this.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
_ensureNotification: function() {
|
||||||
|
if (!Main.messageTray.contains(this))
|
||||||
|
Main.messageTray.add(this);
|
||||||
|
|
||||||
|
if (!this._notification)
|
||||||
|
this._notification = new Notification(this._targetId, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
_messageReceived: function(channel, id, timestamp, sender,
|
||||||
|
type, flags, text) {
|
||||||
|
this._ensureNotification();
|
||||||
|
this._notification.appendMessage(text);
|
||||||
|
this.notify(this._notification);
|
||||||
|
},
|
||||||
|
|
||||||
|
respond: function(text) {
|
||||||
|
this._channelText.SendRemote(Telepathy.ChannelTextMessageType.NORMAL, text);
|
||||||
|
},
|
||||||
|
|
||||||
|
setPresence: function(presence, message) {
|
||||||
|
let msg, notify;
|
||||||
|
|
||||||
|
if (presence == Telepathy.ConnectionPresenceType.AVAILABLE) {
|
||||||
|
msg = _("%s is online.").format(this.title);
|
||||||
|
notify = (this._presence == Telepathy.ConnectionPresenceType.OFFLINE);
|
||||||
|
} else if (presence == Telepathy.ConnectionPresenceType.OFFLINE ||
|
||||||
|
presence == Telepathy.ConnectionPresenceType.EXTENDED_AWAY) {
|
||||||
|
presence = Telepathy.ConnectionPresenceType.OFFLINE;
|
||||||
|
msg = _("%s is offline.").format(this.title);
|
||||||
|
notify = (this._presence != Telepathy.ConnectionPresenceType.OFFLINE);
|
||||||
|
} else if (presence == Telepathy.ConnectionPresenceType.AWAY) {
|
||||||
|
msg = _("%s is away.").format(this.title);
|
||||||
|
notify = false;
|
||||||
|
} else if (presence == Telepathy.ConnectionPresenceType.BUSY) {
|
||||||
|
msg = _("%s is busy.").format(this.title);
|
||||||
|
notify = false;
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._presence = presence;
|
||||||
|
|
||||||
|
if (message)
|
||||||
|
msg += ' <i>(' + GLib.markup_escape_text(message, -1) + ')</i>';
|
||||||
|
|
||||||
|
this._ensureNotification();
|
||||||
|
this._notification.appendMessage(msg, true);
|
||||||
|
if (notify)
|
||||||
|
this.notify(this._notification);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function Notification(id, source) {
|
||||||
|
this._init(id, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
Notification.prototype = {
|
||||||
|
__proto__: MessageTray.Notification.prototype,
|
||||||
|
|
||||||
|
_init: function(id, source) {
|
||||||
|
MessageTray.Notification.prototype._init.call(this, id, source, source.title);
|
||||||
|
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||||
|
|
||||||
|
this._responseEntry = new St.Entry({ style_class: 'chat-response' });
|
||||||
|
this._responseEntry.clutter_text.connect('key-focus-in', Lang.bind(this, this._onEntryFocused));
|
||||||
|
this._responseEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivated));
|
||||||
|
this.setActionArea(this._responseEntry);
|
||||||
|
|
||||||
|
this._history = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
appendMessage: function(text, asTitle) {
|
||||||
|
if (asTitle)
|
||||||
|
this.update(text);
|
||||||
|
else
|
||||||
|
this.update(this.source.title, text);
|
||||||
|
this._append(text, 'chat-received');
|
||||||
|
},
|
||||||
|
|
||||||
|
_append: function(text, style) {
|
||||||
|
let body = this.addBody(text);
|
||||||
|
body.add_style_class_name(style);
|
||||||
|
this.scrollTo(St.Side.BOTTOM);
|
||||||
|
|
||||||
|
let now = new Date().getTime() / 1000;
|
||||||
|
this._history.unshift({ actor: body, time: now });
|
||||||
|
|
||||||
|
if (this._history.length > 1) {
|
||||||
|
// Keep the scrollback from growing too long. If the most
|
||||||
|
// recent message (before the one we just added) is within
|
||||||
|
// SCROLLBACK_RECENT_TIME, we will keep
|
||||||
|
// SCROLLBACK_RECENT_LENGTH previous messages. Otherwise
|
||||||
|
// we'll keep SCROLLBACK_IDLE_LENGTH messages.
|
||||||
|
|
||||||
|
let lastMessageTime = this._history[1].time;
|
||||||
|
let maxLength = (lastMessageTime < now - SCROLLBACK_RECENT_TIME) ?
|
||||||
|
SCROLLBACK_IDLE_LENGTH : SCROLLBACK_RECENT_LENGTH;
|
||||||
|
if (this._history.length > maxLength) {
|
||||||
|
let expired = this._history.splice(maxLength);
|
||||||
|
for (let i = 0; i < expired.length; i++)
|
||||||
|
expired[i].actor.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onButtonPress: function(notification, event) {
|
||||||
|
if (!this._active)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let source = event.get_source ();
|
||||||
|
if (source && notification.contains(source))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// @source is outside @notification, which has to mean that
|
||||||
|
// we have a pointer grab, and the user clicked outside the
|
||||||
|
// notification, so we should deactivate.
|
||||||
|
this._deactivate();
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onEntryFocused: function() {
|
||||||
|
if (this._active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!Main.pushModal(this.actor))
|
||||||
|
return;
|
||||||
|
Clutter.grab_pointer(this.actor);
|
||||||
|
|
||||||
|
this._active = true;
|
||||||
|
Main.messageTray.lock();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onEntryActivated: function() {
|
||||||
|
let text = this._responseEntry.get_text();
|
||||||
|
if (text == '') {
|
||||||
|
this._deactivate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._responseEntry.set_text('');
|
||||||
|
this._append(text, 'chat-sent');
|
||||||
|
this.source.respond(text);
|
||||||
|
},
|
||||||
|
|
||||||
|
_deactivate: function() {
|
||||||
|
if (this._active) {
|
||||||
|
Clutter.ungrab_pointer(this.actor);
|
||||||
|
Main.popModal(this.actor);
|
||||||
|
global.stage.set_key_focus(null);
|
||||||
|
|
||||||
|
// We have to do this after calling popModal(), because
|
||||||
|
// that will return the keyboard focus to
|
||||||
|
// this._responseEntry (because that's where it was when
|
||||||
|
// pushModal() was called), which will cause
|
||||||
|
// _onEntryFocused() to be called again, but we don't want
|
||||||
|
// it to do anything.
|
||||||
|
this._active = false;
|
||||||
|
|
||||||
|
Main.messageTray.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -1,9 +1,10 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const St = imports.gi.St;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Tweener = imports.tweener.tweener;
|
const Tweener = imports.tweener.tweener;
|
||||||
|
|
||||||
@ -42,17 +43,8 @@ const Tweener = imports.tweener.tweener;
|
|||||||
// calls any of these is almost certainly wrong anyway, because they
|
// calls any of these is almost certainly wrong anyway, because they
|
||||||
// affect the entire application.)
|
// affect the entire application.)
|
||||||
|
|
||||||
let slowDownFactor = 1.0;
|
|
||||||
|
|
||||||
// Called from Main.start
|
// Called from Main.start
|
||||||
function init() {
|
function init() {
|
||||||
let slowdownEnv = GLib.getenv("GNOME_SHELL_SLOWDOWN_FACTOR");
|
|
||||||
if (slowdownEnv) {
|
|
||||||
let factor = parseFloat(slowdownEnv);
|
|
||||||
if (!isNaN(factor) && factor > 0.0)
|
|
||||||
slowDownFactor = factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tweener.setFrameTicker(new ClutterFrameTicker());
|
Tweener.setFrameTicker(new ClutterFrameTicker());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +170,7 @@ function resumeTweens() {
|
|||||||
function registerSpecialProperty(name, getFunction, setFunction,
|
function registerSpecialProperty(name, getFunction, setFunction,
|
||||||
parameters, preProcessFunction) {
|
parameters, preProcessFunction) {
|
||||||
Tweener.registerSpecialProperty(name, getFunction, setFunction,
|
Tweener.registerSpecialProperty(name, getFunction, setFunction,
|
||||||
parameters, preProcessFunction);
|
parameters, preProcessFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerSpecialPropertyModifier(name, modifyFunction, getFunction) {
|
function registerSpecialPropertyModifier(name, modifyFunction, getFunction) {
|
||||||
@ -190,7 +182,7 @@ function registerSpecialPropertySplitter(name, splitFunction, parameters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The "FrameTicker" object is an object used to feed new frames to
|
// The 'FrameTicker' object is an object used to feed new frames to
|
||||||
// Tweener so it can update values and redraw. The default frame
|
// Tweener so it can update values and redraw. The default frame
|
||||||
// ticker for Tweener just uses a simple timeout at a fixed frame rate
|
// ticker for Tweener just uses a simple timeout at a fixed frame rate
|
||||||
// and has no idea of "catching up" by dropping frames.
|
// and has no idea of "catching up" by dropping frames.
|
||||||
@ -215,12 +207,19 @@ ClutterFrameTicker.prototype = {
|
|||||||
// when we need to stop, so use 1000 seconds as "infinity"
|
// when we need to stop, so use 1000 seconds as "infinity"
|
||||||
this._timeline = new Clutter.Timeline({ duration: 1000*1000 });
|
this._timeline = new Clutter.Timeline({ duration: 1000*1000 });
|
||||||
this._startTime = -1;
|
this._startTime = -1;
|
||||||
this._currentTime = -1;
|
|
||||||
|
|
||||||
this._timeline.connect('new-frame', Lang.bind(this,
|
this._timeline.connect('new-frame', Lang.bind(this,
|
||||||
function(timeline, frame) {
|
function(timeline, frame) {
|
||||||
this._onNewFrame(frame);
|
this._onNewFrame(frame);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
let perf_log = Shell.PerfLog.get_default();
|
||||||
|
perf_log.define_event("tweener.framePrepareStart",
|
||||||
|
"Start of a new animation frame",
|
||||||
|
"");
|
||||||
|
perf_log.define_event("tweener.framePrepareDone",
|
||||||
|
"Finished preparing frame",
|
||||||
|
"");
|
||||||
},
|
},
|
||||||
|
|
||||||
_onNewFrame : function(frame) {
|
_onNewFrame : function(frame) {
|
||||||
@ -233,22 +232,27 @@ ClutterFrameTicker.prototype = {
|
|||||||
this._startTime = this._timeline.get_elapsed_time();
|
this._startTime = this._timeline.get_elapsed_time();
|
||||||
|
|
||||||
// currentTime is in milliseconds
|
// currentTime is in milliseconds
|
||||||
this._currentTime = (this._timeline.get_elapsed_time() - this._startTime) / slowDownFactor;
|
let perf_log = Shell.PerfLog.get_default();
|
||||||
|
perf_log.event("tweener.framePrepareStart");
|
||||||
this.emit('prepare-frame');
|
this.emit('prepare-frame');
|
||||||
|
perf_log.event("tweener.framePrepareDone");
|
||||||
},
|
},
|
||||||
|
|
||||||
getTime : function() {
|
getTime : function() {
|
||||||
return this._currentTime;
|
return this._timeline.get_elapsed_time();
|
||||||
},
|
},
|
||||||
|
|
||||||
start : function() {
|
start : function() {
|
||||||
|
if (St.get_slow_down_factor() > 0)
|
||||||
|
Tweener.setTimeScale(1 / St.get_slow_down_factor());
|
||||||
this._timeline.start();
|
this._timeline.start();
|
||||||
|
global.begin_work();
|
||||||
},
|
},
|
||||||
|
|
||||||
stop : function() {
|
stop : function() {
|
||||||
this._timeline.stop();
|
this._timeline.stop();
|
||||||
this._startTime = -1;
|
this._startTime = -1;
|
||||||
this._currentTime = -1;
|
global.end_work();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
364
js/ui/widget.js
@ -1,364 +0,0 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
|
||||||
const Gio = imports.gi.Gio;
|
|
||||||
const Gtk = imports.gi.Gtk;
|
|
||||||
const Mainloop = imports.mainloop;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Pango = imports.gi.Pango;
|
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const Signals = imports.signals;
|
|
||||||
const Gettext = imports.gettext.domain('gnome-shell');
|
|
||||||
const _ = Gettext.gettext;
|
|
||||||
|
|
||||||
const AppFavorites = imports.ui.appFavorites;
|
|
||||||
const DocInfo = imports.misc.docInfo;
|
|
||||||
|
|
||||||
const COLLAPSED_WIDTH = 24;
|
|
||||||
const EXPANDED_WIDTH = 200;
|
|
||||||
|
|
||||||
const STATE_EXPANDED = 0;
|
|
||||||
const STATE_COLLAPSING = 1;
|
|
||||||
const STATE_COLLAPSED = 2;
|
|
||||||
const STATE_EXPANDING = 3;
|
|
||||||
const STATE_POPPING_OUT = 4;
|
|
||||||
const STATE_POPPED_OUT = 5;
|
|
||||||
const STATE_POPPING_IN = 6;
|
|
||||||
|
|
||||||
function Widget() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget.prototype = {
|
|
||||||
// _init():
|
|
||||||
//
|
|
||||||
// Your widget constructor. Your constructor function should look
|
|
||||||
// like:
|
|
||||||
//
|
|
||||||
// function MyWidgetType() {
|
|
||||||
// this._init.apply(this, arguments);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// and your _init method should start by doing:
|
|
||||||
//
|
|
||||||
// Widget.Widget.prototype._init.apply(this, arguments);
|
|
||||||
//
|
|
||||||
// The _init method must define a field named "actor" containing
|
|
||||||
// the Clutter.Actor to show in expanded mode. This actor will be
|
|
||||||
// clipped to Widget.EXPANDED_WIDTH. Most widgets will also define
|
|
||||||
// a field named "title" containing the title string to show above
|
|
||||||
// the widget in the sidebar.
|
|
||||||
//
|
|
||||||
// If you want to have a separate collapsed view, you can define a
|
|
||||||
// field "collapsedActor" containing the Clutter.Actor to show in
|
|
||||||
// that mode. (It may be the same actor.) This actor will be
|
|
||||||
// clipped to Widget.COLLAPSED_WIDTH, and will normally end up
|
|
||||||
// having the same height as the main actor.
|
|
||||||
//
|
|
||||||
// If you do not set a collapsedActor, then you must set a title,
|
|
||||||
// since that is what will be displayed in collapsed mode, and
|
|
||||||
// in this case (and only in this case), the widget will support
|
|
||||||
// pop-out, meaning that if the user hovers over its title while
|
|
||||||
// the sidebar is collapsed, the widget's expanded view will pop
|
|
||||||
// out of the sidebar until either the cursor moves out of it,
|
|
||||||
// or else the widget calls this.activated() on itself.
|
|
||||||
_init: function (initialState) {
|
|
||||||
this.state = initialState;
|
|
||||||
},
|
|
||||||
|
|
||||||
// destroy():
|
|
||||||
//
|
|
||||||
// Optional. Will be called when the widget is removed from the
|
|
||||||
// sidebar. (Note that you don't need to destroy the actors,
|
|
||||||
// since they will be destroyed for you.)
|
|
||||||
|
|
||||||
// collapse():
|
|
||||||
//
|
|
||||||
// Optional. Called during the sidebar collapse process, at the
|
|
||||||
// point when the expanded sidebar has slid offscreen, but the
|
|
||||||
// collapsed sidebar has not yet slid onscreen.
|
|
||||||
|
|
||||||
// expand():
|
|
||||||
//
|
|
||||||
// Optional. Called during the sidebar expand process, at the
|
|
||||||
// point when the collapsed sidebar has slid offscreen, but the
|
|
||||||
// expanded sidebar has not yet slid onscreen.
|
|
||||||
|
|
||||||
// activated():
|
|
||||||
//
|
|
||||||
// Emits the "activated" signal for you, which will cause pop-out
|
|
||||||
// to end.
|
|
||||||
activated: function() {
|
|
||||||
this.emit('activated');
|
|
||||||
}
|
|
||||||
|
|
||||||
// state:
|
|
||||||
//
|
|
||||||
// A field set on your widget by the sidebar. Will contain one of
|
|
||||||
// the Widget.STATE_* values. (Eg, Widget.STATE_EXPANDED).
|
|
||||||
};
|
|
||||||
|
|
||||||
Signals.addSignalMethods(Widget.prototype);
|
|
||||||
|
|
||||||
|
|
||||||
function ClockWidget() {
|
|
||||||
this._init.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClockWidget.prototype = {
|
|
||||||
__proto__ : Widget.prototype,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
Widget.prototype._init.apply(this, arguments);
|
|
||||||
|
|
||||||
this.actor = new Clutter.Text({ font_name: "Sans Bold 16px",
|
|
||||||
text: "",
|
|
||||||
// Give an explicit height to ensure
|
|
||||||
// it's the same in both modes
|
|
||||||
height: COLLAPSED_WIDTH });
|
|
||||||
|
|
||||||
this.collapsedActor = new Clutter.CairoTexture({ width: COLLAPSED_WIDTH,
|
|
||||||
height: COLLAPSED_WIDTH,
|
|
||||||
surface_width: COLLAPSED_WIDTH,
|
|
||||||
surface_height: COLLAPSED_WIDTH });
|
|
||||||
|
|
||||||
this._update();
|
|
||||||
},
|
|
||||||
|
|
||||||
destroy: function() {
|
|
||||||
if (this.timer)
|
|
||||||
Mainloop.source_remove(this.timer);
|
|
||||||
},
|
|
||||||
|
|
||||||
expand: function() {
|
|
||||||
this._update();
|
|
||||||
},
|
|
||||||
|
|
||||||
collapse: function() {
|
|
||||||
this._update();
|
|
||||||
},
|
|
||||||
|
|
||||||
_update: function() {
|
|
||||||
let time = new Date();
|
|
||||||
let msec_remaining = 60000 - (1000 * time.getSeconds() +
|
|
||||||
time.getMilliseconds());
|
|
||||||
if (msec_remaining < 500) {
|
|
||||||
time.setMinutes(time.getMinutes() + 1);
|
|
||||||
msec_remaining += 60000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state == STATE_COLLAPSED || this.state == STATE_COLLAPSING)
|
|
||||||
this._updateCairo(time);
|
|
||||||
else
|
|
||||||
this._updateText(time);
|
|
||||||
|
|
||||||
if (this.timer)
|
|
||||||
Mainloop.source_remove(this.timer);
|
|
||||||
this.timer = Mainloop.timeout_add(msec_remaining, Lang.bind(this, this._update));
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateText: function(time) {
|
|
||||||
// Translators: This is a time format.
|
|
||||||
this.actor.set_text(time.toLocaleFormat(_("%H:%M")));
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateCairo: function(time) {
|
|
||||||
Shell.draw_clock(this.collapsedActor,
|
|
||||||
time.getHours() % 12,
|
|
||||||
time.getMinutes());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const ITEM_ICON_SIZE = 48;
|
|
||||||
const ITEM_PADDING = 1;
|
|
||||||
const ITEM_SPACING = 4;
|
|
||||||
|
|
||||||
const ITEM_BG_COLOR = new Clutter.Color();
|
|
||||||
ITEM_BG_COLOR.from_pixel(0x00000000);
|
|
||||||
const ITEM_NAME_COLOR = new Clutter.Color();
|
|
||||||
ITEM_NAME_COLOR.from_pixel(0x000000ff);
|
|
||||||
|
|
||||||
function LauncherWidget() {
|
|
||||||
this._init.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
LauncherWidget.prototype = {
|
|
||||||
__proto__ : Widget.prototype,
|
|
||||||
|
|
||||||
addItem : function(info) {
|
|
||||||
let item = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
|
||||||
width: EXPANDED_WIDTH,
|
|
||||||
height: ITEM_ICON_SIZE,
|
|
||||||
padding: ITEM_PADDING,
|
|
||||||
spacing: ITEM_SPACING,
|
|
||||||
reactive: true });
|
|
||||||
item._info = info;
|
|
||||||
item.append(info.createIcon(ITEM_ICON_SIZE), Big.BoxPackFlags.NONE);
|
|
||||||
item.append(new Clutter.Text({ color: ITEM_NAME_COLOR,
|
|
||||||
font_name: "Sans 14px",
|
|
||||||
ellipsize: Pango.EllipsizeMode.END,
|
|
||||||
text: info.name }),
|
|
||||||
Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
this.actor.append(item, Big.BoxPackFlags.NONE);
|
|
||||||
item.connect('button-press-event', Lang.bind(this, this._buttonPress));
|
|
||||||
item.connect('button-release-event', Lang.bind(this, this._buttonRelease));
|
|
||||||
item.connect('leave-event', Lang.bind(this, this._leave));
|
|
||||||
item.connect('enter-event', Lang.bind(this, this._enter));
|
|
||||||
|
|
||||||
if (!this.collapsedActor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
item = new Big.Box({ width: COLLAPSED_WIDTH,
|
|
||||||
height: COLLAPSED_WIDTH,
|
|
||||||
padding: ITEM_PADDING,
|
|
||||||
reactive: true });
|
|
||||||
item._info = info;
|
|
||||||
item.append(info.createIcon(COLLAPSED_WIDTH - 2 * ITEM_PADDING),
|
|
||||||
Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
this.collapsedActor.append(item, Big.BoxPackFlags.NONE);
|
|
||||||
item.connect('button-press-event', Lang.bind(this, this._buttonPress));
|
|
||||||
item.connect('button-release-event', Lang.bind(this, this._buttonRelease));
|
|
||||||
item.connect('leave-event', Lang.bind(this, this._leave));
|
|
||||||
item.connect('enter-event', Lang.bind(this, this._enter));
|
|
||||||
},
|
|
||||||
|
|
||||||
clear : function() {
|
|
||||||
let children, i;
|
|
||||||
|
|
||||||
children = this.actor.get_children();
|
|
||||||
for (i = 0; i < children.length; i++)
|
|
||||||
children[i].destroy();
|
|
||||||
|
|
||||||
if (this.collapsedActor) {
|
|
||||||
children = this.collapsedActor.get_children();
|
|
||||||
for (i = 0; i < children.length; i++)
|
|
||||||
children[i].destroy();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_buttonPress : function(item) {
|
|
||||||
Clutter.grab_pointer(item);
|
|
||||||
item._buttonDown = true;
|
|
||||||
item._inItem = true;
|
|
||||||
this._updateItemState(item);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_leave : function(item, evt) {
|
|
||||||
if (evt.get_source() == item && item._buttonDown) {
|
|
||||||
item._inItem = false;
|
|
||||||
this._updateItemState(item);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_enter : function(item, evt) {
|
|
||||||
if (evt.get_source() == item && item._buttonDown) {
|
|
||||||
item._inItem = true;
|
|
||||||
this._updateItemState(item);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_buttonRelease : function(item) {
|
|
||||||
Clutter.ungrab_pointer(item);
|
|
||||||
item._buttonDown = false;
|
|
||||||
this._updateItemState(item);
|
|
||||||
|
|
||||||
if (item._inItem) {
|
|
||||||
item._info.launch();
|
|
||||||
this.activated();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateItemState : function(item) {
|
|
||||||
if (item._buttonDown && item._inItem) {
|
|
||||||
item.padding_top = item.padding_left = 2 * ITEM_PADDING;
|
|
||||||
item.padding_bottom = item.padding_right = 0;
|
|
||||||
} else
|
|
||||||
item.padding = ITEM_PADDING;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function AppsWidgetInfo(appInfo) {
|
|
||||||
this._init(appInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppsWidgetInfo.prototype = {
|
|
||||||
_init : function(appInfo) {
|
|
||||||
this._info = appInfo;
|
|
||||||
this.name = appInfo.get_name();
|
|
||||||
},
|
|
||||||
|
|
||||||
createIcon : function(size) {
|
|
||||||
return this._info.create_icon_texture(size);
|
|
||||||
},
|
|
||||||
|
|
||||||
launch : function() {
|
|
||||||
this._info.launch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function AppsWidget() {
|
|
||||||
this._init.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppsWidget.prototype = {
|
|
||||||
__proto__ : LauncherWidget.prototype,
|
|
||||||
|
|
||||||
_init : function() {
|
|
||||||
Widget.prototype._init.apply(this, arguments);
|
|
||||||
|
|
||||||
this.title = _("Applications");
|
|
||||||
this.actor = new Big.Box({ spacing: 2 });
|
|
||||||
this.collapsedActor = new Big.Box({ spacing: 2});
|
|
||||||
|
|
||||||
let appSystem = Shell.AppSystem.get_default();
|
|
||||||
let apps = AppFavorites.getAppFavorites().getFavorites();
|
|
||||||
for (let i = 0; i < apps.length; i++) {
|
|
||||||
this.addItem(new AppsWidgetInfo(apps[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function RecentDocsWidget() {
|
|
||||||
this._init.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
RecentDocsWidget.prototype = {
|
|
||||||
__proto__ : LauncherWidget.prototype,
|
|
||||||
|
|
||||||
_init : function() {
|
|
||||||
Widget.prototype._init.apply(this, arguments);
|
|
||||||
|
|
||||||
this.title = _("Recent Documents");
|
|
||||||
this.actor = new Big.Box({ spacing: 2 });
|
|
||||||
|
|
||||||
this._recentManager = Gtk.RecentManager.get_default();
|
|
||||||
this._recentManager.connect('changed', Lang.bind(this, this._recentChanged));
|
|
||||||
this._recentChanged();
|
|
||||||
},
|
|
||||||
|
|
||||||
_recentChanged: function() {
|
|
||||||
let i;
|
|
||||||
|
|
||||||
this.clear();
|
|
||||||
|
|
||||||
let items = [];
|
|
||||||
let docs = this._recentManager.get_items();
|
|
||||||
for (i = 0; i < docs.length; i++) {
|
|
||||||
let docInfo = new DocInfo.DocInfo (docs[i]);
|
|
||||||
|
|
||||||
items.push(docInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
items.sort(function (a,b) { return b.timestamp - a.timestamp; });
|
|
||||||
for (i = 0; i < Math.min(items.length, 5); i++)
|
|
||||||
this.addItem(items[i]);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,381 +0,0 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
const Big = imports.gi.Big;
|
|
||||||
const Clutter = imports.gi.Clutter;
|
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Mainloop = imports.mainloop;
|
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
|
||||||
const Tweener = imports.ui.tweener;
|
|
||||||
const Widget = imports.ui.widget;
|
|
||||||
|
|
||||||
const WIDGETBOX_BG_COLOR = new Clutter.Color();
|
|
||||||
WIDGETBOX_BG_COLOR.from_pixel(0xf0f0f0ff);
|
|
||||||
const BLACK = new Clutter.Color();
|
|
||||||
BLACK.from_pixel(0x000000ff);
|
|
||||||
|
|
||||||
const WIDGETBOX_PADDING = 2;
|
|
||||||
const ANIMATION_TIME = 0.5;
|
|
||||||
const POP_IN_LAG = 250; /* milliseconds */
|
|
||||||
|
|
||||||
function WidgetBox(widget, expanded) {
|
|
||||||
this._init(widget, expanded);
|
|
||||||
}
|
|
||||||
|
|
||||||
WidgetBox.prototype = {
|
|
||||||
_init: function(widget, expanded) {
|
|
||||||
this.state = expanded ? Widget.STATE_EXPANDED : Widget.STATE_COLLAPSED;
|
|
||||||
|
|
||||||
if (widget instanceof Widget.Widget) {
|
|
||||||
this._widget = widget;
|
|
||||||
this._widget.state = this.state;
|
|
||||||
} else {
|
|
||||||
let ctor = this._ctorFromName(widget);
|
|
||||||
this._widget = new ctor(this.state);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._widget.actor)
|
|
||||||
throw new Error("widget has no actor");
|
|
||||||
else if (!this._widget.title && !this._widget.collapsedActor)
|
|
||||||
throw new Error("widget has neither title nor collapsedActor");
|
|
||||||
|
|
||||||
this.state = expanded ? Widget.STATE_EXPANDED : Widget.STATE_COLLAPSED;
|
|
||||||
|
|
||||||
// The structure of a WidgetBox:
|
|
||||||
//
|
|
||||||
// The top level is a Clutter.Group, which exists to make
|
|
||||||
// pop-out work correctly; when another widget pops out, its
|
|
||||||
// width will increase, which will in turn cause the sidebar's
|
|
||||||
// width to increase, which will cause the sidebar to increase
|
|
||||||
// the width of each of its children (the WidgetBoxes). But we
|
|
||||||
// don't want the non-popped-out widgets to expand, so we make
|
|
||||||
// the top-level actor be a Clutter.Group, which will accept
|
|
||||||
// the new width from the Sidebar, but not impose it on its
|
|
||||||
// own child.
|
|
||||||
//
|
|
||||||
// Inside the toplevel group is a horizontal Big.Box
|
|
||||||
// containing 2 Clutter.Groups; one for the collapsed state
|
|
||||||
// (cgroup) and one for the expanded state (egroup). Each
|
|
||||||
// group contains a single vertical Big.Box (cbox and ebox
|
|
||||||
// respectively), which have the appropriate fixed width. The
|
|
||||||
// cbox contains either the collapsed widget actor or else the
|
|
||||||
// rotated title. The ebox contains the horizontal title (if
|
|
||||||
// any), separator line, and the expanded widget actor. (If
|
|
||||||
// the widget doesn't have a collapsed actor, and therefore
|
|
||||||
// supports pop-out, then it will also have a vertical line
|
|
||||||
// between the two groups, which will only be shown during
|
|
||||||
// pop-out.)
|
|
||||||
//
|
|
||||||
// In the expanded view, cgroup is hidden and egroup is shown.
|
|
||||||
// When animating to the collapsed view, first the ebox is
|
|
||||||
// slid offscreen by giving it increasingly negative x
|
|
||||||
// coordinates within egroup. Then once it's fully offscreen,
|
|
||||||
// we hide egroup, show cgroup, and slide cbox back in in the
|
|
||||||
// same way.
|
|
||||||
//
|
|
||||||
// The pop-out view works similarly to the second half of the
|
|
||||||
// collapsed-to-expanded transition, except that the
|
|
||||||
// horizontal title gets hidden to avoid duplication.
|
|
||||||
|
|
||||||
this.actor = new Clutter.Group();
|
|
||||||
this._hbox = new Big.Box({ background_color: WIDGETBOX_BG_COLOR,
|
|
||||||
padding_top: WIDGETBOX_PADDING,
|
|
||||||
padding_bottom: WIDGETBOX_PADDING,
|
|
||||||
padding_right: WIDGETBOX_PADDING,
|
|
||||||
// Left padding is here to make up for
|
|
||||||
// the X offset used for the sidebar
|
|
||||||
// to hide its rounded corners
|
|
||||||
padding_left: 2 * WIDGETBOX_PADDING,
|
|
||||||
spacing: WIDGETBOX_PADDING,
|
|
||||||
corner_radius: WIDGETBOX_PADDING,
|
|
||||||
orientation: Big.BoxOrientation.HORIZONTAL,
|
|
||||||
reactive: true });
|
|
||||||
this.actor.add_actor(this._hbox);
|
|
||||||
|
|
||||||
this._cgroup = new Clutter.Group({ clip_to_allocation: true });
|
|
||||||
this._hbox.append(this._cgroup, Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
this._cbox = new Big.Box({ width: Widget.COLLAPSED_WIDTH,
|
|
||||||
clip_to_allocation: true });
|
|
||||||
this._cgroup.add_actor(this._cbox);
|
|
||||||
|
|
||||||
if (this._widget.collapsedActor) {
|
|
||||||
if (this._widget.collapsedActor == this._widget.actor)
|
|
||||||
this._singleActor = true;
|
|
||||||
else {
|
|
||||||
this._cbox.append(this._widget.collapsedActor,
|
|
||||||
Big.BoxPackFlags.NONE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let vtitle = new Clutter.Text({ font_name: "Sans 16px",
|
|
||||||
text: this._widget.title,
|
|
||||||
rotation_angle_z: -90.0 });
|
|
||||||
let signalId = vtitle.connect('notify::allocation',
|
|
||||||
function () {
|
|
||||||
vtitle.disconnect(signalId);
|
|
||||||
vtitle.set_anchor_point(vtitle.natural_width, 0);
|
|
||||||
vtitle.set_size(vtitle.natural_height,
|
|
||||||
vtitle.natural_width);
|
|
||||||
});
|
|
||||||
this._vtitle = vtitle;
|
|
||||||
this._cbox.append(this._vtitle, Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
this._vline = new Clutter.Rectangle({ color: BLACK, width: 1 });
|
|
||||||
this._hbox.append(this._vline, Big.BoxPackFlags.NONE);
|
|
||||||
this._vline.hide();
|
|
||||||
|
|
||||||
// Set up pop-out
|
|
||||||
this._eventHandler = this._hbox.connect('captured-event',
|
|
||||||
Lang.bind(this, this._popEventHandler));
|
|
||||||
this._activationHandler = this._widget.connect('activated',
|
|
||||||
Lang.bind(this, this._activationHandler));
|
|
||||||
}
|
|
||||||
|
|
||||||
this._egroup = new Clutter.Group({ clip_to_allocation: true });
|
|
||||||
this._hbox.append(this._egroup, Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
this._ebox = new Big.Box({ spacing: WIDGETBOX_PADDING,
|
|
||||||
width: Widget.EXPANDED_WIDTH,
|
|
||||||
clip_to_allocation: true });
|
|
||||||
this._egroup.add_actor(this._ebox);
|
|
||||||
|
|
||||||
if (this._widget.title) {
|
|
||||||
this._htitle = new Clutter.Text({ font_name: "Sans 16px",
|
|
||||||
text: this._widget.title });
|
|
||||||
this._ebox.append(this._htitle, Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
this._hline = new Clutter.Rectangle({ color: BLACK, height: 1 });
|
|
||||||
this._ebox.append(this._hline, Big.BoxPackFlags.NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._ebox.append(this._widget.actor, Big.BoxPackFlags.NONE);
|
|
||||||
|
|
||||||
if (expanded)
|
|
||||||
this._setWidgetExpanded();
|
|
||||||
else
|
|
||||||
this._setWidgetCollapsed();
|
|
||||||
},
|
|
||||||
|
|
||||||
// Given a name like "imports.ui.widget.ClockWidget", turn that
|
|
||||||
// into a constructor function
|
|
||||||
_ctorFromName: function(name) {
|
|
||||||
// Make sure it's a valid import
|
|
||||||
if (!name.match(/^imports(\.[a-zA-Z0-9_]+)+$/))
|
|
||||||
throw new Error("widget name must start with 'imports.'");
|
|
||||||
if (name.match(/^imports\.gi\./))
|
|
||||||
throw new Error("cannot import widget from GIR");
|
|
||||||
|
|
||||||
let ctor = eval(name);
|
|
||||||
|
|
||||||
// Make sure it's really a constructor
|
|
||||||
if (!ctor || typeof(ctor) != "function")
|
|
||||||
throw new Error("widget name is not a constructor");
|
|
||||||
|
|
||||||
// Make sure it's a widget
|
|
||||||
let proto = ctor.prototype;
|
|
||||||
while (proto && proto != Widget.Widget.prototype)
|
|
||||||
proto = proto.__proto__;
|
|
||||||
if (!proto)
|
|
||||||
throw new Error("widget does not inherit from Widget prototype");
|
|
||||||
|
|
||||||
return ctor;
|
|
||||||
},
|
|
||||||
|
|
||||||
expand: function() {
|
|
||||||
Tweener.addTween(this._cbox, { x: -Widget.COLLAPSED_WIDTH,
|
|
||||||
time: ANIMATION_TIME / 2,
|
|
||||||
transition: "easeOutQuad",
|
|
||||||
onComplete: this._expandPart1Complete,
|
|
||||||
onCompleteScope: this });
|
|
||||||
this.state = this._widget.state = Widget.STATE_EXPANDING;
|
|
||||||
},
|
|
||||||
|
|
||||||
_setWidgetExpanded: function() {
|
|
||||||
this._cgroup.hide();
|
|
||||||
this._egroup.show();
|
|
||||||
|
|
||||||
if (this._singleActor) {
|
|
||||||
this._widget.actor.unparent();
|
|
||||||
this._ebox.append(this._widget.actor, Big.BoxPackFlags.NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._htitle) {
|
|
||||||
this._htitle.show();
|
|
||||||
this._hline.show();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_expandPart1Complete: function() {
|
|
||||||
this._cbox.x = 0;
|
|
||||||
this._setWidgetExpanded();
|
|
||||||
|
|
||||||
if (this._widget.expand) {
|
|
||||||
try {
|
|
||||||
this._widget.expand();
|
|
||||||
} catch (e) {
|
|
||||||
logError(e, 'Widget failed to expand');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._ebox.x = -Widget.EXPANDED_WIDTH;
|
|
||||||
Tweener.addTween(this._ebox, { x: 0,
|
|
||||||
time: ANIMATION_TIME / 2,
|
|
||||||
transition: "easeOutQuad",
|
|
||||||
onComplete: this._expandComplete,
|
|
||||||
onCompleteScope: this });
|
|
||||||
},
|
|
||||||
|
|
||||||
_expandComplete: function() {
|
|
||||||
this.state = this._widget.state = Widget.STATE_EXPANDED;
|
|
||||||
},
|
|
||||||
|
|
||||||
collapse: function() {
|
|
||||||
Tweener.addTween(this._ebox, { x: -Widget.EXPANDED_WIDTH,
|
|
||||||
time: ANIMATION_TIME / 2,
|
|
||||||
transition: "easeOutQuad",
|
|
||||||
onComplete: this._collapsePart1Complete,
|
|
||||||
onCompleteScope: this });
|
|
||||||
this.state = this._widget.state = Widget.STATE_COLLAPSING;
|
|
||||||
},
|
|
||||||
|
|
||||||
_setWidgetCollapsed: function() {
|
|
||||||
this._egroup.hide();
|
|
||||||
this._cgroup.show();
|
|
||||||
|
|
||||||
if (this._singleActor) {
|
|
||||||
this._widget.actor.unparent();
|
|
||||||
this._cbox.append(this._widget.actor, Big.BoxPackFlags.NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._htitle) {
|
|
||||||
this._htitle.hide();
|
|
||||||
this._hline.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._vtitle)
|
|
||||||
this._cbox.height = this._ebox.height;
|
|
||||||
},
|
|
||||||
|
|
||||||
_collapsePart1Complete: function() {
|
|
||||||
this._ebox.x = 0;
|
|
||||||
this._setWidgetCollapsed();
|
|
||||||
|
|
||||||
if (this._widget.collapse) {
|
|
||||||
try {
|
|
||||||
this._widget.collapse();
|
|
||||||
} catch (e) {
|
|
||||||
logError(e, 'Widget failed to collapse');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._cbox.x = -Widget.COLLAPSED_WIDTH;
|
|
||||||
Tweener.addTween(this._cbox, { x: 0,
|
|
||||||
time: ANIMATION_TIME / 2,
|
|
||||||
transition: "easeOutQuad",
|
|
||||||
onComplete: this._collapseComplete,
|
|
||||||
onCompleteScope: this });
|
|
||||||
},
|
|
||||||
|
|
||||||
_collapseComplete: function() {
|
|
||||||
this.state = this._widget.state = Widget.STATE_COLLAPSED;
|
|
||||||
},
|
|
||||||
|
|
||||||
_popEventHandler: function(actor, event) {
|
|
||||||
let type = event.type();
|
|
||||||
|
|
||||||
if (type == Clutter.EventType.ENTER) {
|
|
||||||
this._clearPopInTimeout();
|
|
||||||
if (this.state == Widget.STATE_COLLAPSED ||
|
|
||||||
this.state == Widget.STATE_COLLAPSING) {
|
|
||||||
this._popOut();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (type == Clutter.EventType.LEAVE &&
|
|
||||||
(this.state == Widget.STATE_POPPED_OUT ||
|
|
||||||
this.state == Widget.STATE_POPPING_OUT)) {
|
|
||||||
// If moving into another actor within this._hbox, let the
|
|
||||||
// event be propagated
|
|
||||||
let into = event.get_related();
|
|
||||||
while (into) {
|
|
||||||
if (into == this._hbox)
|
|
||||||
return false;
|
|
||||||
into = into.get_parent();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Else, moving out of this._hbox
|
|
||||||
this._setPopInTimeout();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_activationHandler: function() {
|
|
||||||
if (this.state == Widget.STATE_POPPED_OUT)
|
|
||||||
this._popIn();
|
|
||||||
},
|
|
||||||
|
|
||||||
_popOut: function() {
|
|
||||||
if (this.state != Widget.STATE_COLLAPSED &&
|
|
||||||
this.state != Widget.STATE_COLLAPSING)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._vline.show();
|
|
||||||
this._egroup.show();
|
|
||||||
this._ebox.x = -Widget.EXPANDED_WIDTH;
|
|
||||||
Tweener.addTween(this._ebox, { x: 0,
|
|
||||||
time: ANIMATION_TIME / 2,
|
|
||||||
transition: "easeOutQuad",
|
|
||||||
onComplete: this._popOutComplete,
|
|
||||||
onCompleteScope: this });
|
|
||||||
this.state = this._widget.state = Widget.STATE_POPPING_OUT;
|
|
||||||
|
|
||||||
Main.chrome.trackActor(this._hbox, { affectsStruts: false });
|
|
||||||
},
|
|
||||||
|
|
||||||
_popOutComplete: function() {
|
|
||||||
this.state = this._widget.state = Widget.STATE_POPPED_OUT;
|
|
||||||
},
|
|
||||||
|
|
||||||
_setPopInTimeout: function() {
|
|
||||||
this._clearPopInTimeout();
|
|
||||||
this._popInTimeout = Mainloop.timeout_add(POP_IN_LAG, Lang.bind(this, function () { this._popIn(); return false; }));
|
|
||||||
},
|
|
||||||
|
|
||||||
_clearPopInTimeout: function() {
|
|
||||||
if (this._popInTimeout) {
|
|
||||||
Mainloop.source_remove(this._popInTimeout);
|
|
||||||
delete this._popInTimeout;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_popIn: function() {
|
|
||||||
this._clearPopInTimeout();
|
|
||||||
|
|
||||||
if (this.state != Widget.STATE_POPPED_OUT &&
|
|
||||||
this.state != Widget.STATE_POPPING_OUT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Tweener.addTween(this._ebox, { x: -Widget.EXPANDED_WIDTH,
|
|
||||||
time: ANIMATION_TIME / 2,
|
|
||||||
transition: "easeOutQuad",
|
|
||||||
onComplete: this._popInComplete,
|
|
||||||
onCompleteScope: this });
|
|
||||||
},
|
|
||||||
|
|
||||||
_popInComplete: function() {
|
|
||||||
this.state = this._widget.state = Widget.STATE_COLLAPSED;
|
|
||||||
this._vline.hide();
|
|
||||||
this._egroup.hide();
|
|
||||||
this._ebox.x = 0;
|
|
||||||
|
|
||||||
Main.chrome.untrackActor(this._hbox);
|
|
||||||
},
|
|
||||||
|
|
||||||
destroy: function() {
|
|
||||||
if (this._widget.destroy)
|
|
||||||
this._widget.destroy();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
109
js/ui/windowAttentionHandler.js
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
|
const Gettext = imports.gettext.domain('gnome-shell');
|
||||||
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const MessageTray = imports.ui.messageTray;
|
||||||
|
|
||||||
|
function WindowAttentionHandler() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowAttentionHandler.prototype = {
|
||||||
|
_init : function() {
|
||||||
|
let display = global.screen.get_display();
|
||||||
|
display.connect('window-demands-attention', Lang.bind(this, this._onWindowDemandsAttention));
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
|
this._startupIds = {};
|
||||||
|
tracker.connect('startup-sequence-changed', Lang.bind(this, this._onStartupSequenceChanged));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onStartupSequenceChanged : function(tracker) {
|
||||||
|
let sequences = tracker.get_startup_sequences();
|
||||||
|
this._startupIds = {};
|
||||||
|
for(let i = 0; i < sequences.length; i++) {
|
||||||
|
this._startupIds[sequences[i].get_id()] = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_sourceId : function(appId) {
|
||||||
|
return 'attention-' + appId;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getTitle : function(app, window) {
|
||||||
|
if (this._startupIds[window.get_startup_id()])
|
||||||
|
return app.get_name();
|
||||||
|
else
|
||||||
|
return window.title;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getBanner : function(app, window) {
|
||||||
|
if (this._startupIds[window.get_startup_id()])
|
||||||
|
return _("%s has finished starting").format(app.get_name());
|
||||||
|
else
|
||||||
|
return _("'%s' is ready").format(window.title);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onWindowDemandsAttention : function(display, window) {
|
||||||
|
// We don't want to show the notification when the window is already focused,
|
||||||
|
// because this is rather pointless.
|
||||||
|
// Some apps (like GIMP) do things like setting the urgency hint on the
|
||||||
|
// toolbar windows which would result into a notification even though GIMP itself is
|
||||||
|
// focused.
|
||||||
|
// We are just ignoring the hint on skip_taskbar windows for now.
|
||||||
|
// (Which is the same behaviour as with metacity + panel)
|
||||||
|
|
||||||
|
if (!window || window.has_focus() || window.is_skip_taskbar())
|
||||||
|
return;
|
||||||
|
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
|
let app = tracker.get_window_app(window);
|
||||||
|
|
||||||
|
let source = Main.messageTray.getSource(this._sourceId(app.get_id()));
|
||||||
|
if (source == null) {
|
||||||
|
source = new Source(this._sourceId(app.get_id()), app, window);
|
||||||
|
Main.messageTray.add(source);
|
||||||
|
source.connect('clicked', Lang.bind(this, function() { source.destroy(); }));
|
||||||
|
}
|
||||||
|
|
||||||
|
let notification = new MessageTray.Notification(window.get_startup_id(), source, this._getTitle(app, window), this._getBanner(app, window), true);
|
||||||
|
source.notify(notification);
|
||||||
|
|
||||||
|
window.connect('notify::title', Lang.bind(this, function(win) {
|
||||||
|
notification.update(this._getTitle(app, win), this._getBanner(app, win), false);
|
||||||
|
}));
|
||||||
|
window.connect('notify::demands-attention', Lang.bind(this, function() { source.destroy(); }));
|
||||||
|
window.connect('focus', Lang.bind(this, function() { source.destroy(); }));
|
||||||
|
window.connect('unmanaged', Lang.bind(this, function() { source.destroy(); }));
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function Source(sourceId, app, window) {
|
||||||
|
this._init(sourceId, app, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
Source.prototype = {
|
||||||
|
__proto__ : MessageTray.Source.prototype,
|
||||||
|
|
||||||
|
_init: function(sourceId, app, window) {
|
||||||
|
MessageTray.Source.prototype._init.call(this, sourceId, app.get_name());
|
||||||
|
this._window = window;
|
||||||
|
this._app = app;
|
||||||
|
},
|
||||||
|
|
||||||
|
createIcon : function(size) {
|
||||||
|
return this._app.create_icon_texture(size);
|
||||||
|
},
|
||||||
|
|
||||||
|
clicked : function() {
|
||||||
|
Main.activateWindow(this._window);
|
||||||
|
MessageTray.Source.prototype.clicked.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -5,8 +5,10 @@ const Lang = imports.lang;
|
|||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
const AltTab = imports.ui.altTab;
|
const AltTab = imports.ui.altTab;
|
||||||
|
const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
@ -18,8 +20,9 @@ function WindowManager() {
|
|||||||
|
|
||||||
WindowManager.prototype = {
|
WindowManager.prototype = {
|
||||||
_init : function() {
|
_init : function() {
|
||||||
let shellwm = global.window_manager;
|
this._shellwm = global.window_manager;
|
||||||
|
|
||||||
|
this._keyBindingHandlers = [];
|
||||||
this._minimizing = [];
|
this._minimizing = [];
|
||||||
this._maximizing = [];
|
this._maximizing = [];
|
||||||
this._unmaximizing = [];
|
this._unmaximizing = [];
|
||||||
@ -27,21 +30,38 @@ WindowManager.prototype = {
|
|||||||
this._destroying = [];
|
this._destroying = [];
|
||||||
|
|
||||||
this._switchData = null;
|
this._switchData = null;
|
||||||
shellwm.connect('switch-workspace', Lang.bind(this, this._switchWorkspace));
|
this._shellwm.connect('kill-switch-workspace', Lang.bind(this, this._switchWorkspaceDone));
|
||||||
shellwm.connect('kill-switch-workspace', Lang.bind(this, this._switchWorkspaceDone));
|
this._shellwm.connect('kill-window-effects', Lang.bind(this, function (shellwm, actor) {
|
||||||
shellwm.connect('minimize', Lang.bind(this, this._minimizeWindow));
|
this._minimizeWindowDone(shellwm, actor);
|
||||||
shellwm.connect('kill-minimize', Lang.bind(this, this._minimizeWindowDone));
|
this._maximizeWindowDone(shellwm, actor);
|
||||||
shellwm.connect('maximize', Lang.bind(this, this._maximizeWindow));
|
this._unmaximizeWindowDone(shellwm, actor);
|
||||||
shellwm.connect('kill-maximize', Lang.bind(this, this._maximizeWindowDone));
|
this._mapWindowDone(shellwm, actor);
|
||||||
shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
|
this._destroyWindowDone(shellwm, actor);
|
||||||
shellwm.connect('kill-unmaximize', Lang.bind(this, this._unmaximizeWindowDone));
|
}));
|
||||||
shellwm.connect('map', Lang.bind(this, this._mapWindow));
|
|
||||||
shellwm.connect('kill-map', Lang.bind(this, this._mapWindowDone));
|
|
||||||
shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
|
||||||
shellwm.connect('kill-destroy', Lang.bind(this, this._destroyWindowDone));
|
|
||||||
|
|
||||||
shellwm.takeover_keybinding('switch_windows');
|
this._shellwm.connect('switch-workspace', Lang.bind(this, this._switchWorkspace));
|
||||||
shellwm.connect('keybinding::switch_windows', Lang.bind(this, this._startAppSwitcher));
|
this._shellwm.connect('minimize', Lang.bind(this, this._minimizeWindow));
|
||||||
|
this._shellwm.connect('maximize', Lang.bind(this, this._maximizeWindow));
|
||||||
|
this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
|
||||||
|
this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
|
||||||
|
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
||||||
|
|
||||||
|
this._workspaceSwitcherPopup = null;
|
||||||
|
this.setKeybindingHandler('switch_to_workspace_left', Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
|
this.setKeybindingHandler('switch_to_workspace_right', Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
|
this.setKeybindingHandler('switch_to_workspace_up', Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
|
this.setKeybindingHandler('switch_to_workspace_down', Lang.bind(this, this._showWorkspaceSwitcher));
|
||||||
|
this.setKeybindingHandler('switch_windows', Lang.bind(this, this._startAppSwitcher));
|
||||||
|
},
|
||||||
|
|
||||||
|
setKeybindingHandler: function(keybinding, handler){
|
||||||
|
if (this._keyBindingHandlers[keybinding])
|
||||||
|
this._shellwm.disconnect(this._keyBindingHandlers[keybinding]);
|
||||||
|
else
|
||||||
|
this._shellwm.takeover_keybinding(keybinding);
|
||||||
|
|
||||||
|
this._keyBindingHandlers[keybinding] =
|
||||||
|
this._shellwm.connect('keybinding::' + keybinding, handler);
|
||||||
},
|
},
|
||||||
|
|
||||||
_shouldAnimate : function(actor) {
|
_shouldAnimate : function(actor) {
|
||||||
@ -74,11 +94,19 @@ WindowManager.prototype = {
|
|||||||
* maybe TODO: get icon geometry passed through and move the window towards it?
|
* maybe TODO: get icon geometry passed through and move the window towards it?
|
||||||
*/
|
*/
|
||||||
this._minimizing.push(actor);
|
this._minimizing.push(actor);
|
||||||
|
|
||||||
|
let primary = global.get_primary_monitor();
|
||||||
|
let xDest = primary.x;
|
||||||
|
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
|
||||||
|
xDest += primary.width;
|
||||||
|
|
||||||
Tweener.addTween(actor,
|
Tweener.addTween(actor,
|
||||||
{ scale_x: 0.0,
|
{ scale_x: 0.0,
|
||||||
scale_y: 0.0,
|
scale_y: 0.0,
|
||||||
|
x: xDest,
|
||||||
|
y: 0,
|
||||||
time: WINDOW_ANIMATION_TIME,
|
time: WINDOW_ANIMATION_TIME,
|
||||||
transition: "easeOutQuad",
|
transition: 'easeOutQuad',
|
||||||
onComplete: this._minimizeWindowDone,
|
onComplete: this._minimizeWindowDone,
|
||||||
onCompleteScope: this,
|
onCompleteScope: this,
|
||||||
onCompleteParams: [shellwm, actor],
|
onCompleteParams: [shellwm, actor],
|
||||||
@ -127,17 +155,15 @@ WindowManager.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
actor.move_anchor_point_from_gravity(Clutter.Gravity.CENTER);
|
actor.opacity = 0;
|
||||||
actor.set_scale(0.0, 0.0);
|
|
||||||
actor.show();
|
actor.show();
|
||||||
|
|
||||||
/* scale window up from 0x0 to normal size */
|
/* Fade window in */
|
||||||
this._mapping.push(actor);
|
this._mapping.push(actor);
|
||||||
Tweener.addTween(actor,
|
Tweener.addTween(actor,
|
||||||
{ scale_x: 1.0,
|
{ opacity: 255,
|
||||||
scale_y: 1.0,
|
|
||||||
time: WINDOW_ANIMATION_TIME,
|
time: WINDOW_ANIMATION_TIME,
|
||||||
transition: "easeOutQuad",
|
transition: 'easeOutQuad',
|
||||||
onComplete: this._mapWindowDone,
|
onComplete: this._mapWindowDone,
|
||||||
onCompleteScope: this,
|
onCompleteScope: this,
|
||||||
onCompleteParams: [shellwm, actor],
|
onCompleteParams: [shellwm, actor],
|
||||||
@ -150,8 +176,7 @@ WindowManager.prototype = {
|
|||||||
_mapWindowDone : function(shellwm, actor) {
|
_mapWindowDone : function(shellwm, actor) {
|
||||||
if (this._removeEffect(this._mapping, actor)) {
|
if (this._removeEffect(this._mapping, actor)) {
|
||||||
Tweener.removeTweens(actor);
|
Tweener.removeTweens(actor);
|
||||||
actor.set_scale(1.0, 1.0);
|
actor.opacity = 255;
|
||||||
actor.move_anchor_point_from_gravity(Clutter.Gravity.NORTH_WEST);
|
|
||||||
shellwm.completed_map(actor);
|
shellwm.completed_map(actor);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -175,7 +200,7 @@ WindowManager.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let windows = shellwm.get_switch_workspace_actors();
|
let windows = global.get_windows();
|
||||||
|
|
||||||
/* @direction is the direction that the "camera" moves, so the
|
/* @direction is the direction that the "camera" moves, so the
|
||||||
* screen contents have to move one screen's worth in the
|
* screen contents have to move one screen's worth in the
|
||||||
@ -236,7 +261,7 @@ WindowManager.prototype = {
|
|||||||
{ x: xDest,
|
{ x: xDest,
|
||||||
y: yDest,
|
y: yDest,
|
||||||
time: WINDOW_ANIMATION_TIME,
|
time: WINDOW_ANIMATION_TIME,
|
||||||
transition: "easeOutQuad",
|
transition: 'easeOutQuad',
|
||||||
onComplete: this._switchWorkspaceDone,
|
onComplete: this._switchWorkspaceDone,
|
||||||
onCompleteScope: this,
|
onCompleteScope: this,
|
||||||
onCompleteParams: [shellwm]
|
onCompleteParams: [shellwm]
|
||||||
@ -245,7 +270,7 @@ WindowManager.prototype = {
|
|||||||
{ x: 0,
|
{ x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
time: WINDOW_ANIMATION_TIME,
|
time: WINDOW_ANIMATION_TIME,
|
||||||
transition: "easeOutQuad"
|
transition: 'easeOutQuad'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -272,9 +297,55 @@ WindowManager.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_startAppSwitcher : function(shellwm, binding, window, backwards) {
|
_startAppSwitcher : function(shellwm, binding, window, backwards) {
|
||||||
|
/* prevent a corner case where both popups show up at once */
|
||||||
|
if (this._workspaceSwitcherPopup != null)
|
||||||
|
this._workspaceSwitcherPopup.actor.hide();
|
||||||
|
|
||||||
let tabPopup = new AltTab.AltTabPopup();
|
let tabPopup = new AltTab.AltTabPopup();
|
||||||
|
|
||||||
if (!tabPopup.show(backwards))
|
if (!tabPopup.show(backwards))
|
||||||
tabPopup.destroy();
|
tabPopup.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
|
_showWorkspaceSwitcher : function(shellwm, binding, window, backwards) {
|
||||||
|
/* We don't support this kind of layout */
|
||||||
|
if (binding == 'switch_to_workspace_up' || binding == 'switch_to_workspace_down')
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (global.screen.n_workspaces == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this._workspaceSwitcherPopup == null)
|
||||||
|
this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
|
||||||
|
|
||||||
|
if (binding == 'switch_to_workspace_left') {
|
||||||
|
this.actionMoveWorkspaceLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (binding == 'switch_to_workspace_right') {
|
||||||
|
this.actionMoveWorkspaceRight();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actionMoveWorkspaceLeft: function() {
|
||||||
|
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||||
|
if (activeWorkspaceIndex > 0) {
|
||||||
|
global.screen.get_workspace_by_index(activeWorkspaceIndex - 1).activate(global.get_current_time());
|
||||||
|
if (!Main.overview.visible)
|
||||||
|
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.LEFT, activeWorkspaceIndex - 1);
|
||||||
|
} else if (!Main.overview.visible) {
|
||||||
|
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.LEFT, activeWorkspaceIndex);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actionMoveWorkspaceRight: function() {
|
||||||
|
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||||
|
if (activeWorkspaceIndex < global.screen.n_workspaces - 1) {
|
||||||
|
global.screen.get_workspace_by_index(activeWorkspaceIndex + 1).activate(global.get_current_time());
|
||||||
|
if (!Main.overview.visible)
|
||||||
|
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.RIGHT, activeWorkspaceIndex + 1);
|
||||||
|
} else if (!Main.overview.visible) {
|
||||||
|
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.RIGHT, activeWorkspaceIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
157
js/ui/workspaceSwitcherPopup.js
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const ANIMATION_TIME = 0.1;
|
||||||
|
const DISPLAY_TIMEOUT = 600;
|
||||||
|
|
||||||
|
const LEFT = -1;
|
||||||
|
const RIGHT = 1;
|
||||||
|
|
||||||
|
function WorkspaceSwitcherPopup() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkspaceSwitcherPopup.prototype = {
|
||||||
|
_init : function() {
|
||||||
|
this.actor = new St.Group({ reactive: true,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: global.screen_width,
|
||||||
|
height: global.screen_height,
|
||||||
|
style_class: 'workspace-switcher-group' });
|
||||||
|
Main.uiGroup.add_actor(this.actor);
|
||||||
|
|
||||||
|
this._container = new St.BoxLayout({ style_class: 'workspace-switcher-container' });
|
||||||
|
this._list = new Shell.GenericContainer({ style_class: 'workspace-switcher' });
|
||||||
|
this._itemSpacing = 0;
|
||||||
|
this._list.connect('style-changed', Lang.bind(this, function() {
|
||||||
|
let [found, spacing] = this._list.get_theme_node().get_length('spacing', false);
|
||||||
|
this._itemSpacing = (found) ? spacing : 0;
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._list.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
|
this._list.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
|
this._list.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
|
this._container.add(this._list);
|
||||||
|
|
||||||
|
this.actor.add_actor(this._container);
|
||||||
|
|
||||||
|
this._redraw();
|
||||||
|
|
||||||
|
this._position();
|
||||||
|
|
||||||
|
this.actor.show();
|
||||||
|
this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredWidth : function (actor, forHeight, alloc) {
|
||||||
|
let children = this._list.get_children();
|
||||||
|
let primary = global.get_primary_monitor();
|
||||||
|
|
||||||
|
let availwidth = primary.width;
|
||||||
|
availwidth -= this.actor.get_theme_node().get_horizontal_padding();
|
||||||
|
availwidth -= this._container.get_theme_node().get_horizontal_padding();
|
||||||
|
availwidth -= this._list.get_theme_node().get_horizontal_padding();
|
||||||
|
|
||||||
|
let width = 0;
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
let [childMinWidth, childNaturalWidth] = children[i].get_preferred_width(-1);
|
||||||
|
let [childMinHeight, childNaturalHeight] = children[i].get_preferred_height(childNaturalWidth);
|
||||||
|
width += childNaturalHeight * primary.width / primary.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
let spacing = this._itemSpacing * (global.screen.n_workspaces - 1);
|
||||||
|
width += spacing;
|
||||||
|
width = Math.min(width, availwidth);
|
||||||
|
|
||||||
|
this._childWidth = (width - spacing) / global.screen.n_workspaces;
|
||||||
|
|
||||||
|
alloc.min_size = width;
|
||||||
|
alloc.natural_size = width;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredHeight : function (actor, forWidth, alloc) {
|
||||||
|
let primary = global.get_primary_monitor();
|
||||||
|
this._childHeight = Math.round(this._childWidth * primary.height / primary.width);
|
||||||
|
|
||||||
|
alloc.min_size = this._childHeight;
|
||||||
|
alloc.natural_size = this._childHeight;
|
||||||
|
},
|
||||||
|
|
||||||
|
_allocate : function (actor, box, flags) {
|
||||||
|
let children = this._list.get_children();
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
|
||||||
|
let x = box.x1;
|
||||||
|
let prevChildBoxX2 = box.x1 - this._itemSpacing;
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
childBox.x1 = prevChildBoxX2 + this._itemSpacing;
|
||||||
|
childBox.x2 = Math.round(x + this._childWidth);
|
||||||
|
childBox.y1 = box.y1;
|
||||||
|
childBox.y2 = box.y1 + this._childHeight;
|
||||||
|
x += this._childWidth + this._itemSpacing;
|
||||||
|
prevChildBoxX2 = childBox.x2;
|
||||||
|
children[i].allocate(childBox, flags);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_redraw : function(direction, activeWorkspaceIndex) {
|
||||||
|
this._list.destroy_children();
|
||||||
|
|
||||||
|
for (let i = 0; i < global.screen.n_workspaces; i++) {
|
||||||
|
let indicator = null;
|
||||||
|
|
||||||
|
if (i == activeWorkspaceIndex && direction == LEFT)
|
||||||
|
indicator = new St.Bin({ style_class: 'ws-switcher-active-left' });
|
||||||
|
else if(i == activeWorkspaceIndex && direction == RIGHT)
|
||||||
|
indicator = new St.Bin({ style_class: 'ws-switcher-active-right' });
|
||||||
|
else
|
||||||
|
indicator = new St.Bin({ style_class: 'ws-switcher-box' });
|
||||||
|
|
||||||
|
this._list.add_actor(indicator);
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_position: function() {
|
||||||
|
let primary = global.get_primary_monitor();
|
||||||
|
this._container.x = primary.x + Math.floor((primary.width - this._container.width) / 2);
|
||||||
|
this._container.y = primary.y + Math.floor((primary.height - this._container.height) / 2);
|
||||||
|
},
|
||||||
|
|
||||||
|
_show : function() {
|
||||||
|
Tweener.addTween(this._container, { opacity: 255,
|
||||||
|
time: ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
|
this._position();
|
||||||
|
this.actor.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
display : function(direction, activeWorkspaceIndex) {
|
||||||
|
this._redraw(direction, activeWorkspaceIndex);
|
||||||
|
if (this._timeoutId != 0)
|
||||||
|
Mainloop.source_remove(this._timeoutId);
|
||||||
|
this._timeoutId = Mainloop.timeout_add(DISPLAY_TIMEOUT, Lang.bind(this, this._onTimeout));
|
||||||
|
this._show();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onTimeout : function() {
|
||||||
|
Mainloop.source_remove(this._timeoutId);
|
||||||
|
this._timeoutId = 0;
|
||||||
|
Tweener.addTween(this._container, { opacity: 0.0,
|
||||||
|
time: ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: function() { this.actor.hide(); },
|
||||||
|
onCompleteScope: this
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
1686
js/ui/workspacesView.js
Normal file
1
man/Makefile.am
Normal file
@ -0,0 +1 @@
|
|||||||
|
dist_man_MANS = gnome-shell.1
|
99
man/gnome-shell.1
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
.\" Copyright (c) 2009, Marcelo Jorge Vieira (metal) <metal@alucinados.com>
|
||||||
|
.\"
|
||||||
|
.\" This is free documentation; 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.
|
||||||
|
.\"
|
||||||
|
.\" The GNU General Public License's references to "object code"
|
||||||
|
.\" and "executables" are to be interpreted as the output of any
|
||||||
|
.\" document formatting or typesetting system, including
|
||||||
|
.\" intermediate and printed output.
|
||||||
|
.\"
|
||||||
|
.\" This manual 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 manual; if not, write to the Free
|
||||||
|
.\" Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
.\" Boston, MA 02111-1301 USA.
|
||||||
|
.TH GNOME-SHELL 1
|
||||||
|
.SH NAME
|
||||||
|
gnome-shell \- Graphical shell for the GNOME desktop
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gnome-shell [options]
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
GNOME Shell provides core user interface functions for the GNOME 3
|
||||||
|
desktop, like switching to windows and launching applications. GNOME
|
||||||
|
Shell takes advantage of the capabilities of modern graphics hardware
|
||||||
|
and introduces innovative user interface concepts to provide a
|
||||||
|
visually attractive and easy to use experience.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-r, \-\-replace
|
||||||
|
Replace the running metacity/gnome-panel
|
||||||
|
.br
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-v, \-\-verbose
|
||||||
|
Shows details about the results of running `gnome-shell'.
|
||||||
|
.br
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-g, \-\-debug
|
||||||
|
Run under a debugger
|
||||||
|
.br
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-\-debug\-command
|
||||||
|
Command to use for debugging (defaults to 'gdb \-\-args')
|
||||||
|
.br
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-\-sync
|
||||||
|
.br
|
||||||
|
Make X calls synchronously, useful when debugging down X errors
|
||||||
|
.br
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-\-xephyr
|
||||||
|
Run a debugging instance inside Xephyr
|
||||||
|
.br
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-\-geometry
|
||||||
|
Specify Xephyr screen geometry
|
||||||
|
.br
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-w, \-\-wide
|
||||||
|
Use widescreen (1280x800) with Xephyr
|
||||||
|
.br
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-\-create\-extension
|
||||||
|
Create a new GNOME Shell extension
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-\-eval\-file
|
||||||
|
Evaluate the contents of the given JavaScript file
|
||||||
|
.br
|
||||||
|
|
||||||
|
.SH BUGS
|
||||||
|
The bug tracker can be reached by visiting the website
|
||||||
|
\fIhttps://bugzilla.gnome.org/buglist.cgi?product=gnome-shell\fR
|
||||||
|
|
||||||
|
Before sending a bug report, please verify that you have the latest
|
||||||
|
version of gnome-shell. Many bugs (major and minor) are fixed at each
|
||||||
|
release, and if yours is out of date, the problem may already have
|
||||||
|
been solved.
|
||||||
|
|
||||||
|
.SH ADDITIONAL INFORMATION
|
||||||
|
|
||||||
|
For further information, visit the website \fIhttp://live.gnome.org/GnomeShell\fR
|
10
po/LINGUAS
@ -1,4 +1,5 @@
|
|||||||
ar
|
ar
|
||||||
|
bg
|
||||||
ca
|
ca
|
||||||
cs
|
cs
|
||||||
da
|
da
|
||||||
@ -12,8 +13,10 @@ ga
|
|||||||
gl
|
gl
|
||||||
he
|
he
|
||||||
hu
|
hu
|
||||||
|
id
|
||||||
it
|
it
|
||||||
ko
|
ko
|
||||||
|
lt
|
||||||
nb
|
nb
|
||||||
nl
|
nl
|
||||||
pa
|
pa
|
||||||
@ -22,6 +25,13 @@ pt_BR
|
|||||||
ro
|
ro
|
||||||
ru
|
ru
|
||||||
sl
|
sl
|
||||||
|
sr
|
||||||
|
sr@latin
|
||||||
sv
|
sv
|
||||||
|
th
|
||||||
tr
|
tr
|
||||||
|
uk
|
||||||
|
vi
|
||||||
zh_CN
|
zh_CN
|
||||||
|
zh_HK
|
||||||
|
zh_TW
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
data/gnome-shell.desktop.in.in
|
data/gnome-shell.desktop.in.in
|
||||||
|
data/gnome-shell-clock-preferences.desktop.in.in
|
||||||
|
data/org.gnome.shell.gschema.xml.in
|
||||||
|
[type: gettext/glade]data/clock-preferences.ui
|
||||||
js/ui/appDisplay.js
|
js/ui/appDisplay.js
|
||||||
js/ui/appIcon.js
|
js/ui/appFavorites.js
|
||||||
js/ui/dash.js
|
js/ui/dash.js
|
||||||
|
js/ui/docDisplay.js
|
||||||
|
js/ui/lookingGlass.js
|
||||||
js/ui/overview.js
|
js/ui/overview.js
|
||||||
js/ui/panel.js
|
js/ui/panel.js
|
||||||
js/ui/placeDisplay.js
|
js/ui/placeDisplay.js
|
||||||
js/ui/runDialog.js
|
js/ui/runDialog.js
|
||||||
js/ui/widget.js
|
js/ui/statusMenu.js
|
||||||
|
js/ui/windowAttentionHandler.js
|
||||||
|
js/ui/workspacesView.js
|
||||||
src/gdmuser/gdm-user.c
|
src/gdmuser/gdm-user.c
|
||||||
src/shell-global.c
|
src/shell-global.c
|
||||||
src/shell-uri-util.c
|
src/shell-uri-util.c
|
||||||
|
@ -1 +1,2 @@
|
|||||||
data/gnome-shell.desktop.in
|
data/gnome-shell.desktop.in
|
||||||
|
data/gnome-shell-clock-preferences.desktop.in
|
||||||
|
350
po/ar.po
@ -1,13 +1,13 @@
|
|||||||
# SOME DESCRIPTIVE TITLE.
|
# SOME DESCRIPTIVE TITLE.
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# Khaled Hosny <khaledhosny@eglug.org>, 2009.
|
# Khaled Hosny <khaledhosny@eglug.org>, 2009, 2010.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: HEAD\n"
|
"Project-Id-Version: HEAD\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2009-11-08 20:55+0200\n"
|
"POT-Creation-Date: 2010-05-15 23:40+0300\n"
|
||||||
"PO-Revision-Date: 2009-11-08 20:55+0300\n"
|
"PO-Revision-Date: 2010-05-15 23:40+0300\n"
|
||||||
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
|
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
|
||||||
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -15,8 +15,8 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Language: ar\n"
|
"Language: ar\n"
|
||||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||||
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
|
||||||
"X-Generator: Virtaal 0.4.1\n"
|
"X-Generator: Virtaal 0.6.0\n"
|
||||||
|
|
||||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||||
msgid "GNOME Shell"
|
msgid "GNOME Shell"
|
||||||
@ -26,106 +26,237 @@ msgstr "صدفة جنوم"
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "إدارة النوافذ وإطلاق التطبيقات"
|
msgstr "إدارة النوافذ وإطلاق التطبيقات"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:332
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||||
msgid "Frequent"
|
msgid "Clock"
|
||||||
msgstr "متكرر"
|
msgstr "الساعة"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:867
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||||
msgid "Drag here to add favorites"
|
msgid "Customize the panel clock"
|
||||||
msgstr "اسحب إلى هنا ليضاف إلى المفضّلة"
|
msgstr "طوّع ساعة اللوحة"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:426
|
#. **** Applications ****
|
||||||
|
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||||
|
msgid "APPLICATIONS"
|
||||||
|
msgstr "التطبيقات"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:338
|
||||||
|
msgid "PREFERENCES"
|
||||||
|
msgstr "التفضيلات"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:705
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "نافذة جديدة"
|
msgstr "نافذة جديدة"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:430
|
#: ../js/ui/appDisplay.js:709
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "أزِل من المفضّلة"
|
msgstr "أزِل من المفضّلة"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:431
|
#: ../js/ui/appDisplay.js:710
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "أضِف إلى المفضّلة"
|
msgstr "أضِف إلى المفضّلة"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:267
|
#: ../js/ui/appDisplay.js:1037
|
||||||
msgid "Find..."
|
msgid "Drag here to add favorites"
|
||||||
msgstr "ابحث..."
|
msgstr "اسحب إلى هنا ليضاف إلى المفضّلة"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:376
|
#: ../js/ui/appFavorites.js:89
|
||||||
msgid "More"
|
#, c-format
|
||||||
msgstr "المزيد"
|
msgid "%s has been added to your favorites."
|
||||||
|
msgstr "أضيف %s إلى مفضلتك."
|
||||||
|
|
||||||
#: ../js/ui/dash.js:532
|
#: ../js/ui/appFavorites.js:107
|
||||||
msgid "(see all)"
|
#, c-format
|
||||||
msgstr "(انظر الكل)"
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "أزيل %s من مفضّلتك."
|
||||||
|
|
||||||
#. **** Applications ****
|
#: ../js/ui/dash.js:189
|
||||||
#: ../js/ui/dash.js:711 ../js/ui/dash.js:773
|
msgid "Find"
|
||||||
msgid "APPLICATIONS"
|
msgstr "ابحث"
|
||||||
msgstr "التطبيقات"
|
|
||||||
|
#: ../js/ui/dash.js:505
|
||||||
|
msgid "Searching..."
|
||||||
|
msgstr "يبحث..."
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:519
|
||||||
|
msgid "No matching results."
|
||||||
|
msgstr "لا نتائج مطابقة."
|
||||||
|
|
||||||
#. **** Places ****
|
#. **** Places ****
|
||||||
#. Translators: This is in the sense of locations for documents,
|
#. Translators: This is in the sense of locations for documents,
|
||||||
#. network locations, etc.
|
#. network locations, etc.
|
||||||
#: ../js/ui/dash.js:731
|
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||||
msgid "PLACES"
|
msgid "PLACES & DEVICES"
|
||||||
msgstr "الأماكن"
|
msgstr "الأماكن والأجهزة"
|
||||||
|
|
||||||
#. **** Documents ****
|
#. **** Documents ****
|
||||||
#: ../js/ui/dash.js:738 ../js/ui/dash.js:783
|
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||||
msgid "RECENT DOCUMENTS"
|
msgid "RECENT ITEMS"
|
||||||
msgstr "المستندات الحديثة"
|
msgstr "العناصر الحديثة"
|
||||||
|
|
||||||
#. **** Search Results ****
|
#: ../js/ui/lookingGlass.js:354
|
||||||
#: ../js/ui/dash.js:763 ../js/ui/dash.js:947
|
msgid "No extensions installed"
|
||||||
msgid "SEARCH RESULTS"
|
msgstr "لم تثبّت أية امتدادات"
|
||||||
msgstr "نتائج البحث"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:778
|
#: ../js/ui/lookingGlass.js:391
|
||||||
msgid "PREFERENCES"
|
msgid "Enabled"
|
||||||
msgstr "التفضيلات"
|
msgstr "مفعّل"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:393
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "معطّل"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:395
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "خطأ"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:397
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr "غير محدث"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:422
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr "اعرض المصدر"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:428
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr "صفحة الوب"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:161
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "تراجع"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:535
|
||||||
|
msgid "Quit"
|
||||||
|
msgstr "أنهِ"
|
||||||
|
|
||||||
#. Button on the left side of the panel.
|
#. Button on the left side of the panel.
|
||||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:274
|
#: ../js/ui/panel.js:740
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "الأنشطة"
|
msgstr "الأنشطة"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#. Translators: This is the time format with date used
|
||||||
#: ../js/ui/panel.js:491
|
#. in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:955
|
||||||
|
msgid "%a %b %e, %R:%S"
|
||||||
|
msgstr "%A %e %B، %R:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:956
|
||||||
|
msgid "%a %b %e, %R"
|
||||||
|
msgstr "%A %e %B، %R"
|
||||||
|
|
||||||
|
#. Translators: This is the time format without date used
|
||||||
|
#. in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:960
|
||||||
|
msgid "%a %R:%S"
|
||||||
|
msgstr "%A %R:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:961
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%A %R"
|
||||||
|
|
||||||
|
#. Translators: This is a time format with date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:968
|
||||||
|
msgid "%a %b %e, %l:%M:%S %p"
|
||||||
|
msgstr "%A %e %B، %l:%M:%S %p"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:969
|
||||||
|
msgid "%a %b %e, %l:%M %p"
|
||||||
|
msgstr "%A %e %B، %l:%M %p"
|
||||||
|
|
||||||
|
#. Translators: This is a time format without date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:973
|
||||||
|
msgid "%a %l:%M:%S %p"
|
||||||
|
msgstr "%A %l:%M:%S %p"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:974
|
||||||
msgid "%a %l:%M %p"
|
msgid "%a %l:%M %p"
|
||||||
msgstr "%A %Ol:%OM %p"
|
msgstr "%A %Ol:%OM %p"
|
||||||
|
|
||||||
#: ../js/ui/places.js:178
|
#: ../js/ui/placeDisplay.js:108
|
||||||
|
#, c-format
|
||||||
|
msgid "Failed to unmount '%s'"
|
||||||
|
msgstr "فشل فصْل '%s'"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:111
|
||||||
|
msgid "Retry"
|
||||||
|
msgstr "أعد المحاولة"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:156
|
||||||
msgid "Connect to..."
|
msgid "Connect to..."
|
||||||
msgstr "اتّصل ب..."
|
msgstr "اتّصل ب..."
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:96
|
#: ../js/ui/runDialog.js:231
|
||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "من فضلك اكتب أمرا:"
|
msgstr "من فضلك اكتب أمرا:"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:173
|
#: ../js/ui/runDialog.js:375
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr "فشل تنفيذ '%s':"
|
msgstr "فشل تنفيذ '%s':"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#: ../js/ui/statusMenu.js:90
|
||||||
#: ../js/ui/widget.js:163
|
msgid "Available"
|
||||||
msgid "%H:%M"
|
msgstr "متاح"
|
||||||
msgstr "%OH:%OM"
|
|
||||||
|
|
||||||
#: ../js/ui/widget.js:317
|
#: ../js/ui/statusMenu.js:94
|
||||||
msgid "Applications"
|
msgid "Busy"
|
||||||
msgstr "التطبيقات"
|
msgstr "مشغول"
|
||||||
|
|
||||||
#: ../js/ui/widget.js:339
|
#: ../js/ui/statusMenu.js:98
|
||||||
msgid "Recent Documents"
|
msgid "Invisible"
|
||||||
msgstr "المستندات الحديثة"
|
msgstr "خفي"
|
||||||
|
|
||||||
#: ../src/shell-global.c:821
|
#: ../js/ui/statusMenu.js:105
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "معلومات الحساب..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:109
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "تفضيلات النظام..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:116
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "أوصد الشاشة"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:120
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "بدّل المستخدم"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:125
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "اخرج..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:129
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "أطفئ..."
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:47
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has finished starting"
|
||||||
|
msgstr "انتهى %s من البدء"
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:49
|
||||||
|
#, c-format
|
||||||
|
msgid "'%s' is ready"
|
||||||
|
msgstr "'%s' جاهز"
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:239
|
||||||
|
msgid ""
|
||||||
|
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||||
|
msgstr "تعذّر إضافة مساحة عمل جديدة، لتجاوز أقصى عدد من مساحات العمل."
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:256
|
||||||
|
msgid "Can't remove the first workspace."
|
||||||
|
msgstr "لا يمكن حذف مساحة العمل الأولى."
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:979
|
||||||
msgid "Less than a minute ago"
|
msgid "Less than a minute ago"
|
||||||
msgstr "منذ أقل من دقيقة"
|
msgstr "منذ أقل من دقيقة"
|
||||||
|
|
||||||
#: ../src/shell-global.c:824
|
#: ../src/shell-global.c:983
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d minute ago"
|
msgid "%d minute ago"
|
||||||
msgid_plural "%d minutes ago"
|
msgid_plural "%d minutes ago"
|
||||||
@ -136,7 +267,7 @@ msgstr[3] "منذ %d دقائق"
|
|||||||
msgstr[4] "منذ %d دقيقة"
|
msgstr[4] "منذ %d دقيقة"
|
||||||
msgstr[5] "منذ %d دقيقة"
|
msgstr[5] "منذ %d دقيقة"
|
||||||
|
|
||||||
#: ../src/shell-global.c:827
|
#: ../src/shell-global.c:988
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour ago"
|
msgid "%d hour ago"
|
||||||
msgid_plural "%d hours ago"
|
msgid_plural "%d hours ago"
|
||||||
@ -147,7 +278,7 @@ msgstr[3] "منذ %d ساعات"
|
|||||||
msgstr[4] "منذ %d ساعة"
|
msgstr[4] "منذ %d ساعة"
|
||||||
msgstr[5] "منذ %d ساعة"
|
msgstr[5] "منذ %d ساعة"
|
||||||
|
|
||||||
#: ../src/shell-global.c:830
|
#: ../src/shell-global.c:993
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d day ago"
|
msgid "%d day ago"
|
||||||
msgid_plural "%d days ago"
|
msgid_plural "%d days ago"
|
||||||
@ -158,7 +289,7 @@ msgstr[3] "منذ %d أيام"
|
|||||||
msgstr[4] "منذ %d يوما"
|
msgstr[4] "منذ %d يوما"
|
||||||
msgstr[5] "منذ %d يوم"
|
msgstr[5] "منذ %d يوم"
|
||||||
|
|
||||||
#: ../src/shell-global.c:833
|
#: ../src/shell-global.c:998
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d week ago"
|
msgid "%d week ago"
|
||||||
msgid_plural "%d weeks ago"
|
msgid_plural "%d weeks ago"
|
||||||
@ -169,67 +300,17 @@ msgstr[3] "منذ %d أسابيع"
|
|||||||
msgstr[4] "منذ %d أسبوعا"
|
msgstr[4] "منذ %d أسبوعا"
|
||||||
msgstr[5] "منذ %d أسبوع"
|
msgstr[5] "منذ %d أسبوع"
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:156
|
#: ../src/shell-uri-util.c:89
|
||||||
msgid "Unknown"
|
|
||||||
msgstr "مجهول"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:212
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't lock screen: %s"
|
|
||||||
msgstr "تعذّر إيصاد الشاشة: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:227
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
|
||||||
msgstr "تعذّر ضبك حافظة الشاشة مؤقتا لتكون شاشة خالية: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:351
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't logout: %s"
|
|
||||||
msgstr "تعذّر الخروج: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:492
|
|
||||||
msgid "Account Information..."
|
|
||||||
msgstr "معلومات الحساب..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:502
|
|
||||||
msgid "Sidebar"
|
|
||||||
msgstr "الشريط الجانبي"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:510
|
|
||||||
msgid "System Preferences..."
|
|
||||||
msgstr "تفضيلات النظام..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:525
|
|
||||||
msgid "Lock Screen"
|
|
||||||
msgstr "أوصد الشاشة"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:535
|
|
||||||
msgid "Switch User"
|
|
||||||
msgstr "بدّل المستخدم"
|
|
||||||
|
|
||||||
#. Only show switch user if there are other users
|
|
||||||
#. Log Out
|
|
||||||
#: ../src/shell-status-menu.c:546
|
|
||||||
msgid "Log Out..."
|
|
||||||
msgstr "اخرج..."
|
|
||||||
|
|
||||||
#. Shut down
|
|
||||||
#: ../src/shell-status-menu.c:557
|
|
||||||
msgid "Shut Down..."
|
|
||||||
msgstr "أطفئ..."
|
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:87
|
|
||||||
msgid "Home Folder"
|
msgid "Home Folder"
|
||||||
msgstr "مجلد المنزل"
|
msgstr "مجلد المنزل"
|
||||||
|
|
||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-uri-util.c:102
|
#: ../src/shell-uri-util.c:104
|
||||||
msgid "File System"
|
msgid "File System"
|
||||||
msgstr "نظام الملفات"
|
msgstr "نظام الملفات"
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:248
|
#: ../src/shell-uri-util.c:250
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "ابحث"
|
msgstr "ابحث"
|
||||||
|
|
||||||
@ -238,10 +319,49 @@ msgstr "ابحث"
|
|||||||
#. * example, "Trash: some-directory". It means that the
|
#. * example, "Trash: some-directory". It means that the
|
||||||
#. * directory called "some-directory" is in the trash.
|
#. * directory called "some-directory" is in the trash.
|
||||||
#.
|
#.
|
||||||
#: ../src/shell-uri-util.c:298
|
#: ../src/shell-uri-util.c:300
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s: %2$s"
|
msgid "%1$s: %2$s"
|
||||||
msgstr "%1$s: %2$s"
|
msgstr "%1$s: %2$s"
|
||||||
|
|
||||||
|
#~ msgid "%H:%M"
|
||||||
|
#~ msgstr "%OH:%OM"
|
||||||
|
|
||||||
|
#~ msgid "Applications"
|
||||||
|
#~ msgstr "التطبيقات"
|
||||||
|
|
||||||
|
#~ msgid "Recent Documents"
|
||||||
|
#~ msgstr "المستندات الحديثة"
|
||||||
|
|
||||||
|
#~ msgid "Frequent"
|
||||||
|
#~ msgstr "متكرر"
|
||||||
|
|
||||||
|
#~ msgid "More"
|
||||||
|
#~ msgstr "المزيد"
|
||||||
|
|
||||||
|
#~ msgid "(see all)"
|
||||||
|
#~ msgstr "(انظر الكل)"
|
||||||
|
|
||||||
|
#~ msgid "PLACES"
|
||||||
|
#~ msgstr "الأماكن"
|
||||||
|
|
||||||
|
#~ msgid "SEARCH RESULTS"
|
||||||
|
#~ msgstr "نتائج البحث"
|
||||||
|
|
||||||
|
#~ msgid "Unknown"
|
||||||
|
#~ msgstr "مجهول"
|
||||||
|
|
||||||
|
#~ msgid "Can't lock screen: %s"
|
||||||
|
#~ msgstr "تعذّر إيصاد الشاشة: %s"
|
||||||
|
|
||||||
|
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||||
|
#~ msgstr "تعذّر ضبك حافظة الشاشة مؤقتا لتكون شاشة خالية: %s"
|
||||||
|
|
||||||
|
#~ msgid "Can't logout: %s"
|
||||||
|
#~ msgstr "تعذّر الخروج: %s"
|
||||||
|
|
||||||
|
#~ msgid "Sidebar"
|
||||||
|
#~ msgstr "الشريط الجانبي"
|
||||||
|
|
||||||
#~ msgid "Browse"
|
#~ msgid "Browse"
|
||||||
#~ msgstr "استعرض"
|
#~ msgstr "استعرض"
|
||||||
|
263
po/bg.po
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
# Bulgarian translation of gnome-shell po-file.
|
||||||
|
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
|
# Ivaylo Valkov <ivaylo@e-valkov.org>, 2010.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2010-03-18 13:09+0200\n"
|
||||||
|
"PO-Revision-Date: 2010-03-18 11:30+0200\n"
|
||||||
|
"Last-Translator: Ivaylo Valkov <ivaylo@e-valkov.org>\n"
|
||||||
|
"Language-Team: Bulgarian <dict@fsa-bg.org>\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"
|
||||||
|
|
||||||
|
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||||
|
msgid "GNOME Shell"
|
||||||
|
msgstr "Обвивка на GNOME"
|
||||||
|
|
||||||
|
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||||
|
msgid "Window management and application launching"
|
||||||
|
msgstr "Управление на прозорци и стартиране на програми"
|
||||||
|
|
||||||
|
#. **** Applications ****
|
||||||
|
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:852
|
||||||
|
msgid "APPLICATIONS"
|
||||||
|
msgstr "ПРОГРАМИ"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:343
|
||||||
|
msgid "PREFERENCES"
|
||||||
|
msgstr "ПРЕДПОЧИТАНИЯ"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:728
|
||||||
|
msgid "New Window"
|
||||||
|
msgstr "Нов прозорец"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:732
|
||||||
|
msgid "Remove from Favorites"
|
||||||
|
msgstr "Премахване от „Любими“"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:733
|
||||||
|
msgid "Add to Favorites"
|
||||||
|
msgstr "Добавяне в „Любими“"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:1085
|
||||||
|
msgid "Drag here to add favorites"
|
||||||
|
msgstr "Довлачете до тук обектите за да ги добавите към „Любими“"
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:89
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been added to your favorites."
|
||||||
|
msgstr "Програмата „%s“ беше добавена в „Любими“"
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:107
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "Програмата „%s“ беше премахната от „Любими“"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:194
|
||||||
|
msgid "Find"
|
||||||
|
msgstr "Търсене"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:507
|
||||||
|
msgid "Searching..."
|
||||||
|
msgstr "Търсене…"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:521
|
||||||
|
msgid "No matching results."
|
||||||
|
msgstr "Няма съвпадения."
|
||||||
|
|
||||||
|
#. **** Places ****
|
||||||
|
#. Translators: This is in the sense of locations for documents,
|
||||||
|
#. network locations, etc.
|
||||||
|
#: ../js/ui/dash.js:871 ../js/ui/placeDisplay.js:536
|
||||||
|
msgid "PLACES & DEVICES"
|
||||||
|
msgstr "МЕСТА И УСТРОЙСТВА"
|
||||||
|
|
||||||
|
#. **** Documents ****
|
||||||
|
#: ../js/ui/dash.js:878 ../js/ui/docDisplay.js:488
|
||||||
|
msgid "RECENT ITEMS"
|
||||||
|
msgstr "СКОРО ОТВАРЯНИ"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:363
|
||||||
|
msgid "No extensions installed"
|
||||||
|
msgstr "Няма инсталирани разширения"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:400
|
||||||
|
msgid "Enabled"
|
||||||
|
msgstr "Включено"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:402
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "Изключено"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:404
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "Грешка"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:406
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr "Остаряло"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:431
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr "Преглед на програмния код"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:437
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr "Домашна страница"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:182
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Отмяна"
|
||||||
|
|
||||||
|
#. Button on the left side of the panel.
|
||||||
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
|
#: ../js/ui/panel.js:385
|
||||||
|
msgid "Activities"
|
||||||
|
msgstr "Дейности"
|
||||||
|
|
||||||
|
#. Translators: This is the time format used in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:616
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%a, %R"
|
||||||
|
|
||||||
|
#. Translators: This is a time format used for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:619
|
||||||
|
msgid "%a %l:%M %p"
|
||||||
|
msgstr "%a, %H:%M"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:103
|
||||||
|
#, c-format
|
||||||
|
msgid "Failed to unmount '%s'"
|
||||||
|
msgstr "Неуспех при демонтиране на „%s“"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:106
|
||||||
|
msgid "Retry"
|
||||||
|
msgstr "Повторен опит"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:151
|
||||||
|
msgid "Connect to..."
|
||||||
|
msgstr "Свързване към…"
|
||||||
|
|
||||||
|
#: ../js/ui/runDialog.js:221
|
||||||
|
msgid "Please enter a command:"
|
||||||
|
msgstr "Въведете команда:"
|
||||||
|
|
||||||
|
#: ../js/ui/runDialog.js:344
|
||||||
|
#, c-format
|
||||||
|
msgid "Execution of '%s' failed:"
|
||||||
|
msgstr "Неуспешно изпълнение на „%s“:"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:107
|
||||||
|
msgid "Available"
|
||||||
|
msgstr "Налично"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:112
|
||||||
|
msgid "Busy"
|
||||||
|
msgstr "Заето"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:117
|
||||||
|
msgid "Invisible"
|
||||||
|
msgstr "Невидимо"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:126
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "Информация за настройките на потребителя…"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:132
|
||||||
|
msgid "Sidebar"
|
||||||
|
msgstr "Странична лента"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:142
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "Системни настройки…"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:151
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "Заключване на екрана"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:156
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "Смяна на потребител"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:162
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "Изход…"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:167
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "Изключване на компютъра…"
|
||||||
|
|
||||||
|
#. Translators: This is a time format.
|
||||||
|
#: ../js/ui/widget.js:163
|
||||||
|
msgid "%H:%M"
|
||||||
|
msgstr "%H:%M"
|
||||||
|
|
||||||
|
#: ../js/ui/widget.js:317
|
||||||
|
msgid "Applications"
|
||||||
|
msgstr "Програми"
|
||||||
|
|
||||||
|
#: ../js/ui/widget.js:339
|
||||||
|
msgid "Recent Documents"
|
||||||
|
msgstr "Скоро отваряни документи"
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:967
|
||||||
|
msgid "Less than a minute ago"
|
||||||
|
msgstr "Преди по-малко от минута"
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:971
|
||||||
|
#, c-format
|
||||||
|
msgid "%d minute ago"
|
||||||
|
msgid_plural "%d minutes ago"
|
||||||
|
msgstr[0] "преди %d минута"
|
||||||
|
msgstr[1] "преди %d минути"
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:976
|
||||||
|
#, c-format
|
||||||
|
msgid "%d hour ago"
|
||||||
|
msgid_plural "%d hours ago"
|
||||||
|
msgstr[0] "преди %d час"
|
||||||
|
msgstr[1] "преди %d часа"
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:981
|
||||||
|
#, c-format
|
||||||
|
msgid "%d day ago"
|
||||||
|
msgid_plural "%d days ago"
|
||||||
|
msgstr[0] "преди %d ден"
|
||||||
|
msgstr[1] "преди %d дни"
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:986
|
||||||
|
#, c-format
|
||||||
|
msgid "%d week ago"
|
||||||
|
msgid_plural "%d weeks ago"
|
||||||
|
msgstr[0] "преди %d седмица"
|
||||||
|
msgstr[1] "преди %d седмици"
|
||||||
|
|
||||||
|
#: ../src/shell-uri-util.c:89
|
||||||
|
msgid "Home Folder"
|
||||||
|
msgstr "Домашна папка"
|
||||||
|
|
||||||
|
#. Translators: this is the same string as the one found in
|
||||||
|
#. * nautilus
|
||||||
|
#: ../src/shell-uri-util.c:104
|
||||||
|
msgid "File System"
|
||||||
|
msgstr "Файлова система"
|
||||||
|
|
||||||
|
#: ../src/shell-uri-util.c:250
|
||||||
|
msgid "Search"
|
||||||
|
msgstr "Търсене"
|
||||||
|
|
||||||
|
#. Translators: the first string is the name of a gvfs
|
||||||
|
#. * method, and the second string is a path. For
|
||||||
|
#. * example, "Trash: some-directory". It means that the
|
||||||
|
#. * directory called "some-directory" is in the trash.
|
||||||
|
#.
|
||||||
|
#: ../src/shell-uri-util.c:300
|
||||||
|
#, c-format
|
||||||
|
msgid "%1$s: %2$s"
|
||||||
|
msgstr "%1$s: %2$s"
|
546
po/cs.po
@ -1,14 +1,14 @@
|
|||||||
# Czech translation of gnome-shell.
|
# Czech translation of gnome-shell.
|
||||||
# Copyright (C) 2009 the author(s) of gnome-shell.
|
# Copyright (C) 2009, 2010 the author(s) of gnome-shell.
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
# Andre Klapper <ak-47@gmx.net>, 2009.
|
# Andre Klapper <ak-47@gmx.net>, 2009.
|
||||||
# Petr Kovar <pknbe@volny.cz>, 2009.
|
# Petr Kovar <pknbe@volny.cz>, 2009, 2010.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell\n"
|
"Project-Id-Version: gnome-shell\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2009-11-05 18:03+0100\n"
|
"POT-Creation-Date: 2010-07-11 21:54+0200\n"
|
||||||
"PO-Revision-Date: 2009-11-05 18:03+0100\n"
|
"PO-Revision-Date: 2010-07-11 21:51+0200\n"
|
||||||
"Last-Translator: Petr Kovar <pknbe@volny.cz>\n"
|
"Last-Translator: Petr Kovar <pknbe@volny.cz>\n"
|
||||||
"Language-Team: Czech <gnome-cs-list@gnome.org>\n"
|
"Language-Team: Czech <gnome-cs-list@gnome.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -25,106 +25,461 @@ msgstr "Prostředí GNOME Shell"
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "Správa oken a spouštění aplikací"
|
msgstr "Správa oken a spouštění aplikací"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:332
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||||
msgid "Frequent"
|
msgid "Clock"
|
||||||
msgstr "Časté"
|
msgstr "Hodiny"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:867
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||||
msgid "Drag here to add favorites"
|
msgid "Customize the panel clock"
|
||||||
msgstr "Oblíbené přidáte přetažením sem"
|
msgstr "Přizpůsobit hodiny na panelu"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:426
|
#: ../data/org.gnome.shell.gschema.xml.in.h:1
|
||||||
|
msgid ""
|
||||||
|
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
|
||||||
|
"dialog."
|
||||||
|
msgstr ""
|
||||||
|
"Poskytuje přístup k vnitřním ladicím a monitorovacím nástrojům pomocí okna "
|
||||||
|
"ovládaného přes Alt-F2."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:2
|
||||||
|
msgid "Custom format of the clock"
|
||||||
|
msgstr "Vlastní formát hodin"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:3
|
||||||
|
msgid "Enable internal tools useful for developers and testers from Alt-F2"
|
||||||
|
msgstr "Povolit přes Alt-F2 vnitřní nástroje určené pro vývojáře a testery"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:4
|
||||||
|
msgid "File extension used for storing the screencast"
|
||||||
|
msgstr "Přípona souboru s nahrávkou dění na obrazovce"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:5
|
||||||
|
msgid "Framerate used for recording screencasts."
|
||||||
|
msgstr "Frekvence snímků při nahrávání dění na obrazovce."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:6
|
||||||
|
msgid ""
|
||||||
|
"GNOME Shell extensions have a uuid property; this key lists extensions which "
|
||||||
|
"should not be loaded."
|
||||||
|
msgstr ""
|
||||||
|
"Rozšíření GNOME Shell mají vlastnost uuid; tento klíč uvádí rozšíření, která "
|
||||||
|
"by neměla být načítána."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:7
|
||||||
|
msgid "History for command (Alt-F2) dialog"
|
||||||
|
msgstr "Historie příkazového dialogového okna (Alt-F2)"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:8
|
||||||
|
msgid "Hour format"
|
||||||
|
msgstr "Formát hodin"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:9
|
||||||
|
msgid ""
|
||||||
|
"If true and format is either \"12-hour\" or \"24-hour\", display date in the "
|
||||||
|
"clock, in addition to time."
|
||||||
|
msgstr ""
|
||||||
|
"Je-li \"true\" a formát je buď \"12-hour\" nebo \"24-hour\", zobrazovat v "
|
||||||
|
"hodinách kromě času i datum."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:10
|
||||||
|
msgid ""
|
||||||
|
"If true and format is either \"12-hour\" or \"24-hour\", display seconds in "
|
||||||
|
"time."
|
||||||
|
msgstr ""
|
||||||
|
"Je-li \"true\" a formát je buď \"12-hour\" nebo \"24-hour\", zobrazovat čas "
|
||||||
|
"včetně sekund."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:11
|
||||||
|
msgid "If true, display the ISO week date in the calendar."
|
||||||
|
msgstr "Je-li \"true\", zobrazovat v kalendáři čísla týdnů dle ISO."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:12
|
||||||
|
msgid "List of desktop file IDs for favorite applications"
|
||||||
|
msgstr "Seznam ID souboru desktop oblíbených aplikací"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||||
|
msgid "Overview workspace view mode"
|
||||||
|
msgstr "Režim přehledu pracovních ploch"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||||
|
msgid ""
|
||||||
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
|
"used for gst-launch. The pipeline should have an unconnected sink pad where "
|
||||||
|
"the recorded video is recorded. It will normally have a unconnected source "
|
||||||
|
"pad; output from that pad will be written into the output file. However the "
|
||||||
|
"pipeline can also take care of its own output - this might be used to send "
|
||||||
|
"the output to an icecast server via shout2send or similar. When unset or set "
|
||||||
|
"to an empty value, the default pipeline will be used. This is currently "
|
||||||
|
"'videorate ! theoraenc ! oggmux' and records to Ogg Theora."
|
||||||
|
msgstr ""
|
||||||
|
"Nastavuje rouru systému GStreamer určenou ke kódování nahrávek. Respektuje "
|
||||||
|
"syntax gst-launch. Roura by měla mít nepřipojený cíl, ve kterém se video "
|
||||||
|
"nahrává. Obvykle má nepřipojený zdroj; výstup z takového zdroje bude "
|
||||||
|
"zapisován do výstupního souboru. Roura je ale schopna zabezpečit i vlastní "
|
||||||
|
"výstup, což lze využít při odeslání výstupu na server icecast přes "
|
||||||
|
"shout2send apod. Není-li nastaveno nebo je-li nastaveno na prázdnou hodnotu, "
|
||||||
|
"bude použita výchozí roura. Aktuálně to je 'videorate ! theoraenc ! oggmux' "
|
||||||
|
"s nahráváním do Ogg Theora."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||||
|
msgid "Show date in clock"
|
||||||
|
msgstr "Zobrazovat v hodinách datum"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||||
|
msgid "Show the week date in the calendar"
|
||||||
|
msgstr "Zobrazovat v kalendáři čísla týdnů"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
|
msgid "Show time with seconds"
|
||||||
|
msgstr "Zobrazovat čas včetně sekund"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
|
msgid ""
|
||||||
|
"The applications corresponding to these identifiers will be displayed in the "
|
||||||
|
"favorites area."
|
||||||
|
msgstr ""
|
||||||
|
"Aplikace odpovídající těmto identifikátorům budou zobrazeny oblasti "
|
||||||
|
"oblíbených."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
|
msgid ""
|
||||||
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
|
"a different container format."
|
||||||
|
msgstr ""
|
||||||
|
"Název souboru nahraných dění na obrazovce se bude sestávat z jedinečného "
|
||||||
|
"názvu vycházejícího z aktuálního data a bude používat tuto příponu. Při "
|
||||||
|
"nahrávání do jiného formátu kontejneru by měla být provedena úprava pravidel."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
|
msgid ""
|
||||||
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
|
"screencast recorder in frames-per-second."
|
||||||
|
msgstr ""
|
||||||
|
"Frekvence snímků za sekundu výsledné nahrávky dění na obrazovce, která byla "
|
||||||
|
"nahrána záznamovým programem GNOME Shell."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
|
msgstr "Roura systému gstreamer určená ke kódování nahrávky dění na obrazovce"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
|
msgid ""
|
||||||
|
"The selected workspace view mode in the overview. Supported values are "
|
||||||
|
"\"single\" and \"grid\"."
|
||||||
|
msgstr ""
|
||||||
|
"Vybraný režim zobrazení pracovních ploch v přehledu. Podporované hodnoty "
|
||||||
|
"jsou \"single\" a \"grid\"."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
|
msgid ""
|
||||||
|
"The shell normally monitors active applications in order to present the most "
|
||||||
|
"used ones (e.g. in launchers). While this data will be kept private, you may "
|
||||||
|
"want to disable this for privacy reasons. Please note that doing so won't "
|
||||||
|
"remove already saved data."
|
||||||
|
msgstr ""
|
||||||
|
"Program GNOME Shell obvykle sleduje aktivní aplikace, aby mohl nabídnout ty "
|
||||||
|
"nejpoužívanější (např. ve spouštěčích). Data budou uchovávána v soukromí, "
|
||||||
|
"přesto ale můžete z důvodu ochrany soukromí tuto funkci zakázat. Vezměte "
|
||||||
|
"prosím v potaz skutečnost, že zakázaní funkce neodstraní již uložená data."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
|
msgid ""
|
||||||
|
"This key specifies the format used by the panel clock when the format key is "
|
||||||
|
"set to \"custom\". You can use conversion specifiers understood by strftime"
|
||||||
|
"() to obtain a specific format. See the strftime() manual for more "
|
||||||
|
"information."
|
||||||
|
msgstr ""
|
||||||
|
"Tento klíč určuje formát používaný hodinami na panelu, když je klíč format "
|
||||||
|
"nastaven na \"custom\". K získání konkrétního formátu můžete použít "
|
||||||
|
"specifikátory převodu, kterým rozumí strftime(). Více informací viz manuál k "
|
||||||
|
"strftime()."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
|
msgid ""
|
||||||
|
"This key specifies the hour format used by the panel clock. Possible values "
|
||||||
|
"are \"12-hour\", \"24-hour\", \"unix\" and \"custom\". If set to \"unix\", "
|
||||||
|
"the clock will display time in seconds since Epoch, i.e. 1970-01-01. If set "
|
||||||
|
"to \"custom\", the clock will display time according to the format specified "
|
||||||
|
"in the custom_format key. Note that if set to either \"unix\" or \"custom\", "
|
||||||
|
"the show_date and show_seconds keys are ignored."
|
||||||
|
msgstr ""
|
||||||
|
"Tento klíč určuje formát používaný hodinami na panelu. Možné hodnoty jsou "
|
||||||
|
"\"12-hour\", \"24-hour\", \"unix\" a \"custom\". Je-li nastaven na \"unix\", "
|
||||||
|
"hodiny budou zobrazovat čas v sekundách od počátku epochy, tj. 1970-01-01. "
|
||||||
|
"Je-li nastaven na \"custom\", hodiny budou zobrazovat čas s ohledem na "
|
||||||
|
"formát určený klíčem custom_format key. Je-li klíč nastaven buď na \"unix\" "
|
||||||
|
"nebo \"custom\", budou ignorovány klíče show_date a show_seconds."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
|
msgid "Uuids of extensions to disable"
|
||||||
|
msgstr "Uuid rozšíření určených k vypnutí"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
||||||
|
msgid "Whether to collect stats about applications usage"
|
||||||
|
msgstr "Zda sbírat statistická data o používání aplikací"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:1
|
||||||
|
msgid "Clock Format"
|
||||||
|
msgstr "Formát hodin"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:2
|
||||||
|
msgid "Clock Preferences"
|
||||||
|
msgstr "Předvolby hodin"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:3
|
||||||
|
msgid "Panel Display"
|
||||||
|
msgstr "Zobrazení panelu"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:4
|
||||||
|
msgid "Show seco_nds"
|
||||||
|
msgstr "Zobrazit seku_ndy"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:5
|
||||||
|
msgid "Show the _date"
|
||||||
|
msgstr "Zobrazit _datum"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:6
|
||||||
|
msgid "_12 hour format"
|
||||||
|
msgstr "_12hodinový formát"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:7
|
||||||
|
msgid "_24 hour format"
|
||||||
|
msgstr "_24hodinový formát"
|
||||||
|
|
||||||
|
#. **** Applications ****
|
||||||
|
#: ../js/ui/appDisplay.js:388 ../js/ui/dash.js:777
|
||||||
|
msgid "APPLICATIONS"
|
||||||
|
msgstr "APLIKACE"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:420
|
||||||
|
msgid "PREFERENCES"
|
||||||
|
msgstr "PŘEDVOLBY"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:725
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Nové okno"
|
msgstr "Nové okno"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:430
|
#: ../js/ui/appDisplay.js:729
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Odstranit z oblíbených"
|
msgstr "Odstranit z oblíbených"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:431
|
#: ../js/ui/appDisplay.js:730
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Přidat mezi oblíbené"
|
msgstr "Přidat mezi oblíbené"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:267
|
#: ../js/ui/appDisplay.js:1037
|
||||||
msgid "Find..."
|
msgid "Drag here to add favorites"
|
||||||
msgstr "Najít..."
|
msgstr "Oblíbené přidáte přetažením sem"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:376
|
#: ../js/ui/appFavorites.js:88
|
||||||
msgid "More"
|
#, c-format
|
||||||
msgstr "Více"
|
msgid "%s has been added to your favorites."
|
||||||
|
msgstr "%s byl přidán mezi oblíbené."
|
||||||
|
|
||||||
#: ../js/ui/dash.js:532
|
#: ../js/ui/appFavorites.js:106
|
||||||
msgid "(see all)"
|
#, c-format
|
||||||
msgstr "(zobrazit vše)"
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "%s byl odstraněn z oblíbených."
|
||||||
|
|
||||||
#. **** Applications ****
|
#: ../js/ui/dash.js:146
|
||||||
#: ../js/ui/dash.js:711 ../js/ui/dash.js:773
|
msgid "Find"
|
||||||
msgid "APPLICATIONS"
|
msgstr "Najít"
|
||||||
msgstr "APLIKACE"
|
|
||||||
|
#: ../js/ui/dash.js:475
|
||||||
|
msgid "Searching..."
|
||||||
|
msgstr "Hledá se..."
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:489
|
||||||
|
msgid "No matching results."
|
||||||
|
msgstr "Neodpovídá ani jeden z výsledků."
|
||||||
|
|
||||||
#. **** Places ****
|
#. **** Places ****
|
||||||
#. Translators: This is in the sense of locations for documents,
|
#. Translators: This is in the sense of locations for documents,
|
||||||
#. network locations, etc.
|
#. network locations, etc.
|
||||||
#: ../js/ui/dash.js:731
|
#: ../js/ui/dash.js:796 ../js/ui/placeDisplay.js:552
|
||||||
msgid "PLACES"
|
msgid "PLACES & DEVICES"
|
||||||
msgstr "MÍSTA"
|
msgstr "MÍSTA A ZAŘÍZENÍ"
|
||||||
|
|
||||||
#. **** Documents ****
|
#. **** Documents ****
|
||||||
#: ../js/ui/dash.js:738 ../js/ui/dash.js:783
|
#: ../js/ui/dash.js:803 ../js/ui/docDisplay.js:497
|
||||||
msgid "RECENT DOCUMENTS"
|
msgid "RECENT ITEMS"
|
||||||
msgstr "NEDÁVNÉ DOKUMENTY"
|
msgstr "NEDÁVNÉ POLOŽKY"
|
||||||
|
|
||||||
#. **** Search Results ****
|
#: ../js/ui/lookingGlass.js:471
|
||||||
#: ../js/ui/dash.js:763 ../js/ui/dash.js:947
|
msgid "No extensions installed"
|
||||||
msgid "SEARCH RESULTS"
|
msgstr "Nejsou nainstalována žádná rozšíření"
|
||||||
msgstr "VÝSLEDKY HLEDÁNÍ"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:778
|
#: ../js/ui/lookingGlass.js:508
|
||||||
msgid "PREFERENCES"
|
msgid "Enabled"
|
||||||
msgstr "PŘEDVOLBY"
|
msgstr "Povoleno"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:510
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "Zakázáno"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:512
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "Chyba"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:514
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr "Neaktuální"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:539
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr "Zobrazit zdroj"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:545
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr "Webová stránka"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:165
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Zpět"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:517
|
||||||
|
msgid "Preferences"
|
||||||
|
msgstr "Předvolby"
|
||||||
|
|
||||||
|
# Not sure whether we've enough space for it, but anyway, looks more aesthetically with "%A".
|
||||||
|
#. Translators: This is the time format with date used
|
||||||
|
#. in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:603
|
||||||
|
msgid "%a %b %e, %R:%S"
|
||||||
|
msgstr "%A, %e. %B, %R:%S"
|
||||||
|
|
||||||
|
# Not sure whether we've enough space for it, but anyway, looks more aesthetically with "%A".
|
||||||
|
#: ../js/ui/panel.js:604
|
||||||
|
msgid "%a %b %e, %R"
|
||||||
|
msgstr "%A, %e. %B, %R"
|
||||||
|
|
||||||
|
# Not sure whether we've enough space for it, but anyway, looks more aesthetically with "%A".
|
||||||
|
#. Translators: This is the time format without date used
|
||||||
|
#. in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:608
|
||||||
|
msgid "%a %R:%S"
|
||||||
|
msgstr "%A, %R:%S"
|
||||||
|
|
||||||
|
# Not sure whether we've enough space for it, but anyway, looks more aesthetically with "%A".
|
||||||
|
#: ../js/ui/panel.js:609
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%A, %R"
|
||||||
|
|
||||||
|
# Not sure whether we've enough space for it, but anyway, looks more aesthetically with "%A".
|
||||||
|
#. Translators: This is a time format with date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:616
|
||||||
|
msgid "%a %b %e, %l:%M:%S %p"
|
||||||
|
msgstr "%A, %e. %B, %l:%M:%S %p"
|
||||||
|
|
||||||
|
# Not sure whether we've enough space for it, but anyway, looks more aesthetically with "%A".
|
||||||
|
#: ../js/ui/panel.js:617
|
||||||
|
msgid "%a %b %e, %l:%M %p"
|
||||||
|
msgstr "%A, %e. %B, %l:%M %p"
|
||||||
|
|
||||||
|
# Not sure whether we've enough space for it, but anyway, looks more aesthetically with "%A".
|
||||||
|
#. Translators: This is a time format without date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:621
|
||||||
|
msgid "%a %l:%M:%S %p"
|
||||||
|
msgstr "%A, %l:%M:%S %p"
|
||||||
|
|
||||||
|
# Not sure whether we've enough space for it, but anyway, looks more aesthetically with "%A".
|
||||||
|
#: ../js/ui/panel.js:622
|
||||||
|
msgid "%a %l:%M %p"
|
||||||
|
msgstr "%A, %l:%M %p"
|
||||||
|
|
||||||
#. Button on the left side of the panel.
|
#. Button on the left side of the panel.
|
||||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:274
|
#: ../js/ui/panel.js:760
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Činnosti"
|
msgstr "Činnosti"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#: ../js/ui/placeDisplay.js:109
|
||||||
#: ../js/ui/panel.js:491
|
#, c-format
|
||||||
msgid "%a %l:%M %p"
|
msgid "Failed to unmount '%s'"
|
||||||
msgstr "%a, %H:%M"
|
msgstr "Nelze odpojit \"%s\""
|
||||||
|
|
||||||
#: ../js/ui/places.js:178
|
#: ../js/ui/placeDisplay.js:112
|
||||||
|
msgid "Retry"
|
||||||
|
msgstr "Opakovat"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:157
|
||||||
msgid "Connect to..."
|
msgid "Connect to..."
|
||||||
msgstr "Připojit se k..."
|
msgstr "Připojit se k..."
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:96
|
#: ../js/ui/runDialog.js:234
|
||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Zadejte prosím příkaz:"
|
msgstr "Zadejte prosím příkaz:"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:173
|
#: ../js/ui/runDialog.js:379
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr "Vykonání \"%s\" selhalo:"
|
msgstr "Vykonání \"%s\" selhalo:"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#: ../js/ui/statusMenu.js:91
|
||||||
#: ../js/ui/widget.js:163
|
msgid "Available"
|
||||||
msgid "%H:%M"
|
msgstr "Přítomen"
|
||||||
msgstr "%H:%M"
|
|
||||||
|
|
||||||
#: ../js/ui/widget.js:317
|
#: ../js/ui/statusMenu.js:95
|
||||||
msgid "Applications"
|
msgid "Busy"
|
||||||
msgstr "Aplikace"
|
msgstr "Zaneprázdněn"
|
||||||
|
|
||||||
#: ../js/ui/widget.js:339
|
#: ../js/ui/statusMenu.js:99
|
||||||
msgid "Recent Documents"
|
msgid "Invisible"
|
||||||
msgstr "Nedávné dokumenty"
|
msgstr "Neviditelný"
|
||||||
|
|
||||||
#: ../src/shell-global.c:821
|
#: ../js/ui/statusMenu.js:106
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "Informace o účtu..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:110
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "Předvolby systému..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:117
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "Uzamknout obrazovku"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:121
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "Přepnout uživatele"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:126
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "Odhlásit..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:130
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "Vypnout..."
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:47
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has finished starting"
|
||||||
|
msgstr "Spouštění %s dokončeno"
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:49
|
||||||
|
#, c-format
|
||||||
|
msgid "'%s' is ready"
|
||||||
|
msgstr "Připraveno \"%s\""
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:237
|
||||||
|
msgid ""
|
||||||
|
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||||
|
msgstr ""
|
||||||
|
"Novou pracovní plochu nelze přidat, jelikož byl dosažen maximální počet "
|
||||||
|
"pracovních ploch."
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:254
|
||||||
|
msgid "Can't remove the first workspace."
|
||||||
|
msgstr "Nelze odstranit první pracovní plochu."
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:1039
|
||||||
msgid "Less than a minute ago"
|
msgid "Less than a minute ago"
|
||||||
msgstr "Před méně než minutou"
|
msgstr "Před méně než minutou"
|
||||||
|
|
||||||
#: ../src/shell-global.c:824
|
#: ../src/shell-global.c:1043
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d minute ago"
|
msgid "%d minute ago"
|
||||||
msgid_plural "%d minutes ago"
|
msgid_plural "%d minutes ago"
|
||||||
@ -132,7 +487,7 @@ msgstr[0] "Před %d minutou"
|
|||||||
msgstr[1] "Před %d minutami"
|
msgstr[1] "Před %d minutami"
|
||||||
msgstr[2] "Před %d minutami"
|
msgstr[2] "Před %d minutami"
|
||||||
|
|
||||||
#: ../src/shell-global.c:827
|
#: ../src/shell-global.c:1048
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour ago"
|
msgid "%d hour ago"
|
||||||
msgid_plural "%d hours ago"
|
msgid_plural "%d hours ago"
|
||||||
@ -140,7 +495,7 @@ msgstr[0] "Před %d hodinou"
|
|||||||
msgstr[1] "Před %d hodinami"
|
msgstr[1] "Před %d hodinami"
|
||||||
msgstr[2] "Před %d hodinami"
|
msgstr[2] "Před %d hodinami"
|
||||||
|
|
||||||
#: ../src/shell-global.c:830
|
#: ../src/shell-global.c:1053
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d day ago"
|
msgid "%d day ago"
|
||||||
msgid_plural "%d days ago"
|
msgid_plural "%d days ago"
|
||||||
@ -148,7 +503,7 @@ msgstr[0] "Před %d dnem"
|
|||||||
msgstr[1] "Před %d dny"
|
msgstr[1] "Před %d dny"
|
||||||
msgstr[2] "Před %d dny"
|
msgstr[2] "Před %d dny"
|
||||||
|
|
||||||
#: ../src/shell-global.c:833
|
#: ../src/shell-global.c:1058
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d week ago"
|
msgid "%d week ago"
|
||||||
msgid_plural "%d weeks ago"
|
msgid_plural "%d weeks ago"
|
||||||
@ -156,67 +511,17 @@ msgstr[0] "Před %d týdnem"
|
|||||||
msgstr[1] "Před %d týdny"
|
msgstr[1] "Před %d týdny"
|
||||||
msgstr[2] "Před %d týdny"
|
msgstr[2] "Před %d týdny"
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:156
|
#: ../src/shell-uri-util.c:89
|
||||||
msgid "Unknown"
|
|
||||||
msgstr "Neznámé"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:212
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't lock screen: %s"
|
|
||||||
msgstr "Nelze uzamknout obrazovku: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:227
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
|
||||||
msgstr "Šetřič obrazovky nelze dočasně nastavit na prázdnou obrazovku: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:351
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't logout: %s"
|
|
||||||
msgstr "Nelze se odhlásit: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:492
|
|
||||||
msgid "Account Information..."
|
|
||||||
msgstr "Informace o účtu..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:502
|
|
||||||
msgid "Sidebar"
|
|
||||||
msgstr "Postranní lišta"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:510
|
|
||||||
msgid "System Preferences..."
|
|
||||||
msgstr "Předvolby systému..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:525
|
|
||||||
msgid "Lock Screen"
|
|
||||||
msgstr "Uzamknout obrazovku"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:535
|
|
||||||
msgid "Switch User"
|
|
||||||
msgstr "Přepnout uživatele"
|
|
||||||
|
|
||||||
#. Only show switch user if there are other users
|
|
||||||
#. Log Out
|
|
||||||
#: ../src/shell-status-menu.c:546
|
|
||||||
msgid "Log Out..."
|
|
||||||
msgstr "Odhlásit..."
|
|
||||||
|
|
||||||
#. Shut down
|
|
||||||
#: ../src/shell-status-menu.c:557
|
|
||||||
msgid "Shut Down..."
|
|
||||||
msgstr "Vypnout..."
|
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:87
|
|
||||||
msgid "Home Folder"
|
msgid "Home Folder"
|
||||||
msgstr "Domovská složka"
|
msgstr "Domovská složka"
|
||||||
|
|
||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-uri-util.c:102
|
#: ../src/shell-uri-util.c:104
|
||||||
msgid "File System"
|
msgid "File System"
|
||||||
msgstr "Systém souborů"
|
msgstr "Systém souborů"
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:248
|
#: ../src/shell-uri-util.c:250
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Hledat"
|
msgstr "Hledat"
|
||||||
|
|
||||||
@ -225,16 +530,7 @@ msgstr "Hledat"
|
|||||||
#. * example, "Trash: some-directory". It means that the
|
#. * example, "Trash: some-directory". It means that the
|
||||||
#. * directory called "some-directory" is in the trash.
|
#. * directory called "some-directory" is in the trash.
|
||||||
#.
|
#.
|
||||||
#: ../src/shell-uri-util.c:298
|
#: ../src/shell-uri-util.c:300
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s: %2$s"
|
msgid "%1$s: %2$s"
|
||||||
msgstr "%1$s: %2$s"
|
msgstr "%1$s: %2$s"
|
||||||
|
|
||||||
#~ msgid "Browse"
|
|
||||||
#~ msgstr "Procházet"
|
|
||||||
|
|
||||||
#~ msgid "Manager"
|
|
||||||
#~ msgstr "Správce"
|
|
||||||
|
|
||||||
#~ msgid "The user manager object this user is controlled by."
|
|
||||||
#~ msgstr "Objekt správce uživatele, kterým je tento uživatel ovládán."
|
|
||||||
|
259
po/da.po
@ -1,14 +1,14 @@
|
|||||||
# Danish translation of gnome-shell
|
# Danish translation of gnome-shell
|
||||||
# Copyright (C) 2009 gnome-shell
|
# Copyright (C) 2010 gnome-shell
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
# Kris Thomsen <lakristho@gmail.com>, 2009.
|
# Kris Thomsen <lakristho@gmail.com>, 2009, 2010.
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell\n"
|
"Project-Id-Version: gnome-shell\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2009-10-21 22:51+0200\n"
|
"POT-Creation-Date: 2010-02-23 22:07+0100\n"
|
||||||
"PO-Revision-Date: 2009-10-18 17:32+0200\n"
|
"PO-Revision-Date: 2010-02-11 22:32+0200\n"
|
||||||
"Last-Translator: Kris Thomsen <lakristho@gmail.com>\n"
|
"Last-Translator: Kris Thomsen <lakristho@gmail.com>\n"
|
||||||
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
|
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -24,84 +24,166 @@ msgstr "Skal til GNOME"
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "Vinduehåndtering og åbning af programmer"
|
msgstr "Vinduehåndtering og åbning af programmer"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:332
|
#. **** Applications ****
|
||||||
msgid "Frequent"
|
#: ../js/ui/appDisplay.js:180 ../js/ui/dash.js:881
|
||||||
msgstr "Ofte"
|
msgid "APPLICATIONS"
|
||||||
|
msgstr "PROGRAMMER"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:410
|
#: ../js/ui/appDisplay.js:204
|
||||||
|
msgid "PREFERENCES"
|
||||||
|
msgstr "INDSTILLINGER"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:582
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Nyt vindue"
|
msgstr "Nyt vindue"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:414
|
#: ../js/ui/appDisplay.js:586
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Fjern fra favoritter"
|
msgstr "Fjern fra favoritter"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:415
|
#: ../js/ui/appDisplay.js:587
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Tilføj til favoritter"
|
msgstr "Tilføj til favoritter"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:283
|
#: ../js/ui/appDisplay.js:939
|
||||||
|
msgid "Drag here to add favorites"
|
||||||
|
msgstr "Træk hertil for at tilføje til favoritter"
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:89
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been added to your favorites."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:107
|
||||||
|
#, fuzzy, c-format
|
||||||
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "Fjern fra favoritter"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:235
|
||||||
msgid "Find..."
|
msgid "Find..."
|
||||||
msgstr "Find..."
|
msgstr "Find..."
|
||||||
|
|
||||||
#: ../js/ui/dash.js:400
|
#: ../js/ui/dash.js:505
|
||||||
msgid "More"
|
msgid "Searching..."
|
||||||
msgstr "Mere"
|
msgstr "Søger..."
|
||||||
|
|
||||||
#: ../js/ui/dash.js:543
|
#: ../js/ui/dash.js:519
|
||||||
msgid "(see all)"
|
msgid "No matching results."
|
||||||
msgstr "(se alle)"
|
msgstr "Ingen matchende resultater."
|
||||||
|
|
||||||
#. **** Applications ****
|
|
||||||
#: ../js/ui/dash.js:725 ../js/ui/dash.js:787
|
|
||||||
msgid "APPLICATIONS"
|
|
||||||
msgstr "PROGRAMMER"
|
|
||||||
|
|
||||||
#. **** Places ****
|
#. **** Places ****
|
||||||
#. Translators: This is in the sense of locations for documents,
|
#. Translators: This is in the sense of locations for documents,
|
||||||
#. network locations, etc.
|
#. network locations, etc.
|
||||||
#: ../js/ui/dash.js:745
|
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||||
msgid "PLACES"
|
msgid "PLACES & DEVICES"
|
||||||
msgstr "STEDER"
|
msgstr "STEDER & ENHEDER"
|
||||||
|
|
||||||
#. **** Documents ****
|
#. **** Documents ****
|
||||||
#: ../js/ui/dash.js:752 ../js/ui/dash.js:797
|
#: ../js/ui/dash.js:907 ../js/ui/docDisplay.js:488
|
||||||
msgid "RECENT DOCUMENTS"
|
msgid "RECENT ITEMS"
|
||||||
msgstr "SENESTE DOKUMENTER"
|
msgstr "SENESTE ELEMENTER"
|
||||||
|
|
||||||
#. **** Search Results ****
|
#: ../js/ui/lookingGlass.js:356
|
||||||
#: ../js/ui/dash.js:777 ../js/ui/dash.js:961
|
msgid "No extensions installed"
|
||||||
msgid "SEARCH RESULTS"
|
msgstr ""
|
||||||
msgstr "SØGERESULTATER"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:792
|
#: ../js/ui/lookingGlass.js:393
|
||||||
msgid "PREFERENCES"
|
msgid "Enabled"
|
||||||
msgstr "INDSTILLINGER"
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:395
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:397
|
||||||
|
msgid "Error"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:399
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:424
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:430
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:92
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Button on the left side of the panel.
|
#. Button on the left side of the panel.
|
||||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:274
|
#: ../js/ui/panel.js:336
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Aktiviteter"
|
msgstr "Aktiviteter"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#. Translators: This is the time format used in 24-hour mode.
|
||||||
#: ../js/ui/panel.js:491
|
#: ../js/ui/panel.js:560
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%a %R"
|
||||||
|
|
||||||
|
#. Translators: This is a time format used for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:563
|
||||||
msgid "%a %l:%M %p"
|
msgid "%a %l:%M %p"
|
||||||
msgstr "%a %H:%M"
|
msgstr "%a %H:%M"
|
||||||
|
|
||||||
#: ../js/ui/places.js:178
|
#: ../js/ui/placeDisplay.js:144
|
||||||
msgid "Connect to..."
|
msgid "Connect to..."
|
||||||
msgstr "Forbind til..."
|
msgstr "Forbind til..."
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:96
|
#: ../js/ui/runDialog.js:245
|
||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Indtast en kommando:"
|
msgstr "Indtast en kommando:"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:173
|
#: ../js/ui/runDialog.js:361
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr "Kørsel af \"%s\" mislykkedes:"
|
msgstr "Kørsel af \"%s\" mislykkedes:"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:107
|
||||||
|
msgid "Available"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:112
|
||||||
|
msgid "Busy"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:117
|
||||||
|
msgid "Invisible"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:126
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "Kontoinformation..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:132
|
||||||
|
msgid "Sidebar"
|
||||||
|
msgstr "Sidebjælke"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:142
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "Systemindstillinger..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:151
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "Lås skærm"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:156
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "Skift bruger"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:162
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "Log ud..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:167
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "Luk ned..."
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#. Translators: This is a time format.
|
||||||
#: ../js/ui/widget.js:163
|
#: ../js/ui/widget.js:163
|
||||||
msgid "%H:%M"
|
msgid "%H:%M"
|
||||||
@ -115,99 +197,49 @@ msgstr "Programmer"
|
|||||||
msgid "Recent Documents"
|
msgid "Recent Documents"
|
||||||
msgstr "Seneste dokumenter"
|
msgstr "Seneste dokumenter"
|
||||||
|
|
||||||
#: ../src/shell-global.c:812
|
#: ../src/shell-global.c:954
|
||||||
msgid "Less than a minute ago"
|
msgid "Less than a minute ago"
|
||||||
msgstr "Mindre end et minut siden"
|
msgstr "Mindre end et minut siden"
|
||||||
|
|
||||||
#: ../src/shell-global.c:815
|
#: ../src/shell-global.c:958
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d minute ago"
|
msgid "%d minute ago"
|
||||||
msgid_plural "%d minutes ago"
|
msgid_plural "%d minutes ago"
|
||||||
msgstr[0] "%d minut siden"
|
msgstr[0] "%d minut siden"
|
||||||
msgstr[1] "%d minutter siden"
|
msgstr[1] "%d minutter siden"
|
||||||
|
|
||||||
#: ../src/shell-global.c:818
|
#: ../src/shell-global.c:963
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour ago"
|
msgid "%d hour ago"
|
||||||
msgid_plural "%d hours ago"
|
msgid_plural "%d hours ago"
|
||||||
msgstr[0] "%d time siden"
|
msgstr[0] "%d time siden"
|
||||||
msgstr[1] "%d timer siden"
|
msgstr[1] "%d timer siden"
|
||||||
|
|
||||||
#: ../src/shell-global.c:821
|
#: ../src/shell-global.c:968
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d day ago"
|
msgid "%d day ago"
|
||||||
msgid_plural "%d days ago"
|
msgid_plural "%d days ago"
|
||||||
msgstr[0] "%d dag siden"
|
msgstr[0] "%d dag siden"
|
||||||
msgstr[1] "%d dage siden"
|
msgstr[1] "%d dage siden"
|
||||||
|
|
||||||
#: ../src/shell-global.c:824
|
#: ../src/shell-global.c:973
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d week ago"
|
msgid "%d week ago"
|
||||||
msgid_plural "%d weeks ago"
|
msgid_plural "%d weeks ago"
|
||||||
msgstr[0] "%d uge siden"
|
msgstr[0] "%d uge siden"
|
||||||
msgstr[1] "%d uger siden"
|
msgstr[1] "%d uger siden"
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:156
|
#: ../src/shell-uri-util.c:89
|
||||||
msgid "Unknown"
|
|
||||||
msgstr "Ukendt"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:212
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't lock screen: %s"
|
|
||||||
msgstr "Kan ikke låse skærm: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:227
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
|
||||||
msgstr "Kan ikke midlertidigt sætte pauseskærm til blank skærm: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:351
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't logout: %s"
|
|
||||||
msgstr "Kan ikke logge ud: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:492
|
|
||||||
msgid "Account Information..."
|
|
||||||
msgstr "Kontoinformation..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:502
|
|
||||||
msgid "Sidebar"
|
|
||||||
msgstr "Sidebjælke"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:510
|
|
||||||
msgid "System Preferences..."
|
|
||||||
msgstr "Systemindstillinger..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:525
|
|
||||||
msgid "Lock Screen"
|
|
||||||
msgstr "Lås skærm"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:535
|
|
||||||
msgid "Switch User"
|
|
||||||
msgstr "Skift bruger"
|
|
||||||
|
|
||||||
#. Only show switch user if there are other users
|
|
||||||
#. Log Out
|
|
||||||
#: ../src/shell-status-menu.c:546
|
|
||||||
msgid "Log Out..."
|
|
||||||
msgstr "Log ud..."
|
|
||||||
|
|
||||||
#. Shut down
|
|
||||||
#: ../src/shell-status-menu.c:557
|
|
||||||
msgid "Shut Down..."
|
|
||||||
msgstr "Luk ned..."
|
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:87
|
|
||||||
msgid "Home Folder"
|
msgid "Home Folder"
|
||||||
msgstr "Hjemmemappe"
|
msgstr "Hjemmemappe"
|
||||||
|
|
||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-uri-util.c:102
|
#: ../src/shell-uri-util.c:104
|
||||||
msgid "File System"
|
msgid "File System"
|
||||||
msgstr "Filsystem"
|
msgstr "Filsystem"
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:248
|
#: ../src/shell-uri-util.c:250
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Søg"
|
msgstr "Søg"
|
||||||
|
|
||||||
@ -216,11 +248,38 @@ msgstr "Søg"
|
|||||||
#. * example, "Trash: some-directory". It means that the
|
#. * example, "Trash: some-directory". It means that the
|
||||||
#. * directory called "some-directory" is in the trash.
|
#. * directory called "some-directory" is in the trash.
|
||||||
#.
|
#.
|
||||||
#: ../src/shell-uri-util.c:298
|
#: ../src/shell-uri-util.c:300
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s: %2$s"
|
msgid "%1$s: %2$s"
|
||||||
msgstr "%1$s: %2$s"
|
msgstr "%1$s: %2$s"
|
||||||
|
|
||||||
|
#~ msgid "Frequent"
|
||||||
|
#~ msgstr "Ofte"
|
||||||
|
|
||||||
|
#~ msgid "More"
|
||||||
|
#~ msgstr "Mere"
|
||||||
|
|
||||||
|
#~ msgid "(see all)"
|
||||||
|
#~ msgstr "(se alle)"
|
||||||
|
|
||||||
|
#~ msgid "PLACES"
|
||||||
|
#~ msgstr "STEDER"
|
||||||
|
|
||||||
|
#~ msgid "SEARCH RESULTS"
|
||||||
|
#~ msgstr "SØGERESULTATER"
|
||||||
|
|
||||||
|
#~ msgid "Unknown"
|
||||||
|
#~ msgstr "Ukendt"
|
||||||
|
|
||||||
|
#~ msgid "Can't lock screen: %s"
|
||||||
|
#~ msgstr "Kan ikke låse skærm: %s"
|
||||||
|
|
||||||
|
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||||
|
#~ msgstr "Kan ikke midlertidigt sætte pauseskærm til blank skærm: %s"
|
||||||
|
|
||||||
|
#~ msgid "Can't logout: %s"
|
||||||
|
#~ msgstr "Kan ikke logge ud: %s"
|
||||||
|
|
||||||
#~ msgid "Browse"
|
#~ msgid "Browse"
|
||||||
#~ msgstr "Gennemse"
|
#~ msgstr "Gennemse"
|
||||||
|
|
||||||
|
388
po/de.po
@ -2,24 +2,28 @@
|
|||||||
# Copyright (C) 2009 Free Software Foundation, Inc.
|
# Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
#
|
#
|
||||||
|
# workspace - Arbeitsfläche
|
||||||
|
#
|
||||||
# Hendrik Brandt <heb@gnome-de.org>, 2009.
|
# Hendrik Brandt <heb@gnome-de.org>, 2009.
|
||||||
# Hendrik Richter <hendrikr@gnome.org>, 2009.
|
# Hendrik Richter <hendrikr@gnome.org>, 2009.
|
||||||
# Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009.
|
# Mario Blättermann <mariobl@gnome.org>, 2009, 2010.
|
||||||
# Mario Blättermann <mariobl@gnome.org>, 2009.
|
# Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009, 2010.
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&component=general\n"
|
"shell&component=general\n"
|
||||||
"POT-Creation-Date: 2009-10-16 20:05+0000\n"
|
"POT-Creation-Date: 2010-05-17 18:24+0000\n"
|
||||||
"PO-Revision-Date: 2009-10-17 23:37+0200\n"
|
"PO-Revision-Date: 2010-05-18 22:06+0100\n"
|
||||||
"Last-Translator: Christian Kirbach <Christian.Kirbach@googlemail.com>\n"
|
"Last-Translator: Mario Blättermann <mariobl@gnome.org>\n"
|
||||||
"Language-Team: German <gnome-de@gnome.org>\n"
|
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Poedit-Language: German\n"
|
||||||
|
"X-Poedit-Country: GERMANY\n"
|
||||||
|
|
||||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||||
msgid "GNOME Shell"
|
msgid "GNOME Shell"
|
||||||
@ -29,192 +33,307 @@ msgstr "GNOME-Shell"
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "Fenster verwalten und Anwendungen starten"
|
msgstr "Fenster verwalten und Anwendungen starten"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:335
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||||
msgid "Frequent"
|
msgid "Clock"
|
||||||
msgstr "Häufig"
|
msgstr "Uhr"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:407
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||||
|
msgid "Customize the panel clock"
|
||||||
|
msgstr "Die Uhr im Panel anpassen"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:1
|
||||||
|
#| msgid "<b>Clock Format</b>"
|
||||||
|
msgid "Clock Format"
|
||||||
|
msgstr "Uhr-Format"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:2
|
||||||
|
msgid "Clock Preferences"
|
||||||
|
msgstr "Uhr-Einstellungen"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:3
|
||||||
|
#| msgid "<b>Panel Display</b>"
|
||||||
|
msgid "Panel Display"
|
||||||
|
msgstr "Panel-Anzeige"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:4
|
||||||
|
msgid "Show seco_nds"
|
||||||
|
msgstr "_Sekunden anzeigen"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:5
|
||||||
|
msgid "Show the _date"
|
||||||
|
msgstr "_Datum anzeigen"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:6
|
||||||
|
msgid "_12 hour format"
|
||||||
|
msgstr "_12-Stunden-Format"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:7
|
||||||
|
msgid "_24 hour format"
|
||||||
|
msgstr "_24-Stunden-Format"
|
||||||
|
|
||||||
|
#. **** Applications ****
|
||||||
|
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||||
|
msgid "APPLICATIONS"
|
||||||
|
msgstr "ANWENDUNGEN"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:338
|
||||||
|
msgid "PREFERENCES"
|
||||||
|
msgstr "EINSTELLUNGEN"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:705
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Neues Fenster"
|
msgstr "Neues Fenster"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:420
|
#: ../js/ui/appDisplay.js:709
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Aus Favoriten entfernen"
|
msgstr "Aus Favoriten entfernen"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:421
|
#: ../js/ui/appDisplay.js:710
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Zu Favoriten hinzufügen"
|
msgstr "Zu Favoriten hinzufügen"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:283
|
#: ../js/ui/appDisplay.js:1037
|
||||||
msgid "Find..."
|
msgid "Drag here to add favorites"
|
||||||
msgstr "Suchen …"
|
msgstr "Hier ablegen, um zu Favoriten hinzuzufügen"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:400
|
#: ../js/ui/appFavorites.js:89
|
||||||
msgid "More"
|
#, c-format
|
||||||
msgstr "Mehr"
|
msgid "%s has been added to your favorites."
|
||||||
|
msgstr "%s wurde zu Ihren Favoriten hinzugefügt"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:543
|
#: ../js/ui/appFavorites.js:107
|
||||||
msgid "(see all)"
|
#, c-format
|
||||||
msgstr "(alle sehen)"
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "%s wurde aus Ihren Favoriten entfernt"
|
||||||
|
|
||||||
#. **** Applications ****
|
#: ../js/ui/dash.js:189
|
||||||
#: ../js/ui/dash.js:725 ../js/ui/dash.js:787
|
msgid "Find"
|
||||||
msgid "APPLICATIONS"
|
msgstr "Suchen"
|
||||||
msgstr "ANWENDUNGEN"
|
|
||||||
|
#: ../js/ui/dash.js:505
|
||||||
|
msgid "Searching..."
|
||||||
|
msgstr "Suche läuft …"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:519
|
||||||
|
msgid "No matching results."
|
||||||
|
msgstr "Keine passenden Ergebnisse."
|
||||||
|
|
||||||
#. **** Places ****
|
#. **** Places ****
|
||||||
#. Translators: This is in the sense of locations for documents,
|
#. Translators: This is in the sense of locations for documents,
|
||||||
#. network locations, etc.
|
#. network locations, etc.
|
||||||
#: ../js/ui/dash.js:745
|
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||||
msgid "PLACES"
|
msgid "PLACES & DEVICES"
|
||||||
msgstr "ORTE"
|
msgstr "ORTE UND GERÄTE"
|
||||||
|
|
||||||
#. **** Documents ****
|
#. **** Documents ****
|
||||||
#: ../js/ui/dash.js:752 ../js/ui/dash.js:797
|
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||||
msgid "RECENT DOCUMENTS"
|
msgid "RECENT ITEMS"
|
||||||
msgstr "ZULETZT GEÖFFNETE DOKUMENTE"
|
msgstr "ZULETZT GEÖFFNETE DOKUMENTE"
|
||||||
|
|
||||||
#. **** Search Results ****
|
#: ../js/ui/lookingGlass.js:466
|
||||||
#: ../js/ui/dash.js:777 ../js/ui/dash.js:961
|
msgid "No extensions installed"
|
||||||
msgid "SEARCH RESULTS"
|
msgstr "Keine Erweiterungen installiert"
|
||||||
msgstr "SUCHERGEBNISSE"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:792
|
#: ../js/ui/lookingGlass.js:503
|
||||||
msgid "PREFERENCES"
|
msgid "Enabled"
|
||||||
msgstr "EINSTELLUNGEN"
|
msgstr "Aktiviert"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:505
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "Deaktiviert"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:507
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "Fehler"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:509
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr "Veraltet"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:534
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr "Quelle zeigen"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:540
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr "Webseite"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:161
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Rückgängig"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:535
|
||||||
|
msgid "Quit"
|
||||||
|
msgstr "Beenden"
|
||||||
|
|
||||||
#. Button on the left side of the panel.
|
#. Button on the left side of the panel.
|
||||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:273
|
#: ../js/ui/panel.js:740
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Aktivitäten"
|
msgstr "Aktivitäten"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#. Translators: This is the time format with date used
|
||||||
#: ../js/ui/panel.js:465
|
#. in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:955
|
||||||
|
msgid "%a %b %e, %R:%S"
|
||||||
|
msgstr "%a, %e. %b, %R:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:956
|
||||||
|
msgid "%a %b %e, %R"
|
||||||
|
msgstr "%a, %e. %b, %R"
|
||||||
|
|
||||||
|
#. Translators: This is the time format without date used
|
||||||
|
#. in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:960
|
||||||
|
msgid "%a %R:%S"
|
||||||
|
msgstr "%a %R:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:961
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%a %R"
|
||||||
|
|
||||||
|
#. Translators: This is a time format with date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:968
|
||||||
|
msgid "%a %b %e, %l:%M:%S %p"
|
||||||
|
msgstr "%a, %e. %b, %H:%M:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:969
|
||||||
|
msgid "%a %b %e, %l:%M %p"
|
||||||
|
msgstr "%a, %e. %b, %H:%M"
|
||||||
|
|
||||||
|
#. Translators: This is a time format without date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:973
|
||||||
|
msgid "%a %l:%M:%S %p"
|
||||||
|
msgstr "%a %H:%M:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:974
|
||||||
msgid "%a %l:%M %p"
|
msgid "%a %l:%M %p"
|
||||||
msgstr "%a %H:%M"
|
msgstr "%a %H:%M"
|
||||||
|
|
||||||
#: ../js/ui/places.js:178
|
#: ../js/ui/placeDisplay.js:108
|
||||||
|
#, c-format
|
||||||
|
msgid "Failed to unmount '%s'"
|
||||||
|
msgstr "»%s« konnte nicht ausgehängt werden"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:111
|
||||||
|
msgid "Retry"
|
||||||
|
msgstr "Erneut versuchen"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:156
|
||||||
msgid "Connect to..."
|
msgid "Connect to..."
|
||||||
msgstr "Verbinden mit …"
|
msgstr "Verbinden mit …"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:96
|
#: ../js/ui/runDialog.js:231
|
||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Bitte geben Sie einen Befehl ein:"
|
msgstr "Bitte geben Sie einen Befehl ein:"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:173
|
#: ../js/ui/runDialog.js:375
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr "Ausführung von »%s« ist gescheitert:"
|
msgstr "Ausführung von »%s« ist gescheitert:"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#: ../js/ui/statusMenu.js:90
|
||||||
#: ../js/ui/widget.js:162
|
msgid "Available"
|
||||||
msgid "%H:%M"
|
msgstr "Verfügbar"
|
||||||
msgstr "%H:%M"
|
|
||||||
|
|
||||||
#: ../js/ui/widget.js:316
|
#: ../js/ui/statusMenu.js:94
|
||||||
msgid "Applications"
|
msgid "Busy"
|
||||||
msgstr "Anwendungen"
|
msgstr "Beschäftigt"
|
||||||
|
|
||||||
#: ../js/ui/widget.js:341
|
#: ../js/ui/statusMenu.js:98
|
||||||
msgid "Recent Documents"
|
msgid "Invisible"
|
||||||
msgstr "Zuletzt geöffnete Dokumente"
|
msgstr "Unsichtbar"
|
||||||
|
|
||||||
#: ../src/shell-global.c:812
|
#: ../js/ui/statusMenu.js:105
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "Benutzerinformationen …"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:109
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "Systemeinstellungen …"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:116
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "Bildschirm sperren"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:120
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "Benutzer wechseln"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:125
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "Abmelden …"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:129
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "Ausschalten …"
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:47
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has finished starting"
|
||||||
|
msgstr "Start von %s ist abgeschlossen"
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:49
|
||||||
|
#, c-format
|
||||||
|
msgid "'%s' is ready"
|
||||||
|
msgstr "»%s« ist bereit"
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:239
|
||||||
|
msgid ""
|
||||||
|
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||||
|
msgstr ""
|
||||||
|
"Es kann keine weitere Arbeitsfläche hinzugefügt werden, weil das Maximum an "
|
||||||
|
"Arbeitsflächen erreicht worden ist."
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:256
|
||||||
|
msgid "Can't remove the first workspace."
|
||||||
|
msgstr "Die erste Arbeitsfläche kann nicht entfernt werden."
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:976
|
||||||
msgid "Less than a minute ago"
|
msgid "Less than a minute ago"
|
||||||
msgstr "Vor weniger als einer Minute"
|
msgstr "Vor weniger als einer Minute"
|
||||||
|
|
||||||
#: ../src/shell-global.c:815
|
#: ../src/shell-global.c:980
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d minute ago"
|
msgid "%d minute ago"
|
||||||
msgid_plural "%d minutes ago"
|
msgid_plural "%d minutes ago"
|
||||||
msgstr[0] "Vor %d Minute"
|
msgstr[0] "Vor %d Minute"
|
||||||
msgstr[1] "Vor %d Minuten"
|
msgstr[1] "Vor %d Minuten"
|
||||||
|
|
||||||
#: ../src/shell-global.c:818
|
#: ../src/shell-global.c:985
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour ago"
|
msgid "%d hour ago"
|
||||||
msgid_plural "%d hours ago"
|
msgid_plural "%d hours ago"
|
||||||
msgstr[0] "Vor %d Stunde"
|
msgstr[0] "Vor %d Stunde"
|
||||||
msgstr[1] "Vor %d Stunden"
|
msgstr[1] "Vor %d Stunden"
|
||||||
|
|
||||||
#: ../src/shell-global.c:821
|
#: ../src/shell-global.c:990
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d day ago"
|
msgid "%d day ago"
|
||||||
msgid_plural "%d days ago"
|
msgid_plural "%d days ago"
|
||||||
msgstr[0] "Vor %d Tag"
|
msgstr[0] "Vor %d Tag"
|
||||||
msgstr[1] "Vor %d Tagen"
|
msgstr[1] "Vor %d Tagen"
|
||||||
|
|
||||||
#: ../src/shell-global.c:824
|
#: ../src/shell-global.c:995
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d week ago"
|
msgid "%d week ago"
|
||||||
msgid_plural "%d weeks ago"
|
msgid_plural "%d weeks ago"
|
||||||
msgstr[0] "Vor %d Woche"
|
msgstr[0] "Vor %d Woche"
|
||||||
msgstr[1] "Vor %d Wochen"
|
msgstr[1] "Vor %d Wochen"
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:156
|
#: ../src/shell-uri-util.c:89
|
||||||
msgid "Unknown"
|
|
||||||
msgstr "Unbekannt"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:212
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't lock screen: %s"
|
|
||||||
msgstr "Bildschirm kann nicht gesperrt werden: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:227
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
|
||||||
msgstr ""
|
|
||||||
"Der Bildschirmschoner kann vorübergehend nicht auf einen leeren Schirm "
|
|
||||||
"gesetzt werden: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:351
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't logout: %s"
|
|
||||||
msgstr "Abmelden ist nicht möglich: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:492
|
|
||||||
msgid "Account Information..."
|
|
||||||
msgstr "Benutzerinformationen …"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:502
|
|
||||||
msgid "Sidebar"
|
|
||||||
msgstr "Seitenleiste"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:510
|
|
||||||
msgid "System Preferences..."
|
|
||||||
msgstr "Systemeinstellungen …"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:525
|
|
||||||
msgid "Lock Screen"
|
|
||||||
msgstr "Bildschirm sperren"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:535
|
|
||||||
msgid "Switch User"
|
|
||||||
msgstr "Benutzer wechseln"
|
|
||||||
|
|
||||||
#. Only show switch user if there are other users
|
|
||||||
#. Log Out
|
|
||||||
#: ../src/shell-status-menu.c:546
|
|
||||||
msgid "Log Out..."
|
|
||||||
msgstr "Abmelden …"
|
|
||||||
|
|
||||||
#. Shut down
|
|
||||||
#: ../src/shell-status-menu.c:557
|
|
||||||
msgid "Shut Down..."
|
|
||||||
msgstr "Ausschalten …"
|
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:87
|
|
||||||
msgid "Home Folder"
|
msgid "Home Folder"
|
||||||
msgstr "Persönlicher Ordner"
|
msgstr "Persönlicher Ordner"
|
||||||
|
|
||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-uri-util.c:102
|
#: ../src/shell-uri-util.c:104
|
||||||
msgid "File System"
|
msgid "File System"
|
||||||
msgstr "Dateisystem"
|
msgstr "Dateisystem"
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:248
|
#: ../src/shell-uri-util.c:250
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Suchen"
|
msgstr "Suchen"
|
||||||
|
|
||||||
@ -223,11 +342,52 @@ msgstr "Suchen"
|
|||||||
#. * example, "Trash: some-directory". It means that the
|
#. * example, "Trash: some-directory". It means that the
|
||||||
#. * directory called "some-directory" is in the trash.
|
#. * directory called "some-directory" is in the trash.
|
||||||
#.
|
#.
|
||||||
#: ../src/shell-uri-util.c:298
|
#: ../src/shell-uri-util.c:300
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s: %2$s"
|
msgid "%1$s: %2$s"
|
||||||
msgstr "%1$s: %2$s"
|
msgstr "%1$s: %2$s"
|
||||||
|
|
||||||
|
#~ msgid "Sidebar"
|
||||||
|
#~ msgstr "Seitenleiste"
|
||||||
|
|
||||||
|
#~ msgid "%H:%M"
|
||||||
|
#~ msgstr "%H:%M"
|
||||||
|
|
||||||
|
#~ msgid "Applications"
|
||||||
|
#~ msgstr "Anwendungen"
|
||||||
|
|
||||||
|
#~ msgid "Recent Documents"
|
||||||
|
#~ msgstr "Zuletzt geöffnete Dokumente"
|
||||||
|
|
||||||
|
#~ msgid "Frequent"
|
||||||
|
#~ msgstr "Häufig"
|
||||||
|
|
||||||
|
#~ msgid "More"
|
||||||
|
#~ msgstr "Mehr"
|
||||||
|
|
||||||
|
#~ msgid "(see all)"
|
||||||
|
#~ msgstr "(alle sehen)"
|
||||||
|
|
||||||
|
#~ msgid "PLACES"
|
||||||
|
#~ msgstr "ORTE"
|
||||||
|
|
||||||
|
#~ msgid "SEARCH RESULTS"
|
||||||
|
#~ msgstr "SUCHERGEBNISSE"
|
||||||
|
|
||||||
|
#~ msgid "Unknown"
|
||||||
|
#~ msgstr "Unbekannt"
|
||||||
|
|
||||||
|
#~ msgid "Can't lock screen: %s"
|
||||||
|
#~ msgstr "Bildschirm kann nicht gesperrt werden: %s"
|
||||||
|
|
||||||
|
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||||
|
#~ msgstr ""
|
||||||
|
#~ "Der Bildschirmschoner kann vorübergehend nicht auf einen leeren Schirm "
|
||||||
|
#~ "gesetzt werden: %s"
|
||||||
|
|
||||||
|
#~ msgid "Can't logout: %s"
|
||||||
|
#~ msgstr "Abmelden ist nicht möglich: %s"
|
||||||
|
|
||||||
#~ msgid "Find apps or documents"
|
#~ msgid "Find apps or documents"
|
||||||
#~ msgstr "Anwendungen oder Dokumente suchen"
|
#~ msgstr "Anwendungen oder Dokumente suchen"
|
||||||
|
|
||||||
|
312
po/el.po
@ -7,10 +7,10 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell.po.master\n"
|
"Project-Id-Version: gnome-shell.po.master\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&component=general\n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2009-10-04 08:03+0000\n"
|
"POT-Creation-Date: 2010-03-28 10:46+0300\n"
|
||||||
"PO-Revision-Date: 2009-10-04 10:25+0200\n"
|
"PO-Revision-Date: 2010-03-28 10:53+0200\n"
|
||||||
"Last-Translator: Jennie Petoumenou <epetoumenou@gmail.com>\n"
|
"Last-Translator: Kostas Papadimas <pkst@gnome.org>\n"
|
||||||
"Language-Team: Greek <<team AT BLOCKSPAM gnome DOT gr>>\n"
|
"Language-Team: Greek <<team AT BLOCKSPAM gnome DOT gr>>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@ -26,151 +26,244 @@ msgstr "Κέλυφος GNOME"
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "Διαχείριση παραθύρων και εκκίνηση εφαρμογών"
|
msgstr "Διαχείριση παραθύρων και εκκίνηση εφαρμογών"
|
||||||
|
|
||||||
#. left side
|
|
||||||
#: ../js/ui/panel.js:271
|
|
||||||
msgid "Activities"
|
|
||||||
msgstr "Δραστηριότητες"
|
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
|
||||||
#: ../js/ui/panel.js:461
|
|
||||||
msgid "%a %l:%M %p"
|
|
||||||
msgstr "%a %l:%M %p"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:283
|
|
||||||
msgid "Find..."
|
|
||||||
msgstr "Εύρεση..."
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:400
|
|
||||||
msgid "More"
|
|
||||||
msgstr "Περισσότερα"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:543
|
|
||||||
msgid "(see all)"
|
|
||||||
msgstr "(εμφάνιση όλων)"
|
|
||||||
|
|
||||||
#. **** Applications ****
|
#. **** Applications ****
|
||||||
#: ../js/ui/dash.js:763 ../js/ui/dash.js:825
|
#: ../js/ui/appDisplay.js:312
|
||||||
|
#: ../js/ui/dash.js:855
|
||||||
msgid "APPLICATIONS"
|
msgid "APPLICATIONS"
|
||||||
msgstr "ΕΦΑΡΜΟΓΕΣ"
|
msgstr "ΕΦΑΡΜΟΓΕΣ"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:344
|
||||||
|
msgid "PREFERENCES"
|
||||||
|
msgstr "ΠΡΟΤΙΜΗΣΕΙΣ"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:756
|
||||||
|
msgid "New Window"
|
||||||
|
msgstr "Νέο παράθυρο"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:760
|
||||||
|
msgid "Remove from Favorites"
|
||||||
|
msgstr "Αφαίρεση από τα αγαπημένα"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:761
|
||||||
|
msgid "Add to Favorites"
|
||||||
|
msgstr "Προσθήκη στα αγαπημένα"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:1113
|
||||||
|
msgid "Drag here to add favorites"
|
||||||
|
msgstr "Σύρετε εδώ για να προσθέσετε αγαπημένα"
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:89
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been added to your favorites."
|
||||||
|
msgstr "%s προστέθηκε στα αγαπημένα σας"
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:107
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "%s αφαιρέθηκε από τα αγαπημένα σας"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:194
|
||||||
|
msgid "Find"
|
||||||
|
msgstr "Εύρεση"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:510
|
||||||
|
msgid "Searching..."
|
||||||
|
msgstr "Αναζήτηση..."
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:524
|
||||||
|
msgid "No matching results."
|
||||||
|
msgstr "Δεν βρέθηκαν ταιριάσματα."
|
||||||
|
|
||||||
#. **** Places ****
|
#. **** Places ****
|
||||||
#. Translators: This is in the sense of locations for documents,
|
#. Translators: This is in the sense of locations for documents,
|
||||||
#. network locations, etc.
|
#. network locations, etc.
|
||||||
#: ../js/ui/dash.js:783
|
#: ../js/ui/dash.js:874
|
||||||
msgid "PLACES"
|
#: ../js/ui/placeDisplay.js:582
|
||||||
msgstr "ΤΟΠΟΘΕΣΙΕΣ"
|
msgid "PLACES & DEVICES"
|
||||||
|
msgstr "ΤΟΠΟΘΕΣΙΕΣ $ ΣΥΣΚΕΥΕΣ"
|
||||||
|
|
||||||
#. **** Documents ****
|
#. **** Documents ****
|
||||||
#: ../js/ui/dash.js:790 ../js/ui/dash.js:835
|
#: ../js/ui/dash.js:881
|
||||||
msgid "RECENT DOCUMENTS"
|
#: ../js/ui/docDisplay.js:488
|
||||||
msgstr "ΠΡΟΣΦΑΤΑ ΕΓΓΡΑΦΑ"
|
msgid "RECENT ITEMS"
|
||||||
|
msgstr "ΠΡΟΣΦΑΤΑ ΑΝΤΙΚΕΙΜΕΝΑ"
|
||||||
|
|
||||||
#. **** Search Results ****
|
#: ../js/ui/lookingGlass.js:363
|
||||||
#: ../js/ui/dash.js:815 ../js/ui/dash.js:955
|
msgid "No extensions installed"
|
||||||
msgid "SEARCH RESULTS"
|
msgstr "Δεν υπάρχουν εγκατεστημένες επεκτάσεις"
|
||||||
msgstr "ΑΠΟΤΕΛΕΣΜΑΤΑ ΑΝΑΖΗΤΗΣΗΣ"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:830
|
#: ../js/ui/lookingGlass.js:400
|
||||||
msgid "PREFERENCES"
|
msgid "Enabled"
|
||||||
msgstr "ΠΡΟΤΙΜΗΣΕΙΣ"
|
msgstr ""
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:96
|
#: ../js/ui/lookingGlass.js:402
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:404
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "Σφάλμα"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:406
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:431
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr "Προβολή πηγής"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:437
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr "Ιστοσελίδα"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:182
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Αναίρεση"
|
||||||
|
|
||||||
|
#. Button on the left side of the panel.
|
||||||
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
|
#: ../js/ui/panel.js:385
|
||||||
|
msgid "Activities"
|
||||||
|
msgstr "Δραστηριότητες"
|
||||||
|
|
||||||
|
#. Translators: This is the time format used in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:616
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%a %R"
|
||||||
|
|
||||||
|
#. Translators: This is a time format used for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:619
|
||||||
|
msgid "%a %l:%M %p"
|
||||||
|
msgstr "%a %l:%M %p"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:108
|
||||||
|
#, c-format
|
||||||
|
msgid "Failed to unmount '%s'"
|
||||||
|
msgstr "Αποτυχία αποπροσάρτησης '%s'"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:111
|
||||||
|
msgid "Retry"
|
||||||
|
msgstr "Προσπάθεια ξανά"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:156
|
||||||
|
msgid "Connect to..."
|
||||||
|
msgstr "Σύνδεση σε..."
|
||||||
|
|
||||||
|
#: ../js/ui/runDialog.js:232
|
||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Παρακαλώ εισάγετε μία εντολή:"
|
msgstr "Παρακαλώ εισάγετε μία εντολή:"
|
||||||
|
|
||||||
#: ../src/shell-global.c:812
|
#: ../js/ui/runDialog.js:376
|
||||||
|
#, c-format
|
||||||
|
msgid "Execution of '%s' failed:"
|
||||||
|
msgstr "Η εκτέλεση του '%s' απέτυχε:"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:107
|
||||||
|
msgid "Available"
|
||||||
|
msgstr "Διαθέσιμος"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:112
|
||||||
|
msgid "Busy"
|
||||||
|
msgstr "Απασχολημένος"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:117
|
||||||
|
msgid "Invisible"
|
||||||
|
msgstr "Αόρατος"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:126
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "Πληροφορίες λογαριασμού..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:132
|
||||||
|
msgid "Sidebar"
|
||||||
|
msgstr "Πλευρική στήλη"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:142
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "Προστιμήσεις συστήματος..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:151
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "Κλείδωμα οθόνης"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:156
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "Αλλαγή χρήστη"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:162
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "Αποσύνδεση..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:167
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "Τερματισμός..."
|
||||||
|
|
||||||
|
#. Translators: This is a time format.
|
||||||
|
#: ../js/ui/widget.js:163
|
||||||
|
msgid "%H:%M"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../js/ui/widget.js:317
|
||||||
|
msgid "Applications"
|
||||||
|
msgstr "Εφαρμογές"
|
||||||
|
|
||||||
|
#: ../js/ui/widget.js:339
|
||||||
|
msgid "Recent Documents"
|
||||||
|
msgstr "Πρόσφατα έγγραφα"
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:47
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has finished starting"
|
||||||
|
msgstr "%s ολοκλήρωσε την εκκίνηση "
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:49
|
||||||
|
#, c-format
|
||||||
|
msgid "'%s' is ready"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:967
|
||||||
msgid "Less than a minute ago"
|
msgid "Less than a minute ago"
|
||||||
msgstr "Λιγότερο από ένα λεπτό πριν"
|
msgstr "Λιγότερο από ένα λεπτό πριν"
|
||||||
|
|
||||||
#: ../src/shell-global.c:815
|
#: ../src/shell-global.c:971
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d minute ago"
|
msgid "%d minute ago"
|
||||||
msgid_plural "%d minutes ago"
|
msgid_plural "%d minutes ago"
|
||||||
msgstr[0] "%d λεπτό πριν"
|
msgstr[0] "%d λεπτό πριν"
|
||||||
msgstr[1] "%d λεπτά πριν"
|
msgstr[1] "%d λεπτά πριν"
|
||||||
|
|
||||||
#: ../src/shell-global.c:818
|
#: ../src/shell-global.c:976
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour ago"
|
msgid "%d hour ago"
|
||||||
msgid_plural "%d hours ago"
|
msgid_plural "%d hours ago"
|
||||||
msgstr[0] "%d ώρα πριν"
|
msgstr[0] "%d ώρα πριν"
|
||||||
msgstr[1] "%d ώρες πριν"
|
msgstr[1] "%d ώρες πριν"
|
||||||
|
|
||||||
#: ../src/shell-global.c:821
|
#: ../src/shell-global.c:981
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d day ago"
|
msgid "%d day ago"
|
||||||
msgid_plural "%d days ago"
|
msgid_plural "%d days ago"
|
||||||
msgstr[0] "%d ημέρα πριν"
|
msgstr[0] "%d ημέρα πριν"
|
||||||
msgstr[1] "%d ημέρες πριν"
|
msgstr[1] "%d ημέρες πριν"
|
||||||
|
|
||||||
#: ../src/shell-global.c:824
|
#: ../src/shell-global.c:986
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d week ago"
|
msgid "%d week ago"
|
||||||
msgid_plural "%d weeks ago"
|
msgid_plural "%d weeks ago"
|
||||||
msgstr[0] "%d εβδομάδα πριν"
|
msgstr[0] "%d εβδομάδα πριν"
|
||||||
msgstr[1] "%d εβδομάδες πριν"
|
msgstr[1] "%d εβδομάδες πριν"
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:156
|
#: ../src/shell-uri-util.c:89
|
||||||
msgid "Unknown"
|
|
||||||
msgstr "Άγνωστο"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:212
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't lock screen: %s"
|
|
||||||
msgstr "Αδύνατο το κλείδωμα της οθόνης: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:227
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
|
||||||
msgstr "Δεν είναι δυνατή η προσωρινή ρύθμιση της προστασίας οθόνης σε κενή οθόνη: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:351
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't logout: %s"
|
|
||||||
msgstr "Αδύνατη η αποσύνδεση: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:492
|
|
||||||
msgid "Account Information..."
|
|
||||||
msgstr "Πληροφορίες λογαριασμού..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:502
|
|
||||||
msgid "Sidebar"
|
|
||||||
msgstr "Πλευρική στήλη"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:510
|
|
||||||
msgid "System Preferences..."
|
|
||||||
msgstr "Προστιμήσεις συστήματος..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:525
|
|
||||||
msgid "Lock Screen"
|
|
||||||
msgstr "Κλείδωμα οθόνης"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:535
|
|
||||||
msgid "Switch User"
|
|
||||||
msgstr "Αλλαγή χρήστη"
|
|
||||||
|
|
||||||
#. Only show switch user if there are other users
|
|
||||||
#. Log Out
|
|
||||||
#: ../src/shell-status-menu.c:546
|
|
||||||
msgid "Log Out..."
|
|
||||||
msgstr "Αποσύνδεση..."
|
|
||||||
|
|
||||||
#. Shut down
|
|
||||||
#: ../src/shell-status-menu.c:557
|
|
||||||
msgid "Shut Down..."
|
|
||||||
msgstr "Τερματισμός..."
|
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:87
|
|
||||||
msgid "Home Folder"
|
msgid "Home Folder"
|
||||||
msgstr "Προσωπικός φάκελος"
|
msgstr "Προσωπικός φάκελος"
|
||||||
|
|
||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-uri-util.c:102
|
#: ../src/shell-uri-util.c:104
|
||||||
msgid "File System"
|
msgid "File System"
|
||||||
msgstr "Σύστημα αρχείων"
|
msgstr "Σύστημα αρχείων"
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:248
|
#: ../src/shell-uri-util.c:250
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Αναζήτηση"
|
msgstr "Αναζήτηση"
|
||||||
|
|
||||||
@ -179,8 +272,27 @@ msgstr "Αναζήτηση"
|
|||||||
#. * example, "Trash: some-directory". It means that the
|
#. * example, "Trash: some-directory". It means that the
|
||||||
#. * directory called "some-directory" is in the trash.
|
#. * directory called "some-directory" is in the trash.
|
||||||
#.
|
#.
|
||||||
#: ../src/shell-uri-util.c:298
|
#: ../src/shell-uri-util.c:300
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s: %2$s"
|
msgid "%1$s: %2$s"
|
||||||
msgstr "%1$s: %2$s"
|
msgstr "%1$s: %2$s"
|
||||||
|
|
||||||
|
#~ msgid "More"
|
||||||
|
#~ msgstr "Περισσότερα"
|
||||||
|
#~ msgid "(see all)"
|
||||||
|
#~ msgstr "(εμφάνιση όλων)"
|
||||||
|
#~ msgid "PLACES"
|
||||||
|
#~ msgstr "ΤΟΠΟΘΕΣΙΕΣ"
|
||||||
|
#~ msgid "SEARCH RESULTS"
|
||||||
|
#~ msgstr "ΑΠΟΤΕΛΕΣΜΑΤΑ ΑΝΑΖΗΤΗΣΗΣ"
|
||||||
|
#~ msgid "Unknown"
|
||||||
|
#~ msgstr "Άγνωστο"
|
||||||
|
#~ msgid "Can't lock screen: %s"
|
||||||
|
#~ msgstr "Αδύνατο το κλείδωμα της οθόνης: %s"
|
||||||
|
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||||
|
#~ msgstr ""
|
||||||
|
#~ "Δεν είναι δυνατή η προσωρινή ρύθμιση της προστασίας οθόνης σε κενή οθόνη: "
|
||||||
|
#~ "%s"
|
||||||
|
#~ msgid "Can't logout: %s"
|
||||||
|
#~ msgstr "Αδύνατη η αποσύνδεση: %s"
|
||||||
|
|
||||||
|
308
po/en_GB.po
@ -2,20 +2,22 @@
|
|||||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
# Philip Withnall <philip@tecnocode.co.uk>, 2009.
|
# Philip Withnall <philip@tecnocode.co.uk>, 2009.
|
||||||
#
|
# Bruce Cowan <bcowan@fastmail.co.uk>, 2010.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&component=general\n"
|
"shell&component=general\n"
|
||||||
"POT-Creation-Date: 2009-09-12 12:41+0000\n"
|
"POT-Creation-Date: 2010-03-20 22:31+0000\n"
|
||||||
"PO-Revision-Date: 2009-09-12 12:41+0000\n"
|
"PO-Revision-Date: 2010-03-20 22:32+0100\n"
|
||||||
"Last-Translator: Philip Withnall <philip@tecnocode.co.uk>\n"
|
"Last-Translator: Bruce Cowan <bcowan@fastmail.co.uk>\n"
|
||||||
"Language-Team: British English <en_GB@li.org>\n"
|
"Language-Team: British English <en@li.org>\n"
|
||||||
|
"Language: en_GB\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Generator: Virtaal 0.5.2\n"
|
||||||
|
|
||||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||||
msgid "GNOME Shell"
|
msgid "GNOME Shell"
|
||||||
@ -25,151 +27,231 @@ msgstr "GNOME Shell"
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "Window management and application launching"
|
msgstr "Window management and application launching"
|
||||||
|
|
||||||
#. left side
|
|
||||||
#: ../js/ui/panel.js:269
|
|
||||||
msgid "Activities"
|
|
||||||
msgstr "Activities"
|
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
|
||||||
#: ../js/ui/panel.js:452
|
|
||||||
msgid "%a %l:%M %p"
|
|
||||||
msgstr "%a %l:%M %p"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:283
|
|
||||||
msgid "Find..."
|
|
||||||
msgstr "Find…"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:400
|
|
||||||
msgid "Browse"
|
|
||||||
msgstr "Browse"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:536
|
|
||||||
msgid "(see all)"
|
|
||||||
msgstr "(see all)"
|
|
||||||
|
|
||||||
#. **** Applications ****
|
#. **** Applications ****
|
||||||
#: ../js/ui/dash.js:753 ../js/ui/dash.js:809
|
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:852
|
||||||
msgid "APPLICATIONS"
|
msgid "APPLICATIONS"
|
||||||
msgstr "APPLICATIONS"
|
msgstr "APPLICATIONS"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:343
|
||||||
|
msgid "PREFERENCES"
|
||||||
|
msgstr "PREFERENCES"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:728
|
||||||
|
msgid "New Window"
|
||||||
|
msgstr "New Window"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:732
|
||||||
|
msgid "Remove from Favorites"
|
||||||
|
msgstr "Remove from Favourites"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:733
|
||||||
|
msgid "Add to Favorites"
|
||||||
|
msgstr "Add to Favourites"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:1085
|
||||||
|
msgid "Drag here to add favorites"
|
||||||
|
msgstr "Drag here to add favourites"
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:89
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been added to your favorites."
|
||||||
|
msgstr "%s has been added to your favourites."
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:107
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "%s has been removed from your favourites."
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:194
|
||||||
|
msgid "Find"
|
||||||
|
msgstr "Find"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:507
|
||||||
|
msgid "Searching..."
|
||||||
|
msgstr "Searching…"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:521
|
||||||
|
msgid "No matching results."
|
||||||
|
msgstr "No matching results."
|
||||||
|
|
||||||
#. **** Places ****
|
#. **** Places ****
|
||||||
#. Translators: This is in the sense of locations for documents,
|
#. Translators: This is in the sense of locations for documents,
|
||||||
#. network locations, etc.
|
#. network locations, etc.
|
||||||
#: ../js/ui/dash.js:773
|
#: ../js/ui/dash.js:871 ../js/ui/placeDisplay.js:579
|
||||||
msgid "PLACES"
|
msgid "PLACES & DEVICES"
|
||||||
msgstr "PLACES"
|
msgstr "PLACES & DEVICES"
|
||||||
|
|
||||||
#. **** Documents ****
|
#. **** Documents ****
|
||||||
#: ../js/ui/dash.js:780 ../js/ui/dash.js:819
|
#: ../js/ui/dash.js:878 ../js/ui/docDisplay.js:488
|
||||||
msgid "RECENT DOCUMENTS"
|
msgid "RECENT ITEMS"
|
||||||
msgstr "RECENT DOCUMENTS"
|
msgstr "RECENT ITEMS"
|
||||||
|
|
||||||
#. **** Search Results ****
|
#: ../js/ui/lookingGlass.js:363
|
||||||
#: ../js/ui/dash.js:799 ../js/ui/dash.js:931
|
msgid "No extensions installed"
|
||||||
msgid "SEARCH RESULTS"
|
msgstr "No extensions installed"
|
||||||
msgstr "SEARCH RESULTS"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:814
|
#: ../js/ui/lookingGlass.js:400
|
||||||
msgid "PREFERENCES"
|
msgid "Enabled"
|
||||||
msgstr "PREFERENCES"
|
msgstr "Enabled"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:90
|
#: ../js/ui/lookingGlass.js:402
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "Disabled"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:404
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "Error"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:406
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr "Out of date"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:431
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr "View Source"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:437
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr "Web Page"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:182
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Undo"
|
||||||
|
|
||||||
|
#. Button on the left side of the panel.
|
||||||
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
|
#: ../js/ui/panel.js:385
|
||||||
|
msgid "Activities"
|
||||||
|
msgstr "Activities"
|
||||||
|
|
||||||
|
#. Translators: This is the time format used in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:616
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%a %R"
|
||||||
|
|
||||||
|
#. Translators: This is a time format used for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:619
|
||||||
|
msgid "%a %l:%M %p"
|
||||||
|
msgstr "%a %l:%M %p"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:103
|
||||||
|
#, c-format
|
||||||
|
msgid "Failed to unmount '%s'"
|
||||||
|
msgstr "Failed to unmount '%s'"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:106
|
||||||
|
msgid "Retry"
|
||||||
|
msgstr "Retry"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:151
|
||||||
|
msgid "Connect to..."
|
||||||
|
msgstr "Connect to…"
|
||||||
|
|
||||||
|
#: ../js/ui/runDialog.js:232
|
||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Please enter a command:"
|
msgstr "Please enter a command:"
|
||||||
|
|
||||||
#: ../src/shell-global.c:799
|
#: ../js/ui/runDialog.js:374
|
||||||
|
#, c-format
|
||||||
|
msgid "Execution of '%s' failed:"
|
||||||
|
msgstr "Execution of '%s' failed:"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:107
|
||||||
|
msgid "Available"
|
||||||
|
msgstr "Available"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:112
|
||||||
|
msgid "Busy"
|
||||||
|
msgstr "Busy"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:117
|
||||||
|
msgid "Invisible"
|
||||||
|
msgstr "Invisible"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:126
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "Account Information…"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:132
|
||||||
|
msgid "Sidebar"
|
||||||
|
msgstr "Sidebar"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:142
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "System Preferences…"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:151
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "Lock Screen"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:156
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "Switch User"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:162
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "Log Out…"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:167
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "Shut Down…"
|
||||||
|
|
||||||
|
#. Translators: This is a time format.
|
||||||
|
#: ../js/ui/widget.js:163
|
||||||
|
msgid "%H:%M"
|
||||||
|
msgstr "%H:%M"
|
||||||
|
|
||||||
|
#: ../js/ui/widget.js:317
|
||||||
|
msgid "Applications"
|
||||||
|
msgstr "Applications"
|
||||||
|
|
||||||
|
#: ../js/ui/widget.js:339
|
||||||
|
msgid "Recent Documents"
|
||||||
|
msgstr "Recent Documents"
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:967
|
||||||
msgid "Less than a minute ago"
|
msgid "Less than a minute ago"
|
||||||
msgstr "Less than a minute ago"
|
msgstr "Less than a minute ago"
|
||||||
|
|
||||||
#: ../src/shell-global.c:802
|
#: ../src/shell-global.c:971
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d minute ago"
|
msgid "%d minute ago"
|
||||||
msgid_plural "%d minutes ago"
|
msgid_plural "%d minutes ago"
|
||||||
msgstr[0] "%d minute ago"
|
msgstr[0] "%d minute ago"
|
||||||
msgstr[1] "%d minutes ago"
|
msgstr[1] "%d minutes ago"
|
||||||
|
|
||||||
#: ../src/shell-global.c:805
|
#: ../src/shell-global.c:976
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour ago"
|
msgid "%d hour ago"
|
||||||
msgid_plural "%d hours ago"
|
msgid_plural "%d hours ago"
|
||||||
msgstr[0] "%d hour ago"
|
msgstr[0] "%d hour ago"
|
||||||
msgstr[1] "%d hours ago"
|
msgstr[1] "%d hours ago"
|
||||||
|
|
||||||
#: ../src/shell-global.c:808
|
#: ../src/shell-global.c:981
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d day ago"
|
msgid "%d day ago"
|
||||||
msgid_plural "%d days ago"
|
msgid_plural "%d days ago"
|
||||||
msgstr[0] "%d day ago"
|
msgstr[0] "%d day ago"
|
||||||
msgstr[1] "%d days ago"
|
msgstr[1] "%d days ago"
|
||||||
|
|
||||||
#: ../src/shell-global.c:811
|
#: ../src/shell-global.c:986
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d week ago"
|
msgid "%d week ago"
|
||||||
msgid_plural "%d weeks ago"
|
msgid_plural "%d weeks ago"
|
||||||
msgstr[0] "%d week ago"
|
msgstr[0] "%d week ago"
|
||||||
msgstr[1] "%d weeks ago"
|
msgstr[1] "%d weeks ago"
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:156
|
#: ../src/shell-uri-util.c:89
|
||||||
msgid "Unknown"
|
|
||||||
msgstr "Unknown"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:212
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't lock screen: %s"
|
|
||||||
msgstr "Can't lock screen: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:227
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
|
||||||
msgstr "Can't temporarily set screensaver to blank screen: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:351
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't logout: %s"
|
|
||||||
msgstr "Can't logout: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:492
|
|
||||||
msgid "Account Information..."
|
|
||||||
msgstr "Account Information…"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:502
|
|
||||||
msgid "Sidebar"
|
|
||||||
msgstr "Sidebar"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:510
|
|
||||||
msgid "System Preferences..."
|
|
||||||
msgstr "System Preferences…"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:525
|
|
||||||
msgid "Lock Screen"
|
|
||||||
msgstr "Lock Screen"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:535
|
|
||||||
msgid "Switch User"
|
|
||||||
msgstr "Switch User"
|
|
||||||
|
|
||||||
#. Only show switch user if there are other users
|
|
||||||
#. Log Out
|
|
||||||
#: ../src/shell-status-menu.c:546
|
|
||||||
msgid "Log Out..."
|
|
||||||
msgstr "Log Out…"
|
|
||||||
|
|
||||||
#. Shut down
|
|
||||||
#: ../src/shell-status-menu.c:557
|
|
||||||
msgid "Shut Down..."
|
|
||||||
msgstr "Shut Down…"
|
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:87
|
|
||||||
msgid "Home Folder"
|
msgid "Home Folder"
|
||||||
msgstr "Home Folder"
|
msgstr "Home Folder"
|
||||||
|
|
||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-uri-util.c:102
|
#: ../src/shell-uri-util.c:104
|
||||||
msgid "File System"
|
msgid "File System"
|
||||||
msgstr "File System"
|
msgstr "File System"
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:248
|
#: ../src/shell-uri-util.c:250
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Search"
|
msgstr "Search"
|
||||||
|
|
||||||
@ -178,7 +260,31 @@ msgstr "Search"
|
|||||||
#. * example, "Trash: some-directory". It means that the
|
#. * example, "Trash: some-directory". It means that the
|
||||||
#. * directory called "some-directory" is in the trash.
|
#. * directory called "some-directory" is in the trash.
|
||||||
#.
|
#.
|
||||||
#: ../src/shell-uri-util.c:298
|
#: ../src/shell-uri-util.c:300
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s: %2$s"
|
msgid "%1$s: %2$s"
|
||||||
msgstr "%1$s: %2$s"
|
msgstr "%1$s: %2$s"
|
||||||
|
|
||||||
|
#~ msgid "Browse"
|
||||||
|
#~ msgstr "Browse"
|
||||||
|
|
||||||
|
#~ msgid "(see all)"
|
||||||
|
#~ msgstr "(see all)"
|
||||||
|
|
||||||
|
#~ msgid "PLACES"
|
||||||
|
#~ msgstr "PLACES"
|
||||||
|
|
||||||
|
#~ msgid "SEARCH RESULTS"
|
||||||
|
#~ msgstr "SEARCH RESULTS"
|
||||||
|
|
||||||
|
#~ msgid "Unknown"
|
||||||
|
#~ msgstr "Unknown"
|
||||||
|
|
||||||
|
#~ msgid "Can't lock screen: %s"
|
||||||
|
#~ msgstr "Can't lock screen: %s"
|
||||||
|
|
||||||
|
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||||
|
#~ msgstr "Can't temporarily set screensaver to blank screen: %s"
|
||||||
|
|
||||||
|
#~ msgid "Can't logout: %s"
|
||||||
|
#~ msgstr "Can't logout: %s"
|
||||||
|
475
po/es.po
@ -1,15 +1,15 @@
|
|||||||
# Spanish translation of gnome-shell.
|
# Spanish translation of gnome-shell.
|
||||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
|
# Jorge González <jorgegonz@svn.gnome.org>, 2009, 2010.
|
||||||
#
|
#
|
||||||
# Jorge González <jorgegonz@svn.gnome.org>, 2009.
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master\n"
|
"Project-Id-Version: gnome-shell master\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&component=general\n"
|
"shell&component=general\n"
|
||||||
"POT-Creation-Date: 2009-12-18 15:06+0000\n"
|
"POT-Creation-Date: 2010-07-02 06:59+0000\n"
|
||||||
"PO-Revision-Date: 2009-12-19 14:41+0100\n"
|
"PO-Revision-Date: 2010-07-03 12:50+0200\n"
|
||||||
"Last-Translator: Jorge González <jorgegonz@svn.gnome.org>\n"
|
"Last-Translator: Jorge González <jorgegonz@svn.gnome.org>\n"
|
||||||
"Language-Team: Español <gnome-es-list@gnome.org>\n"
|
"Language-Team: Español <gnome-es-list@gnome.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -25,115 +25,460 @@ msgstr "GNOME Shell"
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "Gestión de ventanas e inicio de aplicaciones"
|
msgstr "Gestión de ventanas e inicio de aplicaciones"
|
||||||
|
|
||||||
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||||
|
msgid "Clock"
|
||||||
|
msgstr "Reloj"
|
||||||
|
|
||||||
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||||
|
msgid "Customize the panel clock"
|
||||||
|
msgstr "Personalizar el reloj del panel"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:1
|
||||||
|
msgid ""
|
||||||
|
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
|
||||||
|
"dialog."
|
||||||
|
msgstr ""
|
||||||
|
"Permitir acceder a las herramientas internas de depuración monitorización "
|
||||||
|
"usando el diálogo Alt+F2"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:2
|
||||||
|
msgid "Custom format of the clock"
|
||||||
|
msgstr "Formato personalizado del reloj"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:3
|
||||||
|
msgid "Enable internal tools useful for developers and testers from Alt-F2"
|
||||||
|
msgstr ""
|
||||||
|
"Activar las herramientas internas, útiles para desarrolladores y probadores, "
|
||||||
|
"desde Alt+F2"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:4
|
||||||
|
msgid "File extension used for storing the screencast"
|
||||||
|
msgstr "Extensión de archivo que usar para almacenar los «screencast»"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:5
|
||||||
|
msgid "Framerate used for recording screencasts."
|
||||||
|
msgstr "Tasa de fotogramas usada para grabar «screencast»."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:6
|
||||||
|
msgid ""
|
||||||
|
"GNOME Shell extensions have a uuid property; this key lists extensions which "
|
||||||
|
"should not be loaded."
|
||||||
|
msgstr ""
|
||||||
|
"Las extensiones de GNOME Shell tienen una propiedad uuid; esta clave lista "
|
||||||
|
"las extensiones que no se deben cargar."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:7
|
||||||
|
msgid "History for command (Alt-F2) dialog"
|
||||||
|
msgstr "Histórico del diálogo de comandos (Alt+F2)"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:8
|
||||||
|
msgid "Hour format"
|
||||||
|
msgstr "Formato de la hora"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:9
|
||||||
|
msgid ""
|
||||||
|
"If true and format is either \"12-hour\" or \"24-hour\", display date in the "
|
||||||
|
"clock, in addition to time."
|
||||||
|
msgstr ""
|
||||||
|
"Si es cierta y el formato es «12-horas» o «24-horas», muestra la fecha en el "
|
||||||
|
"reloj, además de la hora."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:10
|
||||||
|
msgid ""
|
||||||
|
"If true and format is either \"12-hour\" or \"24-hour\", display seconds in "
|
||||||
|
"time."
|
||||||
|
msgstr ""
|
||||||
|
"Si es cierta y el formato es «12-horas» o «24-horas», muestra los segundos en "
|
||||||
|
"la hora."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:11
|
||||||
|
msgid "If true, display the ISO week date in the calendar."
|
||||||
|
msgstr "Si es cierta muestra la fecha de semana ISO en el calendario."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:12
|
||||||
|
msgid "List of desktop file IDs for favorite applications"
|
||||||
|
msgstr "Lista de ID de archivos de escritorio para las aplicaciones favoritas"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:13
|
||||||
|
msgid "Overview workspace view mode"
|
||||||
|
msgstr "Modo de visualización de la vista previa del área de trabajo"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:14
|
||||||
|
msgid ""
|
||||||
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
|
"used for gst-launch. The pipeline should have an unconnected sink pad where "
|
||||||
|
"the recorded video is recorded. It will normally have a unconnected source "
|
||||||
|
"pad; output from that pad will be written into the output file. However the "
|
||||||
|
"pipeline can also take care of its own output - this might be used to send "
|
||||||
|
"the output to an icecast server via shout2send or similar. When unset or set "
|
||||||
|
"to an empty value, the default pipeline will be used. This is currently "
|
||||||
|
"'videorate ! theoraenc ! oggmux' and records to Ogg Theora."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:15
|
||||||
|
msgid "Show date in clock"
|
||||||
|
msgstr "Mostrar la fecha en el reloj"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:16
|
||||||
|
msgid "Show the week date in the calendar"
|
||||||
|
msgstr "Mostrar la fecha de la semana en el calendario"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:17
|
||||||
|
msgid "Show time with seconds"
|
||||||
|
msgstr "Mostrar la hora con segundos"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:18
|
||||||
|
msgid ""
|
||||||
|
"The applications corresponding to these identifiers will be displayed in the "
|
||||||
|
"favorites area."
|
||||||
|
msgstr ""
|
||||||
|
"Las aplicaciones correspondientes con esos identificadores se mostrarán en "
|
||||||
|
"el área de favoritos."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:19
|
||||||
|
msgid ""
|
||||||
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
|
"a different container format."
|
||||||
|
msgstr ""
|
||||||
|
"El nombre de archivo para los «screencast» será un nombre de archivo único "
|
||||||
|
"basado en la fecha actual y usará esta extensión. Se debería cambiar al "
|
||||||
|
"grabar en otro formato contenedor diferente."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:20
|
||||||
|
msgid ""
|
||||||
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
|
"screencast recorder in frames-per-second."
|
||||||
|
msgstr ""
|
||||||
|
"La tasa de fotogramas de la grabación resultante grabada por el grabador de "
|
||||||
|
"«screencast» de GNOME Shell, en fotogramas por segundo."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:21
|
||||||
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
|
msgstr "La tubería de gstreamer usada para codificar el «screencast»"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:22
|
||||||
|
msgid ""
|
||||||
|
"The selected workspace view mode in the overview. Supported values are "
|
||||||
|
"\"single\" and \"grid\"."
|
||||||
|
msgstr ""
|
||||||
|
"El modo de vista del área de trabajo seleccionada en la vista general. Los "
|
||||||
|
"valores soportados son «single» (sencillo) y «grid» (rejilla)."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:23
|
||||||
|
msgid ""
|
||||||
|
"The shell normally monitors active applications in order to present the most "
|
||||||
|
"used ones (e.g. in launchers). While this data will be kept private, you may "
|
||||||
|
"want to disable this for privacy reasons. Please note that doing so won't "
|
||||||
|
"remove already saved data."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:24
|
||||||
|
msgid ""
|
||||||
|
"This key specifies the format used by the panel clock when the format key is "
|
||||||
|
"set to \"custom\". You can use conversion specifiers understood by strftime"
|
||||||
|
"() to obtain a specific format. See the strftime() manual for more "
|
||||||
|
"information."
|
||||||
|
msgstr ""
|
||||||
|
"Esta clave especifica el formato usado por el reloj del panel cuando la "
|
||||||
|
"clave del formato se establece a «custom» (personalizado). Puede usar "
|
||||||
|
"especificadores de conversión que entienda strftime() para obtener un "
|
||||||
|
"formato específico. Consulte el manual de strftime() para obtener más "
|
||||||
|
"información."
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:25
|
||||||
|
msgid ""
|
||||||
|
"This key specifies the hour format used by the panel clock. Possible values "
|
||||||
|
"are \"12-hour\", \"24-hour\", \"unix\" and \"custom\". If set to \"unix\", "
|
||||||
|
"the clock will display time in seconds since Epoch, i.e. 1970-01-01. If set "
|
||||||
|
"to \"custom\", the clock will display time according to the format specified "
|
||||||
|
"in the custom_format key. Note that if set to either \"unix\" or \"custom\", "
|
||||||
|
"the show_date and show_seconds keys are ignored."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:26
|
||||||
|
msgid "Uuids of extensions to disable"
|
||||||
|
msgstr "Uuid de las extensiones que desactivar"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.h:27
|
||||||
|
msgid "Whether to collect stats about applications usage"
|
||||||
|
msgstr ""
|
||||||
|
"Indica si se deben recolectar estadísticas acerca del uso de las aplicaciones"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:1
|
||||||
|
msgid "Clock Format"
|
||||||
|
msgstr "Formato del reloj"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:2
|
||||||
|
msgid "Clock Preferences"
|
||||||
|
msgstr "Preferencias del reloj"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:3
|
||||||
|
msgid "Panel Display"
|
||||||
|
msgstr "Panel de visualización"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:4
|
||||||
|
msgid "Show seco_nds"
|
||||||
|
msgstr "Mostrar los segu_ndos"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:5
|
||||||
|
msgid "Show the _date"
|
||||||
|
msgstr "Mostrar la _fecha"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:6
|
||||||
|
msgid "_12 hour format"
|
||||||
|
msgstr "Formato _12 horas"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:7
|
||||||
|
msgid "_24 hour format"
|
||||||
|
msgstr "Formato _24 horas"
|
||||||
|
|
||||||
#. **** Applications ****
|
#. **** Applications ****
|
||||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:852
|
#: ../js/ui/appDisplay.js:388 ../js/ui/dash.js:777
|
||||||
msgid "APPLICATIONS"
|
msgid "APPLICATIONS"
|
||||||
msgstr "APLICACIONES"
|
msgstr "APLICACIONES"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:276
|
#: ../js/ui/appDisplay.js:420
|
||||||
msgid "PREFERENCES"
|
msgid "PREFERENCES"
|
||||||
msgstr "PREFERENCIAS"
|
msgstr "PREFERENCIAS"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:707 ../js/ui/appIcon.js:425
|
#: ../js/ui/appDisplay.js:725
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Ventana nueva"
|
msgstr "Ventana nueva"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:711 ../js/ui/appIcon.js:429
|
#: ../js/ui/appDisplay.js:729
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Quitar de los favoritos"
|
msgstr "Quitar de los favoritos"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:712 ../js/ui/appIcon.js:430
|
#: ../js/ui/appDisplay.js:730
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Añadir a los favoritos"
|
msgstr "Añadir a los favoritos"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:1064
|
#: ../js/ui/appDisplay.js:1037
|
||||||
msgid "Drag here to add favorites"
|
msgid "Drag here to add favorites"
|
||||||
msgstr "Arrastrar aquí para añadir a los favoritos"
|
msgstr "Arrastrar aquí para añadir a los favoritos"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:240
|
#: ../js/ui/appFavorites.js:88
|
||||||
msgid "Find..."
|
#, c-format
|
||||||
msgstr "Buscar…"
|
msgid "%s has been added to your favorites."
|
||||||
|
msgstr "Se ha añadido %s a sus favoritos."
|
||||||
|
|
||||||
#: ../js/ui/dash.js:437
|
#: ../js/ui/appFavorites.js:106
|
||||||
#| msgid "Search"
|
#, c-format
|
||||||
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "Se ha quitado %s de sus favoritos."
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:146
|
||||||
|
msgid "Find"
|
||||||
|
msgstr "Buscar"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:475
|
||||||
msgid "Searching..."
|
msgid "Searching..."
|
||||||
msgstr "Buscando…"
|
msgstr "Buscando…"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:489
|
||||||
|
msgid "No matching results."
|
||||||
|
msgstr "No se encontró ningún resultado coincidente."
|
||||||
|
|
||||||
#. **** Places ****
|
#. **** Places ****
|
||||||
#. Translators: This is in the sense of locations for documents,
|
#. Translators: This is in the sense of locations for documents,
|
||||||
#. network locations, etc.
|
#. network locations, etc.
|
||||||
#: ../js/ui/dash.js:872 ../js/ui/placeDisplay.js:471
|
#: ../js/ui/dash.js:796 ../js/ui/placeDisplay.js:552
|
||||||
msgid "PLACES"
|
msgid "PLACES & DEVICES"
|
||||||
msgstr "LUGARES"
|
msgstr "LUGARES Y DISPOSITIVOS"
|
||||||
|
|
||||||
#. **** Documents ****
|
#. **** Documents ****
|
||||||
#: ../js/ui/dash.js:879
|
#: ../js/ui/dash.js:803 ../js/ui/docDisplay.js:497
|
||||||
msgid "RECENT DOCUMENTS"
|
msgid "RECENT ITEMS"
|
||||||
msgstr "DOCUMENTOS RECIENTES"
|
msgstr "ELEMENTOS RECIENTES"
|
||||||
|
|
||||||
#. Button on the left side of the panel.
|
#: ../js/ui/lookingGlass.js:471
|
||||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
msgid "No extensions installed"
|
||||||
#: ../js/ui/panel.js:227
|
msgstr "No hay extensiones instaladas"
|
||||||
msgid "Activities"
|
|
||||||
msgstr "Actividades"
|
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#: ../js/ui/lookingGlass.js:508
|
||||||
#: ../js/ui/panel.js:440
|
msgid "Enabled"
|
||||||
|
msgstr "Activado"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:510
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "Desactivado"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:512
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "Error"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:514
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr "Caducado"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:539
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr "Ver fuente"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:545
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr "Página web"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:165
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Deshacer"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:519
|
||||||
|
msgid "Preferences"
|
||||||
|
msgstr "Preferencias"
|
||||||
|
|
||||||
|
#. Translators: This is the time format with date used
|
||||||
|
#. in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:605
|
||||||
|
msgid "%a %b %e, %R:%S"
|
||||||
|
msgstr "%a %e de %b, %R:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:606
|
||||||
|
msgid "%a %b %e, %R"
|
||||||
|
msgstr "%a %e de %b, %R"
|
||||||
|
|
||||||
|
#. Translators: This is the time format without date used
|
||||||
|
#. in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:610
|
||||||
|
msgid "%a %R:%S"
|
||||||
|
msgstr "%a %R:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:611
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%a %R"
|
||||||
|
|
||||||
|
#. Translators: This is a time format with date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:618
|
||||||
|
msgid "%a %b %e, %l:%M:%S %p"
|
||||||
|
msgstr "%a %e de %b, %H:%M:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:619
|
||||||
|
msgid "%a %b %e, %l:%M %p"
|
||||||
|
msgstr "%a %e de %b, %H:%M"
|
||||||
|
|
||||||
|
#. Translators: This is a time format without date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:623
|
||||||
|
msgid "%a %l:%M:%S %p"
|
||||||
|
msgstr "%a %H:%M:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:624
|
||||||
msgid "%a %l:%M %p"
|
msgid "%a %l:%M %p"
|
||||||
msgstr "%a %H:%M"
|
msgstr "%a %H:%M"
|
||||||
|
|
||||||
#: ../js/ui/placeDisplay.js:99
|
#. Button on the left side of the panel.
|
||||||
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
|
#: ../js/ui/panel.js:762
|
||||||
|
msgid "Activities"
|
||||||
|
msgstr "Actividades"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:109
|
||||||
|
#, c-format
|
||||||
|
msgid "Failed to unmount '%s'"
|
||||||
|
msgstr "Falló al desmontar «%s»"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:112
|
||||||
|
msgid "Retry"
|
||||||
|
msgstr "Reintentar"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:157
|
||||||
msgid "Connect to..."
|
msgid "Connect to..."
|
||||||
msgstr "Conectar a…"
|
msgstr "Conectar a…"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:96
|
#: ../js/ui/runDialog.js:234
|
||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Introduzca un comando:"
|
msgstr "Introduzca un comando:"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:173
|
#: ../js/ui/runDialog.js:379
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr "Falló la ejecución de «%s»:"
|
msgstr "Falló la ejecución de «%s»:"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#: ../js/ui/statusMenu.js:91
|
||||||
#: ../js/ui/widget.js:163
|
msgid "Available"
|
||||||
msgid "%H:%M"
|
msgstr "Disponible"
|
||||||
msgstr "%H:%M"
|
|
||||||
|
|
||||||
#: ../js/ui/widget.js:317
|
#: ../js/ui/statusMenu.js:95
|
||||||
msgid "Applications"
|
msgid "Busy"
|
||||||
msgstr "Aplicaciones"
|
msgstr "Ocupado"
|
||||||
|
|
||||||
#: ../js/ui/widget.js:339
|
#: ../js/ui/statusMenu.js:99
|
||||||
msgid "Recent Documents"
|
msgid "Invisible"
|
||||||
msgstr "Documentos recientes"
|
msgstr "Invisible"
|
||||||
|
|
||||||
#: ../src/shell-global.c:826
|
#: ../js/ui/statusMenu.js:106
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "Información de la cuenta…"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:110
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "Preferencias del sistema…"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:117
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "Bloquear la pantalla"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:121
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "Cambiar de usuario"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:126
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "Salir…"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:130
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "Apagar…"
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:47
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has finished starting"
|
||||||
|
msgstr "%s finalizó su lanzamiento"
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:49
|
||||||
|
#, c-format
|
||||||
|
msgid "'%s' is ready"
|
||||||
|
msgstr "«%s» está preparado"
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:237
|
||||||
|
msgid ""
|
||||||
|
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||||
|
msgstr ""
|
||||||
|
"No se puede añadir un área de trabajo nueva porque se ha llegado al límite "
|
||||||
|
"de áreas de trabajo."
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:254
|
||||||
|
msgid "Can't remove the first workspace."
|
||||||
|
msgstr "No se puede quitar el primer área de trabajo."
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:1039
|
||||||
msgid "Less than a minute ago"
|
msgid "Less than a minute ago"
|
||||||
msgstr "Hace menos de un minuto"
|
msgstr "Hace menos de un minuto"
|
||||||
|
|
||||||
#: ../src/shell-global.c:829
|
#: ../src/shell-global.c:1043
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d minute ago"
|
msgid "%d minute ago"
|
||||||
msgid_plural "%d minutes ago"
|
msgid_plural "%d minutes ago"
|
||||||
msgstr[0] "Hace %d minuto"
|
msgstr[0] "Hace %d minuto"
|
||||||
msgstr[1] "Hace %d minutos"
|
msgstr[1] "Hace %d minutos"
|
||||||
|
|
||||||
#: ../src/shell-global.c:832
|
#: ../src/shell-global.c:1048
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour ago"
|
msgid "%d hour ago"
|
||||||
msgid_plural "%d hours ago"
|
msgid_plural "%d hours ago"
|
||||||
msgstr[0] "Hace %d hora"
|
msgstr[0] "Hace %d hora"
|
||||||
msgstr[1] "Hace %d horas"
|
msgstr[1] "Hace %d horas"
|
||||||
|
|
||||||
#: ../src/shell-global.c:835
|
#: ../src/shell-global.c:1053
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d day ago"
|
msgid "%d day ago"
|
||||||
msgid_plural "%d days ago"
|
msgid_plural "%d days ago"
|
||||||
msgstr[0] "Hace %d día"
|
msgstr[0] "Hace %d día"
|
||||||
msgstr[1] "Hace %d días"
|
msgstr[1] "Hace %d días"
|
||||||
|
|
||||||
#: ../src/shell-global.c:838
|
#: ../src/shell-global.c:1058
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d week ago"
|
msgid "%d week ago"
|
||||||
msgid_plural "%d weeks ago"
|
msgid_plural "%d weeks ago"
|
||||||
@ -164,6 +509,25 @@ msgstr "Buscar"
|
|||||||
msgid "%1$s: %2$s"
|
msgid "%1$s: %2$s"
|
||||||
msgstr "%1$s: %2$s"
|
msgstr "%1$s: %2$s"
|
||||||
|
|
||||||
|
#~| msgid "Quit"
|
||||||
|
#~ msgid "Quit %s"
|
||||||
|
#~ msgstr "Salir de %s"
|
||||||
|
|
||||||
|
#~ msgid "Sidebar"
|
||||||
|
#~ msgstr "Barra lateral"
|
||||||
|
|
||||||
|
#~ msgid "%H:%M"
|
||||||
|
#~ msgstr "%H:%M"
|
||||||
|
|
||||||
|
#~ msgid "Applications"
|
||||||
|
#~ msgstr "Aplicaciones"
|
||||||
|
|
||||||
|
#~ msgid "Recent Documents"
|
||||||
|
#~ msgstr "Documentos recientes"
|
||||||
|
|
||||||
|
#~ msgid "PLACES"
|
||||||
|
#~ msgstr "LUGARES"
|
||||||
|
|
||||||
#~ msgid "Frequent"
|
#~ msgid "Frequent"
|
||||||
#~ msgstr "Frecuentes"
|
#~ msgstr "Frecuentes"
|
||||||
|
|
||||||
@ -190,27 +554,6 @@ msgstr "%1$s: %2$s"
|
|||||||
#~ msgid "Can't logout: %s"
|
#~ msgid "Can't logout: %s"
|
||||||
#~ msgstr "No se puede salir de la sesión: %s"
|
#~ msgstr "No se puede salir de la sesión: %s"
|
||||||
|
|
||||||
#~ msgid "Account Information..."
|
|
||||||
#~ msgstr "Información de la cuenta…"
|
|
||||||
|
|
||||||
#~ msgid "Sidebar"
|
|
||||||
#~ msgstr "Barra lateral"
|
|
||||||
|
|
||||||
#~ msgid "System Preferences..."
|
|
||||||
#~ msgstr "Preferencias del sistema…"
|
|
||||||
|
|
||||||
#~ msgid "Lock Screen"
|
|
||||||
#~ msgstr "Bloquear la pantalla"
|
|
||||||
|
|
||||||
#~ msgid "Switch User"
|
|
||||||
#~ msgstr "Cambiar de usuario"
|
|
||||||
|
|
||||||
#~ msgid "Log Out..."
|
|
||||||
#~ msgstr "Salir…"
|
|
||||||
|
|
||||||
#~ msgid "Shut Down..."
|
|
||||||
#~ msgstr "Apagar…"
|
|
||||||
|
|
||||||
#~ msgid "Browse"
|
#~ msgid "Browse"
|
||||||
#~ msgstr "Examine"
|
#~ msgstr "Examine"
|
||||||
|
|
||||||
|
257
po/fi.po
@ -1,14 +1,14 @@
|
|||||||
# gnome-shell Finnish translation
|
# gnome-shell Finnish translation
|
||||||
# Copyright (C) 2009 Timo Jyrinki
|
# Copyright (C) 2009-2010 Timo Jyrinki
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
# Timo Jyrinki <timo.jyrinki@iki.fi>, 2009.
|
# Timo Jyrinki <timo.jyrinki@iki.fi>, 2009-2010.
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell\n"
|
"Project-Id-Version: gnome-shell\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2009-11-04 11:16+0200\n"
|
"POT-Creation-Date: 2010-03-01 20:24+0200\n"
|
||||||
"PO-Revision-Date: 2009-11-04 11:16+0200\n"
|
"PO-Revision-Date: 2010-03-01 20:27+0200\n"
|
||||||
"Last-Translator: Timo Jyrinki <timo.jyrinki@iki.fi>\n"
|
"Last-Translator: Timo Jyrinki <timo.jyrinki@iki.fi>\n"
|
||||||
"Language-Team: Finnish <gnome-fi-laatu@lists.sourceforge.net>\n"
|
"Language-Team: Finnish <gnome-fi-laatu@lists.sourceforge.net>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -24,87 +24,165 @@ msgstr ""
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "Ikkunanhallinta ja sovelluksien käynnistäminen"
|
msgstr "Ikkunanhallinta ja sovelluksien käynnistäminen"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:332
|
#. **** Applications ****
|
||||||
msgid "Frequent"
|
#: ../js/ui/appDisplay.js:180 ../js/ui/dash.js:881
|
||||||
msgstr "Usein käytetyt"
|
msgid "APPLICATIONS"
|
||||||
|
msgstr "SOVELLUKSET"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:867
|
#: ../js/ui/appDisplay.js:204
|
||||||
msgid "Drag here to add favorites"
|
msgid "PREFERENCES"
|
||||||
msgstr "Raahaa tähän lisätäksesi suosikkeihin"
|
msgstr "ASETUKSET"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:426
|
#: ../js/ui/appDisplay.js:582
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Uusi ikkuna"
|
msgstr "Uusi ikkuna"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:430
|
#: ../js/ui/appDisplay.js:586
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Poista suosikeista"
|
msgstr "Poista suosikeista"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:431
|
#: ../js/ui/appDisplay.js:587
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Lisää suosikkeihin"
|
msgstr "Lisää suosikkeihin"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:283
|
#: ../js/ui/appDisplay.js:939
|
||||||
|
msgid "Drag here to add favorites"
|
||||||
|
msgstr "Raahaa tähän lisätäksesi suosikkeihin"
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:89
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been added to your favorites."
|
||||||
|
msgstr "%s on lisätty suosikkeihin."
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:107
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "%s on poistettu suosikeista."
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:235
|
||||||
msgid "Find..."
|
msgid "Find..."
|
||||||
msgstr "Etsi..."
|
msgstr "Etsi..."
|
||||||
|
|
||||||
#: ../js/ui/dash.js:400
|
#: ../js/ui/dash.js:505
|
||||||
msgid "More"
|
msgid "Searching..."
|
||||||
msgstr "Lisää"
|
msgstr "Haetaan..."
|
||||||
|
|
||||||
#: ../js/ui/dash.js:543
|
#: ../js/ui/dash.js:519
|
||||||
msgid "(see all)"
|
msgid "No matching results."
|
||||||
msgstr "(näytä kaikki)"
|
msgstr "Ei tuloksia."
|
||||||
|
|
||||||
#. **** Applications ****
|
|
||||||
#: ../js/ui/dash.js:725 ../js/ui/dash.js:787
|
|
||||||
msgid "APPLICATIONS"
|
|
||||||
msgstr "SOVELLUKSET"
|
|
||||||
|
|
||||||
#. **** Places ****
|
#. **** Places ****
|
||||||
#. Translators: This is in the sense of locations for documents,
|
#. Translators: This is in the sense of locations for documents,
|
||||||
#. network locations, etc.
|
#. network locations, etc.
|
||||||
#: ../js/ui/dash.js:745
|
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||||
msgid "PLACES"
|
msgid "PLACES & DEVICES"
|
||||||
msgstr "SIJAINNIT"
|
msgstr "SIJAINNIT JA LAITTEET"
|
||||||
|
|
||||||
#. **** Documents ****
|
#. **** Documents ****
|
||||||
#: ../js/ui/dash.js:752 ../js/ui/dash.js:797
|
#: ../js/ui/dash.js:907 ../js/ui/docDisplay.js:488
|
||||||
msgid "RECENT DOCUMENTS"
|
msgid "RECENT ITEMS"
|
||||||
msgstr "VIIMEISIMMÄT ASIAKIRJAT"
|
msgstr "VIIMEISIMMÄT"
|
||||||
|
|
||||||
#. **** Search Results ****
|
#: ../js/ui/lookingGlass.js:363
|
||||||
#: ../js/ui/dash.js:777 ../js/ui/dash.js:961
|
msgid "No extensions installed"
|
||||||
msgid "SEARCH RESULTS"
|
msgstr "Laajennuksia ei asennettu"
|
||||||
msgstr "HAKUTULOKSET"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:792
|
#: ../js/ui/lookingGlass.js:400
|
||||||
msgid "PREFERENCES"
|
msgid "Enabled"
|
||||||
msgstr "ASETUKSET"
|
msgstr "Käytössä"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:402
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "Ei käytössä"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:404
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "Virhe"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:406
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr "Ei ajan tasalla"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:431
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr "Näytä lähde"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:437
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr "WWW-sivu"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:92
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Kumoa"
|
||||||
|
|
||||||
#. Button on the left side of the panel.
|
#. Button on the left side of the panel.
|
||||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:274
|
#: ../js/ui/panel.js:399
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Toiminnot"
|
msgstr "Toiminnot"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#. Translators: This is the time format used in 24-hour mode.
|
||||||
#: ../js/ui/panel.js:491
|
#: ../js/ui/panel.js:623
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%a %R"
|
||||||
|
|
||||||
|
#. Translators: This is a time format used for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:626
|
||||||
msgid "%a %l:%M %p"
|
msgid "%a %l:%M %p"
|
||||||
msgstr "%a %I.%M"
|
msgstr "%a %I.%M"
|
||||||
|
|
||||||
#: ../js/ui/places.js:178
|
#: ../js/ui/placeDisplay.js:144
|
||||||
msgid "Connect to..."
|
msgid "Connect to..."
|
||||||
msgstr "Yhdistä..."
|
msgstr "Yhdistä..."
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:96
|
#: ../js/ui/runDialog.js:220
|
||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Syötä komento:"
|
msgstr "Syötä komento:"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:173
|
#: ../js/ui/runDialog.js:328
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr ""
|
msgstr "”%s” suorittaminen epäonnistui:"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:107
|
||||||
|
msgid "Available"
|
||||||
|
msgstr "Tavoitettavissa"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:112
|
||||||
|
msgid "Busy"
|
||||||
|
msgstr "Kiireinen"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:117
|
||||||
|
msgid "Invisible"
|
||||||
|
msgstr "Näkymätön"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:126
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "Käyttäjätilin tiedot..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:132
|
||||||
|
msgid "Sidebar"
|
||||||
|
msgstr "Sivupalkki"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:142
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "Järjestelmän asetukset"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:151
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "Lukitse näyttö"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:156
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "Vaihda käyttäjää"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:162
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "Kirjaudu ulos..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:167
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "Sammuta..."
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#. Translators: This is a time format.
|
||||||
#: ../js/ui/widget.js:163
|
#: ../js/ui/widget.js:163
|
||||||
@ -119,99 +197,49 @@ msgstr "Sovellukset"
|
|||||||
msgid "Recent Documents"
|
msgid "Recent Documents"
|
||||||
msgstr "Viimeisimmät asiakirjat"
|
msgstr "Viimeisimmät asiakirjat"
|
||||||
|
|
||||||
#: ../src/shell-global.c:821
|
#: ../src/shell-global.c:967
|
||||||
msgid "Less than a minute ago"
|
msgid "Less than a minute ago"
|
||||||
msgstr "Alle minuutti sitten"
|
msgstr "Alle minuutti sitten"
|
||||||
|
|
||||||
#: ../src/shell-global.c:824
|
#: ../src/shell-global.c:971
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d minute ago"
|
msgid "%d minute ago"
|
||||||
msgid_plural "%d minutes ago"
|
msgid_plural "%d minutes ago"
|
||||||
msgstr[0] "%d minuutti sitten"
|
msgstr[0] "%d minuutti sitten"
|
||||||
msgstr[1] "%d minuuttia sitten"
|
msgstr[1] "%d minuuttia sitten"
|
||||||
|
|
||||||
#: ../src/shell-global.c:827
|
#: ../src/shell-global.c:976
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour ago"
|
msgid "%d hour ago"
|
||||||
msgid_plural "%d hours ago"
|
msgid_plural "%d hours ago"
|
||||||
msgstr[0] "%d tunti sitten"
|
msgstr[0] "%d tunti sitten"
|
||||||
msgstr[1] "%d tuntia sitten"
|
msgstr[1] "%d tuntia sitten"
|
||||||
|
|
||||||
#: ../src/shell-global.c:830
|
#: ../src/shell-global.c:981
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d day ago"
|
msgid "%d day ago"
|
||||||
msgid_plural "%d days ago"
|
msgid_plural "%d days ago"
|
||||||
msgstr[0] "%d päivä sitten"
|
msgstr[0] "%d päivä sitten"
|
||||||
msgstr[1] "%d päivää sitten"
|
msgstr[1] "%d päivää sitten"
|
||||||
|
|
||||||
#: ../src/shell-global.c:833
|
#: ../src/shell-global.c:986
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d week ago"
|
msgid "%d week ago"
|
||||||
msgid_plural "%d weeks ago"
|
msgid_plural "%d weeks ago"
|
||||||
msgstr[0] "%d viikko sitten"
|
msgstr[0] "%d viikko sitten"
|
||||||
msgstr[1] "%d viikkoa sitten"
|
msgstr[1] "%d viikkoa sitten"
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:156
|
#: ../src/shell-uri-util.c:89
|
||||||
msgid "Unknown"
|
|
||||||
msgstr "Tuntematon"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:212
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't lock screen: %s"
|
|
||||||
msgstr "Näyttöä ei voi lukita: %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:227
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:351
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't logout: %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:492
|
|
||||||
msgid "Account Information..."
|
|
||||||
msgstr "Käyttäjätilin tiedot..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:502
|
|
||||||
msgid "Sidebar"
|
|
||||||
msgstr "Sivupalkki"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:510
|
|
||||||
msgid "System Preferences..."
|
|
||||||
msgstr "Järjestelmän asetukset"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:525
|
|
||||||
msgid "Lock Screen"
|
|
||||||
msgstr "Lukitse näyttö"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:535
|
|
||||||
msgid "Switch User"
|
|
||||||
msgstr "Vaihda käyttäjää"
|
|
||||||
|
|
||||||
#. Only show switch user if there are other users
|
|
||||||
#. Log Out
|
|
||||||
#: ../src/shell-status-menu.c:546
|
|
||||||
msgid "Log Out..."
|
|
||||||
msgstr "Kirjaudu ulos..."
|
|
||||||
|
|
||||||
#. Shut down
|
|
||||||
#: ../src/shell-status-menu.c:557
|
|
||||||
msgid "Shut Down..."
|
|
||||||
msgstr "Sammuta..."
|
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:87
|
|
||||||
msgid "Home Folder"
|
msgid "Home Folder"
|
||||||
msgstr "Kotikansio"
|
msgstr "Kotikansio"
|
||||||
|
|
||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-uri-util.c:102
|
#: ../src/shell-uri-util.c:104
|
||||||
msgid "File System"
|
msgid "File System"
|
||||||
msgstr "Tiedostojärjestelmä"
|
msgstr "Tiedostojärjestelmä"
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:248
|
#: ../src/shell-uri-util.c:250
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Haku"
|
msgstr "Haku"
|
||||||
|
|
||||||
@ -220,7 +248,28 @@ msgstr "Haku"
|
|||||||
#. * example, "Trash: some-directory". It means that the
|
#. * example, "Trash: some-directory". It means that the
|
||||||
#. * directory called "some-directory" is in the trash.
|
#. * directory called "some-directory" is in the trash.
|
||||||
#.
|
#.
|
||||||
#: ../src/shell-uri-util.c:298
|
#: ../src/shell-uri-util.c:300
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s: %2$s"
|
msgid "%1$s: %2$s"
|
||||||
msgstr "%1$s: %2$s"
|
msgstr "%1$s: %2$s"
|
||||||
|
|
||||||
|
#~ msgid "Frequent"
|
||||||
|
#~ msgstr "Usein käytetyt"
|
||||||
|
|
||||||
|
#~ msgid "More"
|
||||||
|
#~ msgstr "Lisää"
|
||||||
|
|
||||||
|
#~ msgid "(see all)"
|
||||||
|
#~ msgstr "(näytä kaikki)"
|
||||||
|
|
||||||
|
#~ msgid "PLACES"
|
||||||
|
#~ msgstr "SIJAINNIT"
|
||||||
|
|
||||||
|
#~ msgid "SEARCH RESULTS"
|
||||||
|
#~ msgstr "HAKUTULOKSET"
|
||||||
|
|
||||||
|
#~ msgid "Unknown"
|
||||||
|
#~ msgstr "Tuntematon"
|
||||||
|
|
||||||
|
#~ msgid "Can't lock screen: %s"
|
||||||
|
#~ msgstr "Näyttöä ei voi lukita: %s"
|
||||||
|
345
po/fr.po
@ -1,17 +1,19 @@
|
|||||||
# French translations for gnome-shell package.
|
# French translations for gnome-shell package.
|
||||||
# Copyright (C) 2009 THE gnome-shell'S COPYRIGHT HOLDER
|
# Copyright (C) 2009-2010 Listed translators
|
||||||
# This file is distributed under the same license as the gnome-shell package.
|
# This file is distributed under the same license as the gnome-shell package.
|
||||||
#
|
#
|
||||||
# Mathieu Bridon <bochecha@fedoraproject.org>, 2009.
|
# Mathieu Bridon <bochecha@fedoraproject.org>, 2009
|
||||||
|
# Pablo Martin-Gomez <pablo.martin-gomez@laposte.net>, 2010
|
||||||
|
# Claude Paroz <claude@2xlibre.net>, 2010
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell master fr\n"
|
"Project-Id-Version: gnome-shell master fr\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&component=general\n"
|
"shell&component=general\n"
|
||||||
"POT-Creation-Date: 2009-11-13 17:44+0000\n"
|
"POT-Creation-Date: 2010-05-15 22:41+0000\n"
|
||||||
"PO-Revision-Date: 2009-12-05 16:43+0100\n"
|
"PO-Revision-Date: 2010-03-09 22:55+0100\n"
|
||||||
"Last-Translator: Pablo Martin-Gomez <pablo.martin-gomez@laposte.net>\n"
|
"Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
|
||||||
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
|
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@ -26,183 +28,305 @@ msgstr "GNOME Shell"
|
|||||||
msgid "Window management and application launching"
|
msgid "Window management and application launching"
|
||||||
msgstr "Gestion des fenêtres et lancement des applications"
|
msgstr "Gestion des fenêtres et lancement des applications"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:696
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||||
msgid "Drag here to add favorites"
|
msgid "Clock"
|
||||||
msgstr "Glisser ici pour ajouter aux favoris"
|
msgstr "Horloge"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:425
|
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||||
|
msgid "Customize the panel clock"
|
||||||
|
msgstr "Personnaliser l'horloge du tableau de bord"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:1
|
||||||
|
msgid "Clock Format"
|
||||||
|
msgstr "Format de l'horloge"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:2
|
||||||
|
msgid "Panel Display"
|
||||||
|
msgstr "Affichage dans le tableau de bord"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:3
|
||||||
|
msgid "Clock Preferences"
|
||||||
|
msgstr "Préférences de l'horloge"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:4
|
||||||
|
msgid "Show seco_nds"
|
||||||
|
msgstr "Afficher les _secondes"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:5
|
||||||
|
msgid "Show the _date"
|
||||||
|
msgstr "Afficher la _date"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:6
|
||||||
|
msgid "_12 hour format"
|
||||||
|
msgstr "Format _12 heures"
|
||||||
|
|
||||||
|
#: ../data/clock-preferences.ui.h:7
|
||||||
|
msgid "_24 hour format"
|
||||||
|
msgstr "Format _24 heures"
|
||||||
|
|
||||||
|
#. **** Applications ****
|
||||||
|
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||||
|
msgid "APPLICATIONS"
|
||||||
|
msgstr "APPLICATIONS"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:338
|
||||||
|
msgid "PREFERENCES"
|
||||||
|
msgstr "PRÉFÉRENCES"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:705
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Nouvelle fenêtre"
|
msgstr "Nouvelle fenêtre"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:429
|
#: ../js/ui/appDisplay.js:709
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Enlever des favoris"
|
msgstr "Enlever des favoris"
|
||||||
|
|
||||||
#: ../js/ui/appIcon.js:430
|
#: ../js/ui/appDisplay.js:710
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Ajouter aux favoris"
|
msgstr "Ajouter aux favoris"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:237
|
#: ../js/ui/appDisplay.js:1037
|
||||||
msgid "Find..."
|
msgid "Drag here to add favorites"
|
||||||
msgstr "Rechercher..."
|
msgstr "Glisser ici pour ajouter aux favoris"
|
||||||
|
|
||||||
#. **** Applications ****
|
#: ../js/ui/appFavorites.js:89
|
||||||
#: ../js/ui/dash.js:656 ../js/ui/dash.js:718
|
#, c-format
|
||||||
msgid "APPLICATIONS"
|
msgid "%s has been added to your favorites."
|
||||||
msgstr "APPLICATIONS"
|
msgstr "%s a été ajouté à vos favoris."
|
||||||
|
|
||||||
|
#: ../js/ui/appFavorites.js:107
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has been removed from your favorites."
|
||||||
|
msgstr "%s a été supprimé de vos favoris."
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:189
|
||||||
|
msgid "Find"
|
||||||
|
msgstr "Rechercher"
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:505
|
||||||
|
msgid "Searching..."
|
||||||
|
msgstr "Recherche en cours..."
|
||||||
|
|
||||||
|
#: ../js/ui/dash.js:519
|
||||||
|
msgid "No matching results."
|
||||||
|
msgstr "Aucun résultat correspondant."
|
||||||
|
|
||||||
#. **** Places ****
|
#. **** Places ****
|
||||||
#. Translators: This is in the sense of locations for documents,
|
#. Translators: This is in the sense of locations for documents,
|
||||||
#. network locations, etc.
|
#. network locations, etc.
|
||||||
#: ../js/ui/dash.js:676 ../js/ui/dash.js:733
|
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||||
msgid "PLACES"
|
msgid "PLACES & DEVICES"
|
||||||
msgstr "RACCOURCIS"
|
msgstr "RACCOURCIS et PÉRIPHÉRIQUES"
|
||||||
|
|
||||||
#. **** Documents ****
|
#. **** Documents ****
|
||||||
#: ../js/ui/dash.js:683 ../js/ui/dash.js:728
|
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||||
msgid "RECENT DOCUMENTS"
|
msgid "RECENT ITEMS"
|
||||||
msgstr "DOCUMENTS RÉCENTS"
|
msgstr "ÉLÉMENTS RÉCENTS"
|
||||||
|
|
||||||
#. **** Search Results ****
|
#: ../js/ui/lookingGlass.js:354
|
||||||
#: ../js/ui/dash.js:708 ../js/ui/dash.js:898
|
msgid "No extensions installed"
|
||||||
msgid "SEARCH RESULTS"
|
msgstr "Aucune extension installée"
|
||||||
msgstr "RÉSULTATS DE LA RECHERCHE"
|
|
||||||
|
|
||||||
#: ../js/ui/dash.js:723
|
#: ../js/ui/lookingGlass.js:391
|
||||||
msgid "PREFERENCES"
|
msgid "Enabled"
|
||||||
msgstr "PRÉFÉRENCES"
|
msgstr "Activé"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:393
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "Désactivé"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:395
|
||||||
|
msgid "Error"
|
||||||
|
msgstr "Erreur"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:397
|
||||||
|
msgid "Out of date"
|
||||||
|
msgstr "Périmé"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:422
|
||||||
|
msgid "View Source"
|
||||||
|
msgstr "Afficher la source"
|
||||||
|
|
||||||
|
#: ../js/ui/lookingGlass.js:428
|
||||||
|
msgid "Web Page"
|
||||||
|
msgstr "Page Web"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:161
|
||||||
|
msgid "Undo"
|
||||||
|
msgstr "Annuler"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:535
|
||||||
|
msgid "Quit"
|
||||||
|
msgstr "Quitter"
|
||||||
|
|
||||||
#. Button on the left side of the panel.
|
#. Button on the left side of the panel.
|
||||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:274
|
#: ../js/ui/panel.js:740
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Activités"
|
msgstr "Activités"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#. Translators: This is the time format with date used
|
||||||
#: ../js/ui/panel.js:491
|
#. in 24-hour mode.
|
||||||
msgid "%a %l:%M %p"
|
#: ../js/ui/panel.js:955
|
||||||
msgstr "%a %H:%M"
|
msgid "%a %b %e, %R:%S"
|
||||||
|
msgstr "%a %e %b, %R:%S"
|
||||||
|
|
||||||
#: ../js/ui/placeDisplay.js:84
|
#: ../js/ui/panel.js:956
|
||||||
|
msgid "%a %b %e, %R"
|
||||||
|
msgstr "%a %e %b, %R"
|
||||||
|
|
||||||
|
#. Translators: This is the time format without date used
|
||||||
|
#. in 24-hour mode.
|
||||||
|
#: ../js/ui/panel.js:960
|
||||||
|
msgid "%a %R:%S"
|
||||||
|
msgstr "%a %R:%S"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:961
|
||||||
|
msgid "%a %R"
|
||||||
|
msgstr "%a %R"
|
||||||
|
|
||||||
|
#. Translators: This is a time format with date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:968
|
||||||
|
msgid "%a %b %e, %l:%M:%S %p"
|
||||||
|
msgstr "%a %e %b, %l:%M:%S %p"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:969
|
||||||
|
msgid "%a %b %e, %l:%M %p"
|
||||||
|
msgstr "%a %e %b, %l:%M %p"
|
||||||
|
|
||||||
|
#. Translators: This is a time format without date used
|
||||||
|
#. for AM/PM.
|
||||||
|
#: ../js/ui/panel.js:973
|
||||||
|
msgid "%a %l:%M:%S %p"
|
||||||
|
msgstr "%a %l:%M:%S %p"
|
||||||
|
|
||||||
|
#: ../js/ui/panel.js:974
|
||||||
|
msgid "%a %l:%M %p"
|
||||||
|
msgstr "%a %l:%M %p"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:108
|
||||||
|
#, c-format
|
||||||
|
msgid "Failed to unmount '%s'"
|
||||||
|
msgstr "Impossible de monter « %s »"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:111
|
||||||
|
msgid "Retry"
|
||||||
|
msgstr "Réessayer"
|
||||||
|
|
||||||
|
#: ../js/ui/placeDisplay.js:156
|
||||||
msgid "Connect to..."
|
msgid "Connect to..."
|
||||||
msgstr "Connexion à..."
|
msgstr "Connexion à..."
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:96
|
#: ../js/ui/runDialog.js:231
|
||||||
msgid "Please enter a command:"
|
msgid "Please enter a command:"
|
||||||
msgstr "Veuillez saisir une commande :"
|
msgstr "Veuillez saisir une commande :"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:173
|
#: ../js/ui/runDialog.js:375
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr "Exécution de « %s » impossible :"
|
msgstr "Exécution de « %s » impossible :"
|
||||||
|
|
||||||
#. Translators: This is a time format.
|
#: ../js/ui/statusMenu.js:90
|
||||||
#: ../js/ui/widget.js:163
|
msgid "Available"
|
||||||
msgid "%H:%M"
|
msgstr "Disponible"
|
||||||
msgstr "%H:%M"
|
|
||||||
|
|
||||||
#: ../js/ui/widget.js:317
|
#: ../js/ui/statusMenu.js:94
|
||||||
msgid "Applications"
|
msgid "Busy"
|
||||||
msgstr "Applications"
|
msgstr "Occupé"
|
||||||
|
|
||||||
#: ../js/ui/widget.js:339
|
#: ../js/ui/statusMenu.js:98
|
||||||
msgid "Recent Documents"
|
msgid "Invisible"
|
||||||
msgstr "Documents récents"
|
msgstr "Invisible"
|
||||||
|
|
||||||
#: ../src/shell-global.c:821
|
#: ../js/ui/statusMenu.js:105
|
||||||
|
msgid "Account Information..."
|
||||||
|
msgstr "Informations personnelles..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:109
|
||||||
|
msgid "System Preferences..."
|
||||||
|
msgstr "Préférences du système..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:116
|
||||||
|
msgid "Lock Screen"
|
||||||
|
msgstr "Verrouiller l'écran"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:120
|
||||||
|
msgid "Switch User"
|
||||||
|
msgstr "Changer d'utilisateur"
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:125
|
||||||
|
msgid "Log Out..."
|
||||||
|
msgstr "Fermer la session..."
|
||||||
|
|
||||||
|
#: ../js/ui/statusMenu.js:129
|
||||||
|
msgid "Shut Down..."
|
||||||
|
msgstr "Éteindre..."
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:47
|
||||||
|
#, c-format
|
||||||
|
msgid "%s has finished starting"
|
||||||
|
msgstr "Lancement de %s terminé"
|
||||||
|
|
||||||
|
#: ../js/ui/windowAttentionHandler.js:49
|
||||||
|
#, c-format
|
||||||
|
msgid "'%s' is ready"
|
||||||
|
msgstr "« %s » est prêt"
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:239
|
||||||
|
msgid ""
|
||||||
|
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||||
|
msgstr ""
|
||||||
|
"Impossible d'ajouter un espace de travail car le nombre maximum d'espaces de "
|
||||||
|
"travail est atteint."
|
||||||
|
|
||||||
|
#: ../js/ui/workspacesView.js:256
|
||||||
|
msgid "Can't remove the first workspace."
|
||||||
|
msgstr "Impossible de supprimer le premier espace de travail."
|
||||||
|
|
||||||
|
#: ../src/shell-global.c:979
|
||||||
msgid "Less than a minute ago"
|
msgid "Less than a minute ago"
|
||||||
msgstr "Il y a moins d'une minute"
|
msgstr "Il y a moins d'une minute"
|
||||||
|
|
||||||
#: ../src/shell-global.c:824
|
#: ../src/shell-global.c:983
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d minute ago"
|
msgid "%d minute ago"
|
||||||
msgid_plural "%d minutes ago"
|
msgid_plural "%d minutes ago"
|
||||||
msgstr[0] "Il y a %d minute"
|
msgstr[0] "Il y a %d minute"
|
||||||
msgstr[1] "Il y a %d minutes"
|
msgstr[1] "Il y a %d minutes"
|
||||||
|
|
||||||
#: ../src/shell-global.c:827
|
#: ../src/shell-global.c:988
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour ago"
|
msgid "%d hour ago"
|
||||||
msgid_plural "%d hours ago"
|
msgid_plural "%d hours ago"
|
||||||
msgstr[0] "Il y a %d heure"
|
msgstr[0] "Il y a %d heure"
|
||||||
msgstr[1] "Il y a %d heures"
|
msgstr[1] "Il y a %d heures"
|
||||||
|
|
||||||
#: ../src/shell-global.c:830
|
#: ../src/shell-global.c:993
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d day ago"
|
msgid "%d day ago"
|
||||||
msgid_plural "%d days ago"
|
msgid_plural "%d days ago"
|
||||||
msgstr[0] "Il y a %d jour"
|
msgstr[0] "Il y a %d jour"
|
||||||
msgstr[1] "Il y a %d jours"
|
msgstr[1] "Il y a %d jours"
|
||||||
|
|
||||||
#: ../src/shell-global.c:833
|
#: ../src/shell-global.c:998
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d week ago"
|
msgid "%d week ago"
|
||||||
msgid_plural "%d weeks ago"
|
msgid_plural "%d weeks ago"
|
||||||
msgstr[0] "Il y a %d semaine"
|
msgstr[0] "Il y a %d semaine"
|
||||||
msgstr[1] "Il y a %d semaines"
|
msgstr[1] "Il y a %d semaines"
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:156
|
#: ../src/shell-uri-util.c:89
|
||||||
msgid "Unknown"
|
|
||||||
msgstr "Inconnu"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:212
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't lock screen: %s"
|
|
||||||
msgstr "Impossible de verrouiller l'écran : %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:227
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
|
||||||
msgstr ""
|
|
||||||
"Impossible de régler temporairement l'écran de veille sur un écran vide : %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:351
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't logout: %s"
|
|
||||||
msgstr "Impossible de fermer la session : %s"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:492
|
|
||||||
msgid "Account Information..."
|
|
||||||
msgstr "Informations personnelles..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:502
|
|
||||||
msgid "Sidebar"
|
|
||||||
msgstr "Barre latérale"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:510
|
|
||||||
msgid "System Preferences..."
|
|
||||||
msgstr "Préférences du système..."
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:525
|
|
||||||
msgid "Lock Screen"
|
|
||||||
msgstr "Verrouiller l'écran"
|
|
||||||
|
|
||||||
#: ../src/shell-status-menu.c:535
|
|
||||||
msgid "Switch User"
|
|
||||||
msgstr "Changer d'utilisateur"
|
|
||||||
|
|
||||||
#. Only show switch user if there are other users
|
|
||||||
#. Log Out
|
|
||||||
#: ../src/shell-status-menu.c:546
|
|
||||||
msgid "Log Out..."
|
|
||||||
msgstr "Fermer la session..."
|
|
||||||
|
|
||||||
#. Shut down
|
|
||||||
#: ../src/shell-status-menu.c:557
|
|
||||||
msgid "Shut Down..."
|
|
||||||
msgstr "Éteindre..."
|
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:87
|
|
||||||
msgid "Home Folder"
|
msgid "Home Folder"
|
||||||
msgstr "Dossier personnel"
|
msgstr "Dossier personnel"
|
||||||
|
|
||||||
#. Translators: this is the same string as the one found in
|
#. Translators: this is the same string as the one found in
|
||||||
#. * nautilus
|
#. * nautilus
|
||||||
#: ../src/shell-uri-util.c:102
|
#: ../src/shell-uri-util.c:104
|
||||||
msgid "File System"
|
msgid "File System"
|
||||||
msgstr "Système de fichiers"
|
msgstr "Système de fichiers"
|
||||||
|
|
||||||
#: ../src/shell-uri-util.c:248
|
#: ../src/shell-uri-util.c:250
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Recherche"
|
msgstr "Recherche"
|
||||||
|
|
||||||
@ -211,10 +335,7 @@ msgstr "Recherche"
|
|||||||
#. * example, "Trash: some-directory". It means that the
|
#. * example, "Trash: some-directory". It means that the
|
||||||
#. * directory called "some-directory" is in the trash.
|
#. * directory called "some-directory" is in the trash.
|
||||||
#.
|
#.
|
||||||
#: ../src/shell-uri-util.c:298
|
#: ../src/shell-uri-util.c:300
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%1$s: %2$s"
|
msgid "%1$s: %2$s"
|
||||||
msgstr "%1$s : %2$s"
|
msgstr "%1$s : %2$s"
|
||||||
|
|
||||||
#~ msgid "Browse"
|
|
||||||
#~ msgstr "Parcourir"
|
|
||||||
|