Compare commits
2022 Commits
Author | SHA1 | Date | |
---|---|---|---|
3fd70e37bd | |||
5580cfaf63 | |||
17c46c2452 | |||
0996174b3d | |||
d6b6f814d3 | |||
987099ea55 | |||
b356aa8e3b | |||
566bdb50c2 | |||
2b57603271 | |||
c3528f5b6b | |||
4c7cc94cdc | |||
5ff2285707 | |||
d714dfd82e | |||
b1064cbe50 | |||
8d3e5ea507 | |||
001b6afc7e | |||
55d6c5ea8f | |||
fa2ff8158f | |||
97e7ea0b5d | |||
65dec2b72a | |||
5fd3ca8d09 | |||
dc9a8d505d | |||
fc8d13f4bd | |||
d1aa7de5d0 | |||
e279ef1c7c | |||
b88657ab83 | |||
d20e646ed6 | |||
8678b87120 | |||
960571a589 | |||
d856338f86 | |||
2b6b2d93a9 | |||
363bd04166 | |||
9bc1a68fe4 | |||
2c2729f7be | |||
9011959356 | |||
c79b8bbe7e | |||
da59eebf8e | |||
7854024326 | |||
a9ab8784c4 | |||
de5b00fd52 | |||
6547f75b12 | |||
827bf506a7 | |||
adc187c32e | |||
5350302b09 | |||
167ca75388 | |||
46cea67258 | |||
463e0919d4 | |||
98906c1da3 | |||
b71e66c335 | |||
2b6c5bb416 | |||
628e59894b | |||
703d2ead33 | |||
43f53a708f | |||
07e7331e7b | |||
c516af3130 | |||
39727d1156 | |||
85cd189a69 | |||
a8e35422f2 | |||
3941961f8b | |||
d9c6485cbf | |||
c52ccc76a3 | |||
be1c4f26b5 | |||
a6ee6739e0 | |||
54a8ad8bc6 | |||
2541bfcdf2 | |||
d7d5da0301 | |||
d2bd9efc25 | |||
779b18bf48 | |||
618a53b34f | |||
f4eaadb948 | |||
ea061b0f46 | |||
3652e42699 | |||
398489f661 | |||
70fc13500d | |||
18541c447e | |||
3294a6e1a7 | |||
38563c38e8 | |||
a465c5f996 | |||
1760ba1279 | |||
3d3c9546a2 | |||
203c5db5eb | |||
cf44234323 | |||
cc94076ffb | |||
8d137eae5b | |||
51fa9ae513 | |||
9951c92459 | |||
ee77e5d582 | |||
d74721f229 | |||
1aa97b19f7 | |||
95de48e986 | |||
a147d0428d | |||
90b3f7b7f6 | |||
c80acfda08 | |||
8a39145e3c | |||
b62f5ef07d | |||
bd5c6c5cd6 | |||
f874a57439 | |||
6a4525e554 | |||
d553a5bdc0 | |||
80076965a7 | |||
84e8d38d4c | |||
33f3f9d997 | |||
be72b1d066 | |||
dc5d2b83ef | |||
3dabe645c2 | |||
e9ede362dc | |||
01357aca35 | |||
c944dd6768 | |||
ff01ed5e4b | |||
d23c374326 | |||
a69ebc8a68 | |||
f4d8a35b9d | |||
2b140f8fb7 | |||
ab603bdbbf | |||
44e2f7f555 | |||
fd1b3b4fee | |||
4ae2a0b2a5 | |||
0cb415b3bd | |||
c1fa9a82e6 | |||
dde124ab5a | |||
668920cec4 | |||
9b38c5b304 | |||
e63c2da433 | |||
38c768fdb3 | |||
0dd4584157 | |||
b7bf712b97 | |||
615723d8df | |||
de352a309d | |||
c573e7f9a1 | |||
d59fd1a75d | |||
18d69d7032 | |||
5d25716cee | |||
840e79c18c | |||
ddf562e306 | |||
20a6ce7003 | |||
8c43298af0 | |||
4bb48e56d2 | |||
338ba10ca2 | |||
36eb745ecc | |||
b07e45e214 | |||
bba5198e63 | |||
9e2bab008a | |||
5ea032bbf7 | |||
897fadfb40 | |||
b05f71eb9b | |||
4ce0e80956 | |||
577ccc4d56 | |||
39d12351ba | |||
e37bc6d7f0 | |||
9593ff3582 | |||
ad8dfd7b04 | |||
ca5ab20f67 | |||
0eab448221 | |||
a26a77f9db | |||
c3df6bb8bd | |||
ce3a26cf37 | |||
04482c23c4 | |||
ff20fe856e | |||
12e3921f81 | |||
928fbee15b | |||
a103c028f9 | |||
775347d865 | |||
6d0be86a4e | |||
a4b69db8af | |||
790b9d3371 | |||
adef2009a5 | |||
1721db6d8d | |||
6d95e8b988 | |||
b07f9932db | |||
9439da81c4 | |||
6257e64d03 | |||
ba110f2d2e | |||
6bdf621d05 | |||
1c4db98c95 | |||
dadac957e4 | |||
cf3976d496 | |||
82ed80c9c3 | |||
67222525ad | |||
fff0861773 | |||
13ffe41498 | |||
96e0528a7b | |||
3df30fbd57 | |||
b57d8b336b | |||
3169b2c440 | |||
6bc34e0f32 | |||
cecb1a41fb | |||
b9069df85c | |||
aee3c6f041 | |||
c427bba9f1 | |||
da83ad561b | |||
85520e34ab | |||
d0edd970e1 | |||
8529ca70af | |||
1a8d78212f | |||
4270a2806d | |||
4333bdc709 | |||
75b824d032 | |||
7bc2573d85 | |||
67b7b7a950 | |||
786cfbd397 | |||
9df8b583cf | |||
8e32290dc9 | |||
23478f3336 | |||
2e244ecb63 | |||
e307680206 | |||
6bb1a3e2c4 | |||
8a1ac6b13f | |||
61b8af2252 | |||
c99afed012 | |||
2947b92148 | |||
39c5d23a87 | |||
d839670f54 | |||
0d1b7e15d1 | |||
ac678f63ee | |||
d862c0879b | |||
23a4d4c69e | |||
472b20d933 | |||
492dd718fb | |||
0d5618fdd1 | |||
503508af41 | |||
4ec5e55122 | |||
8daca865ca | |||
f9b37a21e8 | |||
c398f319fc | |||
1e049f88b8 | |||
4831d9c3a3 | |||
f13f5bc1bb | |||
4e114107ed | |||
0ccb280008 | |||
28c3e0693e | |||
c321c8a02f | |||
2407ec7b47 | |||
70eeb75716 | |||
751d250471 | |||
c28217db80 | |||
0968e556fa | |||
130f2cf808 | |||
4eec7413c7 | |||
efc3246d26 | |||
9930dbc0ff | |||
754f87dac3 | |||
51139bd096 | |||
6e0119d620 | |||
a3528bf973 | |||
77c36af588 | |||
69c0a52a33 | |||
a7442cd0a5 | |||
d47a013931 | |||
745f9c0e6e | |||
414f49fd80 | |||
e49a595f54 | |||
77485c2a04 | |||
e9b28634e5 | |||
b43dcb8876 | |||
f0c1eeece8 | |||
1e6b824ede | |||
1e2d16273c | |||
32dc24c59b | |||
7a8a189c48 | |||
6aa411fecc | |||
9c76318df8 | |||
6510904711 | |||
a9817f4832 | |||
9067689839 | |||
4e9e91fdce | |||
73cc91ba60 | |||
0ab0d0860f | |||
337b399a75 | |||
46f21e81e3 | |||
c1300ddbbc | |||
8bd5b1e696 | |||
40c5db397d | |||
8b52919b4d | |||
2859f23038 | |||
00384ccb47 | |||
0191cc589a | |||
dae6db9b51 | |||
4d912c9feb | |||
07c4b46466 | |||
e9cdce49a3 | |||
84c3ce8778 | |||
d5a32a7fe4 | |||
cc4dfda21b | |||
703b37aa7b | |||
b433de9022 | |||
0c1a22ff95 | |||
4d526e40c3 | |||
4586c7b36b | |||
3d60b73b60 | |||
4ef5cd8ef6 | |||
6959bd19f1 | |||
17e4ce5ea8 | |||
33094b4988 | |||
a8fdcffd44 | |||
5adb5411fa | |||
ff0d11c89c | |||
5f6dce2b5c | |||
a7405e8b39 | |||
d87c520bad | |||
24959f8d34 | |||
6d1432e166 | |||
2c7ba2c125 | |||
a0ba664c64 | |||
131da5f523 | |||
7c6144450a | |||
4c7369db16 | |||
f4355de896 | |||
4a3db9f44d | |||
6c0a9ff9cc | |||
57b1695fcf | |||
045c6546cc | |||
ce5bd954bf | |||
6ef00a4a3b | |||
569d9718a0 | |||
00a3a8697f | |||
c93444e390 | |||
5e5788ab14 | |||
abf57e6362 | |||
74c2074d5a | |||
b74606312e | |||
0c849df4d5 | |||
38690d4a09 | |||
b64c237cb3 | |||
3fbee8e027 | |||
a68e6e3c63 | |||
db5a72774d | |||
966f90f24a | |||
eaa664c023 | |||
e9282c3987 | |||
ed1f8ed339 | |||
5d0d637eb8 | |||
7e70dfdf4c | |||
3f61f39ae3 | |||
371f623a3e | |||
566d566f26 | |||
fb30822860 | |||
526a53bdd4 | |||
3833124d66 | |||
e5e1b52abf | |||
82fc66305d | |||
05e0d5066f | |||
ce2dc84e49 | |||
eb14ed32ea | |||
f97987d0d8 | |||
d23d9c3b05 | |||
3ebf6e3bea | |||
9f41f5c740 | |||
ae00f86887 | |||
ab67c0f8b0 | |||
ed7d4928e5 | |||
f23239a923 | |||
d949920e68 | |||
a1def85c18 | |||
dc624f65e4 | |||
361652d028 | |||
92024b7e54 | |||
4e4ce0dd21 | |||
bc0c490ec3 | |||
6d92af17fd | |||
2140a498a2 | |||
28349d362c | |||
e7af9f98e3 | |||
dd6053c5e1 | |||
37726a4cb6 | |||
4352cc231e | |||
824220356f | |||
247ad9d7ab | |||
09fe12d0c1 | |||
127ef8383b | |||
82eccb566c | |||
543b29efe7 | |||
0f4ce5dd4e | |||
c23919df15 | |||
2b2a8b4747 | |||
2e48dbf6ee | |||
207917ba45 | |||
f824b97f3a | |||
a5ff2fc68f | |||
4906806c0b | |||
d98336a906 | |||
9ddd11cdb8 | |||
554ad4ef05 | |||
45d8550044 | |||
f2b44c1494 | |||
bdb28e87a9 | |||
8b9592e53e | |||
84f89648a6 | |||
1174992099 | |||
391a220dc1 | |||
43f1d0578b | |||
d3e35028ca | |||
61c7d87003 | |||
20f2fa84a4 | |||
17e269b96c | |||
6a57ac92ba | |||
07ad03556f | |||
04c33230c8 | |||
083dac630f | |||
6375724196 | |||
922957c1ae | |||
cbf7d0e738 | |||
fb81efeecf | |||
8466198626 | |||
33718ef7a5 | |||
a94a62764d | |||
12c98df3db | |||
81909a406f | |||
d291aaa4f2 | |||
da36d87e46 | |||
42bc09a7ef | |||
d0defc592e | |||
700f7fbaf3 | |||
74f2d02ac3 | |||
c865d96f4b | |||
cd7b9e108c | |||
f54b82f64c | |||
36bfe8c533 | |||
a40d063cb8 | |||
ac88a88bfb | |||
d89c9b4556 | |||
a07056f5e2 | |||
f91bea3ea5 | |||
9fbd79316a | |||
6d89d0b02a | |||
0febcbfa2a | |||
f2f2898fe3 | |||
f65826b3ba | |||
a869007180 | |||
b5fa48f485 | |||
36d564526c | |||
063f34b5d3 | |||
9486ca5975 | |||
63ead272a9 | |||
9dfa2ad84e | |||
523e431ece | |||
768c4a0dd5 | |||
fd25cf30ff | |||
1d14488a4f | |||
6e32c97c43 | |||
020fe35d98 | |||
e0cf946611 | |||
a42ae6fe3a | |||
196ab6a7c3 | |||
f3235882f3 | |||
0518d69b72 | |||
c9ba94d4d8 | |||
50e4a40bb2 | |||
351421c158 | |||
c3ac2df9ca | |||
7c4f632e06 | |||
a4eb3c17eb | |||
e81cee3949 | |||
e943dcafa4 | |||
a324c390f0 | |||
1cf64b5471 | |||
234a4f3a1b | |||
e69d561e8e | |||
b8f2abcbfa | |||
189617dfb2 | |||
c4bfb1e400 | |||
7db92ad5d9 | |||
fa593a3e15 | |||
8424236daa | |||
5c14be28f3 | |||
9ef80f6ac6 | |||
daf81b5cae | |||
7b407dda91 | |||
4c50293f06 | |||
02b8804b96 | |||
7928f90cf6 | |||
d5e6ea6ebd | |||
52273b6c03 | |||
b3d663b758 | |||
c0028694d4 | |||
3b0110849c | |||
7b1deba590 | |||
7a91f318f0 | |||
2dfde89008 | |||
23146c00ba | |||
cdd95fbbdc | |||
01064af20e | |||
01a9c3fc8e | |||
c1734b279b | |||
b00dc31b55 | |||
c5f8c8c77b | |||
9361c7223d | |||
b43cc22704 | |||
8af4fd64c1 | |||
5b39b87199 | |||
092338a4c7 | |||
7907b19e28 | |||
5790309e88 | |||
9496b64c86 | |||
f7fb6b2160 | |||
98649f9397 | |||
45a1ceaa54 | |||
6496205081 | |||
e2898bea5c | |||
563221698c | |||
92a85071bc | |||
9ae8d90be4 | |||
caade78e79 | |||
4f22c61b16 | |||
5e220e9e47 | |||
857cb9c501 | |||
09fa5d98c2 | |||
268fe464de | |||
27095d1a02 | |||
dd061fed38 | |||
7ddaa8968a | |||
cec1557d04 | |||
84a49a5eef | |||
06ea16bdbf | |||
361d38f93b | |||
016e384fa1 | |||
ef57c9ff83 | |||
627fff967f | |||
e79c093d80 | |||
cbb3831c7b | |||
9752fda1f6 | |||
d99f08b9c4 | |||
bf0bcaa306 | |||
a199c1290b | |||
28bb0c1fb2 | |||
49259b3d19 | |||
a5d0ac7955 | |||
f326dde09c | |||
3b6d907577 | |||
0af108211c | |||
902e78d910 | |||
885e194c25 | |||
d99a2f19a5 | |||
152a7fd1ef | |||
6ceb6545ee | |||
a167b16860 | |||
595be5083c | |||
8b796e745d | |||
d5314736de | |||
a517ab964e | |||
b6c0a2c197 | |||
0151c92a92 | |||
a39440fff5 | |||
5af7e9f6fe | |||
b8d9273a7c | |||
77c4cbb974 | |||
8adc193d73 | |||
86aa4fe0a9 | |||
8c9eb6702d | |||
b245ee6212 | |||
98fa71ba18 | |||
22dcb46bff | |||
3aa904da0a | |||
794f773620 | |||
bbba77c275 | |||
88f2bbba61 | |||
cc8d4e4ab3 | |||
32a11bd8c7 | |||
55c82a389c | |||
a1aa58bb64 | |||
82ffe233dc | |||
9e16bb85e3 | |||
887b41bce3 | |||
63eef286c9 | |||
14e8cba2b1 | |||
3418e6e85e | |||
8f0c980d3c | |||
c86f3b8d48 | |||
8cf6b4c728 | |||
612b9e9faf | |||
c2c4c26f72 | |||
be4d504e27 | |||
9ed0bbb3a9 | |||
e5bc3a2ba8 | |||
1dee10c575 | |||
352fb7b833 | |||
81cee34c17 | |||
fa786fd3ef | |||
0751a90bd9 | |||
709193d680 | |||
d0d82cdf7e | |||
5d2b7e2c9e | |||
07660f7fcf | |||
5d138e1b79 | |||
0133c6e174 | |||
2054f77e2b | |||
e4911e2f7a | |||
eabc2e6781 | |||
71cf87cbb1 | |||
155997b5fa | |||
82ce8fe3ff | |||
9f1da20161 | |||
d4239d570d | |||
1ecbabc69a | |||
7f767c49d8 | |||
aabe56ba79 | |||
d227ddfc88 | |||
021d3dadbb | |||
4902a600d5 | |||
db39ba3b9f | |||
239a9e4816 | |||
35e99266ba | |||
67ae8ed8e9 | |||
356e4c0967 | |||
80a9d2e7c9 | |||
5088f22388 | |||
4156a4c2d0 | |||
b6c2399a17 | |||
5be9326192 | |||
388cfa3695 | |||
e8914c6699 | |||
13bf64a53d | |||
f96b2ee858 | |||
b12967b930 | |||
d896248ff8 | |||
2ebdc81c8f | |||
2af5e851b3 | |||
bd9455ec8e | |||
fefee3b49e | |||
071c49b7c6 | |||
4e9e6e75d3 | |||
a13af7fbcc | |||
4fa8e2b59d | |||
90783c7cdf | |||
f99b4da4ec | |||
a64e0e1f49 | |||
270e82e3db | |||
8f4a4d93f2 | |||
83265bb12a | |||
5be8d5f9cf | |||
08126e5a38 | |||
b76efe17d6 | |||
ca2678446d | |||
06d906b962 | |||
023f5149e5 | |||
2e45508529 | |||
6241a8269f | |||
465d03ab2c | |||
a56cd3c3d6 | |||
d8a98e5467 | |||
2d813cbdd8 | |||
6d3434f3a5 | |||
fa0268f35a | |||
712ea9b9b6 | |||
b7fd78b254 | |||
a2e6b3167b | |||
72037af241 | |||
62048abbf5 | |||
7b61aca956 | |||
6709e5e458 | |||
11c8405879 | |||
6028628261 | |||
3d8a1537d2 | |||
c5b4decdae | |||
c7237be3e3 | |||
aa39166b74 | |||
e7b9933036 | |||
54d51c713c | |||
72e0c2fe11 | |||
7458d3ef39 | |||
52c5f9b144 | |||
8c7085acd4 | |||
083ca7d39b | |||
68e716ae27 | |||
ef8772916d | |||
b54e374bc5 | |||
b3228258ee | |||
e5036a458e | |||
c714a66ba3 | |||
d80b7be6ca | |||
77de611ec7 | |||
60b54c0052 | |||
6a3130e25f | |||
91cba1f8f4 | |||
22b2661df9 | |||
f8b397a5dc | |||
44b475e746 | |||
d25610903a | |||
2efcbaf206 | |||
7f1d2825fd | |||
b9edb1dc01 | |||
b0cc778c49 | |||
ff840db708 | |||
11f30e2e09 | |||
4886275df4 | |||
c5de239e25 | |||
10dcc100e9 | |||
8ada9b43ae | |||
fd77225c3e | |||
7ed3facf8f | |||
6c97e2a5ab | |||
f19e8b1e78 | |||
08e669adde | |||
bbd2c02b7f | |||
0d9da86b7e | |||
5810fcb14d | |||
2466eb3132 | |||
fc59e222d2 | |||
ff983432d9 | |||
67b4f9b3a9 | |||
f279b6bf7e | |||
daec53f4fe | |||
cb1966612e | |||
cda279f5c2 | |||
31915cdc93 | |||
329f803004 | |||
7780c99de6 | |||
d3ad857ba4 | |||
aa1405e4ea | |||
aa0a7f7816 | |||
3850edced5 | |||
ddd59f2e76 | |||
10a0f2b614 | |||
8bc85d4a79 | |||
3dc07d48c5 | |||
c1acf992fa | |||
99149f9c41 | |||
bcd307066a | |||
446910cb10 | |||
fde200d084 | |||
a376cd1610 | |||
dbeab0ef87 | |||
7765d6a08f | |||
aed50e2a39 | |||
b262a42458 | |||
3fd90dfcb1 | |||
dec55a3291 | |||
f6f3ded842 | |||
004c5cf287 | |||
aba5f2f7b8 | |||
2a96964204 | |||
a9fe2a1493 | |||
8f3bdd4f1a | |||
4322a20cbe | |||
2403fd0680 | |||
e01baf2a25 | |||
d27b37fefe | |||
acedb60abe | |||
77556d181e | |||
60612cace9 | |||
f057502834 | |||
21a1149532 | |||
6724ca4f63 | |||
7a6c25b3fb | |||
0366e320af | |||
f03793b825 | |||
0907f030b4 | |||
7542e68b6f | |||
9003a34285 | |||
3cc27eaabe | |||
601b081bf3 | |||
4405d993c9 | |||
361308eb1b | |||
d894dedaf6 | |||
d12dd1491f | |||
1625591598 | |||
a50c30a4fd | |||
02bfc74c1e | |||
a012dd838d | |||
e2b634e59a | |||
80b98d8787 | |||
bf2ba83cd5 | |||
727c43dbab | |||
203dedfb3a | |||
8d5d4159a3 | |||
cecba0269f | |||
3c878793b5 | |||
0549f42030 | |||
50f248ec5b | |||
544bdb4fb1 | |||
88b295ff9f | |||
602326bb57 | |||
31857cf05f | |||
896d8e830c | |||
5f86e29830 | |||
579ae59eca | |||
90db743cc9 | |||
fe82897064 | |||
0f49f36519 | |||
a92b7342ba | |||
86818e9c52 | |||
7a8a00c705 | |||
c8d5e0a51c | |||
524a7ff6fb | |||
5f6ac33d59 | |||
b4f5e4206d | |||
5133c3e010 | |||
0b77ea422a | |||
5c1dd4ea18 | |||
e1c687184e | |||
297d1356a2 | |||
98327b0c13 | |||
6786aee5ed | |||
0b9c726b4e | |||
436dd6ee8c | |||
acc053302d | |||
534b371d42 | |||
6004e3d2e1 | |||
c632074ba7 | |||
664245d2a6 | |||
fda4fc674d | |||
bf28c24c82 | |||
32df0e80ca | |||
297eab738f | |||
5819dd3a5a | |||
a007b1bb2d | |||
5cb43b6bae | |||
f524138a64 | |||
0aa626b2fb | |||
3ae1050f67 | |||
67736642f3 | |||
09f3c87d20 | |||
9deca75de8 | |||
5bc1dede81 | |||
6d53d43766 | |||
325462d9bf | |||
ee4ae62946 | |||
153768ef7f | |||
7249a218ba | |||
de348a4c49 | |||
fda8ffd9ef | |||
6cb707cc4f | |||
998c5f17fc | |||
c34b357051 | |||
40f4e92461 | |||
c727da823b | |||
8d1b7962d8 | |||
a6dfe20348 | |||
ed46390bbc | |||
80eb5bf535 | |||
7596fdb460 | |||
8db1ff8aef | |||
1dfffdbc4e | |||
64b2b4a7d4 | |||
ae35d0e43c | |||
b22c5eb167 | |||
6d5e414863 | |||
3e74dfb66d | |||
1245628521 | |||
c567690004 | |||
2feff4207b | |||
8c40b6f9a7 | |||
fc759bff77 | |||
3581c1d5b4 | |||
64e7459d1c | |||
f71afa9248 | |||
1ebca2e6d5 | |||
6222796b6a | |||
dcecf41d18 | |||
9d1fbffe75 | |||
6a6ba94bb9 | |||
ef5de3a5c0 | |||
f042e43990 | |||
620330db8f | |||
3765acc0a5 | |||
2e8654b96c | |||
cc5c5e7e8a | |||
9c849b0290 | |||
ad314b362e | |||
737a4f2816 | |||
96e4128e3e | |||
6f515f2327 | |||
cbb9a7ab96 | |||
e2e3b29ed1 | |||
82a8ac1976 | |||
bfec396ec2 | |||
d0e7f880d7 | |||
ff81659b9e | |||
6b2b3475c8 | |||
ed8acefc00 | |||
737f395d6c | |||
ab0a5d4a53 | |||
9412ac2027 | |||
c8670819dc | |||
4132ccae33 | |||
c450120409 | |||
6ce07abf50 | |||
e39e539ee9 | |||
9563a8f8a0 | |||
d5f37fa280 | |||
5c6e5ef6d0 | |||
42adc38609 | |||
e5fadb3b42 | |||
4c5f3aa971 | |||
6fc49b79a4 | |||
9e804b082f | |||
1fb220beb7 | |||
1fc1282fad | |||
8834a7df10 | |||
a34071e1c3 | |||
52a342300a | |||
b9456caeb0 | |||
26aa4333a5 | |||
04d2b0d282 | |||
7def1a4aa5 | |||
001b9868fb | |||
59a3e393f9 | |||
b846354787 | |||
2674d96e54 | |||
0c98fe8546 | |||
f18ed3c6ae | |||
644acf7018 | |||
96dca48b3b | |||
1309b64c33 | |||
1301dee744 | |||
efc194e36c | |||
60f41a109f | |||
890efa787a | |||
60c88612f7 | |||
82648bc86c | |||
ea1e5a5210 | |||
aa03734d39 | |||
bb0f76f562 | |||
8c2a290d09 | |||
8e661c3780 | |||
a03b6c419a | |||
fb55dd677f | |||
408790a630 | |||
08371f073d | |||
e7289378b7 | |||
31bde574de | |||
5aacfe4e6e | |||
5cf7bdabfd | |||
2021edd1fb | |||
45c1a9eafb | |||
0ae1556b94 | |||
c0739bd1e3 | |||
af51e8df7b | |||
22ef63cc44 | |||
03a5133e8c | |||
7f2456c00d | |||
aa4dbee362 | |||
7b65735cc9 | |||
7ef35fbec7 | |||
8b10d85fee | |||
d99b1e6c09 | |||
57ab7aec5b | |||
29a221bf62 | |||
671c569a9e | |||
492c033760 | |||
33a3b8046d | |||
88df183450 | |||
6a9080c3d6 | |||
019670b5ab | |||
4cab0c95d3 | |||
d51e79d483 | |||
69a27911a7 | |||
dd48514b24 | |||
eb54662098 | |||
545f0432c8 | |||
fdefb317cb | |||
4e0c8bfe67 | |||
dbd629d5d2 | |||
619a44a499 | |||
c5ca4e3ff0 | |||
55771b437b | |||
8727680983 | |||
ab9f21351f | |||
0055cabc62 | |||
fc70c2246b | |||
f7b6acaff8 | |||
91caa8e59f | |||
4c44bb7f52 | |||
df8a735aa9 | |||
82aea3e8d6 | |||
a8baf4a2a2 | |||
bfd344cdec | |||
a0fd4e195d | |||
4b3fbc4c9b | |||
63b1699a35 | |||
48acc41698 | |||
17672accfe | |||
986d72d9de | |||
ffd461cdb4 | |||
71dfab9711 | |||
c4f5274d74 | |||
4bfc3bafcb | |||
898b2b903d | |||
7921954a31 | |||
0e42de9149 | |||
8e4a5f1ac5 | |||
61577e176e | |||
4b008b1ada | |||
bee37b5bc4 | |||
b5ab8b6ed5 | |||
4d6bd91d16 | |||
5428db5385 | |||
6e6b1e6052 | |||
bc2b47974d | |||
2244b6ff1b | |||
fb384fc291 | |||
73cae8ce9a | |||
dcd07eb23f | |||
fa24448489 | |||
c975740f92 | |||
1e0187fa57 | |||
cbdf060bca | |||
19a8dff975 | |||
72f9f482d6 | |||
88de26138a | |||
57bd964cb3 | |||
74a39ae57c | |||
5090a4ccce | |||
ae0652d13f | |||
101a07a3d7 | |||
b012e93121 | |||
c31109800b | |||
c0dc363a3d | |||
739bb28220 | |||
aab2794e05 | |||
75c8c1bfb6 | |||
6f8bd96195 | |||
25f0d098bd | |||
56d584b7c6 | |||
20bf53add1 | |||
0d440bb0a2 | |||
8ec62ce46b | |||
79927faaec | |||
e4c7f1f3c4 | |||
68710c4647 | |||
7d7cbde1f3 | |||
bafd9c777a | |||
42a5531f15 | |||
227da25776 | |||
2028f33e38 | |||
145bf19636 | |||
d1675c44e2 | |||
6934e4db26 | |||
cae3414854 | |||
90d061edaf | |||
2e02918323 | |||
e77a1fd33b | |||
dd01c24c34 | |||
f88fbee80d | |||
fe08edbe2b | |||
d2a16bca10 | |||
a87f51487e | |||
76fce94b66 | |||
d104f9210a | |||
d0780d1622 | |||
9d5906dae3 | |||
07a0960265 | |||
72bee6d7ca | |||
249f26d23c | |||
7813c5b93f | |||
e38d83fd44 | |||
d97657b151 | |||
7e857dede3 | |||
c3218f6b03 | |||
1060d0db60 | |||
b8925a091c | |||
79cca07a41 | |||
c1d189c9ad | |||
b1a973ee5a | |||
93ef560779 | |||
c28d35ad86 | |||
9c654a6ab5 | |||
64a54e379c | |||
8f4ec8583b | |||
f4852d7264 | |||
092e1a691d | |||
16ac42421d | |||
1d2eadb9c0 | |||
35c85d9fac | |||
f0622c1896 | |||
6d11247417 | |||
59c3e3a179 | |||
42e26a8682 | |||
db6caac9cc | |||
ba4a57ba0b | |||
018e3bc35f | |||
a56bc9d933 | |||
5b93525ce8 | |||
6abb86dff6 | |||
6a27d5ed80 | |||
8232684672 | |||
2d855ce5cf | |||
b2b685e46d | |||
ef552846d1 | |||
c7dfd0894e | |||
5b1a76aeff | |||
529b6ca935 | |||
625a4c0766 | |||
3c3ea2f575 | |||
57a332bb08 | |||
73ac98b193 | |||
59e3cbb36b | |||
fb019a7cbf | |||
09607f6aa7 | |||
1c4a33eb78 | |||
b7513097ea | |||
a35677a9bf | |||
89de3a81c6 | |||
b9828bf5de | |||
d6c3868a7c | |||
a73f02ac23 | |||
7e9594456b | |||
d25418ba04 | |||
a7df1a3d77 | |||
50951d15ea | |||
30076884ae | |||
1eff22a90b | |||
41bdbc203d | |||
7932585656 | |||
68bf4e7b70 | |||
92f09a60f6 | |||
d19f2bb6d2 | |||
b06dce5bf8 | |||
82e2ab89c5 | |||
db198b183c | |||
90bab650e2 | |||
fa1cc556f9 | |||
69b23b0e48 | |||
af69945e5b | |||
f36f7644c8 | |||
20f1457d15 | |||
38bcd52065 | |||
38219fec99 | |||
6c3300bc2f | |||
d1a110d4ca | |||
5b61485143 | |||
6b95a357eb | |||
60bdc726ce | |||
429f809b71 | |||
9396d736f2 | |||
cc9b812466 | |||
5b0f2dc0cf | |||
7ffea1606d | |||
342bc1e72d | |||
0127eb5892 | |||
39023269d6 | |||
35e3cd97fe | |||
a63a171ec3 | |||
7f1763f32f | |||
2d6326815c | |||
ee4c8cca8c | |||
2104e0f411 | |||
84e69f57ea | |||
aba43125f3 | |||
de5fc58fcb | |||
4831dde3fb | |||
b5cbfc5e7a | |||
1124d164ec | |||
9d9391bd95 | |||
0121d74b92 | |||
f81af32963 | |||
8f5198821e | |||
96c2b5ef32 | |||
c5eb324cf0 | |||
f117d9bfd3 | |||
b470736246 | |||
b2a2a00cd8 | |||
659130856c | |||
9a21008177 | |||
8f58bc5b19 | |||
3a0220a875 | |||
9f438d0ec6 | |||
22c22e0d7a | |||
bc48bd5f4a | |||
905c4bb4a5 | |||
94bfaf6896 | |||
25b743b03c | |||
8da4e6ce5e | |||
cedd297ba6 | |||
b6e0c5e0ea | |||
bf3f7d0dc4 | |||
7b42a84422 | |||
8b7c065706 | |||
c6a4b3d9b0 | |||
0ef32f2b8d | |||
f7fdcb7bf1 | |||
848d36ff39 | |||
07ce3e7cdf | |||
cfec145ae2 | |||
641d7a4ea4 | |||
da0650fda6 | |||
6724133927 | |||
c0ded8ef5f | |||
7382de51dc | |||
96a1121e6b | |||
323bbb0692 | |||
59e235623a | |||
40dc85d975 | |||
6006a42cbb | |||
c2e0278bd9 | |||
c1ba920c86 | |||
7b997e9374 | |||
dfb97c1ed7 | |||
fc49fb2f4f | |||
63078fba5b | |||
b0176546c2 | |||
a234ba91a4 | |||
526d11809f | |||
3bbdecc6b3 | |||
00fc4a2eb7 | |||
924b31233b | |||
475161f716 | |||
31b12635d1 | |||
d2de0865bf | |||
9b4dbd0e83 | |||
4577cd7497 | |||
4ebf07c725 | |||
da852a94bd | |||
9b51ff7241 | |||
aa0137e7ce | |||
3889ae7627 | |||
c97a8602a1 | |||
affc9f9058 | |||
1582819259 | |||
05e8ae33dc | |||
219d5fb66b | |||
92ff57c0ea | |||
5233429b6f | |||
475cf7179e | |||
f608c65962 | |||
6cf0a35b4c | |||
bac006ebc1 | |||
be5f74e37f | |||
5c29bff23d | |||
68968d2b40 | |||
038f4e8bde | |||
f8874fec0f | |||
ee6693e6e3 | |||
bfba97647e | |||
82d5194afe | |||
bf449b9f61 | |||
9530048867 | |||
090d54516e | |||
c91b716a63 | |||
80cdb0dc4e | |||
aaa6b54673 | |||
a3b61ec8c8 | |||
6c41d6b66a | |||
1838ab1412 | |||
72e8d38586 | |||
9259e2221d | |||
42ea979b06 | |||
46824adb97 | |||
3758f4952e | |||
8fdbbe78f4 | |||
5a86b0f9e3 | |||
604722b775 | |||
812812d817 | |||
f07fe0a8e7 | |||
1d7cef5bfe | |||
34b12e6a6a | |||
eb6ba563bd | |||
281b2e9b0e | |||
5437629e89 | |||
e1df2f8ff5 | |||
12fad6f05f | |||
4208078750 | |||
dba02f8f08 | |||
35e410fe96 | |||
7dcd2313d8 | |||
40750f2dc6 | |||
85c007431b | |||
cbd187369e | |||
d20d89a0b9 | |||
80eb37ef60 | |||
d19cdc206b | |||
02078255ea | |||
bea2d40f79 | |||
a5d3259cfe | |||
4a93ce703e | |||
661ea906d9 | |||
b382b4cb94 | |||
087e86fb32 | |||
afffa76c17 | |||
69ca18f36b | |||
f84c62f0be | |||
90c554ad42 | |||
e2cb6cc4da | |||
02da366cc2 | |||
54e3a54489 | |||
8798ec653d | |||
d1ffd3cf35 | |||
133b854f1b | |||
33125e78c8 | |||
4118bf1a5e | |||
8282db456b | |||
7b5eacf671 | |||
12bd374477 | |||
9ef4cc0ab9 | |||
528fc9bc47 | |||
c58b8498b3 | |||
c81c564941 | |||
b16de0e374 | |||
d38f41a459 | |||
30346884fe | |||
1518dc9b60 | |||
fd3f2289c3 | |||
22bfd4f7c3 | |||
2782011ce8 | |||
7f17fcfafc | |||
a40daa3c22 | |||
1e366aa56e | |||
bad8dbc2d2 | |||
d0dd37fe94 | |||
b2df3fcd1d | |||
96f89ce4ae | |||
e886a3d891 | |||
0eaf141ae4 | |||
291ef07cf3 | |||
b9066ac997 | |||
206f4604a4 | |||
adbc1d97a0 | |||
70ae700461 | |||
b81ad3ed39 | |||
77cdb17cee | |||
d4e329b76d | |||
fb24585dd8 | |||
bd5efd5968 | |||
650f35c1f3 | |||
14e65168c9 | |||
f00c47c21a | |||
547d105b2e | |||
de671103ca | |||
2c48efa3fd | |||
7f35b2dc43 | |||
6ae914da2f | |||
06ea78af1b | |||
2ea12a7699 | |||
8ab25de6c6 | |||
e0424a7017 | |||
f259162d64 | |||
6bb5cdeb2f | |||
384c30b6fd | |||
67a75d4439 | |||
0d963df7b3 | |||
99efde5673 | |||
c8ff699c4b | |||
0718a888d0 | |||
b7be4df603 | |||
8bece0b49e | |||
47d6edc3c8 | |||
26bb56396d | |||
dd99ed73a9 | |||
36ce460a39 | |||
e92c845dfd | |||
492263c2e9 | |||
0c99f66547 | |||
df440496ee | |||
09f2028d6a | |||
05736ba0a1 | |||
e5f05bc9d8 | |||
cdd1209b55 | |||
0e6458a630 | |||
a1a068a377 | |||
2c5657e8a9 | |||
87fbd715a3 | |||
fc8cba9598 | |||
147725bf7a | |||
06d2c0af35 | |||
708f1a97dd | |||
d8bd9f5a66 | |||
079953c3ee | |||
fea8b6da2f | |||
4bf1df0894 | |||
b4f16c4df8 | |||
61282737c5 | |||
d8c2290099 | |||
830ab599df | |||
0de5c5e8a3 | |||
c6170ed751 | |||
2ea762cfc9 | |||
2646741297 | |||
f5df5faf71 | |||
cab9a580e8 | |||
c8ac3fd4f5 | |||
7f67c34b39 | |||
e27293edbc | |||
8d57c5052c | |||
1314559833 | |||
735397aa89 | |||
c0d0c792e1 | |||
43020b20b7 | |||
0a3d80b86e | |||
a9505d0426 | |||
4d804c2a29 | |||
e8eec2d357 | |||
971e3f679f | |||
7c90f078e7 | |||
5957bd1abb | |||
b16380e7e5 | |||
b72a32c70d | |||
90f15b3c5a | |||
44bbf26cb2 | |||
fcfd17e973 | |||
73853cf147 | |||
ddbc263da2 | |||
982d8a0dc0 | |||
5a269db9d5 | |||
525da01a62 | |||
12df10b2d0 | |||
e6aee5d7ea | |||
6ff69da0de | |||
ebcb87c163 | |||
79d9df9bb1 | |||
8c40c2086a | |||
f4a000cb59 | |||
4029202635 | |||
29d473f2fa | |||
7ad89dc46b | |||
4b2d6f8a99 | |||
9b55de1c6b | |||
8b45211a8f | |||
f079501cff | |||
e375e1789b | |||
30d2cfdf56 | |||
44d61e6857 | |||
3466829766 | |||
d3703516d9 | |||
bdebaa986b | |||
c2d400846b | |||
034e147910 | |||
25015c9c3a | |||
43cf60f563 | |||
057348763b | |||
7230452e23 | |||
438317c1e9 | |||
cfe719c962 | |||
44e2d88628 | |||
6e50e77709 | |||
02ed28d68d | |||
73274e201b | |||
f6fc88cc2d | |||
d16acc43d9 | |||
239aa7b8d5 | |||
44a1bc5396 | |||
821583acae | |||
c6a2814881 | |||
1954a02352 | |||
8a28022a6b | |||
43a243b24a | |||
7c937c8704 | |||
bdd1f82777 | |||
cbb8876815 | |||
f8cdaaae30 | |||
74314bacd7 | |||
04473f607b | |||
88958270cb | |||
856f7ecee9 | |||
9f5584a157 | |||
eda8a94d5b | |||
5956b13588 | |||
162d029c81 | |||
7f3920dbb7 | |||
6d07c3a1df | |||
a0a83428cf | |||
dc2cae07b2 | |||
f8b44cd30e | |||
c3eca3d754 | |||
1ea005f6a6 | |||
16a675b7ce | |||
df2f939f3a | |||
5743224817 | |||
a80e88e33e | |||
0207f1f29b | |||
72120bb87f | |||
7eaca86bf1 | |||
db5f72c868 | |||
69d6ae4141 | |||
edabafc0fc | |||
e9f2aa6010 | |||
e054dd7813 | |||
76d788a186 | |||
3944df1bd2 | |||
49f6280645 | |||
84eb66d5aa | |||
026fc531ba | |||
8d14df0ced | |||
f27547dcff | |||
6f15d1c4c4 | |||
46ffff8438 | |||
8dcd08f47e | |||
2515d5ad6c | |||
e6b1853908 | |||
e2b26c4014 | |||
d4b7a3478e | |||
e187961d72 | |||
ae96b0c971 | |||
c4dad3d2c1 | |||
36287fc33b | |||
edd5a5f185 | |||
bb7388a7fe | |||
797368bf9f | |||
0cccf1d4cc | |||
7aa326a836 | |||
fe16f2b058 | |||
af4fcc831e | |||
868bf5838d | |||
4282748483 | |||
7790a07c08 | |||
ef6cce8988 | |||
df848fdb4d | |||
b4489d9ea6 | |||
1496d6af2f | |||
52a05090bf | |||
38235ecb97 | |||
bf8b9b4906 | |||
727f2ce994 | |||
8b3309f4f6 | |||
5e08b248e8 | |||
0b1bf5f642 | |||
8ed191283a | |||
fefe2df6b5 | |||
aff9b419cf | |||
cae081950d | |||
06bf8d3470 | |||
a532b70f70 | |||
cf85477864 | |||
614176b269 | |||
03401bbb58 | |||
75ae209653 | |||
8ce97961b4 | |||
8ffe5957e5 | |||
47e2c4ae6c | |||
0065e2cfac | |||
2ee4f57395 | |||
e01971eac7 | |||
d6e29be980 | |||
6fbf8fa9e4 | |||
c64242c276 | |||
440b222664 | |||
1c759384fa | |||
602fa1c657 | |||
d964d2baae | |||
d235c205d6 | |||
b1654af406 | |||
29e5768f9b | |||
3a6b4f3eb5 | |||
84889d6dea | |||
34ce17c4b3 | |||
7723e59a72 | |||
7f5135016e | |||
08e0485213 | |||
04afea76e3 | |||
aa9a0aaf17 | |||
3f792df631 | |||
b36aa6f41b | |||
6a5345aeed | |||
b9cb37da5e | |||
6207c68439 | |||
0b149a941d | |||
5e8f7ec590 | |||
6e3c15e2ab | |||
3bee2e4228 | |||
89dcd9027d | |||
102b2e2ca6 | |||
998ea53b46 | |||
2337373a17 | |||
af29174cb6 | |||
412c6bf4b5 | |||
7fc6a3670c | |||
70fbfea5f5 | |||
9616b45518 | |||
3916b5973d | |||
5b3974b6b4 | |||
e8e36e8a66 | |||
88bcd0a9ce | |||
29eb3215b3 | |||
7c534a87cf | |||
e9e30138bd | |||
ddc135839b | |||
474ff2e997 | |||
0d2eb76cee | |||
6172cd3627 | |||
c71a6073e3 | |||
91b0e28b28 | |||
e15a9f2e73 | |||
cac134076b | |||
39e67016b5 | |||
c72241df5b | |||
a78e75775d | |||
91b84e0b06 | |||
3403215698 | |||
260e6662f0 | |||
5137cee3d6 | |||
9915038e9b | |||
7ddf54c4d3 | |||
cc72819579 | |||
6d902633e9 | |||
be775b9206 | |||
15ec185be5 | |||
e1f33739b0 | |||
dff8d579ca | |||
ef2265de4f | |||
f7b4f99d4c | |||
d5735496af | |||
3755783d41 | |||
5b8d3ba1d6 | |||
63be52e191 | |||
d15122c4b2 | |||
6d6ec46f25 | |||
8d78c3a2ab | |||
7077e57d53 | |||
031e606972 | |||
d6601645d6 | |||
97bb5b6680 | |||
adb04eb010 | |||
ff171e3651 | |||
172d68d1fe | |||
885f668d53 | |||
7cf311dac0 | |||
259c84ed9a | |||
196d10454a | |||
06198702c2 | |||
12d991f336 | |||
2b740dc34c | |||
855bbd523c | |||
a2a72d1998 | |||
9a048af1fb | |||
697139043f | |||
29ce02b1d2 | |||
60ae784c01 | |||
e3511127c7 | |||
fbf7528728 | |||
e46a26aec1 | |||
cd2c0565ad | |||
43469de2fe | |||
d1eb2b2b02 | |||
682b7ea0b5 | |||
e4d9b11685 | |||
89cbb9766b | |||
ca4b385916 | |||
26f4e44d6c | |||
610c2b5987 | |||
3c66455112 | |||
867c9a19ae | |||
1496c85bb6 | |||
998ef7d861 | |||
86b925a294 | |||
1fcfadd53c | |||
192d3a94ed | |||
5683bb9b8e | |||
1cf4cb3de5 | |||
d1548aeee1 | |||
fb800f3d8b | |||
21cc6a07f5 | |||
8a22ea948f | |||
b5cea80b54 | |||
5fc4d1751c | |||
75dbe4fdb9 | |||
c692fa4687 | |||
f34ce9271c | |||
6e236546ea | |||
3fd908d92c | |||
a4d3a57a1c | |||
0064ca3582 | |||
9c4cee7875 | |||
4a21dc954a | |||
526384320e | |||
977f45cdb9 | |||
0a94c01f83 | |||
473dad0c3e | |||
a5aa7d4bd6 | |||
4dec1bc846 | |||
9925264410 | |||
51bfbca2f1 | |||
a3a6650e66 | |||
2b90be77b3 | |||
794c986b10 | |||
bffe796413 | |||
6b4c497800 | |||
063038bc41 | |||
932a95fa25 | |||
9ce439e406 | |||
ca2bffcdb0 | |||
01097ac954 | |||
45fe44da85 | |||
89cc6807e0 | |||
9af03194b9 | |||
3056c772c2 | |||
136ed3623b | |||
4bedbca66f | |||
30da70a09e | |||
cf3c631cde | |||
530604d1ad | |||
edc0cd36c5 | |||
5261304231 | |||
a1c0b85819 | |||
1b4cff7cdc | |||
ef983480c0 | |||
bff027c1f7 | |||
1473a66862 | |||
53516733f7 | |||
e9a45190e4 | |||
649ed3332f | |||
7598fd4581 | |||
aaf94ea8f9 | |||
1a639f0b17 | |||
1bc1a0dbf0 | |||
537ce60599 | |||
0ee5a05e00 | |||
bdd805a3ee | |||
43961aaca5 | |||
0ef3f999d2 | |||
fb8f3f19f7 | |||
85ecd1864f | |||
630f0f0ac8 | |||
ae5131f902 | |||
493e82e37d | |||
804b51fa95 | |||
4f23f32fc1 | |||
3631983de5 | |||
a1e019b41a | |||
a80ed030ad | |||
1779f662b1 | |||
07bde8248e | |||
bb70be31c0 | |||
6b429b7f50 | |||
0ae44f4015 | |||
f1c279765b | |||
f39e693324 | |||
e3e16586b8 | |||
8f3376ce62 | |||
140022aaf2 | |||
ccd2fec890 | |||
02bcce07bd | |||
dc51a84cec | |||
2b91ef7833 | |||
0285e62516 | |||
4ef1923573 | |||
370c596fbf | |||
e97c15e01e | |||
69d3aad080 | |||
2fd5371de7 | |||
b750dde05b | |||
9f310b6773 | |||
067e3f2075 | |||
1938a5bcb0 | |||
36a624aafd | |||
8c80a58fa4 | |||
740a946e72 | |||
1aba99336a | |||
37d307c80e | |||
294490f77b | |||
1bc805206b | |||
a047132a2f | |||
c2ae95f912 | |||
ed6af523cb | |||
1224e959b6 | |||
688b9697c8 | |||
0c0e2cc689 | |||
f211681d6c | |||
eaa7b83979 | |||
1c320d1f8a | |||
216be33fb9 | |||
b23989871e | |||
fb5a0f8fa5 | |||
83883fafbb | |||
09717aae58 | |||
03729a71f4 | |||
6bf2dd9138 | |||
7810db6b9f | |||
4c2d9ca16e | |||
b0efe684fc | |||
2f3e47b586 | |||
1d77914316 | |||
aad3560ccb | |||
69d25c975c | |||
64c4bb86c6 | |||
eadd3691a6 | |||
20aec4bb55 | |||
01b646169c | |||
e5130877e7 | |||
75f771d736 | |||
914e5d30c7 | |||
2d716041f1 | |||
cd56de85d0 | |||
47e66ffc01 | |||
b4ec342d06 | |||
0e23ec394e | |||
7d77802ba1 | |||
ce91d85bc0 | |||
aba6a85c56 | |||
475c36048b | |||
ea4c68bd8e | |||
ac3c9f8475 | |||
de3ae87199 | |||
e752aae669 | |||
8f7d5cde90 | |||
d90c98130e | |||
af3883905b | |||
a4e53953a9 | |||
165f4e38b7 | |||
7372308270 | |||
c239d3bb1b | |||
940f06fb32 | |||
026f598c37 | |||
d33958ceee | |||
9bbf293898 | |||
d6020f1402 | |||
29e97a5f88 | |||
2b84554d91 | |||
a0584b9c30 | |||
5aab878e75 | |||
4d474e2f9c | |||
8cf9b5e5d2 | |||
a52ec8f286 | |||
739399eb2e | |||
ef8c9e0abb | |||
c705b64d67 | |||
70dd9c9d3d | |||
4450385458 | |||
1f154f6638 | |||
881a1d5cbc | |||
11064c0e35 | |||
7496a7ff3b | |||
fb71250dce | |||
0d32017ffc | |||
1b8bfda3b4 | |||
f038ce1c69 | |||
e6938ed06c | |||
2d5133ad51 | |||
6514bc845f | |||
eda12542c0 | |||
7c2aee3ac0 | |||
3c593fc056 | |||
9748cc264a | |||
295d286161 | |||
6011dd6bc9 | |||
5eb28e162f | |||
2792ad1cf4 | |||
95e6eae23b | |||
9ec2d5d609 | |||
a138f59cb0 | |||
d3e223c217 | |||
5437a3be4b | |||
c86a977564 | |||
c256fa9b9f | |||
ab80c5080a | |||
acf04d33ef | |||
bd04107593 | |||
e208c7e3dd | |||
fc313b198a | |||
b6749f4b60 | |||
ad27b9eda5 | |||
fd8572d44a | |||
32d59861a0 | |||
5bd40ff416 | |||
d1c3d8cadc | |||
49f270b02b | |||
9148dfba34 | |||
ff89090a09 | |||
ca7b03852d | |||
9735e40e24 | |||
40d8758aae | |||
73bd499d97 | |||
59191bc4b7 | |||
3173401cc2 | |||
9c53ae61f4 | |||
20de1ca772 | |||
5259656ce1 | |||
00df20c618 | |||
7637afe7dc | |||
b864f68c19 | |||
0c12f1d2ee | |||
f3e687eac8 | |||
3653f7c6c1 | |||
ac92d0678b | |||
bd9e6a3bdf | |||
2ce93ce39e | |||
5b95ccae5f | |||
0310f07eab | |||
e3acaa05be | |||
91d8a32f25 | |||
457c7adf59 | |||
8ebdb7f493 | |||
6c55ca59b0 | |||
0e4a47c0aa | |||
33100cd204 | |||
39a8243f27 | |||
5f50922d32 | |||
1137ca0fce | |||
36f3429ad2 | |||
703092f2c9 | |||
fd75c7c7b4 | |||
8abbd5dacb | |||
ed0fa7e1b7 | |||
15f1245927 | |||
25434e42d0 | |||
d6749589e8 | |||
8fea88879a | |||
d9e778f501 | |||
885b6ffaef | |||
4c64920f45 | |||
7369ea6125 | |||
20b7d34577 | |||
6cc4c33b13 | |||
5abf9a0425 | |||
17a0b27109 | |||
2bcdae4d5d | |||
0244c6d5b8 | |||
bc6be40fdd | |||
8c22b58611 | |||
074fe3ea70 | |||
5666fdefce | |||
e9613b0340 | |||
8a030e8fc4 | |||
9c23bf02bd | |||
8468fe87eb | |||
9617e83d88 | |||
912a30c566 | |||
2cd84da835 | |||
64fad9a394 | |||
3b797b32bc | |||
f6ae48ec70 | |||
61869d7db1 | |||
e2e90a550e | |||
80ceead18d | |||
ed8884e192 | |||
3f6165799f | |||
d2a40d6885 | |||
eb8fc738af | |||
b9e1d917da | |||
f721e80685 | |||
361a115729 | |||
d107b84be4 | |||
4cb967f3ac | |||
6f070319a0 | |||
13edecde6c | |||
75d1230dd1 | |||
779d5462f2 | |||
03757c1fcb | |||
1faee65a68 | |||
f7ab90b93b | |||
a7fa7d748d | |||
2b6d4ff279 | |||
06cea89dae | |||
260ca64e94 | |||
6dc4adfc13 | |||
e727c184ef | |||
412c50b939 | |||
8dcd70edbe | |||
1b383c7285 | |||
e96a90b161 | |||
d64d491f63 | |||
a6da22fa70 | |||
56cf7a6628 | |||
5b71788a84 | |||
39f7aa8457 | |||
c6baee2622 | |||
20f49e8c89 | |||
d6a6e6220a | |||
3b333c37fd | |||
289d577bc1 | |||
00ba937171 | |||
df3560143d | |||
bdeb20f7c9 | |||
1dd35b7d08 | |||
450291b856 | |||
125adb4d32 | |||
13cc58937e | |||
ee6a852996 | |||
2cfe978e1f | |||
0625655456 | |||
39a1f5cfe0 | |||
961fdd861f | |||
28adc03cce | |||
68c482ec32 | |||
a739f89dd1 | |||
5c7042cff3 | |||
255d4634a9 | |||
cb4c2ab824 | |||
4c449124ee | |||
c74536c9b3 | |||
df10ef532f | |||
6e18d18a81 | |||
4bc078b5fd | |||
cf49882e96 | |||
b0c6cf3fc5 | |||
883f51be93 | |||
ad52d783bd | |||
05f9be046f | |||
26aaecc33d | |||
f91138d0a2 | |||
89d89ae1cf | |||
e67fbcdc79 | |||
f4572eedd0 | |||
988b515ad2 | |||
2205a395e7 | |||
108b582f0d | |||
6ebd808e8b | |||
343c1133f4 | |||
fea2044eb8 | |||
6b353ece82 | |||
5b3f40102f | |||
b2ab3de80e | |||
56f6c9c5f6 | |||
39b0c88c76 | |||
1fca8a8b95 | |||
d442494f3a | |||
1f1fe36b89 | |||
d21f04b8b4 | |||
e73e4375b8 | |||
2905b0318d | |||
ab1ecb5ba2 | |||
47b8d16067 | |||
dc020628b5 | |||
bed063eea1 | |||
ed76e52918 | |||
e0f58c615b | |||
a681a2ba02 | |||
856207c154 | |||
00d897f282 | |||
49a09657c5 | |||
38fb51a99e | |||
99a865fb0f | |||
b919dd7271 | |||
9ddf19a1a4 | |||
23353fb77a | |||
8bdfb8df68 | |||
a65a0f03d4 | |||
7322a4e4ef | |||
870be026d8 | |||
e4fc899aca | |||
5412ce276c | |||
6200daa5bb | |||
4207536377 | |||
90e042e30c | |||
4e45e28ea0 |
32
.gitignore
vendored
@ -3,11 +3,11 @@
|
|||||||
*.o
|
*.o
|
||||||
.deps
|
.deps
|
||||||
.libs
|
.libs
|
||||||
|
ABOUT-NLS
|
||||||
ChangeLog
|
ChangeLog
|
||||||
INSTALL
|
INSTALL
|
||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
NEWS
|
|
||||||
aclocal.m4
|
aclocal.m4
|
||||||
autom4te.cache
|
autom4te.cache
|
||||||
config.h
|
config.h
|
||||||
@ -21,8 +21,19 @@ data/gnome-shell.desktop.in
|
|||||||
data/gschemas.compiled
|
data/gschemas.compiled
|
||||||
data/org.gnome.shell.gschema.xml
|
data/org.gnome.shell.gschema.xml
|
||||||
data/org.gnome.shell.gschema.valid
|
data/org.gnome.shell.gschema.valid
|
||||||
data/org.gnome.accessibility.magnifier.gschema.xml
|
docs/reference/*/*.args
|
||||||
data/org.gnome.accessibility.magnifier.gschema.valid
|
docs/reference/*/*.bak
|
||||||
|
docs/reference/*/*.hierarchy
|
||||||
|
docs/reference/*/*.interfaces
|
||||||
|
docs/reference/*/*.prerequisites
|
||||||
|
docs/reference/*/*.sgml
|
||||||
|
docs/reference/*/*.signals
|
||||||
|
docs/reference/*/*.stamp
|
||||||
|
docs/reference/*/*.txt
|
||||||
|
docs/reference/*/*.types
|
||||||
|
docs/reference/*/html/
|
||||||
|
docs/reference/*/xml/
|
||||||
|
gtk-doc.make
|
||||||
js/misc/config.js
|
js/misc/config.js
|
||||||
intltool-extract.in
|
intltool-extract.in
|
||||||
intltool-merge.in
|
intltool-merge.in
|
||||||
@ -32,8 +43,13 @@ m4/
|
|||||||
omf.make
|
omf.make
|
||||||
po/*.gmo
|
po/*.gmo
|
||||||
po/gnome-shell.pot
|
po/gnome-shell.pot
|
||||||
|
po/*.header
|
||||||
|
po/*.sed
|
||||||
|
po/*.sin
|
||||||
po/Makefile.in.in
|
po/Makefile.in.in
|
||||||
|
po/Makevars.template
|
||||||
po/POTFILES
|
po/POTFILES
|
||||||
|
po/Rules-quot
|
||||||
po/stamp-it
|
po/stamp-it
|
||||||
scripts/launcher.pyc
|
scripts/launcher.pyc
|
||||||
src/*.gir
|
src/*.gir
|
||||||
@ -42,8 +58,15 @@ src/*-enum-types.[ch]
|
|||||||
src/*-marshal.[ch]
|
src/*-marshal.[ch]
|
||||||
src/Makefile
|
src/Makefile
|
||||||
src/Makefile.in
|
src/Makefile.in
|
||||||
src/gnomeshell-taskpanel
|
src/calendar-server/org.gnome.Shell.CalendarServer.service
|
||||||
src/gnome-shell
|
src/gnome-shell
|
||||||
|
src/gnome-shell-calendar-server
|
||||||
|
src/gnome-shell-extension-tool
|
||||||
|
src/gnome-shell-hotplug-sniffer
|
||||||
|
src/gnome-shell-jhbuild
|
||||||
|
src/gnome-shell-perf-helper
|
||||||
|
src/gnome-shell-real
|
||||||
|
src/hotplug-sniffer/org.gnome.Shell.HotplugSniffer.service
|
||||||
src/run-js-test
|
src/run-js-test
|
||||||
src/test-recorder
|
src/test-recorder
|
||||||
src/test-recorder.ogg
|
src/test-recorder.ogg
|
||||||
@ -56,3 +79,4 @@ tests/run-test.sh
|
|||||||
xmldocs.make
|
xmldocs.make
|
||||||
*~
|
*~
|
||||||
*.patch
|
*.patch
|
||||||
|
*.sw?
|
||||||
|
@ -3,5 +3,5 @@ E-mail: otaylor@redhat.com
|
|||||||
Userid: otaylor
|
Userid: otaylor
|
||||||
|
|
||||||
Colin Walters
|
Colin Walters
|
||||||
E-mail: walters@redhat.com
|
E-mail: walters@verbum.org
|
||||||
Userid: walters
|
Userid: walters
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Point to our macro directory and pick up user flags from the environment
|
# Point to our macro directory and pick up user flags from the environment
|
||||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||||
|
|
||||||
SUBDIRS = data js src tests po man
|
SUBDIRS = data js src browser-plugin tests po man docs
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
.project \
|
.project \
|
||||||
@ -19,3 +19,5 @@ DIST_EXCLUDE = \
|
|||||||
distcheck-hook:
|
distcheck-hook:
|
||||||
@echo "Checking disted files against files in git"
|
@echo "Checking disted files against files in git"
|
||||||
@$(srcdir)/tools/check-for-missing.py $(srcdir) $(distdir) $(DIST_EXCLUDE)
|
@$(srcdir)/tools/check-for-missing.py $(srcdir) $(distdir) $(DIST_EXCLUDE)
|
||||||
|
|
||||||
|
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
||||||
|
680
NEWS
Normal file
@ -0,0 +1,680 @@
|
|||||||
|
3.3.2
|
||||||
|
=====
|
||||||
|
* Port D-Bus usage in the shell to GDBus [Giovanni, Marc-Antoine, Florian,
|
||||||
|
Jasper, Matthias; #648651, #658078, #663902, #663941]
|
||||||
|
* Message tray
|
||||||
|
- Add right-click option to chats to mute the conversation [Ana; #659962]
|
||||||
|
- Don't steal the focus when popping up under the pointer [Rui; #661358]
|
||||||
|
* Looking Glass
|
||||||
|
- Add alt-Tab completion [Jason; #661054]
|
||||||
|
- Show errors from extensions in the extensions tab [Jasper; #660546]
|
||||||
|
- Allow switching tabs with <Control>PageUp/PageDown
|
||||||
|
- Theme consistently with the rest of the shell [Jason; 650900]
|
||||||
|
* Extension system
|
||||||
|
- Don't try to load disabled extensions at all [Jasper; #661815, #662704]
|
||||||
|
- Enable and disable plugins in a consistent order [Jasper; #661815, #662704]
|
||||||
|
- Add options to enable/disable extensions to gnome-shell-extension-tool
|
||||||
|
[Jasper; #661815]
|
||||||
|
* Adapt to Mutter change to GSettings [Florian, Matthias; #663429]
|
||||||
|
* Allow creating a new workspace by dragging a window or launcher in the
|
||||||
|
middle of two existing ones [Jasper; #646409]
|
||||||
|
* Allow using Alt-Tab while during drag-and-drop and other operations
|
||||||
|
that grab the pointer [Adel; #660457]
|
||||||
|
* Do a better job of finding the right user to authenticate
|
||||||
|
as when showing a PolKit dialog [Matthias; #651547]
|
||||||
|
* Control the D-Bus Eval() method by the developer-tools GSetting which
|
||||||
|
is used for looking glass and screen recorder. [Jasper; #662891]
|
||||||
|
* Fix browser plugin to work under WebKit-based browser [Jasper; #663823]
|
||||||
|
* Fix certain stacking issues with alt-Tab [Jasper; #660650]
|
||||||
|
* Fixes for GLib deprecations [Jasper; #662011]p
|
||||||
|
* Fixes for GTK+ deprecations [Florian, Rico; #662245]p
|
||||||
|
* Fixes for Clutter deprecations [Jasper; #662627]
|
||||||
|
* Visual improvements and UI tweaks [Florian, Jakub, Jasper;
|
||||||
|
#662800, #658096, #662226]
|
||||||
|
* Hard-code "Home" as the name for the home dir, rather than looking
|
||||||
|
it up via GSettings; avoids schema dependency [Cosimo; #559895]
|
||||||
|
* Don't show "Switch User" on single user machines [Florian; #657011]
|
||||||
|
* Generate documentation for St toolkit [Florian]
|
||||||
|
* Improve marking of strings for translation [Matthias, Piotr; #658664]
|
||||||
|
* Networking menu bug fixes [Giovanni; #650007, #651378, #659277, #663278]
|
||||||
|
* Code cleanups and leak fixes to StTextureCache
|
||||||
|
[Jasper, Florian; #660968, #662998]
|
||||||
|
* Code cleanups [Adel, Florian, Jasper; #662238, #663584]
|
||||||
|
* Build fixes [Adel, Colin, Florian, Ming Han]
|
||||||
|
* Misc bug fixes [Adel, Florian, "Fry", Jasper, Giovanni, Ray, Rui, Stefan;
|
||||||
|
#660520, #661029, #661231, #661623, #661921, #662235, #662236, #662502,
|
||||||
|
#662394, #662799, #662969, #663175, #663277, #663815, #663891, #662967]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Matthias Clasen, Piotr Drąg, Adel Gadllah,
|
||||||
|
Rui Matos, Florian Müllner, Marc-Antoine Perennou, Ana Risteska,
|
||||||
|
Jason Siefken, Jakub Steiner, Ray Strode, Jasper St. Pierre, Ming Han Teh,
|
||||||
|
Rico Tzschichholz, Colin Walters, Stefan Zwanenburg
|
||||||
|
|
||||||
|
Translation:
|
||||||
|
Alexander Shopov [bg], Marek Černocký [cs], Mario Blättermann [de],
|
||||||
|
Kostas Papadimas [el], Bruce Cowan [en_GB], Kristjan Schmidt [eo],
|
||||||
|
Jorge González, Daniel Mustieles, Benjamín Valero Espinosa [es],
|
||||||
|
Mattias Põldaru [et], Arash Mousavi [fa], Ville-Pekka Vainio [fi],
|
||||||
|
Fran Diéguez [gl], Yaron Shahrabani [he], Hideki Yamane [ja],
|
||||||
|
Algimantas Margevičius [lt], Kjartan Maraas [nb], Daniel Nylander [se],
|
||||||
|
Matej Urbančič [sl], Praveen Illa [te], Muhammet Kara [tr],
|
||||||
|
Nguyễn Thái Ngọc Duy [vi], Cheng-Chia Tseng [zh_HK, zh_TW]
|
||||||
|
|
||||||
|
3.2.1
|
||||||
|
=====
|
||||||
|
* Restore the IM state on startup - if you were available in when you logged
|
||||||
|
out, then you'll be set available again when you log in.
|
||||||
|
[Florian; #65902, #661485]
|
||||||
|
* Improve searching for contacts in the overview: search more fields,
|
||||||
|
show a more meaningful name, require that all search terms match.
|
||||||
|
[Florian, Matthias; #660580]
|
||||||
|
* Improve search for applications in the overview: take frequency into
|
||||||
|
account and tweak match algorithm [Florian; #623372]
|
||||||
|
* Remove the "Show Password" switch from network password prompts, and
|
||||||
|
move the functionality to a right-click menu [Florian; #658948]
|
||||||
|
* Add context menus with Cut/Paste options to most entries [Florian; #659275]
|
||||||
|
* On screen keyboard:
|
||||||
|
- Show the keyboard immediately when it's turned enabled [Dan; #659743]
|
||||||
|
- Fix problem where keyboard would hide when starting to type
|
||||||
|
in the search entry [Nohemi; #661340]
|
||||||
|
- Fix problem with keyboard hiding when selected accented characters
|
||||||
|
[Nohemi; 661707]
|
||||||
|
* Login mode:
|
||||||
|
- Allow hitting Enter to select the first user [Ray; #657996]
|
||||||
|
- Fix flicker of a fingerprint prompt that could show up [Ray; #660492]
|
||||||
|
- Fix password bullets vanishing during login [Ray; #657894]
|
||||||
|
- Misc bug fixes and visual tweaks [Ray; #659763, #660919, #661479]
|
||||||
|
* Display a caps-lock warning in password entries [Florian; #660806]
|
||||||
|
* Show the state of installed extensions in Looking Glass [Jasper; #660494]
|
||||||
|
* Load user extensions after system ones [Jasper; #661815]
|
||||||
|
* Fix problem with many applications showing extra-large icons in
|
||||||
|
notifications [Marina; #659158]
|
||||||
|
* Fix a problem where alt-Tab had trouble tracking the current
|
||||||
|
application with certain applications such as Emacs. [Dan; #645026]
|
||||||
|
* Fix confusion between different users avatar images [Florian; #660585]
|
||||||
|
* Remove behavior where you could switch workspaces by bumping
|
||||||
|
a dragged window in the overview against a screen edge; it was
|
||||||
|
leftover and just confusing. [Florian; #660838]
|
||||||
|
* Fix long-standing bug where the Dash in the overview could end up mis-sized
|
||||||
|
and run off the screen [Florian; #649248]
|
||||||
|
* Fix automatic launching of applications when media is inserted
|
||||||
|
[Cosimo; #660821]
|
||||||
|
* Fix handling of vertically stacked monitors with NVIDIA drivers
|
||||||
|
[Florian; #661387]
|
||||||
|
* Translation marking fixes [Jasper, Wouter; #660600]
|
||||||
|
* Code cleanups and warning fixes [Adel, Dan, Florian, Jasper;
|
||||||
|
#659822, #659940, #660122, #660358, #660968, #661231]
|
||||||
|
* Small memory leak fixes [Florian, Jasper; #661231]
|
||||||
|
* Misc bug fixes [Adel, Florian, Jasper; #659274, #659861, #660166, #660310,
|
||||||
|
#660397, #660608, #660606, #660674, #660774. #660848, #661151, #661617]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Wouter Bolsterlee, Cosimo Cecchi, Matthias Clasen, Nohemi Fernandez,
|
||||||
|
Adel Gadllah, Florian Müllner, Jasper St. Pierre, Ray Strode, Dan Winship,
|
||||||
|
Marina Zhurakhinskaya
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Tiffany Antopolski [eo], Xandru Armesto [ast], Alexander Shopov,
|
||||||
|
Ivaylo Valkov [bg], Gil Forcada [ca], Carles Ferrando [ca@valencia],
|
||||||
|
Mario Blättermann, Paul Seyfert [de], Bruce Cowan [en_GB],
|
||||||
|
Jorge González, Daniel Mustieles [es], Arash Mousavi [fa], Bruno Brouard [fr],
|
||||||
|
Seán de Búrca [ga], Fran Diéguez [gl], Gabor Kelemen [hu], Luca Ferretti [it],
|
||||||
|
Takayuki Kusano [ja], Changwoo Ryu [ko], Erdal Ronahi [ku],
|
||||||
|
Algimantas Margevičius [lt], Rudolfs Mazurs [lv], Wouter Bolsterlee [nl],
|
||||||
|
Piotr Drąg [pl], Adorilson Bezerra [pt_BR], Yuri Myasoedov [ru],
|
||||||
|
Matej Urbančič [sl], Daniel Nylander [sv], Miroslav Nikolić [sr, sr@latin],
|
||||||
|
Tirumurti Vasudevan [ta], Krishnababu Krothapalli [te], Daniel Korostil [uk],
|
||||||
|
Nguyễn Thái Ngọc Duy [vi], YunQiang Su [zh_CN]
|
||||||
|
|
||||||
|
3.2.0
|
||||||
|
=====
|
||||||
|
* Prevent the fallback on-screen keyboard from showing up while
|
||||||
|
GNOME Shell is running [Dan, #659865]
|
||||||
|
* Disable code to reposition windows around the on-screen keyboard;
|
||||||
|
it wasn't finished or working properly. [Dan; #659643]
|
||||||
|
* Fix interaction between on-screen keyboard and notifications
|
||||||
|
[Dan; #658603]
|
||||||
|
* Fix menu-sizing problems in right-to-left locales. [Florian; #659827]
|
||||||
|
* Update chat icons in the message tray when an avatar image changes
|
||||||
|
[Marina; #659768]
|
||||||
|
* Fix problem with empty notification bubbles being left [Marina; #659862]
|
||||||
|
* Fix problem with chat notifications bouncing when new messages come in.
|
||||||
|
[Marina; #659768]
|
||||||
|
* Fix bug that was causing SIP calls to automatically be accepted in some
|
||||||
|
circumstances [Guillaume; #660084]
|
||||||
|
* Fix string that should have been marked translatable [Frédéric]
|
||||||
|
* Fix a crash that could happen during CSS transitions [Florian; #659676]
|
||||||
|
* Build fixes [Colin, Florian]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Guillaume Desmottes, Florian Müllner, Frédéric Péters, Colin Walters,
|
||||||
|
Dan Winship, Marina Zhurakhinskaya
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Friedel Wolff [af], Nilamdyuti Goswami [as], Ihar Hrachyshka [be],
|
||||||
|
Ivaylo Valkov [bg], Gil Forcada [ca], Carles Ferrando [ca@valencia],
|
||||||
|
Petr Kovar [cz], Mario Blättermann [de], Kris Thomsen [dk],
|
||||||
|
Tiffany Antopolski, Kristjan Schmidt [eo], Daniel Mustieles [es],
|
||||||
|
Inaki Larranaga Murgoitio [eu], Tommi Vainikainen [fi], Bruno Brouard [fr],
|
||||||
|
Fran Dieguez [gl], Yaron Shahrabani [he], Gabor Kelemen [hu],
|
||||||
|
Andika Triwidada [id], Jiro Matsuzawa [ja], Changwoo Ryu [ko],
|
||||||
|
Rudolfs Mazurs [lv], Aurimas Černius [lt], Kjartan Maraas [nb],
|
||||||
|
A S Alam [pa], Piotr Drąg [pl], Duarte Loreto [pt], Djavan Fagundes,
|
||||||
|
Rodolfo Ribeiro Gomes, Gabriel F. Vilar [pt_BR], Yuri Myasoedov [ru],
|
||||||
|
Daniel Nylander [se], Martin Srebotnjak [sl], Michal Štrba [sv],
|
||||||
|
Krishnababu Krothapalli, Praveen Illa [te], Cheng-Chia Tseng [zh_KH, zh_TW]
|
||||||
|
|
||||||
|
3.1.92
|
||||||
|
======
|
||||||
|
|
||||||
|
* Login screen
|
||||||
|
- Add the ability to set a logo at the top of the user list [Ray; #658062]
|
||||||
|
- Add fingerprint reader support [Ray; #657823]
|
||||||
|
- Add a power button offering the choice of Suspend/Restart/Power off
|
||||||
|
[Ray; #657822]
|
||||||
|
- Remove the option to view the current keyboad layout [Matthias; #659164]
|
||||||
|
- Make Control-Alt-Tab work for full keyboard access [Ray; #659177]
|
||||||
|
* Frequently initiate a full garbage collection; Spidermonkey isn't very good
|
||||||
|
at tracking the amount of resources we have allocated so this hopefully will
|
||||||
|
improve memory usage without affecting performance too much [Colin; #659254]
|
||||||
|
* Stop adding a notification when the network connection is lost
|
||||||
|
[Colin; #658954]
|
||||||
|
* When disabling notifications; display a notification
|
||||||
|
"Your chat status will be set to busy" [Florian; #652718]
|
||||||
|
* Fix keynav in network dialogs [Florian; #659133]
|
||||||
|
* Improve calendar styling [Sean; #641135, #651299]
|
||||||
|
* Shrink padding around panel buttons for narrow screens [Dan; #651299]
|
||||||
|
* Allow enabling the onscreen keyboard through the accessibility menu
|
||||||
|
[Dan; #612662]
|
||||||
|
* Fix problem that was causing VPN secret dialogs to be delayed before showing
|
||||||
|
[Florian; #658484]
|
||||||
|
* Make custom-keybindings for the window switcher that don't use alt
|
||||||
|
work correctly [Florian; #645200]
|
||||||
|
* Fix duplicate application icons in the Activities Overview [Colin; #659351]
|
||||||
|
* Bug fixes for dimming windows with attached modal dialogs
|
||||||
|
[Jasper, Owen; #659302, 659634]
|
||||||
|
* Add build-time support for BROWSER_PLUGIN_DIR environment variable
|
||||||
|
[Vincent; #659123]
|
||||||
|
* Build fixes [Vincent; #659194]
|
||||||
|
* Code cleanups and test cases
|
||||||
|
[Adel, Dan, Florian, Jasper; #651299, #658092, #658939]
|
||||||
|
* Misc bug fixes
|
||||||
|
[Adel, Colin, Cosimo, Dan, Florian, Giovanni, Jasper, Ray, Xavier;
|
||||||
|
#651299, #652837, #657249, #658004, #658150, #658239, #658469, #658598,
|
||||||
|
#658605, #659050, #659159, #659210, #659270, #659370, #659633]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Xavier Claessens, Matthias Clasen,
|
||||||
|
Rui Matos, Florian Müllner, Jasper St. Pierre, Owen Taylor,
|
||||||
|
Vincent Untz, Colin Walters, Sean Wilson, Dan Winship
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Ihar Hrachyshka [be], Alexander Shopov, Ivaylo Valkov [bg],
|
||||||
|
Mario Blättermann [de], Jorge González, Daniel Mustieles [es],
|
||||||
|
Arash Mousavi [fa], Ville-Pekka Vainio [fi], Fran Dieguez [gl],
|
||||||
|
Sweta Kothari [gu], Gabor Kelemen [hu], Jiro Matsuzawa [ja],
|
||||||
|
Luca Ferretti [it], Rudolfs Mazurs [lv], Kjartan Maraas [nb], A S Alam [pa],
|
||||||
|
Piotr Drąg [pl], Duarte Loreto [pt], Yuri Myasoedov [ru],
|
||||||
|
Daniel Nylander [se], Matej Urbančič [sl], Miroslav Nikolić [sr, sr@latin],
|
||||||
|
Michal Štrba [sv], Tirumurti Vasudevan [ta], Phương Lê Hoàng [vi],
|
||||||
|
Aron Xu [zh_CN], Chao-Hsiung Liao [zh_HK, zh_TW]
|
||||||
|
|
||||||
|
3.1.91.1
|
||||||
|
========
|
||||||
|
|
||||||
|
* Add a browser plugin - this plugin, tied to extensions.gnome.org,
|
||||||
|
allows users to download and install shell extensions, and enable,
|
||||||
|
disable, and uninstall extensions they already have installed.
|
||||||
|
[Jasper; #658070, #658612]
|
||||||
|
* Improve adding links to URLs in notifications [Dan; #636252]
|
||||||
|
* Remove "connection lost" notifications after reconnecting [Giovanni; #658049]
|
||||||
|
* Hide the onscreen keyboard when leaving a text entry [Dan; #658591]
|
||||||
|
* Fixes for translated strings [Florian; #639987, #644097, #645037]
|
||||||
|
* Bug fixes for network menu [Florian; #658492]
|
||||||
|
* Code cleanup [Dan; #646934]
|
||||||
|
* Build fixes [Javier, Rico]
|
||||||
|
* Misc bug fixes [Emmanuele, Florian, Jasper, Marina, Matthias, Ray;
|
||||||
|
#652837, #658423, #658503, #658525, #658562, #658624, #658640, #658983]
|
||||||
|
|
||||||
|
Conributors:
|
||||||
|
Emmanuele Bassi, Giovanni Campagna, Matthias Clasen, Javier Jardón,
|
||||||
|
Florian Muellner, Jasper St. Pierre, Ray Strode, Rico Tzschichholz,
|
||||||
|
Dan Winship, Marina Zhurakhinskaya
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Ihar Hrachyshka [be], Bruce Cowan [en_GB], Jorge González,
|
||||||
|
Daniel Mustieles [es], Timo Jyrinki [fi], Bruno Brouard, Luc Guillemin,
|
||||||
|
Claude Paroz, Luc Pionchon [fr], Fran Dieguez [gl], Rajesh Ranjan [hi],
|
||||||
|
Andika Triwidada [id], Luca Ferretti [it], Changwoo Ryu [ko],
|
||||||
|
Rudolfs Mazurs [lt], Kjartan Maraas [nb], Manoj Kumar Giri [or],
|
||||||
|
A S Alam [pa], Piotr Drąg [pl], Duarte Loreto [pt], Henrique P. Machado,
|
||||||
|
Gabriel F. Vilar [pt_BR], Daniel Nylander [se], Matej Urbančič [sl],
|
||||||
|
Tirumurti Vasudevan [ta], Yinghua Wang [zh_CN],
|
||||||
|
Chao-Hsiung Liao [zh_HK, zh_TW]
|
||||||
|
|
||||||
|
3.1.91
|
||||||
|
======
|
||||||
|
|
||||||
|
* Fix problem with applications vanishing from alt-Tab when
|
||||||
|
desktop files change. [Colin; #657990]
|
||||||
|
* Fix interaction of on-screen keyboard with run-dialog and
|
||||||
|
Looking Glass console [Dan; #657986]
|
||||||
|
* Add public API for adding and removing search providers
|
||||||
|
[Philippe; #657548, #658113]
|
||||||
|
* Allow changing IM status with scroll wheel [Florian; #657973]
|
||||||
|
* Limit volume slider to 100% [Bastien; #657607]
|
||||||
|
* Change "Do Not Disturb" to "Notifications" in user menu [Florian; #652718]
|
||||||
|
* Switch browser in default favorites to Epiphany [Colin; #650616]
|
||||||
|
* Misc bug fixes [Dan, Florian, Jasper, Marc-Antoine, Rui;
|
||||||
|
#649631, #655069, #656142, #657703, #657759, #658007, #658065, #658176]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Rui Matos, Florian Müllner, Philippe Normand, Marc-Antoine Perennou,
|
||||||
|
Jasper St. Pierre, Colin Walters, Dan Winship
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Ihar Hrachyshka [be], Mario Blättermann [de], Kris Thomsen [da],
|
||||||
|
Jorge González [es], Arash Mousavi [fa], Fran Dieguez [gl],
|
||||||
|
Takayuki Kusano [ja],Aurimas Černius [lt], Kjartan Maraas [nb], A S Alam [pa],
|
||||||
|
Stas Solovey [ru], Daniel Nylander [se], Tirumurti Vasudevan [ta],
|
||||||
|
Chao-Hsiung Liao [zh_HK, zh_TW]
|
||||||
|
|
||||||
|
3.1.90.1
|
||||||
|
========
|
||||||
|
|
||||||
|
* Fix typo that was breaking the "Login Screen" mode [Marc-Antoine]
|
||||||
|
* Fix build with new gobject-introspection [Dan]
|
||||||
|
* Use a better icon for removable devices [Cosimo; #657757]
|
||||||
|
* Add support for asynchronous search provides [Philippe, Jasper, Seif; #655220]
|
||||||
|
* Misc bug fixes [Alex, Guillaume, Jasper; #657657, #657696]
|
||||||
|
* Misc build fixes [Adel; #657697]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Cosimo Cecchi, Guillaume Desmottes, Adel Gadllah, Alexander Larsson, Seif Lotfy,
|
||||||
|
Philippe Normand, Marc-Antoine Perennou, Jasper St. Pierre, Dan Winship
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Jorge González, Daniel Mustieles [es], Stas Solovey [ru]
|
||||||
|
|
||||||
|
3.1.90
|
||||||
|
======
|
||||||
|
* Add an on-screen keyboard that uses Caribou as a backend
|
||||||
|
[Nohemi, Dan; #612662]
|
||||||
|
* Allow searching for people in the overview using libfolks
|
||||||
|
as the backend [Morten; #643018]
|
||||||
|
* Add a "Login Screen" mode to be used when GDM is running; this
|
||||||
|
mode has a stripped down user interface, and also contains the
|
||||||
|
code to display the user list and authentication. [Ray; #657082]
|
||||||
|
* Rework user menu to separate out "Do Not Disturb" from the IM
|
||||||
|
status and to visually match GNOME Contacts. [Florian; #652837]
|
||||||
|
* Implement displaying images such as cover-art in notifications
|
||||||
|
[Neha, Marina; #621009]
|
||||||
|
* Support default actions for notifications [Florian; #655818]
|
||||||
|
* Networking
|
||||||
|
- Stop using nm-applet for dialogs; do them as proper system modal
|
||||||
|
dialogs in the shell code. [Giovanni; #650244]
|
||||||
|
- Fix handling of hidden access points [Giovanni; #646454]
|
||||||
|
* Telepathy integration
|
||||||
|
- Support subscription requests [Guillaume, Xavier; #653941]
|
||||||
|
- Notify on account connection errors [Alban, Jasper, Xavier; #654159]
|
||||||
|
- Allow approving file transfers [Guillaume; #653940]
|
||||||
|
- Improve styling of messages [Jasper; #640271]
|
||||||
|
* Extension system [Jasper; #654770]
|
||||||
|
- Support live enabling and disabling of extensions
|
||||||
|
- Add the ability to install extensions from HTTP
|
||||||
|
- Enhance D-Bus interface for controlling extensions
|
||||||
|
- Collect errors separately for each extension
|
||||||
|
* Add Main.panel.addToStatusArea for extension convenience
|
||||||
|
[Giovanni, Jasper, Marc-Antoine; #653205]
|
||||||
|
* Port to the new gnome-menus API. Clean up and speed up
|
||||||
|
application information loading [Colin; #648149, #656546]
|
||||||
|
* Use the accountsservice library rather than cut-and-pasted GDM code
|
||||||
|
[Florian; #650893]
|
||||||
|
* Add a D-Bus interface to take a screenshot; this will avoid various race
|
||||||
|
conditions with the current gnome-screenshot approach [Adel; #652952]
|
||||||
|
* Show numeric indicators to distinguish duplicate keyboard names
|
||||||
|
[Giovanni; #650128]
|
||||||
|
* Add GNOME Documents to the favorites list [Adel; #657520]
|
||||||
|
* Update the clock immediately on resume from suspend [Colin; #656403]
|
||||||
|
* Remove animation support from StAdjustment [Ray; #657082]
|
||||||
|
* Support configuration of calendar applications via gsettings
|
||||||
|
[Tassilo; #651190]
|
||||||
|
* Don't fade in alt-Tab - wait a bit and show it instantly [Rui; #652346]
|
||||||
|
* Darken workspace background on all workspaces [Rui; #656433]
|
||||||
|
* Improve detection of the starting day of the week [Florian; #649078]
|
||||||
|
* Add StButtonAccessible [Alejandro]
|
||||||
|
* Visual tweaks to match mockups
|
||||||
|
[Allan, Dan, Jasper, Marina; #640271, #655627, #655428, #656732]
|
||||||
|
* Misc bug fixes [Dan, Florian, Giovanni, Guillaume, Jasper, Jeremy, Rui;
|
||||||
|
#645708, #646761, #653119, #654398, #656125, #654707, #654898, #654638,
|
||||||
|
#656335, #657111]
|
||||||
|
* Code cleanups [Colin, Dan, Guillaume, Ray;
|
||||||
|
#652718, #654639, #648651, #655813, #657082]
|
||||||
|
* String tweaks [Jasper, Jeremy; #652984, #640271]
|
||||||
|
* Build fixes [Jasper, Nohemi; #644275, #655812]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Jeremy Bicha, Giovanni Campagna, Xavier Claessens, Alban Crequy,
|
||||||
|
Guillaume Desmottes, Allan Day, Neha Doijode, Nohemi Fernandez,
|
||||||
|
Tassilo Horn, Rui Matos, Morten Mjelva, Florian Müllner, Alejandro Piñeiro,
|
||||||
|
Jasper St. Pierre, Ray Strode, Colin Walters, Dan Winship,
|
||||||
|
Marina Zhurakhinskaya
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Ivaylo Valkov [bg], Mario Blättermann [de], Diego Escalante Urrelo,
|
||||||
|
Jorge González, Daniel Mustieles [es], Arash Mousavi [fa], Fran Dieguez [gl],
|
||||||
|
Yaron Shahrabani [he], Andika Triwidada, Wibiharto [id],
|
||||||
|
Aurimas Černius [lt], Umarzuki Bin Mochlis Moktar [ml], Kjartan Maraas [nb],
|
||||||
|
A S Alam [pa], Daniel Nylander [se], Ngô Chin, Nguyễn Thái Ngọc Duy [vi],
|
||||||
|
Aron Xu [zh_CN], Chao-Hsiung Liao [zh_HK, zh_TW]
|
||||||
|
|
||||||
|
3.1.4
|
||||||
|
=====
|
||||||
|
* Take over inserted media handling and autorun from gnome-session [Cosimo]
|
||||||
|
* Message Tray
|
||||||
|
- Display a count of unread notifications on icons
|
||||||
|
[Jasper, Guillaume; #649356, #654139]
|
||||||
|
- Only remove icons when the sender quits from D-Bus, not when it
|
||||||
|
closes its last window [Neha, Marina; #645764]
|
||||||
|
- Solve problems switching chats between shell and Empathy
|
||||||
|
[Guillaume; #654237]
|
||||||
|
- Fix handling of bad GMarkup in messages [Dan; #650298]
|
||||||
|
- Never show notifications when the screensaver is active [Dan; #654550]
|
||||||
|
* Telepathy integrationpp
|
||||||
|
- Implement Telepathy Debug interface to enable empathy-debugger
|
||||||
|
[Guillaume; #652816]
|
||||||
|
- Allow approving room invitations, and audio/video calls
|
||||||
|
[Guillaume; #653740 #653939]
|
||||||
|
- Send typing notifications [Jonny; #650196]
|
||||||
|
* Fix selection highlighting for light-on-dark entries [Jasper; #643768]
|
||||||
|
* Make control-Return in the overview open a new window [Maxim]
|
||||||
|
* Delay showing the alt-Tab switcher to reduce visual noise when
|
||||||
|
flipping betweeen windows [Dan; #652346]
|
||||||
|
* When we have vertically stacked monitors, put the message tray
|
||||||
|
on the bottom one [Dan; #636963]
|
||||||
|
* Fix various problems with keynav and the Activities button
|
||||||
|
[Dan; #641253 #645759]
|
||||||
|
* Ensure screensaver is locked when switching users [Colin; #654565]
|
||||||
|
* Improve extension creation tool [Jasper; #653206]
|
||||||
|
* Fix compatibility with latest GJS [Giovanni; #654349]
|
||||||
|
* Code cleanups [Adel, Dan, Jasper; #645759 #654577 #654791 #654987]
|
||||||
|
* Misc bug fixes [Richard, Dan, Florian, Giovanni, Jasper, Marc-Antoine, Rui;
|
||||||
|
#647175 #649513 #650452 #651082 #653700 #653989 #654105 #654791 #654267
|
||||||
|
#654269 #654527 #655446]
|
||||||
|
* Build fixes [Florian, Siegfried; #654300]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Guillaume Desmottes, Neha Doijode,
|
||||||
|
Maxim Ermilov, Adel Gadllah, Siegfried-Angel Gevatter Pujals, Richard Hughes,
|
||||||
|
Jonny Lamb, Rui Matos, Florian Müllner, Marc-Antoine Perennou, Colin Walters,
|
||||||
|
Dan Winship, Marina Zhurakhinskaya
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Mario Blättermann, Paul Seyfert [de], Jorge González, Daniel Mustieles [es],
|
||||||
|
Fran Dieguez [gl], Yaron Shahrabani [he], Luca Ferretti [it],
|
||||||
|
Rudolfs Mazurs [lv], Kjartan Maraas [nb], A S Alam [pa], Yuri Kozlov [ru],
|
||||||
|
Michal Štrba, Matej Urbančič [sl]
|
||||||
|
|
||||||
|
3.1.3
|
||||||
|
=====
|
||||||
|
* Fix problem with "user theme extension" breaking the CSS for other
|
||||||
|
extensions [Giovanni; #650971]
|
||||||
|
* Telepathy IM framework integration
|
||||||
|
- Switch to using telepathy-glib rather than talking to
|
||||||
|
Telepathy via D-Bus [Guillaume, Jasper; #645585, #649633, #651138, #651227]
|
||||||
|
- Acknowledge messages when the user clicks on them [Guillaume, #647893]
|
||||||
|
- Fix problem with telepathy icon blinking for incoming messages
|
||||||
|
even though the user has been notified of them [Guillaume; #643594]
|
||||||
|
* Networking
|
||||||
|
- keep wirelesss networks in predictable order [Giovanni; #646580, #652313]
|
||||||
|
- Show unmanaged devices in the menu [Giovanni; #646946]
|
||||||
|
- Fix overflow when too many VPN connections [Giovanni; #651602]
|
||||||
|
* Bluetooth
|
||||||
|
- Show "hardware disabled" when disabled by rfkill [Giovanni; #648048]
|
||||||
|
- Fix bug updating status of devices [Giovanni; #647565]
|
||||||
|
* LookingGlass console:
|
||||||
|
- Add a "Memory" tab [Colin; #650692]
|
||||||
|
- Make escape work from any page [Dan Winship; #647303]
|
||||||
|
- Provide a way to refer to panel items as, e.g.,
|
||||||
|
Main.panel._activities [Dan Winship; #646915]
|
||||||
|
* User menu
|
||||||
|
- Fix problem with suspend menu option locking the screen even when the user
|
||||||
|
disabled that. [Florian; #652327]
|
||||||
|
- Hide "power off..." option if shutdown is disabled via PolicyKit
|
||||||
|
[Florian; #652038]
|
||||||
|
* Track changes to WM_CLASS (fixes problems with LibreOffice tracking)
|
||||||
|
[Colin; #649315]
|
||||||
|
* Remove app tracking workarounds for Firefox and LibreOffice [Colin; #651015]
|
||||||
|
* Use upstream gettext autoconfigury rather than glib version [Javier; #631576]
|
||||||
|
* Show messages in the message tray when an application is fullscreen
|
||||||
|
[Dan Winship; #608667]
|
||||||
|
* Don't autohide the workspace pager if there is more than one workspace
|
||||||
|
[Florian; #652714, #653078, #653142]
|
||||||
|
* Don't always slide out the workspace pager at drag begin [Florian; #652730]
|
||||||
|
* Only offer to remove a favorite app when dragging it's icon [Owen; #642895]
|
||||||
|
* Allow dropping an icon anywhere on a workspace [Adel; #652079]
|
||||||
|
* st-scroll-view: Make the fade effect and offset themable [Jasper; #651813]
|
||||||
|
* Obey the user's preference when running an application in a terminal
|
||||||
|
from the run dialog [Florian; #648422]
|
||||||
|
* Consistently exit overview when launching external applications
|
||||||
|
[Colin; #653095]
|
||||||
|
* Adapt to changes in GJS for how GObject APIs are bound
|
||||||
|
[Alex, Colin, Florian, Jasper, Marc-Antoine; #649981, #652597]
|
||||||
|
* Fix problems with scrolling in overflow for alt-Tab switcher
|
||||||
|
[Dan Winship, Adel; #647807]
|
||||||
|
* Mark relationships between labels and actors for accessibility [Alejandro]
|
||||||
|
* Add org.gnome.shell.enabled-extensions complementing disabled-extensions
|
||||||
|
GSetting [Tassilo; #651088]
|
||||||
|
* Visual tweaks [Jakub, Jasper; #646261, #652715]
|
||||||
|
* Switch to building against clutter-1.7 with independent Cogl [Adel; #653397]
|
||||||
|
* Code cleanups [Colin, Dan Winship, Florian; #633620, #645031, #648755, #648758,
|
||||||
|
#648760, #649203, #649517, #650317, #652730]
|
||||||
|
* Memory leak fixes [Colin, Maxim; #649508, #650934]
|
||||||
|
* Build Fixes [Colin, Dan Winship, Florian, Ionut, Morten, Owen, Sean; #647395,
|
||||||
|
#648006, #650869, #653199, #653275
|
||||||
|
* Miscellaneous bug fixes [Adam, Adel, Dan Williams, Dan Winship, Florian,
|
||||||
|
Ionut, Jasper, Maxim, Ray; #620105, #639459, #641570, #642793, #643513,
|
||||||
|
#645848, #646919, #647186, #648305, #648410, #648562, #648894, #649001,
|
||||||
|
#645990, #647893, #647907, #651012, #651086, #651606, #651569, #651866,
|
||||||
|
#652388, #653511]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Ionut Biru, Giovanni Campagna, Guillaume Desmottes, Adam Dingle,
|
||||||
|
Maxim Ermilov, Adel Gadllah, Tassilo Horn, Javier Jardón, Jonny Lamb,
|
||||||
|
Alexander Larsson, Rui Matos, Morten Mjelva, Florian Müllner,
|
||||||
|
Marc-Antoine Perennou, Alejandro Piñeiro, Jasper St. Pierre, Jakub Steiner,
|
||||||
|
Ray Strode, Owen Taylor, Colin Walters, Dan Williams, Sean Wilson, Dan Winship
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Daniel Martinez Cucalon [ar], Ihar Hrachyshka [be], Carles Ferrando,
|
||||||
|
Gil Forcada, Sílvia Miranda [ca], Kristjan Schmidt [eo], Jorge González,
|
||||||
|
Daniel Mustieles [es], Seán de Búrca [ga], Fran Diéguez [gl],
|
||||||
|
Yaron Shahrabani [he], Kjartan Maraas [nb], Misha Shnurapet,
|
||||||
|
Yuri Myasoedov [ru], Daniel Nylander [se], Peter Mráz [sk],
|
||||||
|
Matej Urbančič [sl], Krishnababu Krothapalli [te], Daniel Korostil [uk],
|
||||||
|
Aron Xu [zh_CN]
|
||||||
|
|
||||||
|
3.0.2
|
||||||
|
=====
|
||||||
|
* Network Menu [Dan Williams]
|
||||||
|
- Fix connecting to WPA2 Enterprise access points
|
||||||
|
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=648171
|
||||||
|
- Show the mobile broadband wizard when selecting 3G network
|
||||||
|
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=649318
|
||||||
|
- Miscellaneous bug fixes
|
||||||
|
648648, 650124
|
||||||
|
* Fix duplicate icons in the application browser [Owen]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=648739
|
||||||
|
* Make clicking anywhere on the volume icon slider work [Giovanni]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646660
|
||||||
|
* Fix a case where activating and clicking the hot corner
|
||||||
|
at the same time could result in immediately leaving the
|
||||||
|
overview [Rui]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=649427
|
||||||
|
* Fix a case where applications became misordered in Alt-Tab [Jasper]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=643302
|
||||||
|
* Fix a bug where messages you send could show up in
|
||||||
|
notifications as if someone else sent them [Jonny]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=650219
|
||||||
|
* Memory leak fixes [Colin, Maxim]
|
||||||
|
642652, 649508, 649497
|
||||||
|
* Miscellaneous minor bug fixes [Adel, Christopher, Jasper]
|
||||||
|
649596, 648765, 648983, 649632
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Christopher Aillon, Giovanni Campagna, Maxim Ermilov,
|
||||||
|
Adel Gadllah, Jonny Lamb, Rui Matos, Jasper St. Pierre,
|
||||||
|
Owen Taylor, Colin Walters, Dan Williams
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Arash Mousavi [fa], Seán de Búrca [ga], Timo Jyrinki [fi],
|
||||||
|
Sigurd Gartmann [nb], Daniel Nylander [se], Peter Mráz [sl],
|
||||||
|
Abduxukur Abdurixit [ug], Nguyễn Thái Ngọc Duy [vi]
|
||||||
|
|
||||||
|
3.0.1
|
||||||
|
=====
|
||||||
|
|
||||||
|
* Network menu
|
||||||
|
- Fix problems updating the menu for mobile broadband devices [Giovanni]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646395
|
||||||
|
- Fix missing device descriptions with multiple devices of the
|
||||||
|
same type [Giovanni]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646074
|
||||||
|
- Label ad-hoc neworks with an appropriate icon [Dan]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646141
|
||||||
|
- Fix displaying some devices states as "invalid" [Dan]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646946
|
||||||
|
- Fix problems with access points that don't report a SSID [Giovanni]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=647040
|
||||||
|
- Miscellaneous minor bug fixes [Dan, Giovanni, Owen]
|
||||||
|
645981, 646558, 646443, 646708, 646968
|
||||||
|
* Application menu and icon
|
||||||
|
- Fix bug where application menu icon was missing at GNOME Shell
|
||||||
|
startup. [Florian]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=644122
|
||||||
|
- Fix missing application menu for dialog windows [Colin]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=647082
|
||||||
|
- When launching an application through an alternate launcher
|
||||||
|
(like for a System Settings pane), association the windows with
|
||||||
|
the application, not the launcher. [Colin]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646689
|
||||||
|
* Activities overview
|
||||||
|
- Load the applications view incrementally to avoid potentially freezing
|
||||||
|
for multiple seconds [Colin]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=647778
|
||||||
|
- Fix bug where package installation while the overview
|
||||||
|
was up could result in a corrupted application display. [Giovanni]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=645801
|
||||||
|
- Fix dragging from the search results to launch apps and docs [Florian]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=645990
|
||||||
|
- Fix flickering of selection when searching in the overview [Florian]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646019
|
||||||
|
- Fix bug when typing into the search box when text was already
|
||||||
|
selected [Nohemi]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=636341
|
||||||
|
* Fix layout of notifications for right-to-left languages [Florian]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646921
|
||||||
|
* Remove a confusing special case where Alt-Tab sometimes switched
|
||||||
|
to a different window of the same application rather than to
|
||||||
|
a different application. [Rui]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=648132
|
||||||
|
* Fix a crash that could happen when a window was opened on a
|
||||||
|
workspace that was immediately removed [Dan]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=648132
|
||||||
|
* Fix keyboard navigation in logout/reboot dialogs [Dan]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646740
|
||||||
|
* Fix missing inspector icon in Looking Glass console [Dan]
|
||||||
|
* Miscellaneous minor bug fixes [Adel, Colin, Dan, Florian, Nohemi]
|
||||||
|
645648, 646205, 646257, 646855, 647098, 646730
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Nohemi Fernandez, Adel Gadllah, Rui Matos, Florian Müllner,
|
||||||
|
Owen Taylor, Colin Walters, Dan Winship
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Hendrik Richter [de], Jorge González [es], Arash Mousavi [fa],
|
||||||
|
Fran Diéguez [gl], Jiro Matsuzawa [ja], Piotr Drąg [pl], Daniel Nylander [sv],
|
||||||
|
Sira Nokyoongtong [th], Muhammet Kara [tr], Nguyễn Thái Ngọc Duy [vi],
|
||||||
|
Aron Xu [zh_CN], Chao-Hsiung Liao [zh_HK, zh_TW]
|
||||||
|
|
||||||
|
3.0.0.2
|
||||||
|
=======
|
||||||
|
|
||||||
|
* Fix missing import that was preventing extensions from loading.
|
||||||
|
[Maxim Ermilov]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646333
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Timo Jyrinki [fi]
|
||||||
|
|
||||||
|
3.0.0.1
|
||||||
|
=======
|
||||||
|
|
||||||
|
* Fix problem with stuck event handling if network menu pops down while
|
||||||
|
user is using the scrollbar. [Owen Taylor]
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=646825
|
||||||
|
|
||||||
|
Contributors to GNOME Shell 3.0
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
Josh Adams, Kiyoshi Aman, Nuno Araujo, Emmanuele Bassi, Dirk-Jan C. Binnema,
|
||||||
|
Wouter Bolsterlee, Raphael Bosshard, Milan Bouchet-Valat, Christina Boumpouka,
|
||||||
|
Mathieu Bridon, Alban Browaeys, Phil Bull, Micro Cai, Giovanni Campagna,
|
||||||
|
Cosimo Cecchi, Tor-björn Claesson, Matthias Clasen, Jason D. Clinton,
|
||||||
|
Frederic Crozat, Guillaume Desmottes, Sander Dijkhuis, Neha Doijode,
|
||||||
|
Maxim Ermilov, Diego Escalante Urrelo, Luca Ferretti, Steve Frécinaux,
|
||||||
|
Takao Fujiwara, Adel Gadllah, Vadim Girlin, Nick Glynn, Guido Günther,
|
||||||
|
Leon Handreke, Lex Hider, Richard Hughes, Javier Jardón, Abderrahim Kitouni,
|
||||||
|
Andre Klapper, Alexander Larsson, Nickolas Lloyd, Ryan Lortie, Kjartan Maraas,
|
||||||
|
Koop Mast, Rui Matos, Jonathan Matthew, William Jon McCann, Morten Mjelva,
|
||||||
|
Federico Mena Quintero, Florian Müllner, Jon Nettleton, Hellyna Ng,
|
||||||
|
Discardi Nicola, Carlos Martín Nieto, Bastien Nocera, Bill Nottingham,
|
||||||
|
Matt Novenstern, Marc-Antoine Perennou, Neil Perry, Frédéric Péters,
|
||||||
|
Alejandro Piñeiro, Siegfried-Angel Gevatter Pujals, "res", Neil Roberts,
|
||||||
|
"Sardem FF7", Florian Scandella, Joseph Scheuhammer, Christian Schramm,
|
||||||
|
Gustavo Noronha Silva, Jasper St. Pierre, Eric Springer, Jakub Steiner,
|
||||||
|
Jonathan Strander, Ray Strode, Owen Taylor, Rico Tzschichholz,
|
||||||
|
Sergey V. Udaltsov, Daiki Ueno, Vincent Untz, Marcelo Jorge Vieira,
|
||||||
|
Mads Villadsen, Colin Walters, Dan Winship, William Wolf, Thomas Wood,
|
||||||
|
Pierre Yager, David Zeuthen, Marina Zhurakhinskaya
|
||||||
|
|
||||||
|
Design:
|
||||||
|
|
||||||
|
Allan Day, William Jon McCann, Jeremy Perry, Jakub Steiner
|
||||||
|
2008 Boston GNOME design hackfest participants (especially Neil J. Patel
|
||||||
|
for turning the resulting sketches into our first mockups.)
|
||||||
|
Everybody on irc.gnome.org:#gnome-design
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
|
||||||
|
Friedel Wolff (af), Khaled Hosny (ar), Ivaylo Valkov (bg), Jamil Ahmed (bn)
|
||||||
|
Runa Bhattacharjee (bn_IN), Gil Forcada, Siegfried-Angel Gevatter Pujals,
|
||||||
|
Jordi Serratosa (ca), Andre Klapper, Petr Kovar (cs), Kenneth Nielsen,
|
||||||
|
Kris Thomsen (da), Mario Blättermann, Hendrik Brandt, Christian Kirbach,
|
||||||
|
Hendrik Richter, Wolfgang Stöggl (de), Michael Kotsarinis, Kostas Papadimas,
|
||||||
|
Jennie Petoumenou, Sterios Prosiniklis, Fotis Tsamis, Simos Xenitellis (el),
|
||||||
|
Bruce Cowan, Philip Withnall (en_GB), Jorge Gonzalez, Daniel Mustieles (es),
|
||||||
|
Mattias Põldaru, Ivar Smolin (et), Inaki Larranaga Murgoitio (eu),
|
||||||
|
Mahyar Moghimi (fa), Timo Jyrinki (fi), Cyril Arnaud, Bruno Brouard,
|
||||||
|
Pablo Martin-Gomez, Claude Paroz, Frédéric Peters (fr), Seán de Búrca (ga)
|
||||||
|
Francisco Diéguez, Antón Méixome (gl), Sweta Kothari (gu), Liel Fridman,
|
||||||
|
Yaron Shahrabani (he), Rajesh Ranjan (hi), Gabor Kelemen (hu), Milo Casagrande,
|
||||||
|
Luca Ferretti (it), Dirgita, Andika Triwidada (id), Takayuki KUSANO,
|
||||||
|
Takayoshi OKANO, Kiyotaka NISHIBORI, Futoshi NISHIO (ja), Shankar Prasad (kn),
|
||||||
|
Young-Ho Cha, Changwoo Ryu (ko), Žygimantas Beručka, Gintautas Miliauskas (lt),
|
||||||
|
Rudolfs Mazurs (lv), Sandeep Shedmake (mr), Kjartan Maraas (nb),
|
||||||
|
Wouter Bolsterlee, Sander Dijkhuis, Reinout van Schouwen (nl),
|
||||||
|
Torstein Winterseth (nn), A S Alam (pa), Tomasz Dominikowski, Piotr Drąg (pl),
|
||||||
|
Duarte Loreto (pt), Felipe Borges, Rodrigo Padula de Oliveira,
|
||||||
|
Rodrigo L. M. Flores, Amanda Magalhães, Og B. Maciel, Gabriel F. Vilar,
|
||||||
|
Jonh Wendell (pt_BR), Lucian Adrian Grijincu, Daniel Șerbănescu (ro),
|
||||||
|
Sergey V. Kovylov, Andrey Korzinev, Yuri Myasoedov, Marina Zhurakhinskaya (ru),
|
||||||
|
Daniel Nylander (se), Matej Urbančič, Andrej Žnidaršič (sl),
|
||||||
|
Miloš Popović (sr, sr@latin), Miroslav Nikolić (sr), Tirumurti Vasudevan (ta),
|
||||||
|
Sira Nokyoongtong (th), Baris Cicek (tr), Abduxukur Abdurixit,
|
||||||
|
Gheyret T. Kenji (ug), Maxim V. Dziumanenko, Daniel Korostil (uk),
|
||||||
|
Nguyễn Thái Ngọc Duy (vi), Jessica Ban, 'jiero', Wei Li, YunQiang Su, Ray Wang,
|
||||||
|
Aron Xu (zh_CN), Chao-Hsiung Liao (zh_HK, zh_TW)
|
21
browser-plugin/Makefile.am
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
mozillalibdir = $(BROWSER_PLUGIN_DIR)
|
||||||
|
|
||||||
|
mozillalib_LTLIBRARIES = libgnome-shell-browser-plugin.la
|
||||||
|
|
||||||
|
libgnome_shell_browser_plugin_la_LDFLAGS = -module -avoid-version -no-undefined
|
||||||
|
|
||||||
|
libgnome_shell_browser_plugin_la_LIBADD = \
|
||||||
|
$(BROWSER_PLUGIN_LIBS)
|
||||||
|
|
||||||
|
libgnome_shell_browser_plugin_la_SOURCES = \
|
||||||
|
browser-plugin.c \
|
||||||
|
npapi/npapi.h \
|
||||||
|
npapi/npfunctions.h \
|
||||||
|
npapi/npruntime.h \
|
||||||
|
npapi/nptypes.h
|
||||||
|
|
||||||
|
libgnome_shell_browser_plugin_la_CFLAGS = \
|
||||||
|
$(BROWSER_PLUGIN_CFLAGS) \
|
||||||
|
-DG_DISABLE_DEPRECATED \
|
||||||
|
-DG_LOG_DOMAIN=\"GnomeShellBrowserPlugin\"
|
17
browser-plugin/README
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
The GNOME Shell Browser Plugin provides integration with gnome-shell and the
|
||||||
|
corresponding extensions repository, codenamed "SweetTooth". The plugin allows
|
||||||
|
the extensions repository to provide good integration, letting the website
|
||||||
|
know which extensions are enabled and disabled, and allowing the website to
|
||||||
|
enable, disable and install them.
|
||||||
|
|
||||||
|
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
|
||||||
|
product.
|
||||||
|
|
||||||
|
License
|
||||||
|
=======
|
||||||
|
The GNOME Shell Browser Plugin, like GNOME Shell itself is distributed under
|
||||||
|
the GNU General Public License, version 2 or later. The plugin also contains
|
||||||
|
header files from the "NPAPI SDK" project, tri-licensed under MPL 1.1, GPL 2.0
|
||||||
|
and LGPL 2.1. These headers are third-party sources and can be retrieved from:
|
||||||
|
|
||||||
|
http://code.google.com/p/npapi-sdk/
|
826
browser-plugin/browser-plugin.c
Normal file
@ -0,0 +1,826 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||||
|
* Giovanni Campagna <scampa.giovanni@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define XP_UNIX 1
|
||||||
|
|
||||||
|
#include "npapi/npapi.h"
|
||||||
|
#include "npapi/npruntime.h"
|
||||||
|
#include "npapi/npfunctions.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <json-glib/json-glib.h>
|
||||||
|
|
||||||
|
#define ORIGIN "extensions.gnome.org"
|
||||||
|
#define PLUGIN_NAME "Gnome Shell Integration"
|
||||||
|
#define PLUGIN_DESCRIPTION "This plugin provides integration with Gnome Shell " \
|
||||||
|
"for live extension enabling and disabling. " \
|
||||||
|
"It can be used only by extensions.gnome.org"
|
||||||
|
#define PLUGIN_MIME_STRING "application/x-gnome-shell-integration::Gnome Shell Integration Dummy Content-Type";
|
||||||
|
|
||||||
|
#define PLUGIN_API_VERSION 1
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GDBusProxy *proxy;
|
||||||
|
} PluginData;
|
||||||
|
|
||||||
|
static NPNetscapeFuncs funcs;
|
||||||
|
|
||||||
|
static inline gchar *
|
||||||
|
get_string_property (NPP instance,
|
||||||
|
NPObject *obj,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
NPVariant result = { NPVariantType_Void };
|
||||||
|
NPString result_str;
|
||||||
|
gchar *result_copy;
|
||||||
|
|
||||||
|
result_copy = NULL;
|
||||||
|
|
||||||
|
if (!funcs.getproperty (instance, obj,
|
||||||
|
funcs.getstringidentifier (name),
|
||||||
|
&result))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!NPVARIANT_IS_STRING (result))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
result_str = NPVARIANT_TO_STRING (result);
|
||||||
|
result_copy = g_strndup (result_str.UTF8Characters, result_str.UTF8Length);
|
||||||
|
|
||||||
|
out:
|
||||||
|
funcs.releasevariantvalue (&result);
|
||||||
|
return result_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
check_origin_and_protocol (NPP instance)
|
||||||
|
{
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
NPError error;
|
||||||
|
NPObject *window = NULL;
|
||||||
|
NPVariant document = { NPVariantType_Void };
|
||||||
|
NPVariant location = { NPVariantType_Void };
|
||||||
|
gchar *hostname = NULL;
|
||||||
|
gchar *protocol = NULL;
|
||||||
|
|
||||||
|
error = funcs.getvalue (instance, NPNVWindowNPObject, &window);
|
||||||
|
if (error != NPERR_NO_ERROR)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!funcs.getproperty (instance, window,
|
||||||
|
funcs.getstringidentifier ("document"),
|
||||||
|
&document))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!NPVARIANT_IS_OBJECT (document))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!funcs.getproperty (instance, NPVARIANT_TO_OBJECT (document),
|
||||||
|
funcs.getstringidentifier ("location"),
|
||||||
|
&location))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!NPVARIANT_IS_OBJECT (document))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
hostname = get_string_property (instance,
|
||||||
|
NPVARIANT_TO_OBJECT (location),
|
||||||
|
"hostname");
|
||||||
|
|
||||||
|
if (g_strcmp0 (hostname, ORIGIN))
|
||||||
|
{
|
||||||
|
g_debug ("origin does not match, is %s",
|
||||||
|
hostname);
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol = get_string_property (instance,
|
||||||
|
NPVARIANT_TO_OBJECT (location),
|
||||||
|
"protocol");
|
||||||
|
|
||||||
|
if (g_strcmp0 (protocol, "https:") != 0)
|
||||||
|
{
|
||||||
|
g_debug ("protocol does not match, is %s",
|
||||||
|
protocol);
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_free (protocol);
|
||||||
|
g_free (hostname);
|
||||||
|
|
||||||
|
funcs.releasevariantvalue (&location);
|
||||||
|
funcs.releasevariantvalue (&document);
|
||||||
|
|
||||||
|
if (window != NULL)
|
||||||
|
funcs.releaseobject (window);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =============== public entry points =================== */
|
||||||
|
|
||||||
|
NPError
|
||||||
|
NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
|
||||||
|
{
|
||||||
|
/* global initialization routine, called once when plugin
|
||||||
|
is loaded */
|
||||||
|
|
||||||
|
g_debug ("plugin loaded");
|
||||||
|
|
||||||
|
memcpy (&funcs, pfuncs, sizeof (funcs));
|
||||||
|
|
||||||
|
plugin->size = sizeof(NPPluginFuncs);
|
||||||
|
plugin->newp = NPP_New;
|
||||||
|
plugin->destroy = NPP_Destroy;
|
||||||
|
plugin->getvalue = NPP_GetValue;
|
||||||
|
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError
|
||||||
|
NP_Shutdown(void)
|
||||||
|
{
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
NP_GetMIMEDescription(void)
|
||||||
|
{
|
||||||
|
return PLUGIN_MIME_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError
|
||||||
|
NP_GetValue(void *instance,
|
||||||
|
NPPVariable variable,
|
||||||
|
void *value)
|
||||||
|
{
|
||||||
|
switch (variable) {
|
||||||
|
case NPPVpluginNameString:
|
||||||
|
*(char**)value = PLUGIN_NAME;
|
||||||
|
break;
|
||||||
|
case NPPVpluginDescriptionString:
|
||||||
|
*(char**)value = PLUGIN_DESCRIPTION;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError
|
||||||
|
NPP_New(NPMIMEType mimetype,
|
||||||
|
NPP instance,
|
||||||
|
uint16_t mode,
|
||||||
|
int16_t argc,
|
||||||
|
char **argn,
|
||||||
|
char **argv,
|
||||||
|
NPSavedData *saved)
|
||||||
|
{
|
||||||
|
/* instance initialization function */
|
||||||
|
PluginData *data;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_debug ("plugin created");
|
||||||
|
|
||||||
|
if (!check_origin_and_protocol (instance))
|
||||||
|
return NPERR_GENERIC_ERROR;
|
||||||
|
|
||||||
|
data = g_slice_new (PluginData);
|
||||||
|
instance->pdata = data;
|
||||||
|
|
||||||
|
data->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||||
|
G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
NULL, /* interface info */
|
||||||
|
"org.gnome.Shell",
|
||||||
|
"/org/gnome/Shell",
|
||||||
|
"org.gnome.Shell",
|
||||||
|
NULL, /* GCancellable */
|
||||||
|
&error);
|
||||||
|
if (!data->proxy)
|
||||||
|
{
|
||||||
|
/* ignore error if the shell is not running, otherwise warn */
|
||||||
|
if (error->domain != G_DBUS_ERROR ||
|
||||||
|
error->code != G_DBUS_ERROR_NAME_HAS_NO_OWNER)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to set up Shell proxy: %s", error->message);
|
||||||
|
}
|
||||||
|
g_clear_error (&error);
|
||||||
|
return NPERR_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_debug ("plugin created successfully");
|
||||||
|
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError
|
||||||
|
NPP_Destroy(NPP instance,
|
||||||
|
NPSavedData **saved)
|
||||||
|
{
|
||||||
|
/* instance finalization function */
|
||||||
|
|
||||||
|
PluginData *data = instance->pdata;
|
||||||
|
|
||||||
|
g_debug ("plugin destroyed");
|
||||||
|
|
||||||
|
g_object_unref (data->proxy);
|
||||||
|
|
||||||
|
g_slice_free (PluginData, data);
|
||||||
|
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =================== scripting interface =================== */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
NPObject parent;
|
||||||
|
NPP instance;
|
||||||
|
GDBusProxy *proxy;
|
||||||
|
NPObject *listener;
|
||||||
|
gint signal_id;
|
||||||
|
} PluginObject;
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_shell_signal (GDBusProxy *proxy,
|
||||||
|
gchar *sender_name,
|
||||||
|
gchar *signal_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
PluginObject *obj = user_data;
|
||||||
|
|
||||||
|
if (strcmp (signal_name, "ExtensionStatusChanged") == 0)
|
||||||
|
{
|
||||||
|
gchar *uuid;
|
||||||
|
gint32 status;
|
||||||
|
gchar *error;
|
||||||
|
NPVariant args[3];
|
||||||
|
NPVariant result;
|
||||||
|
|
||||||
|
g_variant_get (parameters, "(sis)", &uuid, &status, &error);
|
||||||
|
STRINGZ_TO_NPVARIANT (uuid, args[0]);
|
||||||
|
INT32_TO_NPVARIANT (status, args[1]);
|
||||||
|
STRINGZ_TO_NPVARIANT (error, args[2]);
|
||||||
|
|
||||||
|
funcs.invokeDefault (obj->instance, obj->listener,
|
||||||
|
args, 3, &result);
|
||||||
|
|
||||||
|
funcs.releasevariantvalue (&result);
|
||||||
|
g_free (uuid);
|
||||||
|
g_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NPObject *
|
||||||
|
plugin_object_allocate (NPP instance,
|
||||||
|
NPClass *klass)
|
||||||
|
{
|
||||||
|
PluginData *data = instance->pdata;
|
||||||
|
PluginObject *obj = g_slice_new0 (PluginObject);
|
||||||
|
|
||||||
|
obj->instance = instance;
|
||||||
|
obj->proxy = g_object_ref (data->proxy);
|
||||||
|
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
|
||||||
|
G_CALLBACK (on_shell_signal), obj);
|
||||||
|
|
||||||
|
g_debug ("plugin object created");
|
||||||
|
|
||||||
|
return (NPObject*)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
plugin_object_deallocate (NPObject *npobj)
|
||||||
|
{
|
||||||
|
PluginObject *obj = (PluginObject*)npobj;
|
||||||
|
|
||||||
|
g_signal_handler_disconnect (obj->proxy, obj->signal_id);
|
||||||
|
g_object_unref (obj->proxy);
|
||||||
|
|
||||||
|
if (obj->listener)
|
||||||
|
funcs.releaseobject (obj->listener);
|
||||||
|
|
||||||
|
g_debug ("plugin object destroyed");
|
||||||
|
|
||||||
|
g_slice_free (PluginObject, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NPIdentifier api_version_id;
|
||||||
|
static NPIdentifier shell_version_id;
|
||||||
|
static NPIdentifier get_info_id;
|
||||||
|
static NPIdentifier list_extensions_id;
|
||||||
|
static NPIdentifier enable_extension_id;
|
||||||
|
static NPIdentifier install_extension_id;
|
||||||
|
static NPIdentifier uninstall_extension_id;
|
||||||
|
static NPIdentifier onextension_changed_id;
|
||||||
|
static NPIdentifier get_errors_id;
|
||||||
|
|
||||||
|
static bool
|
||||||
|
plugin_object_has_method (NPObject *npobj,
|
||||||
|
NPIdentifier name)
|
||||||
|
{
|
||||||
|
return (name == get_info_id ||
|
||||||
|
name == list_extensions_id ||
|
||||||
|
name == enable_extension_id ||
|
||||||
|
name == install_extension_id ||
|
||||||
|
name == uninstall_extension_id ||
|
||||||
|
name == get_errors_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
uuid_is_valid (const gchar *uuid)
|
||||||
|
{
|
||||||
|
gsize i;
|
||||||
|
|
||||||
|
for (i = 0; uuid[i]; i ++)
|
||||||
|
{
|
||||||
|
gchar c = uuid[i];
|
||||||
|
if (c < 32 || c >= 127)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '&':
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
case '/':
|
||||||
|
case '\\':
|
||||||
|
return FALSE;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
jsonify_variant (GVariant *variant,
|
||||||
|
NPVariant *result)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
GVariant *real_value;
|
||||||
|
JsonNode *root;
|
||||||
|
JsonGenerator *generator;
|
||||||
|
gsize json_length;
|
||||||
|
gchar *json;
|
||||||
|
gchar *buffer;
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
/* DBus methods can return multiple values,
|
||||||
|
* but we're only interested in the first. */
|
||||||
|
g_variant_get (variant, "(@*)", &real_value);
|
||||||
|
|
||||||
|
root = json_gvariant_serialize (real_value);
|
||||||
|
|
||||||
|
generator = json_generator_new ();
|
||||||
|
json_generator_set_root (generator, root);
|
||||||
|
json = json_generator_to_data (generator, &json_length);
|
||||||
|
|
||||||
|
buffer = funcs.memalloc (json_length + 1);
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
ret = FALSE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy (buffer, json);
|
||||||
|
|
||||||
|
STRINGN_TO_NPVARIANT (buffer, json_length, *result);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_variant_unref (variant);
|
||||||
|
g_variant_unref (real_value);
|
||||||
|
json_node_free (root);
|
||||||
|
g_free (json);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_list_extensions (PluginObject *obj,
|
||||||
|
NPVariant *result)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GVariant *res;
|
||||||
|
|
||||||
|
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||||
|
"ListExtensions",
|
||||||
|
NULL, /* parameters */
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1, /* timeout */
|
||||||
|
NULL, /* cancellable */
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to retrieve extension list: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonify_variant (res, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_enable_extension (PluginObject *obj,
|
||||||
|
NPString uuid,
|
||||||
|
gboolean enabled)
|
||||||
|
{
|
||||||
|
const gchar *uuid_str = uuid.UTF8Characters;
|
||||||
|
if (!uuid_is_valid (uuid_str))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_dbus_proxy_call (obj->proxy,
|
||||||
|
(enabled ? "EnableExtension" : "DisableExtension"),
|
||||||
|
g_variant_new ("(s)", uuid_str),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1, /* timeout */
|
||||||
|
NULL, /* cancellable */
|
||||||
|
NULL, /* callback */
|
||||||
|
NULL /* user_data */);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_install_extension (PluginObject *obj,
|
||||||
|
NPString uuid,
|
||||||
|
NPString version_tag)
|
||||||
|
{
|
||||||
|
const gchar *uuid_str = uuid.UTF8Characters;
|
||||||
|
if (!uuid_is_valid (uuid_str))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_dbus_proxy_call (obj->proxy,
|
||||||
|
"InstallRemoteExtension",
|
||||||
|
g_variant_new ("(ss)",
|
||||||
|
uuid_str,
|
||||||
|
version_tag.UTF8Characters),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1, /* timeout */
|
||||||
|
NULL, /* cancellable */
|
||||||
|
NULL, /* callback */
|
||||||
|
NULL /* user_data */);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_uninstall_extension (PluginObject *obj,
|
||||||
|
NPString uuid,
|
||||||
|
NPVariant *result)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GVariant *res;
|
||||||
|
const gchar *uuid_str;
|
||||||
|
|
||||||
|
uuid_str = uuid.UTF8Characters;
|
||||||
|
if (!uuid_is_valid (uuid_str))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||||
|
"UninstallExtension",
|
||||||
|
g_variant_new ("(s)",
|
||||||
|
uuid_str),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1, /* timeout */
|
||||||
|
NULL, /* cancellable */
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to uninstall extension: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonify_variant (res, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_get_info (PluginObject *obj,
|
||||||
|
NPString uuid,
|
||||||
|
NPVariant *result)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GVariant *res;
|
||||||
|
const gchar *uuid_str;
|
||||||
|
|
||||||
|
uuid_str = uuid.UTF8Characters;
|
||||||
|
if (!uuid_is_valid (uuid_str))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||||
|
"GetExtensionInfo",
|
||||||
|
g_variant_new ("(s)", uuid_str),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1, /* timeout */
|
||||||
|
NULL, /* cancellable */
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to retrieve extension metadata: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonify_variant (res, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_get_errors (PluginObject *obj,
|
||||||
|
NPString uuid,
|
||||||
|
NPVariant *result)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GVariant *res;
|
||||||
|
const gchar *uuid_str;
|
||||||
|
|
||||||
|
uuid_str = uuid.UTF8Characters;
|
||||||
|
if (!uuid_is_valid (uuid_str))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||||
|
"GetExtensionErrors",
|
||||||
|
g_variant_new ("(s)", uuid_str),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1, /* timeout */
|
||||||
|
NULL, /* cancellable */
|
||||||
|
&error);
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to retrieve errors: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonify_variant (res, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
plugin_get_api_version (PluginObject *obj,
|
||||||
|
NPVariant *result)
|
||||||
|
{
|
||||||
|
INT32_TO_NPVARIANT (PLUGIN_API_VERSION, *result);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_get_shell_version (PluginObject *obj,
|
||||||
|
NPVariant *result)
|
||||||
|
{
|
||||||
|
GVariant *res;
|
||||||
|
const gchar *version;
|
||||||
|
gsize length;
|
||||||
|
gchar *buffer;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
res = g_dbus_proxy_get_cached_property (obj->proxy,
|
||||||
|
"ShellVersion");
|
||||||
|
|
||||||
|
if (res == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to grab shell version.");
|
||||||
|
version = "-1";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_variant_get (res, "&s", &version);
|
||||||
|
}
|
||||||
|
|
||||||
|
length = strlen (version);
|
||||||
|
buffer = funcs.memalloc (length + 1);
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
ret = FALSE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
strcpy (buffer, version);
|
||||||
|
|
||||||
|
STRINGN_TO_NPVARIANT (buffer, length, *result);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_variant_unref (res);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
plugin_object_invoke (NPObject *npobj,
|
||||||
|
NPIdentifier name,
|
||||||
|
const NPVariant *args,
|
||||||
|
uint32_t argc,
|
||||||
|
NPVariant *result)
|
||||||
|
{
|
||||||
|
PluginObject *obj;
|
||||||
|
|
||||||
|
g_debug ("invoking plugin object method");
|
||||||
|
|
||||||
|
obj = (PluginObject*) npobj;
|
||||||
|
|
||||||
|
VOID_TO_NPVARIANT (*result);
|
||||||
|
|
||||||
|
if (!plugin_object_has_method (npobj, name))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (name == list_extensions_id)
|
||||||
|
return plugin_list_extensions (obj, result);
|
||||||
|
else if (name == get_info_id)
|
||||||
|
{
|
||||||
|
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||||
|
|
||||||
|
return plugin_get_info (obj, NPVARIANT_TO_STRING(args[0]), result);
|
||||||
|
}
|
||||||
|
else if (name == enable_extension_id)
|
||||||
|
{
|
||||||
|
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||||
|
if (!NPVARIANT_IS_BOOLEAN(args[1])) return FALSE;
|
||||||
|
|
||||||
|
return plugin_enable_extension (obj,
|
||||||
|
NPVARIANT_TO_STRING(args[0]),
|
||||||
|
NPVARIANT_TO_BOOLEAN(args[1]));
|
||||||
|
}
|
||||||
|
else if (name == install_extension_id)
|
||||||
|
{
|
||||||
|
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||||
|
if (!NPVARIANT_IS_STRING(args[1])) return FALSE;
|
||||||
|
|
||||||
|
return plugin_install_extension (obj,
|
||||||
|
NPVARIANT_TO_STRING(args[0]),
|
||||||
|
NPVARIANT_TO_STRING(args[1]));
|
||||||
|
}
|
||||||
|
else if (name == uninstall_extension_id)
|
||||||
|
{
|
||||||
|
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||||
|
|
||||||
|
return plugin_uninstall_extension (obj,
|
||||||
|
NPVARIANT_TO_STRING(args[0]),
|
||||||
|
result);
|
||||||
|
}
|
||||||
|
else if (name == get_errors_id)
|
||||||
|
{
|
||||||
|
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||||
|
|
||||||
|
return plugin_get_errors (obj,
|
||||||
|
NPVARIANT_TO_STRING(args[0]),
|
||||||
|
result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
plugin_object_has_property (NPObject *npobj,
|
||||||
|
NPIdentifier name)
|
||||||
|
{
|
||||||
|
return (name == onextension_changed_id ||
|
||||||
|
name == api_version_id ||
|
||||||
|
name == shell_version_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
plugin_object_get_property (NPObject *npobj,
|
||||||
|
NPIdentifier name,
|
||||||
|
NPVariant *result)
|
||||||
|
{
|
||||||
|
PluginObject *obj;
|
||||||
|
|
||||||
|
if (!plugin_object_has_property (npobj, name))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
obj = (PluginObject*) npobj;
|
||||||
|
if (name == api_version_id)
|
||||||
|
return plugin_get_api_version (obj, result);
|
||||||
|
else if (name == shell_version_id)
|
||||||
|
return plugin_get_shell_version (obj, result);
|
||||||
|
else if (name == onextension_changed_id)
|
||||||
|
{
|
||||||
|
if (obj->listener)
|
||||||
|
OBJECT_TO_NPVARIANT (obj->listener, *result);
|
||||||
|
else
|
||||||
|
NULL_TO_NPVARIANT (*result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
plugin_object_set_property (NPObject *npobj,
|
||||||
|
NPIdentifier name,
|
||||||
|
const NPVariant *value)
|
||||||
|
{
|
||||||
|
PluginObject *obj;
|
||||||
|
|
||||||
|
if (!plugin_object_has_property (npobj, name))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (name == onextension_changed_id)
|
||||||
|
{
|
||||||
|
obj = (PluginObject*) npobj;
|
||||||
|
if (obj->listener)
|
||||||
|
funcs.releaseobject (obj->listener);
|
||||||
|
|
||||||
|
obj->listener = NULL;
|
||||||
|
if (NPVARIANT_IS_OBJECT (*value))
|
||||||
|
{
|
||||||
|
obj->listener = NPVARIANT_TO_OBJECT (*value);
|
||||||
|
funcs.retainobject (obj->listener);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (NPVARIANT_IS_NULL (*value))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NPClass plugin_class = {
|
||||||
|
NP_CLASS_STRUCT_VERSION,
|
||||||
|
plugin_object_allocate,
|
||||||
|
plugin_object_deallocate,
|
||||||
|
NULL, /* invalidate */
|
||||||
|
plugin_object_has_method,
|
||||||
|
plugin_object_invoke,
|
||||||
|
NULL, /* invoke default */
|
||||||
|
plugin_object_has_property,
|
||||||
|
plugin_object_get_property,
|
||||||
|
plugin_object_set_property,
|
||||||
|
NULL, /* remove property */
|
||||||
|
NULL, /* enumerate */
|
||||||
|
NULL, /* construct */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_methods_and_properties (void)
|
||||||
|
{
|
||||||
|
/* this is the JS public API; it is manipulated through NPIdentifiers for speed */
|
||||||
|
api_version_id = funcs.getstringidentifier ("apiVersion");
|
||||||
|
shell_version_id = funcs.getstringidentifier ("shellVersion");
|
||||||
|
|
||||||
|
get_info_id = funcs.getstringidentifier ("getExtensionInfo");
|
||||||
|
list_extensions_id = funcs.getstringidentifier ("listExtensions");
|
||||||
|
enable_extension_id = funcs.getstringidentifier ("setExtensionEnabled");
|
||||||
|
install_extension_id = funcs.getstringidentifier ("installExtension");
|
||||||
|
uninstall_extension_id = funcs.getstringidentifier ("uninstallExtension");
|
||||||
|
get_errors_id = funcs.getstringidentifier ("getExtensionErrors");
|
||||||
|
|
||||||
|
onextension_changed_id = funcs.getstringidentifier ("onchange");
|
||||||
|
}
|
||||||
|
|
||||||
|
NPError
|
||||||
|
NPP_GetValue(NPP instance,
|
||||||
|
NPPVariable variable,
|
||||||
|
void *value)
|
||||||
|
{
|
||||||
|
g_debug ("NPP_GetValue called");
|
||||||
|
|
||||||
|
switch (variable) {
|
||||||
|
case NPPVpluginScriptableNPObject:
|
||||||
|
g_debug ("creating scriptable object");
|
||||||
|
init_methods_and_properties ();
|
||||||
|
|
||||||
|
*(NPObject**)value = funcs.createobject (instance, &plugin_class);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NPPVpluginNeedsXEmbed:
|
||||||
|
*(bool *)value = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
893
browser-plugin/npapi/npapi.h
Normal file
@ -0,0 +1,893 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef npapi_h_
|
||||||
|
#define npapi_h_
|
||||||
|
|
||||||
|
#if defined(__OS2__)
|
||||||
|
#pragma pack(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nptypes.h"
|
||||||
|
|
||||||
|
#if defined(__OS2__) || defined(OS2)
|
||||||
|
#ifndef XP_OS2
|
||||||
|
#define XP_OS2 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__SYMBIAN32__)
|
||||||
|
#include <windef.h>
|
||||||
|
#ifndef XP_WIN
|
||||||
|
#define XP_WIN 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SYMBIAN32__)
|
||||||
|
#ifndef XP_SYMBIAN
|
||||||
|
#define XP_SYMBIAN 1
|
||||||
|
#undef XP_WIN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__APPLE_CC__) && !defined(XP_UNIX)
|
||||||
|
#ifndef XP_MACOSX
|
||||||
|
#define XP_MACOSX 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX) && defined(__LP64__)
|
||||||
|
#define NP_NO_QUICKDRAW
|
||||||
|
#define NP_NO_CARBON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#include <OpenGL/OpenGL.h>
|
||||||
|
#ifndef NP_NO_CARBON
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_UNIX)
|
||||||
|
#include <stdio.h>
|
||||||
|
#if defined(MOZ_X11)
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_SYMBIAN)
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QRegion>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
/* Plugin Version Constants */
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define NP_VERSION_MAJOR 0
|
||||||
|
#define NP_VERSION_MINOR 27
|
||||||
|
|
||||||
|
|
||||||
|
/* The OS/2 version of Netscape uses RC_DATA to define the
|
||||||
|
mime types, file extensions, etc that are required.
|
||||||
|
Use a vertical bar to separate types, end types with \0.
|
||||||
|
FileVersion and ProductVersion are 32bit ints, all other
|
||||||
|
entries are strings that MUST be terminated with a \0.
|
||||||
|
|
||||||
|
AN EXAMPLE:
|
||||||
|
|
||||||
|
RCDATA NP_INFO_ProductVersion { 1,0,0,1,}
|
||||||
|
|
||||||
|
RCDATA NP_INFO_MIMEType { "video/x-video|",
|
||||||
|
"video/x-flick\0" }
|
||||||
|
RCDATA NP_INFO_FileExtents { "avi|",
|
||||||
|
"flc\0" }
|
||||||
|
RCDATA NP_INFO_FileOpenName{ "MMOS2 video player(*.avi)|",
|
||||||
|
"MMOS2 Flc/Fli player(*.flc)\0" }
|
||||||
|
|
||||||
|
RCDATA NP_INFO_FileVersion { 1,0,0,1 }
|
||||||
|
RCDATA NP_INFO_CompanyName { "Netscape Communications\0" }
|
||||||
|
RCDATA NP_INFO_FileDescription { "NPAVI32 Extension DLL\0"
|
||||||
|
RCDATA NP_INFO_InternalName { "NPAVI32\0" )
|
||||||
|
RCDATA NP_INFO_LegalCopyright { "Copyright Netscape Communications \251 1996\0"
|
||||||
|
RCDATA NP_INFO_OriginalFilename { "NVAPI32.DLL" }
|
||||||
|
RCDATA NP_INFO_ProductName { "NPAVI32 Dynamic Link Library\0" }
|
||||||
|
*/
|
||||||
|
/* RC_DATA types for version info - required */
|
||||||
|
#define NP_INFO_ProductVersion 1
|
||||||
|
#define NP_INFO_MIMEType 2
|
||||||
|
#define NP_INFO_FileOpenName 3
|
||||||
|
#define NP_INFO_FileExtents 4
|
||||||
|
/* RC_DATA types for version info - used if found */
|
||||||
|
#define NP_INFO_FileDescription 5
|
||||||
|
#define NP_INFO_ProductName 6
|
||||||
|
/* RC_DATA types for version info - optional */
|
||||||
|
#define NP_INFO_CompanyName 7
|
||||||
|
#define NP_INFO_FileVersion 8
|
||||||
|
#define NP_INFO_InternalName 9
|
||||||
|
#define NP_INFO_LegalCopyright 10
|
||||||
|
#define NP_INFO_OriginalFilename 11
|
||||||
|
|
||||||
|
#ifndef RC_INVOKED
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
/* Definition of Basic Types */
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
typedef unsigned char NPBool;
|
||||||
|
typedef int16_t NPError;
|
||||||
|
typedef int16_t NPReason;
|
||||||
|
typedef char* NPMIMEType;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
/* Structures and definitions */
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if !defined(__LP64__)
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
#pragma options align=mac68k
|
||||||
|
#endif
|
||||||
|
#endif /* __LP64__ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NPP is a plug-in's opaque instance handle
|
||||||
|
*/
|
||||||
|
typedef struct _NPP
|
||||||
|
{
|
||||||
|
void* pdata; /* plug-in private data */
|
||||||
|
void* ndata; /* netscape private data */
|
||||||
|
} NPP_t;
|
||||||
|
|
||||||
|
typedef NPP_t* NPP;
|
||||||
|
|
||||||
|
typedef struct _NPStream
|
||||||
|
{
|
||||||
|
void* pdata; /* plug-in private data */
|
||||||
|
void* ndata; /* netscape private data */
|
||||||
|
const char* url;
|
||||||
|
uint32_t end;
|
||||||
|
uint32_t lastmodified;
|
||||||
|
void* notifyData;
|
||||||
|
const char* headers; /* Response headers from host.
|
||||||
|
* Exists only for >= NPVERS_HAS_RESPONSE_HEADERS.
|
||||||
|
* Used for HTTP only; NULL for non-HTTP.
|
||||||
|
* Available from NPP_NewStream onwards.
|
||||||
|
* Plugin should copy this data before storing it.
|
||||||
|
* Includes HTTP status line and all headers,
|
||||||
|
* preferably verbatim as received from server,
|
||||||
|
* headers formatted as in HTTP ("Header: Value"),
|
||||||
|
* and newlines (\n, NOT \r\n) separating lines.
|
||||||
|
* Terminated by \n\0 (NOT \n\n\0). */
|
||||||
|
} NPStream;
|
||||||
|
|
||||||
|
typedef struct _NPByteRange
|
||||||
|
{
|
||||||
|
int32_t offset; /* negative offset means from the end */
|
||||||
|
uint32_t length;
|
||||||
|
struct _NPByteRange* next;
|
||||||
|
} NPByteRange;
|
||||||
|
|
||||||
|
typedef struct _NPSavedData
|
||||||
|
{
|
||||||
|
int32_t len;
|
||||||
|
void* buf;
|
||||||
|
} NPSavedData;
|
||||||
|
|
||||||
|
typedef struct _NPRect
|
||||||
|
{
|
||||||
|
uint16_t top;
|
||||||
|
uint16_t left;
|
||||||
|
uint16_t bottom;
|
||||||
|
uint16_t right;
|
||||||
|
} NPRect;
|
||||||
|
|
||||||
|
typedef struct _NPSize
|
||||||
|
{
|
||||||
|
int32_t width;
|
||||||
|
int32_t height;
|
||||||
|
} NPSize;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NPFocusNext = 0,
|
||||||
|
NPFocusPrevious = 1
|
||||||
|
} NPFocusDirection;
|
||||||
|
|
||||||
|
/* Return values for NPP_HandleEvent */
|
||||||
|
#define kNPEventNotHandled 0
|
||||||
|
#define kNPEventHandled 1
|
||||||
|
/* Exact meaning must be spec'd in event model. */
|
||||||
|
#define kNPEventStartIME 2
|
||||||
|
|
||||||
|
#if defined(XP_UNIX)
|
||||||
|
/*
|
||||||
|
* Unix specific structures and definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback Structures.
|
||||||
|
*
|
||||||
|
* These are used to pass additional platform specific information.
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
NP_SETWINDOW = 1,
|
||||||
|
NP_PRINT
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32_t type;
|
||||||
|
} NPAnyCallbackStruct;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32_t type;
|
||||||
|
#if defined(MOZ_X11)
|
||||||
|
Display* display;
|
||||||
|
Visual* visual;
|
||||||
|
Colormap colormap;
|
||||||
|
unsigned int depth;
|
||||||
|
#endif
|
||||||
|
} NPSetWindowCallbackStruct;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32_t type;
|
||||||
|
FILE* fp;
|
||||||
|
} NPPrintCallbackStruct;
|
||||||
|
|
||||||
|
#endif /* XP_UNIX */
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
typedef enum {
|
||||||
|
#ifndef NP_NO_QUICKDRAW
|
||||||
|
NPDrawingModelQuickDraw = 0,
|
||||||
|
#endif
|
||||||
|
NPDrawingModelCoreGraphics = 1,
|
||||||
|
NPDrawingModelOpenGL = 2,
|
||||||
|
NPDrawingModelCoreAnimation = 3,
|
||||||
|
NPDrawingModelInvalidatingCoreAnimation = 4
|
||||||
|
} NPDrawingModel;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
#ifndef NP_NO_CARBON
|
||||||
|
NPEventModelCarbon = 0,
|
||||||
|
#endif
|
||||||
|
NPEventModelCocoa = 1
|
||||||
|
} NPEventModel;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following masks are applied on certain platforms to NPNV and
|
||||||
|
* NPPV selectors that pass around pointers to COM interfaces. Newer
|
||||||
|
* compilers on some platforms may generate vtables that are not
|
||||||
|
* compatible with older compilers. To prevent older plugins from
|
||||||
|
* not understanding a new browser's ABI, these masks change the
|
||||||
|
* values of those selectors on those platforms. To remain backwards
|
||||||
|
* compatible with different versions of the browser, plugins can
|
||||||
|
* use these masks to dynamically determine and use the correct C++
|
||||||
|
* ABI that the browser is expecting. This does not apply to Windows
|
||||||
|
* as Microsoft's COM ABI will likely not change.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NP_ABI_GCC3_MASK 0x10000000
|
||||||
|
/*
|
||||||
|
* gcc 3.x generated vtables on UNIX and OSX are incompatible with
|
||||||
|
* previous compilers.
|
||||||
|
*/
|
||||||
|
#if (defined(XP_UNIX) && defined(__GNUC__) && (__GNUC__ >= 3))
|
||||||
|
#define _NP_ABI_MIXIN_FOR_GCC3 NP_ABI_GCC3_MASK
|
||||||
|
#else
|
||||||
|
#define _NP_ABI_MIXIN_FOR_GCC3 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
#define NP_ABI_MACHO_MASK 0x01000000
|
||||||
|
#define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK
|
||||||
|
#else
|
||||||
|
#define _NP_ABI_MIXIN_FOR_MACHO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of variable names for which NPP_GetValue shall be implemented
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
NPPVpluginNameString = 1,
|
||||||
|
NPPVpluginDescriptionString,
|
||||||
|
NPPVpluginWindowBool,
|
||||||
|
NPPVpluginTransparentBool,
|
||||||
|
NPPVjavaClass,
|
||||||
|
NPPVpluginWindowSize,
|
||||||
|
NPPVpluginTimerInterval,
|
||||||
|
NPPVpluginScriptableInstance = (10 | NP_ABI_MASK),
|
||||||
|
NPPVpluginScriptableIID = 11,
|
||||||
|
NPPVjavascriptPushCallerBool = 12,
|
||||||
|
NPPVpluginKeepLibraryInMemory = 13,
|
||||||
|
NPPVpluginNeedsXEmbed = 14,
|
||||||
|
|
||||||
|
/* Get the NPObject for scripting the plugin. Introduced in NPAPI minor version 14.
|
||||||
|
*/
|
||||||
|
NPPVpluginScriptableNPObject = 15,
|
||||||
|
|
||||||
|
/* Get the plugin value (as \0-terminated UTF-8 string data) for
|
||||||
|
* form submission if the plugin is part of a form. Use
|
||||||
|
* NPN_MemAlloc() to allocate memory for the string data. Introduced
|
||||||
|
* in NPAPI minor version 15.
|
||||||
|
*/
|
||||||
|
NPPVformValue = 16,
|
||||||
|
|
||||||
|
NPPVpluginUrlRequestsDisplayedBool = 17,
|
||||||
|
|
||||||
|
/* Checks if the plugin is interested in receiving the http body of
|
||||||
|
* all http requests (including failed ones, http status != 200).
|
||||||
|
*/
|
||||||
|
NPPVpluginWantsAllNetworkStreams = 18,
|
||||||
|
|
||||||
|
/* Browsers can retrieve a native ATK accessibility plug ID via this variable. */
|
||||||
|
NPPVpluginNativeAccessibleAtkPlugId = 19,
|
||||||
|
|
||||||
|
/* Checks to see if the plug-in would like the browser to load the "src" attribute. */
|
||||||
|
NPPVpluginCancelSrcStream = 20,
|
||||||
|
|
||||||
|
NPPVsupportsAdvancedKeyHandling = 21,
|
||||||
|
|
||||||
|
NPPVpluginUsesDOMForCursorBool = 22
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
/* Used for negotiating drawing models */
|
||||||
|
, NPPVpluginDrawingModel = 1000
|
||||||
|
/* Used for negotiating event models */
|
||||||
|
, NPPVpluginEventModel = 1001
|
||||||
|
/* In the NPDrawingModelCoreAnimation drawing model, the browser asks the plug-in for a Core Animation layer. */
|
||||||
|
, NPPVpluginCoreAnimationLayer = 1003
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
|
||||||
|
, NPPVpluginWindowlessLocalBool = 2002
|
||||||
|
#endif
|
||||||
|
} NPPVariable;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of variable names for which NPN_GetValue should be implemented.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
NPNVxDisplay = 1,
|
||||||
|
NPNVxtAppContext,
|
||||||
|
NPNVnetscapeWindow,
|
||||||
|
NPNVjavascriptEnabledBool,
|
||||||
|
NPNVasdEnabledBool,
|
||||||
|
NPNVisOfflineBool,
|
||||||
|
|
||||||
|
NPNVserviceManager = (10 | NP_ABI_MASK),
|
||||||
|
NPNVDOMElement = (11 | NP_ABI_MASK),
|
||||||
|
NPNVDOMWindow = (12 | NP_ABI_MASK),
|
||||||
|
NPNVToolkit = (13 | NP_ABI_MASK),
|
||||||
|
NPNVSupportsXEmbedBool = 14,
|
||||||
|
|
||||||
|
/* Get the NPObject wrapper for the browser window. */
|
||||||
|
NPNVWindowNPObject = 15,
|
||||||
|
|
||||||
|
/* Get the NPObject wrapper for the plugins DOM element. */
|
||||||
|
NPNVPluginElementNPObject = 16,
|
||||||
|
|
||||||
|
NPNVSupportsWindowless = 17,
|
||||||
|
|
||||||
|
NPNVprivateModeBool = 18,
|
||||||
|
|
||||||
|
NPNVsupportsAdvancedKeyHandling = 21
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
/* Used for negotiating drawing models */
|
||||||
|
, NPNVpluginDrawingModel = 1000
|
||||||
|
#ifndef NP_NO_QUICKDRAW
|
||||||
|
, NPNVsupportsQuickDrawBool = 2000
|
||||||
|
#endif
|
||||||
|
, NPNVsupportsCoreGraphicsBool = 2001
|
||||||
|
, NPNVsupportsOpenGLBool = 2002
|
||||||
|
, NPNVsupportsCoreAnimationBool = 2003
|
||||||
|
, NPNVsupportsInvalidatingCoreAnimationBool = 2004
|
||||||
|
#ifndef NP_NO_CARBON
|
||||||
|
, NPNVsupportsCarbonBool = 3000 /* TRUE if the browser supports the Carbon event model */
|
||||||
|
#endif
|
||||||
|
, NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */
|
||||||
|
, NPNVsupportsUpdatedCocoaTextInputBool = 3002 /* TRUE if the browser supports the updated
|
||||||
|
Cocoa text input specification. */
|
||||||
|
, NPNVsupportsCompositingCoreAnimationPluginsBool = 74656 /* TRUE if the browser supports
|
||||||
|
CA model compositing */
|
||||||
|
#endif
|
||||||
|
#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
|
||||||
|
, NPNVSupportsWindowlessLocal = 2002
|
||||||
|
#endif
|
||||||
|
} NPNVariable;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NPNURLVCookie = 501,
|
||||||
|
NPNURLVProxy
|
||||||
|
} NPNURLVariable;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The type of Toolkit the widgets use
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
NPNVGtk12 = 1,
|
||||||
|
NPNVGtk2
|
||||||
|
} NPNToolkitType;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The type of a NPWindow - it specifies the type of the data structure
|
||||||
|
* returned in the window field.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
NPWindowTypeWindow = 1,
|
||||||
|
NPWindowTypeDrawable
|
||||||
|
} NPWindowType;
|
||||||
|
|
||||||
|
typedef struct _NPWindow
|
||||||
|
{
|
||||||
|
void* window; /* Platform specific window handle */
|
||||||
|
/* OS/2: x - Position of bottom left corner */
|
||||||
|
/* OS/2: y - relative to visible netscape window */
|
||||||
|
int32_t x; /* Position of top left corner relative */
|
||||||
|
int32_t y; /* to a netscape page. */
|
||||||
|
uint32_t width; /* Maximum window size */
|
||||||
|
uint32_t height;
|
||||||
|
NPRect clipRect; /* Clipping rectangle in port coordinates */
|
||||||
|
#if (defined(XP_UNIX) || defined(XP_SYMBIAN)) && !defined(XP_MACOSX)
|
||||||
|
void * ws_info; /* Platform-dependent additional data */
|
||||||
|
#endif /* XP_UNIX */
|
||||||
|
NPWindowType type; /* Is this a window or a drawable? */
|
||||||
|
} NPWindow;
|
||||||
|
|
||||||
|
typedef struct _NPImageExpose
|
||||||
|
{
|
||||||
|
char* data; /* image pointer */
|
||||||
|
int32_t stride; /* Stride of data image pointer */
|
||||||
|
int32_t depth; /* Depth of image pointer */
|
||||||
|
int32_t x; /* Expose x */
|
||||||
|
int32_t y; /* Expose y */
|
||||||
|
uint32_t width; /* Expose width */
|
||||||
|
uint32_t height; /* Expose height */
|
||||||
|
NPSize dataSize; /* Data buffer size */
|
||||||
|
float translateX; /* translate X matrix value */
|
||||||
|
float translateY; /* translate Y matrix value */
|
||||||
|
float scaleX; /* scale X matrix value */
|
||||||
|
float scaleY; /* scale Y matrix value */
|
||||||
|
} NPImageExpose;
|
||||||
|
|
||||||
|
typedef struct _NPFullPrint
|
||||||
|
{
|
||||||
|
NPBool pluginPrinted;/* Set TRUE if plugin handled fullscreen printing */
|
||||||
|
NPBool printOne; /* TRUE if plugin should print one copy to default
|
||||||
|
printer */
|
||||||
|
void* platformPrint; /* Platform-specific printing info */
|
||||||
|
} NPFullPrint;
|
||||||
|
|
||||||
|
typedef struct _NPEmbedPrint
|
||||||
|
{
|
||||||
|
NPWindow window;
|
||||||
|
void* platformPrint; /* Platform-specific printing info */
|
||||||
|
} NPEmbedPrint;
|
||||||
|
|
||||||
|
typedef struct _NPPrint
|
||||||
|
{
|
||||||
|
uint16_t mode; /* NP_FULL or NP_EMBED */
|
||||||
|
union
|
||||||
|
{
|
||||||
|
NPFullPrint fullPrint; /* if mode is NP_FULL */
|
||||||
|
NPEmbedPrint embedPrint; /* if mode is NP_EMBED */
|
||||||
|
} print;
|
||||||
|
} NPPrint;
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
#ifndef NP_NO_CARBON
|
||||||
|
typedef EventRecord NPEvent;
|
||||||
|
#endif
|
||||||
|
#elif defined(XP_SYMBIAN)
|
||||||
|
typedef QEvent NPEvent;
|
||||||
|
#elif defined(XP_WIN)
|
||||||
|
typedef struct _NPEvent
|
||||||
|
{
|
||||||
|
uint16_t event;
|
||||||
|
uintptr_t wParam;
|
||||||
|
uintptr_t lParam;
|
||||||
|
} NPEvent;
|
||||||
|
#elif defined(XP_OS2)
|
||||||
|
typedef struct _NPEvent
|
||||||
|
{
|
||||||
|
uint32_t event;
|
||||||
|
uint32_t wParam;
|
||||||
|
uint32_t lParam;
|
||||||
|
} NPEvent;
|
||||||
|
#elif defined(XP_UNIX) && defined(MOZ_X11)
|
||||||
|
typedef XEvent NPEvent;
|
||||||
|
#else
|
||||||
|
typedef void* NPEvent;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
typedef void* NPRegion;
|
||||||
|
#ifndef NP_NO_QUICKDRAW
|
||||||
|
typedef RgnHandle NPQDRegion;
|
||||||
|
#endif
|
||||||
|
typedef CGPathRef NPCGRegion;
|
||||||
|
#elif defined(XP_WIN)
|
||||||
|
typedef HRGN NPRegion;
|
||||||
|
#elif defined(XP_UNIX) && defined(MOZ_X11)
|
||||||
|
typedef Region NPRegion;
|
||||||
|
#elif defined(XP_SYMBIAN)
|
||||||
|
typedef QRegion* NPRegion;
|
||||||
|
#else
|
||||||
|
typedef void *NPRegion;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _NPNSString NPNSString;
|
||||||
|
typedef struct _NPNSWindow NPNSWindow;
|
||||||
|
typedef struct _NPNSMenu NPNSMenu;
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
typedef NPNSMenu NPMenu;
|
||||||
|
#else
|
||||||
|
typedef void *NPMenu;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NPCoordinateSpacePlugin = 1,
|
||||||
|
NPCoordinateSpaceWindow,
|
||||||
|
NPCoordinateSpaceFlippedWindow,
|
||||||
|
NPCoordinateSpaceScreen,
|
||||||
|
NPCoordinateSpaceFlippedScreen
|
||||||
|
} NPCoordinateSpace;
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
|
||||||
|
#ifndef NP_NO_QUICKDRAW
|
||||||
|
typedef struct NP_Port
|
||||||
|
{
|
||||||
|
CGrafPtr port;
|
||||||
|
int32_t portx; /* position inside the topmost window */
|
||||||
|
int32_t porty;
|
||||||
|
} NP_Port;
|
||||||
|
#endif /* NP_NO_QUICKDRAW */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NP_CGContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelCoreGraphics
|
||||||
|
* as its drawing model.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct NP_CGContext
|
||||||
|
{
|
||||||
|
CGContextRef context;
|
||||||
|
void *window; /* A WindowRef under the Carbon event model. */
|
||||||
|
} NP_CGContext;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NP_GLContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelOpenGL as its
|
||||||
|
* drawing model.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct NP_GLContext
|
||||||
|
{
|
||||||
|
CGLContextObj context;
|
||||||
|
#ifdef NP_NO_CARBON
|
||||||
|
NPNSWindow *window;
|
||||||
|
#else
|
||||||
|
void *window; /* Can be either an NSWindow or a WindowRef depending on the event model */
|
||||||
|
#endif
|
||||||
|
} NP_GLContext;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NPCocoaEventDrawRect = 1,
|
||||||
|
NPCocoaEventMouseDown,
|
||||||
|
NPCocoaEventMouseUp,
|
||||||
|
NPCocoaEventMouseMoved,
|
||||||
|
NPCocoaEventMouseEntered,
|
||||||
|
NPCocoaEventMouseExited,
|
||||||
|
NPCocoaEventMouseDragged,
|
||||||
|
NPCocoaEventKeyDown,
|
||||||
|
NPCocoaEventKeyUp,
|
||||||
|
NPCocoaEventFlagsChanged,
|
||||||
|
NPCocoaEventFocusChanged,
|
||||||
|
NPCocoaEventWindowFocusChanged,
|
||||||
|
NPCocoaEventScrollWheel,
|
||||||
|
NPCocoaEventTextInput
|
||||||
|
} NPCocoaEventType;
|
||||||
|
|
||||||
|
typedef struct _NPCocoaEvent {
|
||||||
|
NPCocoaEventType type;
|
||||||
|
uint32_t version;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t modifierFlags;
|
||||||
|
double pluginX;
|
||||||
|
double pluginY;
|
||||||
|
int32_t buttonNumber;
|
||||||
|
int32_t clickCount;
|
||||||
|
double deltaX;
|
||||||
|
double deltaY;
|
||||||
|
double deltaZ;
|
||||||
|
} mouse;
|
||||||
|
struct {
|
||||||
|
uint32_t modifierFlags;
|
||||||
|
NPNSString *characters;
|
||||||
|
NPNSString *charactersIgnoringModifiers;
|
||||||
|
NPBool isARepeat;
|
||||||
|
uint16_t keyCode;
|
||||||
|
} key;
|
||||||
|
struct {
|
||||||
|
CGContextRef context;
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double width;
|
||||||
|
double height;
|
||||||
|
} draw;
|
||||||
|
struct {
|
||||||
|
NPBool hasFocus;
|
||||||
|
} focus;
|
||||||
|
struct {
|
||||||
|
NPNSString *text;
|
||||||
|
} text;
|
||||||
|
} data;
|
||||||
|
} NPCocoaEvent;
|
||||||
|
|
||||||
|
#ifndef NP_NO_CARBON
|
||||||
|
/* Non-standard event types that can be passed to HandleEvent */
|
||||||
|
enum NPEventType {
|
||||||
|
NPEventType_GetFocusEvent = (osEvt + 16),
|
||||||
|
NPEventType_LoseFocusEvent,
|
||||||
|
NPEventType_AdjustCursorEvent,
|
||||||
|
NPEventType_MenuCommandEvent,
|
||||||
|
NPEventType_ClippingChangedEvent,
|
||||||
|
NPEventType_ScrollingBeginsEvent = 1000,
|
||||||
|
NPEventType_ScrollingEndsEvent
|
||||||
|
};
|
||||||
|
#endif /* NP_NO_CARBON */
|
||||||
|
|
||||||
|
#endif /* XP_MACOSX */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for mode passed to NPP_New:
|
||||||
|
*/
|
||||||
|
#define NP_EMBED 1
|
||||||
|
#define NP_FULL 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for stream type passed to NPP_NewStream:
|
||||||
|
*/
|
||||||
|
#define NP_NORMAL 1
|
||||||
|
#define NP_SEEK 2
|
||||||
|
#define NP_ASFILE 3
|
||||||
|
#define NP_ASFILEONLY 4
|
||||||
|
|
||||||
|
#define NP_MAXREADY (((unsigned)(~0)<<1)>>1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags for NPP_ClearSiteData.
|
||||||
|
*/
|
||||||
|
#define NP_CLEAR_ALL 0
|
||||||
|
#define NP_CLEAR_CACHE (1 << 0)
|
||||||
|
|
||||||
|
#if !defined(__LP64__)
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
#pragma options align=reset
|
||||||
|
#endif
|
||||||
|
#endif /* __LP64__ */
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
/* Error and Reason Code definitions */
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values of type NPError:
|
||||||
|
*/
|
||||||
|
#define NPERR_BASE 0
|
||||||
|
#define NPERR_NO_ERROR (NPERR_BASE + 0)
|
||||||
|
#define NPERR_GENERIC_ERROR (NPERR_BASE + 1)
|
||||||
|
#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2)
|
||||||
|
#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3)
|
||||||
|
#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4)
|
||||||
|
#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5)
|
||||||
|
#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6)
|
||||||
|
#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7)
|
||||||
|
#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8)
|
||||||
|
#define NPERR_INVALID_PARAM (NPERR_BASE + 9)
|
||||||
|
#define NPERR_INVALID_URL (NPERR_BASE + 10)
|
||||||
|
#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11)
|
||||||
|
#define NPERR_NO_DATA (NPERR_BASE + 12)
|
||||||
|
#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13)
|
||||||
|
#define NPERR_TIME_RANGE_NOT_SUPPORTED (NPERR_BASE + 14)
|
||||||
|
#define NPERR_MALFORMED_SITE (NPERR_BASE + 15)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values of type NPReason:
|
||||||
|
*/
|
||||||
|
#define NPRES_BASE 0
|
||||||
|
#define NPRES_DONE (NPRES_BASE + 0)
|
||||||
|
#define NPRES_NETWORK_ERR (NPRES_BASE + 1)
|
||||||
|
#define NPRES_USER_BREAK (NPRES_BASE + 2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't use these obsolete error codes any more.
|
||||||
|
*/
|
||||||
|
#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR
|
||||||
|
#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR
|
||||||
|
#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Version feature information
|
||||||
|
*/
|
||||||
|
#define NPVERS_HAS_STREAMOUTPUT 8
|
||||||
|
#define NPVERS_HAS_NOTIFICATION 9
|
||||||
|
#define NPVERS_HAS_LIVECONNECT 9
|
||||||
|
#define NPVERS_68K_HAS_LIVECONNECT 11
|
||||||
|
#define NPVERS_HAS_WINDOWLESS 11
|
||||||
|
#define NPVERS_HAS_XPCONNECT_SCRIPTING 13
|
||||||
|
#define NPVERS_HAS_NPRUNTIME_SCRIPTING 14
|
||||||
|
#define NPVERS_HAS_FORM_VALUES 15
|
||||||
|
#define NPVERS_HAS_POPUPS_ENABLED_STATE 16
|
||||||
|
#define NPVERS_HAS_RESPONSE_HEADERS 17
|
||||||
|
#define NPVERS_HAS_NPOBJECT_ENUM 18
|
||||||
|
#define NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL 19
|
||||||
|
#define NPVERS_HAS_ALL_NETWORK_STREAMS 20
|
||||||
|
#define NPVERS_HAS_URL_AND_AUTH_INFO 21
|
||||||
|
#define NPVERS_HAS_PRIVATE_MODE 22
|
||||||
|
#define NPVERS_MACOSX_HAS_COCOA_EVENTS 23
|
||||||
|
#define NPVERS_HAS_ADVANCED_KEY_HANDLING 25
|
||||||
|
#define NPVERS_HAS_URL_REDIRECT_HANDLING 26
|
||||||
|
#define NPVERS_HAS_CLEAR_SITE_DATA 27
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
/* Function Prototypes */
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if defined(__OS2__)
|
||||||
|
#define NP_LOADDS _System
|
||||||
|
#else
|
||||||
|
#define NP_LOADDS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* NPP_* functions are provided by the plugin and called by the navigator. */
|
||||||
|
|
||||||
|
#if defined(XP_UNIX)
|
||||||
|
const char* NPP_GetMIMEDescription(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,
|
||||||
|
uint16_t mode, int16_t argc, char* argn[],
|
||||||
|
char* argv[], NPSavedData* saved);
|
||||||
|
NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save);
|
||||||
|
NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window);
|
||||||
|
NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,
|
||||||
|
NPStream* stream, NPBool seekable,
|
||||||
|
uint16_t* stype);
|
||||||
|
NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,
|
||||||
|
NPReason reason);
|
||||||
|
int32_t NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream);
|
||||||
|
int32_t NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32_t offset,
|
||||||
|
int32_t len, void* buffer);
|
||||||
|
void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,
|
||||||
|
const char* fname);
|
||||||
|
void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint);
|
||||||
|
int16_t NP_LOADDS NPP_HandleEvent(NPP instance, void* event);
|
||||||
|
void NP_LOADDS NPP_URLNotify(NPP instance, const char* url,
|
||||||
|
NPReason reason, void* notifyData);
|
||||||
|
NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value);
|
||||||
|
NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value);
|
||||||
|
NPBool NP_LOADDS NPP_GotFocus(NPP instance, NPFocusDirection direction);
|
||||||
|
void NP_LOADDS NPP_LostFocus(NPP instance);
|
||||||
|
void NP_LOADDS NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData);
|
||||||
|
NPError NP_LOADDS NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge);
|
||||||
|
char** NP_LOADDS NPP_GetSitesWithData(void);
|
||||||
|
|
||||||
|
/* NPN_* functions are provided by the navigator and called by the plugin. */
|
||||||
|
void NP_LOADDS NPN_Version(int* plugin_major, int* plugin_minor,
|
||||||
|
int* netscape_major, int* netscape_minor);
|
||||||
|
NPError NP_LOADDS NPN_GetURLNotify(NPP instance, const char* url,
|
||||||
|
const char* target, void* notifyData);
|
||||||
|
NPError NP_LOADDS NPN_GetURL(NPP instance, const char* url,
|
||||||
|
const char* target);
|
||||||
|
NPError NP_LOADDS NPN_PostURLNotify(NPP instance, const char* url,
|
||||||
|
const char* target, uint32_t len,
|
||||||
|
const char* buf, NPBool file,
|
||||||
|
void* notifyData);
|
||||||
|
NPError NP_LOADDS NPN_PostURL(NPP instance, const char* url,
|
||||||
|
const char* target, uint32_t len,
|
||||||
|
const char* buf, NPBool file);
|
||||||
|
NPError NP_LOADDS NPN_RequestRead(NPStream* stream, NPByteRange* rangeList);
|
||||||
|
NPError NP_LOADDS NPN_NewStream(NPP instance, NPMIMEType type,
|
||||||
|
const char* target, NPStream** stream);
|
||||||
|
int32_t NP_LOADDS NPN_Write(NPP instance, NPStream* stream, int32_t len,
|
||||||
|
void* buffer);
|
||||||
|
NPError NP_LOADDS NPN_DestroyStream(NPP instance, NPStream* stream,
|
||||||
|
NPReason reason);
|
||||||
|
void NP_LOADDS NPN_Status(NPP instance, const char* message);
|
||||||
|
const char* NP_LOADDS NPN_UserAgent(NPP instance);
|
||||||
|
void* NP_LOADDS NPN_MemAlloc(uint32_t size);
|
||||||
|
void NP_LOADDS NPN_MemFree(void* ptr);
|
||||||
|
uint32_t NP_LOADDS NPN_MemFlush(uint32_t size);
|
||||||
|
void NP_LOADDS NPN_ReloadPlugins(NPBool reloadPages);
|
||||||
|
NPError NP_LOADDS NPN_GetValue(NPP instance, NPNVariable variable,
|
||||||
|
void *value);
|
||||||
|
NPError NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable,
|
||||||
|
void *value);
|
||||||
|
void NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect);
|
||||||
|
void NP_LOADDS NPN_InvalidateRegion(NPP instance,
|
||||||
|
NPRegion invalidRegion);
|
||||||
|
void NP_LOADDS NPN_ForceRedraw(NPP instance);
|
||||||
|
void NP_LOADDS NPN_PushPopupsEnabledState(NPP instance, NPBool enabled);
|
||||||
|
void NP_LOADDS NPN_PopPopupsEnabledState(NPP instance);
|
||||||
|
void NP_LOADDS NPN_PluginThreadAsyncCall(NPP instance,
|
||||||
|
void (*func) (void *),
|
||||||
|
void *userData);
|
||||||
|
NPError NP_LOADDS NPN_GetValueForURL(NPP instance, NPNURLVariable variable,
|
||||||
|
const char *url, char **value,
|
||||||
|
uint32_t *len);
|
||||||
|
NPError NP_LOADDS NPN_SetValueForURL(NPP instance, NPNURLVariable variable,
|
||||||
|
const char *url, const char *value,
|
||||||
|
uint32_t len);
|
||||||
|
NPError NP_LOADDS NPN_GetAuthenticationInfo(NPP instance,
|
||||||
|
const char *protocol,
|
||||||
|
const char *host, int32_t port,
|
||||||
|
const char *scheme,
|
||||||
|
const char *realm,
|
||||||
|
char **username, uint32_t *ulen,
|
||||||
|
char **password,
|
||||||
|
uint32_t *plen);
|
||||||
|
uint32_t NP_LOADDS NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
|
||||||
|
void NP_LOADDS NPN_UnscheduleTimer(NPP instance, uint32_t timerID);
|
||||||
|
NPError NP_LOADDS NPN_PopUpContextMenu(NPP instance, NPMenu* menu);
|
||||||
|
NPBool NP_LOADDS NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
|
||||||
|
NPBool NP_LOADDS NPN_HandleEvent(NPP instance, void *event, NPBool handled);
|
||||||
|
NPBool NP_LOADDS NPN_UnfocusInstance(NPP instance, NPFocusDirection direction);
|
||||||
|
void NP_LOADDS NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* end extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* RC_INVOKED */
|
||||||
|
#if defined(__OS2__)
|
||||||
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* npapi_h_ */
|
322
browser-plugin/npapi/npfunctions.h
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef npfunctions_h_
|
||||||
|
#define npfunctions_h_
|
||||||
|
|
||||||
|
#ifdef __OS2__
|
||||||
|
#pragma pack(1)
|
||||||
|
#define NP_LOADDS _System
|
||||||
|
#else
|
||||||
|
#define NP_LOADDS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "npapi.h"
|
||||||
|
#include "npruntime.h"
|
||||||
|
|
||||||
|
typedef NPError (* NP_LOADDS NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);
|
||||||
|
typedef NPError (* NP_LOADDS NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
|
||||||
|
typedef NPError (* NP_LOADDS NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);
|
||||||
|
typedef NPError (* NP_LOADDS NPP_NewStreamProcPtr)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype);
|
||||||
|
typedef NPError (* NP_LOADDS NPP_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
|
||||||
|
typedef int32_t (* NP_LOADDS NPP_WriteReadyProcPtr)(NPP instance, NPStream* stream);
|
||||||
|
typedef int32_t (* NP_LOADDS NPP_WriteProcPtr)(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer);
|
||||||
|
typedef void (* NP_LOADDS NPP_StreamAsFileProcPtr)(NPP instance, NPStream* stream, const char* fname);
|
||||||
|
typedef void (* NP_LOADDS NPP_PrintProcPtr)(NPP instance, NPPrint* platformPrint);
|
||||||
|
typedef int16_t (* NP_LOADDS NPP_HandleEventProcPtr)(NPP instance, void* event);
|
||||||
|
typedef void (* NP_LOADDS NPP_URLNotifyProcPtr)(NPP instance, const char* url, NPReason reason, void* notifyData);
|
||||||
|
/* Any NPObjects returned to the browser via NPP_GetValue should be retained
|
||||||
|
by the plugin on the way out. The browser is responsible for releasing. */
|
||||||
|
typedef NPError (* NP_LOADDS NPP_GetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value);
|
||||||
|
typedef NPError (* NP_LOADDS NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *value);
|
||||||
|
typedef NPBool (* NP_LOADDS NPP_GotFocusPtr)(NPP instance, NPFocusDirection direction);
|
||||||
|
typedef void (* NP_LOADDS NPP_LostFocusPtr)(NPP instance);
|
||||||
|
typedef void (* NP_LOADDS NPP_URLRedirectNotifyPtr)(NPP instance, const char* url, int32_t status, void* notifyData);
|
||||||
|
typedef NPError (* NP_LOADDS NPP_ClearSiteDataPtr)(const char* site, uint64_t flags, uint64_t maxAge);
|
||||||
|
typedef char** (* NP_LOADDS NPP_GetSitesWithDataPtr)(void);
|
||||||
|
|
||||||
|
typedef NPError (*NPN_GetValueProcPtr)(NPP instance, NPNVariable variable, void *ret_value);
|
||||||
|
typedef NPError (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable, void *value);
|
||||||
|
typedef NPError (*NPN_GetURLNotifyProcPtr)(NPP instance, const char* url, const char* window, void* notifyData);
|
||||||
|
typedef NPError (*NPN_PostURLNotifyProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file, void* notifyData);
|
||||||
|
typedef NPError (*NPN_GetURLProcPtr)(NPP instance, const char* url, const char* window);
|
||||||
|
typedef NPError (*NPN_PostURLProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file);
|
||||||
|
typedef NPError (*NPN_RequestReadProcPtr)(NPStream* stream, NPByteRange* rangeList);
|
||||||
|
typedef NPError (*NPN_NewStreamProcPtr)(NPP instance, NPMIMEType type, const char* window, NPStream** stream);
|
||||||
|
typedef int32_t (*NPN_WriteProcPtr)(NPP instance, NPStream* stream, int32_t len, void* buffer);
|
||||||
|
typedef NPError (*NPN_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
|
||||||
|
typedef void (*NPN_StatusProcPtr)(NPP instance, const char* message);
|
||||||
|
/* Browser manages the lifetime of the buffer returned by NPN_UserAgent, don't
|
||||||
|
depend on it sticking around and don't free it. */
|
||||||
|
typedef const char* (*NPN_UserAgentProcPtr)(NPP instance);
|
||||||
|
typedef void* (*NPN_MemAllocProcPtr)(uint32_t size);
|
||||||
|
typedef void (*NPN_MemFreeProcPtr)(void* ptr);
|
||||||
|
typedef uint32_t (*NPN_MemFlushProcPtr)(uint32_t size);
|
||||||
|
typedef void (*NPN_ReloadPluginsProcPtr)(NPBool reloadPages);
|
||||||
|
typedef void* (*NPN_GetJavaEnvProcPtr)(void);
|
||||||
|
typedef void* (*NPN_GetJavaPeerProcPtr)(NPP instance);
|
||||||
|
typedef void (*NPN_InvalidateRectProcPtr)(NPP instance, NPRect *rect);
|
||||||
|
typedef void (*NPN_InvalidateRegionProcPtr)(NPP instance, NPRegion region);
|
||||||
|
typedef void (*NPN_ForceRedrawProcPtr)(NPP instance);
|
||||||
|
typedef NPIdentifier (*NPN_GetStringIdentifierProcPtr)(const NPUTF8* name);
|
||||||
|
typedef void (*NPN_GetStringIdentifiersProcPtr)(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers);
|
||||||
|
typedef NPIdentifier (*NPN_GetIntIdentifierProcPtr)(int32_t intid);
|
||||||
|
typedef bool (*NPN_IdentifierIsStringProcPtr)(NPIdentifier identifier);
|
||||||
|
typedef NPUTF8* (*NPN_UTF8FromIdentifierProcPtr)(NPIdentifier identifier);
|
||||||
|
typedef int32_t (*NPN_IntFromIdentifierProcPtr)(NPIdentifier identifier);
|
||||||
|
typedef NPObject* (*NPN_CreateObjectProcPtr)(NPP npp, NPClass *aClass);
|
||||||
|
typedef NPObject* (*NPN_RetainObjectProcPtr)(NPObject *obj);
|
||||||
|
typedef void (*NPN_ReleaseObjectProcPtr)(NPObject *obj);
|
||||||
|
typedef bool (*NPN_InvokeProcPtr)(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||||
|
typedef bool (*NPN_InvokeDefaultProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||||
|
typedef bool (*NPN_EvaluateProcPtr)(NPP npp, NPObject *obj, NPString *script, NPVariant *result);
|
||||||
|
typedef bool (*NPN_GetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result);
|
||||||
|
typedef bool (*NPN_SetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value);
|
||||||
|
typedef bool (*NPN_RemovePropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);
|
||||||
|
typedef bool (*NPN_HasPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);
|
||||||
|
typedef bool (*NPN_HasMethodProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);
|
||||||
|
typedef void (*NPN_ReleaseVariantValueProcPtr)(NPVariant *variant);
|
||||||
|
typedef void (*NPN_SetExceptionProcPtr)(NPObject *obj, const NPUTF8 *message);
|
||||||
|
typedef void (*NPN_PushPopupsEnabledStateProcPtr)(NPP npp, NPBool enabled);
|
||||||
|
typedef void (*NPN_PopPopupsEnabledStateProcPtr)(NPP npp);
|
||||||
|
typedef bool (*NPN_EnumerateProcPtr)(NPP npp, NPObject *obj, NPIdentifier **identifier, uint32_t *count);
|
||||||
|
typedef void (*NPN_PluginThreadAsyncCallProcPtr)(NPP instance, void (*func)(void *), void *userData);
|
||||||
|
typedef bool (*NPN_ConstructProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||||
|
typedef NPError (*NPN_GetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, char **value, uint32_t *len);
|
||||||
|
typedef NPError (*NPN_SetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, const char *value, uint32_t len);
|
||||||
|
typedef NPError (*NPN_GetAuthenticationInfoPtr)(NPP npp, const char *protocol, const char *host, int32_t port, const char *scheme, const char *realm, char **username, uint32_t *ulen, char **password, uint32_t *plen);
|
||||||
|
typedef uint32_t (*NPN_ScheduleTimerPtr)(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
|
||||||
|
typedef void (*NPN_UnscheduleTimerPtr)(NPP instance, uint32_t timerID);
|
||||||
|
typedef NPError (*NPN_PopUpContextMenuPtr)(NPP instance, NPMenu* menu);
|
||||||
|
typedef NPBool (*NPN_ConvertPointPtr)(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
|
||||||
|
typedef NPBool (*NPN_HandleEventPtr)(NPP instance, void *event, NPBool handled);
|
||||||
|
typedef NPBool (*NPN_UnfocusInstancePtr)(NPP instance, NPFocusDirection direction);
|
||||||
|
typedef void (*NPN_URLRedirectResponsePtr)(NPP instance, void* notifyData, NPBool allow);
|
||||||
|
|
||||||
|
typedef struct _NPPluginFuncs {
|
||||||
|
uint16_t size;
|
||||||
|
uint16_t version;
|
||||||
|
NPP_NewProcPtr newp;
|
||||||
|
NPP_DestroyProcPtr destroy;
|
||||||
|
NPP_SetWindowProcPtr setwindow;
|
||||||
|
NPP_NewStreamProcPtr newstream;
|
||||||
|
NPP_DestroyStreamProcPtr destroystream;
|
||||||
|
NPP_StreamAsFileProcPtr asfile;
|
||||||
|
NPP_WriteReadyProcPtr writeready;
|
||||||
|
NPP_WriteProcPtr write;
|
||||||
|
NPP_PrintProcPtr print;
|
||||||
|
NPP_HandleEventProcPtr event;
|
||||||
|
NPP_URLNotifyProcPtr urlnotify;
|
||||||
|
void* javaClass;
|
||||||
|
NPP_GetValueProcPtr getvalue;
|
||||||
|
NPP_SetValueProcPtr setvalue;
|
||||||
|
NPP_GotFocusPtr gotfocus;
|
||||||
|
NPP_LostFocusPtr lostfocus;
|
||||||
|
NPP_URLRedirectNotifyPtr urlredirectnotify;
|
||||||
|
NPP_ClearSiteDataPtr clearsitedata;
|
||||||
|
NPP_GetSitesWithDataPtr getsiteswithdata;
|
||||||
|
} NPPluginFuncs;
|
||||||
|
|
||||||
|
typedef struct _NPNetscapeFuncs {
|
||||||
|
uint16_t size;
|
||||||
|
uint16_t version;
|
||||||
|
NPN_GetURLProcPtr geturl;
|
||||||
|
NPN_PostURLProcPtr posturl;
|
||||||
|
NPN_RequestReadProcPtr requestread;
|
||||||
|
NPN_NewStreamProcPtr newstream;
|
||||||
|
NPN_WriteProcPtr write;
|
||||||
|
NPN_DestroyStreamProcPtr destroystream;
|
||||||
|
NPN_StatusProcPtr status;
|
||||||
|
NPN_UserAgentProcPtr uagent;
|
||||||
|
NPN_MemAllocProcPtr memalloc;
|
||||||
|
NPN_MemFreeProcPtr memfree;
|
||||||
|
NPN_MemFlushProcPtr memflush;
|
||||||
|
NPN_ReloadPluginsProcPtr reloadplugins;
|
||||||
|
NPN_GetJavaEnvProcPtr getJavaEnv;
|
||||||
|
NPN_GetJavaPeerProcPtr getJavaPeer;
|
||||||
|
NPN_GetURLNotifyProcPtr geturlnotify;
|
||||||
|
NPN_PostURLNotifyProcPtr posturlnotify;
|
||||||
|
NPN_GetValueProcPtr getvalue;
|
||||||
|
NPN_SetValueProcPtr setvalue;
|
||||||
|
NPN_InvalidateRectProcPtr invalidaterect;
|
||||||
|
NPN_InvalidateRegionProcPtr invalidateregion;
|
||||||
|
NPN_ForceRedrawProcPtr forceredraw;
|
||||||
|
NPN_GetStringIdentifierProcPtr getstringidentifier;
|
||||||
|
NPN_GetStringIdentifiersProcPtr getstringidentifiers;
|
||||||
|
NPN_GetIntIdentifierProcPtr getintidentifier;
|
||||||
|
NPN_IdentifierIsStringProcPtr identifierisstring;
|
||||||
|
NPN_UTF8FromIdentifierProcPtr utf8fromidentifier;
|
||||||
|
NPN_IntFromIdentifierProcPtr intfromidentifier;
|
||||||
|
NPN_CreateObjectProcPtr createobject;
|
||||||
|
NPN_RetainObjectProcPtr retainobject;
|
||||||
|
NPN_ReleaseObjectProcPtr releaseobject;
|
||||||
|
NPN_InvokeProcPtr invoke;
|
||||||
|
NPN_InvokeDefaultProcPtr invokeDefault;
|
||||||
|
NPN_EvaluateProcPtr evaluate;
|
||||||
|
NPN_GetPropertyProcPtr getproperty;
|
||||||
|
NPN_SetPropertyProcPtr setproperty;
|
||||||
|
NPN_RemovePropertyProcPtr removeproperty;
|
||||||
|
NPN_HasPropertyProcPtr hasproperty;
|
||||||
|
NPN_HasMethodProcPtr hasmethod;
|
||||||
|
NPN_ReleaseVariantValueProcPtr releasevariantvalue;
|
||||||
|
NPN_SetExceptionProcPtr setexception;
|
||||||
|
NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate;
|
||||||
|
NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate;
|
||||||
|
NPN_EnumerateProcPtr enumerate;
|
||||||
|
NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall;
|
||||||
|
NPN_ConstructProcPtr construct;
|
||||||
|
NPN_GetValueForURLPtr getvalueforurl;
|
||||||
|
NPN_SetValueForURLPtr setvalueforurl;
|
||||||
|
NPN_GetAuthenticationInfoPtr getauthenticationinfo;
|
||||||
|
NPN_ScheduleTimerPtr scheduletimer;
|
||||||
|
NPN_UnscheduleTimerPtr unscheduletimer;
|
||||||
|
NPN_PopUpContextMenuPtr popupcontextmenu;
|
||||||
|
NPN_ConvertPointPtr convertpoint;
|
||||||
|
NPN_HandleEventPtr handleevent;
|
||||||
|
NPN_UnfocusInstancePtr unfocusinstance;
|
||||||
|
NPN_URLRedirectResponsePtr urlredirectresponse;
|
||||||
|
} NPNetscapeFuncs;
|
||||||
|
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
/*
|
||||||
|
* Mac OS X version(s) of NP_GetMIMEDescription(const char *)
|
||||||
|
* These can be called to retreive MIME information from the plugin dynamically
|
||||||
|
*
|
||||||
|
* Note: For compatibility with Quicktime, BPSupportedMIMEtypes is another way
|
||||||
|
* to get mime info from the plugin only on OSX and may not be supported
|
||||||
|
* in furture version -- use NP_GetMIMEDescription instead
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kBPSupportedMIMETypesStructVers_1 = 1
|
||||||
|
};
|
||||||
|
typedef struct _BPSupportedMIMETypes
|
||||||
|
{
|
||||||
|
SInt32 structVersion; /* struct version */
|
||||||
|
Handle typeStrings; /* STR# formated handle, allocated by plug-in */
|
||||||
|
Handle infoStrings; /* STR# formated handle, allocated by plug-in */
|
||||||
|
} BPSupportedMIMETypes;
|
||||||
|
OSErr BP_GetSupportedMIMETypes(BPSupportedMIMETypes *mimeInfo, UInt32 flags);
|
||||||
|
#define NP_GETMIMEDESCRIPTION_NAME "NP_GetMIMEDescription"
|
||||||
|
typedef const char* (*NP_GetMIMEDescriptionProcPtr)(void);
|
||||||
|
typedef OSErr (*BP_GetSupportedMIMETypesProcPtr)(BPSupportedMIMETypes*, UInt32);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define OSCALL WINAPI
|
||||||
|
#else
|
||||||
|
#if defined(__OS2__)
|
||||||
|
#define OSCALL _System
|
||||||
|
#else
|
||||||
|
#define OSCALL
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_UNIX)
|
||||||
|
/* GCC 3.3 and later support the visibility attribute. */
|
||||||
|
#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))
|
||||||
|
#define NP_VISIBILITY_DEFAULT __attribute__((visibility("default")))
|
||||||
|
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||||
|
#define NP_VISIBILITY_DEFAULT __global
|
||||||
|
#else
|
||||||
|
#define NP_VISIBILITY_DEFAULT
|
||||||
|
#endif
|
||||||
|
#define NP_EXPORT(__type) NP_VISIBILITY_DEFAULT __type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined (__OS2__)
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* plugin meta member functions */
|
||||||
|
#if defined(__OS2__)
|
||||||
|
typedef struct _NPPluginData { /* Alternate OS2 Plugin interface */
|
||||||
|
char *pMimeTypes;
|
||||||
|
char *pFileExtents;
|
||||||
|
char *pFileOpenTemplate;
|
||||||
|
char *pProductName;
|
||||||
|
char *pProductDescription;
|
||||||
|
unsigned long dwProductVersionMS;
|
||||||
|
unsigned long dwProductVersionLS;
|
||||||
|
} NPPluginData;
|
||||||
|
typedef NPError (*NP_GetPluginDataFunc)(NPPluginData*);
|
||||||
|
NPError OSCALL NP_GetPluginData(NPPluginData * pPluginData);
|
||||||
|
#endif
|
||||||
|
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
||||||
|
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||||
|
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
|
||||||
|
NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs);
|
||||||
|
typedef NPError (*NP_ShutdownFunc)(void);
|
||||||
|
NPError OSCALL NP_Shutdown(void);
|
||||||
|
typedef const char* (*NP_GetMIMEDescriptionFunc)(void);
|
||||||
|
const char* NP_GetMIMEDescription(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__OS2__)
|
||||||
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef XP_UNIX
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
typedef char* (*NP_GetPluginVersionFunc)(void);
|
||||||
|
NP_EXPORT(char*) NP_GetPluginVersion(void);
|
||||||
|
typedef const char* (*NP_GetMIMEDescriptionFunc)(void);
|
||||||
|
NP_EXPORT(const char*) NP_GetMIMEDescription(void);
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
|
||||||
|
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs);
|
||||||
|
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
||||||
|
NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||||
|
#else
|
||||||
|
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
|
||||||
|
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
|
||||||
|
#endif
|
||||||
|
typedef NPError (*NP_ShutdownFunc)(void);
|
||||||
|
NP_EXPORT(NPError) NP_Shutdown(void);
|
||||||
|
typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void *);
|
||||||
|
NP_EXPORT(NPError) NP_GetValue(void *future, NPPVariable aVariable, void *aValue);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* npfunctions_h_ */
|
393
browser-plugin/npapi/npruntime.h
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2004, Apple Computer, Inc. and The Mozilla Foundation.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla
|
||||||
|
* Foundation ("Mozilla") nor the names of their contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS
|
||||||
|
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR
|
||||||
|
* THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef _NP_RUNTIME_H_
|
||||||
|
#define _NP_RUNTIME_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nptypes.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
This API is used to facilitate binding code written in C to script
|
||||||
|
objects. The API in this header does not assume the presence of a
|
||||||
|
user agent. That is, it can be used to bind C code to scripting
|
||||||
|
environments outside of the context of a user agent.
|
||||||
|
|
||||||
|
However, the normal use of the this API is in the context of a
|
||||||
|
scripting environment running in a browser or other user agent.
|
||||||
|
In particular it is used to support the extended Netscape
|
||||||
|
script-ability API for plugins (NP-SAP). NP-SAP is an extension
|
||||||
|
of the Netscape plugin API. As such we have adopted the use of
|
||||||
|
the "NP" prefix for this API.
|
||||||
|
|
||||||
|
The following NP{N|P}Variables were added to the Netscape plugin
|
||||||
|
API (in npapi.h):
|
||||||
|
|
||||||
|
NPNVWindowNPObject
|
||||||
|
NPNVPluginElementNPObject
|
||||||
|
NPPVpluginScriptableNPObject
|
||||||
|
|
||||||
|
These variables are exposed through NPN_GetValue() and
|
||||||
|
NPP_GetValue() (respectively) and are used to establish the
|
||||||
|
initial binding between the user agent and native code. The DOM
|
||||||
|
objects in the user agent can be examined and manipulated using
|
||||||
|
the NPN_ functions that operate on NPObjects described in this
|
||||||
|
header.
|
||||||
|
|
||||||
|
To the extent possible the assumptions about the scripting
|
||||||
|
language used by the scripting environment have been minimized.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NP_BEGIN_MACRO do {
|
||||||
|
#define NP_END_MACRO } while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Objects (non-primitive data) passed between 'C' and script is
|
||||||
|
always wrapped in an NPObject. The 'interface' of an NPObject is
|
||||||
|
described by an NPClass.
|
||||||
|
*/
|
||||||
|
typedef struct NPObject NPObject;
|
||||||
|
typedef struct NPClass NPClass;
|
||||||
|
|
||||||
|
typedef char NPUTF8;
|
||||||
|
typedef struct _NPString {
|
||||||
|
const NPUTF8 *UTF8Characters;
|
||||||
|
uint32_t UTF8Length;
|
||||||
|
} NPString;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NPVariantType_Void,
|
||||||
|
NPVariantType_Null,
|
||||||
|
NPVariantType_Bool,
|
||||||
|
NPVariantType_Int32,
|
||||||
|
NPVariantType_Double,
|
||||||
|
NPVariantType_String,
|
||||||
|
NPVariantType_Object
|
||||||
|
} NPVariantType;
|
||||||
|
|
||||||
|
typedef struct _NPVariant {
|
||||||
|
NPVariantType type;
|
||||||
|
union {
|
||||||
|
bool boolValue;
|
||||||
|
int32_t intValue;
|
||||||
|
double doubleValue;
|
||||||
|
NPString stringValue;
|
||||||
|
NPObject *objectValue;
|
||||||
|
} value;
|
||||||
|
} NPVariant;
|
||||||
|
|
||||||
|
/*
|
||||||
|
NPN_ReleaseVariantValue is called on all 'out' parameters
|
||||||
|
references. Specifically it is to be called on variants that own
|
||||||
|
their value, as is the case with all non-const NPVariant*
|
||||||
|
arguments after a successful call to any methods (except this one)
|
||||||
|
in this API.
|
||||||
|
|
||||||
|
After calling NPN_ReleaseVariantValue, the type of the variant
|
||||||
|
will be NPVariantType_Void.
|
||||||
|
*/
|
||||||
|
void NPN_ReleaseVariantValue(NPVariant *variant);
|
||||||
|
|
||||||
|
#define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void)
|
||||||
|
#define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null)
|
||||||
|
#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool)
|
||||||
|
#define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32)
|
||||||
|
#define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double)
|
||||||
|
#define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String)
|
||||||
|
#define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object)
|
||||||
|
|
||||||
|
#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue)
|
||||||
|
#define NPVARIANT_TO_INT32(_v) ((_v).value.intValue)
|
||||||
|
#define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue)
|
||||||
|
#define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue)
|
||||||
|
#define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue)
|
||||||
|
|
||||||
|
#define VOID_TO_NPVARIANT(_v) \
|
||||||
|
NP_BEGIN_MACRO \
|
||||||
|
(_v).type = NPVariantType_Void; \
|
||||||
|
(_v).value.objectValue = NULL; \
|
||||||
|
NP_END_MACRO
|
||||||
|
|
||||||
|
#define NULL_TO_NPVARIANT(_v) \
|
||||||
|
NP_BEGIN_MACRO \
|
||||||
|
(_v).type = NPVariantType_Null; \
|
||||||
|
(_v).value.objectValue = NULL; \
|
||||||
|
NP_END_MACRO
|
||||||
|
|
||||||
|
#define BOOLEAN_TO_NPVARIANT(_val, _v) \
|
||||||
|
NP_BEGIN_MACRO \
|
||||||
|
(_v).type = NPVariantType_Bool; \
|
||||||
|
(_v).value.boolValue = !!(_val); \
|
||||||
|
NP_END_MACRO
|
||||||
|
|
||||||
|
#define INT32_TO_NPVARIANT(_val, _v) \
|
||||||
|
NP_BEGIN_MACRO \
|
||||||
|
(_v).type = NPVariantType_Int32; \
|
||||||
|
(_v).value.intValue = _val; \
|
||||||
|
NP_END_MACRO
|
||||||
|
|
||||||
|
#define DOUBLE_TO_NPVARIANT(_val, _v) \
|
||||||
|
NP_BEGIN_MACRO \
|
||||||
|
(_v).type = NPVariantType_Double; \
|
||||||
|
(_v).value.doubleValue = _val; \
|
||||||
|
NP_END_MACRO
|
||||||
|
|
||||||
|
#define STRINGZ_TO_NPVARIANT(_val, _v) \
|
||||||
|
NP_BEGIN_MACRO \
|
||||||
|
(_v).type = NPVariantType_String; \
|
||||||
|
NPString str = { _val, (uint32_t)(strlen(_val)) }; \
|
||||||
|
(_v).value.stringValue = str; \
|
||||||
|
NP_END_MACRO
|
||||||
|
|
||||||
|
#define STRINGN_TO_NPVARIANT(_val, _len, _v) \
|
||||||
|
NP_BEGIN_MACRO \
|
||||||
|
(_v).type = NPVariantType_String; \
|
||||||
|
NPString str = { _val, (uint32_t)(_len) }; \
|
||||||
|
(_v).value.stringValue = str; \
|
||||||
|
NP_END_MACRO
|
||||||
|
|
||||||
|
#define OBJECT_TO_NPVARIANT(_val, _v) \
|
||||||
|
NP_BEGIN_MACRO \
|
||||||
|
(_v).type = NPVariantType_Object; \
|
||||||
|
(_v).value.objectValue = _val; \
|
||||||
|
NP_END_MACRO
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Type mappings (JavaScript types have been used for illustration
|
||||||
|
purposes):
|
||||||
|
|
||||||
|
JavaScript to C (NPVariant with type:)
|
||||||
|
undefined NPVariantType_Void
|
||||||
|
null NPVariantType_Null
|
||||||
|
Boolean NPVariantType_Bool
|
||||||
|
Number NPVariantType_Double or NPVariantType_Int32
|
||||||
|
String NPVariantType_String
|
||||||
|
Object NPVariantType_Object
|
||||||
|
|
||||||
|
C (NPVariant with type:) to JavaScript
|
||||||
|
NPVariantType_Void undefined
|
||||||
|
NPVariantType_Null null
|
||||||
|
NPVariantType_Bool Boolean
|
||||||
|
NPVariantType_Int32 Number
|
||||||
|
NPVariantType_Double Number
|
||||||
|
NPVariantType_String String
|
||||||
|
NPVariantType_Object Object
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void *NPIdentifier;
|
||||||
|
|
||||||
|
/*
|
||||||
|
NPObjects have methods and properties. Methods and properties are
|
||||||
|
identified with NPIdentifiers. These identifiers may be reflected
|
||||||
|
in script. NPIdentifiers can be either strings or integers, IOW,
|
||||||
|
methods and properties can be identified by either strings or
|
||||||
|
integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be
|
||||||
|
compared using ==. In case of any errors, the requested
|
||||||
|
NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled
|
||||||
|
by the browser. Plugins do not need to worry about memory management
|
||||||
|
with regards to NPIdentifiers.
|
||||||
|
*/
|
||||||
|
NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name);
|
||||||
|
void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount,
|
||||||
|
NPIdentifier *identifiers);
|
||||||
|
NPIdentifier NPN_GetIntIdentifier(int32_t intid);
|
||||||
|
bool NPN_IdentifierIsString(NPIdentifier identifier);
|
||||||
|
|
||||||
|
/*
|
||||||
|
The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed.
|
||||||
|
*/
|
||||||
|
NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the integer represented by identifier. If identifier is not an
|
||||||
|
integer identifier, the behaviour is undefined.
|
||||||
|
*/
|
||||||
|
int32_t NPN_IntFromIdentifier(NPIdentifier identifier);
|
||||||
|
|
||||||
|
/*
|
||||||
|
NPObject behavior is implemented using the following set of
|
||||||
|
callback functions.
|
||||||
|
|
||||||
|
The NPVariant *result argument of these functions (where
|
||||||
|
applicable) should be released using NPN_ReleaseVariantValue().
|
||||||
|
*/
|
||||||
|
typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass);
|
||||||
|
typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj);
|
||||||
|
typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj);
|
||||||
|
typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);
|
||||||
|
typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name,
|
||||||
|
const NPVariant *args, uint32_t argCount,
|
||||||
|
NPVariant *result);
|
||||||
|
typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj,
|
||||||
|
const NPVariant *args,
|
||||||
|
uint32_t argCount,
|
||||||
|
NPVariant *result);
|
||||||
|
typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);
|
||||||
|
typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
|
||||||
|
NPVariant *result);
|
||||||
|
typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
|
||||||
|
const NPVariant *value);
|
||||||
|
typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj,
|
||||||
|
NPIdentifier name);
|
||||||
|
typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value,
|
||||||
|
uint32_t *count);
|
||||||
|
typedef bool (*NPConstructFunctionPtr)(NPObject *npobj,
|
||||||
|
const NPVariant *args,
|
||||||
|
uint32_t argCount,
|
||||||
|
NPVariant *result);
|
||||||
|
|
||||||
|
/*
|
||||||
|
NPObjects returned by create, retain, invoke, and getProperty pass
|
||||||
|
a reference count to the caller. That is, the callee adds a
|
||||||
|
reference count which passes to the caller. It is the caller's
|
||||||
|
responsibility to release the returned object.
|
||||||
|
|
||||||
|
NPInvokeFunctionPtr function may return 0 to indicate a void
|
||||||
|
result.
|
||||||
|
|
||||||
|
NPInvalidateFunctionPtr is called by the scripting environment
|
||||||
|
when the native code is shutdown. Any attempt to message a
|
||||||
|
NPObject instance after the invalidate callback has been
|
||||||
|
called will result in undefined behavior, even if the native code
|
||||||
|
is still retaining those NPObject instances. (The runtime
|
||||||
|
will typically return immediately, with 0 or NULL, from an attempt
|
||||||
|
to dispatch to a NPObject, but this behavior should not be
|
||||||
|
depended upon.)
|
||||||
|
|
||||||
|
The NPEnumerationFunctionPtr function may pass an array of
|
||||||
|
NPIdentifiers back to the caller. The callee allocs the memory of
|
||||||
|
the array using NPN_MemAlloc(), and it's the caller's responsibility
|
||||||
|
to release it using NPN_MemFree().
|
||||||
|
*/
|
||||||
|
struct NPClass
|
||||||
|
{
|
||||||
|
uint32_t structVersion;
|
||||||
|
NPAllocateFunctionPtr allocate;
|
||||||
|
NPDeallocateFunctionPtr deallocate;
|
||||||
|
NPInvalidateFunctionPtr invalidate;
|
||||||
|
NPHasMethodFunctionPtr hasMethod;
|
||||||
|
NPInvokeFunctionPtr invoke;
|
||||||
|
NPInvokeDefaultFunctionPtr invokeDefault;
|
||||||
|
NPHasPropertyFunctionPtr hasProperty;
|
||||||
|
NPGetPropertyFunctionPtr getProperty;
|
||||||
|
NPSetPropertyFunctionPtr setProperty;
|
||||||
|
NPRemovePropertyFunctionPtr removeProperty;
|
||||||
|
NPEnumerationFunctionPtr enumerate;
|
||||||
|
NPConstructFunctionPtr construct;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NP_CLASS_STRUCT_VERSION 3
|
||||||
|
|
||||||
|
#define NP_CLASS_STRUCT_VERSION_ENUM 2
|
||||||
|
#define NP_CLASS_STRUCT_VERSION_CTOR 3
|
||||||
|
|
||||||
|
#define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \
|
||||||
|
((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM)
|
||||||
|
|
||||||
|
#define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass) \
|
||||||
|
((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR)
|
||||||
|
|
||||||
|
struct NPObject {
|
||||||
|
NPClass *_class;
|
||||||
|
uint32_t referenceCount;
|
||||||
|
/*
|
||||||
|
* Additional space may be allocated here by types of NPObjects
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
If the class has an allocate function, NPN_CreateObject invokes
|
||||||
|
that function, otherwise a NPObject is allocated and
|
||||||
|
returned. This method will initialize the referenceCount member of
|
||||||
|
the NPObject to 1.
|
||||||
|
*/
|
||||||
|
NPObject *NPN_CreateObject(NPP npp, NPClass *aClass);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Increment the NPObject's reference count.
|
||||||
|
*/
|
||||||
|
NPObject *NPN_RetainObject(NPObject *npobj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Decremented the NPObject's reference count. If the reference
|
||||||
|
count goes to zero, the class's destroy function is invoke if
|
||||||
|
specified, otherwise the object is freed directly.
|
||||||
|
*/
|
||||||
|
void NPN_ReleaseObject(NPObject *npobj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Functions to access script objects represented by NPObject.
|
||||||
|
|
||||||
|
Calls to script objects are synchronous. If a function returns a
|
||||||
|
value, it will be supplied via the result NPVariant
|
||||||
|
argument. Successful calls will return true, false will be
|
||||||
|
returned in case of an error.
|
||||||
|
|
||||||
|
Calls made from plugin code to script must be made from the thread
|
||||||
|
on which the plugin was initialized.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,
|
||||||
|
const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||||
|
bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args,
|
||||||
|
uint32_t argCount, NPVariant *result);
|
||||||
|
bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script,
|
||||||
|
NPVariant *result);
|
||||||
|
bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
|
||||||
|
NPVariant *result);
|
||||||
|
bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
|
||||||
|
const NPVariant *value);
|
||||||
|
bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
|
||||||
|
bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
|
||||||
|
bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName);
|
||||||
|
bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,
|
||||||
|
uint32_t *count);
|
||||||
|
bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args,
|
||||||
|
uint32_t argCount, NPVariant *result);
|
||||||
|
|
||||||
|
/*
|
||||||
|
NPN_SetException may be called to trigger a script exception upon
|
||||||
|
return from entry points into NPObjects. Typical usage:
|
||||||
|
|
||||||
|
NPN_SetException (npobj, message);
|
||||||
|
*/
|
||||||
|
void NPN_SetException(NPObject *npobj, const NPUTF8 *message);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
121
browser-plugin/npapi/nptypes.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* mozilla.org.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Johnny Stenback <jst@mozilla.org> (Original author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef nptypes_h_
|
||||||
|
#define nptypes_h_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header file for ensuring that C99 types ([u]int32_t, [u]int64_t and bool) and
|
||||||
|
* true/false macros are available.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(OS2)
|
||||||
|
/*
|
||||||
|
* Win32 and OS/2 don't know C99, so define [u]int_16/32/64 here. The bool
|
||||||
|
* is predefined tho, both in C and C++.
|
||||||
|
*/
|
||||||
|
typedef short int16_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef int int32_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
typedef long long int64_t;
|
||||||
|
typedef unsigned long long uint64_t;
|
||||||
|
#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX)
|
||||||
|
/*
|
||||||
|
* AIX and SunOS ship a inttypes.h header that defines [u]int32_t,
|
||||||
|
* but not bool for C.
|
||||||
|
*/
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
typedef int bool;
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#endif
|
||||||
|
#elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD)
|
||||||
|
/*
|
||||||
|
* BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and
|
||||||
|
* u_int32_t.
|
||||||
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BSD/OS ships no header that defines uint32_t, nor bool (for C)
|
||||||
|
*/
|
||||||
|
#if defined(bsdi)
|
||||||
|
typedef u_int32_t uint32_t;
|
||||||
|
typedef u_int64_t uint64_t;
|
||||||
|
|
||||||
|
#if !defined(__cplusplus)
|
||||||
|
typedef int bool;
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* FreeBSD and OpenBSD define uint32_t and bool.
|
||||||
|
*/
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
|
#elif defined(BEOS)
|
||||||
|
#include <inttypes.h>
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* For those that ship a standard C99 stdint.h header file, include
|
||||||
|
* it. Can't do the same for stdbool.h tho, since some systems ship
|
||||||
|
* with a stdbool.h file that doesn't compile!
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#if !defined(__GNUC__) || (__GNUC__ > 2 || __GNUC_MINOR__ > 95)
|
||||||
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* GCC 2.91 can't deal with a typedef for bool, but a #define
|
||||||
|
* works.
|
||||||
|
*/
|
||||||
|
#define bool int
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* nptypes_h_ */
|
178
configure.ac
@ -1,13 +1,16 @@
|
|||||||
AC_PREREQ(2.63)
|
AC_PREREQ(2.63)
|
||||||
AC_INIT([gnome-shell],[2.91.5],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
AC_INIT([gnome-shell],[3.3.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_CONFIG_AUX_DIR([config])
|
AC_CONFIG_AUX_DIR([config])
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([1.10 dist-bzip2 no-dist-gzip foreign])
|
AC_SUBST([PACKAGE_NAME], ["$PACKAGE_NAME"])
|
||||||
AM_MAINTAINER_MODE
|
AC_SUBST([PACKAGE_VERSION], ["$PACKAGE_VERSION"])
|
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz tar-ustar foreign])
|
||||||
|
AM_MAINTAINER_MODE([enable])
|
||||||
|
|
||||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||||
|
|
||||||
@ -20,19 +23,19 @@ AM_PROG_CC_C_O
|
|||||||
LT_PREREQ([2.2.6])
|
LT_PREREQ([2.2.6])
|
||||||
LT_INIT([disable-static])
|
LT_INIT([disable-static])
|
||||||
|
|
||||||
|
# i18n
|
||||||
|
IT_PROG_INTLTOOL([0.40])
|
||||||
|
|
||||||
|
AM_GNU_GETTEXT([external])
|
||||||
|
AM_GNU_GETTEXT_VERSION([0.17])
|
||||||
|
|
||||||
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.])
|
||||||
IT_PROG_INTLTOOL(0.26)
|
|
||||||
AM_GLIB_GNU_GETTEXT
|
|
||||||
|
|
||||||
PKG_PROG_PKG_CONFIG([0.22])
|
PKG_PROG_PKG_CONFIG([0.22])
|
||||||
|
|
||||||
# GConf stuff
|
|
||||||
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
|
|
||||||
AM_GCONF_SOURCE_2
|
|
||||||
|
|
||||||
GLIB_GSETTINGS
|
GLIB_GSETTINGS
|
||||||
|
|
||||||
# Get a value to substitute into gnome-shell.in
|
# Get a value to substitute into gnome-shell.in
|
||||||
@ -49,56 +52,81 @@ AC_MSG_CHECKING([for GStreamer (needed for recording functionality)])
|
|||||||
if $PKG_CONFIG --exists gstreamer-0.10 '>=' $GSTREAMER_MIN_VERSION ; then
|
if $PKG_CONFIG --exists gstreamer-0.10 '>=' $GSTREAMER_MIN_VERSION ; then
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
build_recorder=true
|
build_recorder=true
|
||||||
recorder_modules="gstreamer-0.10 gstreamer-base-0.10 xfixes"
|
recorder_modules="gstreamer-0.10 gstreamer-base-0.10 x11"
|
||||||
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0)
|
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0 xfixes)
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
||||||
|
|
||||||
CLUTTER_MIN_VERSION=1.5.8
|
CLUTTER_MIN_VERSION=1.7.5
|
||||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.6.11
|
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||||
GJS_MIN_VERSION=0.7
|
GJS_MIN_VERSION=1.29.18
|
||||||
MUTTER_MIN_VERSION=2.91.4
|
MUTTER_MIN_VERSION=3.3.2
|
||||||
GTK_MIN_VERSION=2.91.7
|
FOLKS_MIN_VERSION=0.5.2
|
||||||
GIO_MIN_VERSION=2.25.9
|
GTK_MIN_VERSION=3.0.0
|
||||||
|
GIO_MIN_VERSION=2.31.0
|
||||||
|
LIBECAL_MIN_VERSION=2.32.0
|
||||||
|
LIBEDATASERVER_MIN_VERSION=1.2.0
|
||||||
|
LIBEDATASERVERUI_MIN_VERSION=2.91.6
|
||||||
|
TELEPATHY_GLIB_MIN_VERSION=0.15.5
|
||||||
|
TELEPATHY_LOGGER_MIN_VERSION=0.2.4
|
||||||
|
POLKIT_MIN_VERSION=0.100
|
||||||
|
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
||||||
|
|
||||||
# Collect more than 20 libraries for a prize!
|
# Collect more than 20 libraries for a prize!
|
||||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION
|
PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||||
gio-unix-2.0 dbus-glib-1
|
libxml-2.0
|
||||||
gtk+-3.0 >= $GTK_MIN_VERSION
|
gtk+-3.0 >= $GTK_MIN_VERSION
|
||||||
mutter-plugins >= $MUTTER_MIN_VERSION
|
folks >= $FOLKS_MIN_VERSION
|
||||||
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
libmutter >= $MUTTER_MIN_VERSION
|
||||||
libgnome-menu $recorder_modules gconf-2.0
|
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
||||||
gdk-x11-3.0
|
libgnome-menu-3.0 $recorder_modules
|
||||||
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
gdk-x11-3.0 libsoup-2.4
|
||||||
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
||||||
libstartup-notification-1.0
|
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
||||||
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
|
libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_MIN_VERSION
|
||||||
libcanberra)
|
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
|
||||||
|
libcanberra
|
||||||
|
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
|
||||||
|
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
|
||||||
|
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
||||||
|
libnm-glib libnm-util gnome-keyring-1)
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
|
||||||
|
|
||||||
|
GJS_VERSION=`$PKG_CONFIG --modversion gjs-internals-1.0`
|
||||||
|
AC_DEFINE_UNQUOTED([GJS_VERSION], ["$GJS_VERSION"], [The version of GJS we're linking to])
|
||||||
|
AC_SUBST([GJS_VERSION], ["$GJS_VERSION"])
|
||||||
|
|
||||||
|
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
|
||||||
|
JHBUILD_TYPELIBDIR="$INTROSPECTION_TYPELIBDIR"
|
||||||
|
AC_SUBST(JHBUILD_TYPELIBDIR)
|
||||||
|
|
||||||
saved_CFLAGS=$CFLAGS
|
saved_CFLAGS=$CFLAGS
|
||||||
saved_LIBS=$LIBS
|
saved_LIBS=$LIBS
|
||||||
CFLAGS=$MUTTER_PLUGIN_CFLAGS
|
CFLAGS=$GNOME_SHELL_CFLAGS
|
||||||
LIBS=$MUTTER_PLUGIN_LIBS
|
LIBS=$GNOME_SHELL_LIBS
|
||||||
# sn_startup_sequence_get_application_id, we can replace with a version check later
|
AC_CHECK_FUNCS(JS_NewGlobalObject XFixesCreatePointerBarrier)
|
||||||
AC_CHECK_FUNCS(JS_NewGlobalObject sn_startup_sequence_get_application_id)
|
|
||||||
CFLAGS=$saved_CFLAGS
|
CFLAGS=$saved_CFLAGS
|
||||||
LIBS=$saved_LIBS
|
LIBS=$saved_LIBS
|
||||||
|
|
||||||
PKG_CHECK_MODULES(TIDY, clutter-1.0)
|
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.2 gnome-desktop-3.0 >= 2.90.0 x11)
|
||||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 gnome-desktop-3.0 >= 2.90.0)
|
|
||||||
PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-3.0)
|
|
||||||
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
|
||||||
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
|
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
|
||||||
PKG_CHECK_MODULES(JS_TEST, clutter-x11-1.0 gjs-1.0 gobject-introspection-1.0 gtk+-3.0)
|
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 0.1.7)
|
||||||
|
|
||||||
AC_MSG_CHECKING([for bluetooth support])
|
AC_MSG_CHECKING([for bluetooth support])
|
||||||
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 2.90.0],
|
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],
|
||||||
[BLUETOOTH_DIR=`$PKG_CONFIG --variable=libdir gnome-bluetooth-1.0`/gnome-bluetooth
|
[BLUETOOTH_DIR=`$PKG_CONFIG --variable=applet_libdir gnome-bluetooth-1.0`
|
||||||
BLUETOOTH_LIBS="-L'$BLUETOOTH_DIR' -lgnome-bluetooth-applet"
|
BLUETOOTH_LIBS=`$PKG_CONFIG --variable=applet_libs gnome-bluetooth-1.0`
|
||||||
AC_SUBST([BLUETOOTH_LIBS],["$BLUETOOTH_LIBS"])
|
AC_SUBST([BLUETOOTH_LIBS],["$BLUETOOTH_LIBS"])
|
||||||
|
AC_SUBST([BLUETOOTH_DIR],["$BLUETOOTH_DIR"])
|
||||||
AC_DEFINE_UNQUOTED([BLUETOOTH_DIR],["$BLUETOOTH_DIR"],[Path to installed GnomeBluetooth typelib and library])
|
AC_DEFINE_UNQUOTED([BLUETOOTH_DIR],["$BLUETOOTH_DIR"],[Path to installed GnomeBluetooth typelib and library])
|
||||||
AC_DEFINE([HAVE_BLUETOOTH],[1],[Define if you have libgnome-bluetooth-applet])
|
AC_DEFINE([HAVE_BLUETOOTH],[1],[Define if you have libgnome-bluetooth-applet])
|
||||||
AC_SUBST([HAVE_BLUETOOTH],[1])
|
AC_SUBST([HAVE_BLUETOOTH],[1])
|
||||||
@ -107,13 +135,14 @@ PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 2.90.0],
|
|||||||
AC_SUBST([HAVE_BLUETOOTH],[0])
|
AC_SUBST([HAVE_BLUETOOTH],[0])
|
||||||
AC_MSG_RESULT([no])])
|
AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
|
PKG_CHECK_MODULES(CALENDAR_SERVER, libecal-1.2 >= $LIBECAL_MIN_VERSION libedataserver-1.2 >= $LIBEDATASERVER_MIN_VERSION libedataserverui-3.0 >= $LIBEDATASERVERUI_MIN_VERSION gio-2.0)
|
||||||
# FIXME: metacity-plugins.pc should point directly to its .gir file
|
AC_SUBST(CALENDAR_SERVER_CFLAGS)
|
||||||
MUTTER_LIB_DIR=`$PKG_CONFIG --variable=libdir mutter-plugins`
|
AC_SUBST(CALENDAR_SERVER_LIBS)
|
||||||
MUTTER_PLUGIN_DIR=`$PKG_CONFIG --variable=plugindir mutter-plugins`
|
|
||||||
AC_SUBST(MUTTER_BIN_DIR)
|
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir libmutter`
|
||||||
AC_SUBST(MUTTER_LIB_DIR)
|
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter`
|
||||||
AC_SUBST(MUTTER_PLUGIN_DIR)
|
AC_SUBST(MUTTER_GIR_DIR)
|
||||||
|
AC_SUBST(MUTTER_TYPELIB_DIR)
|
||||||
|
|
||||||
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
|
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
|
||||||
AC_SUBST(GJS_CONSOLE)
|
AC_SUBST(GJS_CONSOLE)
|
||||||
@ -122,6 +151,17 @@ AC_CHECK_FUNCS(fdwalk)
|
|||||||
AC_CHECK_FUNCS(mallinfo)
|
AC_CHECK_FUNCS(mallinfo)
|
||||||
AC_CHECK_HEADERS([sys/resource.h])
|
AC_CHECK_HEADERS([sys/resource.h])
|
||||||
|
|
||||||
|
# _NL_TIME_FIRST_WEEKDAY is an enum and not a define
|
||||||
|
AC_MSG_CHECKING([for _NL_TIME_FIRST_WEEKDAY])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <langinfo.h>]],
|
||||||
|
[[nl_langinfo(_NL_TIME_FIRST_WEEKDAY);]])],
|
||||||
|
[langinfo_ok=yes], [langinfo_ok=no])
|
||||||
|
AC_MSG_RESULT($langinfo_ok)
|
||||||
|
if test "$langinfo_ok" = "yes"; then
|
||||||
|
AC_DEFINE([HAVE__NL_TIME_FIRST_WEEKDAY], [1],
|
||||||
|
[Define if _NL_TIME_FIRST_WEEKDAY is available])
|
||||||
|
fi
|
||||||
|
|
||||||
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
|
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
|
||||||
AM_PATH_GLIB_2_0()
|
AM_PATH_GLIB_2_0()
|
||||||
G_IR_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
|
G_IR_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
|
||||||
@ -135,11 +175,13 @@ AC_SUBST(GIRDIR)
|
|||||||
TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
|
TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
|
||||||
AC_SUBST(TYPELIBDIR)
|
AC_SUBST(TYPELIBDIR)
|
||||||
|
|
||||||
|
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
|
||||||
|
|
||||||
# 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,
|
||||||
AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],[Turn on compiler warnings]),,
|
AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],[Turn on compiler warnings]),,
|
||||||
enable_compile_warnings=error)
|
enable_compile_warnings=maximum)
|
||||||
|
|
||||||
changequote(,)dnl
|
changequote(,)dnl
|
||||||
if test "$enable_compile_warnings" != no ; then
|
if test "$enable_compile_warnings" != no ; then
|
||||||
@ -162,15 +204,51 @@ if test "$enable_compile_warnings" != no ; then
|
|||||||
fi
|
fi
|
||||||
changequote([,])dnl
|
changequote([,])dnl
|
||||||
|
|
||||||
AC_PATH_PROG(mutter, [mutter])
|
AC_ARG_ENABLE(jhbuild-wrapper-script,
|
||||||
AC_SUBST(mutter)
|
AS_HELP_STRING([--jhbuild-wrapper-script=yes],[Make "gnome-shell" script work for jhbuild]),,enable_jhbuild_wrapper_script=no)
|
||||||
|
AM_CONDITIONAL(USE_JHBUILD_WRAPPER_SCRIPT, test "x$enable_jhbuild_wrapper_script" = xyes)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([location of system Certificate Authority list])
|
||||||
|
AC_ARG_WITH(ca-certificates,
|
||||||
|
[AC_HELP_STRING([--with-ca-certificates=@<:@path@:>@],
|
||||||
|
[path to system Certificate Authority list])])
|
||||||
|
|
||||||
|
if test "$with_ca_certificates" = "no"; then
|
||||||
|
AC_MSG_RESULT([disabled])
|
||||||
|
else
|
||||||
|
if test -z "$with_ca_certificates"; then
|
||||||
|
for f in /etc/pki/tls/certs/ca-bundle.crt \
|
||||||
|
/etc/ssl/certs/ca-certificates.crt; do
|
||||||
|
if test -f "$f"; then
|
||||||
|
with_ca_certificates="$f"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if test -z "$with_ca_certificates"; then
|
||||||
|
AC_MSG_ERROR([could not find. Use --with-ca-certificates=path to set, or --without-ca-certificates to disable])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_RESULT($with_ca_certificates)
|
||||||
|
AC_DEFINE_UNQUOTED(SHELL_SYSTEM_CA_FILE, ["$with_ca_certificates"], [The system TLS CA list])
|
||||||
|
fi
|
||||||
|
AC_SUBST(SHELL_SYSTEM_CA_FILE,["$with_ca_certificates"])
|
||||||
|
|
||||||
|
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
|
||||||
|
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
data/Makefile
|
data/Makefile
|
||||||
|
docs/Makefile
|
||||||
|
docs/reference/Makefile
|
||||||
|
docs/reference/shell/Makefile
|
||||||
|
docs/reference/shell/shell-docs.sgml
|
||||||
|
docs/reference/st/Makefile
|
||||||
|
docs/reference/st/st-docs.sgml
|
||||||
js/Makefile
|
js/Makefile
|
||||||
js/misc/config.js
|
js/misc/config.js
|
||||||
src/Makefile
|
src/Makefile
|
||||||
|
browser-plugin/Makefile
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
man/Makefile
|
man/Makefile
|
||||||
|
@ -12,48 +12,42 @@ desktop_DATA = gnome-shell.desktop
|
|||||||
%.desktop:%.desktop.in
|
%.desktop:%.desktop.in
|
||||||
$(AM_V_GEN) sed s/^_// < $< > $@ || rm $@
|
$(AM_V_GEN) sed s/^_// < $< > $@ || rm $@
|
||||||
|
|
||||||
imagesdir = $(pkgdatadir)/images
|
searchprovidersdir = $(pkgdatadir)/search_providers
|
||||||
dist_images_DATA = \
|
dist_searchproviders_DATA = \
|
||||||
close-black.svg \
|
search_providers/google.xml \
|
||||||
magnifier.svg
|
search_providers/wikipedia.xml
|
||||||
|
|
||||||
themedir = $(pkgdatadir)/theme
|
themedir = $(pkgdatadir)/theme
|
||||||
dist_theme_DATA = \
|
dist_theme_DATA = \
|
||||||
theme/add-workspace.svg \
|
theme/calendar-arrow-left.svg \
|
||||||
|
theme/calendar-arrow-right.svg \
|
||||||
|
theme/calendar-today.svg \
|
||||||
theme/close-window.svg \
|
theme/close-window.svg \
|
||||||
theme/close.svg \
|
theme/close.svg \
|
||||||
theme/corner-ripple.png \
|
theme/corner-ripple-ltr.png \
|
||||||
|
theme/corner-ripple-rtl.png \
|
||||||
theme/dash-placeholder.svg \
|
theme/dash-placeholder.svg \
|
||||||
theme/dialog-error.svg \
|
theme/filter-selected-ltr.svg \
|
||||||
theme/filter-selected.svg \
|
theme/filter-selected-rtl.svg \
|
||||||
|
theme/gdm.css \
|
||||||
theme/gnome-shell.css \
|
theme/gnome-shell.css \
|
||||||
theme/mosaic-view-active.svg \
|
theme/panel-border.svg \
|
||||||
theme/mosaic-view.svg \
|
theme/panel-button-border.svg \
|
||||||
theme/move-window-on-new.svg \
|
theme/panel-button-highlight-narrow.svg \
|
||||||
theme/process-working.png \
|
theme/panel-button-highlight-wide.svg \
|
||||||
theme/remove-workspace.svg \
|
theme/process-working.svg \
|
||||||
theme/running-indicator.svg \
|
theme/running-indicator.svg \
|
||||||
theme/scroll-button-down-hover.png \
|
|
||||||
theme/scroll-button-down.png \
|
|
||||||
theme/scroll-button-up-hover.png \
|
|
||||||
theme/scroll-button-up.png \
|
|
||||||
theme/scroll-hhandle.svg \
|
theme/scroll-hhandle.svg \
|
||||||
theme/scroll-vhandle.svg \
|
theme/scroll-vhandle.svg \
|
||||||
theme/section-more.svg \
|
theme/source-button-border.svg \
|
||||||
theme/section-more-open.svg \
|
|
||||||
theme/separator-white.png \
|
|
||||||
theme/single-view-active.svg \
|
|
||||||
theme/single-view.svg \
|
|
||||||
theme/toggle-off-us.svg \
|
theme/toggle-off-us.svg \
|
||||||
theme/toggle-off-intl.svg \
|
theme/toggle-off-intl.svg \
|
||||||
theme/toggle-on-us.svg \
|
theme/toggle-on-us.svg \
|
||||||
theme/toggle-on-intl.svg \
|
theme/toggle-on-intl.svg \
|
||||||
theme/ws-switch-arrow-left.svg \
|
theme/ws-switch-arrow-up.svg \
|
||||||
theme/ws-switch-arrow-right.svg
|
theme/ws-switch-arrow-down.svg
|
||||||
|
|
||||||
gsettings_SCHEMAS = \
|
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
|
||||||
org.gnome.accessibility.magnifier.gschema.xml \
|
|
||||||
org.gnome.shell.gschema.xml
|
|
||||||
|
|
||||||
@INTLTOOL_XML_NOMERGE_RULE@
|
@INTLTOOL_XML_NOMERGE_RULE@
|
||||||
@GSETTINGS_RULES@
|
@GSETTINGS_RULES@
|
||||||
@ -66,30 +60,15 @@ gschemas.compiled: $(gsettings_SCHEMAS:.xml=.valid)
|
|||||||
all-local: gschemas.compiled
|
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
|
|
||||||
|
|
||||||
shadersdir = $(pkgdatadir)/shaders
|
shadersdir = $(pkgdatadir)/shaders
|
||||||
shaders_DATA = \
|
shaders_DATA = \
|
||||||
shaders/dim-window.glsl
|
shaders/dim-window.glsl
|
||||||
|
|
||||||
install-data-local:
|
|
||||||
GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$(gconfschema_DATA)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
gnome-shell.desktop.in.in \
|
gnome-shell.desktop.in.in \
|
||||||
$(menu_DATA) \
|
$(menu_DATA) \
|
||||||
$(gconfschema_DATA) \
|
|
||||||
$(shaders_DATA) \
|
$(shaders_DATA) \
|
||||||
org.gnome.accessibility.magnifier.gschema.xml.in \
|
|
||||||
org.gnome.shell.gschema.xml.in
|
org.gnome.shell.gschema.xml.in
|
||||||
|
|
||||||
CLEANFILES = \
|
CLEANFILES = \
|
||||||
|
@ -1,66 +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.1"
|
|
||||||
id="Foreground"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
width="16px"
|
|
||||||
height="16px"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
enable-background="new 0 0 16 16"
|
|
||||||
xml:space="preserve"
|
|
||||||
sodipodi:version="0.32"
|
|
||||||
inkscape:version="0.46+devel"
|
|
||||||
sodipodi:docname="close-black.svg"
|
|
||||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
|
||||||
id="metadata2399"><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><defs
|
|
||||||
id="defs2397"><linearGradient
|
|
||||||
id="linearGradient3173"><stop
|
|
||||||
style="stop-color:#c4c4c4;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop3175" /><stop
|
|
||||||
style="stop-color:#ffffff;stop-opacity:1;"
|
|
||||||
offset="1"
|
|
||||||
id="stop3177" /></linearGradient><inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 8 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="16 : 8 : 1"
|
|
||||||
inkscape:persp3d-origin="8 : 5.3333333 : 1"
|
|
||||||
id="perspective2401" /></defs><sodipodi:namedview
|
|
||||||
inkscape:window-height="811"
|
|
||||||
inkscape:window-width="1272"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
guidetolerance="10.0"
|
|
||||||
gridtolerance="10.0"
|
|
||||||
objecttolerance="10.0"
|
|
||||||
borderopacity="1.0"
|
|
||||||
bordercolor="#666666"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
id="base"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="32.125"
|
|
||||||
inkscape:cx="8"
|
|
||||||
inkscape:cy="10.440056"
|
|
||||||
inkscape:window-x="40"
|
|
||||||
inkscape:window-y="40"
|
|
||||||
inkscape:current-layer="Foreground" />
|
|
||||||
<path
|
|
||||||
fill-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"
|
|
||||||
id="path2394"
|
|
||||||
style="fill-opacity:1;fill:#545454" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.3 KiB |
@ -7,9 +7,10 @@ X-GNOME-Bugzilla-Bugzilla=GNOME
|
|||||||
X-GNOME-Bugzilla-Product=gnome-shell
|
X-GNOME-Bugzilla-Product=gnome-shell
|
||||||
X-GNOME-Bugzilla-Component=general
|
X-GNOME-Bugzilla-Component=general
|
||||||
X-GNOME-Bugzilla-Version=@VERSION@
|
X-GNOME-Bugzilla-Version=@VERSION@
|
||||||
Categories=GNOME;GTK;Utility;Core;
|
Categories=GNOME;GTK;Core;
|
||||||
OnlyShowIn=GNOME;
|
OnlyShowIn=GNOME;
|
||||||
NoDisplay=true
|
NoDisplay=true
|
||||||
X-GNOME-Autostart-Phase=WindowManager
|
X-GNOME-Autostart-Phase=WindowManager
|
||||||
X-GNOME-Provides=panel;windowmanager;
|
X-GNOME-Provides=panel;windowmanager;
|
||||||
X-GNOME-Autostart-Notify=true
|
X-GNOME-Autostart-Notify=true
|
||||||
|
X-GNOME-AutoRestart=true
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
<gconfschemafile>
|
|
||||||
<schemalist>
|
|
||||||
|
|
||||||
<!-- Metacity overrides -->
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/windows/attach_modal_dialogs</key>
|
|
||||||
<applyto>/desktop/gnome/shell/windows/attach_modal_dialogs</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>bool</type>
|
|
||||||
<default>true</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>Attach modal dialog to the parent window</short>
|
|
||||||
<long>
|
|
||||||
This key overrides /apps/mutter/general/attach_modal_dialogs when
|
|
||||||
running GNOME Shell.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/windows/button_layout</key>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/windows/edge_tiling</key>
|
|
||||||
<applyto>/desktop/gnome/shell/windows/edge_tiling</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>bool</type>
|
|
||||||
<default>true</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>enable edge tiling when dropping windows on screen edges</short>
|
|
||||||
<long>
|
|
||||||
If enabled, dropping windows on vertical screen edges maximizes them
|
|
||||||
vertically and resizes them horizontally to cover half of the
|
|
||||||
available area. Dropping windows on the top screen edge maximizes them
|
|
||||||
completely.
|
|
||||||
|
|
||||||
This key overrides /apps/metacity/general/edge_tiling when
|
|
||||||
running GNOME Shell.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
<schema>
|
|
||||||
<key>/schemas/desktop/gnome/shell/windows/theme</key>
|
|
||||||
<applyto>/desktop/gnome/shell/windows/theme</applyto>
|
|
||||||
<owner>gnome-shell</owner>
|
|
||||||
<type>string</type>
|
|
||||||
<default>Adwaita</default>
|
|
||||||
<locale name="C">
|
|
||||||
<short>Current theme</short>
|
|
||||||
<long>
|
|
||||||
The theme determines the appearance of window borders,
|
|
||||||
titlebar, and so forth.
|
|
||||||
|
|
||||||
This key overrides /apps/metacity/general/theme when
|
|
||||||
running GNOME Shell.
|
|
||||||
</long>
|
|
||||||
</locale>
|
|
||||||
</schema>
|
|
||||||
|
|
||||||
</schemalist>
|
|
||||||
</gconfschemafile>
|
|
@ -1,89 +0,0 @@
|
|||||||
<Menu>
|
|
||||||
<DefaultLayout>
|
|
||||||
<Menuname>Accessories</Menuname>
|
|
||||||
<Menuname>Games</Menuname>
|
|
||||||
<Menuname>Graphics</Menuname>
|
|
||||||
<Menuname>Internet</Menuname>
|
|
||||||
<Menuname>Multimedia</Menuname>
|
|
||||||
<Menuname>Office</Menuname>
|
|
||||||
<Menuname>Other</Menuname>
|
|
||||||
</DefaultLayout>
|
|
||||||
|
|
||||||
<Name>Applications</Name>
|
|
||||||
<AppDir>/usr/local/share/applications</AppDir>
|
|
||||||
<DefaultAppDirs/>
|
|
||||||
|
|
||||||
<Menu>
|
|
||||||
<Name>Accessories</Name>
|
|
||||||
<Include>
|
|
||||||
<And>
|
|
||||||
<Category>Utility</Category>
|
|
||||||
<Not>
|
|
||||||
<Category>System</Category>
|
|
||||||
</Not>
|
|
||||||
</And>
|
|
||||||
</Include>
|
|
||||||
</Menu>
|
|
||||||
|
|
||||||
<Menu>
|
|
||||||
<Name>Games</Name>
|
|
||||||
<Include>
|
|
||||||
<And>
|
|
||||||
<Category>Game</Category>
|
|
||||||
</And>
|
|
||||||
</Include>
|
|
||||||
</Menu>
|
|
||||||
|
|
||||||
<Menu>
|
|
||||||
<Name>Graphics</Name>
|
|
||||||
<Include>
|
|
||||||
<And>
|
|
||||||
<Category>Graphics</Category>
|
|
||||||
</And>
|
|
||||||
</Include>
|
|
||||||
</Menu>
|
|
||||||
|
|
||||||
<Menu>
|
|
||||||
<Name>Internet</Name>
|
|
||||||
<Include>
|
|
||||||
<And>
|
|
||||||
<Category>Network</Category>
|
|
||||||
<Not><Category>Settings</Category></Not>
|
|
||||||
</And>
|
|
||||||
</Include>
|
|
||||||
</Menu>
|
|
||||||
|
|
||||||
<Menu>
|
|
||||||
<Name>Multimedia</Name>
|
|
||||||
<Include>
|
|
||||||
<And>
|
|
||||||
<Category>AudioVideo</Category>
|
|
||||||
<Not><Category>Settings</Category></Not>
|
|
||||||
</And>
|
|
||||||
</Include>
|
|
||||||
</Menu>
|
|
||||||
|
|
||||||
<Menu>
|
|
||||||
<Name>Office</Name>
|
|
||||||
<Include>
|
|
||||||
<And>
|
|
||||||
<Category>Office</Category>
|
|
||||||
</And>
|
|
||||||
</Include>
|
|
||||||
</Menu>
|
|
||||||
|
|
||||||
<Menu>
|
|
||||||
<Name>Other</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>
|
|
@ -1,80 +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="18"
|
|
||||||
height="18"
|
|
||||||
viewBox="0 0 18 18"
|
|
||||||
enable-background="new 0 0 29 18"
|
|
||||||
xml:space="preserve"
|
|
||||||
sodipodi:version="0.32"
|
|
||||||
inkscape:version="0.46+devel"
|
|
||||||
sodipodi:docname="magnifier.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="9.5844061"
|
|
||||||
inkscape:cy="9.4435574"
|
|
||||||
inkscape:window-x="142"
|
|
||||||
inkscape:window-y="26"
|
|
||||||
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>
|
|
||||||
|
|
||||||
<g
|
|
||||||
id="g5"
|
|
||||||
style="fill:#ffffff;fill-opacity:1"
|
|
||||||
transform="translate(-4,-0.023114)">
|
|
||||||
<path
|
|
||||||
d="m 6.246,13.98 c -0.319,-0.319 -0.319,-0.837 0,-1.157 L 9.963,9.106 c 0.319,-0.319 0.837,-0.319 1.157,0 l 0.786,0.787 c 0.32,0.319 0.32,0.837 0,1.157 l -3.717,3.717 c -0.32,0.319 -0.838,0.319 -1.157,0 l -0.786,-0.787 0,0 z"
|
|
||||||
id="path7"
|
|
||||||
style="fill:#ffffff;fill-opacity:1" />
|
|
||||||
<path
|
|
||||||
d="M 9.076,11.937"
|
|
||||||
id="path9"
|
|
||||||
style="fill:#ffffff;fill-opacity:1" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
clip-rule="evenodd"
|
|
||||||
d="m 7.25,7.476886 c 0,-1.243 1.007,-2.25 2.2499998,-2.25 1.2430002,0 2.2500002,1.007 2.2500002,2.25 0,1.243 -1.007,2.25 -2.2500002,2.25 C 8.257,9.726886 7.25,8.719886 7.25,7.476886 z m -2.25,0 c 0,-2.485 2.015,-4.5 4.4999998,-4.5 2.4850002,0 4.5000002,2.015 4.5000002,4.5 0,2.4849998 -2.015,4.5 -4.5000002,4.5 C 7.015,11.976886 5,9.9618858 5,7.476886 z"
|
|
||||||
id="path11"
|
|
||||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.9 KiB |
@ -1,133 +0,0 @@
|
|||||||
<schemalist>
|
|
||||||
|
|
||||||
<enum id="MouseTrackingMode">
|
|
||||||
<value nick="none" value="0"/>
|
|
||||||
<value nick="centered" value="1"/>
|
|
||||||
<value nick="proportional" value="2"/>
|
|
||||||
<value nick="push" value="3"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<enum id="ScreenPosition">
|
|
||||||
<value nick="none" value="0"/>
|
|
||||||
<value nick="full-screen" value="1"/>
|
|
||||||
<value nick="top-half" value="2"/>
|
|
||||||
<value nick="bottom-half" value="3"/>
|
|
||||||
<value nick="left-half" value="4"/>
|
|
||||||
<value nick="right-half" value="5"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<schema id="org.gnome.accessibility.magnifier"
|
|
||||||
path="/desktop/gnome/accessibility/magnifier/"
|
|
||||||
gettext-domain="@GETTEXT_PACKAGE@">
|
|
||||||
<key name="show-magnifier" type="b">
|
|
||||||
<default>false</default>
|
|
||||||
<_summary>Show or hide the magnifier</_summary>
|
|
||||||
<_description>
|
|
||||||
Show or hide the magnifier and all of its zoom regions.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="mouse-tracking" enum="MouseTrackingMode">
|
|
||||||
<default>'proportional'</default>
|
|
||||||
<_summary>Mouse Tracking Mode</_summary>
|
|
||||||
<_description>
|
|
||||||
Determines the position of the magnified mouse image within the
|
|
||||||
magnified view and how it reacts to system mouse movement. The values
|
|
||||||
are
|
|
||||||
- none: no mouse tracking;
|
|
||||||
- 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;
|
|
||||||
- proportional: the position of the magnified mouse in the zoom region
|
|
||||||
is proportionally the same as the position of the system mouse on screen;
|
|
||||||
- push: when the magnified mouse intersects a boundary of the zoom
|
|
||||||
region, the contents are scrolled into view.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="screen-position" enum="ScreenPosition">
|
|
||||||
<default>'full-screen'</default>
|
|
||||||
<_summary>Screen position</_summary>
|
|
||||||
<_description>
|
|
||||||
The magnified view either fills the entire screen, or occupies the
|
|
||||||
top-half, bottom-half, left-half, or right-half of the screen.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="mag-factor" type="d">
|
|
||||||
<default>2.0</default>
|
|
||||||
<_summary>Magnification factor</_summary>
|
|
||||||
<_description>
|
|
||||||
The power of the magnification. A value of 1.0 means no magnification.
|
|
||||||
A value of 2.0 doubles the size.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="lens-mode" type="b">
|
|
||||||
<default>false</default>
|
|
||||||
<_summary>Enable lens mode</_summary>
|
|
||||||
<_description>
|
|
||||||
Whether the magnified view should be centered over the location of
|
|
||||||
the system mouse and move with it.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="scroll-at-edges" type="b">
|
|
||||||
<default>false</default>
|
|
||||||
<_summary>
|
|
||||||
Scroll magnified contents beyond the edges of the desktop
|
|
||||||
</_summary>
|
|
||||||
<_description>
|
|
||||||
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.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
|
|
||||||
<!-- Cross-hairs -->
|
|
||||||
<key name="show-cross-hairs" type="b">
|
|
||||||
<default>false</default>
|
|
||||||
<_summary>Show or hide crosshairs</_summary>
|
|
||||||
<_description>
|
|
||||||
Enables/disables display of crosshairs centered on the magnified
|
|
||||||
mouse sprite.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="cross-hairs-thickness" type="i">
|
|
||||||
<default>8</default>
|
|
||||||
<_summary>Thickness of the crosshairs</_summary>
|
|
||||||
<_description>
|
|
||||||
Width of the vertical and horizontal lines that make up the crosshairs.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="cross-hairs-color" type="s">
|
|
||||||
<default>'#ff0000'</default>
|
|
||||||
<_summary>Color of the crosshairs</_summary>
|
|
||||||
<_description>
|
|
||||||
The color of the the vertical and horizontal lines that make up
|
|
||||||
the crosshairs.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="cross-hairs-opacity" type="i">
|
|
||||||
<default>169</default>
|
|
||||||
<_summary>Opacity of the crosshairs</_summary>
|
|
||||||
<_description>
|
|
||||||
Determines the transparency of the crosshairs, from fully opaque
|
|
||||||
to fully transparent.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="cross-hairs-length" type="i">
|
|
||||||
<default>4096</default>
|
|
||||||
<_summary>Length of the crosshairs</_summary>
|
|
||||||
<_description>
|
|
||||||
Determines the length of the vertical and horizontal lines that
|
|
||||||
make up the crosshairs.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
<key name="cross-hairs-clip" type="b">
|
|
||||||
<default>false</default>
|
|
||||||
<_summary>Clip the crosshairs at the center</_summary>
|
|
||||||
<_description>
|
|
||||||
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.
|
|
||||||
</_description>
|
|
||||||
</key>
|
|
||||||
</schema>
|
|
||||||
</schemalist>
|
|
@ -1,5 +1,5 @@
|
|||||||
<schemalist>
|
<schemalist>
|
||||||
<schema id="org.gnome.shell" path="/apps/gnome-shell/"
|
<schema id="org.gnome.shell" path="/org/gnome/shell/"
|
||||||
gettext-domain="@GETTEXT_PACKAGE@">
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
<key name="development-tools" type="b">
|
<key name="development-tools" type="b">
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
@ -11,12 +11,14 @@
|
|||||||
using the Alt-F2 dialog.
|
using the Alt-F2 dialog.
|
||||||
</_description>
|
</_description>
|
||||||
</key>
|
</key>
|
||||||
<key name="disabled-extensions" type="as">
|
<key name="enabled-extensions" type="as">
|
||||||
<default>[]</default>
|
<default>[]</default>
|
||||||
<_summary>Uuids of extensions to disable</_summary>
|
<_summary>Uuids of extensions to enable</_summary>
|
||||||
<_description>
|
<_description>
|
||||||
GNOME Shell extensions have a uuid property;
|
GNOME Shell extensions have a uuid property; this key lists extensions
|
||||||
this key lists extensions which should not be loaded.
|
which should be loaded. Any extension that wants to be loaded needs
|
||||||
|
to be in this list. You can also manipulate this list with the
|
||||||
|
EnableExtension and DisableExtension DBus methods on org.gnome.Shell.
|
||||||
</_description>
|
</_description>
|
||||||
</key>
|
</key>
|
||||||
<key name="enable-app-monitoring" type="b">
|
<key name="enable-app-monitoring" type="b">
|
||||||
@ -30,23 +32,40 @@
|
|||||||
</_description>
|
</_description>
|
||||||
</key>
|
</key>
|
||||||
<key name="favorite-apps" type="as">
|
<key name="favorite-apps" type="as">
|
||||||
<default>[ 'mozilla-firefox.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'openoffice.org-writer.desktop', 'nautilus.desktop' ]</default>
|
<default>[ 'epiphany.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop' ]</default>
|
||||||
<_summary>List of desktop file IDs for favorite applications</_summary>
|
<_summary>List of desktop file IDs for favorite applications</_summary>
|
||||||
<_description>
|
<_description>
|
||||||
The applications corresponding to these identifiers
|
The applications corresponding to these identifiers
|
||||||
will be displayed in the favorites area.
|
will be displayed in the favorites area.
|
||||||
</_description>
|
</_description>
|
||||||
</key>
|
</key>
|
||||||
|
<key name="disabled-open-search-providers" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<_summary>disabled OpenSearch providers</_summary>
|
||||||
|
</key>
|
||||||
<key name="command-history" type="as">
|
<key name="command-history" type="as">
|
||||||
<default>[]</default>
|
<default>[]</default>
|
||||||
<_summary>History for command (Alt-F2) dialog</_summary>
|
<_summary>History for command (Alt-F2) dialog</_summary>
|
||||||
</key>
|
</key>
|
||||||
|
<key name="looking-glass-history" type="as">
|
||||||
|
<default>[]</default>
|
||||||
|
<_summary>History for the looking glass dialog</_summary>
|
||||||
|
</key>
|
||||||
|
<key name="saved-im-presence" type="i">
|
||||||
|
<default>1</default>
|
||||||
|
<_summary></_summary>
|
||||||
|
</key>
|
||||||
|
<key name="saved-session-presence" type="i">
|
||||||
|
<default>0</default>
|
||||||
|
<_summary></_summary>
|
||||||
|
</key>
|
||||||
<child name="clock" schema="org.gnome.shell.clock"/>
|
<child name="clock" schema="org.gnome.shell.clock"/>
|
||||||
<child name="calendar" schema="org.gnome.shell.calendar"/>
|
<child name="calendar" schema="org.gnome.shell.calendar"/>
|
||||||
<child name="recorder" schema="org.gnome.shell.recorder"/>
|
<child name="recorder" schema="org.gnome.shell.recorder"/>
|
||||||
|
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
<schema id="org.gnome.shell.calendar" path="/apps/gnome-shell/calendar/"
|
<schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/"
|
||||||
gettext-domain="@GETTEXT_PACKAGE@">
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
<key name="show-weekdate" type="b">
|
<key name="show-weekdate" type="b">
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
@ -57,7 +76,18 @@
|
|||||||
</key>
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
<schema id="org.gnome.shell.clock" path="/apps/gnome-shell/clock/"
|
<schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/"
|
||||||
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
|
<key name="keyboard-type" type="s">
|
||||||
|
<default>'touch'</default>
|
||||||
|
<_summary>Which keyboard to use</_summary>
|
||||||
|
<_description>
|
||||||
|
The type of keyboard to use.
|
||||||
|
</_description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
|
||||||
|
<schema id="org.gnome.shell.clock" path="/org/gnome/shell/clock/"
|
||||||
gettext-domain="@GETTEXT_PACKAGE@">
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
<key name="show-seconds" type="b">
|
<key name="show-seconds" type="b">
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
@ -75,7 +105,7 @@
|
|||||||
</key>
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
<schema id="org.gnome.shell.recorder" path="/apps/gnome-shell/recorder/"
|
<schema id="org.gnome.shell.recorder" path="/org/gnome/shell/recorder/"
|
||||||
gettext-domain="@GETTEXT_PACKAGE@">
|
gettext-domain="@GETTEXT_PACKAGE@">
|
||||||
<key name="framerate" type="i">
|
<key name="framerate" type="i">
|
||||||
<default>15</default>
|
<default>15</default>
|
||||||
@ -97,11 +127,13 @@
|
|||||||
take care of its own output - this might be used to send the output
|
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 icecast server via shout2send or similar. When unset or set
|
||||||
to an empty value, the default pipeline will be used. This is currently
|
to an empty value, the default pipeline will be used. This is currently
|
||||||
'videorate ! theoraenc ! oggmux' and records to Ogg Theora.
|
'videorate ! vp8enc quality=10 speed=2 threads=%T ! queue ! webmmux'
|
||||||
|
and records to WEBM using the VP8 codec. %T is used as a placeholder
|
||||||
|
for a guess at the optimal thread count on the system.
|
||||||
</_description>
|
</_description>
|
||||||
</key>
|
</key>
|
||||||
<key name="file-extension" type="s">
|
<key name="file-extension" type="s">
|
||||||
<default>'ogv'</default>
|
<default>'webm'</default>
|
||||||
<_summary>File extension used for storing the screencast</_summary>
|
<_summary>File extension used for storing the screencast</_summary>
|
||||||
<_description>
|
<_description>
|
||||||
The filename for recorded screencasts will be a unique filename
|
The filename for recorded screencasts will be a unique filename
|
||||||
@ -110,4 +142,40 @@
|
|||||||
</_description>
|
</_description>
|
||||||
</key>
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
|
<schema id="org.gnome.shell.overrides" path="/org/gnome/shell/overrides/">
|
||||||
|
<key name="attach-modal-dialogs" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Attach modal dialog to the parent window</summary>
|
||||||
|
<description>
|
||||||
|
This key overrides the key in org.gnome.mutter when running
|
||||||
|
GNOME Shell.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="button-layout" type="s">
|
||||||
|
<default>":close"</default>
|
||||||
|
<summary>Arrangement of buttons on the titlebar</summary>
|
||||||
|
<description>
|
||||||
|
This key overrides the key in org.gnome.desktop.wm.preferences when
|
||||||
|
running GNOME Shell.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="edge-tiling" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Enable edge tiling when dropping windows on screen edges</summary>
|
||||||
|
<description>
|
||||||
|
This key overrides the key in org.gnome.mutter when running GNOME Shell.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
|
|
||||||
|
<key name="workspaces-only-on-primary" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Workspaces only on primary monitor</summary>
|
||||||
|
<description>
|
||||||
|
This key overrides the key in org.gnome.mutter when running GNOME Shell.
|
||||||
|
</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
</schemalist>
|
</schemalist>
|
||||||
|
7
data/search_providers/google.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
|
||||||
|
<ShortName>Google</ShortName>
|
||||||
|
<Description>Google Search</Description>
|
||||||
|
<InputEncoding>UTF-8</InputEncoding>
|
||||||
|
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA</Image>
|
||||||
|
<Url type="text/html" method="GET" template="http://www.google.com/search?q={searchTerms}"/>
|
||||||
|
</OpenSearchDescription>
|
44
data/search_providers/wikipedia.xml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
|
||||||
|
<ShortName>Wikipedia</ShortName>
|
||||||
|
<Description>Wikipedia, the free encyclopedia</Description>
|
||||||
|
<InputEncoding>UTF-8</InputEncoding>
|
||||||
|
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAEAgQAhIOEAMjHyABIR0gA6ejpAGlqaQCpqKkAKCgoAPz9%2FAAZGBkAmJiYANjZ2ABXWFcAent6ALm6uQA8OjwAiIiIiIiIiIiIiI4oiL6IiIiIgzuIV4iIiIhndo53KIiIiB%2FWvXoYiIiIfEZfWBSIiIEGi%2FfoqoiIgzuL84i9iIjpGIoMiEHoiMkos3FojmiLlUipYliEWIF%2BiDe0GoRa7D6GPbjcu1yIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
|
||||||
|
<Url type="text/html" method="GET" template="http://{language}.wikipedia.org/wiki/Special:Search?search={searchTerms}"/>
|
||||||
|
<!-- The criterion for being below is being listed with more than 100,000
|
||||||
|
articles on http://meta.wikimedia.org/wiki/List_of_Wikipedias -->
|
||||||
|
<Language>ar</Language>
|
||||||
|
<Language>bg</Language>
|
||||||
|
<Language>ca</Language>
|
||||||
|
<Language>cs</Language>
|
||||||
|
<Language>da</Language>
|
||||||
|
<Language>de</Language>
|
||||||
|
<Language>en</Language>
|
||||||
|
<Language>eo</Language>
|
||||||
|
<Language>es</Language>
|
||||||
|
<Language>fa</Language>
|
||||||
|
<Language>fi</Language>
|
||||||
|
<Language>fr</Language>
|
||||||
|
<Language>he</Language>
|
||||||
|
<Language>hu</Language>
|
||||||
|
<Language>id</Language>
|
||||||
|
<Language>it</Language>
|
||||||
|
<Language>ja</Language>
|
||||||
|
<Language>ko</Language>
|
||||||
|
<Language>lt</Language>
|
||||||
|
<Language>nl</Language>
|
||||||
|
<Language>no</Language>
|
||||||
|
<Language>pl</Language>
|
||||||
|
<Language>pt</Language>
|
||||||
|
<Language>ro</Language>
|
||||||
|
<Language>ru</Language>
|
||||||
|
<Language>sk</Language>
|
||||||
|
<Language>sl</Language>
|
||||||
|
<Language>sr</Language>
|
||||||
|
<Language>sv</Language>
|
||||||
|
<Language>tr</Language>
|
||||||
|
<Language>uk</Language>
|
||||||
|
<Language>vi</Language>
|
||||||
|
<Language>vo</Language>
|
||||||
|
<Language>war</Language>
|
||||||
|
<Language>zh</Language>
|
||||||
|
</OpenSearchDescription>
|
@ -1,5 +1,5 @@
|
|||||||
#version 110
|
#version 110
|
||||||
uniform sampler2D sampler0;
|
uniform sampler2D tex;
|
||||||
uniform float fraction;
|
uniform float fraction;
|
||||||
uniform float height;
|
uniform float height;
|
||||||
const float c = -0.2;
|
const float c = -0.2;
|
||||||
@ -12,15 +12,16 @@ mat4 contrast = mat4 (1.0 + c, 0.0, 0.0, 0.0,
|
|||||||
vec4 off = vec4(0.633, 0.633, 0.633, 0);
|
vec4 off = vec4(0.633, 0.633, 0.633, 0);
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 color = texture2D(sampler0, gl_TexCoord[0].st);
|
vec4 color = texture2D(tex, cogl_tex_coord_in[0].xy);
|
||||||
float y = height * gl_TexCoord[0][1];
|
float y = height * cogl_tex_coord_in[0].y;
|
||||||
|
|
||||||
// To reduce contrast, blend with a mid gray
|
// To reduce contrast, blend with a mid gray
|
||||||
gl_FragColor = color * contrast - off * c;
|
cogl_color_out = color * contrast - off * c * color.a;
|
||||||
|
|
||||||
// We only fully dim at a distance of BORDER_MAX_HEIGHT from the edge and
|
// We only fully dim at a distance of BORDER_MAX_HEIGHT from the top and
|
||||||
// when the fraction is 1.0. For other locations and fractions we linearly
|
// when the fraction is 1.0. For other locations and fractions we linearly
|
||||||
// interpolate back to the original undimmed color.
|
// interpolate back to the original undimmed color, so the top of the window
|
||||||
gl_FragColor = color + (gl_FragColor - color) * min(y / border_max_height, 1.0);
|
// is at full color.
|
||||||
gl_FragColor = color + (gl_FragColor - color) * fraction;
|
cogl_color_out = color + (cogl_color_out - color) * max(min(y / border_max_height, 1.0), 0.0);
|
||||||
|
cogl_color_out = color + (cogl_color_out - color) * fraction;
|
||||||
}
|
}
|
||||||
|
@ -1,98 +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="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>
|
|
Before Width: | Height: | Size: 3.2 KiB |
85
data/theme/section-more.svg → data/theme/calendar-arrow-left.svg
Executable file → Normal file
@ -9,29 +9,14 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="5.8600588"
|
width="16"
|
||||||
height="9"
|
height="16"
|
||||||
id="svg3647"
|
id="svg2"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
inkscape:version="0.46+devel"
|
inkscape:version="0.48+devel r9942 custom"
|
||||||
sodipodi:docname="New document 6">
|
sodipodi:docname="New document 4">
|
||||||
<defs
|
<defs
|
||||||
id="defs3649">
|
id="defs4" />
|
||||||
<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
|
<sodipodi:namedview
|
||||||
id="base"
|
id="base"
|
||||||
pagecolor="#ffffff"
|
pagecolor="#ffffff"
|
||||||
@ -39,19 +24,29 @@
|
|||||||
borderopacity="1.0"
|
borderopacity="1.0"
|
||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0.0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="0.35"
|
inkscape:zoom="1"
|
||||||
inkscape:cx="112.21575"
|
inkscape:cx="8.984481"
|
||||||
inkscape:cy="-32.642856"
|
inkscape:cy="5.6224906"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:window-width="609"
|
borderlayer="true"
|
||||||
inkscape:window-height="501"
|
inkscape:showpageshadow="false"
|
||||||
inkscape:window-x="164"
|
inkscape:window-width="930"
|
||||||
inkscape:window-y="26"
|
inkscape:window-height="681"
|
||||||
inkscape:window-maximized="0" />
|
inkscape:window-x="1892"
|
||||||
|
inkscape:window-y="272"
|
||||||
|
inkscape:window-maximized="0">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid17403"
|
||||||
|
empspacing="5"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true" />
|
||||||
|
</sodipodi:namedview>
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata3652">
|
id="metadata7">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
<cc:Work
|
<cc:Work
|
||||||
rdf:about="">
|
rdf:about="">
|
||||||
@ -66,22 +61,22 @@
|
|||||||
inkscape:label="Layer 1"
|
inkscape:label="Layer 1"
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer1"
|
id="layer1"
|
||||||
transform="translate(-262.78425,-490.71933)">
|
transform="translate(0,-1036.3622)">
|
||||||
<path
|
<path
|
||||||
transform="matrix(0,0.98149546,-0.71467449,0,506.02358,412.28296)"
|
sodipodi:type="star"
|
||||||
d="M 88.830127,340 80.169873,340 84.5,332.5 88.830127,340 z"
|
style="fill:#5f5f5f;fill-opacity:1;stroke:#5f5f5f;stroke-width:0.43015847;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||||
inkscape:randomized="0"
|
id="path18028"
|
||||||
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"
|
sodipodi:sides="3"
|
||||||
id="path5497-5"
|
sodipodi:cx="84.5"
|
||||||
style="fill:#5f5f5f;fill-opacity:1;stroke:#5f5f5f;stroke-width:0.59699643;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
sodipodi:cy="337.5"
|
||||||
sodipodi:type="star" />
|
sodipodi:r1="5"
|
||||||
|
sodipodi:r2="2.5"
|
||||||
|
sodipodi:arg1="0.52359878"
|
||||||
|
sodipodi:arg2="1.5707963"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="M 88.830127,340 80.169873,340 84.5,332.5 z"
|
||||||
|
transform="matrix(0,1.3621708,0.99186247,0,-325.48222,929.32667)" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.5 KiB |
@ -9,29 +9,14 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="5.8600588"
|
width="16"
|
||||||
height="9"
|
height="16"
|
||||||
id="svg3647"
|
id="svg2"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
inkscape:version="0.47 r22583"
|
inkscape:version="0.48+devel r9942 custom"
|
||||||
sodipodi:docname="section-more.svg">
|
sodipodi:docname="arrow-left.svg">
|
||||||
<defs
|
<defs
|
||||||
id="defs3649">
|
id="defs4" />
|
||||||
<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
|
<sodipodi:namedview
|
||||||
id="base"
|
id="base"
|
||||||
pagecolor="#ffffff"
|
pagecolor="#ffffff"
|
||||||
@ -39,19 +24,29 @@
|
|||||||
borderopacity="1.0"
|
borderopacity="1.0"
|
||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0.0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="82.777778"
|
inkscape:zoom="1"
|
||||||
inkscape:cx="2.9300294"
|
inkscape:cx="7.7366092"
|
||||||
inkscape:cy="5.466443"
|
inkscape:cy="6.4536271"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:window-width="1680"
|
borderlayer="true"
|
||||||
inkscape:window-height="997"
|
inkscape:showpageshadow="false"
|
||||||
inkscape:window-x="0"
|
inkscape:window-width="930"
|
||||||
inkscape:window-y="26"
|
inkscape:window-height="681"
|
||||||
inkscape:window-maximized="1" />
|
inkscape:window-x="1892"
|
||||||
|
inkscape:window-y="272"
|
||||||
|
inkscape:window-maximized="0">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid17403"
|
||||||
|
empspacing="5"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true" />
|
||||||
|
</sodipodi:namedview>
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata3652">
|
id="metadata7">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
<cc:Work
|
<cc:Work
|
||||||
rdf:about="">
|
rdf:about="">
|
||||||
@ -66,22 +61,22 @@
|
|||||||
inkscape:label="Layer 1"
|
inkscape:label="Layer 1"
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer1"
|
id="layer1"
|
||||||
transform="translate(-262.78425,-490.71933)">
|
transform="translate(0,-1036.3622)">
|
||||||
<path
|
<path
|
||||||
transform="matrix(0,-0.98149546,0.71467449,0,25.404986,578.15569)"
|
sodipodi:type="star"
|
||||||
d="M 88.830127,340 80.169873,340 84.5,332.5 88.830127,340 z"
|
style="fill:#5f5f5f;fill-opacity:1;stroke:#5f5f5f;stroke-width:0.43015847;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||||
inkscape:randomized="0"
|
id="path18028"
|
||||||
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"
|
sodipodi:sides="3"
|
||||||
id="path5497-5"
|
sodipodi:cx="84.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:cy="337.5"
|
||||||
sodipodi:type="star" />
|
sodipodi:r1="5"
|
||||||
|
sodipodi:r2="2.5"
|
||||||
|
sodipodi:arg1="0.52359878"
|
||||||
|
sodipodi:arg2="1.5707963"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="M 88.830127,340 80.169873,340 84.5,332.5 z"
|
||||||
|
transform="matrix(0,1.3621708,-0.99186247,0,342.48324,929.32667)" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.5 KiB |
187
data/theme/calendar-today.svg
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
<?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="28"
|
||||||
|
height="25"
|
||||||
|
id="svg10621"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.1 r9760"
|
||||||
|
sodipodi:docname="calendar-today.svg">
|
||||||
|
<defs
|
||||||
|
id="defs10623">
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
id="radialGradient99561-1"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
cx="51"
|
||||||
|
cy="30"
|
||||||
|
fx="51"
|
||||||
|
fy="30"
|
||||||
|
r="42" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient34508-1-3">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop34510-1-9" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop34512-4-5" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
r="42"
|
||||||
|
fy="30"
|
||||||
|
fx="51"
|
||||||
|
cy="30"
|
||||||
|
cx="51"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient10592"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
id="radialGradient3770"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
cx="51"
|
||||||
|
cy="30"
|
||||||
|
fx="51"
|
||||||
|
fy="30"
|
||||||
|
r="42" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
id="radialGradient3001"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
cx="51"
|
||||||
|
cy="30"
|
||||||
|
fx="51"
|
||||||
|
fy="30"
|
||||||
|
r="42" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
id="radialGradient3007"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
cx="51"
|
||||||
|
cy="30"
|
||||||
|
fx="51"
|
||||||
|
fy="30"
|
||||||
|
r="42" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
id="radialGradient3067"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
cx="51"
|
||||||
|
cy="30"
|
||||||
|
fx="51"
|
||||||
|
fy="30"
|
||||||
|
r="42" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
id="radialGradient3072"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
cx="51"
|
||||||
|
cy="30"
|
||||||
|
fx="51"
|
||||||
|
fy="30"
|
||||||
|
r="42" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
id="radialGradient2997"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
cx="51"
|
||||||
|
cy="30"
|
||||||
|
fx="51"
|
||||||
|
fy="30"
|
||||||
|
r="42" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="15.839192"
|
||||||
|
inkscape:cx="8.3750933"
|
||||||
|
inkscape:cy="8.0837211"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="843"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata10626">
|
||||||
|
<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"
|
||||||
|
transform="translate(-469.08263,-536.99307)">
|
||||||
|
<g
|
||||||
|
id="g3003">
|
||||||
|
<path
|
||||||
|
inkscape:export-ydpi="90"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png"
|
||||||
|
transform="matrix(0.43692393,0,0,1.3783114,460.60467,517.48289)"
|
||||||
|
sodipodi:end="6.2831853"
|
||||||
|
sodipodi:start="3.1415927"
|
||||||
|
d="M 9,29.999999 C 9.0000011,21.163443 27.804042,14 51.000002,14 74.195961,14 93,21.163444 93,30 l -42,0 z"
|
||||||
|
sodipodi:ry="16"
|
||||||
|
sodipodi:rx="42"
|
||||||
|
sodipodi:cy="30"
|
||||||
|
sodipodi:cx="51"
|
||||||
|
id="path34506-3"
|
||||||
|
style="opacity:0.4625;color:#000000;fill:url(#radialGradient2997);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<rect
|
||||||
|
y="558.85046"
|
||||||
|
x="468.96878"
|
||||||
|
height="3.1425927"
|
||||||
|
width="28.149134"
|
||||||
|
id="rect2996"
|
||||||
|
style="fill:#ffffff;fill-opacity:0.50196078;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.7 KiB |
@ -1,24 +1,26 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?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) -->
|
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
xmlns="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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
version="1.0"
|
version="1.0"
|
||||||
id="Foreground"
|
id="Foreground"
|
||||||
x="0px"
|
x="0px"
|
||||||
y="0px"
|
y="0px"
|
||||||
width="22"
|
width="32"
|
||||||
height="22"
|
height="32"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 23.272727 23.272727"
|
||||||
enable-background="new 0 0 16 16"
|
enable-background="new 0 0 16 16"
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
sodipodi:version="0.32"
|
sodipodi:version="0.32"
|
||||||
inkscape:version="0.46"
|
inkscape:version="0.48+devel r10081 custom"
|
||||||
sodipodi:docname="close-window.svg"
|
sodipodi:docname="close-window.svg"
|
||||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
||||||
id="metadata2399"><rdf:RDF><cc:Work
|
id="metadata2399"><rdf:RDF><cc:Work
|
||||||
@ -37,11 +39,49 @@
|
|||||||
inkscape:vp_y="0 : 1000 : 0"
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
inkscape:vp_z="16 : 8 : 1"
|
inkscape:vp_z="16 : 8 : 1"
|
||||||
inkscape:persp3d-origin="8 : 5.3333333 : 1"
|
inkscape:persp3d-origin="8 : 5.3333333 : 1"
|
||||||
id="perspective2401" /></defs><sodipodi:namedview
|
id="perspective2401" /><filter
|
||||||
inkscape:window-height="999"
|
color-interpolation-filters="sRGB"
|
||||||
inkscape:window-width="1680"
|
inkscape:collect="always"
|
||||||
|
id="filter16494-4"
|
||||||
|
x="-0.20989846"
|
||||||
|
width="1.4197969"
|
||||||
|
y="-0.20903821"
|
||||||
|
height="1.4180764"><feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="1.3282637"
|
||||||
|
id="feGaussianBlur16496-8" /></filter><radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient16498-6"
|
||||||
|
id="radialGradient16504-1"
|
||||||
|
cx="7.6582627"
|
||||||
|
cy="5.8191104"
|
||||||
|
fx="7.6582627"
|
||||||
|
fy="5.8191104"
|
||||||
|
r="8.6928644"
|
||||||
|
gradientTransform="matrix(1.0474339,0,0,1.0517402,-0.3632615,-0.42032492)"
|
||||||
|
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient16498-6"><stop
|
||||||
|
style="stop-color:#7b7b7b;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop16500-8" /><stop
|
||||||
|
style="stop-color:#101010;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop16502-0" /></linearGradient><filter
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="filter16524-9"
|
||||||
|
x="-0.212979"
|
||||||
|
width="1.425958"
|
||||||
|
y="-0.21305652"
|
||||||
|
height="1.426113"><feGaussianBlur
|
||||||
|
inkscape:collect="always"
|
||||||
|
stdDeviation="0.71020915"
|
||||||
|
id="feGaussianBlur16526-0" /></filter></defs><sodipodi:namedview
|
||||||
|
inkscape:window-height="1114"
|
||||||
|
inkscape:window-width="1463"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:pageopacity="1"
|
inkscape:pageopacity="0"
|
||||||
guidetolerance="10.0"
|
guidetolerance="10.0"
|
||||||
gridtolerance="10.0"
|
gridtolerance="10.0"
|
||||||
objecttolerance="10.0"
|
objecttolerance="10.0"
|
||||||
@ -50,27 +90,63 @@
|
|||||||
pagecolor="#000000"
|
pagecolor="#000000"
|
||||||
id="base"
|
id="base"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:zoom="25.648691"
|
inkscape:zoom="1"
|
||||||
inkscape:cx="8.8097603"
|
inkscape:cx="10.720189"
|
||||||
inkscape:cy="9.0472789"
|
inkscape:cy="13.739577"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="26"
|
inkscape:window-y="26"
|
||||||
inkscape:current-layer="Foreground"
|
inkscape:current-layer="Foreground"
|
||||||
showguides="true"
|
showguides="true"
|
||||||
inkscape:guide-bbox="true" />
|
inkscape:guide-bbox="true"
|
||||||
|
borderlayer="true"
|
||||||
|
inkscape:showpageshadow="false"
|
||||||
|
inkscape:window-maximized="0"><inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid11246"
|
||||||
|
empspacing="5"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true" /></sodipodi:namedview>
|
||||||
|
|
||||||
<g
|
<g
|
||||||
id="g3175"><path
|
style="display:inline"
|
||||||
sodipodi:nodetypes="csssc"
|
id="g16402-8"
|
||||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.59217799;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
transform="translate(4.7533483,2.8238929)"><g
|
||||||
id="path2394"
|
id="g3175-4"><path
|
||||||
d="M 0.83987936,8.0425327 C 0.83987936,4.0805265 4.0712155,0.86823453 8.0567103,0.86823453 C 12.042205,0.86823453 15.273542,4.0805265 15.273542,8.0425327 C 15.273542,12.004539 12.042205,15.216831 8.0567103,15.216831 C 4.0712155,15.216831 0.83987936,12.004539 0.83987936,8.0425327 z"
|
sodipodi:type="inkscape:offset"
|
||||||
clip-rule="evenodd" /><g
|
inkscape:radius="0"
|
||||||
id="g3172"><path
|
inkscape:original="M 7.65625 0.125 C 3.2589349 0.125 -0.3125 3.7070002 -0.3125 8.125 C -0.3125 12.543001 3.2589349 16.125 7.65625 16.125 C 12.053566 16.125 15.625 12.543001 15.625 8.125 C 15.625 3.7070002 12.053566 0.125 7.65625 0.125 z "
|
||||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.67127273;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
xlink:href="#path2394-32"
|
||||||
d="M 5.4242673,5.3313047 L 10.515414,10.421272 L 10.714004,10.646491"
|
style="opacity:0.52994014;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.18181825;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;filter:url(#filter16494-4);enable-background:accumulate"
|
||||||
id="path3152" /></g></g><path
|
id="path16480-5"
|
||||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.67127273;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
inkscape:href="#path2394-32"
|
||||||
d="M 5.4402527,10.650392 L 10.688082,5.3573033"
|
d="m 7.65625,0.125 c -4.3973151,0 -7.96875,3.5820002 -7.96875,8 0,4.418001 3.5714349,8 7.96875,8 4.397316,0 7.96875,-3.581999 7.96875,-8 0,-4.4179998 -3.571434,-8 -7.96875,-8 z"
|
||||||
id="path3154"
|
transform="translate(0,1.028519)" /><path
|
||||||
sodipodi:nodetypes="cc" /></svg>
|
clip-rule="evenodd"
|
||||||
|
d="m -0.30428257,8.1237596 c 0,-4.4179998 3.56522987,-7.9999996 7.96254497,-7.9999996 4.3973156,0 7.9625456,3.5819998 7.9625456,7.9999996 0,4.4180014 -3.56523,8.0000004 -7.9625456,8.0000004 -4.3973151,0 -7.96254497,-3.581999 -7.96254497,-8.0000004 z"
|
||||||
|
id="path2394-32"
|
||||||
|
style="color:#000000;fill:url(#radialGradient16504-1);fill-opacity:1;fill-rule:nonzero;stroke:#eeeeec;stroke-width:1.4545455;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;enable-background:accumulate"
|
||||||
|
sodipodi:nodetypes="csssc"
|
||||||
|
inkscape:connector-curvature="0" /><g
|
||||||
|
id="g3172-6" /></g><g
|
||||||
|
transform="matrix(0.72727273,0,0,0.72727273,2.368236,2.1803254)"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;display:inline"
|
||||||
|
id="g27275-6-6"
|
||||||
|
inkscape:label="window-close"><g
|
||||||
|
style="fill:#ffffff;fill-opacity:1;display:inline"
|
||||||
|
id="g27277-1-1"
|
||||||
|
transform="translate(-41,-760)"><path
|
||||||
|
sodipodi:type="inkscape:offset"
|
||||||
|
inkscape:radius="0"
|
||||||
|
inkscape:original="M 44.21875 764.1875 L 44.21875 765.1875 C 44.19684 765.46825 44.289258 765.74287 44.5 765.9375 L 46.78125 768.21875 L 44.5 770.46875 C 44.31181 770.65692 44.218747 770.92221 44.21875 771.1875 L 44.21875 772.1875 L 45.21875 772.1875 C 45.48404 772.1875 45.749336 772.09444 45.9375 771.90625 L 48.21875 769.625 L 50.5 771.90625 C 50.688164 772.0944 50.953449 772.18749 51.21875 772.1875 L 52.21875 772.1875 L 52.21875 771.1875 C 52.218742 770.9222 52.125688 770.65692 51.9375 770.46875 L 49.6875 768.21875 L 51.96875 765.9375 C 52.18441 765.73815 52.21875 765.47397 52.21875 765.1875 L 52.21875 764.1875 L 51.21875 764.1875 C 50.977922 764.1945 50.796875 764.2695 50.53125 764.5 L 48.21875 766.78125 L 45.9375 764.5 C 45.75987 764.31608 45.504951 764.1987 45.25 764.1875 C 45.23954 764.18704 45.22912 764.18738 45.21875 764.1875 L 44.21875 764.1875 z "
|
||||||
|
xlink:href="#path27279-0-5"
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#bebebe;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.78124988;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter16524-9);enable-background:new;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
|
||||||
|
id="path16506-5"
|
||||||
|
inkscape:href="#path27279-0-5"
|
||||||
|
d="m 44.21875,764.1875 0,1 c -0.02191,0.28075 0.07051,0.55537 0.28125,0.75 l 2.28125,2.28125 -2.28125,2.25 c -0.18819,0.18817 -0.281253,0.45346 -0.28125,0.71875 l 0,1 1,0 c 0.26529,0 0.530586,-0.0931 0.71875,-0.28125 L 48.21875,769.625 50.5,771.90625 c 0.188164,0.18815 0.453449,0.28124 0.71875,0.28125 l 1,0 0,-1 c -8e-6,-0.2653 -0.09306,-0.53058 -0.28125,-0.71875 l -2.25,-2.25 2.28125,-2.28125 c 0.21566,-0.19935 0.25,-0.46353 0.25,-0.75 l 0,-1 -1,0 c -0.240828,0.007 -0.421875,0.082 -0.6875,0.3125 l -2.3125,2.28125 L 45.9375,764.5 c -0.17763,-0.18392 -0.432549,-0.3013 -0.6875,-0.3125 -0.01046,-4.6e-4 -0.02088,-1.2e-4 -0.03125,0 l -1,0 z"
|
||||||
|
transform="translate(0,1.3535534)" /><path
|
||||||
|
sodipodi:nodetypes="ccsccccccccccccccccccccccc"
|
||||||
|
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#bebebe;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.78124988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new;font-family:Andale Mono;-inkscape-font-specification:Andale Mono"
|
||||||
|
id="path27279-0-5"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
d="m 44.226475,764.17222 1,0 c 0.01037,-1.2e-4 0.02079,-4.6e-4 0.03125,0 0.254951,0.0112 0.50987,0.12858 0.6875,0.3125 l 2.28125,2.28125 2.3125,-2.28125 c 0.265625,-0.2305 0.446672,-0.3055 0.6875,-0.3125 l 1,0 0,1 c 0,0.28647 -0.03434,0.55065 -0.25,0.75 l -2.28125,2.28125 2.25,2.25 c 0.188188,0.18817 0.281242,0.45345 0.28125,0.71875 l 0,1 -1,0 c -0.265301,-1e-5 -0.530586,-0.0931 -0.71875,-0.28125 l -2.28125,-2.28125 -2.28125,2.28125 c -0.188164,0.18819 -0.45346,0.28125 -0.71875,0.28125 l -1,0 0,-1 c -3e-6,-0.26529 0.09306,-0.53058 0.28125,-0.71875 l 2.28125,-2.25 -2.28125,-2.28125 c -0.210742,-0.19463 -0.30316,-0.46925 -0.28125,-0.75 l 0,-1 z" /></g></g></g></svg>
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
data/theme/corner-ripple-rtl.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
@ -1,222 +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: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>
|
|
Before Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
@ -9,23 +9,23 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="24"
|
width="10"
|
||||||
height="16"
|
height="20"
|
||||||
id="svg6446"
|
id="svg10003"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
inkscape:version="0.47pre4 r22446"
|
inkscape:version="0.48.1 r9760"
|
||||||
sodipodi:docname="single-view-active.svg">
|
sodipodi:docname="filter-selected-ltr.svg">
|
||||||
<defs
|
<defs
|
||||||
id="defs6448">
|
id="defs10005">
|
||||||
<inkscape:perspective
|
<inkscape:perspective
|
||||||
sodipodi:type="inkscape:persp3d"
|
sodipodi:type="inkscape:persp3d"
|
||||||
inkscape:vp_x="0 : 16 : 1"
|
inkscape:vp_x="0 : 32 : 1"
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
inkscape:vp_z="32 : 16 : 1"
|
inkscape:vp_z="64 : 32 : 1"
|
||||||
inkscape:persp3d-origin="16 : 10.666667 : 1"
|
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||||
id="perspective6454" />
|
id="perspective10011" />
|
||||||
<inkscape:perspective
|
<inkscape:perspective
|
||||||
id="perspective6441"
|
id="perspective9998"
|
||||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||||
inkscape:vp_z="1 : 0.5 : 1"
|
inkscape:vp_z="1 : 0.5 : 1"
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
@ -37,29 +37,29 @@
|
|||||||
pagecolor="#ffffff"
|
pagecolor="#ffffff"
|
||||||
bordercolor="#666666"
|
bordercolor="#666666"
|
||||||
borderopacity="1.0"
|
borderopacity="1.0"
|
||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="11.197802"
|
inkscape:zoom="5.5"
|
||||||
inkscape:cx="0.014720032"
|
inkscape:cx="32.363636"
|
||||||
inkscape:cy="16"
|
inkscape:cy="10.181818"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="true"
|
showgrid="true"
|
||||||
inkscape:grid-bbox="true"
|
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:window-width="1680"
|
inkscape:grid-bbox="true"
|
||||||
inkscape:window-height="997"
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="839"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="26"
|
inkscape:window-y="26"
|
||||||
inkscape:window-maximized="1" />
|
inkscape:window-maximized="1" />
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata6451">
|
id="metadata10008">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
<cc:Work
|
<cc:Work
|
||||||
rdf:about="">
|
rdf:about="">
|
||||||
<dc:format>image/svg+xml</dc:format>
|
<dc:format>image/svg+xml</dc:format>
|
||||||
<dc:type
|
<dc:type
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
<dc:title />
|
<dc:title></dc:title>
|
||||||
</cc:Work>
|
</cc:Work>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</metadata>
|
</metadata>
|
||||||
@ -67,15 +67,15 @@
|
|||||||
id="layer1"
|
id="layer1"
|
||||||
inkscape:label="Layer 1"
|
inkscape:label="Layer 1"
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
transform="translate(0,-17)">
|
transform="translate(0,-44)">
|
||||||
<rect
|
<path
|
||||||
ry="0.5"
|
inkscape:export-ydpi="90"
|
||||||
rx="0.49999979"
|
inkscape:export-xdpi="90"
|
||||||
y="17.483809"
|
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/app-picker.png"
|
||||||
x="0.53483802"
|
sodipodi:nodetypes="cccc"
|
||||||
height="15"
|
inkscape:connector-curvature="0"
|
||||||
width="23"
|
id="rect34320"
|
||||||
id="rect5304"
|
d="m 10.369085,54.181804 -10.55634072,10.55636 -1e-5,-21.11269 z"
|
||||||
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" />
|
style="opacity:0.21000001;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.7 KiB |
180
data/theme/gdm.css
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/* Copyright 2011, Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU Lesser General Public License,
|
||||||
|
* version 2.1, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Login Dialog */
|
||||||
|
|
||||||
|
.login-dialog-title {
|
||||||
|
font-size: 14pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #666666;
|
||||||
|
padding-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog {
|
||||||
|
border-radius: 16px;
|
||||||
|
min-height: 150px;
|
||||||
|
max-height: 700px;
|
||||||
|
min-width: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-prompt-fingerprint-message {
|
||||||
|
font-size: 10.5pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-view {
|
||||||
|
-st-vfade-offset: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list {
|
||||||
|
spacing: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item {
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item:ltr {
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item:rtl {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item .login-dialog-user-list-item-name {
|
||||||
|
font-size: 20pt;
|
||||||
|
padding-left: 1em;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item:hover .login-dialog-user-list-item-name {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item:focus .login-dialog-user-list-item-name {
|
||||||
|
color: white;
|
||||||
|
text-shadow: black 0px 2px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item-vertical-layout {
|
||||||
|
spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item .login-dialog-user-list-item-focus-bin {
|
||||||
|
background-color: rgba(0,0,0,0.0);
|
||||||
|
height: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item:focus .login-dialog-user-list-item-focus-bin {
|
||||||
|
background-color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-list-item-icon {
|
||||||
|
border: 2px solid #8b8b8b;
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-not-listed-button {
|
||||||
|
padding-top: 2em;
|
||||||
|
}
|
||||||
|
.login-dialog-not-listed-label {
|
||||||
|
font-size: 14pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-prompt-layout {
|
||||||
|
padding-bottom: 32px;
|
||||||
|
}
|
||||||
|
.login-dialog-prompt-label {
|
||||||
|
color: white;
|
||||||
|
font-size: 20pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-prompt-entry {
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 2px solid #5656cc;
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
caret-color: black;
|
||||||
|
caret-size: 1px;
|
||||||
|
width: 15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-prompt-entry .capslock-warning {
|
||||||
|
icon-size: 16px;
|
||||||
|
warning-color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-prompt-entry:insensitive {
|
||||||
|
color: rgba(0,0,0,0.7);
|
||||||
|
border: 2px solid #565656;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 10.5pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list-button {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list-button:focus {
|
||||||
|
background-color: #4c4c4c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list-button:active {
|
||||||
|
background-color: #4c4c4c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list-button:hover {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list-scroll-view {
|
||||||
|
background-gradient-start: rgba(80,80,80,0.3);
|
||||||
|
background-gradient-end: rgba(80,80,80,0.7);
|
||||||
|
background-gradient-direction: vertical;
|
||||||
|
box-shadow: inset 0px 2px 4px rgba(0,0,0,0.9);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid rgba(80,80,80,1.0);
|
||||||
|
padding: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list-item:focus {
|
||||||
|
background-color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list-triangle {
|
||||||
|
padding-right: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list-item-box {
|
||||||
|
spacing: .25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-session-list-item-dot {
|
||||||
|
width: .75em;
|
||||||
|
height: .75em;
|
||||||
|
}
|
@ -1,113 +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="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>
|
|
Before Width: | Height: | Size: 3.7 KiB |
@ -1,113 +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="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>
|
|
Before Width: | Height: | Size: 3.6 KiB |
@ -1,89 +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="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>
|
|
Before Width: | Height: | Size: 4.0 KiB |
33
data/theme/panel-border.svg
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?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"
|
||||||
|
width="3"
|
||||||
|
height="10"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1">
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke-width:0.43599999000000000;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="rect3779"
|
||||||
|
width="3"
|
||||||
|
height="10"
|
||||||
|
x="0"
|
||||||
|
y="0" />
|
||||||
|
<rect
|
||||||
|
style="fill:#536272;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="rect3796"
|
||||||
|
width="3"
|
||||||
|
height="1"
|
||||||
|
x="0"
|
||||||
|
y="9" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 787 B |
74
data/theme/panel-button-border.svg
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?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="21"
|
||||||
|
height="10"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.1 r9760"
|
||||||
|
sodipodi:docname="panel-button-border.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="44.8"
|
||||||
|
inkscape:cx="8.6594891"
|
||||||
|
inkscape:cy="5.7029946"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="843"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
guidetolerance="10000"
|
||||||
|
objecttolerance="10000">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3792"
|
||||||
|
empspacing="10"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<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="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="rect3796"
|
||||||
|
width="3"
|
||||||
|
height="2"
|
||||||
|
x="9"
|
||||||
|
y="8" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
111
data/theme/panel-button-highlight-narrow.svg
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?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="30"
|
||||||
|
height="25"
|
||||||
|
id="svg10621"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.1 r9760"
|
||||||
|
sodipodi:docname="panel-button-highlight-narrow.svg">
|
||||||
|
<defs
|
||||||
|
id="defs10623">
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
id="radialGradient99561-1"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
cx="51"
|
||||||
|
cy="30"
|
||||||
|
fx="51"
|
||||||
|
fy="30"
|
||||||
|
r="42" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient34508-1-3">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop34510-1-9" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop34512-4-5" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
r="42"
|
||||||
|
fy="30"
|
||||||
|
fx="51"
|
||||||
|
cy="30"
|
||||||
|
cx="51"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient10592"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.979899"
|
||||||
|
inkscape:cx="-171.36384"
|
||||||
|
inkscape:cy="-53.255157"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="843"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata10626">
|
||||||
|
<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"
|
||||||
|
transform="translate(-468.08632,-537.03477)">
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="opacity:0.4625;color:#000000;fill:url(#radialGradient10592);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
id="path34506-3"
|
||||||
|
sodipodi:cx="51"
|
||||||
|
sodipodi:cy="30"
|
||||||
|
sodipodi:rx="42"
|
||||||
|
sodipodi:ry="16"
|
||||||
|
d="M 9,29.999999 C 9.0000011,21.163443 27.804042,14 51.000002,14 74.195961,14 93,21.163444 93,30 l -42,0 z"
|
||||||
|
sodipodi:start="3.1415927"
|
||||||
|
sodipodi:end="6.2831853"
|
||||||
|
transform="matrix(0.35714286,0,0,1.5625,464.87203,515.15977)"
|
||||||
|
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
111
data/theme/panel-button-highlight-wide.svg
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?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="84"
|
||||||
|
height="25"
|
||||||
|
id="svg10621"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.0 r9654"
|
||||||
|
sodipodi:docname="panel-button-highlight-wide.svg">
|
||||||
|
<defs
|
||||||
|
id="defs10623">
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
id="radialGradient99561-1"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
cx="51"
|
||||||
|
cy="30"
|
||||||
|
fx="51"
|
||||||
|
fy="30"
|
||||||
|
r="42" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient34508-1-3">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop34510-1-9" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop34512-4-5" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
r="42"
|
||||||
|
fy="30"
|
||||||
|
fx="51"
|
||||||
|
cy="30"
|
||||||
|
cx="51"
|
||||||
|
gradientTransform="matrix(0.72146227,0,0,0.27484277,14.205424,21.754717)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient10592"
|
||||||
|
xlink:href="#linearGradient34508-1-3"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.979899"
|
||||||
|
inkscape:cx="-118.50071"
|
||||||
|
inkscape:cy="27.304508"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="843"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata10626">
|
||||||
|
<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"
|
||||||
|
transform="translate(-441.08632,-537.03477)">
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="opacity:0.4625;color:#000000;fill:url(#radialGradient10592);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
id="path34506-3"
|
||||||
|
sodipodi:cx="51"
|
||||||
|
sodipodi:cy="30"
|
||||||
|
sodipodi:rx="42"
|
||||||
|
sodipodi:ry="16"
|
||||||
|
d="M 9,29.999999 C 9.0000011,21.163443 27.804042,14 51.000002,14 74.195961,14 93,21.163444 93,30 l -42,0 z"
|
||||||
|
sodipodi:start="3.1415927"
|
||||||
|
sodipodi:end="6.2831853"
|
||||||
|
transform="matrix(1,0,0,1.5625,432.08632,515.15977)"
|
||||||
|
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/motion/textures/panel.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 4.0 KiB |
261
data/theme/process-working.svg
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
<?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"
|
||||||
|
id="svg5369"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48+devel r10053 custom"
|
||||||
|
width="96"
|
||||||
|
height="48"
|
||||||
|
sodipodi:docname="process-working.svg"
|
||||||
|
style="display:inline">
|
||||||
|
<metadata
|
||||||
|
id="metadata5375">
|
||||||
|
<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>
|
||||||
|
<defs
|
||||||
|
id="defs5373" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#808080"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1975"
|
||||||
|
inkscape:window-height="1098"
|
||||||
|
id="namedview5371"
|
||||||
|
showgrid="true"
|
||||||
|
borderlayer="true"
|
||||||
|
inkscape:showpageshadow="false"
|
||||||
|
inkscape:zoom="16"
|
||||||
|
inkscape:cx="53.997662"
|
||||||
|
inkscape:cy="22.367695"
|
||||||
|
inkscape:window-x="1600"
|
||||||
|
inkscape:window-y="33"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="layer2">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid11933"
|
||||||
|
empspacing="5"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="tiles"
|
||||||
|
style="display:none">
|
||||||
|
<rect
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
id="rect12451"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
x="0"
|
||||||
|
y="0" />
|
||||||
|
<rect
|
||||||
|
y="24"
|
||||||
|
x="0"
|
||||||
|
height="24"
|
||||||
|
width="24"
|
||||||
|
id="rect12453"
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<rect
|
||||||
|
y="0"
|
||||||
|
x="24"
|
||||||
|
height="24"
|
||||||
|
width="24"
|
||||||
|
id="rect12455"
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
id="rect12457"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
x="24"
|
||||||
|
y="24" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
id="rect12459"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
x="48"
|
||||||
|
y="0" />
|
||||||
|
<rect
|
||||||
|
y="24"
|
||||||
|
x="48"
|
||||||
|
height="24"
|
||||||
|
width="24"
|
||||||
|
id="rect12461"
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<rect
|
||||||
|
y="0"
|
||||||
|
x="72"
|
||||||
|
height="24"
|
||||||
|
width="24"
|
||||||
|
id="rect12463"
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
id="rect12465"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
x="72"
|
||||||
|
y="24" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="spinner">
|
||||||
|
<g
|
||||||
|
transform="matrix(0.28240106,0,0,0.28240106,146.92015,-382.52444)"
|
||||||
|
id="g10450-5"
|
||||||
|
style="display:inline">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="opacity:0.6;color:#000000;fill:none;stroke:#ffffff;stroke-width:7.08212566;stroke-linecap:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
d="m -477.76072,1373.3569 0,9.4717"
|
||||||
|
id="path18768"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:transform-center-y="-4.6808838" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:transform-center-y="-3.3099227"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
id="path18770"
|
||||||
|
d="m -461.0171,1380.2922 -7.23427,7.3824"
|
||||||
|
style="opacity:0.7;color:#000000;fill:none;stroke:#ffffff;stroke-width:7.08212566;stroke-linecap:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
inkscape:transform-center-x="-3.3098966" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:transform-center-x="-4.6808962"
|
||||||
|
style="opacity:0.8;color:#000000;fill:none;stroke:#ffffff;stroke-width:7.08212566;stroke-linecap:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
d="m -454.08163,1397.0359 -9.47165,0"
|
||||||
|
id="path18772"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:transform-center-y="-2.6596956e-05" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
id="path18774"
|
||||||
|
d="m -461.01709,1413.7796 -6.93831,-7.0864"
|
||||||
|
style="opacity:0.9;color:#000000;fill:none;stroke:#ffffff;stroke-width:7.08212566;stroke-linecap:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
inkscape:transform-center-x="-3.3098966"
|
||||||
|
inkscape:transform-center-y="3.3098652" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:transform-center-y="4.6808757"
|
||||||
|
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:7.08212566;stroke-linecap:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
d="m -477.76074,1420.715 9e-5,-9.4716"
|
||||||
|
id="path18776"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
id="path18778"
|
||||||
|
d="m -494.50442,1413.7796 6.79048,-6.9384"
|
||||||
|
style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:7.08212566;stroke-linecap:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
inkscape:transform-center-y="3.3098769"
|
||||||
|
inkscape:transform-center-x="3.3098883" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
inkscape:transform-center-x="4.6808941"
|
||||||
|
style="opacity:0.4;color:#000000;fill:none;stroke:#ffffff;stroke-width:7.08212566;stroke-linecap:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
d="m -501.43987,1397.0359 9.47174,0"
|
||||||
|
id="path18780"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:transform-center-y="-2.6596956e-05" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
id="path18782"
|
||||||
|
d="m -494.5044,1380.2922 6.64243,6.9384"
|
||||||
|
style="opacity:0.5;color:#000000;fill:none;stroke:#ffffff;stroke-width:7.08212566;stroke-linecap:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||||
|
inkscape:transform-center-x="3.3098902"
|
||||||
|
inkscape:transform-center-y="-3.3099302" />
|
||||||
|
</g>
|
||||||
|
<use
|
||||||
|
style="display:inline"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#g10450-5"
|
||||||
|
id="use4981"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,36,-4.9705636)"
|
||||||
|
width="400"
|
||||||
|
height="400" />
|
||||||
|
<use
|
||||||
|
style="display:inline"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#use4981"
|
||||||
|
id="use4983"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,43.032478,-21.909695)"
|
||||||
|
width="400"
|
||||||
|
height="400" />
|
||||||
|
<use
|
||||||
|
style="display:inline"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#use4983"
|
||||||
|
id="use4985"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,50.081986,-38.904617)"
|
||||||
|
width="400"
|
||||||
|
height="400" />
|
||||||
|
<use
|
||||||
|
style="display:inline"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#use4985"
|
||||||
|
id="use4987"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,-38.919996,-31.872139)"
|
||||||
|
width="400"
|
||||||
|
height="400" />
|
||||||
|
<use
|
||||||
|
style="display:inline"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#use4987"
|
||||||
|
id="use4989"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,52.986628,2.0890543)"
|
||||||
|
width="400"
|
||||||
|
height="400" />
|
||||||
|
<use
|
||||||
|
style="display:inline"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#use4989"
|
||||||
|
id="use4991"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,60.013026,-14.912936)"
|
||||||
|
width="400"
|
||||||
|
height="400" />
|
||||||
|
<use
|
||||||
|
style="display:inline"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#use4991"
|
||||||
|
id="use4993"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,67.022396,-31.859127)"
|
||||||
|
width="400"
|
||||||
|
height="400" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 9.8 KiB |
@ -1,92 +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="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>
|
|
Before Width: | Height: | Size: 2.9 KiB |
@ -2,24 +2,62 @@
|
|||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<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:svg="http://www.w3.org/2000/svg"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
width="74.01342"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
height="74.006706"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="119.97824"
|
||||||
|
height="119.97824"
|
||||||
id="svg7355"
|
id="svg7355"
|
||||||
version="1.1">
|
version="1.1"
|
||||||
|
inkscape:version="0.48.1 r9760"
|
||||||
|
sodipodi:docname="running-indicator.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata4175">
|
||||||
|
<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>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#2c1cff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="1"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1141"
|
||||||
|
id="namedview4173"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="8.1348081"
|
||||||
|
inkscape:cx="81.120662"
|
||||||
|
inkscape:cy="58.117986"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g30864" />
|
||||||
<defs
|
<defs
|
||||||
id="defs7357">
|
id="defs7357">
|
||||||
<radialGradient
|
<radialGradient
|
||||||
xlink:href="#linearGradient36429"
|
xlink:href="#linearGradient36429"
|
||||||
id="radialGradient7461"
|
id="radialGradient7461"
|
||||||
gradientUnits="userSpaceOnUse"
|
gradientUnits="userSpaceOnUse"
|
||||||
gradientTransform="matrix(1.0525552,0,0,1.0525552,-2.5162753,-9.0000838)"
|
gradientTransform="matrix(1.011539,0,0,0.57582113,-0.39262194,71.83807)"
|
||||||
cx="47.878681"
|
cx="47.428951"
|
||||||
cy="171.25"
|
cy="167.16817"
|
||||||
fx="47.878681"
|
fx="47.428951"
|
||||||
fy="171.25"
|
fy="167.16817"
|
||||||
r="37" />
|
r="37" />
|
||||||
<linearGradient
|
<linearGradient
|
||||||
id="linearGradient36429">
|
id="linearGradient36429">
|
||||||
@ -59,31 +97,34 @@
|
|||||||
fx="49.067139"
|
fx="49.067139"
|
||||||
cy="242.50381"
|
cy="242.50381"
|
||||||
cx="49.067139"
|
cx="49.067139"
|
||||||
gradientTransform="matrix(1.1891549,0,0,0.55513246,-9.281289,36.12653)"
|
gradientTransform="matrix(1.1891549,0,0,0.15252127,-9.281289,132.52772)"
|
||||||
gradientUnits="userSpaceOnUse"
|
gradientUnits="userSpaceOnUse"
|
||||||
id="radialGradient7488"
|
id="radialGradient7488"
|
||||||
xlink:href="#linearGradient36471" />
|
xlink:href="#linearGradient36471" />
|
||||||
</defs>
|
</defs>
|
||||||
<g
|
<g
|
||||||
id="layer1"
|
id="layer1"
|
||||||
transform="translate(-266.21629,-168.11809)">
|
transform="matrix(1.6213276,0,0,1.6213276,-431.6347,-272.5745)">
|
||||||
<g
|
<g
|
||||||
style="display:inline"
|
style="display:inline"
|
||||||
id="g30864"
|
id="g30864"
|
||||||
transform="translate(255.223,70.118091)">
|
transform="translate(255.223,70.118091)">
|
||||||
<rect
|
<rect
|
||||||
ry="3.5996203"
|
ry="3.4593496"
|
||||||
rx="3.5996203"
|
rx="3.4593496"
|
||||||
y="98"
|
y="99.596962"
|
||||||
x="11"
|
x="12.596948"
|
||||||
height="74"
|
height="71.116341"
|
||||||
width="74"
|
width="71.116341"
|
||||||
id="rect14000"
|
id="rect14000"
|
||||||
style="opacity:0.371875;fill:url(#radialGradient7461);fill-opacity:1;stroke:none" />
|
style="opacity:0.37187500000000001;fill:url(#radialGradient7461);fill-opacity:1;stroke:none" />
|
||||||
<path
|
<path
|
||||||
id="rect34520"
|
id="rect34520"
|
||||||
d="m 84.506708,167.95508 c 6e-6,1.96759 -1.584022,3.55162 -3.551629,3.55163 l -65.910146,0 c -1.967608,-1e-5 -3.551648,-1.58402 -3.551643,-3.55164"
|
d="m 83.273151,166.72152 c 0,1.96759 -1.584022,3.55163 -3.551629,3.55163 l -63.443032,0 c -1.967608,0 -3.551648,-1.58402 -3.551643,-3.55164 0,-5.85318 0,-5.85318 0,0"
|
||||||
style="opacity:0.2;fill:none;stroke:url(#radialGradient7488);stroke-width:1;stroke-opacity:1" />
|
style="opacity:0.35;fill:none;stroke:url(#radialGradient7488);stroke-width:1;stroke-opacity:1"
|
||||||
|
connector-curvature="0"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccscc" />
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 225 B |
Before Width: | Height: | Size: 225 B |
Before Width: | Height: | Size: 211 B |
Before Width: | Height: | Size: 211 B |
Before Width: | Height: | Size: 531 B |
@ -1,81 +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="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>
|
|
Before Width: | Height: | Size: 2.4 KiB |
74
data/theme/source-button-border.svg
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?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="21"
|
||||||
|
height="10"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.0 r9654"
|
||||||
|
sodipodi:docname="source-button-border.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="44.8"
|
||||||
|
inkscape:cx="8.704132"
|
||||||
|
inkscape:cy="5.7029946"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:window-width="1600"
|
||||||
|
inkscape:window-height="1145"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
guidetolerance="10000"
|
||||||
|
objecttolerance="10000">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3792"
|
||||||
|
empspacing="10"
|
||||||
|
visible="true"
|
||||||
|
enabled="true"
|
||||||
|
snapvisiblegridlinesonly="true" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<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="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke-width:0.43599999;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="rect3796"
|
||||||
|
width="19"
|
||||||
|
height="2"
|
||||||
|
x="1"
|
||||||
|
y="8" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
@ -13,8 +13,8 @@
|
|||||||
height="22"
|
height="22"
|
||||||
id="svg3199"
|
id="svg3199"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
inkscape:version="0.47 r22583"
|
inkscape:version="0.48.1 r9760"
|
||||||
sodipodi:docname="New document 11">
|
sodipodi:docname="toggle-on-intl.svg">
|
||||||
<defs
|
<defs
|
||||||
id="defs3201">
|
id="defs3201">
|
||||||
<inkscape:perspective
|
<inkscape:perspective
|
||||||
@ -39,14 +39,14 @@
|
|||||||
borderopacity="1.0"
|
borderopacity="1.0"
|
||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0.0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="0.35"
|
inkscape:zoom="1"
|
||||||
inkscape:cx="32.500004"
|
inkscape:cx="49.147112"
|
||||||
inkscape:cy="10.999997"
|
inkscape:cy="17.532036"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:window-width="609"
|
inkscape:window-width="1412"
|
||||||
inkscape:window-height="501"
|
inkscape:window-height="1067"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="26"
|
inkscape:window-y="26"
|
||||||
inkscape:window-maximized="0" />
|
inkscape:window-maximized="0" />
|
||||||
@ -58,7 +58,7 @@
|
|||||||
<dc:format>image/svg+xml</dc:format>
|
<dc:format>image/svg+xml</dc:format>
|
||||||
<dc:type
|
<dc:type
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
<dc:title></dc:title>
|
<dc:title />
|
||||||
</cc:Work>
|
</cc:Work>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</metadata>
|
</metadata>
|
||||||
@ -72,7 +72,7 @@
|
|||||||
transform="translate(-453.5,448.36218)"
|
transform="translate(-453.5,448.36218)"
|
||||||
id="g16453">
|
id="g16453">
|
||||||
<rect
|
<rect
|
||||||
style="color:#000000;fill:#204a87;fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999994;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;enable-background:accumulate"
|
style="color:#000000;fill:#4a90d9;fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999994000000003;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;enable-background:accumulate"
|
||||||
id="rect16256-9-4"
|
id="rect16256-9-4"
|
||||||
width="63.000004"
|
width="63.000004"
|
||||||
height="19"
|
height="19"
|
||||||
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
@ -13,8 +13,8 @@
|
|||||||
height="22"
|
height="22"
|
||||||
id="svg2857"
|
id="svg2857"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
inkscape:version="0.47 r22583"
|
inkscape:version="0.48.1 r9760"
|
||||||
sodipodi:docname="New document 2">
|
sodipodi:docname="toggle-on-us.svg">
|
||||||
<defs
|
<defs
|
||||||
id="defs2859">
|
id="defs2859">
|
||||||
<inkscape:perspective
|
<inkscape:perspective
|
||||||
@ -40,16 +40,18 @@
|
|||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0.0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="1"
|
inkscape:zoom="1"
|
||||||
inkscape:cx="-69.642856"
|
inkscape:cx="19.689855"
|
||||||
inkscape:cy="42.428569"
|
inkscape:cy="2.0517979"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:window-width="609"
|
inkscape:window-width="941"
|
||||||
inkscape:window-height="501"
|
inkscape:window-height="751"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="2577"
|
||||||
inkscape:window-y="26"
|
inkscape:window-y="206"
|
||||||
inkscape:window-maximized="0" />
|
inkscape:window-maximized="0"
|
||||||
|
borderlayer="true"
|
||||||
|
inkscape:showpageshadow="false" />
|
||||||
<metadata
|
<metadata
|
||||||
id="metadata2862">
|
id="metadata2862">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
@ -58,7 +60,7 @@
|
|||||||
<dc:format>image/svg+xml</dc:format>
|
<dc:format>image/svg+xml</dc:format>
|
||||||
<dc:type
|
<dc:type
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
<dc:title></dc:title>
|
<dc:title />
|
||||||
</cc:Work>
|
</cc:Work>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</metadata>
|
</metadata>
|
||||||
@ -72,7 +74,7 @@
|
|||||||
transform="translate(-351.35714,708.36218)"
|
transform="translate(-351.35714,708.36218)"
|
||||||
id="g16453">
|
id="g16453">
|
||||||
<rect
|
<rect
|
||||||
style="color:#000000;fill:#204a87;fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999994;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;enable-background:accumulate"
|
style="color:#000000;fill:#4a90d9;fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999994000000003;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;enable-background:accumulate"
|
||||||
id="rect16256-9-4"
|
id="rect16256-9-4"
|
||||||
width="63.000004"
|
width="63.000004"
|
||||||
height="19"
|
height="19"
|
||||||
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.8 KiB |
@ -2,13 +2,51 @@
|
|||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<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:svg="http://www.w3.org/2000/svg"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
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"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
width="96"
|
width="96"
|
||||||
height="96"
|
height="96"
|
||||||
id="svg25070">
|
id="svg25070"
|
||||||
|
inkscape:version="0.48.0 r9654"
|
||||||
|
sodipodi:docname="ws-switch-arrow-down.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata3353">
|
||||||
|
<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>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="718"
|
||||||
|
inkscape:window-height="480"
|
||||||
|
id="namedview3351"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.6979167"
|
||||||
|
inkscape:cx="48"
|
||||||
|
inkscape:cy="48"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg25070" />
|
||||||
<defs
|
<defs
|
||||||
id="defs25072">
|
id="defs25072">
|
||||||
<linearGradient
|
<linearGradient
|
||||||
@ -288,7 +326,7 @@
|
|||||||
</filter>
|
</filter>
|
||||||
</defs>
|
</defs>
|
||||||
<g
|
<g
|
||||||
transform="translate(0,48)"
|
transform="matrix(0,1,-1,0,48.0003,4.1307112e-7)"
|
||||||
id="layer1">
|
id="layer1">
|
||||||
<g
|
<g
|
||||||
transform="matrix(-2,0,0,2,-97.2497,-374.967)"
|
transform="matrix(-2,0,0,2,-97.2497,-374.967)"
|
||||||
@ -297,35 +335,42 @@
|
|||||||
<path
|
<path
|
||||||
d="m -72.5,173.5 -14,14 14,14"
|
d="m -72.5,173.5 -14,14 14,14"
|
||||||
id="path3165-7-3"
|
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" />
|
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"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
</g>
|
</g>
|
||||||
<path
|
<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"
|
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)"
|
transform="matrix(-3.34328,0,0,3.34328,-89.2797,-623.176)"
|
||||||
id="path4050-2-7-9-4"
|
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" />
|
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"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
<path
|
<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"
|
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)"
|
transform="matrix(-3.34328,0,0,3.34328,-111.2797,-623.176)"
|
||||||
id="path4050-2-7-9-4-8"
|
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" />
|
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"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
<path
|
<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"
|
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)"
|
transform="matrix(-2.86565,0,0,2.86565,-70.8457,-534.143)"
|
||||||
id="path4050-2-7-9-4-0"
|
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" />
|
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"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
<path
|
<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"
|
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)"
|
transform="matrix(-2.86565,0,0,2.86565,-92.8457,-534.143)"
|
||||||
id="path4050-2-7-9-4-0-9"
|
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" />
|
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"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
<path
|
<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"
|
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"
|
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" />
|
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"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
<path
|
<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"
|
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"
|
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" />
|
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"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
@ -1,96 +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: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>
|
|
Before Width: | Height: | Size: 13 KiB |
447
data/theme/ws-switch-arrow-up.svg
Normal file
@ -0,0 +1,447 @@
|
|||||||
|
<?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.48.0 r9654"
|
||||||
|
sodipodi:docname="ws-switch-arrow-up.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="-12.356322"
|
||||||
|
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="840"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
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="g3181"
|
||||||
|
transform="matrix(0,1,-1,0,48.0003,-48)">
|
||||||
|
<g
|
||||||
|
style="stroke:#000000;stroke-opacity:1;display:inline"
|
||||||
|
transform="matrix(2,0,0,2,193.25,-374.967)"
|
||||||
|
id="g4030-1-8">
|
||||||
|
<path
|
||||||
|
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"
|
||||||
|
d="m -72.5,173.5 -14,14 14,14"
|
||||||
|
id="path3165-7-3"
|
||||||
|
sodipodi:nodetypes="ccc"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
transform="matrix(3.34328,0,0,3.34328,185.28,-623.176)"
|
||||||
|
d="m -36.5,186.40625 c 0,1.15635 -0.937404,2.09375 -2.09375,2.09375 -1.156346,0 -2.09375,-0.9374 -2.09375,-2.09375 0,-1.15635 0.937404,-2.09375 2.09375,-2.09375 1.156346,0 2.09375,0.9374 2.09375,2.09375 z"
|
||||||
|
sodipodi:ry="2.09375"
|
||||||
|
sodipodi:rx="2.09375"
|
||||||
|
sodipodi:cy="186.40625"
|
||||||
|
sodipodi:cx="-38.59375"
|
||||||
|
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"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(3.34328,0,0,3.34328,207.28,-623.176)"
|
||||||
|
d="m -36.5,186.40625 c 0,1.15635 -0.937404,2.09375 -2.09375,2.09375 -1.156346,0 -2.09375,-0.9374 -2.09375,-2.09375 0,-1.15635 0.937404,-2.09375 2.09375,-2.09375 1.156346,0 2.09375,0.9374 2.09375,2.09375 z"
|
||||||
|
sodipodi:ry="2.09375"
|
||||||
|
sodipodi:rx="2.09375"
|
||||||
|
sodipodi:cy="186.40625"
|
||||||
|
sodipodi:cx="-38.59375"
|
||||||
|
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"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(2.86565,0,0,2.86565,166.846,-534.143)"
|
||||||
|
d="m -36.5,186.40625 c 0,1.15635 -0.937404,2.09375 -2.09375,2.09375 -1.156346,0 -2.09375,-0.9374 -2.09375,-2.09375 0,-1.15635 0.937404,-2.09375 2.09375,-2.09375 1.156346,0 2.09375,0.9374 2.09375,2.09375 z"
|
||||||
|
sodipodi:ry="2.09375"
|
||||||
|
sodipodi:rx="2.09375"
|
||||||
|
sodipodi:cy="186.40625"
|
||||||
|
sodipodi:cx="-38.59375"
|
||||||
|
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"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(2.86565,0,0,2.86565,188.846,-534.143)"
|
||||||
|
d="m -36.5,186.40625 c 0,1.15635 -0.937404,2.09375 -2.09375,2.09375 -1.156346,0 -2.09375,-0.9374 -2.09375,-2.09375 0,-1.15635 0.937404,-2.09375 2.09375,-2.09375 1.156346,0 2.09375,0.9374 2.09375,2.09375 z"
|
||||||
|
sodipodi:ry="2.09375"
|
||||||
|
sodipodi:rx="2.09375"
|
||||||
|
sodipodi:cy="186.40625"
|
||||||
|
sodipodi:cx="-38.59375"
|
||||||
|
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"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(2,0,0,2,-586,-765.967)"
|
||||||
|
sodipodi:nodetypes="ccccscccsc"
|
||||||
|
id="path3165-7-3-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"
|
||||||
|
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:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
transform="matrix(2,0,0,2,-586,-765.967)"
|
||||||
|
sodipodi:nodetypes="ccccccc"
|
||||||
|
id="path3165-7-3-1-9"
|
||||||
|
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"
|
||||||
|
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:1;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"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 16 KiB |
1
docs/Makefile.am
Normal file
@ -0,0 +1 @@
|
|||||||
|
SUBDIRS = reference
|
1
docs/reference/Makefile.am
Normal file
@ -0,0 +1 @@
|
|||||||
|
SUBDIRS = shell st
|
105
docs/reference/shell/Makefile.am
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
# We require automake 1.6 at least.
|
||||||
|
AUTOMAKE_OPTIONS = 1.6
|
||||||
|
|
||||||
|
# This is a blank Makefile.am for using gtk-doc.
|
||||||
|
# Copy this to your project's API docs directory and modify the variables to
|
||||||
|
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
|
||||||
|
# of using the various options.
|
||||||
|
|
||||||
|
# The name of the module, e.g. 'glib'.
|
||||||
|
DOC_MODULE=shell
|
||||||
|
|
||||||
|
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
|
||||||
|
#DOC_MODULE_VERSION=2
|
||||||
|
|
||||||
|
|
||||||
|
# The top-level SGML file. You can change this if you want to.
|
||||||
|
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
|
||||||
|
|
||||||
|
# Directories containing the source code, relative to $(srcdir).
|
||||||
|
# gtk-doc will search all .c and .h files beneath these paths
|
||||||
|
# for inline comments documenting functions and macros.
|
||||||
|
# e.g. DOC_SOURCE_DIR=../../../gtk ../../../gdk
|
||||||
|
DOC_SOURCE_DIR=../../../src
|
||||||
|
|
||||||
|
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
|
||||||
|
SCANGOBJ_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-scan.
|
||||||
|
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
|
||||||
|
SCAN_OPTIONS=--rebuild-types
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mkdb.
|
||||||
|
# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml
|
||||||
|
MKDB_OPTIONS=--xml-mode --output-format=xml
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mktmpl
|
||||||
|
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
|
||||||
|
MKTMPL_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mkhtml
|
||||||
|
MKHTML_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-fixref. Not normally needed.
|
||||||
|
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
|
||||||
|
FIXXREF_OPTIONS=
|
||||||
|
|
||||||
|
# Used for dependencies. The docs will be rebuilt if any of these change.
|
||||||
|
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
|
||||||
|
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
|
||||||
|
HFILE_GLOB=$(top_srcdir)/src/*.h
|
||||||
|
CFILE_GLOB=$(top_srcdir)/src/*.c
|
||||||
|
|
||||||
|
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
|
||||||
|
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
|
||||||
|
EXTRA_HFILES=
|
||||||
|
|
||||||
|
# Header files or dirs to ignore when scanning. Use base file/dir names
|
||||||
|
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
|
||||||
|
IGNORE_HFILES=calendar-server gvc hotplug-sniffer st tray
|
||||||
|
|
||||||
|
# Images to copy into HTML directory.
|
||||||
|
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
|
||||||
|
HTML_IMAGES=
|
||||||
|
|
||||||
|
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
|
||||||
|
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
|
||||||
|
content_files=
|
||||||
|
|
||||||
|
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
|
||||||
|
# These files must be listed here *and* in content_files
|
||||||
|
# e.g. expand_content_files=running.sgml
|
||||||
|
expand_content_files=
|
||||||
|
|
||||||
|
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
|
||||||
|
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
|
||||||
|
# signals and properties.
|
||||||
|
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
|
||||||
|
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
|
||||||
|
GTKDOC_CFLAGS=$(GNOME_SHELL_CFLAGS)
|
||||||
|
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell.la
|
||||||
|
|
||||||
|
# This includes the standard gtk-doc make rules, copied by gtkdocize.
|
||||||
|
include $(top_srcdir)/gtk-doc.make
|
||||||
|
|
||||||
|
# Other files to distribute
|
||||||
|
# e.g. EXTRA_DIST += version.xml.in
|
||||||
|
EXTRA_DIST +=
|
||||||
|
|
||||||
|
# Files not to distribute
|
||||||
|
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
|
||||||
|
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
|
||||||
|
DISTCLEANFILES = $(DOC_MODULES).types
|
||||||
|
|
||||||
|
# Comment this out if you want 'make check' to test you doc status
|
||||||
|
# and run some sanity checks
|
||||||
|
if ENABLE_GTK_DOC
|
||||||
|
TESTS_ENVIRONMENT = cd $(srcdir) && \
|
||||||
|
DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
|
||||||
|
SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
|
||||||
|
#TESTS = $(GTKDOC_CHECK)
|
||||||
|
endif
|
||||||
|
|
||||||
|
-include $(top_srcdir)/git.mk
|
73
docs/reference/shell/shell-docs.sgml.in
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||||
|
[
|
||||||
|
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||||||
|
]>
|
||||||
|
<book id="index">
|
||||||
|
<bookinfo>
|
||||||
|
<title>Shell Reference Manual</title>
|
||||||
|
<releaseinfo>
|
||||||
|
for Shell @VERSION@.
|
||||||
|
<!--The latest version of this documentation can be found on-line at
|
||||||
|
<ulink role="online-location" url="http://[SERVER]/shell/index.html">http://[SERVER]/shell/</ulink>.-->
|
||||||
|
</releaseinfo>
|
||||||
|
</bookinfo>
|
||||||
|
|
||||||
|
<chapter>
|
||||||
|
<title>Actors</title>
|
||||||
|
<xi:include href="xml/shell-generic-container.xml"/>
|
||||||
|
<xi:include href="xml/shell-slicer.xml"/>
|
||||||
|
<xi:include href="xml/shell-stack.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Application tracking</title>
|
||||||
|
<xi:include href="xml/shell-app.xml"/>
|
||||||
|
<xi:include href="xml/shell-app-usage.xml"/>
|
||||||
|
<xi:include href="xml/shell-window-tracker.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Search</title>
|
||||||
|
<xi:include href="xml/shell-app-system.xml"/>
|
||||||
|
<xi:include href="xml/shell-contact-system.xml"/>
|
||||||
|
<xi:include href="xml/shell-doc-system.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Tray Icons</title>
|
||||||
|
<xi:include href="xml/shell-embedded-window.xml"/>
|
||||||
|
<xi:include href="xml/shell-gtk-embed.xml"/>
|
||||||
|
<xi:include href="xml/shell-tray-icon.xml"/>
|
||||||
|
<xi:include href="xml/shell-tray-manager.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Recorder</title>
|
||||||
|
<xi:include href="xml/shell-recorder.xml"/>
|
||||||
|
<xi:include href="xml/shell-recorder-src.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter>
|
||||||
|
<title>Integration helpers and utilities</title>
|
||||||
|
<xi:include href="xml/shell-global.xml"/>
|
||||||
|
<xi:include href="xml/shell-wm.xml"/>
|
||||||
|
<xi:include href="xml/shell-xfixes-cursor.xml"/>
|
||||||
|
<xi:include href="xml/shell-util.xml"/>
|
||||||
|
<xi:include href="xml/shell-mount-operation.xml"/>
|
||||||
|
<xi:include href="xml/shell-mobile-providers.xml"/>
|
||||||
|
<xi:include href="xml/shell-network-agent.xml"/>
|
||||||
|
<xi:include href="xml/shell-polkit-authentication-agent.xml"/>
|
||||||
|
<xi:include href="xml/shell-tp-client.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="object-tree">
|
||||||
|
<title>Object Hierarchy</title>
|
||||||
|
<xi:include href="xml/tree_index.sgml"/>
|
||||||
|
</chapter>
|
||||||
|
<index id="api-index-full">
|
||||||
|
<title>API Index</title>
|
||||||
|
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||||
|
</index>
|
||||||
|
<index id="deprecated-api-index" role="deprecated">
|
||||||
|
<title>Index of deprecated API</title>
|
||||||
|
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
|
||||||
|
</index>
|
||||||
|
|
||||||
|
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
|
||||||
|
</book>
|
105
docs/reference/st/Makefile.am
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
# We require automake 1.6 at least.
|
||||||
|
AUTOMAKE_OPTIONS = 1.6
|
||||||
|
|
||||||
|
# This is a blank Makefile.am for using gtk-doc.
|
||||||
|
# Copy this to your project's API docs directory and modify the variables to
|
||||||
|
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
|
||||||
|
# of using the various options.
|
||||||
|
|
||||||
|
# The name of the module, e.g. 'glib'.
|
||||||
|
DOC_MODULE=st
|
||||||
|
|
||||||
|
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
|
||||||
|
#DOC_MODULE_VERSION=2
|
||||||
|
|
||||||
|
|
||||||
|
# The top-level SGML file. You can change this if you want to.
|
||||||
|
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
|
||||||
|
|
||||||
|
# Directories containing the source code, relative to $(srcdir).
|
||||||
|
# gtk-doc will search all .c and .h files beneath these paths
|
||||||
|
# for inline comments documenting functions and macros.
|
||||||
|
# e.g. DOC_SOURCE_DIR=../../../gtk ../../../gdk
|
||||||
|
DOC_SOURCE_DIR=../../../src/st
|
||||||
|
|
||||||
|
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
|
||||||
|
SCANGOBJ_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-scan.
|
||||||
|
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
|
||||||
|
SCAN_OPTIONS=--rebuild-types --rebuild-sections
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mkdb.
|
||||||
|
# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml
|
||||||
|
MKDB_OPTIONS=--xml-mode --output-format=xml
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mktmpl
|
||||||
|
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
|
||||||
|
MKTMPL_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-mkhtml
|
||||||
|
MKHTML_OPTIONS=
|
||||||
|
|
||||||
|
# Extra options to supply to gtkdoc-fixref. Not normally needed.
|
||||||
|
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
|
||||||
|
FIXXREF_OPTIONS=
|
||||||
|
|
||||||
|
# Used for dependencies. The docs will be rebuilt if any of these change.
|
||||||
|
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
|
||||||
|
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
|
||||||
|
HFILE_GLOB=$(top_srcdir)/src/st/*.h
|
||||||
|
CFILE_GLOB=$(top_srcdir)/src/st/*.c
|
||||||
|
|
||||||
|
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
|
||||||
|
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
|
||||||
|
EXTRA_HFILES=
|
||||||
|
|
||||||
|
# Header files or dirs to ignore when scanning. Use base file/dir names
|
||||||
|
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
|
||||||
|
IGNORE_HFILES=st-private.h st-theme-node-private.h
|
||||||
|
|
||||||
|
# Images to copy into HTML directory.
|
||||||
|
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
|
||||||
|
HTML_IMAGES=
|
||||||
|
|
||||||
|
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
|
||||||
|
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
|
||||||
|
content_files=
|
||||||
|
|
||||||
|
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
|
||||||
|
# These files must be listed here *and* in content_files
|
||||||
|
# e.g. expand_content_files=running.sgml
|
||||||
|
expand_content_files=
|
||||||
|
|
||||||
|
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
|
||||||
|
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
|
||||||
|
# signals and properties.
|
||||||
|
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
|
||||||
|
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
|
||||||
|
GTKDOC_CFLAGS=
|
||||||
|
GTKDOC_LIBS=$(top_builddir)/src/libst-1.0.la
|
||||||
|
|
||||||
|
# This includes the standard gtk-doc make rules, copied by gtkdocize.
|
||||||
|
include $(top_srcdir)/gtk-doc.make
|
||||||
|
|
||||||
|
# Other files to distribute
|
||||||
|
# e.g. EXTRA_DIST += version.xml.in
|
||||||
|
EXTRA_DIST +=
|
||||||
|
|
||||||
|
# Files not to distribute
|
||||||
|
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
|
||||||
|
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
|
||||||
|
DISTCLEANFILES = $(DOC_MODULE).types $(DOC_MODULE)-sections.txt
|
||||||
|
|
||||||
|
# Comment this out if you want 'make check' to test you doc status
|
||||||
|
# and run some sanity checks
|
||||||
|
if ENABLE_GTK_DOC
|
||||||
|
TESTS_ENVIRONMENT = cd $(srcdir) && \
|
||||||
|
DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
|
||||||
|
SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
|
||||||
|
#TESTS = $(GTKDOC_CHECK)
|
||||||
|
endif
|
||||||
|
|
||||||
|
-include $(top_srcdir)/git.mk
|
68
docs/reference/st/st-docs.sgml.in
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||||
|
[
|
||||||
|
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||||||
|
]>
|
||||||
|
<book id="index">
|
||||||
|
<bookinfo>
|
||||||
|
<title>St Reference Manual</title>
|
||||||
|
<releaseinfo>
|
||||||
|
for St @VERSION@.
|
||||||
|
<!--The latest version of this documentation can be found on-line at
|
||||||
|
<ulink role="online-location" url="http://[SERVER]/st/index.html">http://[SERVER]/st/</ulink>.-->
|
||||||
|
</releaseinfo>
|
||||||
|
</bookinfo>
|
||||||
|
|
||||||
|
<part>
|
||||||
|
<title>API reference</title>
|
||||||
|
<chapter id="base">
|
||||||
|
<title>Abstract classes and Interfaces</title>
|
||||||
|
<xi:include href="xml/st-widget.xml"/>
|
||||||
|
<xi:include href="xml/st-widget-accessible.xml"/>
|
||||||
|
<xi:include href="xml/st-container.xml"/>
|
||||||
|
<xi:include href="xml/st-scrollable.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="widgets">
|
||||||
|
<title>Widgets</title>
|
||||||
|
<xi:include href="xml/st-button.xml"/>
|
||||||
|
<xi:include href="xml/st-drawing-area.xml"/>
|
||||||
|
<xi:include href="xml/st-entry.xml"/>
|
||||||
|
<xi:include href="xml/st-icon.xml"/>
|
||||||
|
<xi:include href="xml/st-label.xml"/>
|
||||||
|
<xi:include href="xml/st-tooltip.xml"/>
|
||||||
|
</chapter>
|
||||||
|
<chapter id="containers">
|
||||||
|
<title>Containers</title>
|
||||||
|
<xi:include href="xml/st-bin.xml"/>
|
||||||
|
<xi:include href="xml/st-box-layout.xml"/>
|
||||||
|
<xi:include href="xml/st-group.xml"/>
|
||||||
|
<xi:include href="xml/st-overflow-box.xml"/>
|
||||||
|
<xi:include href="xml/st-scroll-view.xml"/>
|
||||||
|
<xi:include href="xml/st-table.xml"/>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
|
<chapter id="styling">
|
||||||
|
<title>Styling</title>
|
||||||
|
<xi:include href="xml/st-theme.xml"/>
|
||||||
|
<xi:include href="xml/st-theme-context.xml"/>
|
||||||
|
<xi:include href="xml/st-theme-node.xml"/>
|
||||||
|
<xi:include href="xml/st-theme-node-transition.xml"/>
|
||||||
|
<xi:include href="xml/st-texture-cache.xml"/>
|
||||||
|
</chapter>
|
||||||
|
</part>
|
||||||
|
<chapter id="object-tree">
|
||||||
|
<title>Object Hierarchy</title>
|
||||||
|
<xi:include href="xml/tree_index.sgml"/>
|
||||||
|
</chapter>
|
||||||
|
<index id="api-index-full">
|
||||||
|
<title>API Index</title>
|
||||||
|
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||||
|
</index>
|
||||||
|
<index id="deprecated-api-index" role="deprecated">
|
||||||
|
<title>Index of deprecated API</title>
|
||||||
|
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
|
||||||
|
</index>
|
||||||
|
|
||||||
|
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
|
||||||
|
</book>
|
@ -6,6 +6,22 @@
|
|||||||
|
|
||||||
<name xml:lang="en">GNOME Shell</name>
|
<name xml:lang="en">GNOME Shell</name>
|
||||||
<shortdesc xml:lang="en">Next generation GNOME desktop shell</shortdesc>
|
<shortdesc xml:lang="en">Next generation GNOME desktop shell</shortdesc>
|
||||||
|
<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.
|
||||||
|
|
||||||
|
Tarball releases are provided largely for distributions to build
|
||||||
|
packages. If you are interested in building GNOME Shell from source,
|
||||||
|
we would recommend building from version control using the build
|
||||||
|
script described at:
|
||||||
|
|
||||||
|
http://live.gnome.org/GnomeShell
|
||||||
|
|
||||||
|
Not only will that give you the very latest version of this rapidly
|
||||||
|
changing project, it will be much easier than get GNOME Shell and
|
||||||
|
its dependencies to build from tarballs.</description>
|
||||||
<!--
|
<!--
|
||||||
<homepage rdf:resource="http://live.gnome.org/GnomeShell" />
|
<homepage rdf:resource="http://live.gnome.org/GnomeShell" />
|
||||||
-->
|
-->
|
||||||
@ -33,7 +49,7 @@
|
|||||||
<foaf:Person>
|
<foaf:Person>
|
||||||
<foaf:name>Colin Walters</foaf:name>
|
<foaf:name>Colin Walters</foaf:name>
|
||||||
<foaf:mbox rdf:resource="mailto:walters@verbum.org" />
|
<foaf:mbox rdf:resource="mailto:walters@verbum.org" />
|
||||||
<gnome:userid>cwalters</gnome:userid>
|
<gnome:userid>walters</gnome:userid>
|
||||||
</foaf:Person>
|
</foaf:Person>
|
||||||
</maintainer>
|
</maintainer>
|
||||||
<maintainer>
|
<maintainer>
|
||||||
|
@ -2,29 +2,42 @@
|
|||||||
jsdir = $(pkgdatadir)/js
|
jsdir = $(pkgdatadir)/js
|
||||||
|
|
||||||
nobase_dist_js_DATA = \
|
nobase_dist_js_DATA = \
|
||||||
|
gdm/batch.js \
|
||||||
|
gdm/consoleKit.js \
|
||||||
|
gdm/fingerprint.js \
|
||||||
|
gdm/loginDialog.js \
|
||||||
|
gdm/powerMenu.js \
|
||||||
misc/config.js \
|
misc/config.js \
|
||||||
misc/docInfo.js \
|
misc/docInfo.js \
|
||||||
misc/fileUtils.js \
|
misc/fileUtils.js \
|
||||||
misc/format.js \
|
misc/format.js \
|
||||||
misc/gnomeSession.js \
|
misc/gnomeSession.js \
|
||||||
|
misc/history.js \
|
||||||
|
misc/jsParse.js \
|
||||||
|
misc/modemManager.js \
|
||||||
misc/params.js \
|
misc/params.js \
|
||||||
misc/telepathy.js \
|
misc/screenSaver.js \
|
||||||
misc/utils.js \
|
misc/util.js \
|
||||||
perf/core.js \
|
perf/core.js \
|
||||||
ui/altTab.js \
|
ui/altTab.js \
|
||||||
ui/appDisplay.js \
|
ui/appDisplay.js \
|
||||||
ui/appFavorites.js \
|
ui/appFavorites.js \
|
||||||
|
ui/automountManager.js \
|
||||||
|
ui/autorunManager.js \
|
||||||
ui/boxpointer.js \
|
ui/boxpointer.js \
|
||||||
ui/calendar.js \
|
ui/calendar.js \
|
||||||
ui/chrome.js \
|
ui/contactDisplay.js \
|
||||||
ui/ctrlAltTab.js \
|
ui/ctrlAltTab.js \
|
||||||
ui/dash.js \
|
ui/dash.js \
|
||||||
|
ui/dateMenu.js \
|
||||||
ui/dnd.js \
|
ui/dnd.js \
|
||||||
ui/docDisplay.js \
|
ui/docDisplay.js \
|
||||||
|
ui/endSessionDialog.js \
|
||||||
ui/environment.js \
|
ui/environment.js \
|
||||||
ui/extensionSystem.js \
|
ui/extensionSystem.js \
|
||||||
ui/genericDisplay.js \
|
|
||||||
ui/iconGrid.js \
|
ui/iconGrid.js \
|
||||||
|
ui/keyboard.js \
|
||||||
|
ui/layout.js \
|
||||||
ui/lightbox.js \
|
ui/lightbox.js \
|
||||||
ui/link.js \
|
ui/link.js \
|
||||||
ui/lookingGlass.js \
|
ui/lookingGlass.js \
|
||||||
@ -32,11 +45,16 @@ nobase_dist_js_DATA = \
|
|||||||
ui/magnifierDBus.js \
|
ui/magnifierDBus.js \
|
||||||
ui/main.js \
|
ui/main.js \
|
||||||
ui/messageTray.js \
|
ui/messageTray.js \
|
||||||
|
ui/modalDialog.js \
|
||||||
|
ui/networkAgent.js \
|
||||||
|
ui/shellEntry.js \
|
||||||
|
ui/shellMountOperation.js \
|
||||||
ui/notificationDaemon.js \
|
ui/notificationDaemon.js \
|
||||||
ui/overview.js \
|
ui/overview.js \
|
||||||
ui/panel.js \
|
ui/panel.js \
|
||||||
ui/panelMenu.js \
|
ui/panelMenu.js \
|
||||||
ui/placeDisplay.js \
|
ui/placeDisplay.js \
|
||||||
|
ui/polkitAuthenticationAgent.js \
|
||||||
ui/popupMenu.js \
|
ui/popupMenu.js \
|
||||||
ui/runDialog.js \
|
ui/runDialog.js \
|
||||||
ui/scripting.js \
|
ui/scripting.js \
|
||||||
@ -44,17 +62,20 @@ nobase_dist_js_DATA = \
|
|||||||
ui/searchDisplay.js \
|
ui/searchDisplay.js \
|
||||||
ui/shellDBus.js \
|
ui/shellDBus.js \
|
||||||
ui/statusIconDispatcher.js \
|
ui/statusIconDispatcher.js \
|
||||||
ui/statusMenu.js \
|
|
||||||
ui/status/accessibility.js \
|
ui/status/accessibility.js \
|
||||||
|
ui/status/keyboard.js \
|
||||||
|
ui/status/network.js \
|
||||||
ui/status/power.js \
|
ui/status/power.js \
|
||||||
ui/status/volume.js \
|
ui/status/volume.js \
|
||||||
ui/status/bluetooth.js \
|
ui/status/bluetooth.js \
|
||||||
ui/telepathyClient.js \
|
ui/telepathyClient.js \
|
||||||
ui/tweener.js \
|
ui/tweener.js \
|
||||||
|
ui/userMenu.js \
|
||||||
ui/viewSelector.js \
|
ui/viewSelector.js \
|
||||||
ui/windowAttentionHandler.js \
|
ui/windowAttentionHandler.js \
|
||||||
ui/windowManager.js \
|
ui/windowManager.js \
|
||||||
ui/workspace.js \
|
ui/workspace.js \
|
||||||
|
ui/workspaceThumbnail.js \
|
||||||
ui/workspacesView.js \
|
ui/workspacesView.js \
|
||||||
ui/workspaceSwitcherPopup.js \
|
ui/workspaceSwitcherPopup.js \
|
||||||
ui/xdndHandler.js
|
ui/xdndHandler.js
|
||||||
|
203
js/gdm/batch.js
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Red Hat, Inc
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
const Task = new Lang.Class({
|
||||||
|
Name: 'Task',
|
||||||
|
|
||||||
|
_init: function(scope, handler) {
|
||||||
|
if (scope)
|
||||||
|
this.scope = scope;
|
||||||
|
else
|
||||||
|
this.scope = this;
|
||||||
|
|
||||||
|
this.handler = handler;
|
||||||
|
},
|
||||||
|
|
||||||
|
run: function() {
|
||||||
|
if (this.handler)
|
||||||
|
return this.handler.call(this.scope);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(Task.prototype);
|
||||||
|
|
||||||
|
const Hold = new Lang.Class({
|
||||||
|
Name: 'Hold',
|
||||||
|
Extends: Task,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent(this, function () {
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
|
||||||
|
this._acquisitions = 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
acquire: function() {
|
||||||
|
if (this._acquisitions <= 0)
|
||||||
|
throw new Error("Cannot acquire hold after it's been released");
|
||||||
|
this._acquisitions++;
|
||||||
|
},
|
||||||
|
|
||||||
|
acquireUntilAfter: function(hold) {
|
||||||
|
if (!hold.isAcquired())
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.acquire();
|
||||||
|
let signalId = hold.connect('release', Lang.bind(this, function() {
|
||||||
|
hold.disconnect(signalId);
|
||||||
|
this.release();
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
release: function() {
|
||||||
|
this._acquisitions--;
|
||||||
|
|
||||||
|
if (this._acquisitions == 0)
|
||||||
|
this.emit('release');
|
||||||
|
},
|
||||||
|
|
||||||
|
isAcquired: function() {
|
||||||
|
return this._acquisitions > 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(Hold.prototype);
|
||||||
|
|
||||||
|
const Batch = new Lang.Class({
|
||||||
|
Name: 'Batch',
|
||||||
|
Extends: Task,
|
||||||
|
|
||||||
|
_init: function(scope, tasks) {
|
||||||
|
this.parent();
|
||||||
|
|
||||||
|
this.tasks = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < tasks.length; i++) {
|
||||||
|
let task;
|
||||||
|
|
||||||
|
if (tasks[i] instanceof Task) {
|
||||||
|
task = tasks[i];
|
||||||
|
} else if (typeof tasks[i] == 'function') {
|
||||||
|
task = new Task(scope, tasks[i]);
|
||||||
|
} else {
|
||||||
|
throw new Error('Batch tasks must be functions or Task, Hold or Batch objects');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tasks.push(task);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
process: function() {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
},
|
||||||
|
|
||||||
|
runTask: function() {
|
||||||
|
if (!(this._currentTaskIndex in this.tasks)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.tasks[this._currentTaskIndex].run();
|
||||||
|
},
|
||||||
|
|
||||||
|
_finish: function() {
|
||||||
|
this.hold.release();
|
||||||
|
},
|
||||||
|
|
||||||
|
nextTask: function() {
|
||||||
|
this._currentTaskIndex++;
|
||||||
|
|
||||||
|
// if the entire batch of tasks is finished, release
|
||||||
|
// the hold and notify anyone waiting on the batch
|
||||||
|
if (this._currentTaskIndex >= this.tasks.length) {
|
||||||
|
this._finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.process();
|
||||||
|
},
|
||||||
|
|
||||||
|
_start: function() {
|
||||||
|
// acquire a hold to get released when the entire
|
||||||
|
// batch of tasks is finished
|
||||||
|
this.hold = new Hold();
|
||||||
|
this._currentTaskIndex = 0;
|
||||||
|
this.process();
|
||||||
|
},
|
||||||
|
|
||||||
|
run: function() {
|
||||||
|
this._start();
|
||||||
|
|
||||||
|
// hold may be destroyed at this point
|
||||||
|
// if we're already done running
|
||||||
|
return this.hold;
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel: function() {
|
||||||
|
this.tasks = this.tasks.splice(0, this._currentTaskIndex + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(Batch.prototype);
|
||||||
|
|
||||||
|
const ConcurrentBatch = new Lang.Class({
|
||||||
|
Name: 'ConcurrentBatch',
|
||||||
|
Extends: Batch,
|
||||||
|
|
||||||
|
process: function() {
|
||||||
|
let hold = this.runTask();
|
||||||
|
|
||||||
|
if (hold) {
|
||||||
|
this.hold.acquireUntilAfter(hold);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regardless of the state of the just run task,
|
||||||
|
// fire off the next one, so all the tasks can run
|
||||||
|
// concurrently.
|
||||||
|
this.nextTask();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(ConcurrentBatch.prototype);
|
||||||
|
|
||||||
|
const ConsecutiveBatch = new Lang.Class({
|
||||||
|
Name: 'ConsecutiveBatch',
|
||||||
|
Extends: Batch,
|
||||||
|
|
||||||
|
process: function() {
|
||||||
|
let hold = this.runTask();
|
||||||
|
|
||||||
|
if (hold && hold.isAcquired()) {
|
||||||
|
// This task is inhibiting the batch. Wait on it
|
||||||
|
// before processing the next one.
|
||||||
|
let signalId = hold.connect('release',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
hold.disconnect(signalId);
|
||||||
|
this.nextTask();
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// This task finished, process the next one
|
||||||
|
this.nextTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(ConsecutiveBatch.prototype);
|
22
js/gdm/consoleKit.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
|
||||||
|
const ConsoleKitManagerIface = <interface name='org.freedesktop.ConsoleKit.Manager'>
|
||||||
|
<method name='CanRestart'>
|
||||||
|
<arg type='b' direction='out'/>
|
||||||
|
</method>
|
||||||
|
<method name='CanStop'>
|
||||||
|
<arg type='b' direction='out'/>
|
||||||
|
</method>
|
||||||
|
<method name='Restart' />
|
||||||
|
<method name='Stop' />
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ConsoleKitProxy = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
|
||||||
|
|
||||||
|
function ConsoleKitManager() {
|
||||||
|
return new ConsoleKitProxy(Gio.DBus.system,
|
||||||
|
'org.freedesktop.ConsoleKit',
|
||||||
|
'/org/freedesktop/ConsoleKit/Manager');
|
||||||
|
};
|
20
js/gdm/fingerprint.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
const FprintManagerIface = <interface name='net.reactivated.Fprint.Manager'>
|
||||||
|
<method name='GetDefaultDevice'>
|
||||||
|
<arg type='o' direction='out' />
|
||||||
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const FprintManagerProxy = Gio.DBusProxy.makeProxyWrapper(FprintManagerIface);
|
||||||
|
|
||||||
|
function FprintManager() {
|
||||||
|
return new FprintManagerProxy(Gio.DBus.system,
|
||||||
|
'net.reactivated.Fprint',
|
||||||
|
'/net/reactivated/Fprint/Manager');
|
||||||
|
};
|
1387
js/gdm/loginDialog.js
Normal file
143
js/gdm/powerMenu.js
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Red Hat, Inc
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const UPowerGlib = imports.gi.UPowerGlib;
|
||||||
|
|
||||||
|
const ConsoleKit = imports.gdm.consoleKit;
|
||||||
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
|
const PowerMenuButton = new Lang.Class({
|
||||||
|
Name: 'PowerMenuButton',
|
||||||
|
Extends: PanelMenu.SystemStatusButton,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent('system-shutdown', null);
|
||||||
|
this._consoleKitManager = new ConsoleKit.ConsoleKitManager();
|
||||||
|
this._upClient = new UPowerGlib.Client();
|
||||||
|
|
||||||
|
this._createSubMenu();
|
||||||
|
|
||||||
|
this._upClient.connect('notify::can-suspend',
|
||||||
|
Lang.bind(this, this._updateHaveSuspend));
|
||||||
|
this._updateHaveSuspend();
|
||||||
|
|
||||||
|
// ConsoleKit doesn't send notifications when shutdown/reboot
|
||||||
|
// are disabled, so we update the menu item each time the menu opens
|
||||||
|
this.menu.connect('open-state-changed', Lang.bind(this,
|
||||||
|
function(menu, open) {
|
||||||
|
if (open) {
|
||||||
|
this._updateHaveShutdown();
|
||||||
|
this._updateHaveRestart();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
this._updateHaveShutdown();
|
||||||
|
this._updateHaveRestart();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateVisibility: function() {
|
||||||
|
if (!this._haveSuspend && !this._haveShutdown && !this._haveRestart)
|
||||||
|
this.actor.hide();
|
||||||
|
else
|
||||||
|
this.actor.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateHaveShutdown: function() {
|
||||||
|
this._consoleKitManager.CanStopRemote(Lang.bind(this,
|
||||||
|
function(result, error) {
|
||||||
|
if (!error)
|
||||||
|
this._haveShutdown = result;
|
||||||
|
else
|
||||||
|
this._haveShutdown = false;
|
||||||
|
|
||||||
|
if (this._haveShutdown) {
|
||||||
|
this._powerOffItem.actor.show();
|
||||||
|
} else {
|
||||||
|
this._powerOffItem.actor.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateHaveRestart: function() {
|
||||||
|
this._consoleKitManager.CanRestartRemote(Lang.bind(this,
|
||||||
|
function(result, error) {
|
||||||
|
if (!error)
|
||||||
|
this._haveRestart = result;
|
||||||
|
else
|
||||||
|
this._haveRestart = false;
|
||||||
|
|
||||||
|
if (this._haveRestart) {
|
||||||
|
this._restartItem.actor.show();
|
||||||
|
} else {
|
||||||
|
this._restartItem.actor.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateHaveSuspend: function() {
|
||||||
|
this._haveSuspend = this._upClient.get_can_suspend();
|
||||||
|
|
||||||
|
if (this._haveSuspend)
|
||||||
|
this._suspendItem.actor.show();
|
||||||
|
else
|
||||||
|
this._suspendItem.actor.hide();
|
||||||
|
|
||||||
|
this._updateVisibility();
|
||||||
|
},
|
||||||
|
|
||||||
|
_createSubMenu: function() {
|
||||||
|
let item;
|
||||||
|
|
||||||
|
item = new PopupMenu.PopupMenuItem(_("Suspend"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onActivateSuspend));
|
||||||
|
this.menu.addMenuItem(item);
|
||||||
|
this._suspendItem = item;
|
||||||
|
|
||||||
|
item = new PopupMenu.PopupMenuItem(_("Restart"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onActivateRestart));
|
||||||
|
this.menu.addMenuItem(item);
|
||||||
|
this._restartItem = item;
|
||||||
|
|
||||||
|
item = new PopupMenu.PopupMenuItem(_("Power Off"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onActivatePowerOff));
|
||||||
|
this.menu.addMenuItem(item);
|
||||||
|
this._powerOffItem = item;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onActivateSuspend: function() {
|
||||||
|
if (this._haveSuspend)
|
||||||
|
this._upClient.suspend_sync(null);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onActivateRestart: function() {
|
||||||
|
if (this._haveRestart)
|
||||||
|
this._consoleKitManager.RestartRemote();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onActivatePowerOff: function() {
|
||||||
|
if (this._haveShutdown)
|
||||||
|
this._consoleKitManager.StopRemote();
|
||||||
|
}
|
||||||
|
});
|
@ -1,3 +1,12 @@
|
|||||||
/* mode: js2; indent-tabs-mode: nil; tab-size: 4 */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
|
|
||||||
|
|
||||||
|
/* The name of this package (not localized) */
|
||||||
|
const PACKAGE_NAME = '@PACKAGE_NAME@';
|
||||||
|
/* The version of this package */
|
||||||
|
const PACKAGE_VERSION = '@PACKAGE_VERSION@';
|
||||||
|
/* The version of GJS we're linking to */
|
||||||
|
const GJS_VERSION = '@GJS_VERSION@';
|
||||||
|
/* 1 if gnome-bluetooth is available, 0 otherwise */
|
||||||
|
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
|
||||||
|
/* The system TLS CA list */
|
||||||
|
const SHELL_SYSTEM_CA_FILE = '@SHELL_SYSTEM_CA_FILE@';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
@ -8,11 +8,9 @@ const Search = imports.ui.search;
|
|||||||
|
|
||||||
const THUMBNAIL_ICON_MARGIN = 2;
|
const THUMBNAIL_ICON_MARGIN = 2;
|
||||||
|
|
||||||
function DocInfo(recentInfo) {
|
const DocInfo = new Lang.Class({
|
||||||
this._init(recentInfo);
|
Name: 'DocInfo',
|
||||||
}
|
|
||||||
|
|
||||||
DocInfo.prototype = {
|
|
||||||
_init : function(recentInfo) {
|
_init : function(recentInfo) {
|
||||||
this.recentInfo = recentInfo;
|
this.recentInfo = recentInfo;
|
||||||
// We actually used get_modified() instead of get_visited()
|
// We actually used get_modified() instead of get_visited()
|
||||||
@ -29,8 +27,8 @@ DocInfo.prototype = {
|
|||||||
return St.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
|
return St.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
|
||||||
},
|
},
|
||||||
|
|
||||||
launch : function() {
|
launch : function(workspaceIndex) {
|
||||||
Shell.DocSystem.get_default().open(this.recentInfo);
|
Shell.DocSystem.get_default().open(this.recentInfo, workspaceIndex);
|
||||||
},
|
},
|
||||||
|
|
||||||
matchTerms: function(terms) {
|
matchTerms: function(terms) {
|
||||||
@ -49,7 +47,7 @@ DocInfo.prototype = {
|
|||||||
}
|
}
|
||||||
return mtype;
|
return mtype;
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
var docManagerInstance = null;
|
var docManagerInstance = null;
|
||||||
|
|
||||||
@ -60,14 +58,11 @@ function getDocManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DocManager wraps the DocSystem, primarily to expose DocInfo objects
|
* DocManager wraps the DocSystem, primarily to expose DocInfo objects.
|
||||||
* which conform to the GenericDisplay item API.
|
|
||||||
*/
|
*/
|
||||||
function DocManager() {
|
const DocManager = new Lang.Class({
|
||||||
this._init();
|
Name: 'DocManager',
|
||||||
}
|
|
||||||
|
|
||||||
DocManager.prototype = {
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._docSystem = Shell.DocSystem.get_default();
|
this._docSystem = Shell.DocSystem.get_default();
|
||||||
this._infosByTimestamp = [];
|
this._infosByTimestamp = [];
|
||||||
@ -136,6 +131,6 @@ DocManager.prototype = {
|
|||||||
return this._infosByUri[url];
|
return this._infosByUri[url];
|
||||||
})), terms);
|
})), terms);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
Signals.addSignalMethods(DocManager.prototype);
|
Signals.addSignalMethods(DocManager.prototype);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
|
||||||
@ -20,3 +22,25 @@ function listDirAsync(file, callback) {
|
|||||||
enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, onNextFileComplete);
|
enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, onNextFileComplete);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteGFile(file) {
|
||||||
|
// Work around 'delete' being a keyword in JS.
|
||||||
|
return file['delete'](null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function recursivelyDeleteDir(dir) {
|
||||||
|
let children = dir.enumerate_children('standard::name,standard::type',
|
||||||
|
Gio.FileQueryInfoFlags.NONE, null);
|
||||||
|
|
||||||
|
let info, child;
|
||||||
|
while ((info = children.next_file(null)) != null) {
|
||||||
|
let type = info.get_file_type();
|
||||||
|
let child = dir.get_child(info.get_name());
|
||||||
|
if (type == Gio.FileType.REGULAR)
|
||||||
|
deleteGFile(child);
|
||||||
|
else if (type == Gio.TypeType.DIRECTORY)
|
||||||
|
recursivelyDeleteDir(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteGFile(dir);
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is intended to extend the String object and provide
|
* This function is intended to extend the String object and provide
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
const PresenceIface = {
|
const PresenceIface = <interface name="org.gnome.SessionManager.Presence">
|
||||||
name: 'org.gnome.SessionManager.Presence',
|
<method name="SetStatus">
|
||||||
methods: [{ name: 'SetStatus',
|
<arg type="u" direction="in"/>
|
||||||
inSignature: 'u' }],
|
</method>
|
||||||
properties: [{ name: 'status',
|
<property name="status" type="u" access="readwrite"/>
|
||||||
signature: 'u',
|
<signal name="StatusChanged">
|
||||||
access: 'readwrite' }],
|
<arg type="u" direction="out"/>
|
||||||
signals: [{ name: 'StatusChanged',
|
</signal>
|
||||||
inSignature: 'u' }]
|
</interface>;
|
||||||
};
|
|
||||||
|
|
||||||
const PresenceStatus = {
|
const PresenceStatus = {
|
||||||
AVAILABLE: 0,
|
AVAILABLE: 0,
|
||||||
@ -21,25 +21,41 @@ const PresenceStatus = {
|
|||||||
IDLE: 3
|
IDLE: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
function Presence() {
|
var PresenceProxy = Gio.DBusProxy.makeProxyWrapper(PresenceIface);
|
||||||
this._init();
|
function Presence(initCallback, cancellable) {
|
||||||
|
return new PresenceProxy(Gio.DBus.session, 'org.gnome.SessionManager',
|
||||||
|
'/org/gnome/SessionManager/Presence', initCallback, cancellable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Presence.prototype = {
|
// Note inhibitors are immutable objects, so they don't
|
||||||
_init: function() {
|
// change at runtime (changes always come in the form
|
||||||
DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager/Presence', this);
|
// of new inhibitors)
|
||||||
},
|
const InhibitorIface = <interface name="org.gnome.SessionManager.Inhibitor">
|
||||||
|
<property name="app_id" type="s" access="read" />
|
||||||
|
<property name="client_id" type="s" access="read" />
|
||||||
|
<property name="reason" type="s" access="read" />
|
||||||
|
<property name="flags" type="u" access="read" />
|
||||||
|
<property name="toplevel_xid" type="u" access="read" />
|
||||||
|
<property name="cookie" type="u" access="read" />
|
||||||
|
</interface>;
|
||||||
|
|
||||||
getStatus: function(callback) {
|
var InhibitorProxy = Gio.DBusProxy.makeProxyWrapper(InhibitorIface);
|
||||||
this.GetRemote('status', Lang.bind(this,
|
function Inhibitor(objectPath, initCallback, cancellable) {
|
||||||
function(status, ex) {
|
return new InhibitorProxy(Gio.DBus.session, 'org.gnome.SessionManager', objectPath, initCallback, cancellable);
|
||||||
if (!ex)
|
}
|
||||||
callback(this, status);
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
setStatus: function(status) {
|
// Not the full interface, only the methods we use
|
||||||
this.SetStatusRemote(status);
|
const SessionManagerIface = <interface name="org.gnome.SessionManager">
|
||||||
}
|
<method name="Logout">
|
||||||
};
|
<arg type="u" direction="in" />
|
||||||
DBus.proxifyPrototype(Presence.prototype, PresenceIface);
|
</method>
|
||||||
|
<method name="Shutdown" />
|
||||||
|
<method name="CanShutdown">
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface);
|
||||||
|
function SessionManager(initCallback, cancellable) {
|
||||||
|
return new SessionManagerProxy(Gio.DBus.session, 'org.gnome.SessionManager', '/org/gnome/SessionManager', initCallback, cancellable);
|
||||||
|
}
|
||||||
|
113
js/misc/history.js
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Params = imports.misc.params;
|
||||||
|
|
||||||
|
const DEFAULT_LIMIT = 512;
|
||||||
|
|
||||||
|
const HistoryManager = new Lang.Class({
|
||||||
|
Name: 'HistoryManager',
|
||||||
|
|
||||||
|
_init: function(params) {
|
||||||
|
params = Params.parse(params, { gsettingsKey: null,
|
||||||
|
limit: DEFAULT_LIMIT,
|
||||||
|
entry: null });
|
||||||
|
|
||||||
|
this._key = params.gsettingsKey;
|
||||||
|
this._limit = params.limit;
|
||||||
|
|
||||||
|
this._historyIndex = 0;
|
||||||
|
if (this._key) {
|
||||||
|
this._history = global.settings.get_strv(this._key);
|
||||||
|
global.settings.connect('changed::' + this._key,
|
||||||
|
Lang.bind(this, this._historyChanged));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this._history = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this._entry = params.entry;
|
||||||
|
|
||||||
|
if (this._entry) {
|
||||||
|
this._entry.connect('key-press-event',
|
||||||
|
Lang.bind(this, this._onEntryKeyPress));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_historyChanged: function() {
|
||||||
|
this._history = global.settings.get_strv(this._key);
|
||||||
|
this._historyIndex = this._history.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
prevItem: function(text) {
|
||||||
|
if (this._historyIndex <= 0)
|
||||||
|
return text;
|
||||||
|
|
||||||
|
if (text)
|
||||||
|
this._history[this._historyIndex] = text;
|
||||||
|
this._historyIndex--;
|
||||||
|
return this._indexChanged();
|
||||||
|
},
|
||||||
|
|
||||||
|
nextItem: function(text) {
|
||||||
|
if (this._historyIndex >= this._history.length)
|
||||||
|
return text;
|
||||||
|
|
||||||
|
if (text)
|
||||||
|
this._history[this._historyIndex] = text;
|
||||||
|
this._historyIndex++;
|
||||||
|
return this._indexChanged();
|
||||||
|
},
|
||||||
|
|
||||||
|
lastItem: function() {
|
||||||
|
if (this._historyIndex != this._history.length) {
|
||||||
|
this._historyIndex = this._history.length;
|
||||||
|
this._indexChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._historyIndex[this._history.length];
|
||||||
|
},
|
||||||
|
|
||||||
|
addItem: function(input) {
|
||||||
|
if (this._history.length == 0 ||
|
||||||
|
this._history[this._history.length - 1] != input) {
|
||||||
|
|
||||||
|
this._history.push(input);
|
||||||
|
this._save();
|
||||||
|
}
|
||||||
|
this._historyIndex = this._history.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onEntryKeyPress: function(entry, event) {
|
||||||
|
let symbol = event.get_key_symbol();
|
||||||
|
if (symbol == Clutter.KEY_Up) {
|
||||||
|
this.prevItem(entry.get_text());
|
||||||
|
return true;
|
||||||
|
} else if (symbol == Clutter.KEY_Down) {
|
||||||
|
this.nextItem(entry.get_text());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_indexChanged: function() {
|
||||||
|
let current = this._history[this._historyIndex] || '';
|
||||||
|
this.emit('changed', current);
|
||||||
|
|
||||||
|
if (this._entry)
|
||||||
|
this._entry.set_text(current);
|
||||||
|
|
||||||
|
return current;
|
||||||
|
},
|
||||||
|
|
||||||
|
_save: function() {
|
||||||
|
if (this._history.length > this._limit)
|
||||||
|
this._history.splice(0, this._history.length - this._limit);
|
||||||
|
|
||||||
|
if (this._key)
|
||||||
|
global.settings.set_strv(this._key, this._history);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(HistoryManager.prototype);
|
246
js/misc/jsParse.js
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
// Returns a list of potential completions for text. Completions either
|
||||||
|
// follow a dot (e.g. foo.ba -> bar) or they are picked from globalCompletionList (e.g. fo -> foo)
|
||||||
|
// commandHeader is prefixed on any expression before it is eval'ed. It will most likely
|
||||||
|
// consist of global constants that might not carry over from the calling environment.
|
||||||
|
//
|
||||||
|
// This function is likely the one you want to call from external modules
|
||||||
|
function getCompletions(text, commandHeader, globalCompletionList) {
|
||||||
|
let methods = [];
|
||||||
|
let expr, base;
|
||||||
|
let attrHead = '';
|
||||||
|
if (globalCompletionList == null) {
|
||||||
|
globalCompletionList = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let offset = getExpressionOffset(text, text.length - 1);
|
||||||
|
if (offset >= 0) {
|
||||||
|
text = text.slice(offset);
|
||||||
|
|
||||||
|
// Look for expressions like "Main.panel.foo" and match Main.panel and foo
|
||||||
|
let matches = text.match(/(.*)\.(.*)/);
|
||||||
|
if (matches) {
|
||||||
|
[expr, base, attrHead] = matches;
|
||||||
|
|
||||||
|
methods = getPropertyNamesFromExpression(base, commandHeader).filter(function(attr) {
|
||||||
|
return attr.slice(0, attrHead.length) == attrHead;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for the empty expression or partially entered words
|
||||||
|
// not proceeded by a dot and match them against global constants
|
||||||
|
matches = text.match(/^(\w*)$/);
|
||||||
|
if (text == '' || matches) {
|
||||||
|
[expr, attrHead] = matches;
|
||||||
|
methods = globalCompletionList.filter(function(attr) {
|
||||||
|
return attr.slice(0, attrHead.length) == attrHead;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [methods, attrHead];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// A few functions for parsing strings of javascript code.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Identify characters that delimit an expression. That is,
|
||||||
|
// if we encounter anything that isn't a letter, '.', ')', or ']',
|
||||||
|
// we should stop parsing.
|
||||||
|
function isStopChar(c) {
|
||||||
|
return !c.match(/[\w\.\)\]]/);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given the ending position of a quoted string, find where it starts
|
||||||
|
function findMatchingQuote(expr, offset) {
|
||||||
|
let quoteChar = expr.charAt(offset);
|
||||||
|
for (let i = offset - 1; i >= 0; --i) {
|
||||||
|
if (expr.charAt(i) == quoteChar && expr.charAt(i-1) != '\\'){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given the ending position of a regex, find where it starts
|
||||||
|
function findMatchingSlash(expr, offset) {
|
||||||
|
for (let i = offset - 1; i >= 0; --i) {
|
||||||
|
if (expr.charAt(i) == '/' && expr.charAt(i-1) != '\\'){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If expr.charAt(offset) is ')' or ']',
|
||||||
|
// return the position of the corresponding '(' or '[' bracket.
|
||||||
|
// This function does not check for syntactic correctness. e.g.,
|
||||||
|
// findMatchingBrace("[(])", 3) returns 1.
|
||||||
|
function findMatchingBrace(expr, offset) {
|
||||||
|
let closeBrace = expr.charAt(offset);
|
||||||
|
let openBrace = ({')': '(', ']': '['})[closeBrace];
|
||||||
|
|
||||||
|
function findTheBrace(expr, offset) {
|
||||||
|
if (offset < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expr.charAt(offset) == openBrace) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
if (expr.charAt(offset).match(/['"]/)) {
|
||||||
|
return findTheBrace(expr, findMatchingQuote(expr, offset) - 1);
|
||||||
|
}
|
||||||
|
if (expr.charAt(offset) == '/') {
|
||||||
|
return findTheBrace(expr, findMatchingSlash(expr, offset) - 1);
|
||||||
|
}
|
||||||
|
if (expr.charAt(offset) == closeBrace) {
|
||||||
|
return findTheBrace(expr, findTheBrace(expr, offset - 1) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return findTheBrace(expr, offset - 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return findTheBrace(expr, offset - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk expr backwards from offset looking for the beginning of an
|
||||||
|
// expression suitable for passing to eval.
|
||||||
|
// There is no guarantee of correct javascript syntax between the return
|
||||||
|
// value and offset. This function is meant to take a string like
|
||||||
|
// "foo(Obj.We.Are.Completing" and allow you to extract "Obj.We.Are.Completing"
|
||||||
|
function getExpressionOffset(expr, offset) {
|
||||||
|
while (offset >= 0) {
|
||||||
|
let currChar = expr.charAt(offset);
|
||||||
|
|
||||||
|
if (isStopChar(currChar)){
|
||||||
|
return offset + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currChar.match(/[\)\]]/)) {
|
||||||
|
offset = findMatchingBrace(expr, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
--offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Things with non-word characters or that start with a number
|
||||||
|
// are not accessible via .foo notation and so aren't returned
|
||||||
|
function isValidPropertyName(w) {
|
||||||
|
return !(w.match(/\W/) || w.match(/^\d/));
|
||||||
|
}
|
||||||
|
|
||||||
|
// To get all properties (enumerable and not), we need to walk
|
||||||
|
// the prototype chain ourselves
|
||||||
|
function getAllProps(obj) {
|
||||||
|
if (obj === null || obj === undefined) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return Object.getOwnPropertyNames(obj).concat( getAllProps(Object.getPrototypeOf(obj)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a string _expr_, returns all methods
|
||||||
|
// that can be accessed via '.' notation.
|
||||||
|
// e.g., expr="({ foo: null, bar: null, 4: null })" will
|
||||||
|
// return ["foo", "bar", ...] but the list will not include "4",
|
||||||
|
// since methods accessed with '.' notation must star with a letter or _.
|
||||||
|
function getPropertyNamesFromExpression(expr, commandHeader) {
|
||||||
|
if (commandHeader == null) {
|
||||||
|
commandHeader = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let obj = {};
|
||||||
|
if (!isUnsafeExpression(expr)) {
|
||||||
|
try {
|
||||||
|
obj = eval(commandHeader + expr);
|
||||||
|
} catch (e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let propsUnique = {};
|
||||||
|
if (typeof obj === 'object'){
|
||||||
|
let allProps = getAllProps(obj);
|
||||||
|
// Get only things we are allowed to complete following a '.'
|
||||||
|
allProps = allProps.filter( isValidPropertyName );
|
||||||
|
|
||||||
|
// Make sure propsUnique contains one key for every
|
||||||
|
// property so we end up with a unique list of properties
|
||||||
|
allProps.map(function(p){ propsUnique[p] = null; });
|
||||||
|
}
|
||||||
|
return Object.keys(propsUnique).sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a list of words, returns the longest prefix they all have in common
|
||||||
|
function getCommonPrefix(words) {
|
||||||
|
let word = words[0];
|
||||||
|
for (let i = 0; i < word.length; i++) {
|
||||||
|
for (let w = 1; w < words.length; w++) {
|
||||||
|
if (words[w].charAt(i) != word.charAt(i))
|
||||||
|
return word.slice(0, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if there is reason to think that eval(str)
|
||||||
|
// will modify the global scope
|
||||||
|
function isUnsafeExpression(str) {
|
||||||
|
// Remove any blocks that are quoted or are in a regex
|
||||||
|
function removeLiterals(str) {
|
||||||
|
if (str.length == 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let currChar = str.charAt(str.length - 1);
|
||||||
|
if (currChar == '"' || currChar == '\'') {
|
||||||
|
return removeLiterals(str.slice(0, findMatchingQuote(str, str.length - 1)));
|
||||||
|
} else if (currChar == '/') {
|
||||||
|
return removeLiterals(str.slice(0, findMatchingSlash(str, str.length - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return removeLiterals(str.slice(0, str.length - 1)) + currChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for any sort of assignment
|
||||||
|
// The strategy used is dumb: remove any quotes
|
||||||
|
// or regexs and comparison operators and see if there is an '=' character.
|
||||||
|
// If there is, it might be an unsafe assignment.
|
||||||
|
|
||||||
|
let prunedStr = removeLiterals(str);
|
||||||
|
prunedStr = prunedStr.replace(/[=!]==/g, ''); //replace === and !== with nothing
|
||||||
|
prunedStr = prunedStr.replace(/[=<>!]=/g, ''); //replace ==, <=, >=, != with nothing
|
||||||
|
|
||||||
|
if (prunedStr.match(/=/)) {
|
||||||
|
return true;
|
||||||
|
} else if (prunedStr.match(/;/)) {
|
||||||
|
// If we contain a semicolon not inside of a quote/regex, assume we're unsafe as well
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a list of global keywords derived from str
|
||||||
|
function getDeclaredConstants(str) {
|
||||||
|
let ret = [];
|
||||||
|
str.split(';').forEach(function(s) {
|
||||||
|
let base, keyword;
|
||||||
|
let match = s.match(/const\s+(\w+)\s*=/);
|
||||||
|
if (match) {
|
||||||
|
[base, keyword] = match;
|
||||||
|
ret.push(keyword);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
231
js/misc/modemManager.js
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
// The following are not the complete interfaces, just the methods we need
|
||||||
|
// (or may need in the future)
|
||||||
|
|
||||||
|
const ModemGsmNetworkInterface = <interface name="org.freedesktop.ModemManager.Modem.Gsm.Network">
|
||||||
|
<method name="GetRegistrationInfo">
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
<arg type="s" direction="out" />
|
||||||
|
<arg type="s" direction="out" />
|
||||||
|
</method>
|
||||||
|
<method name="GetSignalQuality">
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
</method>
|
||||||
|
<property name="AccessTechnology" type="u" access="read" />
|
||||||
|
<signal name="SignalQuality">
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
</signal>
|
||||||
|
<signal name="RegistrationInfo">
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
<arg type="s" direction="out" />
|
||||||
|
<arg type="s" direction="out" />
|
||||||
|
</signal>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInterface);
|
||||||
|
|
||||||
|
const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.Cdma">
|
||||||
|
<method name="GetSignalQuality">
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
</method>
|
||||||
|
<method name="GetServingSystem">
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
<arg type="s" direction="out" />
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
</method>
|
||||||
|
<signal name="SignalQuality">
|
||||||
|
<arg type="u" direction="out" />
|
||||||
|
</signal>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
|
||||||
|
|
||||||
|
let _providersTable;
|
||||||
|
function _getProvidersTable() {
|
||||||
|
if (_providersTable)
|
||||||
|
return _providersTable;
|
||||||
|
let [providers, countryCodes] = Shell.mobile_providers_parse();
|
||||||
|
return _providersTable = providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModemGsm = new Lang.Class({
|
||||||
|
Name: 'ModemGsm',
|
||||||
|
|
||||||
|
_init: function(path) {
|
||||||
|
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||||
|
|
||||||
|
this.signal_quality = 0;
|
||||||
|
this.operator_name = null;
|
||||||
|
|
||||||
|
// Code is duplicated because the function have different signatures
|
||||||
|
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, [quality]) {
|
||||||
|
this.signal_quality = quality;
|
||||||
|
this.emit('notify::signal-quality');
|
||||||
|
}));
|
||||||
|
this._proxy.connectSignal('RegistrationInfo', Lang.bind(this, function(proxy, sender, [status, code, name]) {
|
||||||
|
this.operator_name = this._findOperatorName(name, code);
|
||||||
|
this.emit('notify::operator-name');
|
||||||
|
}));
|
||||||
|
this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function(result, err) {
|
||||||
|
if (err) {
|
||||||
|
log(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [status, code, name] = result;
|
||||||
|
this.operator_name = this._findOperatorName(name, code);
|
||||||
|
this.emit('notify::operator-name');
|
||||||
|
}));
|
||||||
|
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
|
||||||
|
if (err) {
|
||||||
|
// it will return an error if the device is not connected
|
||||||
|
this.signal_quality = 0;
|
||||||
|
} else {
|
||||||
|
let [quality] = result;
|
||||||
|
this.signal_quality = quality;
|
||||||
|
}
|
||||||
|
this.emit('notify::signal-quality');
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_findOperatorName: function(name, opCode) {
|
||||||
|
if (name.length != 0 && (name.length > 6 || name.length < 5)) {
|
||||||
|
// this looks like a valid name, i.e. not an MCCMNC (that some
|
||||||
|
// devices return when not yet connected
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
if (isNaN(parseInt(name))) {
|
||||||
|
// name is definitely not a MCCMNC, so it may be a name
|
||||||
|
// after all; return that
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
let needle;
|
||||||
|
if (name.length == 0 && opCode)
|
||||||
|
needle = opCode;
|
||||||
|
else if (name.length == 6 || name.length == 5)
|
||||||
|
needle = name;
|
||||||
|
else // nothing to search
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return this._findProviderForMCCMNC(needle);
|
||||||
|
},
|
||||||
|
|
||||||
|
_findProviderForMCCMNC: function(needle) {
|
||||||
|
let table = _getProvidersTable();
|
||||||
|
let needlemcc = needle.substring(0, 3);
|
||||||
|
let needlemnc = needle.substring(3, needle.length);
|
||||||
|
|
||||||
|
let name2, name3;
|
||||||
|
for (let iter in table) {
|
||||||
|
let providers = table[iter];
|
||||||
|
|
||||||
|
// Search through each country's providers
|
||||||
|
for (let i = 0; i < providers.length; i++) {
|
||||||
|
let provider = providers[i];
|
||||||
|
|
||||||
|
// Search through MCC/MNC list
|
||||||
|
let list = provider.get_gsm_mcc_mnc();
|
||||||
|
for (let j = 0; j < list.length; j++) {
|
||||||
|
let mccmnc = list[j];
|
||||||
|
|
||||||
|
// Match both 2-digit and 3-digit MNC; prefer a
|
||||||
|
// 3-digit match if found, otherwise a 2-digit one.
|
||||||
|
if (mccmnc.mcc != needlemcc)
|
||||||
|
continue; // MCC was wrong
|
||||||
|
|
||||||
|
if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
|
||||||
|
name3 = provider.name;
|
||||||
|
|
||||||
|
if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
|
||||||
|
name2 = provider.name;
|
||||||
|
|
||||||
|
if (name2 && name3)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name3 || name2 || null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(ModemGsm.prototype);
|
||||||
|
|
||||||
|
const ModemCdma = new Lang.Class({
|
||||||
|
Name: 'ModemCdma',
|
||||||
|
|
||||||
|
_init: function(path) {
|
||||||
|
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||||
|
|
||||||
|
this.signal_quality = 0;
|
||||||
|
this.operator_name = null;
|
||||||
|
this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
|
||||||
|
this.signal_quality = params[0];
|
||||||
|
this.emit('notify::signal-quality');
|
||||||
|
|
||||||
|
// receiving this signal means the device got activated
|
||||||
|
// and we can finally call GetServingSystem
|
||||||
|
if (this.operator_name == null)
|
||||||
|
this._refreshServingSystem();
|
||||||
|
}));
|
||||||
|
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
|
||||||
|
if (err) {
|
||||||
|
// it will return an error if the device is not connected
|
||||||
|
this.signal_quality = 0;
|
||||||
|
} else {
|
||||||
|
let [quality] = result;
|
||||||
|
this.signal_quality = quality;
|
||||||
|
}
|
||||||
|
this.emit('notify::signal-quality');
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_refreshServingSystem: function() {
|
||||||
|
this._proxy.GetServingSystemRemote(Lang.bind(this, function(result, err) {
|
||||||
|
if (err) {
|
||||||
|
// it will return an error if the device is not connected
|
||||||
|
this.operator_name = null;
|
||||||
|
} else {
|
||||||
|
let [bandClass, band, id] = result;
|
||||||
|
if (name.length > 0)
|
||||||
|
this.operator_name = this._findProviderForSid(id);
|
||||||
|
else
|
||||||
|
this.operator_name = null;
|
||||||
|
}
|
||||||
|
this.emit('notify::operator-name');
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_findProviderForSid: function(sid) {
|
||||||
|
if (sid == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
let table = _getProvidersTable();
|
||||||
|
|
||||||
|
// Search through each country
|
||||||
|
for (let iter in table) {
|
||||||
|
let providers = table[iter];
|
||||||
|
|
||||||
|
// Search through each country's providers
|
||||||
|
for (let i = 0; i < providers.length; i++) {
|
||||||
|
let provider = providers[i];
|
||||||
|
let cdma_sid = provider.get_cdma_sid();
|
||||||
|
|
||||||
|
// Search through CDMA SID list
|
||||||
|
for (let j = 0; j < cdma_sid.length; j++) {
|
||||||
|
if (cdma_sid[j] == sid)
|
||||||
|
return provider.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(ModemCdma.prototype);
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
// parse:
|
// parse:
|
||||||
// @params: caller-provided parameter object, or %null
|
// @params: caller-provided parameter object, or %null
|
||||||
|
48
js/misc/screenSaver.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
|
||||||
|
const ScreenSaverIface = <interface name="org.gnome.ScreenSaver">
|
||||||
|
<method name="GetActive">
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</method>
|
||||||
|
<method name="Lock" />
|
||||||
|
<method name="SetActive">
|
||||||
|
<arg type="b" direction="in" />
|
||||||
|
</method>
|
||||||
|
<signal name="ActiveChanged">
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</signal>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ScreenSaverInfo = Gio.DBusInterfaceInfo.new_for_xml(ScreenSaverIface);
|
||||||
|
|
||||||
|
function ScreenSaverProxy() {
|
||||||
|
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
|
||||||
|
g_interface_name: ScreenSaverInfo.name,
|
||||||
|
g_interface_info: ScreenSaverInfo,
|
||||||
|
g_name: 'org.gnome.ScreenSaver',
|
||||||
|
g_object_path: '/org/gnome/ScreenSaver',
|
||||||
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
||||||
|
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||||
|
self.init(null);
|
||||||
|
self.screenSaverActive = false;
|
||||||
|
|
||||||
|
self.connectSignal('ActiveChanged', function(proxy, senderName, [isActive]) {
|
||||||
|
self.screenSaverActive = isActive;
|
||||||
|
});
|
||||||
|
self.connect('notify::g-name-owner', function() {
|
||||||
|
if (self.g_name_owner) {
|
||||||
|
self.GetActiveRemote(function(result, excp) {
|
||||||
|
if (result) {
|
||||||
|
let [isActive] = result;
|
||||||
|
self.screenSaverActive = isActive;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
self.screenSaverActive = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
@ -1,361 +0,0 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
const DBus = imports.dbus;
|
|
||||||
|
|
||||||
// D-Bus utils
|
|
||||||
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 = DBus.makeProxyClass(ChannelDispatchOperationIface);
|
|
||||||
|
|
||||||
const CONNECTION_NAME = TELEPATHY + '.Connection';
|
|
||||||
const ConnectionIface = {
|
|
||||||
name: CONNECTION_NAME,
|
|
||||||
signals: [
|
|
||||||
{ name: 'StatusChanged',
|
|
||||||
inSignature: 'uu' }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
let Connection = DBus.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 = DBus.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 = DBus.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 = DBus.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 = DBus.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 = DBus.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 = DBus.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' },
|
|
||||||
{ name: 'Sent',
|
|
||||||
inSignature: 'uus' }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
let ChannelText = DBus.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 = DBus.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 = DBus.makeProxyClass(AccountManagerIface);
|
|
||||||
|
|
||||||
const ACCOUNT_NAME = TELEPATHY + '.Account';
|
|
||||||
const AccountIface = {
|
|
||||||
name: ACCOUNT_NAME,
|
|
||||||
properties: [
|
|
||||||
{ name: 'Connection',
|
|
||||||
signature: 'o',
|
|
||||||
access: 'read' }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
let Account = DBus.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 = DBus.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 = DBus.makeProxyClass(ChannelRequestIface);
|
|
234
js/misc/util.js
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Gdk = imports.gi.Gdk;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
|
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||||
|
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
|
||||||
|
const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
|
||||||
|
const _notTrailingJunk = '[^\\s`!()\\[\\]{};:\'\\".,<>?\u00AB\u00BB\u201C\u201D\u2018\u2019]';
|
||||||
|
|
||||||
|
const _urlRegexp = new RegExp(
|
||||||
|
'(^|' + _leadingJunk + ')' +
|
||||||
|
'(' +
|
||||||
|
'(?:' +
|
||||||
|
'[a-z][\\w-]+://' + // scheme://
|
||||||
|
'|' +
|
||||||
|
'www\\d{0,3}[.]' + // www.
|
||||||
|
'|' +
|
||||||
|
'[a-z0-9.\\-]+[.][a-z]{2,4}/' + // foo.xx/
|
||||||
|
')' +
|
||||||
|
'(?:' + // one or more:
|
||||||
|
'[^\\s()<>]+' + // run of non-space non-()
|
||||||
|
'|' + // or
|
||||||
|
_balancedParens + // balanced parens
|
||||||
|
')+' +
|
||||||
|
'(?:' + // end with:
|
||||||
|
_balancedParens + // balanced parens
|
||||||
|
'|' + // or
|
||||||
|
_notTrailingJunk + // last non-junk char
|
||||||
|
')' +
|
||||||
|
')', 'gi');
|
||||||
|
|
||||||
|
// findUrls:
|
||||||
|
// @str: string to find URLs in
|
||||||
|
//
|
||||||
|
// Searches @str for URLs and returns an array of objects with %url
|
||||||
|
// properties showing the matched URL string, and %pos properties indicating
|
||||||
|
// the position within @str where the URL was found.
|
||||||
|
//
|
||||||
|
// Return value: the list of match objects, as described above
|
||||||
|
function findUrls(str) {
|
||||||
|
let res = [], match;
|
||||||
|
while ((match = _urlRegexp.exec(str)))
|
||||||
|
res.push({ url: match[2], pos: match.index + match[1].length });
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// spawn:
|
||||||
|
// @argv: an argv array
|
||||||
|
//
|
||||||
|
// Runs @argv in the background, handling any errors that occur
|
||||||
|
// when trying to start the program.
|
||||||
|
function spawn(argv) {
|
||||||
|
try {
|
||||||
|
trySpawn(argv);
|
||||||
|
} catch (err) {
|
||||||
|
_handleSpawnError(argv[0], err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// spawnCommandLine:
|
||||||
|
// @command_line: a command line
|
||||||
|
//
|
||||||
|
// Runs @command_line in the background, handling any errors that
|
||||||
|
// occur when trying to parse or start the program.
|
||||||
|
function spawnCommandLine(command_line) {
|
||||||
|
try {
|
||||||
|
let [success, argv] = GLib.shell_parse_argv(command_line);
|
||||||
|
trySpawn(argv);
|
||||||
|
} catch (err) {
|
||||||
|
_handleSpawnError(command_line, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trySpawn:
|
||||||
|
// @argv: an argv array
|
||||||
|
//
|
||||||
|
// Runs @argv in the background. If launching @argv fails,
|
||||||
|
// this will throw an error.
|
||||||
|
function trySpawn(argv)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
GLib.spawn_async(null, argv, null,
|
||||||
|
GLib.SpawnFlags.SEARCH_PATH,
|
||||||
|
null, null);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code == GLib.SpawnError.G_SPAWN_ERROR_NOENT) {
|
||||||
|
err.message = _("Command not found");
|
||||||
|
} else {
|
||||||
|
// The exception from gjs contains an error string like:
|
||||||
|
// Error invoking GLib.spawn_command_line_async: Failed to
|
||||||
|
// execute child process "foo" (No such file or directory)
|
||||||
|
// We are only interested in the part in the parentheses. (And
|
||||||
|
// we can't pattern match the text, since it gets localized.)
|
||||||
|
err.message = err.message.replace(/.*\((.+)\)/, '$1');
|
||||||
|
}
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trySpawnCommandLine:
|
||||||
|
// @command_line: a command line
|
||||||
|
//
|
||||||
|
// Runs @command_line in the background. If launching @command_line
|
||||||
|
// fails, this will throw an error.
|
||||||
|
function trySpawnCommandLine(command_line) {
|
||||||
|
let success, argv;
|
||||||
|
|
||||||
|
try {
|
||||||
|
[success, argv] = GLib.shell_parse_argv(command_line);
|
||||||
|
} catch (err) {
|
||||||
|
// Replace "Error invoking GLib.shell_parse_argv: " with
|
||||||
|
// something nicer
|
||||||
|
err.message = err.message.replace(/[^:]*: /, _("Could not parse command:") + "\n");
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
trySpawn(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _handleSpawnError(command, err) {
|
||||||
|
let title = _("Execution of '%s' failed:").format(command);
|
||||||
|
Main.notifyError(title, err.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// killall:
|
||||||
|
// @processName: a process name
|
||||||
|
//
|
||||||
|
// Kills @processName. If no process with the given name is found,
|
||||||
|
// this will fail silently.
|
||||||
|
function killall(processName) {
|
||||||
|
try {
|
||||||
|
// pkill is more portable than killall, but on Linux at least
|
||||||
|
// it won't match if you pass more than 15 characters of the
|
||||||
|
// process name... However, if you use the '-f' flag to match
|
||||||
|
// the entire command line, it will work, but we have to be
|
||||||
|
// careful in that case that we can match
|
||||||
|
// '/usr/bin/processName' but not 'gedit processName.c' or
|
||||||
|
// whatever...
|
||||||
|
|
||||||
|
let argv = ['pkill', '-f', '^([^ ]*/)?' + processName + '($| )'];
|
||||||
|
GLib.spawn_sync(null, argv, null, GLib.SpawnFlags.SEARCH_PATH, null, null);
|
||||||
|
// It might be useful to return success/failure, but we'd need
|
||||||
|
// a wrapper around WIFEXITED and WEXITSTATUS. Since none of
|
||||||
|
// the current callers care, we don't bother.
|
||||||
|
} catch (e) {
|
||||||
|
logError(e, 'Failed to kill ' + processName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This was ported from network-manager-applet
|
||||||
|
// Copyright 2007 - 2011 Red Hat, Inc.
|
||||||
|
// Author: Dan Williams <dcbw@redhat.com>
|
||||||
|
|
||||||
|
const _IGNORED_WORDS = [
|
||||||
|
'Semiconductor',
|
||||||
|
'Components',
|
||||||
|
'Corporation',
|
||||||
|
'Communications',
|
||||||
|
'Company',
|
||||||
|
'Corp.',
|
||||||
|
'Corp',
|
||||||
|
'Co.',
|
||||||
|
'Inc.',
|
||||||
|
'Inc',
|
||||||
|
'Incorporated',
|
||||||
|
'Ltd.',
|
||||||
|
'Limited.',
|
||||||
|
'Intel',
|
||||||
|
'chipset',
|
||||||
|
'adapter',
|
||||||
|
'[hex]',
|
||||||
|
'NDIS',
|
||||||
|
'Module'
|
||||||
|
];
|
||||||
|
|
||||||
|
const _IGNORED_PHRASES = [
|
||||||
|
'Multiprotocol MAC/baseband processor',
|
||||||
|
'Wireless LAN Controller',
|
||||||
|
'Wireless LAN Adapter',
|
||||||
|
'Wireless Adapter',
|
||||||
|
'Network Connection',
|
||||||
|
'Wireless Cardbus Adapter',
|
||||||
|
'Wireless CardBus Adapter',
|
||||||
|
'54 Mbps Wireless PC Card',
|
||||||
|
'Wireless PC Card',
|
||||||
|
'Wireless PC',
|
||||||
|
'PC Card with XJACK(r) Antenna',
|
||||||
|
'Wireless cardbus',
|
||||||
|
'Wireless LAN PC Card',
|
||||||
|
'Technology Group Ltd.',
|
||||||
|
'Communication S.p.A.',
|
||||||
|
'Business Mobile Networks BV',
|
||||||
|
'Mobile Broadband Minicard Composite Device',
|
||||||
|
'Mobile Communications AB',
|
||||||
|
'(PC-Suite Mode)'
|
||||||
|
];
|
||||||
|
|
||||||
|
function fixupPCIDescription(desc) {
|
||||||
|
desc = desc.replace(/[_,]/, ' ');
|
||||||
|
|
||||||
|
/* Attempt to shorten ID by ignoring certain phrases */
|
||||||
|
for (let i = 0; i < _IGNORED_PHRASES.length; i++) {
|
||||||
|
let item = _IGNORED_PHRASES[i];
|
||||||
|
let pos = desc.indexOf(item);
|
||||||
|
if (pos != -1) {
|
||||||
|
let before = desc.substring(0, pos);
|
||||||
|
let after = desc.substring(pos + item.length, desc.length);
|
||||||
|
desc = before + after;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attmept to shorten ID by ignoring certain individual words */
|
||||||
|
let words = desc.split(' ');
|
||||||
|
let out = [ ];
|
||||||
|
for (let i = 0; i < words.length; i++) {
|
||||||
|
let item = words[i];
|
||||||
|
|
||||||
|
// skip empty items (that come out from consecutive spaces)
|
||||||
|
if (item.length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_IGNORED_WORDS.indexOf(item) == -1) {
|
||||||
|
out.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.join(' ');
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
/* http://daringfireball.net/2010/07/improved_regex_for_matching_urls */
|
|
||||||
const _urlRegexp = /\b(([a-z][\w-]+:(\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)([^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/gi;
|
|
||||||
|
|
||||||
// findUrls:
|
|
||||||
// @str: string to find URLs in
|
|
||||||
//
|
|
||||||
// Searches @str for URLs and returns an array of objects with %url
|
|
||||||
// properties showing the matched URL string, and %pos properties indicating
|
|
||||||
// the position within @str where the URL was found.
|
|
||||||
//
|
|
||||||
// Return value: the list of match objects, as described above
|
|
||||||
function findUrls(str) {
|
|
||||||
let res = [], match;
|
|
||||||
while ((match = _urlRegexp.exec(str)))
|
|
||||||
res.push({ url: match[0], pos: match.index });
|
|
||||||
return res;
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Scripting = imports.ui.scripting;
|
const Scripting = imports.ui.scripting;
|
||||||
@ -21,26 +21,77 @@ let METRICS = {
|
|||||||
overviewFpsSubsequent:
|
overviewFpsSubsequent:
|
||||||
{ description: "Frames rate when going to the overview, second time",
|
{ description: "Frames rate when going to the overview, second time",
|
||||||
units: "frames / s" },
|
units: "frames / s" },
|
||||||
|
overviewFps5Windows:
|
||||||
|
{ description: "Frames rate when going to the overview, 5 windows open",
|
||||||
|
units: "frames / s" },
|
||||||
|
overviewFps10Windows:
|
||||||
|
{ description: "Frames rate when going to the overview, 10 windows open",
|
||||||
|
units: "frames / s" },
|
||||||
|
overviewFps5Maximized:
|
||||||
|
{ description: "Frames rate when going to the overview, 5 maximized windows open",
|
||||||
|
units: "frames / s" },
|
||||||
|
overviewFps10Maximized:
|
||||||
|
{ description: "Frames rate when going to the overview, 10 maximized windows open",
|
||||||
|
units: "frames / s" },
|
||||||
|
overviewFps5Alpha:
|
||||||
|
{ description: "Frames rate when going to the overview, 5 alpha-transparent windows open",
|
||||||
|
units: "frames / s" },
|
||||||
|
overviewFps10Alpha:
|
||||||
|
{ description: "Frames rate when going to the overview, 10 alpha-transparent windows open",
|
||||||
|
units: "frames / s" },
|
||||||
usedAfterOverview:
|
usedAfterOverview:
|
||||||
{ description: "Malloc'ed bytes after the overview is shown once",
|
{ description: "Malloc'ed bytes after the overview is shown once",
|
||||||
units: "B" },
|
units: "B" },
|
||||||
leakedAfterOverview:
|
leakedAfterOverview:
|
||||||
{ description: "Additional malloc'ed bytes the second time the overview is shown",
|
{ description: "Additional malloc'ed bytes the second time the overview is shown",
|
||||||
units: "B" }
|
units: "B" },
|
||||||
|
applicationsShowTimeFirst:
|
||||||
|
{ description: "Time to switch to applications view, first time",
|
||||||
|
units: "us" },
|
||||||
|
applicationsShowTimeSubsequent:
|
||||||
|
{ description: "Time to switch to applications view, second time",
|
||||||
|
units: "us"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let WINDOW_CONFIGS = [
|
||||||
|
{ width: 640, height: 480, alpha: false, maximized: false, count: 1, metric: 'overviewFpsSubsequent' },
|
||||||
|
{ width: 640, height: 480, alpha: false, maximized: false, count: 5, metric: 'overviewFps5Windows' },
|
||||||
|
{ width: 640, height: 480, alpha: false, maximized: false, count: 10, metric: 'overviewFps10Windows' },
|
||||||
|
{ width: 640, height: 480, alpha: false, maximized: true, count: 5, metric: 'overviewFps5Maximized' },
|
||||||
|
{ width: 640, height: 480, alpha: false, maximized: true, count: 10, metric: 'overviewFps10Maximized' },
|
||||||
|
{ width: 640, height: 480, alpha: true, maximized: false, count: 5, metric: 'overviewFps5Alpha' },
|
||||||
|
{ width: 640, height: 480, alpha: true, maximized: false, count: 10, metric: 'overviewFps10Alpha' }
|
||||||
|
];
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
|
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
|
||||||
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
|
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
|
||||||
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
|
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
|
||||||
|
Scripting.defineScriptEvent("applicationsShowStart", "Starting to switch to applications view");
|
||||||
|
Scripting.defineScriptEvent("applicationsShowDone", "Done switching to applications view");
|
||||||
|
|
||||||
Main.overview.connect('shown', function() {
|
Main.overview.connect('shown', function() {
|
||||||
Scripting.scriptEvent('overviewShowDone');
|
Scripting.scriptEvent('overviewShowDone');
|
||||||
});
|
});
|
||||||
|
|
||||||
yield Scripting.sleep(1000);
|
yield Scripting.sleep(1000);
|
||||||
yield Scripting.waitLeisure();
|
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2 * WINDOW_CONFIGS.length; i++) {
|
||||||
|
// We go to the overview twice for each configuration; the first time
|
||||||
|
// to calculate the mipmaps for the windows, the second time to get
|
||||||
|
// a clean set of numbers.
|
||||||
|
if ((i % 2) == 0) {
|
||||||
|
let config = WINDOW_CONFIGS[i / 2];
|
||||||
|
yield Scripting.destroyTestWindows();
|
||||||
|
|
||||||
|
for (let k = 0; k < config.count; k++)
|
||||||
|
yield Scripting.createTestWindow(config.width, config.height, config.alpha, config.maximized);
|
||||||
|
|
||||||
|
yield Scripting.waitTestWindows();
|
||||||
|
yield Scripting.sleep(1000);
|
||||||
|
yield Scripting.waitLeisure();
|
||||||
|
}
|
||||||
|
|
||||||
Scripting.scriptEvent('overviewShowStart');
|
Scripting.scriptEvent('overviewShowStart');
|
||||||
Main.overview.show();
|
Main.overview.show();
|
||||||
|
|
||||||
@ -53,6 +104,21 @@ function run() {
|
|||||||
Scripting.collectStatistics();
|
Scripting.collectStatistics();
|
||||||
Scripting.scriptEvent('afterShowHide');
|
Scripting.scriptEvent('afterShowHide');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
yield Scripting.destroyTestWindows();
|
||||||
|
yield Scripting.sleep(1000);
|
||||||
|
|
||||||
|
Main.overview.show();
|
||||||
|
yield Scripting.waitLeisure();
|
||||||
|
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
Scripting.scriptEvent('applicationsShowStart');
|
||||||
|
Main.overview._viewSelector.switchTab('applications');
|
||||||
|
yield Scripting.waitLeisure();
|
||||||
|
Scripting.scriptEvent('applicationsShowDone');
|
||||||
|
Main.overview._viewSelector.switchTab('windows');
|
||||||
|
yield Scripting.waitLeisure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let showingOverview = false;
|
let showingOverview = false;
|
||||||
@ -64,6 +130,8 @@ let mallocUsedSize = 0;
|
|||||||
let overviewShowCount = 0;
|
let overviewShowCount = 0;
|
||||||
let firstOverviewUsedSize;
|
let firstOverviewUsedSize;
|
||||||
let haveSwapComplete = false;
|
let haveSwapComplete = false;
|
||||||
|
let applicationsShowStart;
|
||||||
|
let applicationsShowCount = 0;
|
||||||
|
|
||||||
function script_overviewShowStart(time) {
|
function script_overviewShowStart(time) {
|
||||||
showingOverview = true;
|
showingOverview = true;
|
||||||
@ -79,6 +147,18 @@ function script_overviewShowDone(time) {
|
|||||||
finishedShowingOverview = true;
|
finishedShowingOverview = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function script_applicationsShowStart(time) {
|
||||||
|
applicationsShowStart = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
function script_applicationsShowDone(time) {
|
||||||
|
applicationsShowCount++;
|
||||||
|
if (applicationsShowCount == 1)
|
||||||
|
METRICS.applicationsShowTimeFirst.value = time - applicationsShowStart;
|
||||||
|
else
|
||||||
|
METRICS.applicationsShowTimeSubsequent.value = time - applicationsShowStart;
|
||||||
|
}
|
||||||
|
|
||||||
function script_afterShowHide(time) {
|
function script_afterShowHide(time) {
|
||||||
if (overviewShowCount == 1) {
|
if (overviewShowCount == 1) {
|
||||||
METRICS.usedAfterOverview.value = mallocUsedSize;
|
METRICS.usedAfterOverview.value = mallocUsedSize;
|
||||||
@ -113,9 +193,15 @@ function _frameDone(time) {
|
|||||||
if (overviewShowCount == 1) {
|
if (overviewShowCount == 1) {
|
||||||
METRICS.overviewLatencyFirst.value = overviewLatency;
|
METRICS.overviewLatencyFirst.value = overviewLatency;
|
||||||
METRICS.overviewFpsFirst.value = fps;
|
METRICS.overviewFpsFirst.value = fps;
|
||||||
} else {
|
} else if (overviewShowCount == 2) {
|
||||||
METRICS.overviewLatencySubsequent.value = overviewLatency;
|
METRICS.overviewLatencySubsequent.value = overviewLatency;
|
||||||
METRICS.overviewFpsSubsequent.value = fps;
|
}
|
||||||
|
|
||||||
|
// Other than overviewFpsFirst, we collect FPS metrics the second
|
||||||
|
// we show each window configuration. overviewShowCount is 1,2,3...
|
||||||
|
if (overviewShowCount % 2 == 0) {
|
||||||
|
let config = WINDOW_CONFIGS[(overviewShowCount / 2) - 1];
|
||||||
|
METRICS[config.metric].value = fps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
429
js/ui/altTab.js
@ -1,9 +1,10 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
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;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@ -13,7 +14,10 @@ const Tweener = imports.ui.tweener;
|
|||||||
|
|
||||||
const POPUP_APPICON_SIZE = 96;
|
const POPUP_APPICON_SIZE = 96;
|
||||||
const POPUP_SCROLL_TIME = 0.10; // seconds
|
const POPUP_SCROLL_TIME = 0.10; // seconds
|
||||||
const POPUP_FADE_TIME = 0.1; // seconds
|
const POPUP_DELAY_TIMEOUT = 150; // milliseconds
|
||||||
|
const POPUP_FADE_OUT_TIME = 0.1; // seconds
|
||||||
|
|
||||||
|
const APP_ICON_HOVER_TIMEOUT = 200; // milliseconds
|
||||||
|
|
||||||
const DISABLE_HOVER_TIMEOUT = 500; // milliseconds
|
const DISABLE_HOVER_TIMEOUT = 500; // milliseconds
|
||||||
|
|
||||||
@ -27,11 +31,21 @@ function mod(a, b) {
|
|||||||
return (a + b) % b;
|
return (a + b) % b;
|
||||||
}
|
}
|
||||||
|
|
||||||
function AltTabPopup() {
|
function primaryModifier(mask) {
|
||||||
this._init();
|
if (mask == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
let primary = 1;
|
||||||
|
while (mask > 1) {
|
||||||
|
mask >>= 1;
|
||||||
|
primary <<= 1;
|
||||||
|
}
|
||||||
|
return primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
AltTabPopup.prototype = {
|
const AltTabPopup = new Lang.Class({
|
||||||
|
Name: 'AltTabPopup',
|
||||||
|
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this.actor = new Shell.GenericContainer({ name: 'altTabPopup',
|
this.actor = new Shell.GenericContainer({ name: 'altTabPopup',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
@ -44,11 +58,15 @@ AltTabPopup.prototype = {
|
|||||||
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._modifierMask = 0;
|
||||||
|
|
||||||
this._currentApp = 0;
|
this._currentApp = 0;
|
||||||
this._currentWindow = -1;
|
this._currentWindow = -1;
|
||||||
this._thumbnailTimeoutId = 0;
|
this._thumbnailTimeoutId = 0;
|
||||||
this._motionTimeoutId = 0;
|
this._motionTimeoutId = 0;
|
||||||
|
this._initialDelayTimeoutId = 0;
|
||||||
|
|
||||||
|
this.thumbnailsVisible = false;
|
||||||
|
|
||||||
// Initially disable hover so we ignore the enter-event if
|
// Initially disable hover so we ignore the enter-event if
|
||||||
// the switcher appears underneath the current pointer location
|
// the switcher appears underneath the current pointer location
|
||||||
@ -69,7 +87,7 @@ AltTabPopup.prototype = {
|
|||||||
|
|
||||||
_allocate: function (actor, box, flags) {
|
_allocate: function (actor, box, flags) {
|
||||||
let childBox = new Clutter.ActorBox();
|
let childBox = new Clutter.ActorBox();
|
||||||
let primary = global.get_primary_monitor();
|
let primary = Main.layoutManager.primaryMonitor;
|
||||||
|
|
||||||
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
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 rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||||
@ -82,7 +100,7 @@ AltTabPopup.prototype = {
|
|||||||
let [childMinHeight, childNaturalHeight] = this._appSwitcher.actor.get_preferred_height(primary.width - hPadding);
|
let [childMinHeight, childNaturalHeight] = this._appSwitcher.actor.get_preferred_height(primary.width - hPadding);
|
||||||
let [childMinWidth, childNaturalWidth] = this._appSwitcher.actor.get_preferred_width(childNaturalHeight);
|
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.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.x2 = Math.min(primary.x + primary.width - rightPadding, childBox.x1 + childNaturalWidth);
|
||||||
childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
|
childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
|
||||||
childBox.y2 = childBox.y1 + childNaturalHeight;
|
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||||
this._appSwitcher.actor.allocate(childBox, flags);
|
this._appSwitcher.actor.allocate(childBox, flags);
|
||||||
@ -92,8 +110,6 @@ AltTabPopup.prototype = {
|
|||||||
// those calculations
|
// those calculations
|
||||||
if (this._thumbnails) {
|
if (this._thumbnails) {
|
||||||
let icon = this._appIcons[this._currentApp].actor;
|
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 [posX, posY] = icon.get_transformed_position();
|
||||||
let thumbnailCenter = posX + icon.width / 2;
|
let thumbnailCenter = posX + icon.width / 2;
|
||||||
let [childMinWidth, childNaturalWidth] = this._thumbnails.actor.get_preferred_width(-1);
|
let [childMinWidth, childNaturalWidth] = this._thumbnails.actor.get_preferred_width(-1);
|
||||||
@ -116,16 +132,50 @@ AltTabPopup.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
show : function(backward) {
|
_getAppLists: function() {
|
||||||
let tracker = Shell.WindowTracker.get_default();
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
let apps = tracker.get_running_apps ('');
|
let appSys = Shell.AppSystem.get_default();
|
||||||
|
let allApps = appSys.get_running ();
|
||||||
|
|
||||||
if (!apps.length)
|
let screen = global.screen;
|
||||||
|
let display = screen.get_display();
|
||||||
|
let windows = display.get_tab_list(Meta.TabList.NORMAL, screen,
|
||||||
|
screen.get_active_workspace());
|
||||||
|
|
||||||
|
// windows is only the windows on the current workspace. For
|
||||||
|
// each one, if it corresponds to an app we know, move that
|
||||||
|
// app from allApps to apps.
|
||||||
|
let apps = [];
|
||||||
|
for (let i = 0; i < windows.length && allApps.length != 0; i++) {
|
||||||
|
let app = tracker.get_window_app(windows[i]);
|
||||||
|
let index = allApps.indexOf(app);
|
||||||
|
if (index != -1) {
|
||||||
|
apps.push(app);
|
||||||
|
allApps.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now @apps is a list of apps on the current workspace, in
|
||||||
|
// standard Alt+Tab order (MRU except for minimized windows),
|
||||||
|
// and allApps is a list of apps that only appear on other
|
||||||
|
// workspaces, sorted by user_time, which is good enough.
|
||||||
|
return [apps, allApps];
|
||||||
|
},
|
||||||
|
|
||||||
|
show : function(backward, binding, mask) {
|
||||||
|
let [localApps, otherApps] = this._getAppLists();
|
||||||
|
|
||||||
|
if (localApps.length == 0 && otherApps.length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!Main.pushModal(this.actor))
|
if (!Main.pushModal(this.actor)) {
|
||||||
return false;
|
// Probably someone else has a pointer grab, try again with keyboard only
|
||||||
|
if (!Main.pushModal(this.actor, global.get_current_time(), Meta.ModalOptions.POINTER_ALREADY_GRABBED)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
this._haveModal = true;
|
this._haveModal = true;
|
||||||
|
this._modifierMask = primaryModifier(mask);
|
||||||
|
|
||||||
this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
|
this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
|
||||||
this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
|
this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
|
||||||
@ -133,38 +183,39 @@ AltTabPopup.prototype = {
|
|||||||
this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
|
this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
|
||||||
this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
|
this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
|
||||||
|
|
||||||
this._appSwitcher = new AppSwitcher(apps);
|
this._appSwitcher = new AppSwitcher(localApps, otherApps, this);
|
||||||
this.actor.add_actor(this._appSwitcher.actor);
|
this.actor.add_actor(this._appSwitcher.actor);
|
||||||
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));
|
||||||
|
|
||||||
this._appIcons = this._appSwitcher.icons;
|
this._appIcons = this._appSwitcher.icons;
|
||||||
|
|
||||||
|
// Need to force an allocation so we can figure out whether we
|
||||||
|
// need to scroll when selecting
|
||||||
|
this.actor.opacity = 0;
|
||||||
|
this.actor.show();
|
||||||
|
this.actor.get_allocation_box();
|
||||||
|
|
||||||
// Make the initial selection
|
// Make the initial selection
|
||||||
if (this._appIcons.length == 1) {
|
if (binding == 'switch-group') {
|
||||||
if (!backward && this._appIcons[0].cachedWindows.length > 1) {
|
if (backward) {
|
||||||
// For compatibility with the multi-app case below
|
this._select(0, this._appIcons[0].cachedWindows.length - 1);
|
||||||
this._select(0, 1, true);
|
} else {
|
||||||
} else
|
if (this._appIcons[0].cachedWindows.length > 1)
|
||||||
this._select(0);
|
this._select(0, 1);
|
||||||
|
else
|
||||||
|
this._select(0, 0);
|
||||||
|
}
|
||||||
|
} else if (binding == 'switch-group-backward') {
|
||||||
|
this._select(0, this._appIcons[0].cachedWindows.length - 1);
|
||||||
|
} else if (binding == 'switch-windows-backward') {
|
||||||
|
this._select(this._appIcons.length - 1);
|
||||||
|
} else if (this._appIcons.length == 1) {
|
||||||
|
this._select(0);
|
||||||
} else if (backward) {
|
} else if (backward) {
|
||||||
this._select(this._appIcons.length - 1);
|
this._select(this._appIcons.length - 1);
|
||||||
} else {
|
} else {
|
||||||
let firstWindows = this._appIcons[0].cachedWindows;
|
this._select(1);
|
||||||
if (firstWindows.length > 1) {
|
|
||||||
let curAppNextWindow = firstWindows[1];
|
|
||||||
let nextAppWindow = this._appIcons[1].cachedWindows[0];
|
|
||||||
|
|
||||||
// If the next window of the current app is more-recently-used
|
|
||||||
// than the first window of the next app, then select it.
|
|
||||||
if (curAppNextWindow.get_workspace() == global.screen.get_active_workspace() &&
|
|
||||||
curAppNextWindow.get_user_time() > nextAppWindow.get_user_time())
|
|
||||||
this._select(0, 1, true);
|
|
||||||
else
|
|
||||||
this._select(1);
|
|
||||||
} else {
|
|
||||||
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
|
||||||
@ -173,18 +224,18 @@ AltTabPopup.prototype = {
|
|||||||
// 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 [x, y, mods] = global.get_pointer();
|
let [x, y, mods] = global.get_pointer();
|
||||||
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
|
if (!(mods & this._modifierMask)) {
|
||||||
this._finish();
|
this._finish();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.actor.opacity = 0;
|
// We delay showing the popup so that fast Alt+Tab users aren't
|
||||||
this.actor.show();
|
// disturbed by the popup briefly flashing.
|
||||||
Tweener.addTween(this.actor,
|
this._initialDelayTimeoutId = Mainloop.timeout_add(POPUP_DELAY_TIMEOUT,
|
||||||
{ opacity: 255,
|
Lang.bind(this, function () {
|
||||||
time: POPUP_FADE_TIME,
|
this.actor.opacity = 255;
|
||||||
transition: 'easeOutQuad'
|
this._initialDelayTimeoutId = 0;
|
||||||
});
|
}));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@ -213,42 +264,31 @@ AltTabPopup.prototype = {
|
|||||||
|
|
||||||
_keyPressEvent : function(actor, event) {
|
_keyPressEvent : function(actor, event) {
|
||||||
let keysym = event.get_key_symbol();
|
let keysym = event.get_key_symbol();
|
||||||
let shift = (Shell.get_event_state(event) & Clutter.ModifierType.SHIFT_MASK);
|
let event_state = Shell.get_event_state(event);
|
||||||
// X allows servers to represent Shift+Tab in two different ways
|
let backwards = event_state & Clutter.ModifierType.SHIFT_MASK;
|
||||||
if (shift && keysym == Clutter.Tab)
|
let action = global.display.get_keybinding_action(event.get_key_code(), event_state);
|
||||||
keysym = Clutter.ISO_Left_Tab;
|
|
||||||
|
|
||||||
this._disableHover();
|
this._disableHover();
|
||||||
|
|
||||||
if (keysym == Clutter.grave)
|
if (keysym == Clutter.Escape) {
|
||||||
this._select(this._currentApp, this._nextWindow());
|
|
||||||
else if (keysym == Clutter.asciitilde)
|
|
||||||
this._select(this._currentApp, this._previousWindow());
|
|
||||||
else if (keysym == Clutter.Escape)
|
|
||||||
this.destroy();
|
this.destroy();
|
||||||
else if (this._thumbnailsFocused) {
|
} else if (action == Meta.KeyBindingAction.SWITCH_GROUP) {
|
||||||
if (keysym == Clutter.Tab) {
|
this._select(this._currentApp, backwards ? this._previousWindow() : this._nextWindow());
|
||||||
if (this._currentWindow == this._appIcons[this._currentApp].cachedWindows.length - 1)
|
} else if (action == Meta.KeyBindingAction.SWITCH_GROUP_BACKWARD) {
|
||||||
this._select(this._nextApp());
|
this._select(this._currentApp, this._previousWindow());
|
||||||
else
|
} else if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) {
|
||||||
this._select(this._currentApp, this._nextWindow());
|
this._select(backwards ? this._previousApp() : this._nextApp());
|
||||||
} else if (keysym == Clutter.ISO_Left_Tab) {
|
} else if (action == Meta.KeyBindingAction.SWITCH_WINDOWS_BACKWARD) {
|
||||||
if (this._currentWindow == 0 || this._currentWindow == -1)
|
this._select(this._previousApp());
|
||||||
this._select(this._previousApp());
|
} else if (this._thumbnailsFocused) {
|
||||||
else
|
if (keysym == Clutter.Left)
|
||||||
this._select(this._currentApp, this._previousWindow());
|
|
||||||
} else if (keysym == Clutter.Left)
|
|
||||||
this._select(this._currentApp, this._previousWindow());
|
this._select(this._currentApp, this._previousWindow());
|
||||||
else if (keysym == Clutter.Right)
|
else if (keysym == Clutter.Right)
|
||||||
this._select(this._currentApp, this._nextWindow());
|
this._select(this._currentApp, this._nextWindow());
|
||||||
else if (keysym == Clutter.Up)
|
else if (keysym == Clutter.Up)
|
||||||
this._select(this._currentApp, null, true);
|
this._select(this._currentApp, null, true);
|
||||||
} else {
|
} else {
|
||||||
if (keysym == Clutter.Tab)
|
if (keysym == Clutter.Left)
|
||||||
this._select(this._nextApp());
|
|
||||||
else if (keysym == Clutter.ISO_Left_Tab)
|
|
||||||
this._select(this._previousApp());
|
|
||||||
else if (keysym == Clutter.Left)
|
|
||||||
this._select(this._previousApp());
|
this._select(this._previousApp());
|
||||||
else if (keysym == Clutter.Right)
|
else if (keysym == Clutter.Right)
|
||||||
this._select(this._nextApp());
|
this._select(this._nextApp());
|
||||||
@ -261,7 +301,7 @@ AltTabPopup.prototype = {
|
|||||||
|
|
||||||
_keyReleaseEvent : function(actor, event) {
|
_keyReleaseEvent : function(actor, event) {
|
||||||
let [x, y, mods] = global.get_pointer();
|
let [x, y, mods] = global.get_pointer();
|
||||||
let state = mods & Clutter.ModifierType.MOD1_MASK;
|
let state = mods & this._modifierMask;
|
||||||
|
|
||||||
if (state == 0)
|
if (state == 0)
|
||||||
this._finish();
|
this._finish();
|
||||||
@ -365,11 +405,19 @@ AltTabPopup.prototype = {
|
|||||||
this.destroy();
|
this.destroy();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_popModal: function() {
|
||||||
|
if (this._haveModal) {
|
||||||
|
Main.popModal(this.actor);
|
||||||
|
this._haveModal = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
destroy : function() {
|
destroy : function() {
|
||||||
|
this._popModal();
|
||||||
if (this.actor.visible) {
|
if (this.actor.visible) {
|
||||||
Tweener.addTween(this.actor,
|
Tweener.addTween(this.actor,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
time: POPUP_FADE_TIME,
|
time: POPUP_FADE_OUT_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: Lang.bind(this,
|
onComplete: Lang.bind(this,
|
||||||
function() {
|
function() {
|
||||||
@ -381,8 +429,7 @@ AltTabPopup.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy : function() {
|
_onDestroy : function() {
|
||||||
if (this._haveModal)
|
this._popModal();
|
||||||
Main.popModal(this.actor);
|
|
||||||
|
|
||||||
if (this._thumbnails)
|
if (this._thumbnails)
|
||||||
this._destroyThumbnails();
|
this._destroyThumbnails();
|
||||||
@ -391,6 +438,8 @@ AltTabPopup.prototype = {
|
|||||||
Mainloop.source_remove(this._motionTimeoutId);
|
Mainloop.source_remove(this._motionTimeoutId);
|
||||||
if (this._thumbnailTimeoutId != 0)
|
if (this._thumbnailTimeoutId != 0)
|
||||||
Mainloop.source_remove(this._thumbnailTimeoutId);
|
Mainloop.source_remove(this._thumbnailTimeoutId);
|
||||||
|
if (this._initialDelayTimeoutId != 0)
|
||||||
|
Mainloop.source_remove(this._initialDelayTimeoutId);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -457,11 +506,15 @@ AltTabPopup.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_destroyThumbnails : function() {
|
_destroyThumbnails : function() {
|
||||||
Tweener.addTween(this._thumbnails.actor,
|
let thumbnailsActor = this._thumbnails.actor;
|
||||||
|
Tweener.addTween(thumbnailsActor,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
time: THUMBNAIL_FADE_TIME,
|
time: THUMBNAIL_FADE_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: function() { this.destroy(); }
|
onComplete: Lang.bind(this, function() {
|
||||||
|
thumbnailsActor.destroy();
|
||||||
|
this.thumbnailsVisible = false;
|
||||||
|
})
|
||||||
});
|
});
|
||||||
this._thumbnails = null;
|
this._thumbnails = null;
|
||||||
},
|
},
|
||||||
@ -473,20 +526,23 @@ AltTabPopup.prototype = {
|
|||||||
|
|
||||||
this.actor.add_actor(this._thumbnails.actor);
|
this.actor.add_actor(this._thumbnails.actor);
|
||||||
|
|
||||||
|
// Need to force an allocation so we can figure out whether we
|
||||||
|
// need to scroll when selecting
|
||||||
|
this._thumbnails.actor.get_allocation_box();
|
||||||
|
|
||||||
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',
|
||||||
|
onComplete: Lang.bind(this, function () { this.thumbnailsVisible = true; })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function SwitcherList(squareItems) {
|
const SwitcherList = new Lang.Class({
|
||||||
this._init(squareItems);
|
Name: 'SwitcherList',
|
||||||
}
|
|
||||||
|
|
||||||
SwitcherList.prototype = {
|
|
||||||
_init : function(squareItems) {
|
_init : function(squareItems) {
|
||||||
this.actor = new Shell.GenericContainer({ 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-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
@ -518,16 +574,11 @@ SwitcherList.prototype = {
|
|||||||
this._leftArrow = new St.DrawingArea({ style_class: 'switcher-arrow',
|
this._leftArrow = new St.DrawingArea({ style_class: 'switcher-arrow',
|
||||||
pseudo_class: 'highlighted' });
|
pseudo_class: 'highlighted' });
|
||||||
this._leftArrow.connect('repaint', Lang.bind(this,
|
this._leftArrow.connect('repaint', Lang.bind(this,
|
||||||
function (area) {
|
function() { _drawArrow(this._leftArrow, St.Side.LEFT); }));
|
||||||
Shell.draw_box_pointer(area, Shell.PointerDirection.LEFT);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._rightArrow = new St.DrawingArea({ style_class: 'switcher-arrow',
|
this._rightArrow = new St.DrawingArea({ style_class: 'switcher-arrow',
|
||||||
pseudo_class: 'highlighted' });
|
pseudo_class: 'highlighted' });
|
||||||
this._rightArrow.connect('repaint', Lang.bind(this,
|
this._rightArrow.connect('repaint', Lang.bind(this,
|
||||||
function (area) {
|
function() { _drawArrow(this._rightArrow, St.Side.RIGHT); }));
|
||||||
Shell.draw_box_pointer(area, Shell.PointerDirection.RIGHT);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.actor.add_actor(this._leftArrow);
|
this.actor.add_actor(this._leftArrow);
|
||||||
this.actor.add_actor(this._rightArrow);
|
this.actor.add_actor(this._rightArrow);
|
||||||
@ -583,24 +634,30 @@ SwitcherList.prototype = {
|
|||||||
this._rightArrow.opacity = this._rightGradient.opacity;
|
this._rightArrow.opacity = this._rightGradient.opacity;
|
||||||
},
|
},
|
||||||
|
|
||||||
addItem : function(item) {
|
addItem : function(item, label) {
|
||||||
let bbox = new St.Clickable({ style_class: 'item-box',
|
let bbox = new St.Button({ style_class: 'item-box',
|
||||||
reactive: true });
|
reactive: true });
|
||||||
|
|
||||||
bbox.set_child(item);
|
bbox.set_child(item);
|
||||||
this._list.add_actor(bbox);
|
this._list.add_actor(bbox);
|
||||||
|
|
||||||
let n = this._items.length;
|
let n = this._items.length;
|
||||||
bbox.connect('clicked', Lang.bind(this, function () {
|
bbox.connect('clicked', Lang.bind(this, function() { this._onItemClicked(n); }));
|
||||||
this._itemActivated(n);
|
bbox.connect('enter-event', Lang.bind(this, function() { this._onItemEnter(n); }));
|
||||||
}));
|
|
||||||
bbox.connect('enter-event', Lang.bind(this, function () {
|
bbox.label_actor = label;
|
||||||
this._itemEntered(n);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._items.push(bbox);
|
this._items.push(bbox);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onItemClicked: function (index) {
|
||||||
|
this._itemActivated(index);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onItemEnter: function (index) {
|
||||||
|
this._itemEntered(index);
|
||||||
|
},
|
||||||
|
|
||||||
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;
|
||||||
@ -622,11 +679,10 @@ SwitcherList.prototype = {
|
|||||||
this._items[this._highlighted].add_style_pseudo_class('selected');
|
this._items[this._highlighted].add_style_pseudo_class('selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
let monitor = global.get_primary_monitor();
|
let [absItemX, absItemY] = this._items[index].get_transformed_position();
|
||||||
let itemSize = this._items[index].allocation.x2 - this._items[index].allocation.x1;
|
let [result, posX, posY] = this.actor.transform_stage_point(absItemX, 0);
|
||||||
let [posX, posY] = this._items[index].get_transformed_position();
|
let [containerWidth, containerHeight] = this.actor.get_transformed_size();
|
||||||
posX += this.actor.x;
|
if (posX + this._items[index].get_width() > containerWidth)
|
||||||
if (posX + itemSize > monitor.width + monitor.x)
|
|
||||||
this._scrollToRight();
|
this._scrollToRight();
|
||||||
else if (posX < 0)
|
else if (posX < 0)
|
||||||
this._scrollToLeft();
|
this._scrollToLeft();
|
||||||
@ -650,7 +706,7 @@ SwitcherList.prototype = {
|
|||||||
|
|
||||||
_scrollToRight : function() {
|
_scrollToRight : function() {
|
||||||
this._scrollableLeft = true;
|
this._scrollableLeft = true;
|
||||||
let monitor = global.get_primary_monitor();
|
let monitor = Main.layoutManager.primaryMonitor;
|
||||||
let padding = this.actor.get_theme_node().get_horizontal_padding();
|
let padding = this.actor.get_theme_node().get_horizontal_padding();
|
||||||
let parentPadding = this.actor.get_parent().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;
|
let x = this._items[this._highlighted].allocation.x2 - monitor.width + padding + parentPadding;
|
||||||
@ -747,7 +803,7 @@ SwitcherList.prototype = {
|
|||||||
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 primary = Main.layoutManager.primaryMonitor;
|
||||||
let parentRightPadding = this.actor.get_parent().get_theme_node().get_padding(St.Side.RIGHT);
|
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.actor.allocation.x2 == primary.x + primary.width - parentRightPadding) {
|
||||||
if (this._squareItems)
|
if (this._squareItems)
|
||||||
@ -791,21 +847,19 @@ SwitcherList.prototype = {
|
|||||||
// Clip the area for scrolling
|
// 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);
|
this._clipBin.set_clip(0, -topPadding, (this.actor.allocation.x2 - this.actor.allocation.x1) - leftPadding - rightPadding, this.actor.height + bottomPadding);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
Signals.addSignalMethods(SwitcherList.prototype);
|
Signals.addSignalMethods(SwitcherList.prototype);
|
||||||
|
|
||||||
function AppIcon(app) {
|
const AppIcon = new Lang.Class({
|
||||||
this._init(app);
|
Name: 'AppIcon',
|
||||||
}
|
|
||||||
|
|
||||||
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 = null;
|
this.icon = null;
|
||||||
this._iconBin = new St.Bin();
|
this._iconBin = new St.Bin({ x_fill: true, y_fill: true });
|
||||||
|
|
||||||
this.actor.add(this._iconBin, { x_fill: false, y_fill: false } );
|
this.actor.add(this._iconBin, { x_fill: false, y_fill: false } );
|
||||||
this.label = new St.Label({ text: this.app.get_name() });
|
this.label = new St.Label({ text: this.app.get_name() });
|
||||||
@ -817,35 +871,31 @@ AppIcon.prototype = {
|
|||||||
this._iconBin.set_size(size, size);
|
this._iconBin.set_size(size, size);
|
||||||
this._iconBin.child = this.icon;
|
this._iconBin.child = this.icon;
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function AppSwitcher(apps) {
|
const AppSwitcher = new Lang.Class({
|
||||||
this._init(apps);
|
Name: 'AppSwitcher',
|
||||||
}
|
Extends: SwitcherList,
|
||||||
|
|
||||||
AppSwitcher.prototype = {
|
_init : function(localApps, otherApps, altTabPopup) {
|
||||||
__proto__ : SwitcherList.prototype,
|
this.parent(true);
|
||||||
|
|
||||||
_init : function(apps) {
|
// Construct the AppIcons, add to the popup
|
||||||
SwitcherList.prototype._init.call(this, true);
|
|
||||||
|
|
||||||
// Construct the AppIcons, sort by time, add to the popup
|
|
||||||
let activeWorkspace = global.screen.get_active_workspace();
|
let activeWorkspace = global.screen.get_active_workspace();
|
||||||
let workspaceIcons = [];
|
let workspaceIcons = [];
|
||||||
let otherIcons = [];
|
let otherIcons = [];
|
||||||
for (let i = 0; i < apps.length; i++) {
|
for (let i = 0; i < localApps.length; i++) {
|
||||||
let appIcon = new AppIcon(apps[i]);
|
let appIcon = new AppIcon(localApps[i]);
|
||||||
// Cache the window list now; we don't handle dynamic changes here,
|
// Cache the window list now; we don't handle dynamic changes here,
|
||||||
// and we don't want to be continually retrieving it
|
// and we don't want to be continually retrieving it
|
||||||
appIcon.cachedWindows = appIcon.app.get_windows();
|
appIcon.cachedWindows = appIcon.app.get_windows();
|
||||||
if (this._hasWindowsOnWorkspace(appIcon, activeWorkspace))
|
workspaceIcons.push(appIcon);
|
||||||
workspaceIcons.push(appIcon);
|
}
|
||||||
else
|
for (let i = 0; i < otherApps.length; i++) {
|
||||||
otherIcons.push(appIcon);
|
let appIcon = new AppIcon(otherApps[i]);
|
||||||
|
appIcon.cachedWindows = appIcon.app.get_windows();
|
||||||
|
otherIcons.push(appIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceIcons.sort(Lang.bind(this, this._sortAppIcon));
|
|
||||||
otherIcons.sort(Lang.bind(this, this._sortAppIcon));
|
|
||||||
|
|
||||||
this.icons = [];
|
this.icons = [];
|
||||||
this._arrows = [];
|
this._arrows = [];
|
||||||
@ -858,6 +908,8 @@ AppSwitcher.prototype = {
|
|||||||
|
|
||||||
this._curApp = -1;
|
this._curApp = -1;
|
||||||
this._iconSize = 0;
|
this._iconSize = 0;
|
||||||
|
this._altTabPopup = altTabPopup;
|
||||||
|
this._mouseTimeOutId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredHeight: function (actor, forWidth, alloc) {
|
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||||
@ -875,9 +927,9 @@ AppSwitcher.prototype = {
|
|||||||
totalSpacing += this._separator.width + this._list.spacing;
|
totalSpacing += this._separator.width + this._list.spacing;
|
||||||
|
|
||||||
// We just assume the whole screen here due to weirdness happing with the passed width
|
// We just assume the whole screen here due to weirdness happing with the passed width
|
||||||
let focus = global.get_focus_monitor();
|
let primary = Main.layoutManager.primaryMonitor;
|
||||||
let parentPadding = this.actor.get_parent().get_theme_node().get_horizontal_padding();
|
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 availWidth = primary.width - parentPadding - this.actor.get_theme_node().get_horizontal_padding();
|
||||||
let height = 0;
|
let height = 0;
|
||||||
|
|
||||||
for(let i = 0; i < iconSizes.length; i++) {
|
for(let i = 0; i < iconSizes.length; i++) {
|
||||||
@ -905,7 +957,7 @@ AppSwitcher.prototype = {
|
|||||||
|
|
||||||
_allocate: function (actor, box, flags) {
|
_allocate: function (actor, box, flags) {
|
||||||
// Allocate the main list items
|
// Allocate the main list items
|
||||||
SwitcherList.prototype._allocate.call(this, actor, box, flags);
|
this.parent(actor, box, flags);
|
||||||
|
|
||||||
let arrowHeight = Math.floor(this.actor.get_theme_node().get_padding(St.Side.BOTTOM) / 3);
|
let arrowHeight = Math.floor(this.actor.get_theme_node().get_padding(St.Side.BOTTOM) / 3);
|
||||||
let arrowWidth = arrowHeight * 2;
|
let arrowWidth = arrowHeight * 2;
|
||||||
@ -922,6 +974,29 @@ AppSwitcher.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// We override SwitcherList's _onItemEnter method to delay
|
||||||
|
// activation when the thumbnail list is open
|
||||||
|
_onItemEnter: function (index) {
|
||||||
|
if (this._mouseTimeOutId != 0)
|
||||||
|
Mainloop.source_remove(this._mouseTimeOutId);
|
||||||
|
if (this._altTabPopup.thumbnailsVisible) {
|
||||||
|
this._mouseTimeOutId = Mainloop.timeout_add(APP_ICON_HOVER_TIMEOUT,
|
||||||
|
Lang.bind(this, function () {
|
||||||
|
this._enterItem(index);
|
||||||
|
this._mouseTimeOutId = 0;
|
||||||
|
return false;
|
||||||
|
}));
|
||||||
|
} else
|
||||||
|
this._itemEntered(index);
|
||||||
|
},
|
||||||
|
|
||||||
|
_enterItem: function(index) {
|
||||||
|
let [x, y, mask] = global.get_pointer();
|
||||||
|
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
|
||||||
|
if (this._items[index].contains(pickedActor))
|
||||||
|
this._itemEntered(index);
|
||||||
|
},
|
||||||
|
|
||||||
// We override SwitcherList's highlight() method to also deal with
|
// We override SwitcherList's highlight() method to also deal with
|
||||||
// the AppSwitcher->ThumbnailList arrows. Apps with only 1 window
|
// the AppSwitcher->ThumbnailList arrows. Apps with only 1 window
|
||||||
// will hide their arrows by default, but show them when their
|
// will hide their arrows by default, but show them when their
|
||||||
@ -937,7 +1012,7 @@ AppSwitcher.prototype = {
|
|||||||
this._arrows[this._curApp].remove_style_pseudo_class('highlighted');
|
this._arrows[this._curApp].remove_style_pseudo_class('highlighted');
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherList.prototype.highlight.call(this, n, justOutline);
|
this.parent(n, justOutline);
|
||||||
this._curApp = n;
|
this._curApp = n;
|
||||||
|
|
||||||
if (this._curApp != -1) {
|
if (this._curApp != -1) {
|
||||||
@ -950,44 +1025,25 @@ AppSwitcher.prototype = {
|
|||||||
|
|
||||||
_addIcon : function(appIcon) {
|
_addIcon : function(appIcon) {
|
||||||
this.icons.push(appIcon);
|
this.icons.push(appIcon);
|
||||||
this.addItem(appIcon.actor);
|
this.addItem(appIcon.actor, appIcon.label);
|
||||||
|
|
||||||
let n = this._arrows.length;
|
let n = this._arrows.length;
|
||||||
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
|
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
|
||||||
arrow.connect('repaint', Lang.bind(this,
|
arrow.connect('repaint', function() { _drawArrow(arrow, St.Side.BOTTOM); });
|
||||||
function (area) {
|
|
||||||
Shell.draw_box_pointer(area, Shell.PointerDirection.DOWN);
|
|
||||||
}));
|
|
||||||
this._list.add_actor(arrow);
|
this._list.add_actor(arrow);
|
||||||
this._arrows.push(arrow);
|
this._arrows.push(arrow);
|
||||||
|
|
||||||
if (appIcon.cachedWindows.length == 1)
|
if (appIcon.cachedWindows.length == 1)
|
||||||
arrow.hide();
|
arrow.hide();
|
||||||
},
|
|
||||||
|
|
||||||
_hasWindowsOnWorkspace: function(appIcon, workspace) {
|
|
||||||
let windows = appIcon.cachedWindows;
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
|
||||||
if (windows[i].get_workspace() == workspace)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_sortAppIcon : function(appIcon1, appIcon2) {
|
|
||||||
return appIcon1.app.compare(appIcon2.app);
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function ThumbnailList(windows) {
|
const ThumbnailList = new Lang.Class({
|
||||||
this._init(windows);
|
Name: 'ThumbnailList',
|
||||||
}
|
Extends: SwitcherList,
|
||||||
|
|
||||||
ThumbnailList.prototype = {
|
|
||||||
__proto__ : SwitcherList.prototype,
|
|
||||||
|
|
||||||
_init : function(windows) {
|
_init : function(windows) {
|
||||||
SwitcherList.prototype._init.call(this);
|
this.parent(false);
|
||||||
|
|
||||||
let activeWorkspace = global.screen.get_active_workspace();
|
let activeWorkspace = global.screen.get_active_workspace();
|
||||||
|
|
||||||
@ -1023,9 +1079,12 @@ ThumbnailList.prototype = {
|
|||||||
this._labels.push(bin);
|
this._labels.push(bin);
|
||||||
bin.add_actor(name);
|
bin.add_actor(name);
|
||||||
box.add_actor(bin);
|
box.add_actor(bin);
|
||||||
|
|
||||||
|
this.addItem(box, name);
|
||||||
|
} else {
|
||||||
|
this.addItem(box, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addItem(box);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1043,6 +1102,9 @@ ThumbnailList.prototype = {
|
|||||||
|
|
||||||
for (let i = 0; i < this._thumbnailBins.length; i++) {
|
for (let i = 0; i < this._thumbnailBins.length; i++) {
|
||||||
let mutterWindow = this._windows[i].get_compositor_private();
|
let mutterWindow = this._windows[i].get_compositor_private();
|
||||||
|
if (!mutterWindow)
|
||||||
|
continue;
|
||||||
|
|
||||||
let windowTexture = mutterWindow.get_texture ();
|
let windowTexture = mutterWindow.get_texture ();
|
||||||
let [width, height] = windowTexture.get_size();
|
let [width, height] = windowTexture.get_size();
|
||||||
let scale = Math.min(1.0, THUMBNAIL_DEFAULT_SIZE / width, availHeight / height);
|
let scale = Math.min(1.0, THUMBNAIL_DEFAULT_SIZE / width, availHeight / height);
|
||||||
@ -1059,4 +1121,47 @@ ThumbnailList.prototype = {
|
|||||||
// Make sure we only do this once
|
// Make sure we only do this once
|
||||||
this._thumbnailBins = new Array();
|
this._thumbnailBins = new Array();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
|
function _drawArrow(area, side) {
|
||||||
|
let themeNode = area.get_theme_node();
|
||||||
|
let borderColor = themeNode.get_border_color(side);
|
||||||
|
let bodyColor = themeNode.get_foreground_color();
|
||||||
|
|
||||||
|
let [width, height] = area.get_surface_size ();
|
||||||
|
let cr = area.get_context();
|
||||||
|
|
||||||
|
cr.setLineWidth(1.0);
|
||||||
|
Clutter.cairo_set_source_color(cr, borderColor);
|
||||||
|
|
||||||
|
switch (side) {
|
||||||
|
case St.Side.TOP:
|
||||||
|
cr.moveTo(0, height);
|
||||||
|
cr.lineTo(Math.floor(width * 0.5), 0);
|
||||||
|
cr.lineTo(width, height);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case St.Side.BOTTOM:
|
||||||
|
cr.moveTo(width, 0);
|
||||||
|
cr.lineTo(Math.floor(width * 0.5), height);
|
||||||
|
cr.lineTo(0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case St.Side.LEFT:
|
||||||
|
cr.moveTo(width, height);
|
||||||
|
cr.lineTo(0, Math.floor(height * 0.5));
|
||||||
|
cr.lineTo(width, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case St.Side.RIGHT:
|
||||||
|
cr.moveTo(0, 0);
|
||||||
|
cr.lineTo(width, Math.floor(height * 0.5));
|
||||||
|
cr.lineTo(0, height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cr.strokePreserve();
|
||||||
|
|
||||||
|
Clutter.cairo_set_source_color(cr, bodyColor);
|
||||||
|
cr.fill();
|
||||||
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const GMenu = imports.gi.GMenu;
|
||||||
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 Meta = imports.gi.Meta;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Gettext = imports.gettext.domain('gnome-shell');
|
|
||||||
const _ = Gettext.gettext;
|
|
||||||
|
|
||||||
const AppFavorites = imports.ui.appFavorites;
|
const AppFavorites = imports.ui.appFavorites;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
@ -21,18 +22,19 @@ const Tweener = imports.ui.tweener;
|
|||||||
const Workspace = imports.ui.workspace;
|
const Workspace = imports.ui.workspace;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
|
|
||||||
|
const MAX_APPLICATION_WORK_MILLIS = 75;
|
||||||
const MENU_POPUP_TIMEOUT = 600;
|
const MENU_POPUP_TIMEOUT = 600;
|
||||||
|
const SCROLL_TIME = 0.1;
|
||||||
|
|
||||||
function AlphabeticalView() {
|
const AlphabeticalView = new Lang.Class({
|
||||||
this._init();
|
Name: 'AlphabeticalView',
|
||||||
}
|
|
||||||
|
|
||||||
AlphabeticalView.prototype = {
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._grid = new IconGrid.IconGrid({ xAlign: St.Align.START });
|
this._grid = new IconGrid.IconGrid({ xAlign: St.Align.START });
|
||||||
this._appSystem = Shell.AppSystem.get_default();
|
this._appSystem = Shell.AppSystem.get_default();
|
||||||
|
|
||||||
this._filterApp = null;
|
this._pendingAppLaterId = 0;
|
||||||
|
this._appIcons = {}; // desktop file id
|
||||||
|
|
||||||
let box = new St.BoxLayout({ vertical: true });
|
let box = new St.BoxLayout({ vertical: true });
|
||||||
box.add(this._grid.actor, { y_align: St.Align.START, expand: true });
|
box.add(this._grid.actor, { y_align: St.Align.START, expand: true });
|
||||||
@ -40,55 +42,97 @@ AlphabeticalView.prototype = {
|
|||||||
this.actor = new St.ScrollView({ x_fill: true,
|
this.actor = new St.ScrollView({ x_fill: true,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
y_align: St.Align.START,
|
y_align: St.Align.START,
|
||||||
vshadows: true });
|
style_class: 'vfade' });
|
||||||
this.actor.add_actor(box);
|
this.actor.add_actor(box);
|
||||||
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||||
|
this.actor.connect('notify::mapped', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
if (!this.actor.mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let adjustment = this.actor.vscroll.adjustment;
|
||||||
|
let direction = Overview.SwipeScrollDirection.VERTICAL;
|
||||||
|
Main.overview.setScrollAdjustment(adjustment, direction);
|
||||||
|
|
||||||
|
// Reset scroll on mapping
|
||||||
|
adjustment.value = 0;
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_removeAll: function() {
|
_removeAll: function() {
|
||||||
this._grid.removeAll();
|
this._grid.removeAll();
|
||||||
this._apps = [];
|
this._appIcons = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
_addApp: function(appInfo) {
|
_addApp: function(app) {
|
||||||
let appIcon = new AppWellIcon(this._appSystem.get_app(appInfo.get_id()));
|
var id = app.get_id();
|
||||||
|
let appIcon = new AppWellIcon(app);
|
||||||
|
|
||||||
this._grid.addItem(appIcon.actor);
|
this._grid.addItem(appIcon.actor);
|
||||||
|
appIcon.actor.connect('key-focus-in', Lang.bind(this, this._ensureIconVisible));
|
||||||
|
|
||||||
appIcon._appInfo = appInfo;
|
this._appIcons[id] = appIcon;
|
||||||
if (this._filterApp && !this._filterApp(appInfo))
|
|
||||||
appIcon.actor.hide();
|
|
||||||
|
|
||||||
this._apps.push(appIcon);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setFilter: function(filter) {
|
_ensureIconVisible: function(icon) {
|
||||||
this._filterApp = filter;
|
let adjustment = this.actor.vscroll.adjustment;
|
||||||
for (let i = 0; i < this._apps.length; i++)
|
let [value, lower, upper, stepIncrement, pageIncrement, pageSize] = adjustment.get_values();
|
||||||
this._apps[i].actor.visible = filter(this._apps[i]._appInfo);
|
|
||||||
|
let offset = 0;
|
||||||
|
let vfade = this.actor.get_effect("vfade");
|
||||||
|
if (vfade)
|
||||||
|
offset = vfade.fade_offset;
|
||||||
|
|
||||||
|
// If this gets called as part of a right-click, the actor
|
||||||
|
// will be needs_allocation, and so "icon.y" would return 0
|
||||||
|
let box = icon.get_allocation_box();
|
||||||
|
|
||||||
|
if (box.y1 < value + offset)
|
||||||
|
value = Math.max(0, box.y1 - offset);
|
||||||
|
else if (box.y2 > value + pageSize - offset)
|
||||||
|
value = Math.min(upper, box.y2 + offset - pageSize);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
Tweener.addTween(adjustment,
|
||||||
|
{ value: value,
|
||||||
|
time: SCROLL_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(apps) {
|
setVisibleApps: function(apps) {
|
||||||
let ids = [];
|
if (apps == null) { // null implies "all"
|
||||||
for (let i in apps)
|
for (var id in this._appIcons) {
|
||||||
ids.push(i);
|
var icon = this._appIcons[id];
|
||||||
ids.sort(function(a, b) {
|
icon.actor.visible = true;
|
||||||
return apps[a].get_name().localeCompare(apps[b].get_name());
|
}
|
||||||
});
|
} else {
|
||||||
|
// Set everything to not-visible, then set to visible what we should see
|
||||||
this._removeAll();
|
for (var id in this._appIcons) {
|
||||||
|
var icon = this._appIcons[id];
|
||||||
for (let i = 0; i < ids.length; i++) {
|
icon.actor.visible = false;
|
||||||
this._addApp(apps[ids[i]]);
|
}
|
||||||
|
for (var i = 0; i < apps.length; i++) {
|
||||||
|
var app = apps[i];
|
||||||
|
var id = app.get_id();
|
||||||
|
var icon = this._appIcons[id];
|
||||||
|
icon.actor.visible = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setAppList: function(apps) {
|
||||||
|
this._removeAll();
|
||||||
|
for (var i = 0; i < apps.length; i++) {
|
||||||
|
var app = apps[i];
|
||||||
|
this._addApp(app);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function ViewByCategories() {
|
const ViewByCategories = new Lang.Class({
|
||||||
this._init();
|
Name: 'ViewByCategories',
|
||||||
}
|
|
||||||
|
|
||||||
ViewByCategories.prototype = {
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._appSystem = Shell.AppSystem.get_default();
|
this._appSystem = Shell.AppSystem.get_default();
|
||||||
this.actor = new St.BoxLayout({ style_class: 'all-app' });
|
this.actor = new St.BoxLayout({ style_class: 'all-app' });
|
||||||
@ -96,82 +140,151 @@ ViewByCategories.prototype = {
|
|||||||
|
|
||||||
this._view = new AlphabeticalView();
|
this._view = new AlphabeticalView();
|
||||||
|
|
||||||
this._filters = new St.BoxLayout({ vertical: true });
|
// categories can be -1 (the All view) or 0...n-1, where n
|
||||||
this.actor.add(this._view.actor, { expand: true, x_fill: true, y_fill: true });
|
// is the number of sections
|
||||||
this.actor.add(this._filters, { expand: false, y_fill: false, y_align: St.Align.START });
|
// -2 is a flag to indicate that nothing is selected
|
||||||
|
// (used only before the actor is mapped the first time)
|
||||||
|
this._currentCategory = -2;
|
||||||
|
this._categories = [];
|
||||||
|
this._apps = null;
|
||||||
|
|
||||||
this._sections = [];
|
this._categoryBox = new St.BoxLayout({ vertical: true, reactive: true });
|
||||||
|
this._categoryScroll = new St.ScrollView({ x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
style_class: 'vfade' });
|
||||||
|
this._categoryScroll.add_actor(this._categoryBox);
|
||||||
|
this.actor.add(this._view.actor, { expand: true, x_fill: true, y_fill: true });
|
||||||
|
this.actor.add(this._categoryScroll, { expand: false, y_fill: false, y_align: St.Align.START });
|
||||||
|
|
||||||
|
// Always select the "All" filter when switching to the app view
|
||||||
|
this.actor.connect('notify::mapped', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
if (this.actor.mapped && this._allCategoryButton)
|
||||||
|
this._selectCategory(-1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
// We need a dummy actor to catch the keyboard focus if the
|
||||||
|
// user Ctrl-Alt-Tabs here before the deferred work creates
|
||||||
|
// our real contents
|
||||||
|
this._focusDummy = new St.Bin({ can_focus: true });
|
||||||
|
this.actor.add(this._focusDummy);
|
||||||
},
|
},
|
||||||
|
|
||||||
_selectCategory: function(num) {
|
_selectCategory: function(num) {
|
||||||
if (num != -1)
|
if (this._currentCategory == num) // nothing to do
|
||||||
this._allFilter.remove_style_pseudo_class('selected');
|
return;
|
||||||
else
|
|
||||||
this._allFilter.add_style_pseudo_class('selected');
|
|
||||||
|
|
||||||
this._view.setFilter(Lang.bind(this, function(app) {
|
this._currentCategory = num;
|
||||||
if (num == -1)
|
|
||||||
return true;
|
|
||||||
return this._sections[num].name == app.get_section();
|
|
||||||
}));
|
|
||||||
|
|
||||||
for (let i = 0; i < this._sections.length; i++) {
|
if (num != -1) {
|
||||||
|
var category = this._categories[num];
|
||||||
|
this._allCategoryButton.remove_style_pseudo_class('selected');
|
||||||
|
this._view.setVisibleApps(category.apps);
|
||||||
|
} else {
|
||||||
|
this._allCategoryButton.add_style_pseudo_class('selected');
|
||||||
|
this._view.setVisibleApps(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < this._categories.length; i++) {
|
||||||
if (i == num)
|
if (i == num)
|
||||||
this._sections[i].filterActor.add_style_pseudo_class('selected');
|
this._categories[i].button.add_style_pseudo_class('selected');
|
||||||
else
|
else
|
||||||
this._sections[i].filterActor.remove_style_pseudo_class('selected');
|
this._categories[i].button.remove_style_pseudo_class('selected');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_addFilter: function(name, num) {
|
// Recursively load a GMenuTreeDirectory; we could put this in ShellAppSystem too
|
||||||
let button = new St.Button({ label: name,
|
_loadCategory: function(dir, appList) {
|
||||||
|
var iter = dir.iter();
|
||||||
|
var nextType;
|
||||||
|
while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) {
|
||||||
|
if (nextType == GMenu.TreeItemType.ENTRY) {
|
||||||
|
var entry = iter.get_entry();
|
||||||
|
var app = this._appSystem.lookup_app_by_tree_entry(entry);
|
||||||
|
if (!entry.get_app_info().get_nodisplay())
|
||||||
|
appList.push(app);
|
||||||
|
} else if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
||||||
|
if (!dir.get_is_nodisplay())
|
||||||
|
this._loadCategory(iter.get_directory(), appList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_addCategory: function(name, index, dir, allApps) {
|
||||||
|
let button = new St.Button({ label: GLib.markup_escape_text (name, -1),
|
||||||
style_class: 'app-filter',
|
style_class: 'app-filter',
|
||||||
x_align: St.Align.START });
|
x_align: St.Align.START,
|
||||||
this._filters.add(button, { expand: true, x_fill: true, y_fill: false });
|
can_focus: true });
|
||||||
button.connect('clicked', Lang.bind(this, function() {
|
button.connect('clicked', Lang.bind(this, function() {
|
||||||
this._selectCategory(num);
|
this._selectCategory(index);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (num != -1)
|
var apps;
|
||||||
this._sections[num] = { filterActor: button,
|
if (dir == null) {
|
||||||
name: name };
|
apps = allApps;
|
||||||
else
|
this._allCategoryButton = button;
|
||||||
this._allFilter = button;
|
} else {
|
||||||
|
apps = [];
|
||||||
|
this._loadCategory(dir, apps);
|
||||||
|
this._categories.push({ apps: apps,
|
||||||
|
name: name,
|
||||||
|
button: button });
|
||||||
|
}
|
||||||
|
|
||||||
|
this._categoryBox.add(button, { expand: true, x_fill: true, y_fill: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
_removeAll: function() {
|
_removeAll: function() {
|
||||||
this._sections = [];
|
this._categories = [];
|
||||||
this._filters.destroy_children();
|
this._categoryBox.destroy_children();
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function(apps) {
|
refresh: function() {
|
||||||
this._removeAll();
|
this._removeAll();
|
||||||
|
|
||||||
let sections = this._appSystem.get_sections();
|
var allApps = Shell.AppSystem.get_default().get_all();
|
||||||
this._apps = apps;
|
allApps.sort(function(a, b) {
|
||||||
this._view.refresh(apps);
|
return a.compare_by_name(b);
|
||||||
|
});
|
||||||
|
|
||||||
/* Translators: Filter to display all applications */
|
/* Translators: Filter to display all applications */
|
||||||
this._addFilter(_("All"), -1);
|
this._addCategory(_("All"), -1, null, allApps);
|
||||||
|
|
||||||
if (!sections)
|
var tree = this._appSystem.get_tree();
|
||||||
return;
|
var root = tree.get_root_directory();
|
||||||
|
|
||||||
for (let i = 0; i < sections.length; i++)
|
var iter = root.iter();
|
||||||
this._addFilter(sections[i], i);
|
var nextType;
|
||||||
|
var i = 0;
|
||||||
|
while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) {
|
||||||
|
if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
||||||
|
var dir = iter.get_directory();
|
||||||
|
if (dir.get_is_nodisplay())
|
||||||
|
continue;
|
||||||
|
this._addCategory(dir.get_name(), i, dir);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._view.setAppList(allApps);
|
||||||
this._selectCategory(-1);
|
this._selectCategory(-1);
|
||||||
|
|
||||||
|
if (this._focusDummy) {
|
||||||
|
let focused = this._focusDummy.has_key_focus();
|
||||||
|
this._focusDummy.destroy();
|
||||||
|
this._focusDummy = null;
|
||||||
|
if (focused)
|
||||||
|
this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
/* This class represents a display containing a collection of application items.
|
/* This class represents a display containing a collection of application items.
|
||||||
* The applications are sorted based on their name.
|
* The applications are sorted based on their name.
|
||||||
*/
|
*/
|
||||||
function AllAppDisplay() {
|
const AllAppDisplay = new Lang.Class({
|
||||||
this._init();
|
Name: 'AllAppDisplay',
|
||||||
}
|
|
||||||
|
|
||||||
AllAppDisplay.prototype = {
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._appSystem = Shell.AppSystem.get_default();
|
this._appSystem = Shell.AppSystem.get_default();
|
||||||
this._appSystem.connect('installed-changed', Lang.bind(this, function() {
|
this._appSystem.connect('installed-changed', Lang.bind(this, function() {
|
||||||
@ -185,141 +298,152 @@ AllAppDisplay.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_redisplay: function() {
|
_redisplay: function() {
|
||||||
let apps = this._appSystem.get_flattened_apps().filter(function(app) {
|
this._appView.refresh();
|
||||||
return !app.get_is_nodisplay();
|
|
||||||
});
|
|
||||||
|
|
||||||
this._appView.refresh(apps);
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function BaseAppSearchProvider() {
|
const AppSearchProvider = new Lang.Class({
|
||||||
this._init();
|
Name: 'AppSearchProvider',
|
||||||
}
|
Extends: Search.SearchProvider,
|
||||||
|
|
||||||
BaseAppSearchProvider.prototype = {
|
_init: function() {
|
||||||
__proto__: Search.SearchProvider.prototype,
|
this.parent(_("APPLICATIONS"));
|
||||||
|
|
||||||
_init: function(name) {
|
|
||||||
Search.SearchProvider.prototype._init.call(this, name);
|
|
||||||
this._appSys = Shell.AppSystem.get_default();
|
this._appSys = Shell.AppSystem.get_default();
|
||||||
},
|
},
|
||||||
|
|
||||||
getResultMeta: function(resultId) {
|
getResultMeta: function(app) {
|
||||||
let app = this._appSys.get_app(resultId);
|
return { 'id': app,
|
||||||
if (!app)
|
|
||||||
return null;
|
|
||||||
return { 'id': resultId,
|
|
||||||
'name': app.get_name(),
|
'name': app.get_name(),
|
||||||
'icon': app.create_icon_texture(Search.RESULT_ICON_SIZE)};
|
'createIcon': function(size) {
|
||||||
},
|
return app.create_icon_texture(size);
|
||||||
|
}
|
||||||
activateResult: function(id) {
|
};
|
||||||
let app = this._appSys.get_app(id);
|
|
||||||
app.activate();
|
|
||||||
},
|
|
||||||
|
|
||||||
dragActivateResult: function(id) {
|
|
||||||
let app = this._appSys.get_app(id);
|
|
||||||
app.open_new_window();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function AppSearchProvider() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
AppSearchProvider.prototype = {
|
|
||||||
__proto__: BaseAppSearchProvider.prototype,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
BaseAppSearchProvider.prototype._init.call(this, _("APPLICATIONS"));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
return this._appSys.initial_search(false, terms);
|
return this._appSys.initial_search(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
return this._appSys.subsearch(false, previousResults, terms);
|
return this._appSys.subsearch(previousResults, terms);
|
||||||
|
},
|
||||||
|
|
||||||
|
activateResult: function(app, params) {
|
||||||
|
params = Params.parse(params, { workspace: -1,
|
||||||
|
timestamp: 0 });
|
||||||
|
|
||||||
|
let event = Clutter.get_current_event();
|
||||||
|
let modifiers = event ? Shell.get_event_state(event) : 0;
|
||||||
|
let openNewWindow = modifiers & Clutter.ModifierType.CONTROL_MASK;
|
||||||
|
|
||||||
|
if (openNewWindow)
|
||||||
|
app.open_new_window(params.workspace);
|
||||||
|
else
|
||||||
|
app.activate_full(params.workspace, params.timestamp);
|
||||||
|
},
|
||||||
|
|
||||||
|
dragActivateResult: function(id, params) {
|
||||||
|
params = Params.parse(params, { workspace: -1,
|
||||||
|
timestamp: 0 });
|
||||||
|
|
||||||
|
let app = this._appSys.lookup_app(id);
|
||||||
|
app.open_new_window(workspace);
|
||||||
},
|
},
|
||||||
|
|
||||||
createResultActor: function (resultMeta, terms) {
|
createResultActor: function (resultMeta, terms) {
|
||||||
let app = this._appSys.get_app(resultMeta['id']);
|
let app = resultMeta['id'];
|
||||||
let icon = new AppWellIcon(app);
|
let icon = new AppWellIcon(app);
|
||||||
return icon.actor;
|
return icon.actor;
|
||||||
},
|
|
||||||
|
|
||||||
expandSearch: function(terms) {
|
|
||||||
log('TODO expand search');
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function PrefsSearchProvider() {
|
const SettingsSearchProvider = new Lang.Class({
|
||||||
this._init();
|
Name: 'SettingsSearchProvider',
|
||||||
}
|
Extends: Search.SearchProvider,
|
||||||
|
|
||||||
PrefsSearchProvider.prototype = {
|
|
||||||
__proto__: BaseAppSearchProvider.prototype,
|
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
BaseAppSearchProvider.prototype._init.call(this, _("PREFERENCES"));
|
this.parent(_("SETTINGS"));
|
||||||
|
|
||||||
|
this._appSys = Shell.AppSystem.get_default();
|
||||||
|
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
|
||||||
|
},
|
||||||
|
|
||||||
|
getResultMeta: function(pref) {
|
||||||
|
return { 'id': pref,
|
||||||
|
'name': pref.get_name(),
|
||||||
|
'createIcon': function(size) {
|
||||||
|
return pref.create_icon_texture(size);
|
||||||
|
}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
return this._appSys.initial_search(true, terms);
|
return this._appSys.search_settings(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
return this._appSys.subsearch(true, previousResults, terms);
|
return this._appSys.search_settings(terms);
|
||||||
},
|
},
|
||||||
|
|
||||||
expandSearch: function(terms) {
|
activateResult: function(pref, params) {
|
||||||
let controlCenter = this._appSys.load_from_desktop_file('gnomecc.desktop');
|
params = Params.parse(params, { workspace: -1,
|
||||||
controlCenter.launch();
|
timestamp: 0 });
|
||||||
Main.overview.hide();
|
|
||||||
|
pref.activate_full(params.workspace, params.timestamp);
|
||||||
|
},
|
||||||
|
|
||||||
|
dragActivateResult: function(pref, params) {
|
||||||
|
this.activateResult(pref, params);
|
||||||
|
},
|
||||||
|
|
||||||
|
createResultActor: function (resultMeta, terms) {
|
||||||
|
let app = resultMeta['id'];
|
||||||
|
let icon = new AppWellIcon(app);
|
||||||
|
return icon.actor;
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function AppIcon(app) {
|
const AppIcon = new Lang.Class({
|
||||||
this._init(app);
|
Name: 'AppIcon',
|
||||||
}
|
Extends: IconGrid.BaseIcon,
|
||||||
|
|
||||||
AppIcon.prototype = {
|
_init : function(app, params) {
|
||||||
__proto__: IconGrid.BaseIcon.prototype,
|
|
||||||
|
|
||||||
_init : function(app) {
|
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
||||||
let label = this.app.get_name();
|
let label = this.app.get_name();
|
||||||
|
|
||||||
IconGrid.BaseIcon.prototype._init.call(this,
|
this.parent(label, params);
|
||||||
label,
|
|
||||||
{ setSizeManually: true });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
createIcon: function(iconSize) {
|
createIcon: function(iconSize) {
|
||||||
return this.app.create_icon_texture(iconSize);
|
return this.app.create_icon_texture(iconSize);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function AppWellIcon(app) {
|
const AppWellIcon = new Lang.Class({
|
||||||
this._init(app);
|
Name: 'AppWellIcon',
|
||||||
}
|
|
||||||
|
|
||||||
AppWellIcon.prototype = {
|
_init : function(app, iconParams, onActivateOverride) {
|
||||||
_init : function(app) {
|
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.actor = new St.Clickable({ style_class: 'app-well-app',
|
this.actor = new St.Button({ style_class: 'app-well-app',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
x_fill: true,
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
|
||||||
y_fill: true });
|
can_focus: true,
|
||||||
|
x_fill: true,
|
||||||
|
y_fill: true });
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
|
|
||||||
this.icon = new AppIcon(app);
|
this.icon = new AppIcon(app, iconParams);
|
||||||
this.actor.set_child(this.icon.actor);
|
this.actor.set_child(this.icon.actor);
|
||||||
|
|
||||||
|
this.actor.label_actor = this.icon.label;
|
||||||
|
|
||||||
|
// A function callback to override the default "app.activate()"; used by preferences
|
||||||
|
this._onActivateOverride = onActivateOverride;
|
||||||
|
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||||
|
this.actor.connect('popup-menu', Lang.bind(this, this._onKeyboardPopupMenu));
|
||||||
|
|
||||||
this._menu = null;
|
this._menu = null;
|
||||||
this._menuManager = new PopupMenu.PopupMenuManager(this);
|
this._menuManager = new PopupMenu.PopupMenuManager(this);
|
||||||
@ -330,12 +454,15 @@ AppWellIcon.prototype = {
|
|||||||
this._removeMenuTimeout();
|
this._removeMenuTimeout();
|
||||||
Main.overview.beginItemDrag(this);
|
Main.overview.beginItemDrag(this);
|
||||||
}));
|
}));
|
||||||
|
this._draggable.connect('drag-cancelled', Lang.bind(this,
|
||||||
|
function () {
|
||||||
|
Main.overview.cancelledItemDrag(this);
|
||||||
|
}));
|
||||||
this._draggable.connect('drag-end', Lang.bind(this,
|
this._draggable.connect('drag-end', Lang.bind(this,
|
||||||
function () {
|
function () {
|
||||||
Main.overview.endItemDrag(this);
|
Main.overview.endItemDrag(this);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
this._menuTimeoutId = 0;
|
this._menuTimeoutId = 0;
|
||||||
@ -374,29 +501,34 @@ AppWellIcon.prototype = {
|
|||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this.popupMenu();
|
this.popupMenu();
|
||||||
}));
|
}));
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onClicked: function(actor, event) {
|
|
||||||
this._removeMenuTimeout();
|
|
||||||
|
|
||||||
let button = event.get_button();
|
|
||||||
if (button == 1) {
|
|
||||||
this._onActivate(event);
|
|
||||||
} else if (button == 2) {
|
|
||||||
let newWorkspace = Main.overview.workspaces.addWorkspace();
|
|
||||||
if (newWorkspace != null) {
|
|
||||||
newWorkspace.activate(global.get_current_time());
|
|
||||||
this.emit('launching');
|
|
||||||
this.app.open_new_window();
|
|
||||||
Main.overview.hide();
|
|
||||||
}
|
|
||||||
} else if (button == 3) {
|
} else if (button == 3) {
|
||||||
this.popupMenu();
|
this.popupMenu();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onClicked: function(actor, button) {
|
||||||
|
this._removeMenuTimeout();
|
||||||
|
|
||||||
|
if (button == 1) {
|
||||||
|
this._onActivate(Clutter.get_current_event());
|
||||||
|
} else if (button == 2) {
|
||||||
|
// Last workspace is always empty
|
||||||
|
let launchWorkspace = global.screen.get_workspace_by_index(global.screen.n_workspaces - 1);
|
||||||
|
launchWorkspace.activate(global.get_current_time());
|
||||||
|
this.emit('launching');
|
||||||
|
this.app.open_new_window(-1);
|
||||||
|
Main.overview.hide();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onKeyboardPopupMenu: function() {
|
||||||
|
this.popupMenu();
|
||||||
|
this._menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
|
},
|
||||||
|
|
||||||
getId: function() {
|
getId: function() {
|
||||||
return this.app.get_id();
|
return this.app.get_id();
|
||||||
},
|
},
|
||||||
@ -407,93 +539,63 @@ AppWellIcon.prototype = {
|
|||||||
|
|
||||||
if (!this._menu) {
|
if (!this._menu) {
|
||||||
this._menu = new AppIconMenu(this);
|
this._menu = new AppIconMenu(this);
|
||||||
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._menu.connect('activate-window', Lang.bind(this, function (menu, window) {
|
||||||
this.activateWindow(window);
|
this.activateWindow(window);
|
||||||
}));
|
}));
|
||||||
this._menu.connect('popup', Lang.bind(this, function (menu, isPoppedUp) {
|
this._menu.connect('open-state-changed', Lang.bind(this, function (menu, isPoppedUp) {
|
||||||
if (isPoppedUp) {
|
if (!isPoppedUp)
|
||||||
this._onMenuPoppedUp();
|
|
||||||
} else {
|
|
||||||
this._onMenuPoppedDown();
|
this._onMenuPoppedDown();
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
Main.overview.connect('hiding', Lang.bind(this, function () { this._menu.close(); }));
|
||||||
|
|
||||||
this._menuManager.addMenu(this._menu);
|
this._menuManager.addMenu(this._menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.actor.set_hover(true);
|
||||||
|
this.actor.show_tooltip();
|
||||||
this._menu.popup();
|
this._menu.popup();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
highlightWindow: function(metaWindow) {
|
|
||||||
if (this._didActivateWindow)
|
|
||||||
return;
|
|
||||||
if (!this._getRunning())
|
|
||||||
return;
|
|
||||||
Main.overview.getWorkspacesForWindow(metaWindow).setHighlightWindow(metaWindow);
|
|
||||||
},
|
|
||||||
|
|
||||||
activateWindow: function(metaWindow) {
|
activateWindow: function(metaWindow) {
|
||||||
if (metaWindow) {
|
if (metaWindow) {
|
||||||
this._didActivateWindow = true;
|
|
||||||
Main.activateWindow(metaWindow);
|
Main.activateWindow(metaWindow);
|
||||||
} else {
|
} else {
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onMenuPoppedUp: function() {
|
|
||||||
if (this._getRunning()) {
|
|
||||||
Main.overview.getWorkspacesForWindow(null).setApplicationWindowSelection(this.app.get_id());
|
|
||||||
this._setWindowSelection = true;
|
|
||||||
this._didActivateWindow = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onMenuPoppedDown: function() {
|
_onMenuPoppedDown: function() {
|
||||||
this.actor.sync_hover();
|
this.actor.sync_hover();
|
||||||
|
|
||||||
if (this._didActivateWindow)
|
|
||||||
return;
|
|
||||||
if (!this._setWindowSelection)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Main.overview.getWorkspacesForWindow(null).setApplicationWindowSelection(null);
|
|
||||||
this._setWindowSelection = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getRunning: function() {
|
|
||||||
return this.app.state != Shell.AppState.STOPPED;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onActivate: function (event) {
|
_onActivate: function (event) {
|
||||||
this.emit('launching');
|
this.emit('launching');
|
||||||
let modifiers = Shell.get_event_state(event);
|
let modifiers = Shell.get_event_state(event);
|
||||||
|
|
||||||
if (modifiers & Clutter.ModifierType.CONTROL_MASK
|
if (this._onActivateOverride) {
|
||||||
&& this.app.state == Shell.AppState.RUNNING) {
|
this._onActivateOverride(event);
|
||||||
this.app.open_new_window();
|
|
||||||
} else {
|
} else {
|
||||||
this.app.activate();
|
if (modifiers & Clutter.ModifierType.CONTROL_MASK
|
||||||
|
&& this.app.state == Shell.AppState.RUNNING) {
|
||||||
|
this.app.open_new_window(-1);
|
||||||
|
} else {
|
||||||
|
this.app.activate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
// called by this._menuManager when it has the grab
|
shellWorkspaceLaunch : function(params) {
|
||||||
menuEventFilter: function(event) {
|
params = Params.parse(params, { workspace: -1,
|
||||||
return this._menu.menuEventFilter(event);
|
timestamp: 0 });
|
||||||
},
|
|
||||||
|
|
||||||
shellWorkspaceLaunch : function() {
|
this.app.open_new_window(params.workspace);
|
||||||
this.app.open_new_window();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getDragActor: function() {
|
getDragActor: function() {
|
||||||
return this.app.create_icon_texture(this.icon.iconSize);
|
return this.app.create_icon_texture(Main.overview.dashIconSize);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Returns the original actor that should align with the actor
|
// Returns the original actor that should align with the actor
|
||||||
@ -501,28 +603,26 @@ AppWellIcon.prototype = {
|
|||||||
getDragActorSource: function() {
|
getDragActorSource: function() {
|
||||||
return this.icon.icon;
|
return this.icon.icon;
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
Signals.addSignalMethods(AppWellIcon.prototype);
|
Signals.addSignalMethods(AppWellIcon.prototype);
|
||||||
|
|
||||||
function AppIconMenu(source) {
|
const AppIconMenu = new Lang.Class({
|
||||||
this._init(source);
|
Name: 'AppIconMenu',
|
||||||
}
|
Extends: PopupMenu.PopupMenu,
|
||||||
|
|
||||||
AppIconMenu.prototype = {
|
|
||||||
__proto__: PopupMenu.PopupMenu.prototype,
|
|
||||||
|
|
||||||
_init: function(source) {
|
_init: function(source) {
|
||||||
let side = St.Side.LEFT;
|
let side = St.Side.LEFT;
|
||||||
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
|
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
|
||||||
side = St.Side.RIGHT;
|
side = St.Side.RIGHT;
|
||||||
|
|
||||||
PopupMenu.PopupMenu.prototype._init.call(this, source.actor, St.Align.MIDDLE, side, 0);
|
this.parent(source.actor, 0.5, side);
|
||||||
|
|
||||||
|
// We want to keep the item hovered while the menu is up
|
||||||
|
this.blockSourceEvents = true;
|
||||||
|
|
||||||
this._source = source;
|
this._source = source;
|
||||||
|
|
||||||
this.connect('active-changed', Lang.bind(this, this._onActiveChanged));
|
|
||||||
this.connect('activate', Lang.bind(this, this._onActivate));
|
this.connect('activate', Lang.bind(this, this._onActivate));
|
||||||
this.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
|
|
||||||
|
|
||||||
this.actor.add_style_class_name('app-well-menu');
|
this.actor.add_style_class_name('app-well-menu');
|
||||||
|
|
||||||
@ -555,19 +655,18 @@ AppIconMenu.prototype = {
|
|||||||
item._window = windows[i];
|
item._window = windows[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (windows.length > 0)
|
if (!this._source.app.is_window_backed()) {
|
||||||
|
if (windows.length > 0)
|
||||||
|
this._appendSeparator();
|
||||||
|
|
||||||
|
let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._source.app.get_id());
|
||||||
|
|
||||||
|
this._newWindowMenuItem = this._appendMenuItem(_("New Window"));
|
||||||
this._appendSeparator();
|
this._appendSeparator();
|
||||||
|
|
||||||
let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._source.app.get_id());
|
this._toggleFavoriteMenuItem = this._appendMenuItem(isFavorite ? _("Remove from Favorites")
|
||||||
|
: _("Add to Favorites"));
|
||||||
this._newWindowMenuItem = windows.length > 0 ? this._appendMenuItem(_("New Window")) : null;
|
}
|
||||||
|
|
||||||
if (windows.length > 0)
|
|
||||||
this._appendSeparator();
|
|
||||||
this._toggleFavoriteMenuItem = this._appendMenuItem(isFavorite ? _("Remove from Favorites")
|
|
||||||
: _("Add to Favorites"));
|
|
||||||
|
|
||||||
this._highlightedItem = null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_appendSeparator: function () {
|
_appendSeparator: function () {
|
||||||
@ -587,78 +686,12 @@ AppIconMenu.prototype = {
|
|||||||
this.open();
|
this.open();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onOpenStateChanged: function (menu, open) {
|
|
||||||
if (open) {
|
|
||||||
this.emit('popup', true);
|
|
||||||
} else {
|
|
||||||
this._updateHighlight(null);
|
|
||||||
this.emit('popup', false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// called by this._menuManager when it has the grab
|
|
||||||
menuEventFilter: function(event) {
|
|
||||||
let eventType = event.type();
|
|
||||||
|
|
||||||
// Check if the user is interacting with a window representation
|
|
||||||
// rather than interacting with the menu
|
|
||||||
|
|
||||||
if (eventType == Clutter.EventType.BUTTON_RELEASE) {
|
|
||||||
let metaWindow = this._findMetaWindowForActor(event.get_source());
|
|
||||||
if (metaWindow)
|
|
||||||
this.emit('activate-window', metaWindow);
|
|
||||||
} else if (eventType == Clutter.EventType.ENTER) {
|
|
||||||
let metaWindow = this._findMetaWindowForActor(event.get_source());
|
|
||||||
if (metaWindow)
|
|
||||||
this._selectMenuItemForWindow(metaWindow, true);
|
|
||||||
} else if (eventType == Clutter.EventType.LEAVE) {
|
|
||||||
let metaWindow = this._findMetaWindowForActor(event.get_source());
|
|
||||||
if (metaWindow)
|
|
||||||
this._selectMenuItemForWindow(metaWindow, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_findMetaWindowForActor: function (actor) {
|
|
||||||
if (actor._delegate instanceof Workspace.WindowClone)
|
|
||||||
return actor._delegate.metaWindow;
|
|
||||||
else if (actor.get_meta_window)
|
|
||||||
return actor.get_meta_window();
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateHighlight: function (item) {
|
|
||||||
if (this._highlightedItem)
|
|
||||||
this.emit('highlight-window', null);
|
|
||||||
this._highlightedItem = item;
|
|
||||||
if (this._highlightedItem) {
|
|
||||||
let window = this._highlightedItem._window;
|
|
||||||
if (window)
|
|
||||||
this.emit('highlight-window', window);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_selectMenuItemForWindow: function (metaWindow, selected) {
|
|
||||||
let items = this.getMenuItems();
|
|
||||||
for (let i = 0; i < items.length; i++) {
|
|
||||||
let item = items[i];
|
|
||||||
let menuMetaWindow = item._window;
|
|
||||||
if (menuMetaWindow == metaWindow)
|
|
||||||
item.setActive(selected);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onActiveChanged: function (menu, child) {
|
|
||||||
this._updateHighlight(child);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onActivate: function (actor, child) {
|
_onActivate: function (actor, child) {
|
||||||
if (child._window) {
|
if (child._window) {
|
||||||
let metaWindow = child._window;
|
let metaWindow = child._window;
|
||||||
this.emit('activate-window', metaWindow);
|
this.emit('activate-window', metaWindow);
|
||||||
} else if (child == this._newWindowMenuItem) {
|
} else if (child == this._newWindowMenuItem) {
|
||||||
this._source.app.open_new_window();
|
this._source.app.open_new_window(-1);
|
||||||
this.emit('activate-window', null);
|
this.emit('activate-window', null);
|
||||||
} else if (child == this._toggleFavoriteMenuItem) {
|
} else if (child == this._toggleFavoriteMenuItem) {
|
||||||
let favs = AppFavorites.getAppFavorites();
|
let favs = AppFavorites.getAppFavorites();
|
||||||
@ -670,5 +703,5 @@ AppIconMenu.prototype = {
|
|||||||
}
|
}
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
Signals.addSignalMethods(AppIconMenu.prototype);
|
Signals.addSignalMethods(AppIconMenu.prototype);
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
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;
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
function AppFavorites() {
|
const AppFavorites = new Lang.Class({
|
||||||
this._init();
|
Name: 'AppFavorites',
|
||||||
}
|
|
||||||
|
|
||||||
AppFavorites.prototype = {
|
|
||||||
FAVORITE_APPS_KEY: 'favorite-apps',
|
FAVORITE_APPS_KEY: 'favorite-apps',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
@ -30,7 +26,7 @@ AppFavorites.prototype = {
|
|||||||
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
|
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.lookup_app(id);
|
||||||
}).filter(function (app) {
|
}).filter(function (app) {
|
||||||
return app != null;
|
return app != null;
|
||||||
});
|
});
|
||||||
@ -67,7 +63,7 @@ AppFavorites.prototype = {
|
|||||||
if (appId in this._favorites)
|
if (appId in this._favorites)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
let app = Shell.AppSystem.get_default().get_app(appId);
|
let app = Shell.AppSystem.get_default().lookup_app(appId);
|
||||||
|
|
||||||
if (!app)
|
if (!app)
|
||||||
return false;
|
return false;
|
||||||
@ -86,9 +82,9 @@ AppFavorites.prototype = {
|
|||||||
if (!this._addFavorite(appId, pos))
|
if (!this._addFavorite(appId, pos))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let app = Shell.AppSystem.get_default().get_app(appId);
|
let app = Shell.AppSystem.get_default().lookup_app(appId);
|
||||||
|
|
||||||
Main.overview.shellInfo.setMessage(_("%s has been added to your favorites.").format(app.get_name()), Lang.bind(this, function () {
|
Main.overview.setMessage(_("%s has been added to your favorites.").format(app.get_name()), Lang.bind(this, function () {
|
||||||
this._removeFavorite(appId);
|
this._removeFavorite(appId);
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
@ -119,12 +115,12 @@ AppFavorites.prototype = {
|
|||||||
if (!this._removeFavorite(appId))
|
if (!this._removeFavorite(appId))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Main.overview.shellInfo.setMessage(_("%s has been removed from your favorites.").format(app.get_name()),
|
Main.overview.setMessage(_("%s has been removed from your favorites.").format(app.get_name()),
|
||||||
Lang.bind(this, function () {
|
Lang.bind(this, function () {
|
||||||
this._addFavorite(appId, pos);
|
this._addFavorite(appId, pos);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
Signals.addSignalMethods(AppFavorites.prototype);
|
Signals.addSignalMethods(AppFavorites.prototype);
|
||||||
|
|
||||||
var appFavoritesInstance = null;
|
var appFavoritesInstance = null;
|
||||||
|
269
js/ui/automountManager.js
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const Params = imports.misc.params;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const ShellMountOperation = imports.ui.shellMountOperation;
|
||||||
|
const ScreenSaver = imports.misc.screenSaver;
|
||||||
|
|
||||||
|
// GSettings keys
|
||||||
|
const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling';
|
||||||
|
const SETTING_ENABLE_AUTOMOUNT = 'automount';
|
||||||
|
|
||||||
|
const AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
|
||||||
|
|
||||||
|
const ConsoleKitSessionIface = <interface name="org.freedesktop.ConsoleKit.Session">
|
||||||
|
<method name="IsActive">
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</method>
|
||||||
|
<signal name="ActiveChanged">
|
||||||
|
<arg type="b" direction="out" />
|
||||||
|
</signal>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ConsoleKitSessionProxy = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface);
|
||||||
|
|
||||||
|
const ConsoleKitManagerIface = <interface name="org.freedesktop.ConsoleKit.Manager">
|
||||||
|
<method name="GetCurrentSession">
|
||||||
|
<arg type="o" direction="out" />
|
||||||
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ConsoleKitManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ConsoleKitManagerIface);
|
||||||
|
|
||||||
|
function ConsoleKitManager() {
|
||||||
|
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.system,
|
||||||
|
g_interface_name: ConsoleKitManagerInfo.name,
|
||||||
|
g_interface_info: ConsoleKitManagerInfo,
|
||||||
|
g_name: 'org.freedesktop.ConsoleKit',
|
||||||
|
g_object_path: '/org/freedesktop/ConsoleKit/Manager',
|
||||||
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
||||||
|
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||||
|
|
||||||
|
self.connect('notify::g-name-owner', function() {
|
||||||
|
if (self.g_name_owner) {
|
||||||
|
self.GetCurrentSessionRemote(function([session]) {
|
||||||
|
self._ckSession = new ConsoleKitSessionProxy(Gio.DBus.system, 'org.freedesktop.ConsoleKit', session);
|
||||||
|
|
||||||
|
self._ckSession.connectSignal('ActiveChanged', function(object, senderName, [isActive]) {
|
||||||
|
self.sessionActive = isActive;
|
||||||
|
});
|
||||||
|
self._ckSession.IsActiveRemote(function([isActive]) {
|
||||||
|
self.sessionActive = isActive;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.sessionActive = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.init(null);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AutomountManager = new Lang.Class({
|
||||||
|
Name: 'AutomountManager',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
|
||||||
|
this._volumeQueue = [];
|
||||||
|
|
||||||
|
this.ckListener = new ConsoleKitManager();
|
||||||
|
|
||||||
|
this._ssProxy = new ScreenSaver.ScreenSaverProxy();
|
||||||
|
this._ssProxy.connectSignal('ActiveChanged',
|
||||||
|
Lang.bind(this, this._screenSaverActiveChanged));
|
||||||
|
|
||||||
|
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||||
|
|
||||||
|
this._volumeMonitor.connect('volume-added',
|
||||||
|
Lang.bind(this,
|
||||||
|
this._onVolumeAdded));
|
||||||
|
this._volumeMonitor.connect('volume-removed',
|
||||||
|
Lang.bind(this,
|
||||||
|
this._onVolumeRemoved));
|
||||||
|
this._volumeMonitor.connect('drive-connected',
|
||||||
|
Lang.bind(this,
|
||||||
|
this._onDriveConnected));
|
||||||
|
this._volumeMonitor.connect('drive-disconnected',
|
||||||
|
Lang.bind(this,
|
||||||
|
this._onDriveDisconnected));
|
||||||
|
this._volumeMonitor.connect('drive-eject-button',
|
||||||
|
Lang.bind(this,
|
||||||
|
this._onDriveEjectButton));
|
||||||
|
|
||||||
|
Mainloop.idle_add(Lang.bind(this, this._startupMountAll));
|
||||||
|
},
|
||||||
|
|
||||||
|
_screenSaverActiveChanged: function(object, senderName, [isActive]) {
|
||||||
|
if (!isActive) {
|
||||||
|
this._volumeQueue.forEach(Lang.bind(this, function(volume) {
|
||||||
|
this._checkAndMountVolume(volume);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear the queue anyway
|
||||||
|
this._volumeQueue = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
_startupMountAll: function() {
|
||||||
|
let volumes = this._volumeMonitor.get_volumes();
|
||||||
|
volumes.forEach(Lang.bind(this, function(volume) {
|
||||||
|
this._checkAndMountVolume(volume, { checkSession: false,
|
||||||
|
useMountOp: false });
|
||||||
|
}));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDriveConnected: function() {
|
||||||
|
// if we're not in the current ConsoleKit session,
|
||||||
|
// or screensaver is active, don't play sounds
|
||||||
|
if (!this.ckListener.sessionActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this._ssProxy.screenSaverActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
global.play_theme_sound(0, 'device-added-media');
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDriveDisconnected: function() {
|
||||||
|
// if we're not in the current ConsoleKit session,
|
||||||
|
// or screensaver is active, don't play sounds
|
||||||
|
if (!this.ckListener.sessionActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this._ssProxy.screenSaverActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
global.play_theme_sound(0, 'device-removed-media');
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDriveEjectButton: function(monitor, drive) {
|
||||||
|
// TODO: this code path is not tested, as the GVfs volume monitor
|
||||||
|
// doesn't emit this signal just yet.
|
||||||
|
if (!this.ckListener.sessionActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// we force stop/eject in this case, so we don't have to pass a
|
||||||
|
// mount operation object
|
||||||
|
if (drive.can_stop()) {
|
||||||
|
drive.stop
|
||||||
|
(Gio.MountUnmountFlags.FORCE, null, null,
|
||||||
|
Lang.bind(this, function(drive, res) {
|
||||||
|
try {
|
||||||
|
drive.stop_finish(res);
|
||||||
|
} catch (e) {
|
||||||
|
log("Unable to stop the drive after drive-eject-button " + e.toString());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
} else if (drive.can_eject()) {
|
||||||
|
drive.eject_with_operation
|
||||||
|
(Gio.MountUnmountFlags.FORCE, null, null,
|
||||||
|
Lang.bind(this, function(drive, res) {
|
||||||
|
try {
|
||||||
|
drive.eject_with_operation_finish(res);
|
||||||
|
} catch (e) {
|
||||||
|
log("Unable to eject the drive after drive-eject-button " + e.toString());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onVolumeAdded: function(monitor, volume) {
|
||||||
|
this._checkAndMountVolume(volume);
|
||||||
|
},
|
||||||
|
|
||||||
|
_checkAndMountVolume: function(volume, params) {
|
||||||
|
params = Params.parse(params, { checkSession: true,
|
||||||
|
useMountOp: true });
|
||||||
|
|
||||||
|
if (params.checkSession) {
|
||||||
|
// if we're not in the current ConsoleKit session,
|
||||||
|
// don't attempt automount
|
||||||
|
if (!this.ckListener.sessionActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this._ssProxy.screenSaverActive) {
|
||||||
|
if (this._volumeQueue.indexOf(volume) == -1)
|
||||||
|
this._volumeQueue.push(volume);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Volume is already mounted, don't bother.
|
||||||
|
if (volume.get_mount())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!this._settings.get_boolean(SETTING_ENABLE_AUTOMOUNT) ||
|
||||||
|
!volume.should_automount() ||
|
||||||
|
!volume.can_mount()) {
|
||||||
|
// allow the autorun to run anyway; this can happen if the
|
||||||
|
// mount gets added programmatically later, even if
|
||||||
|
// should_automount() or can_mount() are false, like for
|
||||||
|
// blank optical media.
|
||||||
|
this._allowAutorun(volume);
|
||||||
|
this._allowAutorunExpire(volume);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.useMountOp) {
|
||||||
|
let operation = new ShellMountOperation.ShellMountOperation(volume);
|
||||||
|
this._mountVolume(volume, operation.mountOp);
|
||||||
|
} else {
|
||||||
|
this._mountVolume(volume, null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_mountVolume: function(volume, operation) {
|
||||||
|
this._allowAutorun(volume);
|
||||||
|
volume.mount(0, operation, null,
|
||||||
|
Lang.bind(this, this._onVolumeMounted));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onVolumeMounted: function(volume, res) {
|
||||||
|
this._allowAutorunExpire(volume);
|
||||||
|
|
||||||
|
try {
|
||||||
|
volume.mount_finish(res);
|
||||||
|
} catch (e) {
|
||||||
|
let string = e.toString();
|
||||||
|
|
||||||
|
// FIXME: needs proper error code handling instead of this
|
||||||
|
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
||||||
|
if (string.indexOf('No key available with this passphrase') != -1)
|
||||||
|
this._reaskPassword(volume);
|
||||||
|
else
|
||||||
|
log('Unable to mount volume ' + volume.get_name() + ': ' + string);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onVolumeRemoved: function(monitor, volume) {
|
||||||
|
this._volumeQueue =
|
||||||
|
this._volumeQueue.filter(function(element) {
|
||||||
|
return (element != volume);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_reaskPassword: function(volume) {
|
||||||
|
let operation = new ShellMountOperation.ShellMountOperation(volume, { reaskPassword: true });
|
||||||
|
this._mountVolume(volume, operation.mountOp);
|
||||||
|
},
|
||||||
|
|
||||||
|
_allowAutorun: function(volume) {
|
||||||
|
volume.allowAutorun = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_allowAutorunExpire: function(volume) {
|
||||||
|
Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, function() {
|
||||||
|
volume.allowAutorun = false;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
603
js/ui/autorunManager.js
Normal file
@ -0,0 +1,603 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const MessageTray = imports.ui.messageTray;
|
||||||
|
const ShellMountOperation = imports.ui.shellMountOperation;
|
||||||
|
|
||||||
|
// GSettings keys
|
||||||
|
const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling';
|
||||||
|
const SETTING_DISABLE_AUTORUN = 'autorun-never';
|
||||||
|
const SETTING_START_APP = 'autorun-x-content-start-app';
|
||||||
|
const SETTING_IGNORE = 'autorun-x-content-ignore';
|
||||||
|
const SETTING_OPEN_FOLDER = 'autorun-x-content-open-folder';
|
||||||
|
|
||||||
|
const AutorunSetting = {
|
||||||
|
RUN: 0,
|
||||||
|
IGNORE: 1,
|
||||||
|
FILES: 2,
|
||||||
|
ASK: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
// misc utils
|
||||||
|
function ignoreAutorunForMount(mount) {
|
||||||
|
let root = mount.get_root();
|
||||||
|
let volume = mount.get_volume();
|
||||||
|
|
||||||
|
if ((root.is_native() && !isMountRootHidden(root)) ||
|
||||||
|
(volume && volume.allowAutorun && volume.should_automount()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMountRootHidden(root) {
|
||||||
|
let path = root.get_path();
|
||||||
|
|
||||||
|
// skip any mounts in hidden directory hierarchies
|
||||||
|
return (path.indexOf('/.') != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startAppForMount(app, mount) {
|
||||||
|
let files = [];
|
||||||
|
let root = mount.get_root();
|
||||||
|
let retval = false;
|
||||||
|
|
||||||
|
files.push(root);
|
||||||
|
|
||||||
|
try {
|
||||||
|
retval = app.launch(files,
|
||||||
|
global.create_app_launch_context())
|
||||||
|
} catch (e) {
|
||||||
|
log('Unable to launch the application ' + app.get_name()
|
||||||
|
+ ': ' + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************/
|
||||||
|
|
||||||
|
const HotplugSnifferIface = <interface name="org.gnome.Shell.HotplugSniffer">
|
||||||
|
<method name="SniffURI">
|
||||||
|
<arg type="s" direction="in" />
|
||||||
|
<arg type="as" direction="out" />
|
||||||
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const HotplugSnifferProxy = Gio.DBusProxy.makeProxyWrapper(HotplugSnifferIface);
|
||||||
|
function HotplugSniffer() {
|
||||||
|
return new HotplugSnifferProxy(Gio.DBus.session,
|
||||||
|
'org.gnome.Shell.HotplugSniffer',
|
||||||
|
'/org/gnome/Shell/HotplugSniffer');
|
||||||
|
}
|
||||||
|
|
||||||
|
const ContentTypeDiscoverer = new Lang.Class({
|
||||||
|
Name: 'ContentTypeDiscoverer',
|
||||||
|
|
||||||
|
_init: function(callback) {
|
||||||
|
this._callback = callback;
|
||||||
|
},
|
||||||
|
|
||||||
|
guessContentTypes: function(mount) {
|
||||||
|
// guess mount's content types using GIO
|
||||||
|
mount.guess_content_type(false, null,
|
||||||
|
Lang.bind(this,
|
||||||
|
this._onContentTypeGuessed));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onContentTypeGuessed: function(mount, res) {
|
||||||
|
let contentTypes = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
contentTypes = mount.guess_content_type_finish(res);
|
||||||
|
} catch (e) {
|
||||||
|
log('Unable to guess content types on added mount ' + mount.get_name()
|
||||||
|
+ ': ' + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentTypes.length) {
|
||||||
|
this._emitCallback(mount, contentTypes);
|
||||||
|
} else {
|
||||||
|
let root = mount.get_root();
|
||||||
|
|
||||||
|
let hotplugSniffer = new HotplugSniffer();
|
||||||
|
hotplugSniffer.SniffURIRemote(root.get_uri(),
|
||||||
|
Lang.bind(this, function([contentTypes]) {
|
||||||
|
this._emitCallback(mount, contentTypes);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_emitCallback: function(mount, contentTypes) {
|
||||||
|
if (!contentTypes)
|
||||||
|
contentTypes = [];
|
||||||
|
|
||||||
|
// we're not interested in win32 software content types here
|
||||||
|
contentTypes = contentTypes.filter(function(type) {
|
||||||
|
return (type != 'x-content/win32-software');
|
||||||
|
});
|
||||||
|
|
||||||
|
let apps = [];
|
||||||
|
contentTypes.forEach(function(type) {
|
||||||
|
let app = Gio.app_info_get_default_for_type(type, false);
|
||||||
|
|
||||||
|
if (app)
|
||||||
|
apps.push(app);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (apps.length == 0)
|
||||||
|
apps.push(Gio.app_info_get_default_for_type('inode/directory', false));
|
||||||
|
|
||||||
|
this._callback(mount, apps, contentTypes);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const AutorunManager = new Lang.Class({
|
||||||
|
Name: 'AutorunManager',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||||
|
|
||||||
|
this._volumeMonitor.connect('mount-added',
|
||||||
|
Lang.bind(this,
|
||||||
|
this._onMountAdded));
|
||||||
|
this._volumeMonitor.connect('mount-removed',
|
||||||
|
Lang.bind(this,
|
||||||
|
this._onMountRemoved));
|
||||||
|
|
||||||
|
this._transDispatcher = new AutorunTransientDispatcher();
|
||||||
|
this._createResidentSource();
|
||||||
|
|
||||||
|
let mounts = this._volumeMonitor.get_mounts();
|
||||||
|
|
||||||
|
mounts.forEach(Lang.bind(this, function (mount) {
|
||||||
|
let discoverer = new ContentTypeDiscoverer(Lang.bind (this,
|
||||||
|
function (mount, apps) {
|
||||||
|
this._residentSource.addMount(mount, apps);
|
||||||
|
}));
|
||||||
|
|
||||||
|
discoverer.guessContentTypes(mount);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_createResidentSource: function() {
|
||||||
|
this._residentSource = new AutorunResidentSource();
|
||||||
|
this._residentSource.connect('destroy',
|
||||||
|
Lang.bind(this,
|
||||||
|
this._createResidentSource));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMountAdded: function(monitor, mount) {
|
||||||
|
// don't do anything if our session is not the currently
|
||||||
|
// active one
|
||||||
|
if (!Main.automountManager.ckListener.sessionActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let discoverer = new ContentTypeDiscoverer(Lang.bind (this,
|
||||||
|
function (mount, apps, contentTypes) {
|
||||||
|
this._transDispatcher.addMount(mount, apps, contentTypes);
|
||||||
|
this._residentSource.addMount(mount, apps);
|
||||||
|
}));
|
||||||
|
|
||||||
|
discoverer.guessContentTypes(mount);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMountRemoved: function(monitor, mount) {
|
||||||
|
this._transDispatcher.removeMount(mount);
|
||||||
|
this._residentSource.removeMount(mount);
|
||||||
|
},
|
||||||
|
|
||||||
|
ejectMount: function(mount) {
|
||||||
|
let mountOp = new ShellMountOperation.ShellMountOperation(mount);
|
||||||
|
|
||||||
|
// first, see if we have a drive
|
||||||
|
let drive = mount.get_drive();
|
||||||
|
let volume = mount.get_volume();
|
||||||
|
|
||||||
|
if (drive &&
|
||||||
|
drive.get_start_stop_type() == Gio.DriveStartStopType.SHUTDOWN &&
|
||||||
|
drive.can_stop()) {
|
||||||
|
drive.stop(0, mountOp.mountOp, null,
|
||||||
|
Lang.bind(this, this._onStop));
|
||||||
|
} else {
|
||||||
|
if (mount.can_eject()) {
|
||||||
|
mount.eject_with_operation(0, mountOp.mountOp, null,
|
||||||
|
Lang.bind(this, this._onEject));
|
||||||
|
} else if (volume && volume.can_eject()) {
|
||||||
|
volume.eject_with_operation(0, mountOp.mountOp, null,
|
||||||
|
Lang.bind(this, this._onEject));
|
||||||
|
} else if (drive && drive.can_eject()) {
|
||||||
|
drive.eject_with_operation(0, mountOp.mountOp, null,
|
||||||
|
Lang.bind(this, this._onEject));
|
||||||
|
} else if (mount.can_unmount()) {
|
||||||
|
mount.unmount_with_operation(0, mountOp.mountOp, null,
|
||||||
|
Lang.bind(this, this._onUnmount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onUnmount: function(mount, res) {
|
||||||
|
try {
|
||||||
|
mount.unmount_with_operation_finish(res);
|
||||||
|
} catch (e) {
|
||||||
|
// FIXME: we need to ignore G_IO_ERROR_FAILED_HANDLED errors here
|
||||||
|
// but we can't access the error code from JS.
|
||||||
|
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
||||||
|
log('Unable to eject the mount ' + mount.get_name()
|
||||||
|
+ ': ' + e.toString());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onEject: function(source, res) {
|
||||||
|
try {
|
||||||
|
source.eject_with_operation_finish(res);
|
||||||
|
} catch (e) {
|
||||||
|
// FIXME: we need to ignore G_IO_ERROR_FAILED_HANDLED errors here
|
||||||
|
// but we can't access the error code from JS.
|
||||||
|
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
||||||
|
log('Unable to eject the drive ' + source.get_name()
|
||||||
|
+ ': ' + e.toString());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onStop: function(drive, res) {
|
||||||
|
try {
|
||||||
|
drive.stop_finish(res);
|
||||||
|
} catch (e) {
|
||||||
|
// FIXME: we need to ignore G_IO_ERROR_FAILED_HANDLED errors here
|
||||||
|
// but we can't access the error code from JS.
|
||||||
|
// See https://bugzilla.gnome.org/show_bug.cgi?id=591480
|
||||||
|
log('Unable to stop the drive ' + drive.get_name()
|
||||||
|
+ ': ' + e.toString());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const AutorunResidentSource = new Lang.Class({
|
||||||
|
Name: 'AutorunResidentSource',
|
||||||
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent(_("Removable Devices"));
|
||||||
|
|
||||||
|
this._mounts = [];
|
||||||
|
|
||||||
|
this._notification = new AutorunResidentNotification(this);
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
},
|
||||||
|
|
||||||
|
addMount: function(mount, apps) {
|
||||||
|
if (ignoreAutorunForMount(mount))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let filtered = this._mounts.filter(function (element) {
|
||||||
|
return (element.mount == mount);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (filtered.length != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let element = { mount: mount, apps: apps };
|
||||||
|
this._mounts.push(element);
|
||||||
|
this._redisplay();
|
||||||
|
},
|
||||||
|
|
||||||
|
removeMount: function(mount) {
|
||||||
|
this._mounts =
|
||||||
|
this._mounts.filter(function (element) {
|
||||||
|
return (element.mount != mount);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._redisplay();
|
||||||
|
},
|
||||||
|
|
||||||
|
_redisplay: function() {
|
||||||
|
if (this._mounts.length == 0) {
|
||||||
|
this._notification.destroy();
|
||||||
|
this.destroy();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._notification.updateForMounts(this._mounts);
|
||||||
|
|
||||||
|
// add ourselves as a source, and push the notification
|
||||||
|
if (!Main.messageTray.contains(this)) {
|
||||||
|
Main.messageTray.add(this);
|
||||||
|
this.pushNotification(this._notification);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createNotificationIcon: function() {
|
||||||
|
return new St.Icon ({ icon_name: 'media-removable',
|
||||||
|
icon_type: St.IconType.FULLCOLOR,
|
||||||
|
icon_size: this.ICON_SIZE });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const AutorunResidentNotification = new Lang.Class({
|
||||||
|
Name: 'AutorunResidentNotification',
|
||||||
|
Extends: MessageTray.Notification,
|
||||||
|
|
||||||
|
_init: function(source) {
|
||||||
|
this.parent(source, source.title, null, { customContent: true });
|
||||||
|
|
||||||
|
// set the notification as resident
|
||||||
|
this.setResident(true);
|
||||||
|
|
||||||
|
this._layout = new St.BoxLayout ({ style_class: 'hotplug-resident-box',
|
||||||
|
vertical: true });
|
||||||
|
|
||||||
|
this.addActor(this._layout,
|
||||||
|
{ x_expand: true,
|
||||||
|
x_fill: true });
|
||||||
|
},
|
||||||
|
|
||||||
|
updateForMounts: function(mounts) {
|
||||||
|
// remove all the layout content
|
||||||
|
this._layout.destroy_children();
|
||||||
|
|
||||||
|
for (let idx = 0; idx < mounts.length; idx++) {
|
||||||
|
let element = mounts[idx];
|
||||||
|
|
||||||
|
let actor = this._itemForMount(element.mount, element.apps);
|
||||||
|
this._layout.add(actor, { x_fill: true,
|
||||||
|
expand: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_itemForMount: function(mount, apps) {
|
||||||
|
let item = new St.BoxLayout();
|
||||||
|
|
||||||
|
// prepare the mount button content
|
||||||
|
let mountLayout = new St.BoxLayout();
|
||||||
|
|
||||||
|
let mountIcon = new St.Icon({ gicon: mount.get_icon(),
|
||||||
|
style_class: 'hotplug-resident-mount-icon' });
|
||||||
|
mountLayout.add_actor(mountIcon);
|
||||||
|
|
||||||
|
let labelBin = new St.Bin({ y_align: St.Align.MIDDLE });
|
||||||
|
let mountLabel =
|
||||||
|
new St.Label({ text: mount.get_name(),
|
||||||
|
style_class: 'hotplug-resident-mount-label',
|
||||||
|
track_hover: true,
|
||||||
|
reactive: true });
|
||||||
|
labelBin.add_actor(mountLabel);
|
||||||
|
mountLayout.add_actor(labelBin);
|
||||||
|
|
||||||
|
let mountButton = new St.Button({ child: mountLayout,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
x_fill: true,
|
||||||
|
style_class: 'hotplug-resident-mount',
|
||||||
|
button_mask: St.ButtonMask.ONE });
|
||||||
|
item.add(mountButton, { x_align: St.Align.START,
|
||||||
|
expand: true });
|
||||||
|
|
||||||
|
let ejectIcon =
|
||||||
|
new St.Icon({ icon_name: 'media-eject',
|
||||||
|
style_class: 'hotplug-resident-eject-icon' });
|
||||||
|
|
||||||
|
let ejectButton =
|
||||||
|
new St.Button({ style_class: 'hotplug-resident-eject-button',
|
||||||
|
button_mask: St.ButtonMask.ONE,
|
||||||
|
child: ejectIcon });
|
||||||
|
item.add(ejectButton, { x_align: St.Align.END });
|
||||||
|
|
||||||
|
// now connect signals
|
||||||
|
mountButton.connect('clicked', Lang.bind(this, function(actor, event) {
|
||||||
|
startAppForMount(apps[0], mount);
|
||||||
|
}));
|
||||||
|
|
||||||
|
ejectButton.connect('clicked', Lang.bind(this, function() {
|
||||||
|
Main.autorunManager.ejectMount(mount);
|
||||||
|
}));
|
||||||
|
|
||||||
|
return item;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const AutorunTransientDispatcher = new Lang.Class({
|
||||||
|
Name: 'AutorunTransientDispatcher',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._sources = [];
|
||||||
|
this._settings = new Gio.Settings({ schema: SETTINGS_SCHEMA });
|
||||||
|
},
|
||||||
|
|
||||||
|
_getAutorunSettingForType: function(contentType) {
|
||||||
|
let runApp = this._settings.get_strv(SETTING_START_APP);
|
||||||
|
if (runApp.indexOf(contentType) != -1)
|
||||||
|
return AutorunSetting.RUN;
|
||||||
|
|
||||||
|
let ignore = this._settings.get_strv(SETTING_IGNORE);
|
||||||
|
if (ignore.indexOf(contentType) != -1)
|
||||||
|
return AutorunSetting.IGNORE;
|
||||||
|
|
||||||
|
let openFiles = this._settings.get_strv(SETTING_OPEN_FOLDER);
|
||||||
|
if (openFiles.indexOf(contentType) != -1)
|
||||||
|
return AutorunSetting.FILES;
|
||||||
|
|
||||||
|
return AutorunSetting.ASK;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getSourceForMount: function(mount) {
|
||||||
|
let filtered =
|
||||||
|
this._sources.filter(function (source) {
|
||||||
|
return (source.mount == mount);
|
||||||
|
});
|
||||||
|
|
||||||
|
// we always make sure not to add two sources for the same
|
||||||
|
// mount in addMount(), so it's safe to assume filtered.length
|
||||||
|
// is always either 1 or 0.
|
||||||
|
if (filtered.length == 1)
|
||||||
|
return filtered[0];
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_addSource: function(mount, apps) {
|
||||||
|
// if we already have a source showing for this
|
||||||
|
// mount, return
|
||||||
|
if (this._getSourceForMount(mount))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// add a new source
|
||||||
|
this._sources.push(new AutorunTransientSource(mount, apps));
|
||||||
|
},
|
||||||
|
|
||||||
|
addMount: function(mount, apps, contentTypes) {
|
||||||
|
// if autorun is disabled globally, return
|
||||||
|
if (this._settings.get_boolean(SETTING_DISABLE_AUTORUN))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// if the mount doesn't want to be autorun, return
|
||||||
|
if (ignoreAutorunForMount(mount))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let setting = this._getAutorunSettingForType(contentTypes[0]);
|
||||||
|
|
||||||
|
// check at the settings for the first content type
|
||||||
|
// to see whether we should ask
|
||||||
|
if (setting == AutorunSetting.IGNORE)
|
||||||
|
return; // return right away
|
||||||
|
|
||||||
|
let success = false;
|
||||||
|
let app = null;
|
||||||
|
|
||||||
|
if (setting == AutorunSetting.RUN) {
|
||||||
|
app = Gio.app_info_get_default_for_type(contentTypes[0], false);
|
||||||
|
} else if (setting == AutorunSetting.FILES) {
|
||||||
|
app = Gio.app_info_get_default_for_type('inode/directory', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app)
|
||||||
|
success = startAppForMount(app, mount);
|
||||||
|
|
||||||
|
// we fallback here also in case the settings did not specify 'ask',
|
||||||
|
// but we failed launching the default app or the default file manager
|
||||||
|
if (!success)
|
||||||
|
this._addSource(mount, apps);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeMount: function(mount) {
|
||||||
|
let source = this._getSourceForMount(mount);
|
||||||
|
|
||||||
|
// if we aren't tracking this mount, don't do anything
|
||||||
|
if (!source)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// destroy the notification source
|
||||||
|
source.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const AutorunTransientSource = new Lang.Class({
|
||||||
|
Name: 'AutorunTransientSource',
|
||||||
|
Extends: MessageTray.Source,
|
||||||
|
|
||||||
|
_init: function(mount, apps) {
|
||||||
|
this.parent(mount.get_name());
|
||||||
|
|
||||||
|
this.mount = mount;
|
||||||
|
this.apps = apps;
|
||||||
|
|
||||||
|
this._notification = new AutorunTransientNotification(this);
|
||||||
|
this._setSummaryIcon(this.createNotificationIcon());
|
||||||
|
|
||||||
|
// add ourselves as a source, and popup the notification
|
||||||
|
Main.messageTray.add(this);
|
||||||
|
this.notify(this._notification);
|
||||||
|
},
|
||||||
|
|
||||||
|
createNotificationIcon: function() {
|
||||||
|
return new St.Icon({ gicon: this.mount.get_icon(),
|
||||||
|
icon_size: this.ICON_SIZE });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const AutorunTransientNotification = new Lang.Class({
|
||||||
|
Name: 'AutorunTransientNotification',
|
||||||
|
Extends: MessageTray.Notification,
|
||||||
|
|
||||||
|
_init: function(source) {
|
||||||
|
this.parent(source, source.title, null, { customContent: true });
|
||||||
|
|
||||||
|
this._box = new St.BoxLayout({ style_class: 'hotplug-transient-box',
|
||||||
|
vertical: true });
|
||||||
|
this.addActor(this._box);
|
||||||
|
|
||||||
|
this._mount = source.mount;
|
||||||
|
|
||||||
|
source.apps.forEach(Lang.bind(this, function (app) {
|
||||||
|
let actor = this._buttonForApp(app);
|
||||||
|
|
||||||
|
if (actor)
|
||||||
|
this._box.add(actor, { x_fill: true,
|
||||||
|
x_align: St.Align.START });
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._box.add(this._buttonForEject(), { x_fill: true,
|
||||||
|
x_align: St.Align.START });
|
||||||
|
|
||||||
|
// set the notification to transient and urgent, so that it
|
||||||
|
// expands out
|
||||||
|
this.setTransient(true);
|
||||||
|
this.setUrgency(MessageTray.Urgency.CRITICAL);
|
||||||
|
},
|
||||||
|
|
||||||
|
_buttonForApp: function(app) {
|
||||||
|
let box = new St.BoxLayout();
|
||||||
|
let icon = new St.Icon({ gicon: app.get_icon(),
|
||||||
|
style_class: 'hotplug-notification-item-icon' });
|
||||||
|
box.add(icon);
|
||||||
|
|
||||||
|
let label = new St.Bin({ y_align: St.Align.MIDDLE,
|
||||||
|
child: new St.Label
|
||||||
|
({ text: _("Open with %s").format(app.get_display_name()) })
|
||||||
|
});
|
||||||
|
box.add(label);
|
||||||
|
|
||||||
|
let button = new St.Button({ child: box,
|
||||||
|
x_fill: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
button_mask: St.ButtonMask.ONE,
|
||||||
|
style_class: 'hotplug-notification-item' });
|
||||||
|
|
||||||
|
button.connect('clicked', Lang.bind(this, function() {
|
||||||
|
startAppForMount(app, this._mount);
|
||||||
|
this.destroy();
|
||||||
|
}));
|
||||||
|
|
||||||
|
return button;
|
||||||
|
},
|
||||||
|
|
||||||
|
_buttonForEject: function() {
|
||||||
|
let box = new St.BoxLayout();
|
||||||
|
let icon = new St.Icon({ icon_name: 'media-eject',
|
||||||
|
style_class: 'hotplug-notification-item-icon' });
|
||||||
|
box.add(icon);
|
||||||
|
|
||||||
|
let label = new St.Bin({ y_align: St.Align.MIDDLE,
|
||||||
|
child: new St.Label
|
||||||
|
({ text: _("Eject") })
|
||||||
|
});
|
||||||
|
box.add(label);
|
||||||
|
|
||||||
|
let button = new St.Button({ child: box,
|
||||||
|
x_fill: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
button_mask: St.ButtonMask.ONE,
|
||||||
|
style_class: 'hotplug-notification-item' });
|
||||||
|
|
||||||
|
button.connect('clicked', Lang.bind(this, function() {
|
||||||
|
Main.autorunManager.ejectMount(this._mount);
|
||||||
|
}));
|
||||||
|
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -1,10 +1,12 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
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 St = imports.gi.St;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const POPUP_ANIMATION_TIME = 0.15;
|
const POPUP_ANIMATION_TIME = 0.15;
|
||||||
@ -19,11 +21,9 @@ const POPUP_ANIMATION_TIME = 0.15;
|
|||||||
* placed. The arrow position may be controlled via setArrowOrigin().
|
* placed. The arrow position may be controlled via setArrowOrigin().
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function BoxPointer(side, binProperties) {
|
const BoxPointer = new Lang.Class({
|
||||||
this._init(side, binProperties);
|
Name: 'BoxPointer',
|
||||||
}
|
|
||||||
|
|
||||||
BoxPointer.prototype = {
|
|
||||||
_init: function(arrowSide, binProperties) {
|
_init: function(arrowSide, binProperties) {
|
||||||
this._arrowSide = arrowSide;
|
this._arrowSide = arrowSide;
|
||||||
this._arrowOrigin = 0;
|
this._arrowOrigin = 0;
|
||||||
@ -40,80 +40,81 @@ BoxPointer.prototype = {
|
|||||||
this._border.connect('repaint', Lang.bind(this, this._drawBorder));
|
this._border.connect('repaint', Lang.bind(this, this._drawBorder));
|
||||||
this._container.add_actor(this._border);
|
this._container.add_actor(this._border);
|
||||||
this.bin.raise(this._border);
|
this.bin.raise(this._border);
|
||||||
|
this._xOffset = 0;
|
||||||
|
this._yOffset = 0;
|
||||||
|
this._xPosition = 0;
|
||||||
|
this._yPosition = 0;
|
||||||
|
this._sourceAlignment = 0.5;
|
||||||
},
|
},
|
||||||
|
|
||||||
show: function(animate, onComplete) {
|
show: function(animate, onComplete) {
|
||||||
let x = this.actor.x;
|
|
||||||
let y = this.actor.y;
|
|
||||||
let themeNode = this.actor.get_theme_node();
|
let themeNode = this.actor.get_theme_node();
|
||||||
let rise = themeNode.get_length('-arrow-rise');
|
let rise = themeNode.get_length('-arrow-rise');
|
||||||
|
|
||||||
this.actor.opacity = 0;
|
this.opacity = 0;
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
switch (this._arrowSide) {
|
switch (this._arrowSide) {
|
||||||
case St.Side.TOP:
|
case St.Side.TOP:
|
||||||
this.actor.y -= rise;
|
this.yOffset = -rise;
|
||||||
break;
|
break;
|
||||||
case St.Side.BOTTOM:
|
case St.Side.BOTTOM:
|
||||||
this.actor.y += rise;
|
this.yOffset = rise;
|
||||||
break;
|
break;
|
||||||
case St.Side.LEFT:
|
case St.Side.LEFT:
|
||||||
this.actor.x -= rise;
|
this.xOffset = -rise;
|
||||||
break;
|
break;
|
||||||
case St.Side.RIGHT:
|
case St.Side.RIGHT:
|
||||||
this.actor.x += rise;
|
this.xOffset = rise;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Tweener.addTween(this.actor, { opacity: 255,
|
Tweener.addTween(this, { opacity: 255,
|
||||||
x: x,
|
xOffset: 0,
|
||||||
y: y,
|
yOffset: 0,
|
||||||
transition: "linear",
|
transition: 'linear',
|
||||||
onComplete: onComplete,
|
onComplete: onComplete,
|
||||||
time: POPUP_ANIMATION_TIME });
|
time: POPUP_ANIMATION_TIME });
|
||||||
},
|
},
|
||||||
|
|
||||||
hide: function(animate, onComplete) {
|
hide: function(animate, onComplete) {
|
||||||
let x = this.actor.x;
|
let xOffset = 0;
|
||||||
let y = this.actor.y;
|
let yOffset = 0;
|
||||||
let originalX = this.actor.x;
|
|
||||||
let originalY = this.actor.y;
|
|
||||||
let themeNode = this.actor.get_theme_node();
|
let themeNode = this.actor.get_theme_node();
|
||||||
let rise = themeNode.get_length('-arrow-rise');
|
let rise = themeNode.get_length('-arrow-rise');
|
||||||
|
|
||||||
if (animate) {
|
if (animate) {
|
||||||
switch (this._arrowSide) {
|
switch (this._arrowSide) {
|
||||||
case St.Side.TOP:
|
case St.Side.TOP:
|
||||||
y += rise;
|
yOffset = rise;
|
||||||
break;
|
break;
|
||||||
case St.Side.BOTTOM:
|
case St.Side.BOTTOM:
|
||||||
y -= rise;
|
yOffset = -rise;
|
||||||
break;
|
break;
|
||||||
case St.Side.LEFT:
|
case St.Side.LEFT:
|
||||||
x += rise;
|
xOffset = rise;
|
||||||
break;
|
break;
|
||||||
case St.Side.RIGHT:
|
case St.Side.RIGHT:
|
||||||
x -= rise;
|
xOffset = -rise;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Tweener.addTween(this.actor, { opacity: 0,
|
Tweener.addTween(this, { opacity: 0,
|
||||||
x: x,
|
xOffset: xOffset,
|
||||||
y: y,
|
yOffset: yOffset,
|
||||||
transition: "linear",
|
transition: 'linear',
|
||||||
time: POPUP_ANIMATION_TIME,
|
time: POPUP_ANIMATION_TIME,
|
||||||
onComplete: Lang.bind(this, function () {
|
onComplete: Lang.bind(this, function () {
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
this.actor.x = originalX;
|
this.xOffset = 0;
|
||||||
this.actor.y = originalY;
|
this.yOffset = 0;
|
||||||
if (onComplete)
|
if (onComplete)
|
||||||
onComplete();
|
onComplete();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_adjustAllocationForArrow: function(isWidth, alloc) {
|
_adjustAllocationForArrow: function(isWidth, alloc) {
|
||||||
@ -176,6 +177,9 @@ BoxPointer.prototype = {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.bin.allocate(childBox, flags);
|
this.bin.allocate(childBox, flags);
|
||||||
|
|
||||||
|
if (this._sourceActor && this._sourceActor.mapped)
|
||||||
|
this._reposition(this._sourceActor, this._arrowAlignment);
|
||||||
},
|
},
|
||||||
|
|
||||||
_drawBorder: function(area) {
|
_drawBorder: function(area) {
|
||||||
@ -189,10 +193,8 @@ BoxPointer.prototype = {
|
|||||||
let halfBorder = borderWidth / 2;
|
let halfBorder = borderWidth / 2;
|
||||||
let halfBase = Math.floor(base/2);
|
let halfBase = Math.floor(base/2);
|
||||||
|
|
||||||
let borderColor = new Clutter.Color();
|
let borderColor = themeNode.get_color('-arrow-border-color');
|
||||||
themeNode.get_color('-arrow-border-color', borderColor);
|
let backgroundColor = themeNode.get_color('-arrow-background-color');
|
||||||
let backgroundColor = new Clutter.Color();
|
|
||||||
themeNode.get_color('-arrow-background-color', backgroundColor);
|
|
||||||
|
|
||||||
let [width, height] = area.get_surface_size();
|
let [width, height] = area.get_surface_size();
|
||||||
let [boxWidth, boxHeight] = [width, height];
|
let [boxWidth, boxHeight] = [width, height];
|
||||||
@ -212,46 +214,88 @@ BoxPointer.prototype = {
|
|||||||
cr.translate(rise, 0);
|
cr.translate(rise, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
cr.moveTo(borderRadius, halfBorder);
|
let [x1, y1] = [halfBorder, halfBorder];
|
||||||
|
let [x2, y2] = [boxWidth - halfBorder, boxHeight - halfBorder];
|
||||||
|
|
||||||
|
cr.moveTo(x1 + borderRadius, y1);
|
||||||
if (this._arrowSide == St.Side.TOP) {
|
if (this._arrowSide == St.Side.TOP) {
|
||||||
cr.lineTo(this._arrowOrigin - halfBase, halfBorder);
|
if (this._arrowOrigin < (x1 + (borderRadius + halfBase))) {
|
||||||
cr.lineTo(this._arrowOrigin, halfBorder - rise);
|
cr.lineTo(this._arrowOrigin, y1 - rise);
|
||||||
cr.lineTo(this._arrowOrigin + halfBase, halfBorder);
|
cr.lineTo(Math.max(x1 + borderRadius, this._arrowOrigin) + halfBase, y1);
|
||||||
|
} else if (this._arrowOrigin > (x2 - (borderRadius + halfBase))) {
|
||||||
|
cr.lineTo(Math.min(x2 - borderRadius, this._arrowOrigin) - halfBase, y1);
|
||||||
|
cr.lineTo(this._arrowOrigin, y1 - rise);
|
||||||
|
} else {
|
||||||
|
cr.lineTo(this._arrowOrigin - halfBase, y1);
|
||||||
|
cr.lineTo(this._arrowOrigin, y1 - rise);
|
||||||
|
cr.lineTo(this._arrowOrigin + halfBase, y1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cr.lineTo(boxWidth - borderRadius, halfBorder);
|
|
||||||
|
|
||||||
cr.arc(boxWidth - borderRadius - halfBorder, borderRadius + halfBorder, borderRadius,
|
cr.lineTo(x2 - borderRadius, y1);
|
||||||
|
|
||||||
|
// top-right corner
|
||||||
|
cr.arc(x2 - borderRadius, y1 + borderRadius, borderRadius,
|
||||||
3*Math.PI/2, Math.PI*2);
|
3*Math.PI/2, Math.PI*2);
|
||||||
|
|
||||||
if (this._arrowSide == St.Side.RIGHT) {
|
if (this._arrowSide == St.Side.RIGHT) {
|
||||||
cr.lineTo(boxWidth - halfBorder, this._arrowOrigin - halfBase);
|
if (this._arrowOrigin < (y1 + (borderRadius + halfBase))) {
|
||||||
cr.lineTo(boxWidth - halfBorder + rise, this._arrowOrigin);
|
cr.lineTo(x2 + rise, this._arrowOrigin);
|
||||||
cr.lineTo(boxWidth - halfBorder, this._arrowOrigin + halfBase);
|
cr.lineTo(x2, Math.max(y1 + borderRadius, this._arrowOrigin) + halfBase);
|
||||||
|
} else if (this._arrowOrigin > (y2 - (borderRadius + halfBase))) {
|
||||||
|
cr.lineTo(x2, Math.min(y2 - borderRadius, this._arrowOrigin) - halfBase);
|
||||||
|
cr.lineTo(x2 + rise, this._arrowOrigin);
|
||||||
|
} else {
|
||||||
|
cr.lineTo(x2, this._arrowOrigin - halfBase);
|
||||||
|
cr.lineTo(x2 + rise, this._arrowOrigin);
|
||||||
|
cr.lineTo(x2, this._arrowOrigin + halfBase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cr.lineTo(boxWidth - halfBorder, boxHeight - borderRadius);
|
|
||||||
|
|
||||||
cr.arc(boxWidth - borderRadius - halfBorder, boxHeight - borderRadius - halfBorder, borderRadius,
|
cr.lineTo(x2, y2 - borderRadius);
|
||||||
|
|
||||||
|
// bottom-right corner
|
||||||
|
cr.arc(x2 - borderRadius, y2 - borderRadius, borderRadius,
|
||||||
0, Math.PI/2);
|
0, Math.PI/2);
|
||||||
|
|
||||||
if (this._arrowSide == St.Side.BOTTOM) {
|
if (this._arrowSide == St.Side.BOTTOM) {
|
||||||
cr.lineTo(this._arrowOrigin + halfBase, boxHeight - halfBorder);
|
if (this._arrowOrigin < (x1 + (borderRadius + halfBase))) {
|
||||||
cr.lineTo(this._arrowOrigin, boxHeight - halfBorder + rise);
|
cr.lineTo(Math.max(x1 + borderRadius, this._arrowOrigin) + halfBase, y2);
|
||||||
cr.lineTo(this._arrowOrigin - halfBase, boxHeight - halfBorder);
|
cr.lineTo(this._arrowOrigin, y2 + rise);
|
||||||
|
} else if (this._arrowOrigin > (x2 - (borderRadius + halfBase))) {
|
||||||
|
cr.lineTo(this._arrowOrigin, y2 + rise);
|
||||||
|
cr.lineTo(Math.min(x2 - borderRadius, this._arrowOrigin) - halfBase, y2);
|
||||||
|
} else {
|
||||||
|
cr.lineTo(this._arrowOrigin + halfBase, y2);
|
||||||
|
cr.lineTo(this._arrowOrigin, y2 + rise);
|
||||||
|
cr.lineTo(this._arrowOrigin - halfBase, y2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cr.lineTo(borderRadius, boxHeight - halfBorder);
|
|
||||||
|
|
||||||
cr.arc(borderRadius + halfBorder, boxHeight - borderRadius - halfBorder, borderRadius,
|
cr.lineTo(x1 + borderRadius, y2);
|
||||||
|
|
||||||
|
// bottom-left corner
|
||||||
|
cr.arc(x1 + borderRadius, y2 - borderRadius, borderRadius,
|
||||||
Math.PI/2, Math.PI);
|
Math.PI/2, Math.PI);
|
||||||
|
|
||||||
if (this._arrowSide == St.Side.LEFT) {
|
if (this._arrowSide == St.Side.LEFT) {
|
||||||
cr.lineTo(halfBorder, this._arrowOrigin + halfBase);
|
if (this._arrowOrigin < (y1 + (borderRadius + halfBase))) {
|
||||||
cr.lineTo(halfBorder - rise, this._arrowOrigin);
|
cr.lineTo(x1, Math.max(y1 + borderRadius, this._arrowOrigin) + halfBase);
|
||||||
cr.lineTo(halfBorder, this._arrowOrigin - halfBase);
|
cr.lineTo(x1 - rise, this._arrowOrigin);
|
||||||
|
} else if (this._arrowOrigin > (y2 - (borderRadius + halfBase))) {
|
||||||
|
cr.lineTo(x1 - rise, this._arrowOrigin);
|
||||||
|
cr.lineTo(x1, Math.min(y2 - borderRadius, this._arrowOrigin) - halfBase);
|
||||||
|
} else {
|
||||||
|
cr.lineTo(x1, this._arrowOrigin + halfBase);
|
||||||
|
cr.lineTo(x1 - rise, this._arrowOrigin);
|
||||||
|
cr.lineTo(x1, this._arrowOrigin - halfBase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cr.lineTo(halfBorder, borderRadius);
|
|
||||||
|
|
||||||
cr.arc(borderRadius + halfBorder, borderRadius + halfBorder, borderRadius,
|
cr.lineTo(x1, y1 + borderRadius);
|
||||||
|
|
||||||
|
// top-left corner
|
||||||
|
cr.arc(x1 + borderRadius, y1 + borderRadius, borderRadius,
|
||||||
Math.PI, 3*Math.PI/2);
|
Math.PI, 3*Math.PI/2);
|
||||||
|
|
||||||
Clutter.cairo_set_source_color(cr, backgroundColor);
|
Clutter.cairo_set_source_color(cr, backgroundColor);
|
||||||
@ -261,39 +305,67 @@ BoxPointer.prototype = {
|
|||||||
cr.stroke();
|
cr.stroke();
|
||||||
},
|
},
|
||||||
|
|
||||||
setPosition: function(sourceActor, gap, alignment) {
|
setPosition: function(sourceActor, alignment) {
|
||||||
// We need to show it now to force an allocation,
|
// We need to show it now to force an allocation,
|
||||||
// so that we can query the correct size.
|
// so that we can query the correct size.
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
|
|
||||||
// Position correctly relative to the sourceActor
|
this._sourceActor = sourceActor;
|
||||||
let [sourceX, sourceY] = sourceActor.get_transformed_position();
|
this._arrowAlignment = alignment;
|
||||||
let [sourceWidth, sourceHeight] = sourceActor.get_transformed_size();
|
|
||||||
|
|
||||||
|
this._reposition(sourceActor, alignment);
|
||||||
|
},
|
||||||
|
|
||||||
|
setSourceAlignment: function(alignment) {
|
||||||
|
this._sourceAlignment = alignment;
|
||||||
|
|
||||||
|
if (!this._sourceActor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We need to show it now to force an allocation,
|
||||||
|
// so that we can query the correct size.
|
||||||
|
this.actor.show();
|
||||||
|
|
||||||
|
this._reposition(this._sourceActor, this._arrowAlignment);
|
||||||
|
},
|
||||||
|
|
||||||
|
_reposition: function(sourceActor, alignment) {
|
||||||
|
// Position correctly relative to the sourceActor
|
||||||
|
let sourceNode = sourceActor.get_theme_node();
|
||||||
|
let sourceContentBox = sourceNode.get_content_box(sourceActor.get_allocation_box());
|
||||||
|
let sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
|
||||||
|
let sourceCenterX = sourceAllocation.x1 + sourceContentBox.x1 + (sourceContentBox.x2 - sourceContentBox.x1) * this._sourceAlignment;
|
||||||
|
let sourceCenterY = sourceAllocation.y1 + sourceContentBox.y1 + (sourceContentBox.y2 - sourceContentBox.y1) * this._sourceAlignment;
|
||||||
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
|
||||||
|
|
||||||
// We also want to keep it onscreen, and separated from the
|
// We also want to keep it onscreen, and separated from the
|
||||||
// edge by the same distance as the main part of the box is
|
// edge by the same distance as the main part of the box is
|
||||||
// separated from its sourceActor
|
// separated from its sourceActor
|
||||||
let primary = global.get_primary_monitor();
|
let monitor = Main.layoutManager.findMonitorForActor(sourceActor);
|
||||||
let themeNode = this.actor.get_theme_node();
|
let themeNode = this.actor.get_theme_node();
|
||||||
let arrowRise = themeNode.get_length('-arrow-rise');
|
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||||
|
let arrowBase = themeNode.get_length('-arrow-base');
|
||||||
let borderRadius = themeNode.get_length('-arrow-border-radius');
|
let borderRadius = themeNode.get_length('-arrow-border-radius');
|
||||||
|
let margin = (4 * borderRadius + borderWidth + arrowBase);
|
||||||
|
let halfMargin = margin / 2;
|
||||||
|
|
||||||
|
let themeNode = this.actor.get_theme_node();
|
||||||
|
let gap = themeNode.get_length('-boxpointer-gap');
|
||||||
|
|
||||||
let resX, resY;
|
let resX, resY;
|
||||||
|
|
||||||
switch (this._arrowSide) {
|
switch (this._arrowSide) {
|
||||||
case St.Side.TOP:
|
case St.Side.TOP:
|
||||||
resY = sourceY + sourceHeight + gap;
|
resY = sourceAllocation.y2 + gap;
|
||||||
break;
|
break;
|
||||||
case St.Side.BOTTOM:
|
case St.Side.BOTTOM:
|
||||||
resY = sourceY - natHeight - gap;
|
resY = sourceAllocation.y1 - natHeight - gap;
|
||||||
break;
|
break;
|
||||||
case St.Side.LEFT:
|
case St.Side.LEFT:
|
||||||
resX = sourceX + sourceWidth + gap;
|
resX = sourceAllocation.x2 + gap;
|
||||||
break;
|
break;
|
||||||
case St.Side.RIGHT:
|
case St.Side.RIGHT:
|
||||||
resX = sourceX - natWidth - gap;
|
resX = sourceAllocation.x1 - natWidth - gap;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,42 +374,21 @@ BoxPointer.prototype = {
|
|||||||
switch (this._arrowSide) {
|
switch (this._arrowSide) {
|
||||||
case St.Side.TOP:
|
case St.Side.TOP:
|
||||||
case St.Side.BOTTOM:
|
case St.Side.BOTTOM:
|
||||||
switch (alignment) {
|
resX = sourceCenterX - (halfMargin + (natWidth - margin) * alignment);
|
||||||
case St.Align.START:
|
|
||||||
resX = sourceX - 2 * borderRadius;
|
|
||||||
break;
|
|
||||||
case St.Align.MIDDLE:
|
|
||||||
resX = sourceX - Math.floor((natWidth - sourceWidth) / 2);
|
|
||||||
break;
|
|
||||||
case St.Align.END:
|
|
||||||
resX = sourceX - (natWidth - sourceWidth) + 2 * borderRadius;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
resX = Math.min(resX, primary.x + primary.width - natWidth - arrowRise - gap);
|
resX = Math.max(resX, monitor.x + 10);
|
||||||
resX = Math.max(resX, primary.x);
|
resX = Math.min(resX, monitor.x + monitor.width - (10 + natWidth));
|
||||||
|
this.setArrowOrigin(sourceCenterX - resX);
|
||||||
this.setArrowOrigin((sourceX - resX) + Math.floor(sourceWidth / 2));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case St.Side.LEFT:
|
case St.Side.LEFT:
|
||||||
case St.Side.RIGHT:
|
case St.Side.RIGHT:
|
||||||
switch (alignment) {
|
resY = sourceCenterY - (halfMargin + (natHeight - margin) * alignment);
|
||||||
case St.Align.START:
|
|
||||||
resY = sourceY - 2 * borderRadius;
|
|
||||||
break;
|
|
||||||
case St.Align.MIDDLE:
|
|
||||||
resY = sourceY - Math.floor((natHeight - sourceHeight) / 2);
|
|
||||||
break;
|
|
||||||
case St.Align.END:
|
|
||||||
resY = sourceY - (natHeight - sourceHeight) + 2 * borderRadius;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
resY = Math.min(resY, primary.y + primary.height - natHeight - arrowRise - gap);
|
resY = Math.max(resY, monitor.y + 10);
|
||||||
resY = Math.max(resY, primary.y);
|
resY = Math.min(resY, monitor.y + monitor.height - (10 + natHeight));
|
||||||
|
|
||||||
this.setArrowOrigin((sourceY - resY) + Math.floor(sourceHeight / 2));
|
this.setArrowOrigin(sourceCenterY - resY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,9 +399,9 @@ BoxPointer.prototype = {
|
|||||||
parent = parent.get_parent();
|
parent = parent.get_parent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actually set the position
|
this._xPosition = Math.floor(x);
|
||||||
this.actor.x = Math.floor(x);
|
this._yPosition = Math.floor(y);
|
||||||
this.actor.y = Math.floor(y);
|
this._shiftActor();
|
||||||
},
|
},
|
||||||
|
|
||||||
// @origin: Coordinate specifying middle of the arrow, along
|
// @origin: Coordinate specifying middle of the arrow, along
|
||||||
@ -361,5 +412,42 @@ BoxPointer.prototype = {
|
|||||||
this._arrowOrigin = origin;
|
this._arrowOrigin = origin;
|
||||||
this._border.queue_repaint();
|
this._border.queue_repaint();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_shiftActor : function() {
|
||||||
|
// Since the position of the BoxPointer depends on the allocated size
|
||||||
|
// of the BoxPointer and the position of the source actor, trying
|
||||||
|
// to position the BoxPoiner via the x/y properties will result in
|
||||||
|
// allocation loops and warnings. Instead we do the positioning via
|
||||||
|
// the anchor point, which is independent of allocation, and leave
|
||||||
|
// x == y == 0.
|
||||||
|
this.actor.set_anchor_point(-(this._xPosition + this._xOffset),
|
||||||
|
-(this._yPosition + this._yOffset));
|
||||||
|
},
|
||||||
|
|
||||||
|
set xOffset(offset) {
|
||||||
|
this._xOffset = offset;
|
||||||
|
this._shiftActor();
|
||||||
|
},
|
||||||
|
|
||||||
|
get xOffset() {
|
||||||
|
return this._xOffset;
|
||||||
|
},
|
||||||
|
|
||||||
|
set yOffset(offset) {
|
||||||
|
this._yOffset = offset;
|
||||||
|
this._shiftActor();
|
||||||
|
},
|
||||||
|
|
||||||
|
get yOffset() {
|
||||||
|
return this._yOffset;
|
||||||
|
},
|
||||||
|
|
||||||
|
set opacity(opacity) {
|
||||||
|
this.actor.opacity = opacity;
|
||||||
|
},
|
||||||
|
|
||||||
|
get opacity() {
|
||||||
|
return this.actor.opacity;
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
@ -1,22 +1,83 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
const Signals = imports.signals;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
const Gettext_gtk30 = imports.gettext.domain('gtk30');
|
const Gettext_gtk30 = imports.gettext.domain('gtk30');
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||||
const WEEKDATE_HEADER_WIDTH_DIGITS = 3;
|
const WEEKDATE_HEADER_WIDTH_DIGITS = 3;
|
||||||
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||||
|
|
||||||
|
// in org.gnome.desktop.interface
|
||||||
|
const CLOCK_FORMAT_KEY = 'clock-format';
|
||||||
|
|
||||||
function _sameDay(dateA, dateB) {
|
function _sameDay(dateA, dateB) {
|
||||||
return (dateA.getDate() == dateB.getDate() &&
|
return (dateA.getDate() == dateB.getDate() &&
|
||||||
dateA.getMonth() == dateB.getMonth() &&
|
dateA.getMonth() == dateB.getMonth() &&
|
||||||
dateA.getYear() == dateB.getYear());
|
dateA.getYear() == dateB.getYear());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _sameYear(dateA, dateB) {
|
||||||
|
return (dateA.getYear() == dateB.getYear());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: maybe needs config - right now we assume that Saturday and
|
||||||
|
* Sunday are non-work days (not true in e.g. Israel, it's Sunday and
|
||||||
|
* Monday there)
|
||||||
|
*/
|
||||||
|
function _isWorkDay(date) {
|
||||||
|
return date.getDay() != 0 && date.getDay() != 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getBeginningOfDay(date) {
|
||||||
|
let ret = new Date(date.getTime());
|
||||||
|
ret.setHours(0);
|
||||||
|
ret.setMinutes(0);
|
||||||
|
ret.setSeconds(0);
|
||||||
|
ret.setMilliseconds(0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getEndOfDay(date) {
|
||||||
|
let ret = new Date(date.getTime());
|
||||||
|
ret.setHours(23);
|
||||||
|
ret.setMinutes(59);
|
||||||
|
ret.setSeconds(59);
|
||||||
|
ret.setMilliseconds(999);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _formatEventTime(event, clockFormat) {
|
||||||
|
let ret;
|
||||||
|
if (event.allDay) {
|
||||||
|
/* Translators: Shown in calendar event list for all day events
|
||||||
|
* Keep it short, best if you can use less then 10 characters
|
||||||
|
*/
|
||||||
|
ret = C_("event list time", "All Day");
|
||||||
|
} else {
|
||||||
|
switch (clockFormat) {
|
||||||
|
case '24h':
|
||||||
|
/* Translators: Shown in calendar event list, if 24h format */
|
||||||
|
ret = event.date.toLocaleFormat(C_("event list time", "%H:%M"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* explicit fall-through */
|
||||||
|
case '12h':
|
||||||
|
/* Transators: Shown in calendar event list, if 12h format */
|
||||||
|
ret = event.date.toLocaleFormat(C_("event list time", "%l:%M %p"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
function _getCalendarWeekForDate(date) {
|
function _getCalendarWeekForDate(date) {
|
||||||
// Based on the algorithms found here:
|
// Based on the algorithms found here:
|
||||||
// http://en.wikipedia.org/wiki/Talk:ISO_week_date
|
// http://en.wikipedia.org/wiki/Talk:ISO_week_date
|
||||||
@ -43,16 +104,259 @@ function _getDigitWidth(actor){
|
|||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Calendar() {
|
function _getCalendarDayAbbreviation(dayNumber) {
|
||||||
this._init();
|
let abbreviations = [
|
||||||
|
/* Translators: Calendar grid abbreviation for Sunday.
|
||||||
|
*
|
||||||
|
* NOTE: These grid abbreviations are always shown together
|
||||||
|
* and in order, e.g. "S M T W T F S".
|
||||||
|
*/
|
||||||
|
C_("grid sunday", "S"),
|
||||||
|
/* Translators: Calendar grid abbreviation for Monday */
|
||||||
|
C_("grid monday", "M"),
|
||||||
|
/* Translators: Calendar grid abbreviation for Tuesday */
|
||||||
|
C_("grid tuesday", "T"),
|
||||||
|
/* Translators: Calendar grid abbreviation for Wednesday */
|
||||||
|
C_("grid wednesday", "W"),
|
||||||
|
/* Translators: Calendar grid abbreviation for Thursday */
|
||||||
|
C_("grid thursday", "T"),
|
||||||
|
/* Translators: Calendar grid abbreviation for Friday */
|
||||||
|
C_("grid friday", "F"),
|
||||||
|
/* Translators: Calendar grid abbreviation for Saturday */
|
||||||
|
C_("grid saturday", "S")
|
||||||
|
];
|
||||||
|
return abbreviations[dayNumber];
|
||||||
}
|
}
|
||||||
|
|
||||||
Calendar.prototype = {
|
function _getEventDayAbbreviation(dayNumber) {
|
||||||
|
let abbreviations = [
|
||||||
|
/* Translators: Event list abbreviation for Sunday.
|
||||||
|
*
|
||||||
|
* NOTE: These list abbreviations are normally not shown together
|
||||||
|
* so they need to be unique (e.g. Tuesday and Thursday cannot
|
||||||
|
* both be 'T').
|
||||||
|
*/
|
||||||
|
C_("list sunday", "Su"),
|
||||||
|
/* Translators: Event list abbreviation for Monday */
|
||||||
|
C_("list monday", "M"),
|
||||||
|
/* Translators: Event list abbreviation for Tuesday */
|
||||||
|
C_("list tuesday", "T"),
|
||||||
|
/* Translators: Event list abbreviation for Wednesday */
|
||||||
|
C_("list wednesday", "W"),
|
||||||
|
/* Translators: Event list abbreviation for Thursday */
|
||||||
|
C_("list thursday", "Th"),
|
||||||
|
/* Translators: Event list abbreviation for Friday */
|
||||||
|
C_("list friday", "F"),
|
||||||
|
/* Translators: Event list abbreviation for Saturday */
|
||||||
|
C_("list saturday", "S")
|
||||||
|
];
|
||||||
|
return abbreviations[dayNumber];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abstraction for an appointment/event in a calendar
|
||||||
|
|
||||||
|
const CalendarEvent = new Lang.Class({
|
||||||
|
Name: 'CalendarEvent',
|
||||||
|
|
||||||
|
_init: function(date, end, summary, allDay) {
|
||||||
|
this.date = date;
|
||||||
|
this.end = end;
|
||||||
|
this.summary = summary;
|
||||||
|
this.allDay = allDay;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Interface for appointments/events - e.g. the contents of a calendar
|
||||||
|
//
|
||||||
|
|
||||||
|
// First, an implementation with no events
|
||||||
|
const EmptyEventSource = new Lang.Class({
|
||||||
|
Name: 'EmptyEventSource',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
// FIXME: This is actually the fallback method for GTK+ for the week start;
|
},
|
||||||
// GTK+ by preference uses nl_langinfo (NL_TIME_FIRST_WEEKDAY). We probably
|
|
||||||
// should add a C function so we can do the full handling.
|
requestRange: function(begin, end) {
|
||||||
this._weekStart = NaN;
|
},
|
||||||
|
|
||||||
|
getEvents: function(begin, end) {
|
||||||
|
let result = [];
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
hasEvents: function(day) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(EmptyEventSource.prototype);
|
||||||
|
|
||||||
|
const CalendarServerIface = <interface name="org.gnome.Shell.CalendarServer">
|
||||||
|
<method name="GetEvents">
|
||||||
|
<arg type="x" direction="in" />
|
||||||
|
<arg type="x" direction="in" />
|
||||||
|
<arg type="b" direction="in" />
|
||||||
|
<arg type="a(sssbxxa{sv})" direction="out" />
|
||||||
|
</method>
|
||||||
|
<signal name="Changed" />
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const CalendarServerInfo = Gio.DBusInterfaceInfo.new_for_xml(CalendarServerIface);
|
||||||
|
|
||||||
|
function CalendarServer() {
|
||||||
|
var self = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
|
||||||
|
g_interface_name: CalendarServerInfo.name,
|
||||||
|
g_interface_info: CalendarServerInfo,
|
||||||
|
g_name: 'org.gnome.Shell.CalendarServer',
|
||||||
|
g_object_path: '/org/gnome/Shell/CalendarServer',
|
||||||
|
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
||||||
|
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||||
|
|
||||||
|
self.init(null);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _datesEqual(a, b) {
|
||||||
|
if (a < b)
|
||||||
|
return false;
|
||||||
|
else if (a > b)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _dateIntervalsOverlap(a0, a1, b0, b1)
|
||||||
|
{
|
||||||
|
if (a1 <= b0)
|
||||||
|
return false;
|
||||||
|
else if (b1 <= a0)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// an implementation that reads data from a session bus service
|
||||||
|
const DBusEventSource = new Lang.Class({
|
||||||
|
Name: 'DBusEventSource',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._resetCache();
|
||||||
|
|
||||||
|
this._dbusProxy = new CalendarServer();
|
||||||
|
this._dbusProxy.connectSignal('Changed', Lang.bind(this, this._onChanged));
|
||||||
|
|
||||||
|
this._dbusProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
|
||||||
|
if (this._dbusProxy.g_name_owner)
|
||||||
|
this._onNameAppeared();
|
||||||
|
else
|
||||||
|
this._onNameVanished();
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_resetCache: function() {
|
||||||
|
this._events = [];
|
||||||
|
this._lastRequestBegin = null;
|
||||||
|
this._lastRequestEnd = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onNameAppeared: function(owner) {
|
||||||
|
this._resetCache();
|
||||||
|
this._loadEvents(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onNameVanished: function(oldOwner) {
|
||||||
|
this._resetCache();
|
||||||
|
this.emit('changed');
|
||||||
|
},
|
||||||
|
|
||||||
|
_onChanged: function() {
|
||||||
|
this._loadEvents(false);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onEventsReceived: function([appointments]) {
|
||||||
|
let newEvents = [];
|
||||||
|
if (appointments != null) {
|
||||||
|
for (let n = 0; n < appointments.length; n++) {
|
||||||
|
let a = appointments[n];
|
||||||
|
let date = new Date(a[4] * 1000);
|
||||||
|
let end = new Date(a[5] * 1000);
|
||||||
|
let summary = a[1];
|
||||||
|
let allDay = a[3];
|
||||||
|
let event = new CalendarEvent(date, end, summary, allDay);
|
||||||
|
newEvents.push(event);
|
||||||
|
}
|
||||||
|
newEvents.sort(function(event1, event2) {
|
||||||
|
return event1.date.getTime() - event2.date.getTime();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this._events = newEvents;
|
||||||
|
this.emit('changed');
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadEvents: function(forceReload) {
|
||||||
|
if (this._curRequestBegin && this._curRequestEnd){
|
||||||
|
let callFlags = Gio.DBusCallFlags.NO_AUTO_START;
|
||||||
|
if (forceReload)
|
||||||
|
callFlags = Gio.DBusCallFlags.NONE;
|
||||||
|
this._dbusProxy.GetEventsRemote(this._curRequestBegin.getTime() / 1000,
|
||||||
|
this._curRequestEnd.getTime() / 1000,
|
||||||
|
forceReload,
|
||||||
|
Lang.bind(this, this._onEventsReceived),
|
||||||
|
callFlags);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
requestRange: function(begin, end, forceReload) {
|
||||||
|
if (forceReload || !(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
|
||||||
|
this._lastRequestBegin = begin;
|
||||||
|
this._lastRequestEnd = end;
|
||||||
|
this._curRequestBegin = begin;
|
||||||
|
this._curRequestEnd = end;
|
||||||
|
this._loadEvents(forceReload);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getEvents: function(begin, end) {
|
||||||
|
let result = [];
|
||||||
|
for(let n = 0; n < this._events.length; n++) {
|
||||||
|
let event = this._events[n];
|
||||||
|
if (_dateIntervalsOverlap (event.date, event.end, begin, end)) {
|
||||||
|
result.push(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
hasEvents: function(day) {
|
||||||
|
let dayBegin = _getBeginningOfDay(day);
|
||||||
|
let dayEnd = _getEndOfDay(day);
|
||||||
|
|
||||||
|
let events = this.getEvents(dayBegin, dayEnd);
|
||||||
|
|
||||||
|
if (events.length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(DBusEventSource.prototype);
|
||||||
|
|
||||||
|
// Calendar:
|
||||||
|
// @eventSource: is an object implementing the EventSource API, e.g. the
|
||||||
|
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
|
||||||
|
const Calendar = new Lang.Class({
|
||||||
|
Name: 'Calendar',
|
||||||
|
|
||||||
|
_init: function(eventSource) {
|
||||||
|
if (eventSource) {
|
||||||
|
this._eventSource = eventSource;
|
||||||
|
|
||||||
|
this._eventSource.connect('changed', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._update(false);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
this._weekStart = Shell.util_get_week_start();
|
||||||
this._weekdate = NaN;
|
this._weekdate = NaN;
|
||||||
this._digitWidth = NaN;
|
this._digitWidth = NaN;
|
||||||
this._settings = new Gio.Settings({ schema: 'org.gnome.shell.calendar' });
|
this._settings = new Gio.Settings({ schema: 'org.gnome.shell.calendar' });
|
||||||
@ -60,17 +364,8 @@ Calendar.prototype = {
|
|||||||
this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
|
this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
|
||||||
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
|
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
|
||||||
|
|
||||||
let weekStartString = Gettext_gtk30.gettext('calendar:week_start:0');
|
|
||||||
if (weekStartString.indexOf('calendar:week_start:') == 0) {
|
|
||||||
this._weekStart = parseInt(weekStartString.substring(20));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNaN(this._weekStart) || this._weekStart < 0 || this._weekStart > 6) {
|
|
||||||
log('Translation of "calendar:week_start:0" in GTK+ is not correct');
|
|
||||||
this._weekStart = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the ordering for month/year in the calendar heading
|
// Find the ordering for month/year in the calendar heading
|
||||||
|
this._headerFormatWithoutYear = '%B';
|
||||||
switch (Gettext_gtk30.gettext('calendar:MY')) {
|
switch (Gettext_gtk30.gettext('calendar:MY')) {
|
||||||
case 'calendar:MY':
|
case 'calendar:MY':
|
||||||
this._headerFormat = '%B %Y';
|
this._headerFormat = '%B %Y';
|
||||||
@ -85,7 +380,7 @@ Calendar.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start off with the current date
|
// Start off with the current date
|
||||||
this.date = new Date();
|
this._selectedDate = new Date();
|
||||||
|
|
||||||
this.actor = new St.Table({ homogeneous: false,
|
this.actor = new St.Table({ homogeneous: false,
|
||||||
style_class: 'calendar',
|
style_class: 'calendar',
|
||||||
@ -95,14 +390,17 @@ Calendar.prototype = {
|
|||||||
Lang.bind(this, this._onScroll));
|
Lang.bind(this, this._onScroll));
|
||||||
|
|
||||||
this._buildHeader ();
|
this._buildHeader ();
|
||||||
this._update();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Sets the calendar to show a specific date
|
// Sets the calendar to show a specific date
|
||||||
setDate: function(date) {
|
setDate: function(date, forceReload) {
|
||||||
if (!_sameDay(date, this.date)) {
|
if (!_sameDay(date, this._selectedDate)) {
|
||||||
this.date = date;
|
this._selectedDate = date;
|
||||||
this._update();
|
this._update(forceReload);
|
||||||
|
this.emit('selected-date-changed', new Date(this._selectedDate));
|
||||||
|
} else {
|
||||||
|
if (forceReload)
|
||||||
|
this._update(forceReload);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -116,45 +414,36 @@ Calendar.prototype = {
|
|||||||
{ row: 0, col: 0, col_span: offsetCols + 7 });
|
{ row: 0, col: 0, col_span: offsetCols + 7 });
|
||||||
|
|
||||||
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChange));
|
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' });
|
let back = new St.Button({ style_class: 'calendar-change-month-back' });
|
||||||
this._topBox.add(back);
|
this._topBox.add(back);
|
||||||
back.connect('clicked', Lang.bind(this, this._prevMonth));
|
back.connect('clicked', Lang.bind(this, this._onPrevMonthButtonClicked));
|
||||||
|
|
||||||
this._dateLabel = new St.Label();
|
this._monthLabel = new St.Label({style_class: 'calendar-month-label'});
|
||||||
this._topBox.add(this._dateLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE });
|
this._topBox.add(this._monthLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
let forward = new St.Button({ label: forwardlabel, style_class: 'calendar-change-month' });
|
let forward = new St.Button({ style_class: 'calendar-change-month-forward' });
|
||||||
this._topBox.add(forward);
|
this._topBox.add(forward);
|
||||||
forward.connect('clicked', Lang.bind(this, this._nextMonth));
|
forward.connect('clicked', Lang.bind(this, this._onNextMonthButtonClicked));
|
||||||
|
|
||||||
|
// Add weekday labels...
|
||||||
|
//
|
||||||
// We need to figure out the abbreviated localized names for the days of the week;
|
// 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
|
// 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
|
// them in the right cell in the table. It doesn't matter if we add them in order
|
||||||
let iter = new Date(this.date);
|
let iter = new Date(this._selectedDate);
|
||||||
iter.setSeconds(0); // Leap second protection. Hah!
|
iter.setSeconds(0); // Leap second protection. Hah!
|
||||||
iter.setHours(12);
|
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++) {
|
for (let i = 0; i < 7; i++) {
|
||||||
this.actor.add(new St.Label({ text: iter.toLocaleFormat('%a') }),
|
// Could use iter.toLocaleFormat('%a') but that normally gives three characters
|
||||||
|
// and we want, ideally, a single character for e.g. S M T W T F S
|
||||||
|
let customDayAbbrev = _getCalendarDayAbbreviation(iter.getDay());
|
||||||
|
let label = new St.Label({ style_class: 'calendar-day-base calendar-day-heading',
|
||||||
|
text: customDayAbbrev });
|
||||||
|
this.actor.add(label,
|
||||||
{ row: 1,
|
{ row: 1,
|
||||||
col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7,
|
col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7,
|
||||||
x_fill: false, x_align: St.Align.END });
|
x_fill: false, x_align: St.Align.MIDDLE });
|
||||||
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,43 +467,72 @@ Calendar.prototype = {
|
|||||||
switch (event.get_scroll_direction()) {
|
switch (event.get_scroll_direction()) {
|
||||||
case Clutter.ScrollDirection.UP:
|
case Clutter.ScrollDirection.UP:
|
||||||
case Clutter.ScrollDirection.LEFT:
|
case Clutter.ScrollDirection.LEFT:
|
||||||
this._prevMonth();
|
this._onPrevMonthButtonClicked();
|
||||||
break;
|
break;
|
||||||
case Clutter.ScrollDirection.DOWN:
|
case Clutter.ScrollDirection.DOWN:
|
||||||
case Clutter.ScrollDirection.RIGHT:
|
case Clutter.ScrollDirection.RIGHT:
|
||||||
this._nextMonth();
|
this._onNextMonthButtonClicked();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_prevMonth: function() {
|
_onPrevMonthButtonClicked: function() {
|
||||||
if (this.date.getMonth() == 0) {
|
let newDate = new Date(this._selectedDate);
|
||||||
this.date.setMonth(11);
|
let oldMonth = newDate.getMonth();
|
||||||
this.date.setFullYear(this.date.getFullYear() - 1);
|
if (oldMonth == 0) {
|
||||||
} else {
|
newDate.setMonth(11);
|
||||||
this.date.setMonth(this.date.getMonth() - 1);
|
newDate.setFullYear(newDate.getFullYear() - 1);
|
||||||
|
if (newDate.getMonth() != 11) {
|
||||||
|
let day = 32 - new Date(newDate.getFullYear() - 1, 11, 32).getDate();
|
||||||
|
newDate = new Date(newDate.getFullYear() - 1, 11, day);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this._update();
|
else {
|
||||||
|
newDate.setMonth(oldMonth - 1);
|
||||||
|
if (newDate.getMonth() != oldMonth - 1) {
|
||||||
|
let day = 32 - new Date(newDate.getFullYear(), oldMonth - 1, 32).getDate();
|
||||||
|
newDate = new Date(newDate.getFullYear(), oldMonth - 1, day);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setDate(newDate, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_nextMonth: function() {
|
_onNextMonthButtonClicked: function() {
|
||||||
if (this.date.getMonth() == 11) {
|
let newDate = new Date(this._selectedDate);
|
||||||
this.date.setMonth(0);
|
let oldMonth = newDate.getMonth();
|
||||||
this.date.setFullYear(this.date.getFullYear() + 1);
|
if (oldMonth == 11) {
|
||||||
} else {
|
newDate.setMonth(0);
|
||||||
this.date.setMonth(this.date.getMonth() + 1);
|
newDate.setFullYear(newDate.getFullYear() + 1);
|
||||||
|
if (newDate.getMonth() != 0) {
|
||||||
|
let day = 32 - new Date(newDate.getFullYear() + 1, 0, 32).getDate();
|
||||||
|
newDate = new Date(newDate.getFullYear() + 1, 0, day);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this._update();
|
else {
|
||||||
|
newDate.setMonth(oldMonth + 1);
|
||||||
|
if (newDate.getMonth() != oldMonth + 1) {
|
||||||
|
let day = 32 - new Date(newDate.getFullYear(), oldMonth + 1, 32).getDate();
|
||||||
|
newDate = new Date(newDate.getFullYear(), oldMonth + 1, day);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setDate(newDate, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onSettingsChange: function() {
|
_onSettingsChange: function() {
|
||||||
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
|
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
|
||||||
this._buildHeader();
|
this._buildHeader();
|
||||||
this._update();
|
this._update(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_update: function() {
|
_update: function(forceReload) {
|
||||||
this._dateLabel.text = this.date.toLocaleFormat(this._headerFormat);
|
let now = new Date();
|
||||||
|
|
||||||
|
if (_sameYear(this._selectedDate, now))
|
||||||
|
this._monthLabel.text = this._selectedDate.toLocaleFormat(this._headerFormatWithoutYear);
|
||||||
|
else
|
||||||
|
this._monthLabel.text = this._selectedDate.toLocaleFormat(this._headerFormat);
|
||||||
|
|
||||||
// Remove everything but the topBox and the weekday labels
|
// Remove everything but the topBox and the weekday labels
|
||||||
let children = this.actor.get_children();
|
let children = this.actor.get_children();
|
||||||
@ -222,45 +540,212 @@ Calendar.prototype = {
|
|||||||
children[i].destroy();
|
children[i].destroy();
|
||||||
|
|
||||||
// Start at the beginning of the week before the start of the month
|
// Start at the beginning of the week before the start of the month
|
||||||
let iter = new Date(this.date);
|
let beginDate = new Date(this._selectedDate);
|
||||||
iter.setDate(1);
|
beginDate.setDate(1);
|
||||||
iter.setSeconds(0);
|
beginDate.setSeconds(0);
|
||||||
iter.setHours(12);
|
beginDate.setHours(12);
|
||||||
let daysToWeekStart = (7 + iter.getDay() - this._weekStart) % 7;
|
let daysToWeekStart = (7 + beginDate.getDay() - this._weekStart) % 7;
|
||||||
iter.setTime(iter.getTime() - daysToWeekStart * MSECS_IN_DAY);
|
beginDate.setTime(beginDate.getTime() - daysToWeekStart * MSECS_IN_DAY);
|
||||||
|
|
||||||
let now = new Date();
|
|
||||||
|
|
||||||
|
let iter = new Date(beginDate);
|
||||||
let row = 2;
|
let row = 2;
|
||||||
while (true) {
|
while (true) {
|
||||||
let label = new St.Label({ text: iter.getDate().toString() });
|
let button = new St.Button({ label: iter.getDate().toString() });
|
||||||
if (_sameDay(now, iter))
|
|
||||||
label.style_class = 'calendar-day calendar-today';
|
if (!this._eventSource)
|
||||||
else if (iter.getMonth() != this.date.getMonth())
|
button.reactive = false;
|
||||||
label.style_class = 'calendar-day calendar-other-month-day';
|
|
||||||
|
let iterStr = iter.toUTCString();
|
||||||
|
button.connect('clicked', Lang.bind(this, function() {
|
||||||
|
let newlySelectedDate = new Date(iterStr);
|
||||||
|
this.setDate(newlySelectedDate, false);
|
||||||
|
}));
|
||||||
|
|
||||||
|
let hasEvents = this._eventSource && this._eventSource.hasEvents(iter);
|
||||||
|
let styleClass = 'calendar-day-base calendar-day';
|
||||||
|
if (_isWorkDay(iter))
|
||||||
|
styleClass += ' calendar-work-day'
|
||||||
else
|
else
|
||||||
label.style_class = 'calendar-day';
|
styleClass += ' calendar-nonwork-day'
|
||||||
|
|
||||||
|
// Hack used in lieu of border-collapse - see gnome-shell.css
|
||||||
|
if (row == 2)
|
||||||
|
styleClass = 'calendar-day-top ' + styleClass;
|
||||||
|
if (iter.getDay() == this._weekStart)
|
||||||
|
styleClass = 'calendar-day-left ' + styleClass;
|
||||||
|
|
||||||
|
if (_sameDay(now, iter))
|
||||||
|
styleClass += ' calendar-today';
|
||||||
|
else if (iter.getMonth() != this._selectedDate.getMonth())
|
||||||
|
styleClass += ' calendar-other-month-day';
|
||||||
|
|
||||||
|
if (_sameDay(this._selectedDate, iter))
|
||||||
|
button.add_style_pseudo_class('active');
|
||||||
|
|
||||||
|
if (hasEvents)
|
||||||
|
styleClass += ' calendar-day-with-events'
|
||||||
|
|
||||||
|
button.style_class = styleClass;
|
||||||
|
|
||||||
let offsetCols = this._useWeekdate ? 1 : 0;
|
let offsetCols = this._useWeekdate ? 1 : 0;
|
||||||
this.actor.add(label,
|
this.actor.add(button,
|
||||||
{ row: row, col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7,
|
{ row: row, col: offsetCols + (7 + iter.getDay() - this._weekStart) % 7 });
|
||||||
x_fill: false, x_align: St.Align.END });
|
|
||||||
|
|
||||||
if (this._useWeekdate && iter.getDay() == 4) {
|
if (this._useWeekdate && iter.getDay() == 4) {
|
||||||
let label = new St.Label({ text: _getCalendarWeekForDate(iter).toString(),
|
let label = new St.Label({ text: _getCalendarWeekForDate(iter).toString(),
|
||||||
style_class: 'calendar-day calendar-calendarweek'});
|
style_class: 'calendar-day-base calendar-week-number'});
|
||||||
this.actor.add(label,
|
this.actor.add(label,
|
||||||
{ row: row, col: 0,
|
{ row: row, col: 0, y_align: St.Align.MIDDLE });
|
||||||
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) {
|
||||||
// We stop on the first "first day of the week" after the month we are displaying
|
// We stop on the first "first day of the week" after the month we are displaying
|
||||||
if (iter.getMonth() > this.date.getMonth() || iter.getYear() > this.date.getYear())
|
if (iter.getMonth() > this._selectedDate.getMonth() || iter.getYear() > this._selectedDate.getYear())
|
||||||
break;
|
break;
|
||||||
row++;
|
row++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Signal to the event source that we are interested in events
|
||||||
|
// only from this date range
|
||||||
|
if (this._eventSource)
|
||||||
|
this._eventSource.requestRange(beginDate, iter, forceReload);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
|
Signals.addSignalMethods(Calendar.prototype);
|
||||||
|
|
||||||
|
const EventsList = new Lang.Class({
|
||||||
|
Name: 'EventsList',
|
||||||
|
|
||||||
|
_init: function(eventSource) {
|
||||||
|
this.actor = new St.BoxLayout({ vertical: true, style_class: 'events-header-vbox'});
|
||||||
|
this._date = new Date();
|
||||||
|
this._eventSource = eventSource;
|
||||||
|
this._eventSource.connect('changed', Lang.bind(this, this._update));
|
||||||
|
this._desktopSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
|
||||||
|
this._desktopSettings.connect('changed', Lang.bind(this, this._update));
|
||||||
|
this._weekStart = Shell.util_get_week_start();
|
||||||
|
|
||||||
|
this._update();
|
||||||
|
},
|
||||||
|
|
||||||
|
_addEvent: function(dayNameBox, timeBox, eventTitleBox, includeDayName, day, time, desc) {
|
||||||
|
if (includeDayName) {
|
||||||
|
dayNameBox.add(new St.Label( { style_class: 'events-day-dayname',
|
||||||
|
text: day } ),
|
||||||
|
{ x_fill: true } );
|
||||||
|
}
|
||||||
|
timeBox.add(new St.Label( { style_class: 'events-day-time',
|
||||||
|
text: time} ),
|
||||||
|
{ x_fill: true } );
|
||||||
|
eventTitleBox.add(new St.Label( { style_class: 'events-day-task',
|
||||||
|
text: desc} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
_addPeriod: function(header, begin, end, includeDayName, showNothingScheduled) {
|
||||||
|
if (!this._eventSource)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let events = this._eventSource.getEvents(begin, end);
|
||||||
|
|
||||||
|
let clockFormat = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);;
|
||||||
|
|
||||||
|
if (events.length == 0 && !showNothingScheduled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let vbox = new St.BoxLayout( {vertical: true} );
|
||||||
|
this.actor.add(vbox);
|
||||||
|
|
||||||
|
vbox.add(new St.Label({ style_class: 'events-day-header', text: header }));
|
||||||
|
let box = new St.BoxLayout({style_class: 'events-header-hbox'});
|
||||||
|
let dayNameBox = new St.BoxLayout({ vertical: true, style_class: 'events-day-name-box' });
|
||||||
|
let timeBox = new St.BoxLayout({ vertical: true, style_class: 'events-time-box' });
|
||||||
|
let eventTitleBox = new St.BoxLayout({ vertical: true, style_class: 'events-event-box' });
|
||||||
|
box.add(dayNameBox, {x_fill: false});
|
||||||
|
box.add(timeBox, {x_fill: false});
|
||||||
|
box.add(eventTitleBox, {expand: true});
|
||||||
|
vbox.add(box);
|
||||||
|
|
||||||
|
for (let n = 0; n < events.length; n++) {
|
||||||
|
let event = events[n];
|
||||||
|
let dayString = _getEventDayAbbreviation(event.date.getDay());
|
||||||
|
let timeString = _formatEventTime(event, clockFormat);
|
||||||
|
let summaryString = event.summary;
|
||||||
|
this._addEvent(dayNameBox, timeBox, eventTitleBox, includeDayName, dayString, timeString, summaryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (events.length == 0 && showNothingScheduled) {
|
||||||
|
let now = new Date();
|
||||||
|
/* Translators: Text to show if there are no events */
|
||||||
|
let nothingEvent = new CalendarEvent(now, now, _("Nothing Scheduled"), true);
|
||||||
|
let timeString = _formatEventTime(nothingEvent, clockFormat);
|
||||||
|
this._addEvent(dayNameBox, timeBox, eventTitleBox, false, "", timeString, nothingEvent.summary);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_showOtherDay: function(day) {
|
||||||
|
this.actor.destroy_children();
|
||||||
|
|
||||||
|
let dayBegin = _getBeginningOfDay(day);
|
||||||
|
let dayEnd = _getEndOfDay(day);
|
||||||
|
|
||||||
|
let dayString;
|
||||||
|
let now = new Date();
|
||||||
|
if (_sameYear(day, now))
|
||||||
|
/* Translators: Shown on calendar heading when selected day occurs on current year */
|
||||||
|
dayString = day.toLocaleFormat(C_("calendar heading", "%A, %B %d"));
|
||||||
|
else
|
||||||
|
/* Translators: Shown on calendar heading when selected day occurs on different year */
|
||||||
|
dayString = day.toLocaleFormat(C_("calendar heading", "%A, %B %d, %Y"));
|
||||||
|
this._addPeriod(dayString, dayBegin, dayEnd, false, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_showToday: function() {
|
||||||
|
this.actor.destroy_children();
|
||||||
|
|
||||||
|
let now = new Date();
|
||||||
|
let dayBegin = _getBeginningOfDay(now);
|
||||||
|
let dayEnd = _getEndOfDay(now);
|
||||||
|
this._addPeriod(_("Today"), dayBegin, dayEnd, false, true);
|
||||||
|
|
||||||
|
let tomorrowBegin = new Date(dayBegin.getTime() + 86400 * 1000);
|
||||||
|
let tomorrowEnd = new Date(dayEnd.getTime() + 86400 * 1000);
|
||||||
|
this._addPeriod(_("Tomorrow"), tomorrowBegin, tomorrowEnd, false, true);
|
||||||
|
|
||||||
|
if (dayEnd.getDay() <= 4 + this._weekStart) {
|
||||||
|
/* If now is within the first 5 days we show "This week" and
|
||||||
|
* include events up until and including Saturday/Sunday
|
||||||
|
* (depending on whether a week starts on Sunday/Monday).
|
||||||
|
*/
|
||||||
|
let thisWeekBegin = new Date(dayBegin.getTime() + 2 * 86400 * 1000);
|
||||||
|
let thisWeekEnd = new Date(dayEnd.getTime() + (6 + this._weekStart - dayEnd.getDay()) * 86400 * 1000);
|
||||||
|
this._addPeriod(_("This week"), thisWeekBegin, thisWeekEnd, true, false);
|
||||||
|
} else {
|
||||||
|
/* otherwise it's one of the two last days of the week ... show
|
||||||
|
* "Next week" and include events up until and including *next*
|
||||||
|
* Saturday/Sunday
|
||||||
|
*/
|
||||||
|
let nextWeekBegin = new Date(dayBegin.getTime() + 2 * 86400 * 1000);
|
||||||
|
let nextWeekEnd = new Date(dayEnd.getTime() + (13 + this._weekStart - dayEnd.getDay()) * 86400 * 1000);
|
||||||
|
this._addPeriod(_("Next week"), nextWeekBegin, nextWeekEnd, true, false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Sets the event list to show events from a specific date
|
||||||
|
setDate: function(date) {
|
||||||
|
if (!_sameDay(date, this._date)) {
|
||||||
|
this._date = date;
|
||||||
|
this._update();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_update: function() {
|
||||||
|
let today = new Date();
|
||||||
|
if (_sameDay (this._date, today)) {
|
||||||
|
this._showToday();
|
||||||
|
} else {
|
||||||
|
this._showOtherDay(this._date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
364
js/ui/chrome.js
@ -1,364 +0,0 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Mainloop = imports.mainloop;
|
|
||||||
const Meta = imports.gi.Meta;
|
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const Signals = imports.signals;
|
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
|
||||||
const Params = imports.misc.params;
|
|
||||||
|
|
||||||
// This manages the shell "chrome"; the UI that's visible in the
|
|
||||||
// normal mode (ie, outside the Overview), that surrounds the main
|
|
||||||
// workspace content.
|
|
||||||
|
|
||||||
const Visibility = {
|
|
||||||
FULL: 1,
|
|
||||||
FULLSCREEN: 2,
|
|
||||||
OVERVIEW: 3
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultParams = {
|
|
||||||
visibleInOverview: false,
|
|
||||||
visibleInFullscreen: false,
|
|
||||||
affectsStruts: true,
|
|
||||||
affectsInputRegion: true
|
|
||||||
};
|
|
||||||
|
|
||||||
function Chrome() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
Chrome.prototype = {
|
|
||||||
_init: function() {
|
|
||||||
// The group itself has zero size so it doesn't interfere with DND
|
|
||||||
this.actor = new Shell.GenericContainer({ width: 0, height: 0 });
|
|
||||||
Main.uiGroup.add_actor(this.actor);
|
|
||||||
this.actor.connect('allocate', Lang.bind(this, this._allocated));
|
|
||||||
|
|
||||||
this._inFullscreen = false;
|
|
||||||
this._inOverview = false;
|
|
||||||
this.visibility = Visibility.FULL;
|
|
||||||
|
|
||||||
this._trackedActors = [];
|
|
||||||
|
|
||||||
global.screen.connect('restacked',
|
|
||||||
Lang.bind(this, this._windowsRestacked));
|
|
||||||
|
|
||||||
// Need to update struts on new workspaces when they are added
|
|
||||||
global.screen.connect('notify::n-workspaces',
|
|
||||||
Lang.bind(this, this._queueUpdateRegions));
|
|
||||||
|
|
||||||
Main.overview.connect('showing',
|
|
||||||
Lang.bind(this, this._overviewShowing));
|
|
||||||
Main.overview.connect('hidden',
|
|
||||||
Lang.bind(this, this._overviewHidden));
|
|
||||||
|
|
||||||
this._queueUpdateRegions();
|
|
||||||
},
|
|
||||||
|
|
||||||
_allocated: function(actor, box, flags) {
|
|
||||||
let children = this.actor.get_children();
|
|
||||||
for (let i = 0; i < children.length; i++)
|
|
||||||
children[i].allocate_preferred_size(flags);
|
|
||||||
},
|
|
||||||
|
|
||||||
// addActor:
|
|
||||||
// @actor: an actor to add to the chrome layer
|
|
||||||
// @params: (optional) additional params
|
|
||||||
//
|
|
||||||
// Adds @actor to the chrome layer and extends the input region
|
|
||||||
// and window manager struts to include it. (Window manager struts
|
|
||||||
// will only be affected if @actor is touching a screen edge.)
|
|
||||||
// Changes in @actor's size and position will automatically result
|
|
||||||
// in appropriate changes to the input region and struts. Changes
|
|
||||||
// in its visibility will affect the input region, but NOT the
|
|
||||||
// struts.
|
|
||||||
//
|
|
||||||
// If %visibleInOverview is %true in @params, @actor will remain
|
|
||||||
// visible when the overview is brought up. Otherwise it will
|
|
||||||
// automatically be hidden. Likewise, if %visibleInFullscreen is
|
|
||||||
// %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) {
|
|
||||||
this.actor.add_actor(actor);
|
|
||||||
this._trackActor(actor, params);
|
|
||||||
},
|
|
||||||
|
|
||||||
// trackActor:
|
|
||||||
// @actor: a descendant of the chrome to begin tracking
|
|
||||||
// @params: parameters describing how to track @actor
|
|
||||||
//
|
|
||||||
// Tells the chrome to track @actor, which must be a descendant
|
|
||||||
// of an actor added via addActor(). This can be used to extend the
|
|
||||||
// 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) {
|
|
||||||
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');
|
|
||||||
|
|
||||||
let ancestorData = this._trackedActors[index];
|
|
||||||
if (!params)
|
|
||||||
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:
|
|
||||||
// @actor: an actor previously tracked via trackActor()
|
|
||||||
//
|
|
||||||
// Undoes the effect of trackActor()
|
|
||||||
untrackActor: function(actor) {
|
|
||||||
this._untrackActor(actor);
|
|
||||||
},
|
|
||||||
|
|
||||||
// removeActor:
|
|
||||||
// @actor: a child of the chrome layer
|
|
||||||
//
|
|
||||||
// Removes @actor from the chrome layer
|
|
||||||
removeActor: function(actor) {
|
|
||||||
this.actor.remove_actor(actor);
|
|
||||||
this._untrackActor(actor);
|
|
||||||
},
|
|
||||||
|
|
||||||
_findActor: function(actor) {
|
|
||||||
for (let i = 0; i < this._trackedActors.length; i++) {
|
|
||||||
let actorData = this._trackedActors[i];
|
|
||||||
if (actorData.actor == actor)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
},
|
|
||||||
|
|
||||||
_trackActor: function(actor, params) {
|
|
||||||
if (this._findActor(actor) != -1)
|
|
||||||
throw new Error('trying to re-track existing chrome actor');
|
|
||||||
|
|
||||||
let actorData = Params.parse(params, defaultParams);
|
|
||||||
actorData.actor = actor;
|
|
||||||
actorData.visibleId = actor.connect('notify::visible',
|
|
||||||
Lang.bind(this, this._queueUpdateRegions));
|
|
||||||
actorData.allocationId = actor.connect('notify::allocation',
|
|
||||||
Lang.bind(this, this._queueUpdateRegions));
|
|
||||||
actorData.parentSetId = actor.connect('parent-set',
|
|
||||||
Lang.bind(this, this._actorReparented));
|
|
||||||
// Note that destroying actor will unset its parent, so we don't
|
|
||||||
// need to connect to 'destroy' too.
|
|
||||||
|
|
||||||
this._trackedActors.push(actorData);
|
|
||||||
this._queueUpdateRegions();
|
|
||||||
},
|
|
||||||
|
|
||||||
_untrackActor: function(actor) {
|
|
||||||
let i = this._findActor(actor);
|
|
||||||
|
|
||||||
if (i == -1)
|
|
||||||
return;
|
|
||||||
let actorData = this._trackedActors[i];
|
|
||||||
|
|
||||||
this._trackedActors.splice(i, 1);
|
|
||||||
actor.disconnect(actorData.visibleId);
|
|
||||||
actor.disconnect(actorData.allocationId);
|
|
||||||
actor.disconnect(actorData.parentSetId);
|
|
||||||
|
|
||||||
this._queueUpdateRegions();
|
|
||||||
},
|
|
||||||
|
|
||||||
_actorReparented: function(actor, oldParent) {
|
|
||||||
if (!this.actor.contains(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() {
|
|
||||||
this._inOverview = true;
|
|
||||||
this._updateVisibility();
|
|
||||||
this._queueUpdateRegions();
|
|
||||||
},
|
|
||||||
|
|
||||||
_overviewHidden: function() {
|
|
||||||
this._inOverview = false;
|
|
||||||
this._updateVisibility();
|
|
||||||
this._queueUpdateRegions();
|
|
||||||
},
|
|
||||||
|
|
||||||
_queueUpdateRegions: function() {
|
|
||||||
if (!this._updateRegionIdle)
|
|
||||||
this._updateRegionIdle = Mainloop.idle_add(Lang.bind(this, this._updateRegions),
|
|
||||||
Meta.PRIORITY_BEFORE_REDRAW);
|
|
||||||
},
|
|
||||||
|
|
||||||
_windowsRestacked: function() {
|
|
||||||
let windows = global.get_window_actors();
|
|
||||||
let primary = global.get_primary_monitor();
|
|
||||||
|
|
||||||
// The chrome layer should be visible unless there is a window
|
|
||||||
// with layer FULLSCREEN, or a window with layer
|
|
||||||
// OVERRIDE_REDIRECT that covers the whole screen.
|
|
||||||
// ('override_redirect' is not actually a layer above all
|
|
||||||
// other windows, but this seems to be how mutter treats it
|
|
||||||
// currently...) If we wanted to be extra clever, we could
|
|
||||||
// figure out when an OVERRIDE_REDIRECT window was trying to
|
|
||||||
// partially overlap us, and then adjust the input region and
|
|
||||||
// our clip region accordingly...
|
|
||||||
|
|
||||||
// @windows is sorted bottom to top.
|
|
||||||
|
|
||||||
let wasInFullscreen = this._inFullscreen;
|
|
||||||
this._inFullscreen = false;
|
|
||||||
for (let i = windows.length - 1; i > -1; i--) {
|
|
||||||
let layer = windows[i].get_meta_window().get_layer();
|
|
||||||
|
|
||||||
// There are 3 cases we check here for:
|
|
||||||
// 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 &&
|
|
||||||
windows[i].x + windows[i].width >= primary.x + primary.width &&
|
|
||||||
windows[i].y <= primary.y &&
|
|
||||||
windows[i].y + windows[i].height >= primary.y + primary.height) {
|
|
||||||
this._inFullscreen = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._inFullscreen != wasInFullscreen) {
|
|
||||||
this._updateVisibility();
|
|
||||||
this._queueUpdateRegions();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateRegions: function() {
|
|
||||||
let rects = [], struts = [], i;
|
|
||||||
|
|
||||||
delete this._updateRegionIdle;
|
|
||||||
|
|
||||||
for (i = 0; i < this._trackedActors.length; i++) {
|
|
||||||
let actorData = this._trackedActors[i];
|
|
||||||
if (!actorData.affectsInputRegion && !actorData.affectsStruts)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
let [x, y] = actorData.actor.get_transformed_position();
|
|
||||||
let [w, h] = actorData.actor.get_transformed_size();
|
|
||||||
x = Math.round(x);
|
|
||||||
y = Math.round(y);
|
|
||||||
w = Math.round(w);
|
|
||||||
h = Math.round(h);
|
|
||||||
let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h});
|
|
||||||
|
|
||||||
if (actorData.affectsInputRegion &&
|
|
||||||
actorData.actor.get_paint_visibility() &&
|
|
||||||
!this.actor.get_skip_paint(actorData.actor))
|
|
||||||
rects.push(rect);
|
|
||||||
|
|
||||||
if (!actorData.affectsStruts)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Metacity wants to know what side of the screen the
|
|
||||||
// strut is considered to be attached to. If the actor is
|
|
||||||
// only touching one edge, or is touching the entire
|
|
||||||
// width/height of one edge, then it's obvious which side
|
|
||||||
// to call it. If it's in a corner, we pick a side
|
|
||||||
// arbitrarily. If it doesn't touch any edges, or it spans
|
|
||||||
// the width/height across the middle of the screen, then
|
|
||||||
// we don't create a strut for it at all.
|
|
||||||
let side;
|
|
||||||
if (w >= global.screen_width) {
|
|
||||||
if (y <= 0)
|
|
||||||
side = Meta.Side.TOP;
|
|
||||||
else if (y + h >= global.screen_height)
|
|
||||||
side = Meta.Side.BOTTOM;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
} else if (h >= global.screen_height) {
|
|
||||||
if (x <= 0)
|
|
||||||
side = Meta.Side.LEFT;
|
|
||||||
else if (x + w >= global.screen_width)
|
|
||||||
side = Meta.Side.RIGHT;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
} else if (x <= 0)
|
|
||||||
side = Meta.Side.LEFT;
|
|
||||||
else if (y <= 0)
|
|
||||||
side = Meta.Side.TOP;
|
|
||||||
else if (x + w >= global.screen_width)
|
|
||||||
side = Meta.Side.RIGHT;
|
|
||||||
else if (y + h >= global.screen_height)
|
|
||||||
side = Meta.Side.BOTTOM;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
let strut = new Meta.Strut({ rect: rect, side: side });
|
|
||||||
struts.push(strut);
|
|
||||||
}
|
|
||||||
|
|
||||||
global.set_stage_input_region(rects);
|
|
||||||
|
|
||||||
let screen = global.screen;
|
|
||||||
for (let w = 0; w < screen.n_workspaces; w++) {
|
|
||||||
let workspace = screen.get_workspace_by_index(w);
|
|
||||||
workspace.set_builtin_struts(struts);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Signals.addSignalMethods(Chrome.prototype);
|
|
180
js/ui/contactDisplay.js
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Folks = imports.gi.Folks
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Util = imports.misc.util;
|
||||||
|
const IconGrid = imports.ui.iconGrid;
|
||||||
|
const Search = imports.ui.search;
|
||||||
|
const SearchDisplay = imports.ui.searchDisplay;
|
||||||
|
|
||||||
|
const MAX_SEARCH_RESULTS_ROWS = 1;
|
||||||
|
const ICON_SIZE = 81;
|
||||||
|
|
||||||
|
function launchContact(id) {
|
||||||
|
Util.spawn(['gnome-contacts', '-i', id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This class represents a shown contact search result in the overview */
|
||||||
|
const Contact = new Lang.Class({
|
||||||
|
Name: 'Contact',
|
||||||
|
|
||||||
|
_init: function(id) {
|
||||||
|
this._contactSys = Shell.ContactSystem.get_default();
|
||||||
|
this.individual = this._contactSys.get_individual(id);
|
||||||
|
|
||||||
|
this.actor = new St.Bin({ style_class: 'contact',
|
||||||
|
reactive: true,
|
||||||
|
track_hover: true });
|
||||||
|
|
||||||
|
let content = new St.BoxLayout( { style_class: 'contact-content',
|
||||||
|
vertical: false });
|
||||||
|
this.actor.set_child(content);
|
||||||
|
|
||||||
|
let icon = new St.Icon({ icon_type: St.IconType.FULLCOLOR,
|
||||||
|
icon_size: ICON_SIZE,
|
||||||
|
style_class: 'contact-icon' });
|
||||||
|
if (this.individual.avatar != null)
|
||||||
|
icon.gicon = this.individual.avatar;
|
||||||
|
else
|
||||||
|
icon.icon_name = 'avatar-default';
|
||||||
|
|
||||||
|
content.add(icon, { x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
|
let details = new St.BoxLayout({ style_class: 'contact-details',
|
||||||
|
vertical: true });
|
||||||
|
content.add(details, { x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
|
let email = this._contactSys.get_email_for_display(this.individual);
|
||||||
|
let aliasText = this.individual.alias ||
|
||||||
|
this.individual.full_name ||
|
||||||
|
this.individual.nickname ||
|
||||||
|
email ||
|
||||||
|
_("Unknown");
|
||||||
|
let aliasLabel = new St.Label({ text: aliasText,
|
||||||
|
style_class: 'contact-details-alias' });
|
||||||
|
details.add(aliasLabel, { x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
let presence = this._createPresence(this.individual.presence_type);
|
||||||
|
details.add(presence, { x_fill: false,
|
||||||
|
y_fill: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.END });
|
||||||
|
},
|
||||||
|
|
||||||
|
_createPresence: function(presence) {
|
||||||
|
let text;
|
||||||
|
let iconName;
|
||||||
|
|
||||||
|
switch(presence) {
|
||||||
|
case Folks.PresenceType.AVAILABLE:
|
||||||
|
text = _("Available");
|
||||||
|
iconName = 'user-available';
|
||||||
|
break;
|
||||||
|
case Folks.PresenceType.AWAY:
|
||||||
|
case Folks.PresenceType.EXTENDED_AWAY:
|
||||||
|
text = _("Away");
|
||||||
|
iconName = 'user-away';
|
||||||
|
break;
|
||||||
|
case Folks.PresenceType.BUSY:
|
||||||
|
text = _("Busy");
|
||||||
|
iconName = 'user-busy';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
text = _("Offline");
|
||||||
|
iconName = 'user-offline';
|
||||||
|
}
|
||||||
|
|
||||||
|
let icon = new St.Icon({ icon_name: iconName,
|
||||||
|
icon_type: St.IconType.FULLCOLOR,
|
||||||
|
icon_size: 16,
|
||||||
|
style_class: 'contact-details-status-icon' });
|
||||||
|
let label = new St.Label({ text: text });
|
||||||
|
|
||||||
|
let box = new St.BoxLayout({ vertical: false,
|
||||||
|
style_class: 'contact-details-status' });
|
||||||
|
box.add(icon, { x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
box.add(label, { x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.END,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
return box;
|
||||||
|
},
|
||||||
|
|
||||||
|
createIcon: function(size) {
|
||||||
|
let tc = St.TextureCache.get_default();
|
||||||
|
let icon = this.individual.avatar;
|
||||||
|
|
||||||
|
if (icon != null) {
|
||||||
|
return tc.load_gicon(null, icon, size);
|
||||||
|
} else {
|
||||||
|
return tc.load_icon_name(null, 'avatar-default', St.IconType.FULLCOLOR, size);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/* Searches for and returns contacts */
|
||||||
|
const ContactSearchProvider = new Lang.Class({
|
||||||
|
Name: 'ContactSearchProvider',
|
||||||
|
Extends: Search.SearchProvider,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent(_("CONTACTS"));
|
||||||
|
this._contactSys = Shell.ContactSystem.get_default();
|
||||||
|
},
|
||||||
|
|
||||||
|
getResultMeta: function(id) {
|
||||||
|
let contact = new Contact(id);
|
||||||
|
return { 'id': id,
|
||||||
|
'name': contact.alias,
|
||||||
|
'createIcon': function(size) {
|
||||||
|
return contact.createIcon(size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialResultSet: function(terms) {
|
||||||
|
return this._contactSys.initial_search(terms);
|
||||||
|
},
|
||||||
|
|
||||||
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
|
return this._contactSys.subsearch(previousResults, terms);
|
||||||
|
},
|
||||||
|
|
||||||
|
createResultActor: function(resultMeta, terms) {
|
||||||
|
let contact = new Contact(resultMeta.id);
|
||||||
|
return contact.actor;
|
||||||
|
},
|
||||||
|
|
||||||
|
createResultContainerActor: function() {
|
||||||
|
let grid = new IconGrid.IconGrid({ rowLimit: MAX_SEARCH_RESULTS_ROWS,
|
||||||
|
xAlign: St.Align.START });
|
||||||
|
grid.actor.style_class = 'contact-grid';
|
||||||
|
|
||||||
|
let actor = new SearchDisplay.GridSearchResults(this, grid);
|
||||||
|
return actor;
|
||||||
|
},
|
||||||
|
|
||||||
|
activateResult: function(id, params) {
|
||||||
|
launchContact(id);
|
||||||
|
}
|
||||||
|
});
|
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gdk = imports.gi.Gdk;
|
const Gdk = imports.gi.Gdk;
|
||||||
@ -10,27 +10,36 @@ const St = imports.gi.St;
|
|||||||
|
|
||||||
const AltTab = imports.ui.altTab;
|
const AltTab = imports.ui.altTab;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const Params = imports.misc.params;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const POPUP_APPICON_SIZE = 96;
|
const POPUP_APPICON_SIZE = 96;
|
||||||
const POPUP_FADE_TIME = 0.1; // seconds
|
const POPUP_FADE_TIME = 0.1; // seconds
|
||||||
|
|
||||||
function CtrlAltTabManager() {
|
const SortGroup = {
|
||||||
this._init();
|
TOP: 0,
|
||||||
}
|
MIDDLE: 1,
|
||||||
|
BOTTOM: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
const CtrlAltTabManager = new Lang.Class({
|
||||||
|
Name: 'CtrlAltTabManager',
|
||||||
|
|
||||||
CtrlAltTabManager.prototype = {
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._items = [];
|
this._items = [];
|
||||||
this._focusManager = St.FocusManager.get_for_stage(global.stage);
|
this._focusManager = St.FocusManager.get_for_stage(global.stage);
|
||||||
Main.wm.setKeybindingHandler('switch_panels', Lang.bind(this,
|
|
||||||
function (shellwm, binding, window, backwards) {
|
|
||||||
this.popup(backwards);
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
addGroup: function(root, name, icon) {
|
addGroup: function(root, name, icon, params) {
|
||||||
this._items.push({ root: root, name: name, iconName: icon });
|
let item = Params.parse(params, { sortGroup: SortGroup.MIDDLE,
|
||||||
|
proxy: root,
|
||||||
|
focusCallback: null });
|
||||||
|
|
||||||
|
item.root = root;
|
||||||
|
item.name = name;
|
||||||
|
item.iconName = icon;
|
||||||
|
|
||||||
|
this._items.push(item);
|
||||||
root.connect('destroy', Lang.bind(this, function() { this.removeGroup(root); }));
|
root.connect('destroy', Lang.bind(this, function() { this.removeGroup(root); }));
|
||||||
this._focusManager.add_group(root);
|
this._focusManager.add_group(root);
|
||||||
},
|
},
|
||||||
@ -45,71 +54,146 @@ CtrlAltTabManager.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
focusGroup: function(root) {
|
focusGroup: function(item) {
|
||||||
if (global.stage_input_mode == Shell.StageInputMode.NONREACTIVE ||
|
if (global.stage_input_mode == Shell.StageInputMode.NONREACTIVE ||
|
||||||
global.stage_input_mode == Shell.StageInputMode.NORMAL)
|
global.stage_input_mode == Shell.StageInputMode.NORMAL)
|
||||||
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
|
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
|
||||||
root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
|
||||||
|
if (item.window)
|
||||||
|
Main.activateWindow(item.window);
|
||||||
|
else if (item.focusCallback)
|
||||||
|
item.focusCallback();
|
||||||
|
else
|
||||||
|
item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
popup: function(backwards) {
|
// Sort the items into a consistent order; panel first, tray last,
|
||||||
|
// and everything else in between, sorted by X coordinate, so that
|
||||||
|
// they will have the same left-to-right ordering in the
|
||||||
|
// Ctrl-Alt-Tab dialog as they do onscreen.
|
||||||
|
_sortItems: function(a, b) {
|
||||||
|
if (a.sortGroup != b.sortGroup)
|
||||||
|
return a.sortGroup - b.sortGroup;
|
||||||
|
|
||||||
|
let y;
|
||||||
|
if (a.x == undefined) {
|
||||||
|
if (a.window)
|
||||||
|
a.x = a.window.get_compositor_private().x;
|
||||||
|
else
|
||||||
|
[a.x, y] = a.proxy.get_transformed_position();
|
||||||
|
}
|
||||||
|
if (b.x == undefined) {
|
||||||
|
if (b.window)
|
||||||
|
b.x = b.window.get_compositor_private().x;
|
||||||
|
else
|
||||||
|
[b.x, y] = b.proxy.get_transformed_position();
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.x - b.x;
|
||||||
|
},
|
||||||
|
|
||||||
|
popup: function(backwards, mask) {
|
||||||
// Start with the set of focus groups that are currently mapped
|
// Start with the set of focus groups that are currently mapped
|
||||||
let items = this._items.filter(function (item) { return item.root.mapped; });
|
let items = this._items.filter(function (item) { return item.proxy.mapped; });
|
||||||
|
|
||||||
// And add the windows metacity would show in its Ctrl-Alt-Tab list
|
// And add the windows metacity would show in its Ctrl-Alt-Tab list
|
||||||
let screen = global.screen;
|
if (!Main.overview.visible) {
|
||||||
let display = screen.get_display();
|
let screen = global.screen;
|
||||||
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ());
|
let display = screen.get_display();
|
||||||
let windowTracker = Shell.WindowTracker.get_default();
|
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ());
|
||||||
let textureCache = St.TextureCache.get_default();
|
let windowTracker = Shell.WindowTracker.get_default();
|
||||||
for (let i = 0; i < windows.length; i++) {
|
let textureCache = St.TextureCache.get_default();
|
||||||
let icon;
|
for (let i = 0; i < windows.length; i++) {
|
||||||
let app = windowTracker.get_window_app(windows[i]);
|
let icon;
|
||||||
if (app)
|
let app = windowTracker.get_window_app(windows[i]);
|
||||||
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
|
if (app)
|
||||||
else
|
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
|
||||||
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
else
|
||||||
items.push({ window: windows[i],
|
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
||||||
name: windows[i].title,
|
items.push({ window: windows[i],
|
||||||
iconActor: icon });
|
name: windows[i].title,
|
||||||
|
iconActor: icon,
|
||||||
|
sortGroup: SortGroup.MIDDLE });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!items.length)
|
if (!items.length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
new CtrlAltTabPopup().show(items, backwards);
|
items.sort(Lang.bind(this, this._sortItems));
|
||||||
|
|
||||||
|
if (!this._popup) {
|
||||||
|
this._popup = new CtrlAltTabPopup();
|
||||||
|
this._popup.show(items, backwards, mask);
|
||||||
|
|
||||||
|
this._popup.actor.connect('destroy',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._popup = null;
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function mod(a, b) {
|
function mod(a, b) {
|
||||||
return (a + b) % b;
|
return (a + b) % b;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CtrlAltTabPopup() {
|
const CtrlAltTabPopup = new Lang.Class({
|
||||||
this._init();
|
Name: 'CtrlAltTabPopup',
|
||||||
}
|
|
||||||
|
|
||||||
CtrlAltTabPopup.prototype = {
|
|
||||||
_init : function() {
|
_init : function() {
|
||||||
let primary = global.get_primary_monitor();
|
this.actor = new Shell.GenericContainer({ name: 'ctrlAltTabPopup',
|
||||||
this.actor = new St.BoxLayout({ name: 'ctrlAltTabPopup',
|
reactive: true });
|
||||||
reactive: true,
|
|
||||||
x: primary.x + primary.width / 2,
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
y: primary.y + primary.height / 2,
|
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
anchor_gravity: Clutter.Gravity.CENTER });
|
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._modifierMask = 0;
|
||||||
this._selection = 0;
|
this._selection = 0;
|
||||||
|
|
||||||
Main.uiGroup.add_actor(this.actor);
|
Main.uiGroup.add_actor(this.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
show : function(items, startBackwards) {
|
_getPreferredWidth: function (actor, forHeight, alloc) {
|
||||||
|
let primary = Main.layoutManager.primaryMonitor;
|
||||||
|
|
||||||
|
alloc.min_size = primary.width;
|
||||||
|
alloc.natural_size = primary.width;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||||
|
let primary = Main.layoutManager.primaryMonitor;
|
||||||
|
|
||||||
|
alloc.min_size = primary.height;
|
||||||
|
alloc.natural_size = primary.height;
|
||||||
|
},
|
||||||
|
|
||||||
|
_allocate: function (actor, box, flags) {
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
let primary = Main.layoutManager.primaryMonitor;
|
||||||
|
|
||||||
|
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
||||||
|
let vPadding = this.actor.get_theme_node().get_vertical_padding();
|
||||||
|
let hPadding = this.actor.get_theme_node().get_horizontal_padding();
|
||||||
|
|
||||||
|
let [childMinHeight, childNaturalHeight] = this._switcher.actor.get_preferred_height(primary.width - hPadding);
|
||||||
|
let [childMinWidth, childNaturalWidth] = this._switcher.actor.get_preferred_width(childNaturalHeight);
|
||||||
|
childBox.x1 = Math.max(primary.x + leftPadding, primary.x + Math.floor((primary.width - childNaturalWidth) / 2));
|
||||||
|
childBox.x2 = Math.min(primary.x + primary.width - hPadding, childBox.x1 + childNaturalWidth);
|
||||||
|
childBox.y1 = primary.y + Math.floor((primary.height - childNaturalHeight) / 2);
|
||||||
|
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||||
|
this._switcher.actor.allocate(childBox, flags);
|
||||||
|
},
|
||||||
|
|
||||||
|
show : function(items, startBackwards, mask) {
|
||||||
if (!Main.pushModal(this.actor))
|
if (!Main.pushModal(this.actor))
|
||||||
return false;
|
return false;
|
||||||
this._haveModal = true;
|
this._haveModal = true;
|
||||||
|
this._modifierMask = AltTab.primaryModifier(mask);
|
||||||
|
|
||||||
this._keyPressEventId = this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
|
this._keyPressEventId = this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
|
||||||
this._keyReleaseEventId = this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
|
this._keyReleaseEventId = this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
|
||||||
@ -123,7 +207,7 @@ CtrlAltTabPopup.prototype = {
|
|||||||
this._select(this._selection);
|
this._select(this._selection);
|
||||||
|
|
||||||
let [x, y, mods] = global.get_pointer();
|
let [x, y, mods] = global.get_pointer();
|
||||||
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
|
if (!(mods & this._modifierMask)) {
|
||||||
this._finish();
|
this._finish();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -169,7 +253,7 @@ CtrlAltTabPopup.prototype = {
|
|||||||
|
|
||||||
_keyReleaseEvent : function(actor, event) {
|
_keyReleaseEvent : function(actor, event) {
|
||||||
let [x, y, mods] = global.get_pointer();
|
let [x, y, mods] = global.get_pointer();
|
||||||
let state = mods & Clutter.ModifierType.MOD1_MASK;
|
let state = mods & this._modifierMask;
|
||||||
|
|
||||||
if (state == 0)
|
if (state == 0)
|
||||||
this._finish();
|
this._finish();
|
||||||
@ -180,11 +264,7 @@ CtrlAltTabPopup.prototype = {
|
|||||||
_finish : function() {
|
_finish : function() {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
|
|
||||||
let item = this._items[this._selection];
|
Main.ctrlAltTabManager.focusGroup(this._items[this._selection]);
|
||||||
if (item.root)
|
|
||||||
Main.ctrlAltTabManager.focusGroup(item.root);
|
|
||||||
else
|
|
||||||
Main.activateWindow(item.window);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_popModal: function() {
|
_popModal: function() {
|
||||||
@ -208,6 +288,7 @@ CtrlAltTabPopup.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy : function() {
|
_onDestroy : function() {
|
||||||
|
this._popModal();
|
||||||
if (this._keyPressEventId)
|
if (this._keyPressEventId)
|
||||||
this.actor.disconnect(this._keyPressEventId);
|
this.actor.disconnect(this._keyPressEventId);
|
||||||
if (this._keyReleaseEventId)
|
if (this._keyReleaseEventId)
|
||||||
@ -218,17 +299,14 @@ CtrlAltTabPopup.prototype = {
|
|||||||
this._selection = num;
|
this._selection = num;
|
||||||
this._switcher.highlight(num);
|
this._switcher.highlight(num);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
function CtrlAltTabSwitcher(items) {
|
const CtrlAltTabSwitcher = new Lang.Class({
|
||||||
this._init(items);
|
Name: 'CtrlAltTabSwitcher',
|
||||||
}
|
Extends: AltTab.SwitcherList,
|
||||||
|
|
||||||
CtrlAltTabSwitcher.prototype = {
|
|
||||||
__proto__ : AltTab.SwitcherList.prototype,
|
|
||||||
|
|
||||||
_init : function(items) {
|
_init : function(items) {
|
||||||
AltTab.SwitcherList.prototype._init.call(this, true);
|
this.parent(true);
|
||||||
|
|
||||||
for (let i = 0; i < items.length; i++)
|
for (let i = 0; i < items.length; i++)
|
||||||
this._addIcon(items[i]);
|
this._addIcon(items[i]);
|
||||||
@ -249,6 +327,6 @@ CtrlAltTabSwitcher.prototype = {
|
|||||||
let text = new St.Label({ text: item.name });
|
let text = new St.Label({ text: item.name });
|
||||||
box.add(text, { x_fill: false });
|
box.add(text, { x_fill: false });
|
||||||
|
|
||||||
this.addItem(box);
|
this.addItem(box, text);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
590
js/ui/dash.js
@ -1,34 +1,179 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
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 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 AppFavorites = imports.ui.appFavorites;
|
const AppFavorites = imports.ui.appFavorites;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const IconGrid = imports.ui.iconGrid;
|
const IconGrid = imports.ui.iconGrid;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
const Workspace = imports.ui.workspace;
|
const Workspace = imports.ui.workspace;
|
||||||
|
|
||||||
|
const DASH_ANIMATION_TIME = 0.2;
|
||||||
|
|
||||||
function RemoveFavoriteIcon() {
|
// A container like StBin, but taking the child's scale into account
|
||||||
this._init();
|
// when requesting a size
|
||||||
}
|
const DashItemContainer = new Lang.Class({
|
||||||
|
Name: 'DashItemContainer',
|
||||||
|
|
||||||
RemoveFavoriteIcon.prototype = {
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.actor = new St.Bin({ style_class: 'remove-favorite' });
|
this.actor = new Shell.GenericContainer({ style_class: 'dash-item-container' });
|
||||||
|
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.actor._delegate = this;
|
||||||
|
|
||||||
|
this.child = null;
|
||||||
|
this._childScale = 1;
|
||||||
|
this._childOpacity = 255;
|
||||||
|
this.animatingOut = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_allocate: function(actor, box, flags) {
|
||||||
|
if (this.child == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let availWidth = box.x2 - box.x1;
|
||||||
|
let availHeight = box.y2 - box.y1;
|
||||||
|
let [minChildWidth, minChildHeight, natChildWidth, natChildHeight] =
|
||||||
|
this.child.get_preferred_size();
|
||||||
|
let [childScaleX, childScaleY] = this.child.get_scale();
|
||||||
|
|
||||||
|
let childWidth = Math.min(natChildWidth * childScaleX, availWidth);
|
||||||
|
let childHeight = Math.min(natChildHeight * childScaleY, availHeight);
|
||||||
|
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
childBox.x1 = (availWidth - childWidth) / 2;
|
||||||
|
childBox.y1 = (availHeight - childHeight) / 2;
|
||||||
|
childBox.x2 = childBox.x1 + childWidth;
|
||||||
|
childBox.y2 = childBox.y1 + childHeight;
|
||||||
|
|
||||||
|
this.child.allocate(childBox, flags);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||||
|
alloc.min_size = 0;
|
||||||
|
alloc.natural_size = 0;
|
||||||
|
|
||||||
|
if (this.child == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let [minHeight, natHeight] = this.child.get_preferred_height(forWidth);
|
||||||
|
alloc.min_size += minHeight * this.child.scale_y;
|
||||||
|
alloc.natural_size += natHeight * this.child.scale_y;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||||
|
alloc.min_size = 0;
|
||||||
|
alloc.natural_size = 0;
|
||||||
|
|
||||||
|
if (this.child == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let [minWidth, natWidth] = this.child.get_preferred_width(forHeight);
|
||||||
|
alloc.min_size = minWidth * this.child.scale_y;
|
||||||
|
alloc.natural_size = natWidth * this.child.scale_y;
|
||||||
|
},
|
||||||
|
|
||||||
|
setChild: function(actor) {
|
||||||
|
if (this.child == actor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.actor.destroy_children();
|
||||||
|
|
||||||
|
this.child = actor;
|
||||||
|
this.actor.add_actor(this.child);
|
||||||
|
},
|
||||||
|
|
||||||
|
animateIn: function() {
|
||||||
|
if (this.child == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.childScale = 0;
|
||||||
|
this.childOpacity = 0;
|
||||||
|
Tweener.addTween(this,
|
||||||
|
{ childScale: 1.0,
|
||||||
|
childOpacity: 255,
|
||||||
|
time: DASH_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
animateOutAndDestroy: function() {
|
||||||
|
if (this.child == null) {
|
||||||
|
this.actor.destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.animatingOut = true;
|
||||||
|
this.childScale = 1.0;
|
||||||
|
Tweener.addTween(this,
|
||||||
|
{ childScale: 0.0,
|
||||||
|
childOpacity: 0,
|
||||||
|
time: DASH_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this, function() {
|
||||||
|
this.actor.destroy();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
set childScale(scale) {
|
||||||
|
this._childScale = scale;
|
||||||
|
|
||||||
|
if (this.child == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.child.set_scale_with_gravity(scale, scale,
|
||||||
|
Clutter.Gravity.CENTER);
|
||||||
|
this.actor.queue_relayout();
|
||||||
|
},
|
||||||
|
|
||||||
|
get childScale() {
|
||||||
|
return this._childScale;
|
||||||
|
},
|
||||||
|
|
||||||
|
set childOpacity(opacity) {
|
||||||
|
this._childOpacity = opacity;
|
||||||
|
|
||||||
|
if (this.child == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.child.set_opacity(opacity);
|
||||||
|
this.actor.queue_redraw();
|
||||||
|
},
|
||||||
|
|
||||||
|
get childOpacity() {
|
||||||
|
return this._childOpacity;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const RemoveFavoriteIcon = new Lang.Class({
|
||||||
|
Name: 'RemoveFavoriteIcon',
|
||||||
|
Extends: DashItemContainer,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent();
|
||||||
|
|
||||||
|
this._iconBin = new St.Bin({ style_class: 'remove-favorite' });
|
||||||
this._iconActor = null;
|
this._iconActor = null;
|
||||||
this.icon = new IconGrid.BaseIcon(_("Remove"),
|
this.icon = new IconGrid.BaseIcon(_("Remove"),
|
||||||
{ setSizeManually: true,
|
{ setSizeManually: true,
|
||||||
|
showLabel: false,
|
||||||
createIcon: Lang.bind(this, this._createIcon) });
|
createIcon: Lang.bind(this, this._createIcon) });
|
||||||
this.actor.set_child(this.icon.actor);
|
this._iconBin.set_child(this.icon.actor);
|
||||||
this.actor._delegate = this;
|
this._iconBin._delegate = this;
|
||||||
|
|
||||||
|
this.setChild(this._iconBin);
|
||||||
},
|
},
|
||||||
|
|
||||||
_createIcon: function(size) {
|
_createIcon: function(size) {
|
||||||
@ -39,7 +184,7 @@ RemoveFavoriteIcon.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setHover: function(hovered) {
|
setHover: function(hovered) {
|
||||||
this.actor.set_hover(hovered);
|
this._iconBin.set_hover(hovered);
|
||||||
if (this._iconActor)
|
if (this._iconActor)
|
||||||
this._iconActor.set_hover(hovered);
|
this._iconActor.set_hover(hovered);
|
||||||
},
|
},
|
||||||
@ -53,8 +198,8 @@ RemoveFavoriteIcon.prototype = {
|
|||||||
let app = null;
|
let app = null;
|
||||||
if (source instanceof AppDisplay.AppWellIcon) {
|
if (source instanceof AppDisplay.AppWellIcon) {
|
||||||
let appSystem = Shell.AppSystem.get_default();
|
let appSystem = Shell.AppSystem.get_default();
|
||||||
app = appSystem.get_app(source.getId());
|
app = appSystem.lookup_app(source.getId());
|
||||||
} else if (source instanceof Workspace.WindowClone) {
|
} else if (source.metaWindow) {
|
||||||
let tracker = Shell.WindowTracker.get_default();
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
app = tracker.get_window_app(source.metaWindow);
|
app = tracker.get_window_app(source.metaWindow);
|
||||||
}
|
}
|
||||||
@ -69,26 +214,31 @@ RemoveFavoriteIcon.prototype = {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
|
const DragPlaceholderItem = new Lang.Class({
|
||||||
|
Name: 'DragPlaceholderItem',
|
||||||
|
Extends: DashItemContainer,
|
||||||
|
|
||||||
function Dash() {
|
_init: function() {
|
||||||
this._init();
|
this.parent();
|
||||||
}
|
this.setChild(new St.Bin({ style_class: 'placeholder' }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const Dash = new Lang.Class({
|
||||||
|
Name: 'Dash',
|
||||||
|
|
||||||
Dash.prototype = {
|
|
||||||
_init : function() {
|
_init : function() {
|
||||||
this._menus = [];
|
|
||||||
this._menuDisplays = [];
|
|
||||||
this._maxHeight = -1;
|
this._maxHeight = -1;
|
||||||
this._iconSize = 48;
|
this.iconSize = 64;
|
||||||
|
this._shownInitially = false;
|
||||||
|
|
||||||
this._dragPlaceholder = null;
|
this._dragPlaceholder = null;
|
||||||
this._dragPlaceholderPos = -1;
|
this._dragPlaceholderPos = -1;
|
||||||
|
this._animatingPlaceholdersCount = 0;
|
||||||
this._favRemoveTarget = null;
|
this._favRemoveTarget = null;
|
||||||
|
|
||||||
this._favorites = [];
|
|
||||||
|
|
||||||
this._box = new St.BoxLayout({ name: 'dash',
|
this._box = new St.BoxLayout({ name: 'dash',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
clip_to_allocation: true });
|
clip_to_allocation: true });
|
||||||
@ -109,48 +259,60 @@ Dash.prototype = {
|
|||||||
|
|
||||||
this._appSystem.connect('installed-changed', Lang.bind(this, this._queueRedisplay));
|
this._appSystem.connect('installed-changed', Lang.bind(this, this._queueRedisplay));
|
||||||
AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay));
|
AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay));
|
||||||
this._tracker.connect('app-state-changed', Lang.bind(this, this._queueRedisplay));
|
this._appSystem.connect('app-state-changed', Lang.bind(this, this._queueRedisplay));
|
||||||
},
|
|
||||||
|
|
||||||
show: function() {
|
Main.overview.connect('item-drag-begin',
|
||||||
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
Lang.bind(this, this._onDragBegin));
|
||||||
Lang.bind(this, this._onDragBegin));
|
Main.overview.connect('item-drag-end',
|
||||||
this._itemDragEndId = Main.overview.connect('item-drag-end',
|
Lang.bind(this, this._onDragEnd));
|
||||||
Lang.bind(this, this._onDragEnd));
|
Main.overview.connect('item-drag-cancelled',
|
||||||
this._windowDragBeginId = Main.overview.connect('window-drag-begin',
|
Lang.bind(this, this._onDragCancelled));
|
||||||
Lang.bind(this, this._onDragBegin));
|
Main.overview.connect('window-drag-begin',
|
||||||
this._windowDragEndId = Main.overview.connect('window-drag-end',
|
Lang.bind(this, this._onDragBegin));
|
||||||
Lang.bind(this, this._onDragEnd));
|
Main.overview.connect('window-drag-cancelled',
|
||||||
},
|
Lang.bind(this, this._onDragCancelled));
|
||||||
|
Main.overview.connect('window-drag-end',
|
||||||
hide: function() {
|
Lang.bind(this, this._onDragEnd));
|
||||||
Main.overview.disconnect(this._itemDragBeginId);
|
|
||||||
Main.overview.disconnect(this._itemDragEndId);
|
|
||||||
Main.overview.disconnect(this._windowDragBeginId);
|
|
||||||
Main.overview.disconnect(this._windowDragEndId);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDragBegin: function() {
|
_onDragBegin: function() {
|
||||||
|
this._dragCancelled = false;
|
||||||
this._dragMonitor = {
|
this._dragMonitor = {
|
||||||
dragMotion: Lang.bind(this, this._onDragMotion)
|
dragMotion: Lang.bind(this, this._onDragMotion)
|
||||||
};
|
};
|
||||||
DND.addDragMonitor(this._dragMonitor);
|
DND.addDragMonitor(this._dragMonitor);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onDragCancelled: function() {
|
||||||
|
this._dragCancelled = true;
|
||||||
|
this._endDrag();
|
||||||
|
},
|
||||||
|
|
||||||
_onDragEnd: function() {
|
_onDragEnd: function() {
|
||||||
|
if (this._dragCancelled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._endDrag();
|
||||||
|
},
|
||||||
|
|
||||||
|
_endDrag: function() {
|
||||||
this._clearDragPlaceholder();
|
this._clearDragPlaceholder();
|
||||||
if (this._favRemoveTarget) {
|
if (this._favRemoveTarget) {
|
||||||
this._favRemoveTarget.actor.destroy();
|
this._favRemoveTarget.animateOutAndDestroy();
|
||||||
this._favRemoveTarget = null;
|
this._favRemoveTarget.actor.connect('destroy', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._favRemoveTarget = null;
|
||||||
|
}));
|
||||||
|
this._adjustIconSize();
|
||||||
}
|
}
|
||||||
DND.removeMonitor(this._dragMonitor);
|
DND.removeDragMonitor(this._dragMonitor);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDragMotion: function(dragEvent) {
|
_onDragMotion: function(dragEvent) {
|
||||||
let app = null;
|
let app = null;
|
||||||
if (dragEvent.source instanceof AppDisplay.AppWellIcon)
|
if (dragEvent.source instanceof AppDisplay.AppWellIcon)
|
||||||
app = this._appSystem.get_app(dragEvent.source.getId());
|
app = this._appSystem.lookup_app(dragEvent.source.getId());
|
||||||
else if (dragEvent.source instanceof Workspace.WindowClone)
|
else if (dragEvent.source.metaWindow)
|
||||||
app = this._tracker.get_window_app(dragEvent.source.metaWindow);
|
app = this._tracker.get_window_app(dragEvent.source.metaWindow);
|
||||||
else
|
else
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
@ -161,10 +323,15 @@ Dash.prototype = {
|
|||||||
|
|
||||||
let srcIsFavorite = (id in favorites);
|
let srcIsFavorite = (id in favorites);
|
||||||
|
|
||||||
if (srcIsFavorite && this._favRemoveTarget == null) {
|
if (srcIsFavorite &&
|
||||||
|
dragEvent.source.actor &&
|
||||||
|
this.actor.contains (dragEvent.source.actor) &&
|
||||||
|
this._favRemoveTarget == null) {
|
||||||
this._favRemoveTarget = new RemoveFavoriteIcon();
|
this._favRemoveTarget = new RemoveFavoriteIcon();
|
||||||
this._favRemoveTarget.icon.setIconSize(this._iconSize);
|
this._favRemoveTarget.icon.setIconSize(this.iconSize);
|
||||||
this._box.add(this._favRemoveTarget.actor);
|
this._box.add(this._favRemoveTarget.actor);
|
||||||
|
this._adjustIconSize();
|
||||||
|
this._favRemoveTarget.animateIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
let favRemoveHovered = false;
|
let favRemoveHovered = false;
|
||||||
@ -192,8 +359,10 @@ Dash.prototype = {
|
|||||||
Main.queueDeferredWork(this._workId);
|
Main.queueDeferredWork(this._workId);
|
||||||
},
|
},
|
||||||
|
|
||||||
_addApp: function(app) {
|
_createAppItem: function(app) {
|
||||||
let display = new AppDisplay.AppWellIcon(app);
|
let display = new AppDisplay.AppWellIcon(app,
|
||||||
|
{ setSizeManually: true,
|
||||||
|
showLabel: false });
|
||||||
display._draggable.connect('drag-begin',
|
display._draggable.connect('drag-begin',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
display.actor.opacity = 50;
|
display.actor.opacity = 50;
|
||||||
@ -202,61 +371,248 @@ Dash.prototype = {
|
|||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
display.actor.opacity = 255;
|
display.actor.opacity = 255;
|
||||||
}));
|
}));
|
||||||
this._box.add(display.actor);
|
display.actor.set_tooltip_text(app.get_name());
|
||||||
|
|
||||||
|
let item = new DashItemContainer();
|
||||||
|
item.setChild(display.actor);
|
||||||
|
|
||||||
|
display.icon.setIconSize(this.iconSize);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
},
|
||||||
|
|
||||||
|
_adjustIconSize: function() {
|
||||||
|
// For the icon size, we only consider children which are "proper"
|
||||||
|
// icons (i.e. ignoring drag placeholders) and which are not
|
||||||
|
// animating out (which means they will be destroyed at the end of
|
||||||
|
// the animation)
|
||||||
|
let iconChildren = this._box.get_children().filter(function(actor) {
|
||||||
|
return actor._delegate.child &&
|
||||||
|
actor._delegate.child._delegate &&
|
||||||
|
actor._delegate.child._delegate.icon &&
|
||||||
|
!actor._delegate.animatingOut;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (iconChildren.length == 0) {
|
||||||
|
this._box.add_style_pseudo_class('empty');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._box.remove_style_pseudo_class('empty');
|
||||||
|
|
||||||
|
if (this._maxHeight == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
let themeNode = this.actor.get_theme_node();
|
||||||
|
let maxAllocation = new Clutter.ActorBox({ x1: 0, y1: 0,
|
||||||
|
x2: 42 /* whatever */,
|
||||||
|
y2: this._maxHeight });
|
||||||
|
let maxContent = themeNode.get_content_box(maxAllocation);
|
||||||
|
let availHeight = maxContent.y2 - maxContent.y1;
|
||||||
|
let spacing = themeNode.get_length('spacing');
|
||||||
|
|
||||||
|
|
||||||
|
let firstIcon = iconChildren[0]._delegate.child._delegate.icon;
|
||||||
|
|
||||||
|
let minHeight, natHeight;
|
||||||
|
|
||||||
|
// Enforce the current icon size during the size request if
|
||||||
|
// the icon is animating
|
||||||
|
if (firstIcon._animating) {
|
||||||
|
let [currentWidth, currentHeight] = firstIcon.icon.get_size();
|
||||||
|
|
||||||
|
firstIcon.icon.set_size(this.iconSize, this.iconSize);
|
||||||
|
[minHeight, natHeight] = iconChildren[0].get_preferred_height(-1);
|
||||||
|
|
||||||
|
firstIcon.icon.set_size(currentWidth, currentHeight);
|
||||||
|
} else {
|
||||||
|
[minHeight, natHeight] = iconChildren[0].get_preferred_height(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Subtract icon padding and box spacing from the available height
|
||||||
|
availHeight -= iconChildren.length * (natHeight - this.iconSize) +
|
||||||
|
(iconChildren.length - 1) * spacing;
|
||||||
|
|
||||||
|
let availSize = availHeight / iconChildren.length;
|
||||||
|
|
||||||
|
let iconSizes = [ 16, 22, 24, 32, 48, 64 ];
|
||||||
|
|
||||||
|
let newIconSize = 16;
|
||||||
|
for (let i = 0; i < iconSizes.length; i++) {
|
||||||
|
if (iconSizes[i] < availSize)
|
||||||
|
newIconSize = iconSizes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newIconSize == this.iconSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let oldIconSize = this.iconSize;
|
||||||
|
this.iconSize = newIconSize;
|
||||||
|
this.emit('icon-size-changed');
|
||||||
|
|
||||||
|
let scale = oldIconSize / newIconSize;
|
||||||
|
for (let i = 0; i < iconChildren.length; i++) {
|
||||||
|
let icon = iconChildren[i]._delegate.child._delegate.icon;
|
||||||
|
|
||||||
|
// Set the new size immediately, to keep the icons' sizes
|
||||||
|
// in sync with this.iconSize
|
||||||
|
icon.setIconSize(this.iconSize);
|
||||||
|
|
||||||
|
// Don't animate the icon size change when the overview
|
||||||
|
// is not visible or when initially filling the dash
|
||||||
|
if (!Main.overview.visible || !this._shownInitially)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let [targetWidth, targetHeight] = icon.icon.get_size();
|
||||||
|
|
||||||
|
// Scale the icon's texture to the previous size and
|
||||||
|
// tween to the new size
|
||||||
|
icon.icon.set_size(icon.icon.width * scale,
|
||||||
|
icon.icon.height * scale);
|
||||||
|
|
||||||
|
icon._animating = true;
|
||||||
|
Tweener.addTween(icon.icon,
|
||||||
|
{ width: targetWidth,
|
||||||
|
height: targetHeight,
|
||||||
|
time: DASH_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: function() {
|
||||||
|
icon._animating = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_redisplay: function () {
|
_redisplay: function () {
|
||||||
this._box.hide();
|
|
||||||
this._box.remove_all();
|
|
||||||
|
|
||||||
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
||||||
|
|
||||||
/* hardcode here pending some design about how exactly desktop contexts behave */
|
let running = this._appSystem.get_running();
|
||||||
let contextId = '';
|
|
||||||
|
|
||||||
let running = this._tracker.get_running_apps(contextId);
|
let children = this._box.get_children().filter(function(actor) {
|
||||||
|
return actor._delegate.child &&
|
||||||
|
actor._delegate.child._delegate &&
|
||||||
|
actor._delegate.child._delegate.app;
|
||||||
|
});
|
||||||
|
// Apps currently in the dash
|
||||||
|
let oldApps = children.map(function(actor) {
|
||||||
|
return actor._delegate.child._delegate.app;
|
||||||
|
});
|
||||||
|
// Apps supposed to be in the dash
|
||||||
|
let newApps = [];
|
||||||
|
|
||||||
for (let id in favorites) {
|
for (let id in favorites)
|
||||||
let app = favorites[id];
|
newApps.push(favorites[id]);
|
||||||
this._addApp(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < running.length; i++) {
|
for (let i = 0; i < running.length; i++) {
|
||||||
let app = running[i];
|
let app = running[i];
|
||||||
if (app.get_id() in favorites)
|
if (app.get_id() in favorites)
|
||||||
continue;
|
continue;
|
||||||
this._addApp(app);
|
newApps.push(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
let children = this._box.get_children();
|
// Figure out the actual changes to the list of items; we iterate
|
||||||
if (children.length == 0) {
|
// over both the list of items currently in the dash and the list
|
||||||
this._box.add_style_pseudo_class('empty');
|
// of items expected there, and collect additions and removals.
|
||||||
} else {
|
// Moves are both an addition and a removal, where the order of
|
||||||
this._box.remove_style_pseudo_class('empty');
|
// the operations depends on whether we encounter the position
|
||||||
|
// where the item has been added first or the one from where it
|
||||||
|
// was removed.
|
||||||
|
// There is an assumption that only one item is moved at a given
|
||||||
|
// time; when moving several items at once, everything will still
|
||||||
|
// end up at the right position, but there might be additional
|
||||||
|
// additions/removals (e.g. it might remove all the launchers
|
||||||
|
// and add them back in the new order even if a smaller set of
|
||||||
|
// additions and removals is possible).
|
||||||
|
// If above assumptions turns out to be a problem, we might need
|
||||||
|
// to use a more sophisticated algorithm, e.g. Longest Common
|
||||||
|
// Subsequence as used by diff.
|
||||||
|
let addedItems = [];
|
||||||
|
let removedActors = [];
|
||||||
|
|
||||||
if (this._maxHeight > -1) {
|
let newIndex = 0;
|
||||||
let iconSizes = [ 48, 32, 24, 22, 16 ];
|
let oldIndex = 0;
|
||||||
|
while (newIndex < newApps.length || oldIndex < oldApps.length) {
|
||||||
|
// No change at oldIndex/newIndex
|
||||||
|
if (oldApps[oldIndex] == newApps[newIndex]) {
|
||||||
|
oldIndex++;
|
||||||
|
newIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < iconSizes.length; i++) {
|
// App removed at oldIndex
|
||||||
let minHeight, natHeight;
|
if (oldApps[oldIndex] &&
|
||||||
|
newApps.indexOf(oldApps[oldIndex]) == -1) {
|
||||||
|
removedActors.push(children[oldIndex]);
|
||||||
|
oldIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
this._iconSize = iconSizes[i];
|
// App added at newIndex
|
||||||
for (let j = 0; j < children.length; j++)
|
if (newApps[newIndex] &&
|
||||||
children[j]._delegate.icon.setIconSize(this._iconSize);
|
oldApps.indexOf(newApps[newIndex]) == -1) {
|
||||||
|
addedItems.push({ app: newApps[newIndex],
|
||||||
|
item: this._createAppItem(newApps[newIndex]),
|
||||||
|
pos: newIndex });
|
||||||
|
newIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
[minHeight, natHeight] = this.actor.get_preferred_height(-1);
|
// App moved
|
||||||
|
let insertHere = newApps[newIndex + 1] &&
|
||||||
|
newApps[newIndex + 1] == oldApps[oldIndex];
|
||||||
|
let alreadyRemoved = removedActors.reduce(function(result, actor) {
|
||||||
|
let removedApp = actor._delegate.child._delegate.app;
|
||||||
|
return result || removedApp == newApps[newIndex];
|
||||||
|
}, false);
|
||||||
|
|
||||||
if (natHeight <= this._maxHeight)
|
if (insertHere || alreadyRemoved) {
|
||||||
break;
|
let newItem = this._createAppItem(newApps[newIndex]);
|
||||||
}
|
addedItems.push({ app: newApps[newIndex],
|
||||||
|
item: newItem,
|
||||||
|
pos: newIndex + removedActors.length });
|
||||||
|
newIndex++;
|
||||||
|
} else {
|
||||||
|
removedActors.push(children[oldIndex]);
|
||||||
|
oldIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._box.show();
|
|
||||||
|
for (let i = 0; i < addedItems.length; i++)
|
||||||
|
this._box.insert_actor(addedItems[i].item.actor,
|
||||||
|
addedItems[i].pos);
|
||||||
|
|
||||||
|
for (let i = 0; i < removedActors.length; i++) {
|
||||||
|
let item = removedActors[i]._delegate;
|
||||||
|
|
||||||
|
// Don't animate item removal when the overview is hidden
|
||||||
|
if (Main.overview.visible)
|
||||||
|
item.animateOutAndDestroy();
|
||||||
|
else
|
||||||
|
item.actor.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._adjustIconSize();
|
||||||
|
|
||||||
|
// Skip animations on first run when adding the initial set
|
||||||
|
// of items, to avoid all items zooming in at once
|
||||||
|
if (!this._shownInitially) {
|
||||||
|
this._shownInitially = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't animate item addition when the overview is hidden
|
||||||
|
if (!Main.overview.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let i = 0; i < addedItems.length; i++)
|
||||||
|
addedItems[i].item.animateIn();
|
||||||
},
|
},
|
||||||
|
|
||||||
_clearDragPlaceholder: function() {
|
_clearDragPlaceholder: function() {
|
||||||
if (this._dragPlaceholder) {
|
if (this._dragPlaceholder) {
|
||||||
this._dragPlaceholder.destroy();
|
this._dragPlaceholder.animateOutAndDestroy();
|
||||||
this._dragPlaceholder = null;
|
this._dragPlaceholder = null;
|
||||||
this._dragPlaceholderPos = -1;
|
this._dragPlaceholderPos = -1;
|
||||||
}
|
}
|
||||||
@ -265,12 +621,12 @@ Dash.prototype = {
|
|||||||
handleDragOver : function(source, actor, x, y, time) {
|
handleDragOver : function(source, actor, x, y, time) {
|
||||||
let app = null;
|
let app = null;
|
||||||
if (source instanceof AppDisplay.AppWellIcon)
|
if (source instanceof AppDisplay.AppWellIcon)
|
||||||
app = this._appSystem.get_app(source.getId());
|
app = this._appSystem.lookup_app(source.getId());
|
||||||
else if (source instanceof Workspace.WindowClone)
|
else if (source.metaWindow)
|
||||||
app = this._tracker.get_window_app(source.metaWindow);
|
app = this._tracker.get_window_app(source.metaWindow);
|
||||||
|
|
||||||
// Don't allow favoriting of transient apps
|
// Don't allow favoriting of transient apps
|
||||||
if (app == null || app.is_transient())
|
if (app == null || app.is_window_backed())
|
||||||
return DND.DragMotionResult.NO_DROP;
|
return DND.DragMotionResult.NO_DROP;
|
||||||
|
|
||||||
let favorites = AppFavorites.getAppFavorites().getFavorites();
|
let favorites = AppFavorites.getAppFavorites().getFavorites();
|
||||||
@ -278,30 +634,66 @@ Dash.prototype = {
|
|||||||
|
|
||||||
let favPos = favorites.indexOf(app);
|
let favPos = favorites.indexOf(app);
|
||||||
|
|
||||||
let numChildren = this._box.get_children().length;
|
let children = this._box.get_children();
|
||||||
|
let numChildren = children.length;
|
||||||
let boxHeight = this._box.height;
|
let boxHeight = this._box.height;
|
||||||
|
|
||||||
// Keep the placeholder out of the index calculation; assuming that
|
// Keep the placeholder out of the index calculation; assuming that
|
||||||
// the remove target has the same size as "normal" items, we don't
|
// the remove target has the same size as "normal" items, we don't
|
||||||
// need to do the same adjustment there.
|
// need to do the same adjustment there.
|
||||||
if (this._dragPlaceholder) {
|
if (this._dragPlaceholder) {
|
||||||
boxHeight -= this._dragPlaceholder.height;
|
boxHeight -= this._dragPlaceholder.actor.height;
|
||||||
numChildren--;
|
numChildren--;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pos = Math.round(y * numChildren / boxHeight);
|
let pos = Math.round(y * numChildren / boxHeight);
|
||||||
|
|
||||||
if (pos != this._dragPlaceholderPos && pos <= numFavorites) {
|
if (pos != this._dragPlaceholderPos && pos <= numFavorites) {
|
||||||
this._dragPlaceholderPos = pos;
|
if (this._animatingPlaceholdersCount > 0) {
|
||||||
if (this._dragPlaceholder)
|
let appChildren = children.filter(function(actor) {
|
||||||
this._dragPlaceholder.destroy();
|
return actor._delegate &&
|
||||||
|
actor._delegate.child &&
|
||||||
|
actor._delegate.child._delegate &&
|
||||||
|
actor._delegate.child._delegate.app;
|
||||||
|
});
|
||||||
|
this._dragPlaceholderPos = children.indexOf(appChildren[pos]);
|
||||||
|
} else {
|
||||||
|
this._dragPlaceholderPos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't allow positioning before or after self
|
// Don't allow positioning before or after self
|
||||||
if (favPos != -1 && (pos == favPos || pos == favPos + 1))
|
if (favPos != -1 && (pos == favPos || pos == favPos + 1)) {
|
||||||
return DND.DragMotionResult.CONTINUE;
|
if (this._dragPlaceholder) {
|
||||||
|
this._dragPlaceholder.animateOutAndDestroy();
|
||||||
|
this._animatingPlaceholdersCount++;
|
||||||
|
this._dragPlaceholder.actor.connect('destroy',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._animatingPlaceholdersCount--;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
this._dragPlaceholder = null;
|
||||||
|
|
||||||
this._dragPlaceholder = new St.Bin({ style_class: 'dash-placeholder' });
|
return DND.DragMotionResult.CONTINUE;
|
||||||
this._box.insert_actor(this._dragPlaceholder, pos);
|
}
|
||||||
|
|
||||||
|
// If the placeholder already exists, we just move
|
||||||
|
// it, but if we are adding it, expand its size in
|
||||||
|
// an animation
|
||||||
|
let fadeIn;
|
||||||
|
if (this._dragPlaceholder) {
|
||||||
|
this._dragPlaceholder.actor.destroy();
|
||||||
|
fadeIn = false;
|
||||||
|
} else {
|
||||||
|
fadeIn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._dragPlaceholder = new DragPlaceholderItem();
|
||||||
|
this._dragPlaceholder.child.set_width (this.iconSize);
|
||||||
|
this._dragPlaceholder.child.set_height (this.iconSize / 2);
|
||||||
|
this._box.insert_actor(this._dragPlaceholder.actor,
|
||||||
|
this._dragPlaceholderPos);
|
||||||
|
if (fadeIn)
|
||||||
|
this._dragPlaceholder.animateIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
let srcIsFavorite = (favPos != -1);
|
let srcIsFavorite = (favPos != -1);
|
||||||
@ -316,13 +708,13 @@ Dash.prototype = {
|
|||||||
acceptDrop : function(source, actor, x, y, time) {
|
acceptDrop : function(source, actor, x, y, time) {
|
||||||
let app = null;
|
let app = null;
|
||||||
if (source instanceof AppDisplay.AppWellIcon) {
|
if (source instanceof AppDisplay.AppWellIcon) {
|
||||||
app = this._appSystem.get_app(source.getId());
|
app = this._appSystem.lookup_app(source.getId());
|
||||||
} else if (source instanceof Workspace.WindowClone) {
|
} else if (source.metaWindow) {
|
||||||
app = this._tracker.get_window_app(source.metaWindow);
|
app = this._tracker.get_window_app(source.metaWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't allow favoriting of transient apps
|
// Don't allow favoriting of transient apps
|
||||||
if (app == null || app.is_transient()) {
|
if (app == null || app.is_window_backed()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +727,11 @@ Dash.prototype = {
|
|||||||
let favPos = 0;
|
let favPos = 0;
|
||||||
let children = this._box.get_children();
|
let children = this._box.get_children();
|
||||||
for (let i = 0; i < this._dragPlaceholderPos; i++) {
|
for (let i = 0; i < this._dragPlaceholderPos; i++) {
|
||||||
let childId = children[i]._delegate.app.get_id();
|
if (this._dragPlaceholder &&
|
||||||
|
children[i] == this._dragPlaceholder.actor)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let childId = children[i]._delegate.child._delegate.app.get_id();
|
||||||
if (childId == id)
|
if (childId == id)
|
||||||
continue;
|
continue;
|
||||||
if (childId in favorites)
|
if (childId in favorites)
|
||||||
@ -354,6 +750,6 @@ Dash.prototype = {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
Signals.addSignalMethods(Dash.prototype);
|
Signals.addSignalMethods(Dash.prototype);
|
||||||
|
239
js/ui/dateMenu.js
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
|
const Cairo = imports.cairo;
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Params = imports.misc.params;
|
||||||
|
const Util = imports.misc.util;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
const Calendar = imports.ui.calendar;
|
||||||
|
const UPowerGlib = imports.gi.UPowerGlib;
|
||||||
|
|
||||||
|
// in org.gnome.desktop.interface
|
||||||
|
const CLOCK_FORMAT_KEY = 'clock-format';
|
||||||
|
|
||||||
|
// in org.gnome.shell.clock
|
||||||
|
const CLOCK_SHOW_DATE_KEY = 'show-date';
|
||||||
|
const CLOCK_SHOW_SECONDS_KEY = 'show-seconds';
|
||||||
|
|
||||||
|
function _onVertSepRepaint (area)
|
||||||
|
{
|
||||||
|
let cr = area.get_context();
|
||||||
|
let themeNode = area.get_theme_node();
|
||||||
|
let [width, height] = area.get_surface_size();
|
||||||
|
let stippleColor = themeNode.get_color('-stipple-color');
|
||||||
|
let stippleWidth = themeNode.get_length('-stipple-width');
|
||||||
|
let x = Math.floor(width/2) + 0.5;
|
||||||
|
cr.moveTo(x, 0);
|
||||||
|
cr.lineTo(x, height);
|
||||||
|
Clutter.cairo_set_source_color(cr, stippleColor);
|
||||||
|
cr.setDash([1, 3], 1); // Hard-code for now
|
||||||
|
cr.setLineWidth(stippleWidth);
|
||||||
|
cr.stroke();
|
||||||
|
};
|
||||||
|
|
||||||
|
const DateMenuButton = new Lang.Class({
|
||||||
|
Name: 'DateMenuButton',
|
||||||
|
Extends: PanelMenu.Button,
|
||||||
|
|
||||||
|
_init: function(params) {
|
||||||
|
params = Params.parse(params, { showEvents: true });
|
||||||
|
|
||||||
|
let item;
|
||||||
|
let hbox;
|
||||||
|
let vbox;
|
||||||
|
|
||||||
|
let menuAlignment = 0.25;
|
||||||
|
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
|
||||||
|
menuAlignment = 1.0 - menuAlignment;
|
||||||
|
this.parent(menuAlignment);
|
||||||
|
|
||||||
|
this._clock = new St.Label();
|
||||||
|
this.actor.add_actor(this._clock);
|
||||||
|
|
||||||
|
hbox = new St.BoxLayout({name: 'calendarArea' });
|
||||||
|
this.menu.addActor(hbox);
|
||||||
|
|
||||||
|
// Fill up the first column
|
||||||
|
|
||||||
|
vbox = new St.BoxLayout({vertical: true});
|
||||||
|
hbox.add(vbox);
|
||||||
|
|
||||||
|
// Date
|
||||||
|
this._date = new St.Label();
|
||||||
|
this._date.style_class = 'datemenu-date-label';
|
||||||
|
vbox.add(this._date);
|
||||||
|
|
||||||
|
if (params.showEvents) {
|
||||||
|
this._eventSource = new Calendar.DBusEventSource();
|
||||||
|
this._eventList = new Calendar.EventsList(this._eventSource);
|
||||||
|
} else {
|
||||||
|
this._eventSource = null;
|
||||||
|
this._eventList = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calendar
|
||||||
|
this._calendar = new Calendar.Calendar(this._eventSource);
|
||||||
|
|
||||||
|
this._calendar.connect('selected-date-changed',
|
||||||
|
Lang.bind(this, function(calendar, date) {
|
||||||
|
// we know this._eventList is defined here, because selected-data-changed
|
||||||
|
// only gets emitted when the user clicks a date in the calendar,
|
||||||
|
// and the calender makes those dates unclickable when instantiated with
|
||||||
|
// a null event source
|
||||||
|
this._eventList.setDate(date);
|
||||||
|
}));
|
||||||
|
vbox.add(this._calendar.actor);
|
||||||
|
|
||||||
|
item = this.menu.addSettingsAction(_("Date and Time Settings"), 'gnome-datetime-panel.desktop');
|
||||||
|
if (item) {
|
||||||
|
let separator = new PopupMenu.PopupSeparatorMenuItem();
|
||||||
|
separator.setColumnWidths(1);
|
||||||
|
vbox.add(separator.actor, {y_align: St.Align.END, expand: true, y_fill: false});
|
||||||
|
|
||||||
|
item.actor.can_focus = false;
|
||||||
|
item.actor.reparent(vbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.showEvents) {
|
||||||
|
// Add vertical separator
|
||||||
|
|
||||||
|
item = new St.DrawingArea({ style_class: 'calendar-vertical-separator',
|
||||||
|
pseudo_class: 'highlighted' });
|
||||||
|
item.connect('repaint', Lang.bind(this, _onVertSepRepaint));
|
||||||
|
hbox.add(item);
|
||||||
|
|
||||||
|
// Fill up the second column
|
||||||
|
vbox = new St.BoxLayout({name: 'calendarEventsArea',
|
||||||
|
vertical: true});
|
||||||
|
hbox.add(vbox, { expand: true });
|
||||||
|
|
||||||
|
// Event list
|
||||||
|
vbox.add(this._eventList.actor, { expand: true });
|
||||||
|
|
||||||
|
item = new PopupMenu.PopupMenuItem(_("Open Calendar"));
|
||||||
|
item.connect('activate', Lang.bind(this, this._onOpenCalendarActivate));
|
||||||
|
item.actor.can_focus = false;
|
||||||
|
vbox.add(item.actor, {y_align: St.Align.END, expand: true, y_fill: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whenever the menu is opened, select today
|
||||||
|
this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
|
||||||
|
if (isOpen) {
|
||||||
|
let now = new Date();
|
||||||
|
/* Passing true to setDate() forces events to be reloaded. We
|
||||||
|
* want this behavior, because
|
||||||
|
*
|
||||||
|
* o It will cause activation of the calendar server which is
|
||||||
|
* useful if it has crashed
|
||||||
|
*
|
||||||
|
* o It will cause the calendar server to reload events which
|
||||||
|
* is useful if dynamic updates are not supported or not
|
||||||
|
* properly working
|
||||||
|
*
|
||||||
|
* Since this only happens when the menu is opened, the cost
|
||||||
|
* isn't very big.
|
||||||
|
*/
|
||||||
|
this._calendar.setDate(now, true);
|
||||||
|
// No need to update this._eventList as ::selected-date-changed
|
||||||
|
// signal will fire
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Done with hbox for calendar and event list
|
||||||
|
|
||||||
|
// Track changes to clock settings
|
||||||
|
this._desktopSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
|
||||||
|
this._clockSettings = new Gio.Settings({ schema: 'org.gnome.shell.clock' });
|
||||||
|
this._desktopSettings.connect('changed', Lang.bind(this, this._updateClockAndDate));
|
||||||
|
this._clockSettings.connect('changed', Lang.bind(this, this._updateClockAndDate));
|
||||||
|
|
||||||
|
// https://bugzilla.gnome.org/show_bug.cgi?id=655129
|
||||||
|
this._upClient = new UPowerGlib.Client();
|
||||||
|
this._upClient.connect('notify-resume', Lang.bind(this, this._updateClockAndDate));
|
||||||
|
|
||||||
|
// Start the clock
|
||||||
|
this._updateClockAndDate();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateClockAndDate: function() {
|
||||||
|
let format = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);
|
||||||
|
let showDate = this._clockSettings.get_boolean(CLOCK_SHOW_DATE_KEY);
|
||||||
|
let showSeconds = this._clockSettings.get_boolean(CLOCK_SHOW_SECONDS_KEY);
|
||||||
|
|
||||||
|
let clockFormat;
|
||||||
|
let dateFormat;
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case '24h':
|
||||||
|
if (showDate)
|
||||||
|
/* Translators: This is the time format with date used
|
||||||
|
in 24-hour mode. */
|
||||||
|
clockFormat = showSeconds ? _("%a %b %e, %R:%S")
|
||||||
|
: _("%a %b %e, %R");
|
||||||
|
else
|
||||||
|
/* Translators: This is the time format without date used
|
||||||
|
in 24-hour mode. */
|
||||||
|
clockFormat = showSeconds ? _("%a %R:%S")
|
||||||
|
: _("%a %R");
|
||||||
|
break;
|
||||||
|
case '12h':
|
||||||
|
default:
|
||||||
|
if (showDate)
|
||||||
|
/* Translators: This is a time format with date used
|
||||||
|
for AM/PM. */
|
||||||
|
clockFormat = showSeconds ? _("%a %b %e, %l:%M:%S %p")
|
||||||
|
: _("%a %b %e, %l:%M %p");
|
||||||
|
else
|
||||||
|
/* Translators: This is a time format without date used
|
||||||
|
for AM/PM. */
|
||||||
|
clockFormat = showSeconds ? _("%a %l:%M:%S %p")
|
||||||
|
: _("%a %l:%M %p");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let displayDate = new Date();
|
||||||
|
|
||||||
|
this._clock.set_text(displayDate.toLocaleFormat(clockFormat));
|
||||||
|
|
||||||
|
/* Translators: This is the date format to use when the calendar popup is
|
||||||
|
* shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
|
*/
|
||||||
|
dateFormat = _("%A %B %e, %Y");
|
||||||
|
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
|
||||||
|
|
||||||
|
Mainloop.timeout_add_seconds(1, Lang.bind(this, this._updateClockAndDate));
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onOpenCalendarActivate: function() {
|
||||||
|
this.menu.close();
|
||||||
|
let calendarSettings = new Gio.Settings({ schema: 'org.gnome.desktop.default-applications.office.calendar' });
|
||||||
|
let tool = calendarSettings.get_string('exec');
|
||||||
|
if (tool.length == 0 || tool == 'evolution') {
|
||||||
|
// TODO: pass the selected day
|
||||||
|
Util.spawn(['evolution', '-c', 'calendar']);
|
||||||
|
} else {
|
||||||
|
let needTerm = calendarSettings.get_boolean('needs-term');
|
||||||
|
if (needTerm) {
|
||||||
|
let terminalSettings = new Gio.Settings({ schema: 'org.gnome.desktop.default-applications.terminal' });
|
||||||
|
let term = terminalSettings.get_string('exec');
|
||||||
|
let arg = terminalSettings.get_string('exec-arg');
|
||||||
|
if (arg != '')
|
||||||
|
Util.spawn([term, arg, tool]);
|
||||||
|
else
|
||||||
|
Util.spawn([term, tool]);
|
||||||
|
} else {
|
||||||
|
Util.spawnCommandLine(tool)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
89
js/ui/dnd.js
@ -1,4 +1,4 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 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;
|
||||||
@ -61,7 +61,7 @@ function addDragMonitor(monitor) {
|
|||||||
dragMonitors.push(monitor);
|
dragMonitors.push(monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeMonitor(monitor) {
|
function removeDragMonitor(monitor) {
|
||||||
for (let i = 0; i < dragMonitors.length; i++)
|
for (let i = 0; i < dragMonitors.length; i++)
|
||||||
if (dragMonitors[i] == monitor) {
|
if (dragMonitors[i] == monitor) {
|
||||||
dragMonitors.splice(i, 1);
|
dragMonitors.splice(i, 1);
|
||||||
@ -69,11 +69,9 @@ function removeMonitor(monitor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _Draggable(actor, params) {
|
const _Draggable = new Lang.Class({
|
||||||
this._init(actor, params);
|
Name: 'Draggable',
|
||||||
}
|
|
||||||
|
|
||||||
_Draggable.prototype = {
|
|
||||||
_init : function(actor, params) {
|
_init : function(actor, params) {
|
||||||
params = Params.parse(params, { manualMode: false,
|
params = Params.parse(params, { manualMode: false,
|
||||||
restoreOnSuccess: false,
|
restoreOnSuccess: false,
|
||||||
@ -87,6 +85,10 @@ _Draggable.prototype = {
|
|||||||
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, function() {
|
this.actor.connect('destroy', Lang.bind(this, function() {
|
||||||
this._actorDestroyed = true;
|
this._actorDestroyed = true;
|
||||||
|
// If the drag actor is destroyed and we were going to fix
|
||||||
|
// up its hover state, fix up the parent hover state instead
|
||||||
|
if (this.actor == this._firstLeaveActor)
|
||||||
|
this._firstLeaveActor = this._dragOrigParent;
|
||||||
if (this._dragInProgress)
|
if (this._dragInProgress)
|
||||||
this._cancelDrag(global.get_current_time());
|
this._cancelDrag(global.get_current_time());
|
||||||
this.disconnectAll();
|
this.disconnectAll();
|
||||||
@ -101,6 +103,12 @@ _Draggable.prototype = {
|
|||||||
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._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
||||||
|
|
||||||
|
// During the drag, we eat enter/leave events so that actors don't prelight or show
|
||||||
|
// tooltips. But we remember the actors that we first left/last entered so we can
|
||||||
|
// fix up the hover state after the drag ends.
|
||||||
|
this._firstLeaveActor = null;
|
||||||
|
this._lastEnterActor = null;
|
||||||
|
|
||||||
this._eventsGrabbed = false;
|
this._eventsGrabbed = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -112,11 +120,11 @@ _Draggable.prototype = {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
this._buttonDown = true;
|
this._buttonDown = true;
|
||||||
// special case St.Clickable: grabbing the pointer would mess up the
|
// special case St.Button: grabbing the pointer would mess up the
|
||||||
// internal state, so we start the drag manually on hover change
|
// internal state, so we start the drag manually on hover change
|
||||||
if (this.actor instanceof St.Clickable)
|
if (this.actor instanceof St.Button)
|
||||||
this.actor.connect('notify::hover',
|
this.actor.connect('notify::hover',
|
||||||
Lang.bind(this, this._onClickableHoverChanged));
|
Lang.bind(this, this._onButtonHoverChanged));
|
||||||
else
|
else
|
||||||
this._grabActor();
|
this._grabActor();
|
||||||
|
|
||||||
@ -127,8 +135,8 @@ _Draggable.prototype = {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onClickableHoverChanged: function(button) {
|
_onButtonHoverChanged: function(button) {
|
||||||
if (button.hover || !button.held)
|
if (button.hover || !button.pressed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
button.fake_release();
|
button.fake_release();
|
||||||
@ -144,6 +152,8 @@ _Draggable.prototype = {
|
|||||||
|
|
||||||
_ungrabActor: function() {
|
_ungrabActor: function() {
|
||||||
Clutter.ungrab_pointer();
|
Clutter.ungrab_pointer();
|
||||||
|
if (!this._onEventId)
|
||||||
|
return;
|
||||||
this.actor.disconnect(this._onEventId);
|
this.actor.disconnect(this._onEventId);
|
||||||
this._onEventId = null;
|
this._onEventId = null;
|
||||||
},
|
},
|
||||||
@ -198,6 +208,11 @@ _Draggable.prototype = {
|
|||||||
this._cancelDrag(event.get_time());
|
this._cancelDrag(event.get_time());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else if (event.type() == Clutter.EventType.LEAVE) {
|
||||||
|
if (this._firstLeaveActor == null)
|
||||||
|
this._firstLeaveActor = event.get_source();
|
||||||
|
} else if (event.type() == Clutter.EventType.ENTER) {
|
||||||
|
this._lastEnterActor = event.get_source();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -267,13 +282,13 @@ _Draggable.prototype = {
|
|||||||
this._dragOffsetY = actorStageY - this._dragStartY;
|
this._dragOffsetY = actorStageY - this._dragStartY;
|
||||||
|
|
||||||
// Set the actor's scale such that it will keep the same
|
// Set the actor's scale such that it will keep the same
|
||||||
// transformed size when it's reparented to the stage
|
// transformed size when it's reparented to the uiGroup
|
||||||
let [scaledWidth, scaledHeight] = this.actor.get_transformed_size();
|
let [scaledWidth, scaledHeight] = this.actor.get_transformed_size();
|
||||||
this.actor.set_scale(scaledWidth / this.actor.width,
|
this.actor.set_scale(scaledWidth / this.actor.width,
|
||||||
scaledHeight / this.actor.height);
|
scaledHeight / this.actor.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._dragActor.reparent(this.actor.get_stage());
|
this._dragActor.reparent(Main.uiGroup);
|
||||||
this._dragActor.raise_top();
|
this._dragActor.raise_top();
|
||||||
Shell.util_set_hidden_from_pick(this._dragActor, true);
|
Shell.util_set_hidden_from_pick(this._dragActor, true);
|
||||||
|
|
||||||
@ -425,7 +440,7 @@ _Draggable.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
// If it accepted the drop without taking the actor,
|
// If it accepted the drop without taking the actor,
|
||||||
// handle it ourselves.
|
// handle it ourselves.
|
||||||
if (this._dragActor.get_parent() == this._dragActor.get_stage()) {
|
if (this._dragActor.get_parent() == Main.uiGroup) {
|
||||||
if (this._restoreOnSuccess) {
|
if (this._restoreOnSuccess) {
|
||||||
this._restoreDragActor(event.get_time());
|
this._restoreDragActor(event.get_time());
|
||||||
return true;
|
return true;
|
||||||
@ -461,12 +476,14 @@ _Draggable.prototype = {
|
|||||||
// its parent, adjusting for the fact that the parent
|
// its parent, adjusting for the fact that the parent
|
||||||
// may have been moved or scaled
|
// may have been moved or scaled
|
||||||
let [parentX, parentY] = this._dragOrigParent.get_transformed_position();
|
let [parentX, parentY] = this._dragOrigParent.get_transformed_position();
|
||||||
x = parentX + this._dragOrigParent.scale_x * this._dragOrigX;
|
|
||||||
y = parentY + this._dragOrigParent.scale_y * this._dragOrigY;
|
|
||||||
|
|
||||||
let [parentWidth, parentHeight] = this._dragOrigParent.get_size();
|
let [parentWidth, parentHeight] = this._dragOrigParent.get_size();
|
||||||
let [parentScaledWidth, parentScaledHeight] = this._dragOrigParent.get_transformed_size();
|
let [parentScaledWidth, parentScaledHeight] = this._dragOrigParent.get_transformed_size();
|
||||||
let parentScale = parentScaledWidth / parentWidth;
|
let parentScale = 1.0;
|
||||||
|
if (parentWidth != 0)
|
||||||
|
parentScale = parentScaledWidth / parentWidth;
|
||||||
|
|
||||||
|
x = parentX + parentScale * this._dragOrigX;
|
||||||
|
y = parentY + parentScale * this._dragOrigY;
|
||||||
scale = this._dragOrigScale * parentScale;
|
scale = this._dragOrigScale * parentScale;
|
||||||
} else {
|
} else {
|
||||||
// Snap back actor to its original stage position
|
// Snap back actor to its original stage position
|
||||||
@ -479,14 +496,18 @@ _Draggable.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_cancelDrag: function(eventTime) {
|
_cancelDrag: function(eventTime) {
|
||||||
|
this.emit('drag-cancelled', eventTime);
|
||||||
this._dragInProgress = false;
|
this._dragInProgress = false;
|
||||||
let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
|
let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
|
||||||
|
|
||||||
if (this._actorDestroyed) {
|
if (this._actorDestroyed) {
|
||||||
global.unset_cursor();
|
global.unset_cursor();
|
||||||
if (!this._buttonDown)
|
if (!this._buttonDown)
|
||||||
this._ungrabEvents();
|
this._dragComplete();
|
||||||
this.emit('drag-end', eventTime, false);
|
this.emit('drag-end', eventTime, false);
|
||||||
|
if (!this._dragOrigParent)
|
||||||
|
this._dragActor.destroy();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,14 +563,38 @@ _Draggable.prototype = {
|
|||||||
this._dragComplete();
|
this._dragComplete();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Actor is an actor we have entered or left during the drag; call
|
||||||
|
// st_widget_sync_hover on all StWidget ancestors
|
||||||
|
_syncHover: function(actor) {
|
||||||
|
while (actor) {
|
||||||
|
let parent = actor.get_parent();
|
||||||
|
if (actor instanceof St.Widget)
|
||||||
|
actor.sync_hover();
|
||||||
|
|
||||||
|
actor = parent;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_dragComplete: function() {
|
_dragComplete: function() {
|
||||||
Shell.util_set_hidden_from_pick(this._dragActor, false);
|
if (!this._actorDestroyed)
|
||||||
|
Shell.util_set_hidden_from_pick(this._dragActor, false);
|
||||||
|
|
||||||
|
this._ungrabEvents();
|
||||||
|
|
||||||
|
if (this._firstLeaveActor) {
|
||||||
|
this._syncHover(this._firstLeaveActor);
|
||||||
|
this._firstLeaveActor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._lastEnterActor) {
|
||||||
|
this._syncHover(this._lastEnterActor);
|
||||||
|
this._lastEnterActor = null;
|
||||||
|
}
|
||||||
|
|
||||||
this._dragActor = undefined;
|
this._dragActor = undefined;
|
||||||
currentDraggable = null;
|
currentDraggable = null;
|
||||||
this._ungrabEvents();
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
Signals.addSignalMethods(_Draggable.prototype);
|
Signals.addSignalMethods(_Draggable.prototype);
|
||||||
|
|
||||||
|
@ -1,497 +1,16 @@
|
|||||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const Signals = imports.signals;
|
|
||||||
const St = imports.gi.St;
|
|
||||||
const Mainloop = imports.mainloop;
|
|
||||||
const Gettext = imports.gettext.domain('gnome-shell');
|
|
||||||
const _ = Gettext.gettext;
|
|
||||||
|
|
||||||
const DocInfo = imports.misc.docInfo;
|
const DocInfo = imports.misc.docInfo;
|
||||||
const DND = imports.ui.dnd;
|
const Lang = imports.lang;
|
||||||
const GenericDisplay = imports.ui.genericDisplay;
|
const Params = imports.misc.params;
|
||||||
const Main = imports.ui.main;
|
|
||||||
const Search = imports.ui.search;
|
const Search = imports.ui.search;
|
||||||
|
|
||||||
const MAX_DASH_DOCS = 50;
|
const DocSearchProvider = new Lang.Class({
|
||||||
const DASH_DOCS_ICON_SIZE = 16;
|
Name: 'DocSearchProvider',
|
||||||
|
Extends: Search.SearchProvider,
|
||||||
const DEFAULT_SPACING = 4;
|
|
||||||
|
|
||||||
/* This class represents a single display item containing information about a document.
|
|
||||||
* We take the current number of seconds in the constructor to avoid looking up the current
|
|
||||||
* time for every item when they are created in a batch.
|
|
||||||
*
|
|
||||||
* docInfo - DocInfo object containing information about the document
|
|
||||||
* currentSeconds - current number of seconds since the epoch
|
|
||||||
*/
|
|
||||||
function DocDisplayItem(docInfo, currentSecs) {
|
|
||||||
this._init(docInfo, currentSecs);
|
|
||||||
}
|
|
||||||
|
|
||||||
DocDisplayItem.prototype = {
|
|
||||||
__proto__: GenericDisplay.GenericDisplayItem.prototype,
|
|
||||||
|
|
||||||
_init : function(docInfo, currentSecs) {
|
|
||||||
GenericDisplay.GenericDisplayItem.prototype._init.call(this);
|
|
||||||
this._docInfo = docInfo;
|
|
||||||
|
|
||||||
this._setItemInfo(docInfo.name, '');
|
|
||||||
|
|
||||||
this._timeoutTime = -1;
|
|
||||||
this._resetTimeDisplay(currentSecs);
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Public methods ////
|
|
||||||
|
|
||||||
getUpdateTimeoutTime: function() {
|
|
||||||
return this._timeoutTime;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Update any relative-time based displays for this item.
|
|
||||||
redisplay: function(currentSecs) {
|
|
||||||
this._resetTimeDisplay(currentSecs);
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Public method overrides ////
|
|
||||||
|
|
||||||
// Opens a document represented by this display item.
|
|
||||||
launch : function() {
|
|
||||||
this._docInfo.launch();
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Protected method overrides ////
|
|
||||||
|
|
||||||
// Returns an icon for the item.
|
|
||||||
_createIcon : function() {
|
|
||||||
return this._docInfo.createIcon(GenericDisplay.ITEM_DISPLAY_ICON_SIZE);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Returns a preview icon for the item.
|
|
||||||
_createPreviewIcon : function() {
|
|
||||||
return this._docInfo.createIcon(GenericDisplay.PREVIEW_ICON_SIZE);
|
|
||||||
},
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
_createLargePreviewIcon : function() {
|
|
||||||
if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf('image/') != 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return St.TextureCache.get_default().load_uri_sync(St.TextureCachePolicy.NONE,
|
|
||||||
this._docInfo.uri, -1, -1);
|
|
||||||
} catch (e) {
|
|
||||||
// An exception will be raised when the image format isn't know
|
|
||||||
/* FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=591480: should
|
|
||||||
* only ignore GDK_PIXBUF_ERROR_UNKNOWN_TYPE. */
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Drag and Drop ////
|
|
||||||
|
|
||||||
shellWorkspaceLaunch: function() {
|
|
||||||
this.launch();
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Private Methods ////
|
|
||||||
|
|
||||||
// Updates the last visited time displayed in the description text for the item.
|
|
||||||
_resetTimeDisplay: function(currentSecs) {
|
|
||||||
let lastSecs = this._docInfo.timestamp;
|
|
||||||
let timeDelta = currentSecs - lastSecs;
|
|
||||||
let [text, nextUpdate] = global.format_time_relative_pretty(timeDelta);
|
|
||||||
this._timeoutTime = currentSecs + nextUpdate;
|
|
||||||
this._setDescriptionText(text);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This class represents a display containing a collection of document items.
|
|
||||||
* The documents are sorted by how recently they were last visited.
|
|
||||||
*/
|
|
||||||
function DocDisplay() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
DocDisplay.prototype = {
|
|
||||||
__proto__: GenericDisplay.GenericDisplay.prototype,
|
|
||||||
|
|
||||||
_init : function() {
|
|
||||||
GenericDisplay.GenericDisplay.prototype._init.call(this);
|
|
||||||
// We keep a single timeout callback for updating last visited times
|
|
||||||
// for all the items in the display. This avoids creating individual
|
|
||||||
// callbacks for each item in the display. So proper time updates
|
|
||||||
// for individual items and item details depend on the item being
|
|
||||||
// associated with one of the displays.
|
|
||||||
this._updateTimeoutTargetTime = -1;
|
|
||||||
this._updateTimeoutId = 0;
|
|
||||||
|
|
||||||
this._docManager = DocInfo.getDocManager();
|
|
||||||
this._docsStale = true;
|
|
||||||
this._docManager.connect('changed', Lang.bind(this, function(mgr, userData) {
|
|
||||||
this._docsStale = true;
|
|
||||||
// Changes in local recent files should not happen when we are in the Overview mode,
|
|
||||||
// but redisplaying right away is cool when we use Zephyr.
|
|
||||||
// Also, we might be displaying remote documents, like Google Docs, in the future
|
|
||||||
// which might be edited by someone else.
|
|
||||||
this._redisplay(GenericDisplay.RedisplayFlags.NONE);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.connect('destroy', Lang.bind(this, function (o) {
|
|
||||||
if (this._updateTimeoutId > 0)
|
|
||||||
Mainloop.source_remove(this._updateTimeoutId);
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Protected method overrides ////
|
|
||||||
|
|
||||||
// Gets the list of recent items from the recent items manager.
|
|
||||||
_refreshCache : function() {
|
|
||||||
if (!this._docsStale)
|
|
||||||
return true;
|
|
||||||
this._allItems = {};
|
|
||||||
Lang.copyProperties(this._docManager.getInfosByUri(), this._allItems);
|
|
||||||
this._docsStale = false;
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Sets the list of the displayed items based on how recently they were last visited.
|
|
||||||
_setDefaultList : function() {
|
|
||||||
// It seems to be an implementation detail of the Mozilla JavaScript that object
|
|
||||||
// properties are returned during the iteration in the same order in which they were
|
|
||||||
// defined, but it is not a guarantee according to this
|
|
||||||
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/for...in
|
|
||||||
// While this._allItems associative array seems to always be ordered by last added,
|
|
||||||
// as the results of this._recentManager.get_items() based on which it is constructed are,
|
|
||||||
// we should do the sorting manually because we want the order to be based on last visited.
|
|
||||||
//
|
|
||||||
// This function is called each time the search string is set back to '' or we display
|
|
||||||
// the Overview, so we are doing the sorting over the same items multiple times if the list
|
|
||||||
// of recent items didn't change. We could store an additional array of doc ids and sort
|
|
||||||
// them once when they are returned by this._recentManager.get_items() to avoid having to do
|
|
||||||
// this sorting each time, but the sorting seems to be very fast anyway, so there is no need
|
|
||||||
// to introduce an additional class variable.
|
|
||||||
this._matchedItems = {};
|
|
||||||
this._matchedItemKeys = [];
|
|
||||||
let docIdsToRemove = [];
|
|
||||||
for (docId in this._allItems) {
|
|
||||||
this._matchedItems[docId] = 1;
|
|
||||||
this._matchedItemKeys.push(docId);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (docId in docIdsToRemove) {
|
|
||||||
delete this._allItems[docId];
|
|
||||||
}
|
|
||||||
|
|
||||||
this._matchedItemKeys.sort(Lang.bind(this, this._compareItems));
|
|
||||||
},
|
|
||||||
|
|
||||||
// Compares items associated with the item ids based on how recently the items
|
|
||||||
// were last visited.
|
|
||||||
// Returns an integer value indicating the result of the comparison.
|
|
||||||
_compareItems : function(itemIdA, itemIdB) {
|
|
||||||
let docA = this._allItems[itemIdA];
|
|
||||||
let docB = this._allItems[itemIdB];
|
|
||||||
|
|
||||||
return docB.timestamp - docA.timestamp;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Checks if the item info can be a match for the search string by checking
|
|
||||||
// the name of the document. Item info is expected to be GtkRecentInfo.
|
|
||||||
// Returns a boolean flag indicating if itemInfo is a match.
|
|
||||||
_isInfoMatching : function(itemInfo, search) {
|
|
||||||
if (!itemInfo.exists())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (search == null || search == '')
|
|
||||||
return true;
|
|
||||||
|
|
||||||
let name = itemInfo.name.toLowerCase();
|
|
||||||
if (name.indexOf(search) >= 0)
|
|
||||||
return true;
|
|
||||||
// TODO: we can also check doc URIs, so that
|
|
||||||
// if you search for a directory name, we display recent files from it
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Creates a DocDisplayItem based on itemInfo, which is expected to be a DocInfo object.
|
|
||||||
_createDisplayItem: function(itemInfo) {
|
|
||||||
let currentSecs = new Date().getTime() / 1000;
|
|
||||||
let docDisplayItem = new DocDisplayItem(itemInfo, currentSecs);
|
|
||||||
this._updateTimeoutCallback(docDisplayItem, currentSecs);
|
|
||||||
return docDisplayItem;
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Private Methods ////
|
|
||||||
|
|
||||||
// A callback function that redisplays the items, updating their descriptions,
|
|
||||||
// and sets up a new timeout callback.
|
|
||||||
_docTimeout: function () {
|
|
||||||
let currentSecs = new Date().getTime() / 1000;
|
|
||||||
this._updateTimeoutId = 0;
|
|
||||||
this._updateTimeoutTargetTime = -1;
|
|
||||||
for (let docId in this._displayedItems) {
|
|
||||||
let docDisplayItem = this._displayedItems[docId];
|
|
||||||
docDisplayItem.redisplay(currentSecs);
|
|
||||||
this._updateTimeoutCallback(docDisplayItem, currentSecs);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Updates the timeout callback if the timeout time for the docDisplayItem
|
|
||||||
// is earlier than the target time for the current timeout callback.
|
|
||||||
_updateTimeoutCallback: function (docDisplayItem, currentSecs) {
|
|
||||||
let timeoutTime = docDisplayItem.getUpdateTimeoutTime();
|
|
||||||
if (this._updateTimeoutTargetTime < 0 || timeoutTime < this._updateTimeoutTargetTime) {
|
|
||||||
if (this._updateTimeoutId > 0)
|
|
||||||
Mainloop.source_remove(this._updateTimeoutId);
|
|
||||||
this._updateTimeoutId = Mainloop.timeout_add_seconds(timeoutTime - currentSecs, Lang.bind(this, this._docTimeout));
|
|
||||||
this._updateTimeoutTargetTime = timeoutTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Signals.addSignalMethods(DocDisplay.prototype);
|
|
||||||
|
|
||||||
function DashDocDisplayItem(docInfo) {
|
|
||||||
this._init(docInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
DashDocDisplayItem.prototype = {
|
|
||||||
_init: function(docInfo) {
|
|
||||||
this._info = docInfo;
|
|
||||||
this._icon = docInfo.createIcon(DASH_DOCS_ICON_SIZE);
|
|
||||||
|
|
||||||
this.actor = new St.Clickable({ style_class: 'recent-docs-item',
|
|
||||||
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();
|
|
||||||
Main.overview.hide();
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.actor._delegate = this;
|
|
||||||
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() {
|
|
||||||
return this._info.uri;
|
|
||||||
},
|
|
||||||
|
|
||||||
getDragActorSource: function() {
|
|
||||||
return this._icon;
|
|
||||||
},
|
|
||||||
|
|
||||||
getDragActor: function(stageX, stageY) {
|
|
||||||
this.dragActor = this._info.createIcon(DASH_DOCS_ICON_SIZE);
|
|
||||||
return this.dragActor;
|
|
||||||
},
|
|
||||||
|
|
||||||
//// Drag and drop functions ////
|
|
||||||
|
|
||||||
shellWorkspaceLaunch: function () {
|
|
||||||
this._info.launch();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class used to display two column recent documents in the dash
|
|
||||||
*/
|
|
||||||
function DashDocDisplay() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
DashDocDisplay.prototype = {
|
|
||||||
_init: function() {
|
|
||||||
this.actor = new Shell.GenericContainer();
|
|
||||||
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._workId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._redisplay));
|
|
||||||
|
|
||||||
this._actorsByUri = {};
|
|
||||||
|
|
||||||
this._docManager = DocInfo.getDocManager();
|
|
||||||
this._docManager.connect('changed', Lang.bind(this, this._onDocsChanged));
|
|
||||||
this._pendingDocsChange = true;
|
|
||||||
this._checkDocExistence = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
|
||||||
let children = actor.get_children();
|
|
||||||
|
|
||||||
// We use two columns maximum. Just take the min and natural size of the
|
|
||||||
// first two items, even though strictly speaking it's not correct; we'd
|
|
||||||
// need to calculate how many items we could fit for the height, then
|
|
||||||
// take the biggest preferred width for each column.
|
|
||||||
// In practice the dash gets a fixed width anyways.
|
|
||||||
|
|
||||||
// If we have one child, add its minimum and natural size
|
|
||||||
if (children.length > 0) {
|
|
||||||
let [minSize, naturalSize] = children[0].get_preferred_width(forHeight);
|
|
||||||
alloc.min_size += minSize;
|
|
||||||
alloc.natural_size += naturalSize;
|
|
||||||
}
|
|
||||||
// If we have two, add its size, plus DEFAULT_SPACING
|
|
||||||
if (children.length > 1) {
|
|
||||||
let [minSize, naturalSize] = children[1].get_preferred_width(forHeight);
|
|
||||||
alloc.min_size += DEFAULT_SPACING + minSize;
|
|
||||||
alloc.natural_size += DEFAULT_SPACING + naturalSize;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
|
||||||
let children = actor.get_children();
|
|
||||||
|
|
||||||
// The width of an item is our allocated width, minus spacing, divided in half.
|
|
||||||
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);
|
|
||||||
alloc.natural_size = (firstColumnChildren * maxNatural +
|
|
||||||
(firstColumnChildren - 1) * DEFAULT_SPACING);
|
|
||||||
},
|
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
|
||||||
let width = box.x2 - box.x1;
|
|
||||||
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 x = 0;
|
|
||||||
let y = 0;
|
|
||||||
let columnIndex = 0;
|
|
||||||
let i = 0;
|
|
||||||
// Loop over the children, going vertically down first. When we run
|
|
||||||
// out of vertical space (our y variable is bigger than box.y2), switch
|
|
||||||
// to the second column.
|
|
||||||
while (i < children.length) {
|
|
||||||
let child = children[i];
|
|
||||||
|
|
||||||
if (y + this._itemHeight > box.y2) {
|
|
||||||
// Is this the second column, or we're in
|
|
||||||
// the first column and can't even fit one
|
|
||||||
// item? In that case, break.
|
|
||||||
if (columnIndex == 1 || i == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Set x to the halfway point.
|
|
||||||
columnIndex += 1;
|
|
||||||
x = x + this._itemWidth + DEFAULT_SPACING;
|
|
||||||
// And y is back to the top.
|
|
||||||
y = 0;
|
|
||||||
// Retry this same item, now that we're in the second column.
|
|
||||||
// By looping back to the top here, we re-test the size
|
|
||||||
// again for the second column.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let childBox = new Clutter.ActorBox();
|
|
||||||
childBox.x1 = x;
|
|
||||||
childBox.y1 = y;
|
|
||||||
childBox.x2 = childBox.x1 + this._itemWidth;
|
|
||||||
childBox.y2 = y + this._itemHeight;
|
|
||||||
|
|
||||||
y = childBox.y2 + DEFAULT_SPACING;
|
|
||||||
|
|
||||||
child.allocate(childBox, flags);
|
|
||||||
this.actor.set_skip_paint(child, false);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._checkDocExistence) {
|
|
||||||
// Now we know how many docs we are displaying, queue a check to see if any of them
|
|
||||||
// have been deleted. If they are deleted, then we'll get a 'changed' signal; since
|
|
||||||
// we'll now be displaying items we weren't previously, we'll check again to see
|
|
||||||
// if they were deleted, and so forth and so on.
|
|
||||||
// TODO: We should change this to ask for as many as we can fit in the given space:
|
|
||||||
// https://bugzilla.gnome.org/show_bug.cgi?id=603522#c23
|
|
||||||
this._docManager.queueExistenceCheck(i);
|
|
||||||
this._checkDocExistence = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i < children.length; i++)
|
|
||||||
this.actor.set_skip_paint(children[i], true);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onDocsChanged: function() {
|
|
||||||
this._checkDocExistence = true;
|
|
||||||
Main.queueDeferredWork(this._workId);
|
|
||||||
},
|
|
||||||
|
|
||||||
_redisplay: function() {
|
|
||||||
// Should be kept alive by the _actorsByUri
|
|
||||||
this.actor.remove_all();
|
|
||||||
let docs = this._docManager.getTimestampOrderedInfos();
|
|
||||||
for (let i = 0; i < docs.length && i < MAX_DASH_DOCS; i++) {
|
|
||||||
let doc = docs[i];
|
|
||||||
let display = this._actorsByUri[doc.uri];
|
|
||||||
if (display) {
|
|
||||||
this.actor.add_actor(display.actor);
|
|
||||||
} else {
|
|
||||||
let display = new DashDocDisplayItem(doc);
|
|
||||||
this.actor.add_actor(display.actor);
|
|
||||||
this._actorsByUri[doc.uri] = display;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Any unparented actors must have been deleted
|
|
||||||
for (let uri in this._actorsByUri) {
|
|
||||||
let display = this._actorsByUri[uri];
|
|
||||||
if (display.actor.get_parent() == null) {
|
|
||||||
display.actor.destroy();
|
|
||||||
delete this._actorsByUri[uri];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.emit('changed');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Signals.addSignalMethods(DashDocDisplay.prototype);
|
|
||||||
|
|
||||||
function DocSearchProvider() {
|
|
||||||
this._init();
|
|
||||||
}
|
|
||||||
|
|
||||||
DocSearchProvider.prototype = {
|
|
||||||
__proto__: Search.SearchProvider.prototype,
|
|
||||||
|
|
||||||
_init: function(name) {
|
_init: function(name) {
|
||||||
Search.SearchProvider.prototype._init.call(this, _("RECENT ITEMS"));
|
this.parent(_("RECENT ITEMS"));
|
||||||
this._docManager = DocInfo.getDocManager();
|
this._docManager = DocInfo.getDocManager();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -501,12 +20,18 @@ DocSearchProvider.prototype = {
|
|||||||
return null;
|
return null;
|
||||||
return { 'id': resultId,
|
return { 'id': resultId,
|
||||||
'name': docInfo.name,
|
'name': docInfo.name,
|
||||||
'icon': docInfo.createIcon(Search.RESULT_ICON_SIZE)};
|
'createIcon': function(size) {
|
||||||
|
return docInfo.createIcon(size);
|
||||||
|
}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
activateResult: function(id) {
|
activateResult: function(id, params) {
|
||||||
|
params = Params.parse(params, { workspace: -1,
|
||||||
|
timestamp: 0 });
|
||||||
|
|
||||||
let docInfo = this._docManager.lookupByUri(id);
|
let docInfo = this._docManager.lookupByUri(id);
|
||||||
docInfo.launch();
|
docInfo.launch(params.workspace);
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialResultSet: function(terms) {
|
getInitialResultSet: function(terms) {
|
||||||
@ -515,9 +40,5 @@ DocSearchProvider.prototype = {
|
|||||||
|
|
||||||
getSubsearchResultSet: function(previousResults, terms) {
|
getSubsearchResultSet: function(previousResults, terms) {
|
||||||
return this._docManager.subsearch(previousResults, terms);
|
return this._docManager.subsearch(previousResults, terms);
|
||||||
},
|
|
||||||
|
|
||||||
expandSearch: function(terms) {
|
|
||||||
log('TODO expand docs search');
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
536
js/ui/endSessionDialog.js
Normal file
@ -0,0 +1,536 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
/*
|
||||||
|
* Copyright 2010 Red Hat, Inc
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
const AccountsService = imports.gi.AccountsService;
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
|
const Pango = imports.gi.Pango;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const GnomeSession = imports.misc.gnomeSession;
|
||||||
|
const Lightbox = imports.ui.lightbox;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
let _endSessionDialog = null;
|
||||||
|
|
||||||
|
const _ITEM_ICON_SIZE = 48;
|
||||||
|
const _DIALOG_ICON_SIZE = 32;
|
||||||
|
|
||||||
|
const GSM_SESSION_MANAGER_LOGOUT_FORCE = 2;
|
||||||
|
|
||||||
|
const EndSessionDialogIface = <interface name="org.gnome.SessionManager.EndSessionDialog">
|
||||||
|
<method name="Open">
|
||||||
|
<arg type="u" direction="in" />
|
||||||
|
<arg type="u" direction="in" />
|
||||||
|
<arg type="u" direction="in" />
|
||||||
|
<arg type="ao" direction="in" />
|
||||||
|
</method>
|
||||||
|
<signal name="ConfirmedLogout" />
|
||||||
|
<signal name="ConfirmedReboot" />
|
||||||
|
<signal name="ConfirmedShutdown" />
|
||||||
|
<signal name="Canceled" />
|
||||||
|
<signal name="Closed" />
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const logoutDialogContent = {
|
||||||
|
subjectWithUser: C_("title", "Log Out %s"),
|
||||||
|
subject: C_("title", "Log Out"),
|
||||||
|
inhibitedDescription: _("Click Log Out to quit these applications and log out of the system."),
|
||||||
|
uninhibitedDescriptionWithUser: function(user, seconds) {
|
||||||
|
return ngettext("%s will be logged out automatically in %d second.",
|
||||||
|
"%s will be logged out automatically in %d seconds.",
|
||||||
|
seconds).format(user, seconds);
|
||||||
|
},
|
||||||
|
uninhibitedDescription: function(seconds) {
|
||||||
|
return ngettext("You will be logged out automatically in %d second.",
|
||||||
|
"You will be logged out automatically in %d seconds.",
|
||||||
|
seconds).format(seconds);
|
||||||
|
},
|
||||||
|
endDescription: _("Logging out of the system."),
|
||||||
|
confirmButtons: [{ signal: 'ConfirmedLogout',
|
||||||
|
label: C_("button", "Log Out") }],
|
||||||
|
iconStyleClass: 'end-session-dialog-logout-icon'
|
||||||
|
};
|
||||||
|
|
||||||
|
const shutdownDialogContent = {
|
||||||
|
subject: C_("title", "Power Off"),
|
||||||
|
inhibitedDescription: _("Click Power Off to quit these applications and power off the system."),
|
||||||
|
uninhibitedDescription: function(seconds) {
|
||||||
|
return ngettext("The system will power off automatically in %d second.",
|
||||||
|
"The system will power off automatically in %d seconds.",
|
||||||
|
seconds).format(seconds);
|
||||||
|
},
|
||||||
|
endDescription: _("Powering off the system."),
|
||||||
|
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||||
|
label: C_("button", "Restart") },
|
||||||
|
{ signal: 'ConfirmedShutdown',
|
||||||
|
label: C_("button", "Power Off") }],
|
||||||
|
iconName: 'system-shutdown',
|
||||||
|
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
||||||
|
};
|
||||||
|
|
||||||
|
const restartDialogContent = {
|
||||||
|
subject: C_("title", "Restart"),
|
||||||
|
inhibitedDescription: _("Click Restart to quit these applications and restart the system."),
|
||||||
|
uninhibitedDescription: function(seconds) {
|
||||||
|
return ngettext("The system will restart automatically in %d second.",
|
||||||
|
"The system will restart automatically in %d seconds.",
|
||||||
|
seconds).format(seconds);
|
||||||
|
},
|
||||||
|
endDescription: _("Restarting the system."),
|
||||||
|
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||||
|
label: C_("button", "Restart") }],
|
||||||
|
iconName: 'system-shutdown',
|
||||||
|
iconStyleClass: 'end-session-dialog-shutdown-icon'
|
||||||
|
};
|
||||||
|
|
||||||
|
const DialogContent = {
|
||||||
|
0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */: logoutDialogContent,
|
||||||
|
1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */: shutdownDialogContent,
|
||||||
|
2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */: restartDialogContent
|
||||||
|
};
|
||||||
|
|
||||||
|
function findAppFromInhibitor(inhibitor) {
|
||||||
|
let desktopFile = inhibitor.app_id;
|
||||||
|
|
||||||
|
if (!GLib.str_has_suffix(desktopFile, '.desktop'))
|
||||||
|
desktopFile += '.desktop';
|
||||||
|
|
||||||
|
let candidateDesktopFiles = [];
|
||||||
|
|
||||||
|
candidateDesktopFiles.push(desktopFile);
|
||||||
|
candidateDesktopFiles.push('gnome-' + desktopFile);
|
||||||
|
|
||||||
|
let appSystem = Shell.AppSystem.get_default();
|
||||||
|
let app = null;
|
||||||
|
for (let i = 0; i < candidateDesktopFiles.length; i++) {
|
||||||
|
try {
|
||||||
|
app = appSystem.lookup_app(candidateDesktopFiles[i]);
|
||||||
|
|
||||||
|
if (app)
|
||||||
|
break;
|
||||||
|
} catch(e) {
|
||||||
|
// ignore errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListItem = new Lang.Class({
|
||||||
|
Name: 'ListItem',
|
||||||
|
|
||||||
|
_init: function(app, reason) {
|
||||||
|
this._app = app;
|
||||||
|
this._reason = reason;
|
||||||
|
|
||||||
|
if (this._reason == null)
|
||||||
|
this._reason = '';
|
||||||
|
|
||||||
|
let layout = new St.BoxLayout({ vertical: false});
|
||||||
|
|
||||||
|
this.actor = new St.Button({ style_class: 'end-session-dialog-app-list-item',
|
||||||
|
can_focus: true,
|
||||||
|
child: layout,
|
||||||
|
reactive: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
x_fill: true });
|
||||||
|
|
||||||
|
this._icon = this._app.create_icon_texture(_ITEM_ICON_SIZE);
|
||||||
|
|
||||||
|
let iconBin = new St.Bin({ style_class: 'end-session-dialog-app-list-item-icon',
|
||||||
|
child: this._icon });
|
||||||
|
layout.add(iconBin);
|
||||||
|
|
||||||
|
let textLayout = new St.BoxLayout({ style_class: 'end-session-dialog-app-list-item-text-box',
|
||||||
|
vertical: true });
|
||||||
|
layout.add(textLayout);
|
||||||
|
|
||||||
|
this._nameLabel = new St.Label({ text: this._app.get_name(),
|
||||||
|
style_class: 'end-session-dialog-app-list-item-name' });
|
||||||
|
textLayout.add(this._nameLabel,
|
||||||
|
{ expand: false,
|
||||||
|
x_fill: true });
|
||||||
|
|
||||||
|
this._descriptionLabel = new St.Label({ text: this._reason,
|
||||||
|
style_class: 'end-session-dialog-app-list-item-description' });
|
||||||
|
textLayout.add(this._descriptionLabel,
|
||||||
|
{ expand: true,
|
||||||
|
x_fill: true });
|
||||||
|
|
||||||
|
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onClicked: function() {
|
||||||
|
this.emit('activate');
|
||||||
|
this._app.activate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(ListItem.prototype);
|
||||||
|
|
||||||
|
// The logout timer only shows updates every 10 seconds
|
||||||
|
// until the last 10 seconds, then it shows updates every
|
||||||
|
// second. This function takes a given time and returns
|
||||||
|
// what we should show to the user for that time.
|
||||||
|
function _roundSecondsToInterval(totalSeconds, secondsLeft, interval) {
|
||||||
|
let time;
|
||||||
|
|
||||||
|
time = Math.ceil(secondsLeft);
|
||||||
|
|
||||||
|
// Final count down is in decrements of 1
|
||||||
|
if (time <= interval)
|
||||||
|
return time;
|
||||||
|
|
||||||
|
// Round up higher than last displayable time interval
|
||||||
|
time += interval - 1;
|
||||||
|
|
||||||
|
// Then round down to that time interval
|
||||||
|
if (time > totalSeconds)
|
||||||
|
time = Math.ceil(totalSeconds);
|
||||||
|
else
|
||||||
|
time -= time % interval;
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _setLabelText(label, text) {
|
||||||
|
if (text) {
|
||||||
|
label.set_text(text);
|
||||||
|
label.show();
|
||||||
|
} else {
|
||||||
|
label.set_text('');
|
||||||
|
label.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
// This always returns the same singleton object
|
||||||
|
// By instantiating it initially, we register the
|
||||||
|
// bus object, etc.
|
||||||
|
_endSessionDialog = new EndSessionDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
const EndSessionDialog = new Lang.Class({
|
||||||
|
Name: 'EndSessionDialog',
|
||||||
|
Extends: ModalDialog.ModalDialog,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent({ styleClass: 'end-session-dialog' });
|
||||||
|
|
||||||
|
this._user = AccountsService.UserManager.get_default().get_user(GLib.get_user_name());
|
||||||
|
|
||||||
|
this._secondsLeft = 0;
|
||||||
|
this._totalSecondsToStayOpen = 0;
|
||||||
|
this._inhibitors = [];
|
||||||
|
|
||||||
|
this.connect('destroy',
|
||||||
|
Lang.bind(this, this._onDestroy));
|
||||||
|
this.connect('opened',
|
||||||
|
Lang.bind(this, this._onOpened));
|
||||||
|
|
||||||
|
this._userLoadedId = this._user.connect('notify::is_loaded',
|
||||||
|
Lang.bind(this, this._updateContent));
|
||||||
|
|
||||||
|
this._userChangedId = this._user.connect('changed',
|
||||||
|
Lang.bind(this, this._updateContent));
|
||||||
|
|
||||||
|
let mainContentLayout = new St.BoxLayout({ vertical: false });
|
||||||
|
this.contentLayout.add(mainContentLayout,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: false });
|
||||||
|
|
||||||
|
this._iconBin = new St.Bin();
|
||||||
|
mainContentLayout.add(this._iconBin,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.END,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
let messageLayout = new St.BoxLayout({ vertical: true });
|
||||||
|
mainContentLayout.add(messageLayout,
|
||||||
|
{ y_align: St.Align.START });
|
||||||
|
|
||||||
|
this._subjectLabel = new St.Label({ style_class: 'end-session-dialog-subject' });
|
||||||
|
|
||||||
|
messageLayout.add(this._subjectLabel,
|
||||||
|
{ y_fill: false,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
this._descriptionLabel = new St.Label({ style_class: 'end-session-dialog-description' });
|
||||||
|
this._descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
|
this._descriptionLabel.clutter_text.line_wrap = true;
|
||||||
|
|
||||||
|
messageLayout.add(this._descriptionLabel,
|
||||||
|
{ y_fill: true,
|
||||||
|
y_align: St.Align.START });
|
||||||
|
|
||||||
|
let scrollView = new St.ScrollView({ style_class: 'end-session-dialog-app-list'});
|
||||||
|
scrollView.set_policy(Gtk.PolicyType.NEVER,
|
||||||
|
Gtk.PolicyType.AUTOMATIC);
|
||||||
|
this.contentLayout.add(scrollView,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: true });
|
||||||
|
scrollView.hide();
|
||||||
|
|
||||||
|
this._applicationList = new St.BoxLayout({ vertical: true });
|
||||||
|
scrollView.add_actor(this._applicationList,
|
||||||
|
{ x_fill: true,
|
||||||
|
y_fill: true,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
|
||||||
|
this._applicationList.connect('actor-added',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
if (this._applicationList.get_children().length == 1)
|
||||||
|
scrollView.show();
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._applicationList.connect('actor-removed',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
if (this._applicationList.get_children().length == 0)
|
||||||
|
scrollView.hide();
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(EndSessionDialogIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDestroy: function() {
|
||||||
|
this._user.disconnect(this._userLoadedId);
|
||||||
|
this._user.disconnect(this._userChangedId);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setIconFromFile: function(iconFile, styleClass) {
|
||||||
|
if (styleClass)
|
||||||
|
this._iconBin.set_style_class_name(styleClass);
|
||||||
|
this._iconBin.set_style(null);
|
||||||
|
|
||||||
|
this._iconBin.child = null;
|
||||||
|
if (iconFile) {
|
||||||
|
this._iconBin.show();
|
||||||
|
this._iconBin.set_style('background-image: url("' + iconFile + '");');
|
||||||
|
} else {
|
||||||
|
this._iconBin.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_setIconFromName: function(iconName, styleClass) {
|
||||||
|
if (styleClass)
|
||||||
|
this._iconBin.set_style_class_name(styleClass);
|
||||||
|
this._iconBin.set_style(null);
|
||||||
|
|
||||||
|
if (iconName != null) {
|
||||||
|
let textureCache = St.TextureCache.get_default();
|
||||||
|
let icon = textureCache.load_icon_name(this._iconBin.get_theme_node(),
|
||||||
|
iconName,
|
||||||
|
St.IconType.SYMBOLIC,
|
||||||
|
_DIALOG_ICON_SIZE);
|
||||||
|
|
||||||
|
this._iconBin.child = icon;
|
||||||
|
this._iconBin.show();
|
||||||
|
} else {
|
||||||
|
this._iconBin.child = null;
|
||||||
|
this._iconBin.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateContent: function() {
|
||||||
|
if (this.state != ModalDialog.State.OPENING &&
|
||||||
|
this.state != ModalDialog.State.OPENED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let dialogContent = DialogContent[this._type];
|
||||||
|
|
||||||
|
let subject = dialogContent.subject;
|
||||||
|
let description;
|
||||||
|
|
||||||
|
if (this._user.is_loaded && !dialogContent.iconName) {
|
||||||
|
let iconFile = this._user.get_icon_file();
|
||||||
|
if (GLib.file_test(iconFile, GLib.FileTest.EXISTS))
|
||||||
|
this._setIconFromFile(iconFile, dialogContent.iconStyleClass);
|
||||||
|
else
|
||||||
|
this._setIconFromName('avatar-default', dialogContent.iconStyleClass);
|
||||||
|
} else if (dialogContent.iconName) {
|
||||||
|
this._setIconFromName(dialogContent.iconName,
|
||||||
|
dialogContent.iconStyleClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._inhibitors.length > 0) {
|
||||||
|
this._stopTimer();
|
||||||
|
description = dialogContent.inhibitedDescription;
|
||||||
|
} else if (this._secondsLeft > 0 && this._inhibitors.length == 0) {
|
||||||
|
let displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen,
|
||||||
|
this._secondsLeft,
|
||||||
|
10);
|
||||||
|
|
||||||
|
if (this._user.is_loaded) {
|
||||||
|
let realName = this._user.get_real_name();
|
||||||
|
|
||||||
|
if (realName != null) {
|
||||||
|
if (dialogContent.subjectWithUser)
|
||||||
|
subject = dialogContent.subjectWithUser.format(realName);
|
||||||
|
|
||||||
|
if (dialogContent.uninhibitedDescriptionWithUser)
|
||||||
|
description = dialogContent.uninhibitedDescriptionWithUser(realName, displayTime);
|
||||||
|
else
|
||||||
|
description = dialogContent.uninhibitedDescription(displayTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!description)
|
||||||
|
description = dialogContent.uninhibitedDescription(displayTime);
|
||||||
|
} else {
|
||||||
|
description = dialogContent.endDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
_setLabelText(this._subjectLabel, subject);
|
||||||
|
_setLabelText(this._descriptionLabel, description);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateButtons: function() {
|
||||||
|
let dialogContent = DialogContent[this._type];
|
||||||
|
let buttons = [{ action: Lang.bind(this, this.cancel),
|
||||||
|
label: _("Cancel"),
|
||||||
|
key: Clutter.Escape }];
|
||||||
|
|
||||||
|
for (let i = 0; i < dialogContent.confirmButtons.length; i++) {
|
||||||
|
let signal = dialogContent.confirmButtons[i].signal;
|
||||||
|
let label = dialogContent.confirmButtons[i].label;
|
||||||
|
buttons.push({ action: Lang.bind(this, function() {
|
||||||
|
this._confirm(signal);
|
||||||
|
}),
|
||||||
|
label: label });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setButtons(buttons);
|
||||||
|
},
|
||||||
|
|
||||||
|
close: function() {
|
||||||
|
this.parent();
|
||||||
|
this._dbusImpl.emit_signal('Closed', null);
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel: function() {
|
||||||
|
this._stopTimer();
|
||||||
|
this._dbusImpl.emit_signal('Canceled', null);
|
||||||
|
this.close(global.get_current_time());
|
||||||
|
},
|
||||||
|
|
||||||
|
_confirm: function(signal) {
|
||||||
|
this._fadeOutDialog();
|
||||||
|
this._stopTimer();
|
||||||
|
this._dbusImpl.emit_signal(signal, null);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onOpened: function() {
|
||||||
|
if (this._inhibitors.length == 0)
|
||||||
|
this._startTimer();
|
||||||
|
},
|
||||||
|
|
||||||
|
_startTimer: function() {
|
||||||
|
this._secondsLeft = this._totalSecondsToStayOpen;
|
||||||
|
Tweener.addTween(this,
|
||||||
|
{ _secondsLeft: 0,
|
||||||
|
time: this._secondsLeft,
|
||||||
|
transition: 'linear',
|
||||||
|
onUpdate: Lang.bind(this, this._updateContent),
|
||||||
|
onComplete: Lang.bind(this, function() {
|
||||||
|
let dialogContent = DialogContent[this._type];
|
||||||
|
let button = dialogContent.confirmButtons[dialogContent.confirmButtons.length - 1];
|
||||||
|
this._confirm(button.signal);
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_stopTimer: function() {
|
||||||
|
Tweener.removeTweens(this);
|
||||||
|
this._secondsLeft = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onInhibitorLoaded: function(inhibitor) {
|
||||||
|
if (this._inhibitors.indexOf(inhibitor) < 0) {
|
||||||
|
// Stale inhibitor
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let app = findAppFromInhibitor(inhibitor);
|
||||||
|
|
||||||
|
if (app) {
|
||||||
|
let item = new ListItem(app, inhibitor.reason);
|
||||||
|
item.connect('activate',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this.close(global.get_current_time());
|
||||||
|
}));
|
||||||
|
this._applicationList.add(item.actor, { x_fill: true });
|
||||||
|
this._stopTimer();
|
||||||
|
} else {
|
||||||
|
// inhibiting app is a service, not an application
|
||||||
|
this._inhibitors.splice(this._inhibitors.indexOf(inhibitor), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateContent();
|
||||||
|
},
|
||||||
|
|
||||||
|
OpenAsync: function(parameters, invocation) {
|
||||||
|
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
|
||||||
|
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
|
||||||
|
this._inhibitors = [];
|
||||||
|
this._applicationList.destroy_children();
|
||||||
|
this._type = type;
|
||||||
|
|
||||||
|
if (!(this._type in DialogContent)) {
|
||||||
|
invocation.report_dbus_error('org.gnome.Shell.ModalDialog.TypeError',
|
||||||
|
"Unknown dialog type requested");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < inhibitorObjectPaths.length; i++) {
|
||||||
|
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], Lang.bind(this, function(proxy, error) {
|
||||||
|
this._onInhibitorLoaded(proxy);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._inhibitors.push(inhibitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateButtons();
|
||||||
|
|
||||||
|
if (!this.open(timestamp)) {
|
||||||
|
invocation.report_dbus_error('org.gnome.Shell.ModalDialog.GrabError',
|
||||||
|
"Cannot grab pointer and keyboard");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateContent();
|
||||||
|
|
||||||
|
let signalId = this.connect('opened',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
invocation.return_value(null);
|
||||||
|
this.disconnect(signalId);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|