Compare commits
908 Commits
3.31.4
...
benzea/sys
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff1b411f74 | ||
|
|
098114f4c8 | ||
|
|
9a49b20fac | ||
|
|
d9775e41b2 | ||
|
|
5796a5d193 | ||
|
|
afefc88e02 | ||
|
|
44cd1ae25b | ||
|
|
f226398c7c | ||
|
|
890ac9ff38 | ||
|
|
6a027cd566 | ||
|
|
1dc971d760 | ||
|
|
dcf0bf0bb1 | ||
|
|
cf156b469c | ||
|
|
da6c154ceb | ||
|
|
957fa910b3 | ||
|
|
8ac5be95d3 | ||
|
|
c27bd62106 | ||
|
|
480e8b8842 | ||
|
|
c6580421b3 | ||
|
|
c2f5331187 | ||
|
|
5d0c403f1d | ||
|
|
20fc4b4490 | ||
|
|
ea3f906f38 | ||
|
|
2c4df6abcf | ||
|
|
67a0b3b98e | ||
|
|
c366e9f3ca | ||
|
|
812a8552e5 | ||
|
|
069d7d6cac | ||
|
|
785a8b78b1 | ||
|
|
2d927639fe | ||
|
|
d5cad10181 | ||
|
|
441a56b916 | ||
|
|
c2a6a6c939 | ||
|
|
15d1aee21a | ||
|
|
f1bc2d56f4 | ||
|
|
6f62965305 | ||
|
|
a6aa0ac74a | ||
|
|
32ed4ee12e | ||
|
|
33a48aecb7 | ||
|
|
3b63062a30 | ||
|
|
b680952197 | ||
|
|
a4ec460f96 | ||
|
|
5bd295842b | ||
|
|
db9a7ea7a9 | ||
|
|
490a62e781 | ||
|
|
d4b8912c0e | ||
|
|
532acf4c4a | ||
|
|
7141c5be6d | ||
|
|
2df7757905 | ||
|
|
9d5c743a98 | ||
|
|
653e6c85bb | ||
|
|
d9fa389079 | ||
|
|
a429fdbd08 | ||
|
|
f9357457bf | ||
|
|
369e400e32 | ||
|
|
07ad4d8911 | ||
|
|
803a096b7e | ||
|
|
1b40abe37a | ||
|
|
0de5209cf1 | ||
|
|
07fad38a50 | ||
|
|
ac4b88f25d | ||
|
|
23a7aa5740 | ||
|
|
0b1e29e5e3 | ||
|
|
c8c93b2a70 | ||
|
|
d8c7cac536 | ||
|
|
5cb02c1cb5 | ||
|
|
10c1df61cd | ||
|
|
387e5ef0f1 | ||
|
|
f8f40f247f | ||
|
|
16cb918e0d | ||
|
|
638b315e40 | ||
|
|
a20b8dc1ad | ||
|
|
4370aee81e | ||
|
|
779e37fbd9 | ||
|
|
6f4c5022eb | ||
|
|
b499ca47a3 | ||
|
|
dc38e48202 | ||
|
|
7efdb97641 | ||
|
|
14fd7c7532 | ||
|
|
21e14bd46f | ||
|
|
f0e1dc5715 | ||
|
|
6b7af407e1 | ||
|
|
d67c64af83 | ||
|
|
5d2e5fe85a | ||
|
|
308da6ae53 | ||
|
|
76eceec1f5 | ||
|
|
209d332a30 | ||
|
|
35dbc3fcc9 | ||
|
|
ada01507a4 | ||
|
|
826ac95726 | ||
|
|
9b7f228f8e | ||
|
|
5d8ea4f9a3 | ||
|
|
4c89eac9a4 | ||
|
|
f76f30fd6a | ||
|
|
488d98289c | ||
|
|
ff3d32dd18 | ||
|
|
be6ce3c5b4 | ||
|
|
21966afbc6 | ||
|
|
68e3f74ffd | ||
|
|
87f5aa7a13 | ||
|
|
1dadbd0cbb | ||
|
|
481490fdc7 | ||
|
|
3114a24d1f | ||
|
|
73850fee02 | ||
|
|
c0047cd11d | ||
|
|
dd9a452594 | ||
|
|
e45c917811 | ||
|
|
fd19906c64 | ||
|
|
54a2773046 | ||
|
|
ec8b7bc7b2 | ||
|
|
ea71172d44 | ||
|
|
5dfa620f86 | ||
|
|
09d5f0779d | ||
|
|
d1880dc987 | ||
|
|
928b49705f | ||
|
|
f50cac3005 | ||
|
|
ec6e1315a5 | ||
|
|
ad55cb6d5d | ||
|
|
0ce0376725 | ||
|
|
015ca2c507 | ||
|
|
21e752e5e4 | ||
|
|
1e20a1249a | ||
|
|
b67c300484 | ||
|
|
8ac2086ed1 | ||
|
|
72defaa97e | ||
|
|
9097c5e9c0 | ||
|
|
79b54f65b4 | ||
|
|
52c2417685 | ||
|
|
9073debe60 | ||
|
|
8b368d010f | ||
|
|
8b97a06961 | ||
|
|
fffe7bdf9c | ||
|
|
ef18f621ac | ||
|
|
dfa41f6926 | ||
|
|
3d3dca4aa2 | ||
|
|
928595fe21 | ||
|
|
fc958f4215 | ||
|
|
0846238f69 | ||
|
|
007b6ca2e8 | ||
|
|
0b4a4487a0 | ||
|
|
99b4e047dd | ||
|
|
ae2af34453 | ||
|
|
fdf24ceecc | ||
|
|
870dd84a50 | ||
|
|
5d6db923b7 | ||
|
|
8eb88d17fe | ||
|
|
abe012b9fc | ||
|
|
749f52fc8b | ||
|
|
1e6cb43815 | ||
|
|
213d10bf4e | ||
|
|
1abfbb82c5 | ||
|
|
bf36d99a33 | ||
|
|
3ee525833e | ||
|
|
bf497ed643 | ||
|
|
9b8c0f7519 | ||
|
|
12ec5d1cbe | ||
|
|
0f178c3b3d | ||
|
|
9aa06e3001 | ||
|
|
00ec8ca989 | ||
|
|
9c6f558c9e | ||
|
|
1c172955ee | ||
|
|
1d44bf7ce6 | ||
|
|
036e41621d | ||
|
|
3003e9091d | ||
|
|
8d9da10710 | ||
|
|
4d23c12028 | ||
|
|
476816732f | ||
|
|
31968ea53c | ||
|
|
7e00d22bfa | ||
|
|
50055004f5 | ||
|
|
abe2f07779 | ||
|
|
277f0d77f3 | ||
|
|
01d2ad760a | ||
|
|
25f118bf2c | ||
|
|
12b8fb15b1 | ||
|
|
5295866eff | ||
|
|
02b47f4640 | ||
|
|
108ac7cf20 | ||
|
|
933c037c6e | ||
|
|
8f3554ff3e | ||
|
|
668128f8c9 | ||
|
|
28ab1f4af4 | ||
|
|
d360114226 | ||
|
|
5fc456d9d9 | ||
|
|
007d305736 | ||
|
|
ae7ec648b2 | ||
|
|
99a2fad311 | ||
|
|
82d466598c | ||
|
|
3a748fe737 | ||
|
|
89ce53e3ff | ||
|
|
2f29081667 | ||
|
|
cb0d28770f | ||
|
|
86c3909908 | ||
|
|
b970ee7293 | ||
|
|
5545e84430 | ||
|
|
85d9f39417 | ||
|
|
a81450df17 | ||
|
|
a7c94b2cd2 | ||
|
|
9d65c8b2ec | ||
|
|
1b7ff76092 | ||
|
|
17e32bf16d | ||
|
|
74905f3edc | ||
|
|
8e1b13ca96 | ||
|
|
c0e90807e0 | ||
|
|
3db1058c2c | ||
|
|
a57c4c580e | ||
|
|
33bbbdc322 | ||
|
|
5826336a77 | ||
|
|
3b5d13a0b2 | ||
|
|
ed37ba1d9b | ||
|
|
8ea6fd1925 | ||
|
|
93a461f3f7 | ||
|
|
fda7c9b06e | ||
|
|
1e13f32cea | ||
|
|
e357559582 | ||
|
|
71759a0769 | ||
|
|
11b116cb9d | ||
|
|
2f97a1a55d | ||
|
|
79cf3a6dd0 | ||
|
|
0257de1b7e | ||
|
|
466dc8da8f | ||
|
|
2c61badc02 | ||
|
|
3f8d3a7ee2 | ||
|
|
a455860978 | ||
|
|
0ecf135a4b | ||
|
|
cebb6d40df | ||
|
|
0ee13672ee | ||
|
|
49260a85ad | ||
|
|
da9f37e629 | ||
|
|
164f3fa3fd | ||
|
|
8e75d81a44 | ||
|
|
1d60c4d9d4 | ||
|
|
eaa32090b9 | ||
|
|
32ddb6f739 | ||
|
|
2653402c5c | ||
|
|
2743f18af4 | ||
|
|
dd1fdf88ff | ||
|
|
2a041e9d8d | ||
|
|
1117f4760c | ||
|
|
7dda7abf5e | ||
|
|
7ca3cca306 | ||
|
|
d471e3a23b | ||
|
|
ce1bee727a | ||
|
|
43cb3754d9 | ||
|
|
1d6ddf060b | ||
|
|
9928125e7d | ||
|
|
1c63893c4b | ||
|
|
a7ec7583aa | ||
|
|
4a3476266f | ||
|
|
32e0b895a4 | ||
|
|
58806359ee | ||
|
|
4589da957b | ||
|
|
6a4c55b852 | ||
|
|
ea17740719 | ||
|
|
d82810240f | ||
|
|
2768b73015 | ||
|
|
f9a7718dda | ||
|
|
d9d9778a98 | ||
|
|
bd5162105e | ||
|
|
208c5e9562 | ||
|
|
305e63750e | ||
|
|
ab0f74aa15 | ||
|
|
43443d08ae | ||
|
|
b82b553b9e | ||
|
|
08464eadff | ||
|
|
49e56776e8 | ||
|
|
043667dde5 | ||
|
|
f583a7c6d8 | ||
|
|
2d908e80fc | ||
|
|
8f0e9abe47 | ||
|
|
1a27ff6130 | ||
|
|
3f2cffc2e6 | ||
|
|
a78527050a | ||
|
|
a823a213ba | ||
|
|
2c8d380e67 | ||
|
|
3996309f8a | ||
|
|
bd18313d12 | ||
|
|
2ff7a78b56 | ||
|
|
c765082f72 | ||
|
|
7d2c5c1ac9 | ||
|
|
404bc34089 | ||
|
|
16ca7a21a7 | ||
|
|
1b31fd5afe | ||
|
|
e0457b6dc4 | ||
|
|
42b77e7ba5 | ||
|
|
f6bed08993 | ||
|
|
5f77cdb0b9 | ||
|
|
109b8e8f38 | ||
|
|
4c0bd88a2c | ||
|
|
3731be9947 | ||
|
|
6cc19ee6f0 | ||
|
|
1570f838f3 | ||
|
|
74feb110b5 | ||
|
|
6ba03ac2a6 | ||
|
|
55c717c2dc | ||
|
|
355b5eebec | ||
|
|
51938c398a | ||
|
|
dbb71f0dfc | ||
|
|
1cac7b2218 | ||
|
|
ff9bb5399b | ||
|
|
68e45eb051 | ||
|
|
d0da96ad29 | ||
|
|
55b036170b | ||
|
|
5473637736 | ||
|
|
bb6d9734e4 | ||
|
|
53be76c9e2 | ||
|
|
be40de5a9b | ||
|
|
7359e431d3 | ||
|
|
8a5de327bb | ||
|
|
1778adae0d | ||
|
|
0d035a4e53 | ||
|
|
46874eed05 | ||
|
|
e95f3febd6 | ||
|
|
0bdd1b6fc4 | ||
|
|
8a22092632 | ||
|
|
915415d919 | ||
|
|
14d7897a93 | ||
|
|
1398aa6562 | ||
|
|
8fcd6c7153 | ||
|
|
6ed5bc2f6c | ||
|
|
5ec4c2e43e | ||
|
|
6f8dd065a4 | ||
|
|
02db21fc55 | ||
|
|
8c28f9a77d | ||
|
|
95b80eec01 | ||
|
|
02c76695e5 | ||
|
|
d5a1a888d9 | ||
|
|
6c33aff6d1 | ||
|
|
61f86cbc54 | ||
|
|
4c5206954a | ||
|
|
8fda3116f0 | ||
|
|
7ac35c644e | ||
|
|
29b04fcbf2 | ||
|
|
55235c2552 | ||
|
|
f250643385 | ||
|
|
d008c6c5c5 | ||
|
|
e2e02c9a2f | ||
|
|
e56d7f5021 | ||
|
|
e7d44bb349 | ||
|
|
321730fcb9 | ||
|
|
fe83cd91bb | ||
|
|
0b08ee54bb | ||
|
|
f6b4b96737 | ||
|
|
b87455c089 | ||
|
|
2c1a81f448 | ||
|
|
b3736f45e6 | ||
|
|
3c382c4bbe | ||
|
|
5f3bad9c94 | ||
|
|
6970f43e66 | ||
|
|
9476aa598a | ||
|
|
69725e5d41 | ||
|
|
42dabef8c7 | ||
|
|
e10a768ddb | ||
|
|
a8f0787c91 | ||
|
|
074129682b | ||
|
|
c67460a1e3 | ||
|
|
eab320dab5 | ||
|
|
04c7cb6fbe | ||
|
|
d4582491f5 | ||
|
|
0641b1e279 | ||
|
|
ae0450b68e | ||
|
|
cb0a5de83b | ||
|
|
2f5086efaf | ||
|
|
68e580e394 | ||
|
|
b143869d5d | ||
|
|
6a477be874 | ||
|
|
03bb8cdcbd | ||
|
|
8864816b94 | ||
|
|
751cd2f1c1 | ||
|
|
6f6b6fb9d6 | ||
|
|
fe346b89f0 | ||
|
|
0744c6af2e | ||
|
|
2e070ab834 | ||
|
|
00f9b7bf69 | ||
|
|
94ba52af0c | ||
|
|
44e1a6ce06 | ||
|
|
ccf646f54a | ||
|
|
4e84b46c9b | ||
|
|
b4797956c7 | ||
|
|
c1c45f95af | ||
|
|
ac09e0110a | ||
|
|
0e37cd2ec9 | ||
|
|
76dc77f617 | ||
|
|
cb4c0d32c0 | ||
|
|
3d4ba028c4 | ||
|
|
5481c1899f | ||
|
|
2fd120162f | ||
|
|
523ba5a719 | ||
|
|
07d25cd69d | ||
|
|
520cea9394 | ||
|
|
58c4212cfa | ||
|
|
7059e31f6a | ||
|
|
a9234f7631 | ||
|
|
1e5a8b0cd7 | ||
|
|
5ef343f245 | ||
|
|
22e33b4c47 | ||
|
|
5ace4682bf | ||
|
|
14d9839ed3 | ||
|
|
3b6fae582b | ||
|
|
3cbdf4f9a5 | ||
|
|
d8825e0d12 | ||
|
|
3c5fea59df | ||
|
|
443c8347ea | ||
|
|
ee3f52c097 | ||
|
|
4b01bb6f99 | ||
|
|
27ef8154dc | ||
|
|
0a7e717e0e | ||
|
|
2d2824b947 | ||
|
|
40c2a403ac | ||
|
|
238b87d386 | ||
|
|
8c01d341c7 | ||
|
|
866629b3d3 | ||
|
|
2b3ab3ecec | ||
|
|
759120b95f | ||
|
|
de0e21612c | ||
|
|
83e83444db | ||
|
|
5060aee7b2 | ||
|
|
12bace2721 | ||
|
|
2c45b5416e | ||
|
|
96c2473317 | ||
|
|
6359d6ef30 | ||
|
|
2f6323afc2 | ||
|
|
d25bcbc3a7 | ||
|
|
dd5d7d3b70 | ||
|
|
771b1a0788 | ||
|
|
5a9d094f3e | ||
|
|
9ca8433170 | ||
|
|
0ada312748 | ||
|
|
88697add1b | ||
|
|
4730b7a094 | ||
|
|
aa3e64aec3 | ||
|
|
af26e2b212 | ||
|
|
8167f20972 | ||
|
|
bd4aac8f49 | ||
|
|
785dd5c5f7 | ||
|
|
71e469a59c | ||
|
|
6d4b9d29b8 | ||
|
|
33f5bb39cd | ||
|
|
a1c3900630 | ||
|
|
cdaf164c01 | ||
|
|
2bd80579ed | ||
|
|
54039c3552 | ||
|
|
b197a1affb | ||
|
|
51655be6a3 | ||
|
|
9697c209c0 | ||
|
|
6ecb0a4546 | ||
|
|
30861d4800 | ||
|
|
a23391ea28 | ||
|
|
58e0b80cac | ||
|
|
41dd744b74 | ||
|
|
bdf66d7b62 | ||
|
|
4258ae3ec2 | ||
|
|
9b379c49ba | ||
|
|
7e70dd8453 | ||
|
|
2e209a82f9 | ||
|
|
ab0ecc469f | ||
|
|
7d75ddf635 | ||
|
|
271e43a1ed | ||
|
|
2702a82896 | ||
|
|
8ad33d8752 | ||
|
|
d84bbb8770 | ||
|
|
c0c2edf2e1 | ||
|
|
de0c3251dd | ||
|
|
0afd600ea4 | ||
|
|
598407b14a | ||
|
|
d9bfa16f05 | ||
|
|
03117d65b2 | ||
|
|
5520bb3890 | ||
|
|
4e6b2eb72a | ||
|
|
2e5295b3a9 | ||
|
|
3121c9aa29 | ||
|
|
1ebbd7c768 | ||
|
|
8572bb97c7 | ||
|
|
d5ebd8c816 | ||
|
|
ed999ce926 | ||
|
|
50b7739076 | ||
|
|
94995e9c1e | ||
|
|
fb04dafb0b | ||
|
|
d57234bec9 | ||
|
|
38da54fb02 | ||
|
|
bbd3275dad | ||
|
|
3a3f9aa008 | ||
|
|
3c54e863e6 | ||
|
|
a63ba61194 | ||
|
|
ab9710ee7b | ||
|
|
43cef45229 | ||
|
|
8db4f3c67f | ||
|
|
594a070029 | ||
|
|
c2e04e3cfa | ||
|
|
293f50e8e5 | ||
|
|
df7fea3407 | ||
|
|
563412698a | ||
|
|
2b30146c6c | ||
|
|
0f531d8c44 | ||
|
|
218c87994b | ||
|
|
f74c07b9ac | ||
|
|
59edea4bb4 | ||
|
|
4d4d5a0b16 | ||
|
|
03c4930883 | ||
|
|
9593e20425 | ||
|
|
2b1d6e607f | ||
|
|
1dff32e48a | ||
|
|
1e3a174de9 | ||
|
|
7bb84dae80 | ||
|
|
44fcb9e9af | ||
|
|
2d30e310bc | ||
|
|
be2d630348 | ||
|
|
bea6045aae | ||
|
|
ad491e7922 | ||
|
|
fedb8e706a | ||
|
|
1be933bc49 | ||
|
|
526bb72f3d | ||
|
|
49c95cff6c | ||
|
|
56a361650c | ||
|
|
d4763b157d | ||
|
|
d2dc072ba9 | ||
|
|
ffaca00594 | ||
|
|
9090b7dc3d | ||
|
|
a540fe4130 | ||
|
|
5be61bbb68 | ||
|
|
8e51fee5c1 | ||
|
|
9d6fcfdc85 | ||
|
|
5f5a3b78a5 | ||
|
|
4e5ca6d376 | ||
|
|
2fab75f448 | ||
|
|
22883f2fa2 | ||
|
|
5d9f80bc73 | ||
|
|
f7d117488b | ||
|
|
244a329ee7 | ||
|
|
044572cb60 | ||
|
|
746875258d | ||
|
|
4892a87dfe | ||
|
|
8b9c8ddb1e | ||
|
|
eb9000576c | ||
|
|
862aaf341e | ||
|
|
a5c75ff58b | ||
|
|
4541fb9819 | ||
|
|
9f8edd980c | ||
|
|
e5b9043435 | ||
|
|
c0012c2ea4 | ||
|
|
b77e4975f0 | ||
|
|
e83f2344f6 | ||
|
|
de6512be1a | ||
|
|
0b72ff1896 | ||
|
|
fea0192772 | ||
|
|
f81ac498fb | ||
|
|
5357e0a18c | ||
|
|
d7632bbd3d | ||
|
|
1b5e91e4b3 | ||
|
|
727195c767 | ||
|
|
9158f55360 | ||
|
|
8146e9d527 | ||
|
|
4247251020 | ||
|
|
7eee0e0ed6 | ||
|
|
4f0851ca77 | ||
|
|
911ae49767 | ||
|
|
5af81d4057 | ||
|
|
c435889baa | ||
|
|
49f79d9d5d | ||
|
|
1767cd0f6c | ||
|
|
3e0915521a | ||
|
|
a298943fac | ||
|
|
df9ddf96a5 | ||
|
|
4fa5d701d5 | ||
|
|
b05683d586 | ||
|
|
2f3f3fbcdb | ||
|
|
611605a67f | ||
|
|
0427a782be | ||
|
|
32baff5906 | ||
|
|
0089143d06 | ||
|
|
05e55cee23 | ||
|
|
31e7f0340f | ||
|
|
6e317a54fd | ||
|
|
9c1f62c38c | ||
|
|
1341d5557f | ||
|
|
b7d79a5f06 | ||
|
|
62233a4db4 | ||
|
|
4a7e2ddff5 | ||
|
|
fb737ebde0 | ||
|
|
bf77cb44e7 | ||
|
|
c72e2bb4a9 | ||
|
|
68c182b1df | ||
|
|
348d303794 | ||
|
|
ede0fd8660 | ||
|
|
187c2193e8 | ||
|
|
706bdd8059 | ||
|
|
436861edc8 | ||
|
|
9729a2e772 | ||
|
|
6b924c00c5 | ||
|
|
b90f4d29a4 | ||
|
|
47915f8c11 | ||
|
|
5dfdeaa4ea | ||
|
|
98a2a81f2a | ||
|
|
c4850027bc | ||
|
|
d4202e7f38 | ||
|
|
4f65283f31 | ||
|
|
d86d3bbe54 | ||
|
|
6f794738e8 | ||
|
|
ef7a93bb07 | ||
|
|
5197a992a6 | ||
|
|
49d8540f6d | ||
|
|
6e1a1f1a57 | ||
|
|
c73428247c | ||
|
|
fc2caf5794 | ||
|
|
b117826ada | ||
|
|
26b44b48ab | ||
|
|
6349f0feb1 | ||
|
|
2ae17cfb50 | ||
|
|
4785093a5c | ||
|
|
859aef78c4 | ||
|
|
20730a5465 | ||
|
|
fc5f687afc | ||
|
|
53e56f2395 | ||
|
|
da314aff79 | ||
|
|
fe89f7c5ac | ||
|
|
8b3be5e063 | ||
|
|
58dc538510 | ||
|
|
6cbef9355d | ||
|
|
22eac5c508 | ||
|
|
a2860e9c73 | ||
|
|
1c5258ab68 | ||
|
|
8641eaa538 | ||
|
|
88436383c0 | ||
|
|
affdcdcb0e | ||
|
|
06174be777 | ||
|
|
fde8401124 | ||
|
|
70ac33d58c | ||
|
|
5a897407d9 | ||
|
|
1b3c26364b | ||
|
|
ae07aa7864 | ||
|
|
fb80831269 | ||
|
|
561cecf383 | ||
|
|
60ccdc2deb | ||
|
|
d7d996b1d3 | ||
|
|
32b8bc39ac | ||
|
|
9dc99ad611 | ||
|
|
628cb4d553 | ||
|
|
ad80bce78d | ||
|
|
1c9d821aa2 | ||
|
|
510b060947 | ||
|
|
26e33ff093 | ||
|
|
5f2bd70690 | ||
|
|
6dfa550663 | ||
|
|
252e2420ad | ||
|
|
572d54981e | ||
|
|
61471f9fb4 | ||
|
|
4d0a742d64 | ||
|
|
5f4e0e5ff8 | ||
|
|
a4c159ecad | ||
|
|
b1f893e998 | ||
|
|
789dc165af | ||
|
|
115eda9650 | ||
|
|
d027e35cef | ||
|
|
b3e178af9d | ||
|
|
559ec8750a | ||
|
|
02c3980b83 | ||
|
|
6f027ee7dc | ||
|
|
6d6c2e5b99 | ||
|
|
4a4f752459 | ||
|
|
8f1fff1374 | ||
|
|
deead2af97 | ||
|
|
9e881ab637 | ||
|
|
b6ec02cef2 | ||
|
|
26e3ccda49 | ||
|
|
2bda79cb3a | ||
|
|
19c60ff5c5 | ||
|
|
e3c5c9a2e7 | ||
|
|
2c17c186b8 | ||
|
|
ef1697d00d | ||
|
|
40e7638a4b | ||
|
|
aaf69b2898 | ||
|
|
0464361ca5 | ||
|
|
420697693b | ||
|
|
37f53a42da | ||
|
|
5617ffc79c | ||
|
|
ca4d86e9e5 | ||
|
|
0141fef561 | ||
|
|
5d4a804c90 | ||
|
|
6bc3300e5a | ||
|
|
15f69bdc3b | ||
|
|
0bcf76970a | ||
|
|
03c4628cad | ||
|
|
9f4ae9618a | ||
|
|
3590af15bb | ||
|
|
c5de7fd20e | ||
|
|
7127fb1fa1 | ||
|
|
7cf11abefc | ||
|
|
d78b416e1a | ||
|
|
f5144ec899 | ||
|
|
08d1ebe7ee | ||
|
|
a665801e9f | ||
|
|
112e3b110b | ||
|
|
94a674c008 | ||
|
|
72be8eeb31 | ||
|
|
ad8690bb2e | ||
|
|
76cb08a72a | ||
|
|
2d4989e937 | ||
|
|
f248b91f82 | ||
|
|
d671eb1969 | ||
|
|
70f4906ca5 | ||
|
|
ffb9aa1ace | ||
|
|
823fd855cf | ||
|
|
f5ee225362 | ||
|
|
ff1ea4b1c9 | ||
|
|
779b5afa51 | ||
|
|
6d870f6ae4 | ||
|
|
d3926cbca9 | ||
|
|
a308804679 | ||
|
|
a4e4da705a | ||
|
|
7a494ec027 | ||
|
|
d53ebb101a | ||
|
|
f3168d22a6 | ||
|
|
be06101e9a | ||
|
|
6e4178981a | ||
|
|
b85ea59cda | ||
|
|
bbd68626cc | ||
|
|
8490173879 | ||
|
|
baed9518c2 | ||
|
|
27d0d9f2b3 | ||
|
|
382282b931 | ||
|
|
23d233857e | ||
|
|
9620bd0f22 | ||
|
|
ecfe56ca63 | ||
|
|
eabb02d3da | ||
|
|
da3953a388 | ||
|
|
2d26dbc96f | ||
|
|
7073471302 | ||
|
|
81f0e7de9e | ||
|
|
33e05f5912 | ||
|
|
c1d3e304cb | ||
|
|
1b169655ac | ||
|
|
67393e09c3 | ||
|
|
1ec8d2c531 | ||
|
|
a111bfb90a | ||
|
|
7dd326f090 | ||
|
|
24a26e025b | ||
|
|
1eb7ba0506 | ||
|
|
d17d99bd6d | ||
|
|
fd50b9a45e | ||
|
|
a1534dab02 | ||
|
|
7484458b7c | ||
|
|
5ca039c1db | ||
|
|
2294ae0c46 | ||
|
|
4d2b2a12ea | ||
|
|
c6d57059ff | ||
|
|
5f13cf767e | ||
|
|
93425b0500 | ||
|
|
a87ab6d0fc | ||
|
|
1c117c469a | ||
|
|
8003f8b803 | ||
|
|
7df93458d7 | ||
|
|
753618a19f | ||
|
|
e355756758 | ||
|
|
62a3b9e6a3 | ||
|
|
dc79393b27 | ||
|
|
c334aa2a4c | ||
|
|
9f61a4f5fd | ||
|
|
15d0050994 | ||
|
|
1846f337d8 | ||
|
|
a9e63039ce | ||
|
|
7edd5f27d1 | ||
|
|
9b47195974 | ||
|
|
4ef8041be0 | ||
|
|
f0a7395b30 | ||
|
|
c1a6effea0 | ||
|
|
f78efc46e7 | ||
|
|
42ae052da7 | ||
|
|
fab390826e | ||
|
|
2a9923628b | ||
|
|
291aa0b053 | ||
|
|
83eb75ad7a | ||
|
|
bb215966e5 | ||
|
|
545d49c70d | ||
|
|
ace44af815 | ||
|
|
699e97559d | ||
|
|
4aecf4c973 | ||
|
|
b092c5f37d | ||
|
|
aca8aec94b | ||
|
|
9cfb51c106 | ||
|
|
e2352f5126 | ||
|
|
40e624444c | ||
|
|
3cf67b1236 | ||
|
|
5dedb97fcc | ||
|
|
4590094605 | ||
|
|
15e7625c80 | ||
|
|
cdd2803498 | ||
|
|
43fb2b38b1 | ||
|
|
95224bd006 | ||
|
|
446183adee | ||
|
|
345a8fe748 | ||
|
|
d8593c5b4a | ||
|
|
f89d721c12 | ||
|
|
af34b7c25e | ||
|
|
b108aa1ace | ||
|
|
5dbf09c008 | ||
|
|
680dc18c6b | ||
|
|
73413ac6c0 | ||
|
|
f61c8e5e1d | ||
|
|
36713db990 | ||
|
|
6bb7d4002f | ||
|
|
aa28d487d3 | ||
|
|
a7d974481c | ||
|
|
3730314dd5 | ||
|
|
6b0c8c9fe0 | ||
|
|
28a56d24ad | ||
|
|
5e6629e1a7 | ||
|
|
a00b967df0 | ||
|
|
193e4ae31e | ||
|
|
409a27c3b8 | ||
|
|
ba97e8da7a | ||
|
|
c47e672eea | ||
|
|
43a19739ab | ||
|
|
36f9147b21 | ||
|
|
8647922df9 | ||
|
|
df3068d9ca | ||
|
|
036e67049b | ||
|
|
f02033acb7 | ||
|
|
91d73d65c3 | ||
|
|
81c4c23016 | ||
|
|
fef2bac8ab | ||
|
|
c59c5eb893 | ||
|
|
a977c1388a | ||
|
|
0f799ae313 | ||
|
|
23c3f3fdea | ||
|
|
82c7090e9e | ||
|
|
0fdfebdb67 | ||
|
|
208c551787 | ||
|
|
b10606e884 | ||
|
|
f4a64f77f2 | ||
|
|
e92477a752 | ||
|
|
37e0a73c8f | ||
|
|
4f76e05058 | ||
|
|
3134222d27 | ||
|
|
a9ed128dce | ||
|
|
c264cc4131 | ||
|
|
a7943ff934 | ||
|
|
c353914dd0 | ||
|
|
91319e3963 | ||
|
|
dc4ff941bd | ||
|
|
b597d5faf0 | ||
|
|
f6da36ad3a | ||
|
|
5f4e2749a2 | ||
|
|
69b1fb699f | ||
|
|
259f90bbf6 | ||
|
|
8665045326 | ||
|
|
a7bb8ee639 | ||
|
|
8f732e4f45 | ||
|
|
95a31b0c31 | ||
|
|
36b9f45368 | ||
|
|
46575804cc | ||
|
|
86a00b6872 | ||
|
|
23d6d13d80 | ||
|
|
09addfc87c | ||
|
|
a2f27a9409 | ||
|
|
412003efbf | ||
|
|
582b3aacf4 | ||
|
|
1af0b54c1e | ||
|
|
74ba2e6634 | ||
|
|
78608a5080 | ||
|
|
7a86637f8d | ||
|
|
c2961f2152 | ||
|
|
6845c6f958 | ||
|
|
794a056819 | ||
|
|
69ad75cf48 | ||
|
|
3db52155dd | ||
|
|
38805ae662 | ||
|
|
dfa0750ffd | ||
|
|
d80e7e0118 | ||
|
|
b7e2718bdc | ||
|
|
e68dfed1f7 | ||
|
|
bacfdbbb03 | ||
|
|
99ce3deeb0 | ||
|
|
d75a3484d6 | ||
|
|
3dcb593a71 | ||
|
|
1847a4f4cc | ||
|
|
deec0bf255 | ||
|
|
8bb9eb0fc9 | ||
|
|
21de3c327b | ||
|
|
081d94e0f6 | ||
|
|
ddd1825162 | ||
|
|
5f223e0bd8 | ||
|
|
809d92129b | ||
|
|
8840608a25 | ||
|
|
edbb204332 | ||
|
|
9dc3b73ef9 | ||
|
|
a7d618915c | ||
|
|
3e3da8e2f8 | ||
|
|
a6763e7731 | ||
|
|
8f15193b40 | ||
|
|
467b7c1bca | ||
|
|
97963a1ca8 | ||
|
|
2fc1f1adbe | ||
|
|
200f4908d5 | ||
|
|
1f864c905d | ||
|
|
df77fb6793 | ||
|
|
3fa3889fa5 | ||
|
|
4b28b90e0f | ||
|
|
e0a992af73 | ||
|
|
7c4e43c84f | ||
|
|
b57832716a | ||
|
|
945a019974 | ||
|
|
22e21ad7d1 | ||
|
|
ae48f8bda9 | ||
|
|
62abf3edc7 | ||
|
|
f8ce47c24d | ||
|
|
ddb3a5c625 | ||
|
|
c6d2bc4c57 | ||
|
|
e3a0b6d4ee |
6
.eslintrc.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": [
|
||||
"./lint/eslintrc-gjs.json",
|
||||
"./lint/eslintrc-shell.json"
|
||||
]
|
||||
}
|
||||
1
.gitignore
vendored
@@ -80,3 +80,4 @@ tests/run-test.sh
|
||||
*~
|
||||
*.patch
|
||||
*.sw?
|
||||
.vscode
|
||||
|
||||
97
.gitlab-ci.yml
Normal file
@@ -0,0 +1,97 @@
|
||||
stages:
|
||||
- review
|
||||
- build
|
||||
- test
|
||||
|
||||
variables:
|
||||
JS_LOG: "js-report.txt"
|
||||
POT_LOG: "pot-update.txt"
|
||||
|
||||
.only_default: &only_default
|
||||
only:
|
||||
- branches
|
||||
- tags
|
||||
- merge_requests
|
||||
|
||||
check_commit_log:
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
|
||||
stage: review
|
||||
variables:
|
||||
GIT_DEPTH: "100"
|
||||
script:
|
||||
- ./.gitlab-ci/check-commit-log.sh
|
||||
only:
|
||||
- merge_requests
|
||||
|
||||
js_check:
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
|
||||
stage: review
|
||||
script:
|
||||
- find js -name '*.js' -exec js60 -c -s '{}' ';' 2>&1 | tee $JS_LOG
|
||||
- (! grep -q . $JS_LOG)
|
||||
<<: *only_default
|
||||
artifacts:
|
||||
paths:
|
||||
- ${JS_LOG}
|
||||
when: on_failure
|
||||
|
||||
eslint:
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-shell/extension-ci:v1
|
||||
stage: review
|
||||
script:
|
||||
- ./.gitlab-ci/run-eslint.sh
|
||||
<<: *only_default
|
||||
artifacts:
|
||||
paths:
|
||||
- reports
|
||||
when: always
|
||||
|
||||
build:
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
|
||||
stage: build
|
||||
before_script:
|
||||
- .gitlab-ci/checkout-mutter.sh
|
||||
- meson mutter mutter/build --prefix=/usr -Dtests=false
|
||||
- ninja -C mutter/build install
|
||||
script:
|
||||
- meson . build -Dbuiltype=debugoptimized -Dman=false
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
<<: *only_default
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- mutter
|
||||
- build
|
||||
|
||||
test:
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
|
||||
stage: test
|
||||
variables:
|
||||
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
|
||||
before_script:
|
||||
- ninja -C mutter/build install
|
||||
script:
|
||||
- xvfb-run meson test -C build --no-rebuild
|
||||
<<: *only_default
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- build/meson-logs/testlog.txt
|
||||
when: on_failure
|
||||
|
||||
test-pot:
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
|
||||
stage: test
|
||||
before_script:
|
||||
- ninja -C mutter/build install
|
||||
script:
|
||||
# Check that pot files are generated correctly:
|
||||
# https://savannah.gnu.org/bugs/?50920#comment5
|
||||
- ninja -C build gnome-shell-pot 2>&1 | awk '
|
||||
BEGIN { start=0; }
|
||||
start==1 { print $0; }
|
||||
/gnome-shell-pot/ { start=1; }
|
||||
' | tee $POT_LOG
|
||||
- (! grep -q . $POT_LOG)
|
||||
<<: *only_default
|
||||
18
.gitlab-ci/Dockerfile.extension-ci
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM registry.fedoraproject.org/fedora:latest
|
||||
|
||||
RUN dnf -y update && dnf -y upgrade && \
|
||||
dnf install -y 'dnf-command(copr)' git && \
|
||||
|
||||
# For syntax checks with `find . -name '*.js' -exec js60 -c -s '{}' ';'`
|
||||
dnf install -y findutils mozjs60-devel && \
|
||||
|
||||
# For static analysis with eslint
|
||||
dnf install -y nodejs && \
|
||||
npm install -g eslint && \
|
||||
|
||||
# Shameless plug for my own tooling; useful for generating zip
|
||||
dnf copr enable -y fmuellner/gnome-shell-ci && \
|
||||
dnf install -y gnome-extensions-tool meson && \
|
||||
|
||||
dnf clean all && \
|
||||
rm -rf /var/cache/dnf
|
||||
31
.gitlab-ci/check-commit-log.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
echo Cannot review non-merge request
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
|
||||
branch_point=$(git merge-base HEAD FETCH_HEAD)
|
||||
|
||||
commits=$(git log --format='format:%H' $branch_point..$CI_COMMIT_SHA)
|
||||
|
||||
if [ -z "$commits" ]; then
|
||||
echo Commit range empty
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function commit_message_has_url() {
|
||||
commit=$1
|
||||
commit_message=$(git show -s --format='format:%b' $commit)
|
||||
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
|
||||
return $?
|
||||
}
|
||||
|
||||
for commit in $commits; do
|
||||
if ! commit_message_has_url $commit; then
|
||||
echo "Missing merge request or issue URL on commit $(echo $commit | cut -c -8)"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
35
.gitlab-ci/checkout-mutter.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
shell_branch=$(git describe --contains --all HEAD)
|
||||
mutter_target=
|
||||
|
||||
git clone https://gitlab.gnome.org/GNOME/mutter.git
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo Checkout failed
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd mutter
|
||||
|
||||
if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//gnome-shell/mutter}
|
||||
merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
|
||||
echo Looking for $merge_request_branch on remote ...
|
||||
if git fetch -q $merge_request_remote $merge_request_branch 2>/dev/null; then
|
||||
mutter_target=FETCH_HEAD
|
||||
else
|
||||
mutter_target=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
echo Using $mutter_target instead
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$mutter_target" ]; then
|
||||
mutter_target=$(git branch -r -l origin/$shell_branch)
|
||||
mutter_target=${mutter_target:-$(git branch -r -l ${shell_branch#remotes/})}
|
||||
mutter_target=${mutter_target:-origin/master}
|
||||
echo Using $mutter_target instead
|
||||
fi
|
||||
|
||||
git checkout -q $mutter_target
|
||||
97
.gitlab-ci/run-eslint.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
OUTPUT_REGULAR=reports/lint-regular-report.txt
|
||||
OUTPUT_LEGACY=reports/lint-legacy-report.txt
|
||||
OUTPUT_FINAL=reports/lint-common-report.txt
|
||||
|
||||
OUTPUT_MR=reports/lint-mr-report.txt
|
||||
|
||||
LINE_CHANGES=changed-lines.txt
|
||||
|
||||
is_empty() {
|
||||
(! grep -q . $1)
|
||||
}
|
||||
|
||||
run_eslint() {
|
||||
ARGS_LEGACY='--config lint/eslintrc-legacy.json'
|
||||
|
||||
local extra_args=ARGS_$1
|
||||
local output=OUTPUT_$1
|
||||
eslint -f unix ${!extra_args} -o ${!output} js
|
||||
}
|
||||
|
||||
list_commit_range_additions() {
|
||||
# Turn raw context-less git-diff into a list of
|
||||
# filename:lineno pairs of new (+) lines
|
||||
git diff -U0 "$@" -- js |
|
||||
awk '
|
||||
BEGIN { file=""; }
|
||||
/^+++ b/ { file=substr($0,7); }
|
||||
/^@@ / {
|
||||
len = split($3,a,",")
|
||||
start=a[1]
|
||||
count=(len > 1) ? a[2] : 1
|
||||
|
||||
for (line=start; line<start+count; line++)
|
||||
printf "%s/%s:%d:\n",ENVIRON["PWD"],file,line;
|
||||
}'
|
||||
}
|
||||
|
||||
copy_matched_lines() {
|
||||
local source=$1
|
||||
local matches=$2
|
||||
local target=$3
|
||||
|
||||
echo -n > $target
|
||||
for l in $(<$matches); do
|
||||
grep $l $source >> $target
|
||||
done
|
||||
}
|
||||
|
||||
create_common() {
|
||||
# comm requires sorted input;
|
||||
# we also strip the error message to make the following a "common" error:
|
||||
# regular:
|
||||
# file.js:42:23 Indentation of 55, expected 42
|
||||
# legacy:
|
||||
# file.js:42:23 Indentation of 55, extected 24
|
||||
prepare() {
|
||||
sed 's: .*::' $1 | sort
|
||||
}
|
||||
|
||||
comm -12 <(prepare $OUTPUT_REGULAR) <(prepare $OUTPUT_LEGACY) >$OUTPUT_FINAL.tmp
|
||||
|
||||
# Now add back the stripped error messages
|
||||
copy_matched_lines $OUTPUT_REGULAR $OUTPUT_FINAL.tmp $OUTPUT_FINAL
|
||||
rm $OUTPUT_FINAL.tmp
|
||||
}
|
||||
|
||||
if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
branch_point=$(git merge-base HEAD FETCH_HEAD)
|
||||
commit_range=$branch_point...$CI_COMMIT_SHA
|
||||
|
||||
list_commit_range_additions $commit_range > $LINE_CHANGES
|
||||
|
||||
# Don't bother with running lint when no JS changed
|
||||
if is_empty $LINE_CHANGES; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo Generating lint report using regular configuration
|
||||
run_eslint REGULAR
|
||||
echo Generating lint report using legacy configuration
|
||||
run_eslint LEGACY
|
||||
echo Done.
|
||||
create_common
|
||||
|
||||
# Just show the report and succeed when not testing a MR
|
||||
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
cat $OUTPUT_FINAL
|
||||
exit 0
|
||||
fi
|
||||
|
||||
copy_matched_lines $OUTPUT_FINAL $LINE_CHANGES $OUTPUT_MR
|
||||
cat $OUTPUT_MR
|
||||
is_empty $OUTPUT_MR
|
||||
31
.project
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>gnome-shell</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.linuxtools.cdt.autotools.genmakebuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
<nature>org.eclipse.linuxtools.cdt.autotools.autotoolsNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,148 +0,0 @@
|
||||
#Fri Nov 28 14:33:30 EST 2008
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80
|
||||
org.eclipse.cdt.core.formatter.alignment_for_compact_if=0
|
||||
org.eclipse.cdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.cdt.core.formatter.alignment_for_declarator_list=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_enumerator_list=48
|
||||
org.eclipse.cdt.core.formatter.alignment_for_expression_list=0
|
||||
org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_array_initializer=next_line_shifted
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_block=next_line_shifted
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_block_in_case=next_line_shifted
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_method_declaration=next_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration=next_line
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_switch=next_line_shifted
|
||||
org.eclipse.cdt.core.formatter.brace_position_for_type_declaration=next_line
|
||||
org.eclipse.cdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.cdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header=false
|
||||
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier=true
|
||||
org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header=true
|
||||
org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header=true
|
||||
org.eclipse.cdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.cdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.cdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.cdt.core.formatter.indentation.size=8
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
|
||||
org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.cdt.core.formatter.lineSplit=80
|
||||
org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.cdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.cdt.core.formatter.tabulation.size=2
|
||||
org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
@@ -1,4 +0,0 @@
|
||||
#Fri Nov 28 14:33:30 EST 2008
|
||||
eclipse.preferences.version=1
|
||||
formatter_profile=org.eclipse.cdt.ui.default.gnu_profile
|
||||
formatter_settings_version=1
|
||||
@@ -1,315 +0,0 @@
|
||||
#Fri Nov 28 14:43:43 EST 2008
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.wst.jsdt.core.codeComplete.argumentPrefixes=
|
||||
org.eclipse.wst.jsdt.core.codeComplete.argumentSuffixes=
|
||||
org.eclipse.wst.jsdt.core.codeComplete.fieldPrefixes=
|
||||
org.eclipse.wst.jsdt.core.codeComplete.fieldSuffixes=
|
||||
org.eclipse.wst.jsdt.core.codeComplete.localPrefixes=
|
||||
org.eclipse.wst.jsdt.core.codeComplete.localSuffixes=
|
||||
org.eclipse.wst.jsdt.core.codeComplete.staticFieldPrefixes=
|
||||
org.eclipse.wst.jsdt.core.codeComplete.staticFieldSuffixes=
|
||||
org.eclipse.wst.jsdt.core.compiler.codegen.inlineJsrBytecode=disabled
|
||||
org.eclipse.wst.jsdt.core.compiler.codegen.targetPlatform=1.2
|
||||
org.eclipse.wst.jsdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.wst.jsdt.core.compiler.compliance=1.4
|
||||
org.eclipse.wst.jsdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.wst.jsdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.wst.jsdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.assertIdentifier=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.deprecation=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.enumIdentifier=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.fallthroughCase=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.forbiddenReference=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.looseVarDecleration=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.nullReference=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.optionalSemicolon=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.undefinedField=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unresolvedFieldReference=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unresolvedMethodReference=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unresolvedTypeReference=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.wst.jsdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.wst.jsdt.core.compiler.source=1.3
|
||||
org.eclipse.wst.jsdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.wst.jsdt.core.formatter.blank_lines_between_type_declarations=0
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_objlit_initializer=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.indent_root_tags=true
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.comment.line_length=80
|
||||
org.eclipse.wst.jsdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.wst.jsdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_objlit_initializer=1
|
||||
org.eclipse.wst.jsdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.wst.jsdt.core.formatter.indentation.size=4
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_annotation=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_comma_in_objlit_initializer=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_objlit_initializer=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_objlit_initializer=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.wst.jsdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.wst.jsdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.wst.jsdt.core.formatter.keep_empty_objlit_initializer_on_one_line=false
|
||||
org.eclipse.wst.jsdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.wst.jsdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.wst.jsdt.core.formatter.lineSplit=80
|
||||
org.eclipse.wst.jsdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.wst.jsdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.wst.jsdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.wst.jsdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.wst.jsdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.wst.jsdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.wst.jsdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.wst.jsdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.wst.jsdt.core.formatter.wrap_before_binary_operator=true
|
||||
@@ -1,10 +0,0 @@
|
||||
#Fri Nov 28 14:39:12 EST 2008
|
||||
eclipse.preferences.version=1
|
||||
formatter_profile=_gjs
|
||||
formatter_settings_version=11
|
||||
org.eclipse.wst.jsdt.ui.exception.name=e
|
||||
org.eclipse.wst.jsdt.ui.gettersetter.use.is=true
|
||||
org.eclipse.wst.jsdt.ui.javadoc=false
|
||||
org.eclipse.wst.jsdt.ui.keywordthis=false
|
||||
org.eclipse.wst.jsdt.ui.overrideannotation=true
|
||||
org.eclipse.wst.jsdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>
|
||||
@@ -1 +0,0 @@
|
||||
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
|
||||
@@ -1 +0,0 @@
|
||||
Window
|
||||
155
HACKING.md
@@ -80,14 +80,10 @@ e.g. `imports.ui.popupMenu`.
|
||||
Each import block should be sorted alphabetically. Don't import modules you
|
||||
don't use.
|
||||
```javascript
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const St = imports.gi.St;
|
||||
const { GLib, Gio, St } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Util = imports.misc.util;
|
||||
```
|
||||
The alphabetical ordering should be done independently of the location of the
|
||||
@@ -121,40 +117,34 @@ See [What's new in JavaScript 1.7](https://developer.mozilla.org/en/JavaScript/N
|
||||
|
||||
## Classes
|
||||
|
||||
There are many approaches to classes in JavaScript. We use our own class framework
|
||||
(sigh), which is built in gjs. The advantage is that it supports inheriting from
|
||||
GObjects, although this feature isn't used very often in the Shell itself.
|
||||
There are many approaches to classes in JavaScript. We use standard ES6 classes
|
||||
whenever possible, that is when not inheriting from GObjects.
|
||||
```javascript
|
||||
var IconLabelMenuItem = new Lang.Class({
|
||||
Name: 'IconLabelMenuItem',
|
||||
Extends: PopupMenu.PopupMenuBaseItem,
|
||||
|
||||
_init(icon, label) {
|
||||
this.parent({ reactive: false });
|
||||
var IconLabelMenuItem = class extends PopupMenu.PopupMenuBaseItem {
|
||||
constructor(icon, label) {
|
||||
super({ reactive: false });
|
||||
this.actor.add_child(icon);
|
||||
this.actor.add_child(label);
|
||||
},
|
||||
}
|
||||
|
||||
open() {
|
||||
log("menu opened!");
|
||||
}
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
* 'Name' is required. 'Extends' is optional. If you leave it out, you will
|
||||
automatically inherit from Object.
|
||||
For GObject inheritence, we use the GObject.registerClass() function provided
|
||||
by gjs.
|
||||
```javascript
|
||||
var MyActor = GObject.registerClass(
|
||||
class MyActor extends Clutter.Actor {
|
||||
_init(params) {
|
||||
super._init(params);
|
||||
|
||||
* Leave a blank line between the "class header" (Name, Extends, and other
|
||||
things) and the "class body" (methods). Leave a blank line between each
|
||||
method.
|
||||
|
||||
* No space before the colon, one space after.
|
||||
|
||||
* No trailing comma after the last item.
|
||||
|
||||
* Make sure to use a semicolon after the closing paren to the class. It's
|
||||
still a giant function call, even though it may resemble a more
|
||||
conventional syntax.
|
||||
this.name = 'MyCustomActor';
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## GObject Introspection
|
||||
|
||||
@@ -162,19 +152,18 @@ GObject Introspection is a powerful feature that allows us to have native
|
||||
bindings for almost any library built around GObject. If a library requires
|
||||
you to inherit from a type to use it, you can do so:
|
||||
```javascript
|
||||
var MyClutterActor = new Lang.Class({
|
||||
Name: 'MyClutterActor',
|
||||
Extends: Clutter.Actor,
|
||||
var MyClutterActor = GObject.registerClass(
|
||||
class MyClutterActor extends Clutter.Actor {
|
||||
|
||||
vfunc_get_preferred_width(actor, forHeight) {
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
return [100, 100];
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_get_preferred_height(actor, forWidth) {
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
return [100, 100];
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_paint(actor) {
|
||||
vfunc_paint() {
|
||||
let alloc = this.get_allocation_box();
|
||||
Cogl.set_source_color4ub(255, 0, 0, 255);
|
||||
Cogl.rectangle(alloc.x1, alloc.y1,
|
||||
@@ -207,20 +196,18 @@ that has a property called `actor`. We call this wrapper class the "delegate".
|
||||
We sometimes use expando properties to set a property called `_delegate` on
|
||||
the actor itself:
|
||||
```javascript
|
||||
var MyClass = new Lang.Class({
|
||||
Name: 'MyClass',
|
||||
|
||||
_init() {
|
||||
var MyClass = class {
|
||||
constructor() {
|
||||
this.actor = new St.Button({ text: "This is a button" });
|
||||
this.actor._delegate = this;
|
||||
|
||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_onClicked(actor) {
|
||||
actor.set_label("You clicked the button!");
|
||||
}
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
The 'delegate' property is important for anything which trying to get the
|
||||
@@ -246,8 +233,6 @@ variable that can be captured in closures.
|
||||
All closures should be wrapped with Function.prototype.bind or use arrow
|
||||
notation.
|
||||
```javascript
|
||||
const Lang = imports.lang;
|
||||
|
||||
let closure1 = () => { this._fnorbate(); };
|
||||
let closure2 = this._fnorbate.bind(this);
|
||||
```
|
||||
@@ -255,19 +240,18 @@ notation.
|
||||
A more realistic example would be connecting to a signal on a method of a
|
||||
prototype:
|
||||
```javascript
|
||||
const Lang = imports.lang;
|
||||
const FnorbLib = imports.fborbLib;
|
||||
|
||||
var MyClass = new Lang.Class({
|
||||
var MyClass = class {
|
||||
_init() {
|
||||
let fnorb = new FnorbLib.Fnorb();
|
||||
fnorb.connect('frobate', this._onFnorbFrobate.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_onFnorbFrobate(fnorb) {
|
||||
this._updateFnorb();
|
||||
}
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
## Object literal syntax
|
||||
@@ -292,36 +276,49 @@ If your usage of an object is like a hash table (and thus conceptually the keys
|
||||
can have special chars in them), don't use quotes, but use brackets: `{ bar: 42
|
||||
}`, `foo['bar']`.
|
||||
|
||||
## Getters, setters, and Tweener
|
||||
## Animations
|
||||
|
||||
Most objects that are animated are actors, and most properties used in animations
|
||||
are animatable, which means they can use implicit animations:
|
||||
|
||||
Getters and setters should be used when you are dealing with an API that is
|
||||
designed around setting properties, like Tweener. If you want to animate an
|
||||
arbitrary property, create a getter and setter, and use Tweener to animate the
|
||||
property.
|
||||
```javascript
|
||||
var ANIMATION_TIME = 2000;
|
||||
|
||||
var MyClass = new Lang.Class({
|
||||
Name: 'MyClass',
|
||||
|
||||
_init() {
|
||||
this.actor = new St.BoxLayout();
|
||||
this._position = 0;
|
||||
},
|
||||
|
||||
get position() {
|
||||
return this._position;
|
||||
},
|
||||
|
||||
set position(value) {
|
||||
this._position = value;
|
||||
this.actor.set_position(value, value);
|
||||
}
|
||||
});
|
||||
|
||||
let myThing = new MyClass();
|
||||
Tweener.addTween(myThing,
|
||||
{ position: 100,
|
||||
time: ANIMATION_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
moveActor(actor, x, y) {
|
||||
actor.ease({
|
||||
x,
|
||||
y,
|
||||
duration: 500, // ms
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
The above is a convenience wrapper around the actual Clutter API, and should generally
|
||||
be preferred over the more verbose:
|
||||
|
||||
```javascript
|
||||
moveActor(actor, x, y) {
|
||||
actor.save_easing_state();
|
||||
|
||||
actor.set_easing_duration(500);
|
||||
actor.set_easing_mode(Clutter.AnimationMode.EASE_OUT_QUAD);
|
||||
actor.set({
|
||||
x,
|
||||
y
|
||||
});
|
||||
|
||||
actor.restore_easing_state();
|
||||
}
|
||||
```
|
||||
|
||||
There is a similar convenience API around Clutter.PropertyTransition to animate
|
||||
actor (or actor meta) properties that cannot use implicit animations:
|
||||
|
||||
```javascript
|
||||
desaturateActor(actor, desaturate) {
|
||||
let factor = desaturate ? 1.0 : 0.0;
|
||||
actor.ease_property('@effects.desaturate.factor', factor, {
|
||||
duration: 500, // ms
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
268
NEWS
@@ -1,3 +1,271 @@
|
||||
3.33.91
|
||||
=======
|
||||
* Fix regression when adjusting brightness [Florian; #1500]
|
||||
* Fix pointer a11y timeout animation [Jonas D.; #1533]
|
||||
* Add new extensions CLI tool [Florian; #1234]
|
||||
* Only track top-level windows [Carlos; #556]
|
||||
* Misc. bug fixes and cleanups [Jonas D., Jonas Å., Piotr, Florian;
|
||||
!678, !682, !686]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Jonas Dreßler, Carlos Garnacho, Florian Müllner
|
||||
|
||||
Translators:
|
||||
Asier Sarasua Garmendia [eu], Sveinn í Felli [is], Anders Jonsson [sv],
|
||||
Jordi Mas [ca], Kukuh Syafaat [id], Florentina Mușat [ro], Jiri Grönroos [fi],
|
||||
Aurimas Černius [lt], Daniel Mustieles [es], Piotr Drąg [pl],
|
||||
Danial Behzadi [fa]
|
||||
|
||||
3.33.90
|
||||
=======
|
||||
* Implement DND app picker folder management [Georges; !643, !645, !664, !671]
|
||||
* Make Clocks/Weather integration work with sandboxed apps [Florian; #1158]
|
||||
* Support startup via systemd user instance [Benjamin; !507]
|
||||
* Replace Tweener with Clutter animations [Florian; !663, !22, !666, !668, !669]
|
||||
* Minimize travel distance in overview animation [Sergey; !267]
|
||||
* Rescan icon theme when installed apps changed [Georges; !661]
|
||||
* Consistently animate new window actions [Jonas; !662, !673]
|
||||
* Misc. bug fixes and cleanups [Florian, Daniel, Ray, Bastien, Jonas, Niels,
|
||||
Marco, Georges; !635, !636, !637, #1462, !628, !640, !641, !627, !644, !647,
|
||||
!385, #1474, !651, #1144, !646, !653, !652, !655, #1482, !656, $654, !665,
|
||||
!667, !670, #1357, !672, !657, #1507, !674, !677]
|
||||
|
||||
Contributors:
|
||||
Benjamin Berg, Sergey Bugaev, Jonas Dreßler, Niels De Graef, Florian Müllner,
|
||||
Georges Basile Stavracas Neto, Bastien Nocera, Ray Strode,
|
||||
Marco Trevisan (Treviño), verdre, Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Asier Sarasua Garmendia [eu], Rafael Fontenelle [pt_BR],
|
||||
Kristjan SCHMIDT [eo], Jor Teron [mjw], Daniel Mustieles [es],
|
||||
Kukuh Syafaat [id], Jordi Mas [ca], Fabio Tomat [fur], Daniel Șerbănescu [ro],
|
||||
Anders Jonsson [sv]
|
||||
|
||||
3.33.4
|
||||
======
|
||||
* Fix unintentional interference between gestures [Jonas; !598]
|
||||
* Fix unintentional loop while polkit dialog is active [Ray; !602]
|
||||
* Fix alt-tab icon size on HiDPI [Jonas; !587]
|
||||
* Style fixes and improvements [Frederik, Jakub; !610, #1446, #1449]
|
||||
* Fix style updates for non-background CSS properties [Florian; #1212]
|
||||
* Fix cursor visibility in screen recordings [Illya; #1208]
|
||||
* Add option for disabling the hot corner [Florian; #688320]
|
||||
* Use more fine-grained levels in battery indicator [Florian; !561, #1442]
|
||||
* Fix the calculation of the maximum number of app search results [Jonas; !110]
|
||||
* Handle horizontal workspace layout with gestures/animations [Florian; !575]
|
||||
* Improve handling of session mode extensions [Florian, Didier; #789852]
|
||||
* Misc. bug fixes and cleanups [Jonas, Florian, Sonny, Carlos, Mario, Benjamin,
|
||||
Marco, Ting-Wei; !599, !600, !591, !606, !152, !607, !604, !495, !608, !611,
|
||||
!614, !612, !615, !618, #369, !620, #774, !621, !616, #1065, !609, !626,
|
||||
!491, !631, !632, !633, #1457]
|
||||
|
||||
Contributors:
|
||||
Benjamin Berg, Jonas Dreßler, Frederik Feichtmeier, Carlos Garnacho,
|
||||
Illya Klymov, Ting-Wei Lan, Florian Müllner, Sonny Piers, Mario Sanchez Prada,
|
||||
Didier Roche, Jakub Steiner, Ray Strode, Jor Teron, Marco Trevisan (Treviño)
|
||||
|
||||
Translators:
|
||||
Jordi Mas [ca], Jor Teron [mjw]
|
||||
|
||||
3.33.3
|
||||
======
|
||||
* Prepare for optional X11 [Carlos; !378]
|
||||
* Fix opening window menu [Marco; !557]
|
||||
* Reload search providers when installed applications change [Cosimo; !562]
|
||||
* Implement locate-pointer accessibility feature [Olivier; #981]
|
||||
* Allow to disable window menus via session mode [Cosimo; !569]
|
||||
* Implement mouse accessibility [Olivier; !474]
|
||||
* Call GDM's RegisterSession() after startup [Iain; !570]
|
||||
* Fix extended keys popups being hidden by on-screen keyboard [Marco; !583]
|
||||
* Fix top bar being hidden by lock screen [Jonas; !571]
|
||||
* Update theme to better match GTK's Adwaita [Frederik; #841]
|
||||
* Set up GJS profiler when GJS_TRACE_FD is set [Christian; !573]
|
||||
* Misc. bug fixes and cleanups [Jonas, Cosimo, Robert, Florian, Marco, Simon,
|
||||
Laurent, Niels, Will; !551, !555, !464, #1333, !565, !572, !568, !558, #1205,
|
||||
#1336, !579, !576, #1392, !582, !586, #1406, #1351]
|
||||
|
||||
Contributors:
|
||||
Laurent Bigonville, Cosimo Cecchi, Piotr Drąg, Jonas Dreßler,
|
||||
Frederik Feichtmeier, Olivier Fourdan, Carlos Garnacho, Niels De Graef,
|
||||
Christian Hergert, Iain Lane, Robert Mader, Florian Müllner, Simon Schampijer,
|
||||
Jakub Steiner, Will Thompson, Marco Trevisan (Treviño)
|
||||
|
||||
Translators:
|
||||
Kukuh Syafaat [id], Balázs Meskó [hu], Daniel Mustieles [es],
|
||||
Fabio Tomat [fur], Nathan Follens [nl], Goran Vidović [hr], Jordi Mas [ca]
|
||||
|
||||
3.33.2
|
||||
======
|
||||
* Fix keeping actors visible in scrollviews [Marco; #1061]
|
||||
* Move some chrome above popup windows [Jonas D.; !358]
|
||||
* Include 'sandboxed-app-id' in winodw introspection info [Florian; #1289]
|
||||
* Port to libecal-2.0 [Milan; !501]
|
||||
* Support TCRYPT in mount password dialog [segfault; !126]
|
||||
* Misc. bug fixes and cleanups [Florian, Marco, Veerasamy; !517, #745, !499,
|
||||
!510, !515, !546, !549]
|
||||
|
||||
Contributors:
|
||||
Cosimo Cecchi, Milan Crha, Jonas Dreßler, Florian Müllner, segfault,
|
||||
Veerasamy Sevagen, Marco Trevisan (Treviño)
|
||||
|
||||
Translators:
|
||||
Daniel Mustieles [es]
|
||||
|
||||
3.33.1
|
||||
======
|
||||
* Refine the app menu [Florian; #968]
|
||||
* Refine window preview style [Feichtmeier; !461]
|
||||
* Only emit ::style-changed on actual changes [Carlos; #1153]
|
||||
* Disable emoji on-screen keyboard support on X11 [Florian; #1172]
|
||||
* Fix tablet button mapping overlay [Carlos; #1220]
|
||||
* Don't crash for world clock locations with no timezone [Florian; #1062]
|
||||
* Don't leak old on-screen keyboard layout groups [Carlos; mutter#556]
|
||||
* Fix ellipsization in dialog subtitles/bodies [Marco; !531]
|
||||
* Fix glitch of fullscreen window in workspace switch animation [Jonas D.; !322]
|
||||
* Fix distortion of some image contents [Florian; !525]
|
||||
* Allow dragging unfocused tiled/maximized windows from top bar [Dylan; #679290]
|
||||
* Handle network interface name changes [Fabrice; !534]
|
||||
* Avoid unnecessary style changes when computing :first/:last-child
|
||||
[Florian; !529]
|
||||
* Misc. bug fixes and cleanups [Florian, Marco, Robert, Georges, Carlos, Simon,
|
||||
Jonas D.; !487, !441, !502, !503, !504, !506, #822, !551, !512, !509, !511,
|
||||
#1054, !524, #1065, !331, !540]
|
||||
|
||||
Contributors:
|
||||
Fabrice Bellet, Jonas Dreßler, Feichtmeier, Carlos Garnacho, Robert Mader,
|
||||
Dylan McCall, Simon McVittie, Florian Müllner, Georges Basile Stavracas Neto,
|
||||
Marco Trevisan (Treviño)
|
||||
|
||||
Translators:
|
||||
Daniel Mustieles [es], Kukuh Syafaat [id], Fabio Tomat [fur],
|
||||
Carmen Bianca BAKKER [eo], Dingzhong Chen [zh_CN], Tim Sabsch [de]
|
||||
|
||||
3.32.1
|
||||
======
|
||||
* Fix avatar scaling on login screen [Florian; #1024]
|
||||
* Fix distortion of desktop zoom [Florian; #646]
|
||||
* Fix mouse cursor visibility when using desktop zoom [Florian, Marco; #1020]
|
||||
* Fix screen dimming after wake-up on lock screen [Xiaoguang; #900]
|
||||
* Fix Alt+Esc switcher [Florian; #1064]
|
||||
* Respect struts for popover placement [Andrea; #1102]
|
||||
* Fix app icons updates after theme changes [Florian; #1117]
|
||||
* Fix desktop zoom after resolution changes [Marco; #1120]
|
||||
* Implement stick-to-finger workspace switch overview gestures [Florian; #516]
|
||||
* Make World Clocks offsets relative to local time [Florian; #1157]
|
||||
* Fix top app icon disappearing from dash [Florian; #1053]
|
||||
* Update switch style to match new Adwaita [Jakub; !496]
|
||||
* Ensure CSS units are pixel-aligned when scaling is used [Carlos; #91]
|
||||
* Misc. bug fixes and cleanups [Florian, Jakub, Robert, Alex, Carlos, Phil,
|
||||
Marco, Benjamin, AsciiWolf, Ray, verdre; !444, #1016, #1018, !449, #1036,
|
||||
!455, #1094, !440, #1023, #624, #1017, !476, !473, !480, #1130, !485, !481,
|
||||
!490, !489, #1151, !435, #1160, !482, #1150, #1166, !384]
|
||||
|
||||
Contributors:
|
||||
AsciiWolf, Andrea Azzarone, Benjamin Berg, Carlos Garnacho, Victor Ibragimov,
|
||||
Robert Mader, Alex Monday, Florian Müllner, Jakub Steiner, Ray Strode,
|
||||
Marco Trevisan (Treviño), verdre, Xiaoguang Wang, Phil Wyett
|
||||
|
||||
Translators:
|
||||
Victor Ibragimov [tg, af, et, ja], Bruce Cowan [en_GB], Piotr Drąg [tg],
|
||||
Charles Monzat [fr], Khaled Hosny [ar], Goran Vidović [hr],
|
||||
Cheng-Chia Tseng [zh_TW], Carmen Bianca BAKKER [eo], Daniel Mustieles [es],
|
||||
Dušan Kazik [sk]
|
||||
|
||||
3.32.0
|
||||
======
|
||||
* Fix sizing issues in on-screen-keyboard emoji panel [Carlos; !439]
|
||||
* Fix test linker failure on Debian/Ubuntu [Iain; !442]
|
||||
* Avoid assertion when sizing fallback app icons from CSS [Florian; #1027]
|
||||
* Fix mis-sized menu arrows after texture cache changes [Florian; !452]
|
||||
|
||||
Contributors:
|
||||
Carlos Garnacho, Iain Lane, Florian Müllner
|
||||
|
||||
Translators:
|
||||
Gábor Kelemen [hu], Victor Ibragimov [tg], Ryuta Fujii [ja], Piotr Drąg [af,
|
||||
tg], Mart Raudsepp [et]
|
||||
|
||||
3.31.92
|
||||
=======
|
||||
* Fix visual glitch in submenus [Alex; #987]
|
||||
* Support fractional scaling [Jonas, Marco; #765011, !5]
|
||||
* Only consider visible children for :first-child/:last-child [Florian; !312]
|
||||
* Hide trailing separator in search results [verdre; !311]
|
||||
* Remember choice in inhibit-shortcuts dialogue [Olivier; !382]
|
||||
* Don't toggle on-screen keyboard on every focus change [Carlos; !397]
|
||||
* Fix legacy tray icons not responding to events on wayland [Florian; #191]
|
||||
* Fix generating French OSK layout [Florian; #997]
|
||||
* Use borderless round user images [Florian; #811]
|
||||
* Misc. bug fixes and cleanups [Andrea, Robert, Florian, Marco, Niels,
|
||||
Benjamin; !414, !417, !420, #996, !408, !422, !425, #1006, !427, !315,
|
||||
#989, !430, !431, !432, #1015, !429, !423, !419, !434]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Alan, Andrea Azzarone, Benjamin Berg, Olivier Fourdan,
|
||||
Carlos Garnacho, Niels De Graef, Robert Mader, Alex Monday, Florian Müllner,
|
||||
Marco Trevisan (Treviño), verdre
|
||||
|
||||
Translators:
|
||||
Carmen Bianca BAKKER [eo], Asier Sarasua Garmendia [eu], Stas Solovey [ru],
|
||||
Changwoo Ryu [ko], Julien Humbert [fr], Milo Casagrande [it],
|
||||
Марко Костић [sr], Ask Hjorth Larsen [da], Kukuh Syafaat [id],
|
||||
Daniel Șerbănescu [ro], Bernd Homuth [de], Trần Ngọc Quân [vi],
|
||||
Nathan Follens [nl], Rūdolfs Mazurs [lv], Aurimas Černius [lt]
|
||||
|
||||
3.31.91
|
||||
=======
|
||||
* Don't close on-screen-keyboard's language menu on hover [Florian; #171]
|
||||
* Don't let unfullscreen gesture interfere with top bar taps [Jonas D.; #552]
|
||||
* Always use symbolic user icon in system menu [Florian; #957]
|
||||
* Add flags parameter in GrabAccelerators API [Andrea; #68]
|
||||
* Misc. bug fixes and cleanups [Florian, Jonas A.; !399, !398, !400, !402,
|
||||
!407, !410, !411]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Andrea Azzarone, Arnaud Bonatti, Jonas Dreßler, Florian Müllner
|
||||
|
||||
Translators:
|
||||
Jordi Mas [ca], Ryuta Fujii [ja], Marek Cernocky [cs], Fran Dieguez [gl],
|
||||
Jiri Grönroos [fi], Serdar Sağlam [tr], Anders Jonsson [sv],
|
||||
Matej Urbančič [sl], Gun Chleoc [gd], Kukuh Syafaat [id],
|
||||
Baurzhan Muftakhidinov [kk], Alan Mortensen [da], Rafael Fontenelle [pt_BR],
|
||||
Sveinn í Felli [is]
|
||||
|
||||
3.31.90
|
||||
=======
|
||||
* Fix input methods after ibus restarts [Takao; #295]
|
||||
* Refresh world clocks and weather sections [Florian; #262]
|
||||
* Port to ES6 classes (update your extensions!) [Florian; !361]
|
||||
* networkAgent: Advise users when WPS support is available [Lubomir; !329]
|
||||
* Performance improvements [Carlos; #832, #815]
|
||||
* Fix drag-and-drop with wacom pens [Carlos; #540]
|
||||
* Fix CAPS LOCK indication on wayland [Carlos; #762881]
|
||||
* Show details of non-sensitive notifications on lock screen [Philip; #726]
|
||||
* Refine extension-prefs' error UI [Florian; !193]
|
||||
* Add switch-to-application-n keybindings [Florian; #648000]
|
||||
* Remove top bar translucency [Florian; #408]
|
||||
* Support emojis and keypads in on-screen keyboard [Carlos; #675]
|
||||
* Don't allow popups to re-enable keyboard shortcuts on lock screen
|
||||
(CVE-2019-3820) [Florian, Ray; #851]
|
||||
* Replace app menu [Florian; #624]
|
||||
* Include commonly copied+pasted extension helpers [Florian; !150]
|
||||
* Misc. bug fixes and cleanups [Florian, Daniel, Philip, Sergio, Pascal,
|
||||
Georges, verdre, Carlos, Christopher; #780, #909, !316, !308, !309, #915,
|
||||
!350, !362, !357, !365, !366, !283, !367, #942, !371, !373, !374, !343,
|
||||
!375, !292, !317, !377, !379, !346, !383, #953, !388]
|
||||
|
||||
Contributors:
|
||||
Sergio Costas, Christopher Davis, Bilal Elmoussaoui, Takao Fujiwara,
|
||||
Carlos Garnacho, Niels De Graef, Christian Kellner, Ignat Loskutov,
|
||||
Florian Müllner, Georges Basile Stavracas Neto, Pascal Nowack, Lubomir Rintel,
|
||||
Jakub Steiner, Ray Strode, verdre, Daniel van Vugt, Philip Withnall
|
||||
|
||||
Translators:
|
||||
Daniel Mustieles [es], Carmen Bianca BAKKER [eo], Charles Monzat [fr],
|
||||
Pieter Schalk Schoeman [af], Jordi Mas [ca], Matej Urbančič [sl],
|
||||
Fran Dieguez [gl], Balázs Úr [hu], A S Alam [pa], Fabio Tomat [fur],
|
||||
Aurimas Černius [lt], Piotr Drąg [pl], Marek Cernocky [cs], Ryuta Fujii [ja]
|
||||
|
||||
3.31.4
|
||||
======
|
||||
* Improve icon grid performance [Daniel; #174]
|
||||
|
||||
@@ -11,6 +11,14 @@ see the [project wiki][project-wiki].
|
||||
|
||||
Bugs should be reported to the GNOME [bug tracking system][bug-tracker].
|
||||
|
||||
## Contributing
|
||||
|
||||
To contribute, open merge requests at https://gitlab.gnome.org/GNOME/gnome-shell.
|
||||
|
||||
Commit messages should follow the [GNOME commit message
|
||||
guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL
|
||||
to either an issue or a merge request in each commit.
|
||||
|
||||
## License
|
||||
GNOME Shell is distributed under the terms of the GNU General Public License,
|
||||
version 2 or later. See the [COPYING][license] file for details.
|
||||
|
||||
40
README.mdwn
Normal file
@@ -0,0 +1,40 @@
|
||||
cldr2json
|
||||
=========
|
||||
|
||||
This script converts Unicode CLDR android keyboard layouts to JSON usable by
|
||||
GNOME Shell.
|
||||
|
||||
CLDR keyboard layouts can be found at
|
||||
<http://www.unicode.org/Public/cldr/latest/keyboards.zip>
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
./cldr2json <input file or directory> <output directory>
|
||||
|
||||
example:
|
||||
|
||||
./cldr2json cldr/keyboards/android/ json_layouts/
|
||||
|
||||
|
||||
Keyboard layout mapping
|
||||
=======================
|
||||
|
||||
Unicode CLDR layout identifiers are language codes, while XKB layout
|
||||
identifiers are... something else. The mapping between the two currently uses
|
||||
heuristic based on the layout descriptions, in this order:
|
||||
|
||||
- if the CLDR layout description matches an XKB layout description, chose its
|
||||
XKB identifier
|
||||
- if one word of the CLDR layout description matches an XKB layout
|
||||
description, chose its XKB identifier
|
||||
- if the CLDR layout description matches one word of an XKB layout description,
|
||||
chose its XKB identifier
|
||||
|
||||
That doesn't always work. For instance it fails for "en" language, that should
|
||||
match "us" XKB identifier. For such cases, there is a mapping in
|
||||
LOCALE_TO_XKB_OVERRIDES at the top of the script. If you discover a weird
|
||||
mapping of if you get a "failed to find XKB mapping for <locale>" warning then
|
||||
please consider adding an override there.
|
||||
|
||||
208
cldr2json.py
Executable file
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright 2015 Daiki Ueno <dueno@src.gnome.org>
|
||||
# 2016 Parag Nemade <pnemade@redhat.com>
|
||||
# 2017 Alan <alan@boum.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This 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
|
||||
# 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, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
import glob
|
||||
import json
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import xml.etree.ElementTree
|
||||
|
||||
import gi
|
||||
gi.require_version('GnomeDesktop', '3.0') # NOQA: E402
|
||||
from gi.repository import GnomeDesktop
|
||||
|
||||
ESCAPE_PATTERN = re.compile(r'\\u\{([0-9A-Fa-f]+?)\}')
|
||||
ISO_PATTERN = re.compile(r'[A-E]([0-9]+)')
|
||||
|
||||
LOCALE_TO_XKB_OVERRIDES = {
|
||||
'af': 'za',
|
||||
'en': 'us',
|
||||
'en-GB': 'uk',
|
||||
'es-US': 'latam',
|
||||
'fr-CA': 'ca',
|
||||
'hi': 'in+bolnagri',
|
||||
'ky': 'kg',
|
||||
'nl-BE': 'be',
|
||||
'zu': None
|
||||
}
|
||||
|
||||
|
||||
def parse_single_key(value):
|
||||
def unescape(m):
|
||||
return chr(int(m.group(1), 16))
|
||||
value = ESCAPE_PATTERN.sub(unescape, value)
|
||||
return value
|
||||
|
||||
|
||||
def parse_rows(keymap):
|
||||
unsorted_rows = {}
|
||||
for _map in keymap.iter('map'):
|
||||
value = _map.get('to')
|
||||
key = [parse_single_key(value)]
|
||||
iso = _map.get('iso')
|
||||
if not ISO_PATTERN.match(iso):
|
||||
sys.stderr.write('invalid ISO key name: %s\n' % iso)
|
||||
continue
|
||||
if not iso[0] in unsorted_rows:
|
||||
unsorted_rows[iso[0]] = []
|
||||
unsorted_rows[iso[0]].append((int(iso[1:]), key))
|
||||
# add subkeys
|
||||
longPress = _map.get('longPress')
|
||||
if longPress:
|
||||
for value in longPress.split(' '):
|
||||
subkey = parse_single_key(value)
|
||||
key.append(subkey)
|
||||
|
||||
rows = []
|
||||
for k, v in sorted(list(unsorted_rows.items()),
|
||||
key=lambda x: x[0],
|
||||
reverse=True):
|
||||
row = []
|
||||
for key in sorted(v, key=lambda x: x):
|
||||
row.append(key[1])
|
||||
rows.append(row)
|
||||
|
||||
return rows
|
||||
|
||||
|
||||
def convert_xml(tree):
|
||||
root = {}
|
||||
for xml_keyboard in tree.iter("keyboard"):
|
||||
locale_full = xml_keyboard.get("locale")
|
||||
locale, sep, end = locale_full.partition("-t-")
|
||||
root["locale"] = locale
|
||||
for xml_name in tree.iter("name"):
|
||||
name = xml_name.get("value")
|
||||
root["name"] = name
|
||||
root["levels"] = []
|
||||
# parse levels
|
||||
for index, keymap in enumerate(tree.iter('keyMap')):
|
||||
# FIXME: heuristics here
|
||||
modifiers = keymap.get('modifiers')
|
||||
if not modifiers:
|
||||
mode = 'default'
|
||||
modifiers = ''
|
||||
elif 'shift' in modifiers.split(' '):
|
||||
mode = 'latched'
|
||||
modifiers = 'shift'
|
||||
else:
|
||||
mode = 'locked'
|
||||
level = {}
|
||||
level["level"] = modifiers
|
||||
level["mode"] = mode
|
||||
level["rows"] = parse_rows(keymap)
|
||||
root["levels"].append(level)
|
||||
return root
|
||||
|
||||
|
||||
def locale_to_xkb(locale, name):
|
||||
if locale in sorted(LOCALE_TO_XKB_OVERRIDES.keys()):
|
||||
xkb = LOCALE_TO_XKB_OVERRIDES[locale]
|
||||
logging.debug("override for %s → %s",
|
||||
locale, xkb)
|
||||
if xkb:
|
||||
return xkb
|
||||
else:
|
||||
raise KeyError("layout %s explicitely disabled in overrides"
|
||||
% locale)
|
||||
xkb_names = sorted(name_to_xkb.keys())
|
||||
if name in xkb_names:
|
||||
return name_to_xkb[name]
|
||||
else:
|
||||
logging.debug("name %s failed" % name)
|
||||
for sub_name in name.split(' '):
|
||||
if sub_name in xkb_names:
|
||||
xkb = name_to_xkb[sub_name]
|
||||
logging.debug("dumb mapping failed but match with locale word: "
|
||||
"%s (%s) → %s (%s)",
|
||||
locale, name, xkb, sub_name)
|
||||
return xkb
|
||||
else:
|
||||
logging.debug("sub_name failed")
|
||||
for xkb_name in xkb_names:
|
||||
for xkb_sub_name in xkb_name.split(' '):
|
||||
if xkb_sub_name.strip('()') == name:
|
||||
xkb = name_to_xkb[xkb_name]
|
||||
logging.debug("dumb mapping failed but match with xkb word: "
|
||||
"%s (%s) → %s (%s)",
|
||||
locale, name, xkb, xkb_name)
|
||||
return xkb
|
||||
raise KeyError("failed to find XKB mapping for %s" % locale)
|
||||
|
||||
|
||||
def convert_file(source_file, destination_path):
|
||||
logging.info("Parsing %s", source_file)
|
||||
|
||||
itree = xml.etree.ElementTree.ElementTree()
|
||||
itree.parse(source_file)
|
||||
|
||||
root = convert_xml(itree)
|
||||
|
||||
try:
|
||||
xkb_name = locale_to_xkb(root["locale"], root["name"])
|
||||
except KeyError as e:
|
||||
logging.warn(e)
|
||||
return False
|
||||
destination_file = os.path.join(destination_path, xkb_name + ".json")
|
||||
|
||||
with open(destination_file, 'w', encoding="utf-8") as dest_fd:
|
||||
json.dump(root, dest_fd, ensure_ascii=False, indent=2, sort_keys=True)
|
||||
|
||||
logging.debug("written %s", destination_file)
|
||||
|
||||
|
||||
def load_xkb_mappings():
|
||||
xkb = GnomeDesktop.XkbInfo()
|
||||
layouts = xkb.get_all_layouts()
|
||||
name_to_xkb = {}
|
||||
|
||||
for layout in layouts:
|
||||
name = xkb.get_layout_info(layout).display_name
|
||||
name_to_xkb[name] = layout
|
||||
|
||||
return name_to_xkb
|
||||
|
||||
|
||||
locale.setlocale(locale.LC_ALL, "C")
|
||||
name_to_xkb = load_xkb_mappings()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if "DEBUG" in os.environ:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("supply a CLDR keyboard file")
|
||||
sys.exit(1)
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("supply an output directory")
|
||||
sys.exit(1)
|
||||
|
||||
source = sys.argv[1]
|
||||
destination = sys.argv[2]
|
||||
if os.path.isfile(source):
|
||||
convert_file(source, destination)
|
||||
elif os.path.isdir(source):
|
||||
for path in glob.glob(source + "/*-t-k0-android.xml"):
|
||||
convert_file(path, destination)
|
||||
12
data/dbus-interfaces/org.gnome.Shell.CalendarServer.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<node>
|
||||
<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>
|
||||
<property name="HasCalendars" type="b" access="read" />
|
||||
<signal name="Changed" />
|
||||
</interface>
|
||||
</node>
|
||||
15
data/dbus-interfaces/org.gnome.Shell.ClocksIntegration.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<node>
|
||||
|
||||
<!--
|
||||
org.gnome.Shell.ClocksIntegration:
|
||||
@short_description: Clocks integration interface
|
||||
|
||||
The interface used for exporting location settings to GNOME Shell's
|
||||
world clocks integration.
|
||||
-->
|
||||
<interface name="org.gnome.Shell.ClocksIntegration">
|
||||
|
||||
<property name="Locations" type="av" access="read"/>
|
||||
|
||||
</interface>
|
||||
</node>
|
||||
@@ -173,6 +173,30 @@
|
||||
<arg type="s" direction="in" name="uuid"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
EnableExtension:
|
||||
@uuid: The UUID of the extension
|
||||
@success: Whether the operation was successful
|
||||
|
||||
Enable an extension.
|
||||
-->
|
||||
<method name="EnableExtension"> \
|
||||
<arg type="s" direction="in" name="uuid"/> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
</method> \
|
||||
|
||||
<!--
|
||||
DisableExtension:
|
||||
@uuid: The UUID of the extension
|
||||
@success: Whether the operation was successful
|
||||
|
||||
Disable an extension.
|
||||
-->
|
||||
<method name="DisableExtension"> \
|
||||
<arg type="s" direction="in" name="uuid"/> \
|
||||
<arg type="b" direction="out" name="success"/> \
|
||||
</method> \
|
||||
|
||||
<!--
|
||||
LaunchExtensionPrefs:
|
||||
@uuid: The UUID of the extension
|
||||
@@ -189,6 +213,15 @@
|
||||
-->
|
||||
<method name="CheckForUpdates"/>
|
||||
|
||||
<signal name="ExtensionStateChanged">
|
||||
<arg type="s" name="uuid"/>
|
||||
<arg type="a{sv}" name="state"/>
|
||||
</signal>
|
||||
|
||||
<!--
|
||||
ExtensionStatusChanged:
|
||||
Deprecated for ExtensionStateChanged
|
||||
-->
|
||||
<signal name="ExtensionStatusChanged">
|
||||
<arg type="s" name="uuid"/>
|
||||
<arg type="i" name="state"/>
|
||||
|
||||
16
data/dbus-interfaces/org.gnome.Shell.WeatherIntegration.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<node>
|
||||
|
||||
<!--
|
||||
org.gnome.Shell.WeatherIntegration:
|
||||
@short_description: Weather integration interface
|
||||
|
||||
The interface used for exporting location settings to GNOME Shell's
|
||||
weather integration.
|
||||
-->
|
||||
<interface name="org.gnome.Shell.WeatherIntegration">
|
||||
|
||||
<property name="AutomaticLocation" type="b" access="read"/>
|
||||
<property name="Locations" type="av" access="read"/>
|
||||
|
||||
</interface>
|
||||
</node>
|
||||
@@ -10,9 +10,6 @@
|
||||
<arg type="a{sv}" direction="in" name="params"/>
|
||||
</method>
|
||||
<method name="ShowMonitorLabels">
|
||||
<arg type="a{uv}" direction="in" name="params"/>
|
||||
</method>
|
||||
<method name="ShowMonitorLabels2">
|
||||
<arg type="a{sv}" direction="in" name="params"/>
|
||||
</method>
|
||||
<method name="HideMonitorLabels"/>
|
||||
@@ -22,17 +19,22 @@
|
||||
<method name="ShowApplications"/>
|
||||
<method name="GrabAccelerator">
|
||||
<arg type="s" direction="in" name="accelerator"/>
|
||||
<arg type="u" direction="in" name="flags"/>
|
||||
<arg type="u" direction="in" name="modeFlags"/>
|
||||
<arg type="u" direction="in" name="grabFlags"/>
|
||||
<arg type="u" direction="out" name="action"/>
|
||||
</method>
|
||||
<method name="GrabAccelerators">
|
||||
<arg type="a(su)" direction="in" name="accelerators"/>
|
||||
<arg type="a(suu)" direction="in" name="accelerators"/>
|
||||
<arg type="au" direction="out" name="actions"/>
|
||||
</method>
|
||||
<method name="UngrabAccelerator">
|
||||
<arg type="u" direction="in" name="action"/>
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
</method>
|
||||
<method name="UngrabAccelerators">
|
||||
<arg type="au" direction="in" name="action"/>
|
||||
<arg type="b" direction="out" name="success"/>
|
||||
</method>
|
||||
<signal name="AcceleratorActivated">
|
||||
<arg name="action" type="u"/>
|
||||
<arg name="parameters" type="a{sv}"/>
|
||||
|
||||
15740
data/emoji.json
Normal file
@@ -39,6 +39,8 @@
|
||||
<file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Rfkill.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Wacom.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.AudioDeviceSelection.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.CalendarServer.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.ClocksIntegration.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.Extensions.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.Introspect.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.HotplugSniffer.xml</file>
|
||||
@@ -47,6 +49,7 @@
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.Screencast.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.Screenshot.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.Wacom.PadOsd.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.WeatherIntegration.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gnome.Shell.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.Gtk.MountOperationHandler.xml</file>
|
||||
<file preprocess="xml-stripblanks">org.gtk.Notifications.xml</file>
|
||||
|
||||
14
data/gnome-shell-disable-extensions.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Disable GNOME Shell extensions after failure
|
||||
DefaultDependencies=no
|
||||
|
||||
# Only disable extensions for a short period of time after login.
|
||||
# This means we err on the side of failing the first login after a broken
|
||||
# extension was installed.
|
||||
Requisite=gnome-session-stable.timer
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
# Disable extensions
|
||||
ExecStart=gsettings set org.gnome.shell disable-user-extensions true
|
||||
Restart=no
|
||||
12
data/gnome-shell-extensions-disabled-warning.desktop.in.in
Normal file
@@ -0,0 +1,12 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=GNOME Shell Extensions Disabled Warning
|
||||
Comment=Warning shown if extensions were disabled due to a failure
|
||||
Exec=@bindir@/gnome-shell-extension-prefs --disabled-warning
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-shell
|
||||
X-GNOME-Bugzilla-Component=general
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
||||
OnlyShowIn=GNOME;
|
||||
AutostartCondition=if-exists gnome-shell-extensions-disabled-warning
|
||||
X-GNOME-HiddenUnderSystemd=@systemd_hidden@
|
||||
13
data/gnome-shell-extensions-disabled-warning.service.in
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Warn about GNOME Shell extensions being disabled
|
||||
ConditionPathExists=%E/gnome-shell-extensions-disabled-warning
|
||||
|
||||
Requisite=gnome-session.target
|
||||
After=gnome-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=-/bin/rm %E/gnome-shell-extensions-disabled-warning
|
||||
ExecStart=@bindir@/gnome-shell-extension-prefs --disabled-warning
|
||||
Restart=no
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<file>be.json</file>
|
||||
<file>bg.json</file>
|
||||
<file>by.json</file>
|
||||
<file>ca.json</file>
|
||||
<file>cz.json</file>
|
||||
<file>de.json</file>
|
||||
<file>dk.json</file>
|
||||
@@ -54,5 +55,6 @@
|
||||
<file>us.json</file>
|
||||
<file>vn.json</file>
|
||||
<file>za.json</file>
|
||||
<file>emoji.json</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@@ -20,12 +20,16 @@
|
||||
<file>no-notifications.svg</file>
|
||||
<file>noise-texture.png</file>
|
||||
<file>pad-osd.css</file>
|
||||
<file alias="icons/pointer-double-click-symbolic.svg">pointer-double-click-symbolic.svg</file>
|
||||
<file alias="icons/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file>
|
||||
<file alias="icons/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file>
|
||||
<file alias="icons/pointer-secondary-click-symbolic.svg">pointer-secondary-click-symbolic.svg</file>
|
||||
<file>process-working.svg</file>
|
||||
<file>toggle-off-us.svg</file>
|
||||
<file>toggle-off-intl.svg</file>
|
||||
<file>toggle-off.svg</file>
|
||||
<file>toggle-off-dark.svg</file>
|
||||
<file>toggle-off-hc.svg</file>
|
||||
<file>toggle-on-us.svg</file>
|
||||
<file>toggle-on-intl.svg</file>
|
||||
<file>toggle-on.svg</file>
|
||||
<file>toggle-on-dark.svg</file>
|
||||
<file>toggle-on-hc.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
25
data/gnome-shell-wayland.service.in
Normal file
@@ -0,0 +1,25 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell on Wayland
|
||||
# On wayland, force a session shutdown
|
||||
OnFailure=gnome-shell-disable-extensions.service gnome-session-shutdown.target
|
||||
OnFailureJobMode=replace-irreversibly
|
||||
CollectMode=inactive-or-failed
|
||||
RefuseManualStart=on
|
||||
RefuseManualStop=on
|
||||
|
||||
After=gnome-session-manager.target
|
||||
|
||||
Requisite=gnome-session-initialized.target
|
||||
PartOf=gnome-session-initialized.target
|
||||
Before=gnome-session-initialized.target
|
||||
|
||||
# The units already conflict because they use the same BusName
|
||||
#Conflicts=gnome-shell-x11.service
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=@bindir@/gnome-shell
|
||||
# Exit code 1 means we are probably *not* dealing with an extension failure
|
||||
SuccessExitStatus=1
|
||||
# On wayland we cannot restart
|
||||
Restart=no
|
||||
@@ -1,5 +1,12 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell (wayland sync point)
|
||||
After=gnome-shell.service
|
||||
BindsTo=gnome-shell.service
|
||||
Conflicts=gnome-shell-x11.target
|
||||
Description=GNOME Shell on Wayland
|
||||
DefaultDependencies=no
|
||||
|
||||
Requisite=gnome-session-initialized.target
|
||||
PartOf=gnome-session-initialized.target
|
||||
Before=gnome-session-initialized.target
|
||||
|
||||
Requires=gnome-shell-wayland.service
|
||||
After=gnome-shell-wayland.service
|
||||
|
||||
Wants=gnome-shell-extensions-disabled-warning.service
|
||||
|
||||
31
data/gnome-shell-x11.service.in
Normal file
@@ -0,0 +1,31 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell on X11
|
||||
# On X11, try to show the GNOME Session Failed screen
|
||||
OnFailure=gnome-shell-disable-extensions.service gnome-session-failed.target
|
||||
OnFailureJobMode=replace
|
||||
CollectMode=inactive-or-failed
|
||||
RefuseManualStart=on
|
||||
RefuseManualStop=on
|
||||
|
||||
After=gnome-session-manager.target
|
||||
|
||||
Requisite=gnome-session-initialized.target
|
||||
PartOf=gnome-session-initialized.target
|
||||
Before=gnome-session-initialized.target
|
||||
|
||||
# The units already conflict because they use the same BusName
|
||||
#Conflicts=gnome-shell-wayland.service
|
||||
|
||||
# Limit startup frequency more than the default
|
||||
StartLimitIntervalSec=15s
|
||||
StartLimitBurst=3
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
ExecStart=@bindir@/gnome-shell
|
||||
# Exit code 1 means we are probably *not* dealing with an extension failure
|
||||
SuccessExitStatus=1
|
||||
# On X11 we want to restart on-success (Alt+F2 + r) and on-failure.
|
||||
Restart=always
|
||||
# Do not wait before restarting the shell
|
||||
RestartSec=0ms
|
||||
@@ -1,5 +1,12 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell (x11 sync point)
|
||||
After=gnome-shell.service
|
||||
BindsTo=gnome-shell.service
|
||||
Conflicts=gnome-shell-wayland.target
|
||||
Description=GNOME Shell on X11
|
||||
DefaultDependencies=no
|
||||
|
||||
Requisite=gnome-session-initialized.target
|
||||
PartOf=gnome-session-initialized.target
|
||||
Before=gnome-session-initialized.target
|
||||
|
||||
Requires=gnome-shell-x11.service
|
||||
After=gnome-shell-x11.service
|
||||
|
||||
Wants=gnome-shell-extensions-disabled-warning.service
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
[Unit]
|
||||
Description=GNOME Shell
|
||||
Wants=gnome-session.service
|
||||
After=graphical-session-pre.target gnome-session-bus.target
|
||||
PartOf=graphical-session.target
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
ExecStart=@bindir@/gnome-shell
|
||||
Restart=on-failure
|
||||
BusName=org.gnome.Shell
|
||||
@@ -14,6 +14,8 @@ desktopconf = configuration_data()
|
||||
# file when built in a non-system prefix
|
||||
desktopconf.set('bindir', bindir)
|
||||
desktopconf.set('VERSION', meson.project_version())
|
||||
desktopconf.set('systemd_hidden', have_systemd ? 'true' : 'false')
|
||||
|
||||
foreach desktop_file : desktop_files
|
||||
i18n.merge_file('desktop',
|
||||
input: configure_file(
|
||||
@@ -22,13 +24,26 @@ foreach desktop_file : desktop_files
|
||||
configuration: desktopconf
|
||||
),
|
||||
output: desktop_file,
|
||||
po_dir: '../po',
|
||||
po_dir: po_dir,
|
||||
install: true,
|
||||
install_dir: desktopdir,
|
||||
type: 'desktop'
|
||||
)
|
||||
endforeach
|
||||
|
||||
i18n.merge_file('desktop',
|
||||
input: configure_file(
|
||||
input: 'gnome-shell-extensions-disabled-warning.desktop.in.in',
|
||||
output: 'gnome-shell-extensions-disabled-warning.desktop.in',
|
||||
configuration: desktopconf
|
||||
),
|
||||
output: 'gnome-shell-extension-disabled-warning.desktop',
|
||||
po_dir: po_dir,
|
||||
install: true,
|
||||
install_dir: autostartdir,
|
||||
type: 'desktop'
|
||||
)
|
||||
|
||||
serviceconf = configuration_data()
|
||||
serviceconf.set('libexecdir', libexecdir)
|
||||
foreach service_file : service_files
|
||||
@@ -98,15 +113,23 @@ if have_systemd
|
||||
unitconf = configuration_data()
|
||||
unitconf.set('bindir', bindir)
|
||||
|
||||
unit = configure_file(
|
||||
input: 'gnome-shell.service.in',
|
||||
output: 'gnome-shell.service',
|
||||
configure_file(
|
||||
input: 'gnome-shell-x11.service.in',
|
||||
output: 'gnome-shell-x11.service',
|
||||
configuration: unitconf,
|
||||
install_dir: systemduserunitdir
|
||||
)
|
||||
|
||||
units = files('gnome-shell-wayland.target',
|
||||
'gnome-shell-x11.target')
|
||||
configure_file(
|
||||
input: 'gnome-shell-wayland.service.in',
|
||||
output: 'gnome-shell-wayland.service',
|
||||
configuration: unitconf,
|
||||
install_dir: systemduserunitdir
|
||||
)
|
||||
|
||||
units = files('gnome-shell-x11.target',
|
||||
'gnome-shell-wayland.target',
|
||||
'gnome-shell-disable-extensions.service')
|
||||
|
||||
install_data(units, install_dir: systemduserunitdir)
|
||||
endif
|
||||
|
||||
@@ -14,3 +14,4 @@ X-GNOME-Autostart-Phase=DisplayServer
|
||||
X-GNOME-Provides=panel;windowmanager;
|
||||
X-GNOME-Autostart-Notify=true
|
||||
X-GNOME-AutoRestart=false
|
||||
X-GNOME-HiddenUnderSystemd=@systemd_hidden@
|
||||
|
||||
@@ -21,6 +21,17 @@
|
||||
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
|
||||
</description>
|
||||
</key>
|
||||
<key name="disabled-extensions" type="as">
|
||||
<default>[]</default>
|
||||
<summary>UUIDs of extensions to force disabling</summary>
|
||||
<description>
|
||||
GNOME Shell extensions have a UUID property; this key lists extensions
|
||||
which should be disabled, even if loaded as part of the current mode.
|
||||
You can also manipulate this list with the EnableExtension and
|
||||
DisableExtension D-Bus methods on org.gnome.Shell.
|
||||
This key takes precedence over the “enabled-extensions” setting.
|
||||
</description>
|
||||
</key>
|
||||
<key name="disable-user-extensions" type="b">
|
||||
<default>false</default>
|
||||
<summary>Disable user extensions</summary>
|
||||
@@ -99,7 +110,6 @@
|
||||
</description>
|
||||
</key>
|
||||
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
|
||||
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
|
||||
</schema>
|
||||
|
||||
<schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/"
|
||||
@@ -140,21 +150,41 @@
|
||||
Keybinding to focus the active notification.
|
||||
</description>
|
||||
</key>
|
||||
<key name="pause-resume-tweens" type="as">
|
||||
<default>[]</default>
|
||||
<summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary>
|
||||
<description></description>
|
||||
<key name="switch-to-application-1" type="as">
|
||||
<default>["<Super>1"]</default>
|
||||
<summary>Switch to application 1</summary>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
<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 name="switch-to-application-2" type="as">
|
||||
<default>["<Super>2"]</default>
|
||||
<summary>Switch to application 2</summary>
|
||||
</key>
|
||||
<key name="switch-to-application-3" type="as">
|
||||
<default>["<Super>3"]</default>
|
||||
<summary>Switch to application 3</summary>
|
||||
</key>
|
||||
<key name="switch-to-application-4" type="as">
|
||||
<default>["<Super>4"]</default>
|
||||
<summary>Switch to application 4</summary>
|
||||
</key>
|
||||
<key name="switch-to-application-5" type="as">
|
||||
<default>["<Super>5"]</default>
|
||||
<summary>Switch to application 5</summary>
|
||||
</key>
|
||||
<key name="switch-to-application-6" type="as">
|
||||
<default>["<Super>6"]</default>
|
||||
<summary>Switch to application 6</summary>
|
||||
</key>
|
||||
<key name="switch-to-application-7" type="as">
|
||||
<default>["<Super>7"]</default>
|
||||
<summary>Switch to application 7</summary>
|
||||
</key>
|
||||
<key name="switch-to-application-8" type="as">
|
||||
<default>["<Super>8"]</default>
|
||||
<summary>Switch to application 8</summary>
|
||||
</key>
|
||||
<key name="switch-to-application-9" type="as">
|
||||
<default>["<Super>9"]</default>
|
||||
<summary>Switch to application 9</summary>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
@@ -198,6 +228,36 @@
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
<schema id="org.gnome.shell.world-clocks" path="/org/gnome/shell/world-clocks/"
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="locations" type="av">
|
||||
<summary>Locations</summary>
|
||||
<description>
|
||||
The locations to show in world clocks
|
||||
</description>
|
||||
<default>[]</default>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
<schema id="org.gnome.shell.weather" path="/org/gnome/shell/weather/"
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="automatic-location" type="b">
|
||||
<summary>Automatic location</summary>
|
||||
<description>
|
||||
Whether to fetch the current location or not
|
||||
</description>
|
||||
<default>false</default>
|
||||
</key>
|
||||
|
||||
<key name="locations" type="av">
|
||||
<summary>Location</summary>
|
||||
<description>
|
||||
The location for which to show a forecast
|
||||
</description>
|
||||
<default>[]</default>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
<!-- unused, change 00_org.gnome.shell.gschema.override instead -->
|
||||
<schema id="org.gnome.shell.overrides" path="/org/gnome/shell/overrides/"
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
|
||||
599
data/osk-layouts/ca.json
Normal file
@@ -0,0 +1,599 @@
|
||||
{
|
||||
"levels": [
|
||||
{
|
||||
"level": "",
|
||||
"mode": "default",
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"q"
|
||||
],
|
||||
[
|
||||
"w"
|
||||
],
|
||||
[
|
||||
"e",
|
||||
"é",
|
||||
"è",
|
||||
"ê",
|
||||
"ë",
|
||||
"%",
|
||||
"ę",
|
||||
"ė",
|
||||
"ē"
|
||||
],
|
||||
[
|
||||
"r"
|
||||
],
|
||||
[
|
||||
"t"
|
||||
],
|
||||
[
|
||||
"y",
|
||||
"%",
|
||||
"ÿ"
|
||||
],
|
||||
[
|
||||
"u",
|
||||
"ù",
|
||||
"û",
|
||||
"%",
|
||||
"ü",
|
||||
"ú",
|
||||
"ū"
|
||||
],
|
||||
[
|
||||
"i",
|
||||
"î",
|
||||
"%",
|
||||
"ï",
|
||||
"ì",
|
||||
"í",
|
||||
"į",
|
||||
"ī"
|
||||
],
|
||||
[
|
||||
"o",
|
||||
"ô",
|
||||
"œ",
|
||||
"%",
|
||||
"ö",
|
||||
"ò",
|
||||
"ó",
|
||||
"õ",
|
||||
"ø",
|
||||
"ō",
|
||||
"º"
|
||||
],
|
||||
[
|
||||
"p"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"a",
|
||||
"à",
|
||||
"â",
|
||||
"%",
|
||||
"æ",
|
||||
"á",
|
||||
"ä",
|
||||
"ã",
|
||||
"å",
|
||||
"ā",
|
||||
"ª"
|
||||
],
|
||||
[
|
||||
"s"
|
||||
],
|
||||
[
|
||||
"d"
|
||||
],
|
||||
[
|
||||
"f"
|
||||
],
|
||||
[
|
||||
"g"
|
||||
],
|
||||
[
|
||||
"h"
|
||||
],
|
||||
[
|
||||
"j"
|
||||
],
|
||||
[
|
||||
"k"
|
||||
],
|
||||
[
|
||||
"l"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"z"
|
||||
],
|
||||
[
|
||||
"x"
|
||||
],
|
||||
[
|
||||
"c",
|
||||
"ç",
|
||||
"ć",
|
||||
"č"
|
||||
],
|
||||
[
|
||||
"v"
|
||||
],
|
||||
[
|
||||
"b"
|
||||
],
|
||||
[
|
||||
"n"
|
||||
],
|
||||
[
|
||||
"m"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
","
|
||||
],
|
||||
[
|
||||
" "
|
||||
],
|
||||
[
|
||||
".",
|
||||
"#",
|
||||
"!",
|
||||
",",
|
||||
"?",
|
||||
"-",
|
||||
":",
|
||||
"'",
|
||||
"@"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": "shift",
|
||||
"mode": "latched",
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"Q"
|
||||
],
|
||||
[
|
||||
"W"
|
||||
],
|
||||
[
|
||||
"E",
|
||||
"É",
|
||||
"È",
|
||||
"Ê",
|
||||
"Ë",
|
||||
"%",
|
||||
"Ę",
|
||||
"Ė",
|
||||
"Ē"
|
||||
],
|
||||
[
|
||||
"R"
|
||||
],
|
||||
[
|
||||
"T"
|
||||
],
|
||||
[
|
||||
"Y",
|
||||
"%",
|
||||
"Ÿ"
|
||||
],
|
||||
[
|
||||
"U",
|
||||
"Ù",
|
||||
"Û",
|
||||
"%",
|
||||
"Ü",
|
||||
"Ú",
|
||||
"Ū"
|
||||
],
|
||||
[
|
||||
"I",
|
||||
"Î",
|
||||
"%",
|
||||
"Ï",
|
||||
"Ì",
|
||||
"Í",
|
||||
"Į",
|
||||
"Ī"
|
||||
],
|
||||
[
|
||||
"O",
|
||||
"Ô",
|
||||
"Œ",
|
||||
"%",
|
||||
"Ö",
|
||||
"Ò",
|
||||
"Ó",
|
||||
"Õ",
|
||||
"Ø",
|
||||
"Ō",
|
||||
"º"
|
||||
],
|
||||
[
|
||||
"P"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"A",
|
||||
"À",
|
||||
"Â",
|
||||
"%",
|
||||
"Æ",
|
||||
"Á",
|
||||
"Ä",
|
||||
"Ã",
|
||||
"Å",
|
||||
"Ā",
|
||||
"ª"
|
||||
],
|
||||
[
|
||||
"S"
|
||||
],
|
||||
[
|
||||
"D"
|
||||
],
|
||||
[
|
||||
"F"
|
||||
],
|
||||
[
|
||||
"G"
|
||||
],
|
||||
[
|
||||
"H"
|
||||
],
|
||||
[
|
||||
"J"
|
||||
],
|
||||
[
|
||||
"K"
|
||||
],
|
||||
[
|
||||
"L"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"Z"
|
||||
],
|
||||
[
|
||||
"X"
|
||||
],
|
||||
[
|
||||
"C",
|
||||
"Ç",
|
||||
"Ć",
|
||||
"Č"
|
||||
],
|
||||
[
|
||||
"V"
|
||||
],
|
||||
[
|
||||
"B"
|
||||
],
|
||||
[
|
||||
"N"
|
||||
],
|
||||
[
|
||||
"M"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
","
|
||||
],
|
||||
[
|
||||
" "
|
||||
],
|
||||
[
|
||||
".",
|
||||
"#",
|
||||
"!",
|
||||
",",
|
||||
"?",
|
||||
"-",
|
||||
":",
|
||||
"'",
|
||||
"@"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": "opt",
|
||||
"mode": "locked",
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"1",
|
||||
"¹",
|
||||
"½",
|
||||
"⅓",
|
||||
"¼",
|
||||
"⅛"
|
||||
],
|
||||
[
|
||||
"2",
|
||||
"²",
|
||||
"⅔"
|
||||
],
|
||||
[
|
||||
"3",
|
||||
"³",
|
||||
"¾",
|
||||
"⅜"
|
||||
],
|
||||
[
|
||||
"4",
|
||||
"⁴"
|
||||
],
|
||||
[
|
||||
"5",
|
||||
"⅝"
|
||||
],
|
||||
[
|
||||
"6"
|
||||
],
|
||||
[
|
||||
"7",
|
||||
"⅞"
|
||||
],
|
||||
[
|
||||
"8"
|
||||
],
|
||||
[
|
||||
"9"
|
||||
],
|
||||
[
|
||||
"0",
|
||||
"ⁿ",
|
||||
"∅"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"@"
|
||||
],
|
||||
[
|
||||
"#"
|
||||
],
|
||||
[
|
||||
"$",
|
||||
"¢",
|
||||
"£",
|
||||
"€",
|
||||
"¥",
|
||||
"₱"
|
||||
],
|
||||
[
|
||||
"%",
|
||||
"‰"
|
||||
],
|
||||
[
|
||||
"&"
|
||||
],
|
||||
[
|
||||
"-",
|
||||
"_",
|
||||
"–",
|
||||
"—",
|
||||
"·"
|
||||
],
|
||||
[
|
||||
"+",
|
||||
"±"
|
||||
],
|
||||
[
|
||||
"(",
|
||||
"<",
|
||||
"{",
|
||||
"["
|
||||
],
|
||||
[
|
||||
")",
|
||||
">",
|
||||
"}",
|
||||
"]"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"*",
|
||||
"†",
|
||||
"‡",
|
||||
"★"
|
||||
],
|
||||
[
|
||||
"\"",
|
||||
"“",
|
||||
"”",
|
||||
"«",
|
||||
"»"
|
||||
],
|
||||
[
|
||||
"'",
|
||||
"‘",
|
||||
"’",
|
||||
"‹",
|
||||
"›"
|
||||
],
|
||||
[
|
||||
":"
|
||||
],
|
||||
[
|
||||
";"
|
||||
],
|
||||
[
|
||||
"!",
|
||||
"¡"
|
||||
],
|
||||
[
|
||||
"?",
|
||||
"¿"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"_"
|
||||
],
|
||||
[
|
||||
"/"
|
||||
],
|
||||
[
|
||||
" "
|
||||
],
|
||||
[
|
||||
","
|
||||
],
|
||||
[
|
||||
".",
|
||||
"…"
|
||||
]
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": "opt+shift",
|
||||
"mode": "locked",
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"~"
|
||||
],
|
||||
[
|
||||
"`"
|
||||
],
|
||||
[
|
||||
"|"
|
||||
],
|
||||
[
|
||||
"•",
|
||||
"♪",
|
||||
"♥",
|
||||
"♠",
|
||||
"♦",
|
||||
"♣"
|
||||
],
|
||||
[
|
||||
"√"
|
||||
],
|
||||
[
|
||||
"Π",
|
||||
"π"
|
||||
],
|
||||
[
|
||||
"÷"
|
||||
],
|
||||
[
|
||||
"×"
|
||||
],
|
||||
[
|
||||
"¶",
|
||||
"§"
|
||||
],
|
||||
[
|
||||
"∆"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"£"
|
||||
],
|
||||
[
|
||||
"¢"
|
||||
],
|
||||
[
|
||||
"€"
|
||||
],
|
||||
[
|
||||
"¥"
|
||||
],
|
||||
[
|
||||
"^",
|
||||
"↑",
|
||||
"↓",
|
||||
"←",
|
||||
"→"
|
||||
],
|
||||
[
|
||||
"°",
|
||||
"′",
|
||||
"″"
|
||||
],
|
||||
[
|
||||
"=",
|
||||
"≠",
|
||||
"≈",
|
||||
"∞"
|
||||
],
|
||||
[
|
||||
"{"
|
||||
],
|
||||
[
|
||||
"}"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"\\"
|
||||
],
|
||||
[
|
||||
"©"
|
||||
],
|
||||
[
|
||||
"®"
|
||||
],
|
||||
[
|
||||
"™"
|
||||
],
|
||||
[
|
||||
"℅"
|
||||
],
|
||||
[
|
||||
"["
|
||||
],
|
||||
[
|
||||
"]"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"<",
|
||||
"‹",
|
||||
"≤",
|
||||
"«"
|
||||
],
|
||||
[
|
||||
">",
|
||||
"›",
|
||||
"≥",
|
||||
"»"
|
||||
],
|
||||
[
|
||||
" "
|
||||
],
|
||||
[
|
||||
","
|
||||
],
|
||||
[
|
||||
".",
|
||||
"…"
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"locale": "fr-CA",
|
||||
"name": "French Canada"
|
||||
}
|
||||
@@ -6,10 +6,20 @@
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"q"
|
||||
"a",
|
||||
"à",
|
||||
"â",
|
||||
"%",
|
||||
"æ",
|
||||
"á",
|
||||
"ä",
|
||||
"ã",
|
||||
"å",
|
||||
"ā",
|
||||
"ª"
|
||||
],
|
||||
[
|
||||
"w"
|
||||
"z"
|
||||
],
|
||||
[
|
||||
"e",
|
||||
@@ -71,17 +81,7 @@
|
||||
],
|
||||
[
|
||||
[
|
||||
"a",
|
||||
"à",
|
||||
"â",
|
||||
"%",
|
||||
"æ",
|
||||
"á",
|
||||
"ä",
|
||||
"ã",
|
||||
"å",
|
||||
"ā",
|
||||
"ª"
|
||||
"q"
|
||||
],
|
||||
[
|
||||
"s"
|
||||
@@ -106,11 +106,14 @@
|
||||
],
|
||||
[
|
||||
"l"
|
||||
],
|
||||
[
|
||||
"m"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"z"
|
||||
"w"
|
||||
],
|
||||
[
|
||||
"x"
|
||||
@@ -131,7 +134,11 @@
|
||||
"n"
|
||||
],
|
||||
[
|
||||
"m"
|
||||
"'",
|
||||
"‘",
|
||||
"’",
|
||||
"‹",
|
||||
"›"
|
||||
]
|
||||
],
|
||||
[
|
||||
@@ -161,10 +168,20 @@
|
||||
"rows": [
|
||||
[
|
||||
[
|
||||
"Q"
|
||||
"A",
|
||||
"À",
|
||||
"Â",
|
||||
"%",
|
||||
"Æ",
|
||||
"Á",
|
||||
"Ä",
|
||||
"Ã",
|
||||
"Å",
|
||||
"Ā",
|
||||
"ª"
|
||||
],
|
||||
[
|
||||
"W"
|
||||
"Z"
|
||||
],
|
||||
[
|
||||
"E",
|
||||
@@ -226,17 +243,7 @@
|
||||
],
|
||||
[
|
||||
[
|
||||
"A",
|
||||
"À",
|
||||
"Â",
|
||||
"%",
|
||||
"Æ",
|
||||
"Á",
|
||||
"Ä",
|
||||
"Ã",
|
||||
"Å",
|
||||
"Ā",
|
||||
"ª"
|
||||
"Q"
|
||||
],
|
||||
[
|
||||
"S"
|
||||
@@ -261,11 +268,14 @@
|
||||
],
|
||||
[
|
||||
"L"
|
||||
],
|
||||
[
|
||||
"M"
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
"Z"
|
||||
"W"
|
||||
],
|
||||
[
|
||||
"X"
|
||||
@@ -286,7 +296,11 @@
|
||||
"N"
|
||||
],
|
||||
[
|
||||
"M"
|
||||
"'",
|
||||
"‘",
|
||||
"’",
|
||||
"‹",
|
||||
"›"
|
||||
]
|
||||
],
|
||||
[
|
||||
@@ -369,10 +383,10 @@
|
||||
"#"
|
||||
],
|
||||
[
|
||||
"$",
|
||||
"€",
|
||||
"¢",
|
||||
"£",
|
||||
"€",
|
||||
"$",
|
||||
"¥",
|
||||
"₱"
|
||||
],
|
||||
@@ -511,13 +525,14 @@
|
||||
"£"
|
||||
],
|
||||
[
|
||||
"¥"
|
||||
],
|
||||
[
|
||||
"$",
|
||||
"¢"
|
||||
],
|
||||
[
|
||||
"€"
|
||||
],
|
||||
[
|
||||
"¥"
|
||||
"¢"
|
||||
],
|
||||
[
|
||||
"^",
|
||||
@@ -594,6 +609,6 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"locale": "fr-CA",
|
||||
"name": "French Canada"
|
||||
"locale": "fr",
|
||||
"name": "French"
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
$variant: 'light';
|
||||
|
||||
@import "gnome-shell-sass/_high-contrast-colors"; //use gtk colors
|
||||
@import "gnome-shell-sass/_drawing";
|
||||
@import "gnome-shell-sass/_common";
|
||||
|
||||
@@ -2,33 +2,34 @@
|
||||
// it gets @if ed depending on $variant
|
||||
|
||||
|
||||
$base_color: if($variant =='light', #ffffff, #292929);
|
||||
$bg_color: if($variant =='light', #ededed, #393f3f);
|
||||
$fg_color: if($variant =='light', #2e3436, #eeeeec);
|
||||
$base_color: if($variant == 'light', #ffffff, lighten(desaturate(#241f31, 20%), 2%));
|
||||
$bg_color: if($variant == 'light', #f6f5f4, darken(desaturate(#3d3846, 100%), 4%));
|
||||
$fg_color: if($variant == 'light', #2e3436, #eeeeec);
|
||||
|
||||
$selected_fg_color: #ffffff;
|
||||
$selected_bg_color: if($variant == 'light', #4a90d9, darken(#4a90d9,20%));
|
||||
$selected_borders_color: if($variant=='light', darken($selected_bg_color, 30%),
|
||||
darken($selected_bg_color, 20%));
|
||||
$borders_color: if($variant =='light', darken($bg_color,30%), darken($bg_color,12%));
|
||||
$borders_edge: if($variant =='light', white, transparentize($fg_color, 0.9));
|
||||
$link_color: if($variant == 'light', darken($selected_bg_color,10%),
|
||||
lighten($selected_bg_color,20%));
|
||||
$link_visited_color: if($variant == 'light', darken($selected_bg_color,20%),
|
||||
lighten($selected_bg_color,10%));
|
||||
$selected_bg_color: if($variant == 'light', #3584e4, darken(#3584e4, 10%));
|
||||
$selected_borders_color: if($variant== 'light', darken($selected_bg_color, 15%), darken($selected_bg_color, 30%));
|
||||
$borders_color: if($variant == 'light', darken($bg_color, 18%), darken($bg_color, 10%));
|
||||
$borders_edge: if($variant == 'light', transparentize(white, 0.2), transparentize($fg_color, 0.93));
|
||||
$link_color: if($variant == 'light', darken($selected_bg_color, 10%), lighten($selected_bg_color, 20%));
|
||||
$link_visited_color: if($variant == 'light', darken($selected_bg_color, 20%), lighten($selected_bg_color, 10%));
|
||||
$top_hilight: $borders_edge;
|
||||
|
||||
$warning_color: #f57900;
|
||||
$error_color: #cc0000;
|
||||
$success_color: if($variant =='light', #73d216, darken(#73d216,10%));
|
||||
$destructive_color: if($variant =='light', #ef2929, darken(#ef2929,10%));
|
||||
$error_color: #ff8080;
|
||||
$success_color: if($variant == 'light', #33d17a, darken(#33d17a, 10%));
|
||||
$destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
|
||||
|
||||
$osd_fg_color: #eeeeec;
|
||||
$osd_bg_color: #2e3436;
|
||||
$osd_text_color: white;
|
||||
$osd_bg_color: transparentize(darken(desaturate(#3d3846, 100%), 12%),0.04);
|
||||
$osd_insensitive_bg_color: transparentize(mix($osd_fg_color, opacify($osd_bg_color, 1), 10%), 0.5);
|
||||
$osd_insensitive_fg_color: mix($osd_fg_color, opacify($osd_bg_color, 1), 50%);
|
||||
$osd_borders_color: transparentize(black, 0.3);
|
||||
$osd_outer_borders_color: transparentize(white, 0.9);
|
||||
$osd_outer_borders_color: transparentize(white, 0.84);
|
||||
|
||||
$tooltip_borders_color: $osd_outer_borders_color;
|
||||
$shadow_color: transparentize(black, 0.9);
|
||||
|
||||
//insensitive state derived colors
|
||||
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);
|
||||
|
||||
@@ -37,16 +37,13 @@
|
||||
// possible $t values:
|
||||
// normal, focus, insensitive
|
||||
//
|
||||
$_inner_shadows: inset 0 2px 4px transparentize(black, 0.6);
|
||||
|
||||
@if $t==normal {
|
||||
background-color: $base_color;
|
||||
border-color: $borders_color;
|
||||
@include _shadows($_inner_shadows);
|
||||
|
||||
}
|
||||
@if $t==focus {
|
||||
@include _shadows($_inner_shadows);
|
||||
border-color: if($fc==$selected_bg_color,
|
||||
$selected_borders_color,
|
||||
darken($fc,35%));
|
||||
@@ -111,7 +108,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button($t, $c:$osd_bg_color, $tc:$fg_color, $edge: $borders_edge) {
|
||||
@mixin button($t, $c:$bg_color, $tc:$fg_color, $edge: $borders_edge) {
|
||||
//
|
||||
// Button drawing function
|
||||
//
|
||||
@@ -130,46 +127,39 @@
|
||||
$_hilight_color: _button_hilight_color($c);
|
||||
$_button_edge: if($edge == none, none, _widget_edge($edge));
|
||||
$_blank_edge: if($edge == none, none, _widget_edge(transparentize($edge,1)));
|
||||
|
||||
$_button_shadow: 0 1px 2px transparentize($shadow_color, 0.03);
|
||||
|
||||
@if $t==normal {
|
||||
//
|
||||
// normal button
|
||||
//
|
||||
$_bg: if($c!=$osd_bg_color, transparentize($c, 0.5),
|
||||
$osd_bg_color);
|
||||
|
||||
color: $osd_fg_color;
|
||||
background-color: $_bg;
|
||||
border-color: $osd_borders_color;
|
||||
box-shadow: inset 0 1px lighten($osd_bg_color,10%);
|
||||
color: $tc;
|
||||
background-color: $c;
|
||||
border-color: $borders_color;
|
||||
box-shadow: $_button_shadow;
|
||||
text-shadow: 0 1px black;
|
||||
icon-shadow: 0 1px black;
|
||||
}
|
||||
@if $t==focus {
|
||||
//
|
||||
// focused button
|
||||
//
|
||||
$_bg: if($c!=$osd_bg_color, transparentize($c, 0.3),
|
||||
lighten($osd_bg_color,3%));
|
||||
|
||||
color: $osd_fg_color;
|
||||
//
|
||||
color: $tc;
|
||||
text-shadow: 0 1px black;
|
||||
icon-shadow: 0 1px black;
|
||||
box-shadow: inset 0px 0px 0px 1px $selected_bg_color;
|
||||
box-shadow: inset 0px 0px 0px 2px $selected_bg_color;
|
||||
//border-color: $selected_bg_color;
|
||||
}
|
||||
|
||||
@else if $t==hover {
|
||||
//
|
||||
// active osd button
|
||||
//
|
||||
$_bg: if($c!=$osd_bg_color, transparentize($c, 0.3),
|
||||
lighten($osd_bg_color,3%));
|
||||
|
||||
color: white;
|
||||
border-color: $osd_borders_color;
|
||||
background-color: $_bg;
|
||||
box-shadow: inset 0 1px lighten($osd_bg_color,20%);
|
||||
color: $tc;
|
||||
border-color: $borders_color;
|
||||
background-color: $c;
|
||||
box-shadow: $_button_shadow;
|
||||
text-shadow: 0 1px black;
|
||||
icon-shadow: 0 1px black;
|
||||
|
||||
@@ -178,27 +168,18 @@
|
||||
//
|
||||
// active osd button
|
||||
//
|
||||
$_bg: if($c!=$bg_color, $c, $osd_borders_color);
|
||||
|
||||
color: white;
|
||||
border-color: $osd_borders_color;
|
||||
background-color: $selected_bg_color;
|
||||
// This should be none, but it's creating some issues with borders, so to
|
||||
// workaround it for now, use inset wich goes through a different code path.
|
||||
// see https://bugzilla.gnome.org/show_bug.cgi?id=752934
|
||||
box-shadow: inset 0 0 black;
|
||||
color: $tc;
|
||||
border-color: $borders_color;
|
||||
background-color: $c;
|
||||
text-shadow: none;
|
||||
icon-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
@else if $t==insensitive {
|
||||
//
|
||||
// insensitive osd button
|
||||
//
|
||||
$_bg: transparentize(mix($insensitive_fg_color,$osd_bg_color,20%),0.3);
|
||||
|
||||
color: $insensitive_fg_color;
|
||||
border-color: $osd_borders_color;
|
||||
background-color: $_bg;
|
||||
border-color: $insensitive_borders_color;
|
||||
background-color: $insensitive_bg_color;
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
icon-shadow: none;
|
||||
|
||||
@@ -26,6 +26,7 @@ $osd_borders_color: transparentize(black, 0.3);
|
||||
$osd_outer_borders_color: transparentize(white, 0.9);
|
||||
|
||||
$tooltip_borders_color: $osd_outer_borders_color;
|
||||
$shadow_color: transparentize(black, 0.9);
|
||||
|
||||
//insensitive state derived colors
|
||||
$insensitive_fg_color: mix($fg_color, $bg_color, 50%);
|
||||
|
||||
28
data/theme/pointer-double-click-symbolic.svg
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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="20"
|
||||
height="20"
|
||||
id="svg2">
|
||||
<g
|
||||
id="layer1"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="id1"
|
||||
transform="translate(-19,-0.75)">
|
||||
<path
|
||||
style="color:#000000;shape-padding:0;clip-rule:nonzero;display:block;overflow:visible;visibility:visible;opacity:1;solid-color:#000000;solid-opacity:1;fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 19.855469,0.45507812 c 0,6.69466128 0,13.38932288 0,20.08398388 1.414713,-1.38151 2.829427,-2.763021 4.24414,-4.144531 0.5882,1.18866 1.158389,2.386561 1.758464,3.569127 1.108631,1.640259 4.157538,0.465128 3.89799,-1.495859 0.01057,-0.470226 -0.405577,-0.908445 -0.434651,-1.313638 0.259401,-0.25321 0.518802,-0.50642 0.778203,-0.75963 0.5882,1.18866 1.158389,2.386561 1.758464,3.569127 1.108631,1.640259 4.157538,0.465128 3.89799,-1.495859 -0.192325,-0.904303 -0.717854,-1.698026 -1.068629,-2.548967 -0.238908,-0.512658 -0.477817,-1.025315 -0.716725,-1.537973 1.755859,0 3.511719,0 5.267578,0 C 34.777352,9.738932 30.31641,5.0970051 25.855469,0.45507812 c 0,2.08138018 0,4.16276048 0,6.24414068 -2,-2.0813802 -4,-4.1627605 -6,-6.24414068 z m 1.5,3.72656248 c 2,2.0813801 4,4.1627603 6,6.2441404 0,-2.0813801 0,-4.1627603 0,-6.2441404 2.786458,2.8997395 5.572917,5.7994789 8.359375,8.6992184 -1.366537,0 -2.733073,0 -4.09961,0 0.883468,1.903435 1.781983,3.800273 2.656081,5.707817 0.0065,0.622781 -1.227555,0.980575 -1.325116,0.207118 -0.80433,-1.640251 -1.608661,-3.280501 -2.412991,-4.920752 -1.020182,0.995443 -2.040365,1.990885 -3.060547,2.986328 0.263642,0.608048 0.596803,1.192457 0.814693,1.816134 -0.182662,0.601037 -1.26833,0.8373 -1.365856,0.06795 -0.796094,-1.623456 -1.592189,-3.246912 -2.388284,-4.870368 -1.059245,1.033854 -2.118489,2.067708 -3.177734,3.101562 -4e-6,-4.265002 -7e-6,-8.5300036 -1.1e-5,-12.7950054 z"
|
||||
id="path5565" />
|
||||
</g>
|
||||
<g
|
||||
id="id2"
|
||||
transform="translate(-25,-0.75)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
20
data/theme/pointer-drag-symbolic.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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="20"
|
||||
height="20"
|
||||
id="svg2">
|
||||
<g
|
||||
id="g835">
|
||||
<path
|
||||
style="color:#000000;shape-padding:0;clip-rule:nonzero;display:block;overflow:visible;visibility:visible;opacity:1;solid-color:#000000;solid-opacity:1;fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="M 10.705078 1.671875 C 9.8685536 1.7465699 8.886927 1.5353073 8.2578125 2.2480469 C 8.0785627 2.7511513 7.8667422 2.9777446 7.3125 2.8652344 C 6.5186841 2.8141575 5.6105879 2.9190179 5.125 3.6386719 C 4.5700923 4.4696324 4.8113194 5.4949043 4.7578125 6.4316406 L 4.7578125 7.9335938 C 4.2480917 7.6156216 3.6258927 7.8015358 3.0585938 7.7519531 C 2.6157606 7.7312277 2.1774807 7.7771069 1.7402344 7.84375 C 1.7971654 10.529678 1.813967 13.217089 1.8613281 15.902344 C 1.9550191 17.204635 3.0933719 18.307155 4.40625 18.326172 C 5.0391993 18.341272 5.8885801 18.332951 6.6308594 18.337891 C 9.8526764 18.325821 13.076973 18.38774 16.296875 18.28125 C 17.459088 18.161027 18.510143 17.092798 18.367188 15.884766 L 18.367188 6.4042969 C 17.660379 5.4636119 16.551912 4.623434 15.308594 4.8339844 C 15.009045 4.3804158 14.822476 3.3608651 14.082031 3.0351562 C 13.727176 2.744118 13.242443 2.9253873 12.822266 2.8730469 C 12.524824 2.8003648 11.966366 3.0655864 11.953125 2.6210938 C 11.795774 2.0995736 11.23789 1.7125276 10.705078 1.671875 z M 10.599609 3.1757812 C 10.764131 3.4472414 10.782382 3.9294982 10.818359 4.3007812 C 10.824915 4.3076775 10.838155 4.3066925 10.845703 4.3125 C 10.836598 4.3123268 10.827465 4.3126732 10.818359 4.3125 L 11.3125 10.212891 L 11.976562 4.3710938 L 13.322266 4.375 C 13.858345 4.7645492 13.735252 5.5154752 13.876953 6.0976562 C 13.865826 6.1651282 13.88335 6.1937019 13.892578 6.234375 C 13.891928 6.2343667 13.891276 6.2343833 13.890625 6.234375 L 13.902344 6.3203125 L 14.384766 10.185547 L 15.048828 6.265625 C 15.622863 6.228498 16.206517 6.3041365 16.607422 6.7675781 C 17.017062 6.9844433 16.823063 7.4565491 16.867188 7.8261719 L 16.867188 16.167969 C 16.530129 17.131654 15.267211 16.71624 14.492188 16.828125 C 11.121671 16.841205 7.7500508 16.861953 4.3808594 16.814453 C 3.4051926 16.786173 3.2389196 15.744474 3.3398438 14.972656 C 3.3282027 13.065594 3.2950998 11.158732 3.2617188 9.2519531 C 3.5880829 9.2584131 3.9376766 9.2391948 4.25 9.2617188 C 4.7438842 10.17694 4.7346154 11.262903 4.7578125 12.277344 C 5.2504494 12.270544 5.8011939 12.317174 6.2578125 12.277344 C 6.2669593 9.7577406 6.2393741 7.2373172 6.2714844 4.71875 C 6.3763823 4.198849 7.0022289 4.409587 7.3828125 4.3652344 L 8.0585938 4.3652344 L 8.546875 10.212891 L 9.2167969 4.3359375 L 9.2128906 4.3359375 C 9.2438386 3.9531035 9.0622615 3.4401006 9.4609375 3.2167969 L 10.599609 3.1757812 z "
|
||||
id="path5630" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
26
data/theme/pointer-primary-click-symbolic.svg
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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="20"
|
||||
height="20"
|
||||
id="svg2"
|
||||
version="1.1">
|
||||
<g
|
||||
id="layer1"
|
||||
style="display:inline">
|
||||
<g
|
||||
id="id1"
|
||||
transform="translate(-22.25,-0.75)">
|
||||
<path
|
||||
style="color:#000000;shape-padding:0;clip-rule:nonzero;display:block;overflow:visible;visibility:visible;opacity:1;solid-color:#000000;solid-opacity:1;fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 25.855469,0.45507812 c 0,6.69466128 0,13.38932288 0,20.08398388 1.414713,-1.380859 2.829427,-2.761719 4.24414,-4.142578 0.612408,1.215372 1.173049,2.460221 1.819709,3.656095 1.141947,1.476279 3.975266,0.389006 3.846009,-1.473608 -0.09413,-0.822519 -0.594755,-1.521423 -0.899969,-2.277599 -0.298869,-0.640171 -0.597739,-1.280342 -0.896608,-1.920513 1.75651,0 3.513021,0 5.269531,0 C 34.777344,9.738932 30.316406,5.0970051 25.855469,0.45507812 Z m 1.5,3.72656248 c 2.786458,2.8997395 5.572917,5.7994789 8.359375,8.6992184 -1.367188,0 -2.734375,0 -4.101563,0 0.885072,1.903196 1.781799,3.80152 2.659622,5.707744 0.0349,0.566084 -1.149057,0.988823 -1.282093,0.297971 -0.818567,-1.671162 -1.637133,-3.342323 -2.455699,-5.013485 -1.059896,1.034505 -2.119791,2.06901 -3.179687,3.103515 1.5e-5,-4.264988 3e-5,-8.5299756 4.5e-5,-12.7949634 z"
|
||||
id="path5565" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
26
data/theme/pointer-secondary-click-symbolic.svg
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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="20"
|
||||
height="20"
|
||||
id="svg2">
|
||||
<g
|
||||
id="layer1"
|
||||
style="display:inline;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke:#000000;stroke-opacity:1">
|
||||
<g
|
||||
transform="matrix(-1,0,0,1,42,-0.75)"
|
||||
id="g5847"
|
||||
style="stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke:#000000;stroke-opacity:1">
|
||||
<path
|
||||
style="color:#000000;shape-padding:0;clip-rule:nonzero;display:block;overflow:visible;visibility:visible;opacity:1;solid-color:#000000;solid-opacity:1;fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 25.855469,0.45507812 c 0,6.69466128 0,13.38932288 0,20.08398388 1.414713,-1.380859 2.829427,-2.761719 4.24414,-4.142578 0.612408,1.215372 1.173049,2.460221 1.819709,3.656095 1.141947,1.476279 3.975266,0.389006 3.846009,-1.473608 -0.09413,-0.822519 -0.594755,-1.521423 -0.899969,-2.277599 -0.298869,-0.640171 -0.597739,-1.280342 -0.896608,-1.920513 1.75651,0 3.513021,0 5.269531,0 C 34.777344,9.738932 30.316406,5.0970051 25.855469,0.45507812 Z m 1.5,3.72656248 c 2.786458,2.8997395 5.572917,5.7994789 8.359375,8.6992184 -1.367188,0 -2.734375,0 -4.101563,0 0.885072,1.903196 1.781799,3.80152 2.659622,5.707744 0.0349,0.566084 -1.149057,0.988823 -1.282093,0.297971 -0.818567,-1.671162 -1.637133,-3.342323 -2.455699,-5.013485 -1.059896,1.034505 -2.119791,2.06901 -3.179687,3.103515 1.5e-5,-4.264988 3e-5,-8.5299756 4.5e-5,-12.7949634 z"
|
||||
id="path5851" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
1
data/theme/toggle-off-dark.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="46" height="22"><defs><linearGradient id="a"><stop offset="0" stop-color="#39393a"/><stop offset="1" stop-color="#302f30"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="53" y1="294.429" x2="53" y2="309.804" gradientUnits="userSpaceOnUse" gradientTransform="translate(-42.76)"/></defs><g transform="translate(0 -291.18)" stroke-width="1.085"><rect style="marker:none" width="44.446" height="20.911" x=".625" y="291.715" rx="10.455" ry="10.073" fill="#323233" stroke="#272728"/><rect ry="10.455" rx="10.455" y="291.715" x=".543" height="20.911" width="21.143" style="marker:none" fill="url(#b)" stroke="#151515"/></g></svg>
|
||||
|
After Width: | Height: | Size: 725 B |
@@ -1,209 +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="65"
|
||||
height="22"
|
||||
id="svg2857"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
sodipodi:docname="toggle-off-us.svg">
|
||||
<defs
|
||||
id="defs2859">
|
||||
<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="perspective2865" />
|
||||
<inkscape:perspective
|
||||
id="perspective2843"
|
||||
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="#linearGradient76469-7-7-4"
|
||||
id="linearGradient38024"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
|
||||
x1="6"
|
||||
y1="102.95528"
|
||||
x2="6"
|
||||
y2="84.505203" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient76469-7-7-4">
|
||||
<stop
|
||||
style="stop-color:#2e3232;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop76471-7-1-5" />
|
||||
<stop
|
||||
style="stop-color:#3e4545;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop76473-9-0-0" />
|
||||
</linearGradient>
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect77541-4"
|
||||
is_visible="true" />
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect77541-4-0"
|
||||
is_visible="true" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient37802-8"
|
||||
id="linearGradient12311-3-1-0-5-4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)"
|
||||
x1="610.13782"
|
||||
y1="501.43866"
|
||||
x2="610.13782"
|
||||
y2="492.52756" />
|
||||
<linearGradient
|
||||
id="linearGradient37802-8"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop37804-1"
|
||||
offset="0"
|
||||
style="stop-color:#2c2c2c;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop37806-8"
|
||||
offset="1"
|
||||
style="stop-color:#16191a;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="492.52756"
|
||||
x2="610.13782"
|
||||
y1="501.43866"
|
||||
x1="610.13782"
|
||||
gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient13602"
|
||||
xlink:href="#linearGradient37802-8"
|
||||
inkscape:collect="always" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="-5.0602834"
|
||||
inkscape:cy="16.473273"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g37994"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1375"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:snap-bbox="true"
|
||||
showborder="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid12954"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata2862">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-444.64286,-781.36218)">
|
||||
<g
|
||||
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
|
||||
id="g37994">
|
||||
<g
|
||||
id="g37996"
|
||||
transform="translate(-115,1277)">
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;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;opacity:0.19591837"
|
||||
id="rect13475"
|
||||
width="98"
|
||||
height="25"
|
||||
x="644.5"
|
||||
y="484.61118"
|
||||
rx="4.7429576"
|
||||
ry="3.8424656" />
|
||||
<rect
|
||||
ry="3.8424656"
|
||||
rx="4.7429576"
|
||||
y="483.5"
|
||||
x="644.5"
|
||||
height="25"
|
||||
width="98"
|
||||
id="rect38000"
|
||||
style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;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:new" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-49.946213,-1.890275)"
|
||||
id="g38002">
|
||||
<g
|
||||
transform="translate(-115,1247)"
|
||||
style="display:inline"
|
||||
id="g38004">
|
||||
<rect
|
||||
ry="3.7972314"
|
||||
rx="4.6871223"
|
||||
y="515.5"
|
||||
x="694.53046"
|
||||
height="25"
|
||||
width="45.969578"
|
||||
id="rect38006"
|
||||
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;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" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;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"
|
||||
d="m 699.09675,516.7365 36.86904,0"
|
||||
id="path38016"
|
||||
inkscape:path-effect="#path-effect77541-4"
|
||||
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:2.15627193;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:new"
|
||||
id="path13479"
|
||||
sodipodi:cx="16.4375"
|
||||
sodipodi:cy="10.8125"
|
||||
sodipodi:rx="4.3125"
|
||||
sodipodi:ry="4.3125"
|
||||
d="m 20.75,10.8125 a 4.3125,4.3125 0 1 1 -8.625,0 4.3125,4.3125 0 1 1 8.625,0 z"
|
||||
transform="matrix(1.4212691,0,0,1.1514287,577.38488,1761.1138)" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.5 KiB |
@@ -1,255 +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="65"
|
||||
height="22"
|
||||
id="svg2857"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
sodipodi:docname="toggle-on-intl.svg">
|
||||
<defs
|
||||
id="defs2859">
|
||||
<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="perspective2865" />
|
||||
<inkscape:perspective
|
||||
id="perspective2843"
|
||||
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="#linearGradient76469-7-7-4"
|
||||
id="linearGradient38024"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
|
||||
x1="6"
|
||||
y1="102.95528"
|
||||
x2="6"
|
||||
y2="84.505203" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient76469-7-7-4">
|
||||
<stop
|
||||
style="stop-color:#2e3232;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop76471-7-1-5" />
|
||||
<stop
|
||||
style="stop-color:#3e4545;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop76473-9-0-0" />
|
||||
</linearGradient>
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect77541-4"
|
||||
is_visible="true" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient37802"
|
||||
id="linearGradient12311-3-1-0-5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)"
|
||||
x1="610.13782"
|
||||
y1="501.43866"
|
||||
x2="610.13782"
|
||||
y2="492.52756" />
|
||||
<linearGradient
|
||||
id="linearGradient37802"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop37804"
|
||||
offset="0"
|
||||
style="stop-color:#2c2c2c;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop37806"
|
||||
offset="1"
|
||||
style="stop-color:#16191a;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient76469-7-7-4-3"
|
||||
id="linearGradient77680"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.0322581,717.71949,428.68472)"
|
||||
x1="6"
|
||||
y1="102.95528"
|
||||
x2="6"
|
||||
y2="84.505203" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient76469-7-7-4-3">
|
||||
<stop
|
||||
style="stop-color:#2e3232;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop76471-7-1-5-7" />
|
||||
<stop
|
||||
style="stop-color:#3e4545;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop76473-9-0-0-9" />
|
||||
</linearGradient>
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect77541-4-0"
|
||||
is_visible="true" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient37802-8"
|
||||
id="linearGradient12311-3-1-0-5-4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5918367,0,0,0.85714285,-256.56122,59.071426)"
|
||||
x1="610.13782"
|
||||
y1="501.43866"
|
||||
x2="610.13782"
|
||||
y2="492.52756" />
|
||||
<linearGradient
|
||||
id="linearGradient37802-8"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop37804-1"
|
||||
offset="0"
|
||||
style="stop-color:#2c2c2c;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop37806-8"
|
||||
offset="1"
|
||||
style="stop-color:#16191a;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="492.52756"
|
||||
x2="610.13782"
|
||||
y1="501.43866"
|
||||
x1="610.13782"
|
||||
gradientTransform="matrix(1.5918367,0,0,0.85714285,-900.56122,-423.92857)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient13602"
|
||||
xlink:href="#linearGradient37802-8"
|
||||
inkscape:collect="always" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="16.760995"
|
||||
inkscape:cy="21.955673"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g37994"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1375"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:snap-bbox="true"
|
||||
showborder="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid12954"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata2862">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-444.64286,-781.36218)">
|
||||
<g
|
||||
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
|
||||
id="g37994">
|
||||
<g
|
||||
id="g37996"
|
||||
transform="translate(-115,1277)">
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;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;opacity:0.19591837"
|
||||
id="rect13475"
|
||||
width="98"
|
||||
height="25"
|
||||
x="644.5"
|
||||
y="484.61118"
|
||||
rx="4.7429576"
|
||||
ry="3.8424656" />
|
||||
<rect
|
||||
ry="3.8424656"
|
||||
rx="4.7429576"
|
||||
y="483.5"
|
||||
x="644.5"
|
||||
height="25"
|
||||
width="98"
|
||||
id="rect38000"
|
||||
style="color:#000000;fill:url(#linearGradient12311-3-1-0-5-4);fill-opacity:1;fill-rule:nonzero;stroke:#16191a;stroke-width:1.37920942;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:new" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-49.946213,-1.890275)"
|
||||
id="g38002">
|
||||
<g
|
||||
transform="translate(-115,1247)"
|
||||
style="display:inline"
|
||||
id="g38004">
|
||||
<rect
|
||||
ry="3.7972314"
|
||||
rx="4.6871223"
|
||||
y="515.5"
|
||||
x="694.53046"
|
||||
height="25"
|
||||
width="45.969578"
|
||||
id="rect38006"
|
||||
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;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" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;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"
|
||||
d="m 699.09675,516.7365 36.86904,0"
|
||||
id="path38016"
|
||||
inkscape:path-effect="#path-effect77541-4"
|
||||
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:13.79166794px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
|
||||
x="520.29974"
|
||||
y="1997.0011"
|
||||
id="text75614"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="scale(1.1236771,0.88993537)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan75616"
|
||||
x="520.29974"
|
||||
y="1997.0011">OFF</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.8 KiB |
1
data/theme/toggle-off.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="22"><g transform="translate(0 -291.18)"><rect style="marker:none;font-variant-east_asian:normal" width="44.446" height="20.911" x=".625" y="291.715" rx="10.455" ry="10.073" fill="#e1dedb" stroke="#cdc7c2" stroke-linecap="round" stroke-linejoin="round"/><rect ry="10.455" rx="10.455" y="291.715" x=".543" height="20.911" width="21.143" style="marker:none;font-variant-east_asian:normal" fill="#f8f7f7" stroke="#aa9f98" stroke-linecap="round" stroke-linejoin="round"/><g transform="matrix(.97148 0 0 1 1658.914 -2552.91)" stroke-width="1.015" stroke-linecap="round" stroke-linejoin="round"><rect ry="13.17" rx="13.556" y="1234.681" x="-1242.732" height="26" width="49.409" style="marker:none" fill="#e1dedb" stroke="#cdc7c2"/><rect style="marker:none" width="26.763" height="26" x="-1242.732" y="1234.769" rx="13.511" ry="13.126" fill="#f8f7f7" stroke="#aa9f98"/></g><g transform="matrix(.97148 0 0 1 1658.914 -2512.91)" stroke-width="1.015" stroke="#2b73cc"><rect style="marker:none" width="49.409" height="26" x="-1242.732" y="1234.681" rx="13.556" ry="13.17" fill="#3081e3"/><rect ry="13.126" rx="13.511" y="1234.769" x="-1220.086" height="26" width="26.763" style="marker:none" fill="#f8f7f7" stroke-linecap="round" stroke-linejoin="round"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
data/theme/toggle-on-dark.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="46" height="22"><defs><linearGradient id="a"><stop offset="0" stop-color="#39393a"/><stop offset="1" stop-color="#302f30"/></linearGradient><linearGradient xlink:href="#a" id="b" x1="53" y1="294.429" x2="53" y2="309.804" gradientUnits="userSpaceOnUse" gradientTransform="translate(-19)"/></defs><g transform="translate(0 -291.18)" stroke="#030e1b" stroke-width="1.085"><rect style="marker:none" width="44.446" height="20.911" x=".625" y="291.715" rx="10.455" ry="10.073" fill="#15539e"/><rect ry="10.455" rx="10.455" y="291.715" x="24.304" height="20.911" width="21.143" style="marker:none" fill="url(#b)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 707 B |
@@ -1,192 +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="65"
|
||||
height="22"
|
||||
id="svg2857"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="toggle-on-intl.svg">
|
||||
<defs
|
||||
id="defs2859">
|
||||
<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="perspective2865" />
|
||||
<inkscape:perspective
|
||||
id="perspective2843"
|
||||
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="#linearGradient77461"
|
||||
id="linearGradient77551"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.3066667,0,0,1,-841.64667,-483)"
|
||||
x1="1164.7644"
|
||||
y1="962.93695"
|
||||
x2="1164.7644"
|
||||
y2="970.51404" />
|
||||
<linearGradient
|
||||
id="linearGradient77461"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop77463"
|
||||
offset="0"
|
||||
style="stop-color:#182f4c;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop77465"
|
||||
offset="1"
|
||||
style="stop-color:#205b9a;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient76469-7-7-4"
|
||||
id="linearGradient38024"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
|
||||
x1="6"
|
||||
y1="102.95528"
|
||||
x2="6"
|
||||
y2="84.505203" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient76469-7-7-4">
|
||||
<stop
|
||||
style="stop-color:#2e3232;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop76471-7-1-5" />
|
||||
<stop
|
||||
style="stop-color:#3e4545;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop76473-9-0-0" />
|
||||
</linearGradient>
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect77541-4"
|
||||
is_visible="true" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="37.410841"
|
||||
inkscape:cy="16.009314"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g37994"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1376"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:snap-bbox="true"
|
||||
showborder="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid12954"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata2862">
|
||||
<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(-444.64286,-781.36218)">
|
||||
<g
|
||||
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
|
||||
id="g37994">
|
||||
<g
|
||||
id="g37996"
|
||||
transform="translate(-115,1277)">
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;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;opacity:0.19591837"
|
||||
id="rect13475"
|
||||
width="98"
|
||||
height="25"
|
||||
x="644.5"
|
||||
y="484.61118"
|
||||
rx="4.7429576"
|
||||
ry="3.8424656" />
|
||||
<rect
|
||||
ry="3.8424656"
|
||||
rx="4.7429576"
|
||||
y="483.5"
|
||||
x="644.5"
|
||||
height="25"
|
||||
width="98"
|
||||
id="rect38000"
|
||||
style="color:#000000;fill:url(#linearGradient77551);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;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" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(2.0625,-2)"
|
||||
id="g38002">
|
||||
<g
|
||||
transform="translate(-115,1247)"
|
||||
style="display:inline"
|
||||
id="g38004">
|
||||
<rect
|
||||
ry="3.7972314"
|
||||
rx="4.6871223"
|
||||
y="515.5"
|
||||
x="694.53046"
|
||||
height="25"
|
||||
width="45.969578"
|
||||
id="rect38006"
|
||||
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;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" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;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"
|
||||
d="m 699.09675,516.7365 36.86904,0"
|
||||
id="path38016"
|
||||
inkscape:path-effect="#path-effect77541-4"
|
||||
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
|
||||
id="rect13678"
|
||||
width="3.0646207"
|
||||
height="12.414008"
|
||||
x="554.77728"
|
||||
y="1767.3566" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.8 KiB |
@@ -1,207 +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="65"
|
||||
height="22"
|
||||
id="svg2857"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="toggle-on-us.svg">
|
||||
<defs
|
||||
id="defs2859">
|
||||
<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="perspective2865" />
|
||||
<inkscape:perspective
|
||||
id="perspective2843"
|
||||
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="#linearGradient76469-7-7-4"
|
||||
id="linearGradient38024"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0215462,0,0,1.0322581,717.22867,428.68472)"
|
||||
x1="6"
|
||||
y1="102.95528"
|
||||
x2="6"
|
||||
y2="84.505203" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient76469-7-7-4">
|
||||
<stop
|
||||
style="stop-color:#2e3232;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop76471-7-1-5" />
|
||||
<stop
|
||||
style="stop-color:#3e4545;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop76473-9-0-0" />
|
||||
</linearGradient>
|
||||
<inkscape:path-effect
|
||||
effect="spiro"
|
||||
id="path-effect77541-4"
|
||||
is_visible="true" />
|
||||
<linearGradient
|
||||
id="linearGradient77461-1"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop77463-1"
|
||||
offset="0"
|
||||
style="stop-color:#182f4c;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop77465-4"
|
||||
offset="1"
|
||||
style="stop-color:#205b9a;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient77461-1"
|
||||
id="linearGradient77551-6-5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.8527367,0,0,0.80554422,-969.41608,-778.00299)"
|
||||
x1="1164.7644"
|
||||
y1="962.93695"
|
||||
x2="1164.7644"
|
||||
y2="970.51404" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient77461-1"
|
||||
id="linearGradient11198"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.3066667,0,0,1,-1066.3709,794.25325)"
|
||||
x1="1322.5831"
|
||||
y1="-312.51855"
|
||||
x2="1322.5831"
|
||||
y2="-306.53461" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="-26.798898"
|
||||
inkscape:cy="5.3753009"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g37994"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1376"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:snap-bbox="true"
|
||||
showborder="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid12954"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata2862">
|
||||
<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(-444.64286,-781.36218)">
|
||||
<g
|
||||
transform="matrix(0.6526046,0,0,0.80554422,99.592644,-636.32172)"
|
||||
id="g37994">
|
||||
<g
|
||||
id="g37996"
|
||||
transform="translate(-115,1277)">
|
||||
<rect
|
||||
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964000000001;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;opacity:0.19591837"
|
||||
id="rect13475"
|
||||
width="98"
|
||||
height="25"
|
||||
x="644.5"
|
||||
y="484.61118"
|
||||
rx="4.7429576"
|
||||
ry="3.8424656" />
|
||||
<rect
|
||||
ry="3.8424656"
|
||||
rx="4.7429576"
|
||||
y="483.5"
|
||||
x="644.5"
|
||||
height="25"
|
||||
width="98"
|
||||
id="rect38000"
|
||||
style="color:#000000;fill:url(#linearGradient11198);fill-opacity:1;fill-rule:nonzero;stroke:#182f4c;stroke-width:1.37920964;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;clip-rule:nonzero;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;filter-blend-mode:normal;filter-gaussianBlur-deviation:0;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(2.0625,-2)"
|
||||
id="g38002">
|
||||
<g
|
||||
transform="translate(-115,1247)"
|
||||
style="display:inline"
|
||||
id="g38004">
|
||||
<rect
|
||||
ry="3.7972314"
|
||||
rx="4.6871223"
|
||||
y="515.5"
|
||||
x="694.53046"
|
||||
height="25"
|
||||
width="45.969578"
|
||||
id="rect38006"
|
||||
style="color:#000000;fill:url(#linearGradient38024);fill-opacity:1;fill-rule:nonzero;stroke:#1f2020;stroke-width:1.37920964;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" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="opacity:0.1;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.37920964px;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"
|
||||
d="m 699.09675,516.7365 36.86904,0"
|
||||
id="path38016"
|
||||
inkscape:path-effect="#path-effect77541-4"
|
||||
inkscape:original-d="m 699.09675,516.7365 36.86904,0"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
transform="scale(1.1000946,0.90901274)"
|
||||
sodipodi:linespacing="125%"
|
||||
id="text38018"
|
||||
y="1955.5205"
|
||||
x="495.94223"
|
||||
style="font-size:13.29953671px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Cantarell;-inkscape-font-specification:Cantarell Bold"
|
||||
xml:space="preserve"><tspan
|
||||
y="1955.5205"
|
||||
x="495.94223"
|
||||
id="tspan38020"
|
||||
sodipodi:role="line">ON</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.7 KiB |
1
data/theme/toggle-on.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="46" height="22"><g transform="translate(0 -291.18)" stroke="#2b73cc"><rect style="marker:none;font-variant-east_asian:normal" width="44.446" height="20.911" x=".625" y="291.715" rx="10.455" ry="10.073" fill="#3081e3"/><rect ry="10.455" rx="10.455" y="291.715" x="24.304" height="20.911" width="21.143" style="marker:none;font-variant-east_asian:normal" fill="#f8f7f7" stroke-linecap="round" stroke-linejoin="round"/></g></svg>
|
||||
|
After Width: | Height: | Size: 473 B |
@@ -40,6 +40,7 @@ do
|
||||
done
|
||||
|
||||
cat >>$TMP_GRESOURCE_FILE <<EOF
|
||||
<file>emoji.json</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
EOF
|
||||
|
||||
@@ -28,7 +28,7 @@ foreach iface : ifaces
|
||||
output: 'doc-gen-' + iface[1],
|
||||
command: [
|
||||
'gdbus-codegen',
|
||||
'--interface-prefix=@0@.'.format(iface),
|
||||
'--interface-prefix=@0@.'.format(iface[0]),
|
||||
'--generate-docbook', 'doc-gen',
|
||||
'--output-directory', '@OUTDIR@',
|
||||
'@INPUT@'
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/* exported main */
|
||||
imports.gi.versions.Gdk = '3.0';
|
||||
imports.gi.versions.Gtk = '3.0';
|
||||
|
||||
const Lang = imports.lang;
|
||||
const Gettext = imports.gettext;
|
||||
const GLib = imports.gi.GLib;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Gdk = imports.gi.Gdk;
|
||||
const Pango = imports.gi.Pango;
|
||||
const { Gdk, GLib, Gio, GObject, Gtk, Pango } = imports.gi;
|
||||
const Format = imports.format;
|
||||
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
const { loadInterfaceXML, deleteGFile } = imports.misc.fileUtils;
|
||||
|
||||
const { ExtensionState } = ExtensionUtils;
|
||||
|
||||
const GnomeShellIface = loadInterfaceXML('org.gnome.Shell.Extensions');
|
||||
const GnomeShellProxy = Gio.DBusProxy.makeProxyWrapper(GnomeShellIface);
|
||||
@@ -24,75 +23,54 @@ function stripPrefix(string, prefix) {
|
||||
return string;
|
||||
}
|
||||
|
||||
var Application = new Lang.Class({
|
||||
Name: 'Application',
|
||||
var Application = GObject.registerClass({
|
||||
GTypeName: 'ExtensionPrefs_Application'
|
||||
}, class Application extends Gtk.Application {
|
||||
_init() {
|
||||
GLib.set_prgname('gnome-shell-extension-prefs');
|
||||
this.application = new Gtk.Application({
|
||||
super._init({
|
||||
application_id: 'org.gnome.shell.ExtensionPrefs',
|
||||
flags: Gio.ApplicationFlags.HANDLES_COMMAND_LINE
|
||||
});
|
||||
|
||||
this.application.connect('activate', this._onActivate.bind(this));
|
||||
this.application.connect('command-line', this._onCommandLine.bind(this));
|
||||
this.application.connect('startup', this._onStartup.bind(this));
|
||||
|
||||
this._extensionPrefsModules = {};
|
||||
|
||||
this._startupUuid = null;
|
||||
this._loaded = false;
|
||||
this._skipMainWindow = false;
|
||||
},
|
||||
this._shellProxy = null;
|
||||
}
|
||||
|
||||
_extensionAvailable(uuid) {
|
||||
let extension = ExtensionUtils.extensions[uuid];
|
||||
get shellProxy() {
|
||||
return this._shellProxy;
|
||||
}
|
||||
|
||||
if (!extension)
|
||||
_showPrefs(uuid) {
|
||||
let row = this._extensionSelector.get_children().find(c => {
|
||||
return c.uuid === uuid && c.hasPrefs;
|
||||
});
|
||||
|
||||
if (!row)
|
||||
return false;
|
||||
|
||||
if (!extension.dir.get_child('prefs.js').query_exists(null))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_getExtensionPrefsModule(extension) {
|
||||
let uuid = extension.metadata.uuid;
|
||||
|
||||
if (this._extensionPrefsModules.hasOwnProperty(uuid))
|
||||
return this._extensionPrefsModules[uuid];
|
||||
|
||||
ExtensionUtils.installImporter(extension);
|
||||
|
||||
let prefsModule = extension.imports.prefs;
|
||||
prefsModule.init(extension.metadata);
|
||||
|
||||
this._extensionPrefsModules[uuid] = prefsModule;
|
||||
return prefsModule;
|
||||
},
|
||||
|
||||
_selectExtension(uuid) {
|
||||
if (!this._extensionAvailable(uuid))
|
||||
return;
|
||||
|
||||
let extension = ExtensionUtils.extensions[uuid];
|
||||
let widget;
|
||||
|
||||
try {
|
||||
let prefsModule = this._getExtensionPrefsModule(extension);
|
||||
widget = prefsModule.buildPrefsWidget();
|
||||
widget = row.prefsModule.buildPrefsWidget();
|
||||
} catch (e) {
|
||||
widget = this._buildErrorUI(extension, e);
|
||||
widget = this._buildErrorUI(row, e);
|
||||
}
|
||||
|
||||
let dialog = new Gtk.Window({ modal: !this._skipMainWindow,
|
||||
type_hint: Gdk.WindowTypeHint.DIALOG });
|
||||
dialog.set_titlebar(new Gtk.HeaderBar({ show_close_button: true,
|
||||
title: extension.metadata.name,
|
||||
visible: true }));
|
||||
let dialog = new Gtk.Window({
|
||||
modal: !this._skipMainWindow,
|
||||
type_hint: Gdk.WindowTypeHint.DIALOG
|
||||
});
|
||||
dialog.set_titlebar(new Gtk.HeaderBar({
|
||||
show_close_button: true,
|
||||
title: row.name,
|
||||
visible: true
|
||||
}));
|
||||
|
||||
if (this._skipMainWindow) {
|
||||
this.application.add_window(dialog);
|
||||
this.add_window(dialog);
|
||||
if (this._window)
|
||||
this._window.destroy();
|
||||
this._window = dialog;
|
||||
@@ -104,36 +82,127 @@ var Application = new Lang.Class({
|
||||
dialog.set_default_size(600, 400);
|
||||
dialog.add(widget);
|
||||
dialog.show();
|
||||
},
|
||||
|
||||
_buildErrorUI(extension, exc) {
|
||||
let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
|
||||
return true;
|
||||
}
|
||||
|
||||
_buildErrorUI(row, exc) {
|
||||
let scroll = new Gtk.ScrolledWindow({
|
||||
hscrollbar_policy: Gtk.PolicyType.NEVER,
|
||||
propagate_natural_height: true
|
||||
});
|
||||
|
||||
let box = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 12,
|
||||
margin: 100,
|
||||
margin_bottom: 60
|
||||
});
|
||||
scroll.add(box);
|
||||
|
||||
let label = new Gtk.Label({
|
||||
label: _("There was an error loading the preferences dialog for %s:").format(extension.metadata.name)
|
||||
label: '<span size="x-large">%s</span>'.format(_("Something’s gone wrong")),
|
||||
use_markup: true
|
||||
});
|
||||
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
|
||||
box.add(label);
|
||||
|
||||
label = new Gtk.Label({
|
||||
label: _("We’re very sorry, but there’s been a problem: the settings for this extension can’t be displayed. We recommend that you report the issue to the extension authors."),
|
||||
justify: Gtk.Justification.CENTER,
|
||||
wrap: true
|
||||
});
|
||||
box.add(label);
|
||||
|
||||
let errortext = '';
|
||||
errortext += exc;
|
||||
errortext += '\n\n';
|
||||
errortext += 'Stack trace:\n';
|
||||
let expander = new Expander({
|
||||
label: _("Technical Details"),
|
||||
margin_top: 12
|
||||
});
|
||||
box.add(expander);
|
||||
|
||||
// Indent stack trace.
|
||||
errortext += exc.stack.split('\n').map(line => ' ' + line).join('\n');
|
||||
let errortext = `${exc}\n\nStack trace:\n${
|
||||
// Indent stack trace.
|
||||
exc.stack.split('\n').map(line => ` ${line}`).join('\n')
|
||||
}`;
|
||||
|
||||
let scroll = new Gtk.ScrolledWindow({ vexpand: true });
|
||||
let buffer = new Gtk.TextBuffer({ text: errortext });
|
||||
let textview = new Gtk.TextView({ buffer: buffer });
|
||||
textview.override_font(Pango.font_description_from_string('monospace'));
|
||||
scroll.add(textview);
|
||||
box.add(scroll);
|
||||
let textview = new Gtk.TextView({
|
||||
buffer: buffer,
|
||||
wrap_mode: Gtk.WrapMode.WORD,
|
||||
monospace: true,
|
||||
editable: false,
|
||||
top_margin: 12,
|
||||
bottom_margin: 12,
|
||||
left_margin: 12,
|
||||
right_margin: 12
|
||||
});
|
||||
|
||||
box.show_all();
|
||||
return box;
|
||||
},
|
||||
let toolbar = new Gtk.Toolbar();
|
||||
let provider = new Gtk.CssProvider();
|
||||
provider.load_from_data(`* {
|
||||
border: 0 solid @borders;
|
||||
border-top-width: 1px;
|
||||
}`);
|
||||
toolbar.get_style_context().add_provider(
|
||||
provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
|
||||
);
|
||||
|
||||
_buildUI(app) {
|
||||
this._window = new Gtk.ApplicationWindow({ application: app,
|
||||
let copyButton = new Gtk.ToolButton({
|
||||
icon_name: 'edit-copy-symbolic',
|
||||
tooltip_text: _("Copy Error")
|
||||
});
|
||||
toolbar.add(copyButton);
|
||||
|
||||
copyButton.connect('clicked', w => {
|
||||
let clipboard = Gtk.Clipboard.get_default(w.get_display());
|
||||
// markdown for pasting in gitlab issues
|
||||
let lines = [
|
||||
`The settings of extension ${row.uuid} had an error:`,
|
||||
'```',
|
||||
`${exc}`,
|
||||
'```',
|
||||
'',
|
||||
'Stack trace:',
|
||||
'```',
|
||||
exc.stack.replace(/\n$/, ''), // stack without trailing newline
|
||||
'```',
|
||||
''
|
||||
];
|
||||
clipboard.set_text(lines.join('\n'), -1);
|
||||
});
|
||||
|
||||
let spacing = new Gtk.SeparatorToolItem({ draw: false });
|
||||
toolbar.add(spacing);
|
||||
toolbar.child_set_property(spacing, "expand", true);
|
||||
|
||||
let urlButton = new Gtk.ToolButton({
|
||||
label: _("Homepage"),
|
||||
tooltip_text: _("Visit extension homepage"),
|
||||
no_show_all: true,
|
||||
visible: row.url != null
|
||||
});
|
||||
toolbar.add(urlButton);
|
||||
|
||||
urlButton.connect('clicked', w => {
|
||||
let context = w.get_display().get_app_launch_context();
|
||||
Gio.AppInfo.launch_default_for_uri(row.url, context);
|
||||
});
|
||||
|
||||
let expandedBox = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL
|
||||
});
|
||||
expandedBox.add(textview);
|
||||
expandedBox.add(toolbar);
|
||||
|
||||
expander.add(expandedBox);
|
||||
|
||||
scroll.show_all();
|
||||
return scroll;
|
||||
}
|
||||
|
||||
_buildUI() {
|
||||
this._window = new Gtk.ApplicationWindow({ application: this,
|
||||
window_position: Gtk.WindowPosition.CENTER });
|
||||
|
||||
this._window.set_default_size(800, 500);
|
||||
@@ -150,8 +219,35 @@ var Application = new Lang.Class({
|
||||
Gio.SettingsBindFlags.DEFAULT |
|
||||
Gio.SettingsBindFlags.INVERT_BOOLEAN);
|
||||
|
||||
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
|
||||
this._window.add(vbox);
|
||||
|
||||
this.disabledInfobar = new Gtk.InfoBar({
|
||||
message_type: Gtk.MessageType.ERROR,
|
||||
revealed: false,
|
||||
show_close_button: true
|
||||
});
|
||||
this.disabledInfobar.connect('response', () => {
|
||||
this.disabledInfobar.revealed = false;
|
||||
});
|
||||
let contentArea = this.disabledInfobar.get_content_area();
|
||||
let label = new Gtk.Label({
|
||||
label: _('A problem was detected and extensions were automatically disabled. It is recommended to disable or reconfigure any extensions that may have caused the issue before re-enabling them at the top.'),
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
wrap: true,
|
||||
lines: 2,
|
||||
xalign: 0,
|
||||
margin: 6
|
||||
});
|
||||
contentArea.add(label);
|
||||
vbox.add(this.disabledInfobar);
|
||||
|
||||
this._mainStack = new Gtk.Stack({
|
||||
transition_type: Gtk.StackTransitionType.CROSSFADE
|
||||
});
|
||||
vbox.add(this._mainStack);
|
||||
|
||||
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
|
||||
this._window.add(scroll);
|
||||
|
||||
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
|
||||
this._extensionSelector.set_sort_func(this._sortList.bind(this));
|
||||
@@ -159,21 +255,19 @@ var Application = new Lang.Class({
|
||||
|
||||
scroll.add(this._extensionSelector);
|
||||
|
||||
this._mainStack.add_named(scroll, 'listing');
|
||||
this._mainStack.add_named(new EmptyPlaceholder(), 'placeholder');
|
||||
|
||||
this._shellProxy = new GnomeShellProxy(Gio.DBus.session, 'org.gnome.Shell', '/org/gnome/Shell');
|
||||
this._shellProxy.connectSignal('ExtensionStatusChanged', (proxy, senderName, [uuid, state, error]) => {
|
||||
if (ExtensionUtils.extensions[uuid] !== undefined)
|
||||
this._scanExtensions();
|
||||
});
|
||||
this._shellProxy.connectSignal('ExtensionStateChanged',
|
||||
this._onExtensionStateChanged.bind(this));
|
||||
|
||||
this._window.show_all();
|
||||
},
|
||||
}
|
||||
|
||||
_sortList(row1, row2) {
|
||||
let name1 = ExtensionUtils.extensions[row1.uuid].metadata.name;
|
||||
let name2 = ExtensionUtils.extensions[row2.uuid].metadata.name;
|
||||
return name1.localeCompare(name2);
|
||||
},
|
||||
return row1.name.localeCompare(row2.name);
|
||||
}
|
||||
|
||||
_updateHeader(row, before) {
|
||||
if (!before || row.get_header())
|
||||
@@ -181,49 +275,106 @@ var Application = new Lang.Class({
|
||||
|
||||
let sep = new Gtk.Separator({ orientation: Gtk.Orientation.HORIZONTAL });
|
||||
row.set_header(sep);
|
||||
},
|
||||
}
|
||||
|
||||
_findExtensionRow(uuid) {
|
||||
return this._extensionSelector.get_children().find(c => c.uuid === uuid);
|
||||
}
|
||||
|
||||
_onExtensionStateChanged(proxy, senderName, [uuid, newState]) {
|
||||
let row = this._findExtensionRow(uuid);
|
||||
if (row) {
|
||||
let { state } = ExtensionUtils.deserializeExtension(newState);
|
||||
if (state == ExtensionState.UNINSTALLED)
|
||||
row.destroy();
|
||||
return; // we only deal with new and deleted extensions here
|
||||
}
|
||||
|
||||
this._shellProxy.GetExtensionInfoRemote(uuid, ([serialized]) => {
|
||||
let extension = ExtensionUtils.deserializeExtension(serialized);
|
||||
if (!extension)
|
||||
return;
|
||||
// check the extension wasn't added in between
|
||||
if (this._findExtensionRow(uuid) != null)
|
||||
return;
|
||||
this._addExtensionRow(extension);
|
||||
});
|
||||
}
|
||||
|
||||
_scanExtensions() {
|
||||
let finder = new ExtensionUtils.ExtensionFinder();
|
||||
finder.connect('extension-found', this._extensionFound.bind(this));
|
||||
finder.scanExtensions();
|
||||
this._extensionsLoaded();
|
||||
},
|
||||
this._shellProxy.ListExtensionsRemote(([extensionsMap], e) => {
|
||||
if (e) {
|
||||
if (e instanceof Gio.DBusError) {
|
||||
log(`Failed to connect to shell proxy: ${e}`);
|
||||
this._mainStack.add_named(new NoShellPlaceholder(), 'noshell');
|
||||
this._mainStack.visible_child_name = 'noshell';
|
||||
} else
|
||||
throw e;
|
||||
return;
|
||||
}
|
||||
|
||||
_extensionFound(finder, extension) {
|
||||
let row = new ExtensionRow(extension.uuid);
|
||||
for (let uuid in extensionsMap) {
|
||||
let extension = ExtensionUtils.deserializeExtension(extensionsMap[uuid]);
|
||||
this._addExtensionRow(extension);
|
||||
}
|
||||
this._extensionsLoaded();
|
||||
});
|
||||
}
|
||||
|
||||
_addExtensionRow(extension) {
|
||||
let row = new ExtensionRow(extension);
|
||||
|
||||
row.prefsButton.visible = this._extensionAvailable(row.uuid);
|
||||
row.prefsButton.connect('clicked', () => {
|
||||
this._selectExtension(row.uuid);
|
||||
this._showPrefs(row.uuid);
|
||||
});
|
||||
|
||||
row.show_all();
|
||||
this._extensionSelector.add(row);
|
||||
},
|
||||
}
|
||||
|
||||
_extensionsLoaded() {
|
||||
if (this._startupUuid && this._extensionAvailable(this._startupUuid))
|
||||
this._selectExtension(this._startupUuid);
|
||||
if (this._extensionSelector.get_children().length > 0)
|
||||
this._mainStack.visible_child_name = 'listing';
|
||||
else
|
||||
this._mainStack.visible_child_name = 'placeholder';
|
||||
|
||||
if (this._startupUuid)
|
||||
this._showPrefs(this._startupUuid);
|
||||
this._startupUuid = null;
|
||||
this._skipMainWindow = false;
|
||||
this._loaded = true;
|
||||
},
|
||||
}
|
||||
|
||||
_onActivate() {
|
||||
vfunc_activate() {
|
||||
this._window.present();
|
||||
},
|
||||
}
|
||||
|
||||
_onStartup(app) {
|
||||
this._buildUI(app);
|
||||
vfunc_startup() {
|
||||
super.vfunc_startup();
|
||||
|
||||
this._buildUI();
|
||||
this._scanExtensions();
|
||||
},
|
||||
}
|
||||
|
||||
_onCommandLine(app, commandLine) {
|
||||
app.activate();
|
||||
vfunc_command_line(commandLine) {
|
||||
this.activate();
|
||||
let args = commandLine.get_arguments();
|
||||
|
||||
if (args.length) {
|
||||
if (args[0] == '--disabled-warning') {
|
||||
if (!this._settings.is_writable('disable-user-extensions'))
|
||||
this.quit();
|
||||
|
||||
this.disabledInfobar.set_revealed(true);
|
||||
|
||||
let file = GLib.build_filenamev ([GLib.get_user_config_dir(), 'gnome-shell-extensions-disabled-warning']);
|
||||
let gfile = Gio.File.new_for_path(file);
|
||||
if (gfile.query_exists(null))
|
||||
deleteGFile(gfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
let uuid = args[0];
|
||||
|
||||
this._skipMainWindow = true;
|
||||
@@ -231,57 +382,273 @@ var Application = new Lang.Class({
|
||||
// Strip off "extension:///" prefix which fakes a URI, if it exists
|
||||
uuid = stripPrefix(uuid, "extension:///");
|
||||
|
||||
if (this._extensionAvailable(uuid))
|
||||
this._selectExtension(uuid);
|
||||
else if (!this._loaded)
|
||||
if (!this._loaded)
|
||||
this._startupUuid = uuid;
|
||||
else
|
||||
else if (!this._showPrefs(uuid))
|
||||
this._skipMainWindow = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
var DescriptionLabel = new Lang.Class({
|
||||
Name: 'DescriptionLabel',
|
||||
Extends: Gtk.Label,
|
||||
var Expander = GObject.registerClass({
|
||||
Properties: {
|
||||
'label': GObject.ParamSpec.string(
|
||||
'label', 'label', 'label',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
null
|
||||
)
|
||||
}
|
||||
}, class Expander extends Gtk.Box {
|
||||
_init(params = {}) {
|
||||
this._labelText = null;
|
||||
|
||||
vfunc_get_preferred_height_for_width(width) {
|
||||
// Hack: Request the maximum height allowed by the line limit
|
||||
if (this.lines > 0)
|
||||
return this.parent(0);
|
||||
return this.parent(width);
|
||||
super._init(Object.assign(params, {
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 0
|
||||
}));
|
||||
|
||||
this._frame = new Gtk.Frame({
|
||||
shadow_type: Gtk.ShadowType.IN,
|
||||
hexpand: true
|
||||
});
|
||||
|
||||
let eventBox = new Gtk.EventBox();
|
||||
this._frame.add(eventBox);
|
||||
|
||||
let hbox = new Gtk.Box({
|
||||
spacing: 6,
|
||||
margin: 12
|
||||
});
|
||||
eventBox.add(hbox);
|
||||
|
||||
this._arrow = new Gtk.Image({
|
||||
icon_name: 'pan-end-symbolic'
|
||||
});
|
||||
hbox.add(this._arrow);
|
||||
|
||||
this._label = new Gtk.Label({ label: this._labelText });
|
||||
hbox.add(this._label);
|
||||
|
||||
this._revealer = new Gtk.Revealer();
|
||||
|
||||
this._childBin = new Gtk.Frame({
|
||||
shadow_type: Gtk.ShadowType.IN
|
||||
});
|
||||
this._revealer.add(this._childBin);
|
||||
|
||||
// Directly chain up to parent for internal children
|
||||
super.add(this._frame);
|
||||
super.add(this._revealer);
|
||||
|
||||
let provider = new Gtk.CssProvider();
|
||||
provider.load_from_data('* { border-top-width: 0; }');
|
||||
this._childBin.get_style_context().add_provider(
|
||||
provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
|
||||
);
|
||||
|
||||
this._gesture = new Gtk.GestureMultiPress({
|
||||
widget: this._frame,
|
||||
button: 0,
|
||||
exclusive: true
|
||||
});
|
||||
this._gesture.connect('released', (gesture, nPress) => {
|
||||
if (nPress == 1)
|
||||
this._revealer.reveal_child = !this._revealer.reveal_child;
|
||||
});
|
||||
this._revealer.connect('notify::reveal-child', () => {
|
||||
if (this._revealer.reveal_child)
|
||||
this._arrow.icon_name = 'pan-down-symbolic';
|
||||
else
|
||||
this._arrow.icon_name = 'pan-end-symbolic';
|
||||
});
|
||||
}
|
||||
|
||||
get label() {
|
||||
return this._labelText;
|
||||
}
|
||||
|
||||
set label(text) {
|
||||
if (this._labelText == text)
|
||||
return;
|
||||
|
||||
if (this._label)
|
||||
this._label.label = text;
|
||||
this._labelText = text;
|
||||
this.notify('label');
|
||||
}
|
||||
|
||||
add(child) {
|
||||
// set expanded child
|
||||
this._childBin.get_children().forEach(c => {
|
||||
this._childBin.remove(c);
|
||||
});
|
||||
|
||||
if (child)
|
||||
this._childBin.add(child);
|
||||
}
|
||||
});
|
||||
|
||||
var ExtensionRow = new Lang.Class({
|
||||
Name: 'ExtensionRow',
|
||||
Extends: Gtk.ListBoxRow,
|
||||
|
||||
_init(uuid) {
|
||||
this.parent();
|
||||
|
||||
this.uuid = uuid;
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
|
||||
this._settings.connect('changed::enabled-extensions', () => {
|
||||
this._switch.state = this._isEnabled();
|
||||
var EmptyPlaceholder = GObject.registerClass(
|
||||
class EmptyPlaceholder extends Gtk.Box {
|
||||
_init() {
|
||||
super._init({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 6,
|
||||
margin: 32
|
||||
});
|
||||
this._settings.connect('changed::disable-extension-version-validation',
|
||||
() => {
|
||||
this._switch.sensitive = this._canEnable();
|
||||
|
||||
let image = new Gtk.Image({
|
||||
icon_name: 'application-x-addon-symbolic',
|
||||
pixel_size: 96,
|
||||
visible: true,
|
||||
vexpand: true,
|
||||
valign: Gtk.Align.END
|
||||
});
|
||||
image.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
|
||||
this.add(image);
|
||||
|
||||
let label = new Gtk.Label({
|
||||
label: `<b><span size="x-large">${_("No Extensions Installed" )}</span></b>`,
|
||||
use_markup: true,
|
||||
visible: true
|
||||
});
|
||||
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
|
||||
this.add(label);
|
||||
|
||||
let appInfo = Gio.DesktopAppInfo.new('org.gnome.Software.desktop');
|
||||
|
||||
let desc = new Gtk.Label({
|
||||
label: _("Extensions can be installed through Software or <a href=\"https://extensions.gnome.org\">extensions.gnome.org</a>."),
|
||||
use_markup: true,
|
||||
wrap: true,
|
||||
justify: Gtk.Justification.CENTER,
|
||||
visible: true,
|
||||
max_width_chars: 50,
|
||||
hexpand: true,
|
||||
vexpand: (appInfo == null),
|
||||
halign: Gtk.Align.CENTER,
|
||||
valign: Gtk.Align.START
|
||||
});
|
||||
this.add(desc);
|
||||
|
||||
if (appInfo) {
|
||||
let button = new Gtk.Button({
|
||||
label: _("Browse in Software"),
|
||||
image: new Gtk.Image({
|
||||
icon_name: "org.gnome.Software-symbolic"
|
||||
}),
|
||||
always_show_image: true,
|
||||
margin_top: 12,
|
||||
visible: true,
|
||||
halign: Gtk.Align.CENTER,
|
||||
valign: Gtk.Align.START,
|
||||
vexpand: true
|
||||
});
|
||||
this._settings.connect('changed::disable-user-extensions',
|
||||
() => {
|
||||
this._switch.sensitive = this._canEnable();
|
||||
this.add(button);
|
||||
|
||||
button.connect('clicked', w => {
|
||||
let context = w.get_display().get_app_launch_context();
|
||||
appInfo.launch([], context);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var NoShellPlaceholder = GObject.registerClass(
|
||||
class NoShellPlaceholder extends Gtk.Box {
|
||||
_init() {
|
||||
super._init({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 12,
|
||||
margin: 100,
|
||||
margin_bottom: 60
|
||||
});
|
||||
|
||||
let label = new Gtk.Label({
|
||||
label: '<span size="x-large">%s</span>'.format(
|
||||
_("Something’s gone wrong")),
|
||||
use_markup: true
|
||||
});
|
||||
label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL);
|
||||
this.add(label);
|
||||
|
||||
label = new Gtk.Label({
|
||||
label: _("We’re very sorry, but it was not possible to get the list of installed extensions. Make sure you are logged into GNOME and try again."),
|
||||
justify: Gtk.Justification.CENTER,
|
||||
wrap: true
|
||||
});
|
||||
this.add(label);
|
||||
|
||||
this.show_all();
|
||||
}
|
||||
});
|
||||
|
||||
var DescriptionLabel = GObject.registerClass(
|
||||
class DescriptionLabel extends Gtk.Label {
|
||||
vfunc_get_preferred_height_for_width(width) {
|
||||
// Hack: Request the maximum height allowed by the line limit
|
||||
if (this.lines > 0)
|
||||
return super.vfunc_get_preferred_height_for_width(0);
|
||||
return super.vfunc_get_preferred_height_for_width(width);
|
||||
}
|
||||
});
|
||||
|
||||
var ExtensionRow = GObject.registerClass(
|
||||
class ExtensionRow extends Gtk.ListBoxRow {
|
||||
_init(extension) {
|
||||
super._init();
|
||||
|
||||
this._app = Gio.Application.get_default();
|
||||
this._extension = extension;
|
||||
this._prefsModule = null;
|
||||
|
||||
this._extensionStateChangedId = this._app.shellProxy.connectSignal(
|
||||
'ExtensionStateChanged', (p, sender, [uuid, newState]) => {
|
||||
if (this.uuid !== uuid)
|
||||
return;
|
||||
|
||||
this._extension = ExtensionUtils.deserializeExtension(newState);
|
||||
let state = (this._extension.state == ExtensionState.ENABLED);
|
||||
this._switch.freeze_notify();
|
||||
this._switch.state = state;
|
||||
this._switch.active = this._extension.isRequested;
|
||||
this._switch.sensitive = this._canToggle();
|
||||
this._switch.thaw_notify();
|
||||
});
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._buildUI();
|
||||
},
|
||||
}
|
||||
|
||||
get uuid() {
|
||||
return this._extension.uuid;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this._extension.metadata.name;
|
||||
}
|
||||
|
||||
get hasPrefs() {
|
||||
return this._extension.hasPrefs;
|
||||
}
|
||||
|
||||
get url() {
|
||||
return this._extension.metadata.url;
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (!this._app.shellProxy)
|
||||
return;
|
||||
|
||||
if (this._extensionStateChangedId)
|
||||
this._app.shellProxy.disconnectSignal(this._extensionStateChangedId);
|
||||
this._extensionStateChangedId = 0;
|
||||
}
|
||||
|
||||
_buildUI() {
|
||||
let extension = ExtensionUtils.extensions[this.uuid];
|
||||
|
||||
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
|
||||
hexpand: true, margin_end: 24, spacing: 24,
|
||||
margin: 12 });
|
||||
@@ -291,73 +658,64 @@ var ExtensionRow = new Lang.Class({
|
||||
spacing: 6, hexpand: true });
|
||||
hbox.add(vbox);
|
||||
|
||||
let name = GLib.markup_escape_text(extension.metadata.name, -1);
|
||||
let name = GLib.markup_escape_text(this.name, -1);
|
||||
let label = new Gtk.Label({ label: '<b>' + name + '</b>',
|
||||
use_markup: true,
|
||||
halign: Gtk.Align.START });
|
||||
vbox.add(label);
|
||||
|
||||
let desc = extension.metadata.description.split('\n')[0];
|
||||
let desc = this._extension.metadata.description.split('\n')[0];
|
||||
label = new DescriptionLabel({ label: desc, wrap: true, lines: 2,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
xalign: 0, yalign: 0 });
|
||||
vbox.add(label);
|
||||
|
||||
let button = new Gtk.Button({ valign: Gtk.Align.CENTER,
|
||||
visible: this.hasPrefs,
|
||||
no_show_all: true });
|
||||
button.add(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
|
||||
icon_size: Gtk.IconSize.BUTTON,
|
||||
visible: true }));
|
||||
button.set_image(new Gtk.Image({ icon_name: 'emblem-system-symbolic',
|
||||
icon_size: Gtk.IconSize.BUTTON,
|
||||
visible: true }));
|
||||
button.get_style_context().add_class('circular');
|
||||
hbox.add(button);
|
||||
|
||||
this.prefsButton = button;
|
||||
|
||||
this._switch = new Gtk.Switch({ valign: Gtk.Align.CENTER,
|
||||
sensitive: this._canEnable(),
|
||||
state: this._isEnabled() });
|
||||
this._switch = new Gtk.Switch({
|
||||
valign: Gtk.Align.CENTER,
|
||||
sensitive: this._canToggle(),
|
||||
});
|
||||
this._switch.connect('notify::active', () => {
|
||||
if (this._switch.active)
|
||||
this._enable();
|
||||
this._app.shellProxy.EnableExtensionRemote(this.uuid);
|
||||
else
|
||||
this._disable();
|
||||
this._app.shellProxy.DisableExtensionRemote(this.uuid);
|
||||
});
|
||||
this._switch.connect('state-set', () => true);
|
||||
this._switch.freeze_notify();
|
||||
this._switch.state = this._extension.state === ExtensionState.ENABLED;
|
||||
this._switch.active = this._extension.isRequested;
|
||||
this._switch.thaw_notify();
|
||||
|
||||
hbox.add(this._switch);
|
||||
},
|
||||
}
|
||||
|
||||
_canEnable() {
|
||||
let extension = ExtensionUtils.extensions[this.uuid];
|
||||
let checkVersion = !this._settings.get_boolean('disable-extension-version-validation');
|
||||
_canToggle() {
|
||||
return this._extension.canChange;
|
||||
}
|
||||
|
||||
return !this._settings.get_boolean('disable-user-extensions') &&
|
||||
!(checkVersion && ExtensionUtils.isOutOfDate(extension));
|
||||
},
|
||||
get prefsModule() {
|
||||
if (!this._prefsModule) {
|
||||
ExtensionUtils.installImporter(this._extension);
|
||||
|
||||
_isEnabled() {
|
||||
let extensions = this._settings.get_strv('enabled-extensions');
|
||||
return extensions.indexOf(this.uuid) != -1;
|
||||
},
|
||||
// give extension prefs access to their own extension object
|
||||
ExtensionUtils.getCurrentExtension = () => this._extension;
|
||||
|
||||
_enable() {
|
||||
let extensions = this._settings.get_strv('enabled-extensions');
|
||||
if (extensions.indexOf(this.uuid) != -1)
|
||||
return;
|
||||
this._prefsModule = this._extension.imports.prefs;
|
||||
this._prefsModule.init(this._extension.metadata);
|
||||
}
|
||||
|
||||
extensions.push(this.uuid);
|
||||
this._settings.set_strv('enabled-extensions', extensions);
|
||||
},
|
||||
|
||||
_disable() {
|
||||
let extensions = this._settings.get_strv('enabled-extensions');
|
||||
let pos = extensions.indexOf(this.uuid);
|
||||
if (pos == -1)
|
||||
return;
|
||||
do {
|
||||
extensions.splice(pos, 1);
|
||||
pos = extensions.indexOf(this.uuid);
|
||||
} while (pos != -1);
|
||||
this._settings.set_strv('enabled-extensions', extensions);
|
||||
return this._prefsModule;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -365,12 +723,12 @@ function initEnvironment() {
|
||||
// Monkey-patch in a "global" object that fakes some Shell utilities
|
||||
// that ExtensionUtils depends on.
|
||||
window.global = {
|
||||
log() {
|
||||
print([].join.call(arguments, ', '));
|
||||
log(...args) {
|
||||
print(args.join(', '));
|
||||
},
|
||||
|
||||
logError(s) {
|
||||
log('ERROR: ' + s);
|
||||
log(`ERROR: ${s}`);
|
||||
},
|
||||
|
||||
userdatadir: GLib.build_filenamev([GLib.get_user_data_dir(), 'gnome-shell'])
|
||||
@@ -385,6 +743,5 @@ function main(argv) {
|
||||
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
||||
Gettext.textdomain(Config.GETTEXT_PACKAGE);
|
||||
|
||||
let app = new Application();
|
||||
app.application.run(argv);
|
||||
new Application().run(argv);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,20 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const { Clutter, Pango, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
const Batch = imports.gdm.batch;
|
||||
const GdmUtil = imports.gdm.util;
|
||||
const Params = imports.misc.params;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
|
||||
var DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
|
||||
var DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
|
||||
var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3;
|
||||
var DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1000;
|
||||
var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
|
||||
|
||||
var MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5;
|
||||
var MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
|
||||
|
||||
var AuthPromptMode = {
|
||||
UNLOCK_ONLY: 0,
|
||||
@@ -38,10 +33,8 @@ var BeginRequestType = {
|
||||
DONT_PROVIDE_USERNAME: 1
|
||||
};
|
||||
|
||||
var AuthPrompt = new Lang.Class({
|
||||
Name: 'AuthPrompt',
|
||||
|
||||
_init(gdmClient, mode) {
|
||||
var AuthPrompt = class {
|
||||
constructor(gdmClient, mode) {
|
||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||
|
||||
this._gdmClient = gdmClient;
|
||||
@@ -65,23 +58,23 @@ var AuthPrompt = new Lang.Class({
|
||||
this.smartcardDetected = this._userVerifier.smartcardDetected;
|
||||
|
||||
this.connect('next', () => {
|
||||
this.updateSensitivity(false);
|
||||
this.startSpinning();
|
||||
if (this._queryingService) {
|
||||
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
|
||||
} else {
|
||||
this._preemptiveAnswer = this._entry.text;
|
||||
}
|
||||
});
|
||||
this.updateSensitivity(false);
|
||||
this.startSpinning();
|
||||
if (this._queryingService) {
|
||||
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
|
||||
} else {
|
||||
this._preemptiveAnswer = this._entry.text;
|
||||
}
|
||||
});
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
|
||||
vertical: true });
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.actor.connect('key-press-event', (actor, event) => {
|
||||
if (event.get_key_symbol() == Clutter.KEY_Escape)
|
||||
this.cancel();
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
});
|
||||
if (event.get_key_symbol() == Clutter.KEY_Escape)
|
||||
this.cancel();
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
});
|
||||
|
||||
this._userWell = new St.Bin({ x_fill: true,
|
||||
x_align: St.Align.START });
|
||||
@@ -99,7 +92,7 @@ var AuthPrompt = new Lang.Class({
|
||||
x_align: St.Align.START });
|
||||
this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
|
||||
can_focus: true });
|
||||
ShellEntry.addContextMenu(this._entry, { isPassword: true });
|
||||
ShellEntry.addContextMenu(this._entry, { isPassword: true, actionMode: Shell.ActionMode.NONE });
|
||||
|
||||
this.actor.add(this._entry,
|
||||
{ expand: true,
|
||||
@@ -118,7 +111,7 @@ var AuthPrompt = new Lang.Class({
|
||||
this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',
|
||||
vertical: false });
|
||||
this.actor.add(this._buttonBox,
|
||||
{ expand: true,
|
||||
{ expand: true,
|
||||
x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.END });
|
||||
|
||||
@@ -127,17 +120,16 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this._initButtons();
|
||||
|
||||
let spinnerIcon = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
|
||||
this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
|
||||
this._spinner = new Animation.Spinner(DEFAULT_BUTTON_WELL_ICON_SIZE);
|
||||
this._spinner.actor.opacity = 0;
|
||||
this._spinner.actor.show();
|
||||
this._defaultButtonWell.add_child(this._spinner.actor);
|
||||
},
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._userVerifier.destroy();
|
||||
this._userVerifier = null;
|
||||
},
|
||||
}
|
||||
|
||||
_initButtons() {
|
||||
this.cancelButton = new St.Button({ style_class: 'modal-dialog-button button',
|
||||
@@ -145,7 +137,7 @@ var AuthPrompt = new Lang.Class({
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
label: _("Cancel") });
|
||||
this.cancelButton.connect('clicked', () => { this.cancel(); });
|
||||
this.cancelButton.connect('clicked', () => this.cancel());
|
||||
this._buttonBox.add(this.cancelButton,
|
||||
{ expand: false,
|
||||
x_fill: false,
|
||||
@@ -164,7 +156,7 @@ var AuthPrompt = new Lang.Class({
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
label: _("Next") });
|
||||
this.nextButton.connect('clicked', () => { this.emit('next'); });
|
||||
this.nextButton.connect('clicked', () => this.emit('next'));
|
||||
this.nextButton.add_style_pseudo_class('default');
|
||||
this._buttonBox.add(this.nextButton,
|
||||
{ expand: false,
|
||||
@@ -185,7 +177,7 @@ var AuthPrompt = new Lang.Class({
|
||||
if (this.nextButton.reactive)
|
||||
this.emit('next');
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_onAskQuestion(verifier, serviceName, question, passwordChar) {
|
||||
if (this._queryingService)
|
||||
@@ -211,12 +203,12 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this.updateSensitivity(true);
|
||||
this.emit('prompted');
|
||||
},
|
||||
}
|
||||
|
||||
_onOVirtUserAuthenticated() {
|
||||
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
||||
this.reset();
|
||||
},
|
||||
}
|
||||
|
||||
_onSmartcardStatusChanged() {
|
||||
this.smartcardDetected = this._userVerifier.smartcardDetected;
|
||||
@@ -235,12 +227,12 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
||||
this.reset();
|
||||
},
|
||||
}
|
||||
|
||||
_onShowMessage(userVerifier, message, type) {
|
||||
this.setMessage(message, type);
|
||||
this.emit('prompted');
|
||||
},
|
||||
}
|
||||
|
||||
_onVerificationFailed(userVerifier, canRetry) {
|
||||
this._queryingService = null;
|
||||
@@ -249,22 +241,22 @@ var AuthPrompt = new Lang.Class({
|
||||
this.updateSensitivity(canRetry);
|
||||
this.setActorInDefaultButtonWell(null);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
|
||||
},
|
||||
}
|
||||
|
||||
_onVerificationComplete() {
|
||||
this.setActorInDefaultButtonWell(null);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
|
||||
this.cancelButton.reactive = false;
|
||||
},
|
||||
}
|
||||
|
||||
_onReset() {
|
||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||
this.reset();
|
||||
},
|
||||
}
|
||||
|
||||
addActorToDefaultButtonWell(actor) {
|
||||
this._defaultButtonWell.add_child(actor);
|
||||
},
|
||||
}
|
||||
|
||||
setActorInDefaultButtonWell(actor, animate) {
|
||||
if (!this._defaultButtonWellActor &&
|
||||
@@ -274,7 +266,7 @@ var AuthPrompt = new Lang.Class({
|
||||
let oldActor = this._defaultButtonWellActor;
|
||||
|
||||
if (oldActor)
|
||||
Tweener.removeTweens(oldActor);
|
||||
oldActor.remove_all_transitions();
|
||||
|
||||
let wasSpinner;
|
||||
if (oldActor == this._spinner.actor)
|
||||
@@ -297,19 +289,18 @@ var AuthPrompt = new Lang.Class({
|
||||
this._spinner.stop();
|
||||
}
|
||||
} else {
|
||||
Tweener.addTween(oldActor,
|
||||
{ opacity: 0,
|
||||
time: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
|
||||
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
|
||||
transition: 'linear',
|
||||
onCompleteScope: this,
|
||||
onComplete() {
|
||||
if (wasSpinner) {
|
||||
if (this._spinner)
|
||||
this._spinner.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
oldActor.ease({
|
||||
opacity: 0,
|
||||
duration: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
|
||||
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
|
||||
mode: Clutter.AnimationMode.LINEAR,
|
||||
onComplete: () => {
|
||||
if (wasSpinner) {
|
||||
if (this._spinner)
|
||||
this._spinner.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,33 +311,34 @@ var AuthPrompt = new Lang.Class({
|
||||
if (!animate)
|
||||
actor.opacity = 255;
|
||||
else
|
||||
Tweener.addTween(actor,
|
||||
{ opacity: 255,
|
||||
time: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
|
||||
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
|
||||
transition: 'linear' });
|
||||
actor.ease({
|
||||
opacity: 255,
|
||||
duration: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
|
||||
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
|
||||
mode: Clutter.AnimationMode.LINEAR
|
||||
});
|
||||
}
|
||||
|
||||
this._defaultButtonWellActor = actor;
|
||||
},
|
||||
}
|
||||
|
||||
startSpinning() {
|
||||
this.setActorInDefaultButtonWell(this._spinner.actor, true);
|
||||
},
|
||||
}
|
||||
|
||||
stopSpinning() {
|
||||
this.setActorInDefaultButtonWell(null, false);
|
||||
},
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._entry.text = '';
|
||||
this.stopSpinning();
|
||||
},
|
||||
}
|
||||
|
||||
setPasswordChar(passwordChar) {
|
||||
this._entry.clutter_text.set_password_char(passwordChar);
|
||||
this._entry.menu.isPassword = passwordChar != '';
|
||||
},
|
||||
}
|
||||
|
||||
setQuestion(question) {
|
||||
this._label.set_text(question);
|
||||
@@ -355,7 +347,7 @@ var AuthPrompt = new Lang.Class({
|
||||
this._entry.show();
|
||||
|
||||
this._entry.grab_key_focus();
|
||||
},
|
||||
}
|
||||
|
||||
getAnswer() {
|
||||
let text;
|
||||
@@ -368,18 +360,18 @@ var AuthPrompt = new Lang.Class({
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
}
|
||||
|
||||
_fadeOutMessage() {
|
||||
if (this._message.opacity == 0)
|
||||
return;
|
||||
Tweener.removeTweens(this._message);
|
||||
Tweener.addTween(this._message,
|
||||
{ opacity: 0,
|
||||
time: MESSAGE_FADE_OUT_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
},
|
||||
this._message.remove_all_transitions();
|
||||
this._message.ease({
|
||||
opacity: 0,
|
||||
duration: MESSAGE_FADE_OUT_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
});
|
||||
}
|
||||
|
||||
setMessage(message, type) {
|
||||
if (type == GdmUtil.MessageType.ERROR)
|
||||
@@ -393,24 +385,24 @@ var AuthPrompt = new Lang.Class({
|
||||
this._message.remove_style_class_name('login-dialog-message-hint');
|
||||
|
||||
if (message) {
|
||||
Tweener.removeTweens(this._message);
|
||||
this._message.remove_all_transitions();
|
||||
this._message.text = message;
|
||||
this._message.opacity = 255;
|
||||
} else {
|
||||
this._message.opacity = 0;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_updateNextButtonSensitivity(sensitive) {
|
||||
this.nextButton.reactive = sensitive;
|
||||
this.nextButton.can_focus = sensitive;
|
||||
},
|
||||
}
|
||||
|
||||
updateSensitivity(sensitive) {
|
||||
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
|
||||
this._entry.reactive = sensitive;
|
||||
this._entry.clutter_text.editable = sensitive;
|
||||
},
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.setActorInDefaultButtonWell(null, true);
|
||||
@@ -421,7 +413,7 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this.updateSensitivity(true);
|
||||
this._entry.set_text('');
|
||||
},
|
||||
}
|
||||
|
||||
setUser(user) {
|
||||
let oldChild = this._userWell.get_child();
|
||||
@@ -432,7 +424,7 @@ var AuthPrompt = new Lang.Class({
|
||||
let userWidget = new UserWidget.UserWidget(user);
|
||||
this._userWell.set_child(userWidget.actor);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
reset() {
|
||||
let oldStatus = this.verificationStatus;
|
||||
@@ -470,7 +462,7 @@ var AuthPrompt = new Lang.Class({
|
||||
}
|
||||
|
||||
this.emit('reset', beginRequestType);
|
||||
},
|
||||
}
|
||||
|
||||
addCharacter(unichar) {
|
||||
if (!this._entry.visible)
|
||||
@@ -478,7 +470,7 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this._entry.grab_key_focus();
|
||||
this._entry.clutter_text.insert_unichar(unichar);
|
||||
},
|
||||
}
|
||||
|
||||
begin(params) {
|
||||
params = Params.parse(params, { userName: null,
|
||||
@@ -492,7 +484,7 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this._userVerifier.begin(params.userName, hold);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFYING;
|
||||
},
|
||||
}
|
||||
|
||||
finish(onComplete) {
|
||||
if (!this._userVerifier.hasPendingMessages) {
|
||||
@@ -506,7 +498,7 @@ var AuthPrompt = new Lang.Class({
|
||||
this._userVerifier.clear();
|
||||
onComplete();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
cancel() {
|
||||
if (this.verificationStatus == AuthPromptStatus.VERIFICATION_SUCCEEDED) {
|
||||
@@ -515,5 +507,5 @@ var AuthPrompt = new Lang.Class({
|
||||
this.reset();
|
||||
this.emit('cancelled');
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(AuthPrompt.prototype);
|
||||
|
||||
118
js/gdm/batch.js
@@ -20,7 +20,7 @@
|
||||
* In order for transformation animations to look good, they need to be
|
||||
* incremental and have some order to them (e.g., fade out hidden items,
|
||||
* then shrink to close the void left over). Chaining animations in this way can
|
||||
* be error-prone and wordy using just Tweener callbacks.
|
||||
* be error-prone and wordy using just ease() callbacks.
|
||||
*
|
||||
* The classes in this file help with this:
|
||||
*
|
||||
@@ -44,45 +44,40 @@
|
||||
* replaced by something else.
|
||||
*/
|
||||
|
||||
const Lang = imports.lang;
|
||||
const { GObject } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
var Task = new Lang.Class({
|
||||
Name: 'Task',
|
||||
|
||||
_init(scope, handler) {
|
||||
var Task = class {
|
||||
constructor(scope, handler) {
|
||||
if (scope)
|
||||
this.scope = scope;
|
||||
else
|
||||
this.scope = this;
|
||||
|
||||
this.handler = handler;
|
||||
},
|
||||
}
|
||||
|
||||
run() {
|
||||
if (this.handler)
|
||||
return this.handler.call(this.scope);
|
||||
|
||||
return null;
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Task.prototype);
|
||||
|
||||
var Hold = new Lang.Class({
|
||||
Name: 'Hold',
|
||||
Extends: Task,
|
||||
|
||||
_init() {
|
||||
this.parent(this, () => this);
|
||||
var Hold = class extends Task {
|
||||
constructor() {
|
||||
super(null, () => this);
|
||||
|
||||
this._acquisitions = 1;
|
||||
},
|
||||
}
|
||||
|
||||
acquire() {
|
||||
if (this._acquisitions <= 0)
|
||||
throw new Error("Cannot acquire hold after it's been released");
|
||||
this._acquisitions++;
|
||||
},
|
||||
}
|
||||
|
||||
acquireUntilAfter(hold) {
|
||||
if (!hold.isAcquired())
|
||||
@@ -93,27 +88,24 @@ var Hold = new Lang.Class({
|
||||
hold.disconnect(signalId);
|
||||
this.release();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
release() {
|
||||
this._acquisitions--;
|
||||
|
||||
if (this._acquisitions == 0)
|
||||
this.emit('release');
|
||||
},
|
||||
}
|
||||
|
||||
isAcquired() {
|
||||
return this._acquisitions > 0;
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(Hold.prototype);
|
||||
|
||||
var Batch = new Lang.Class({
|
||||
Name: 'Batch',
|
||||
Extends: Task,
|
||||
|
||||
_init(scope, tasks) {
|
||||
this.parent();
|
||||
var Batch = class extends Task {
|
||||
constructor(scope, tasks) {
|
||||
super();
|
||||
|
||||
this.tasks = [];
|
||||
|
||||
@@ -130,11 +122,11 @@ var Batch = new Lang.Class({
|
||||
|
||||
this.tasks.push(task);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
process() {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
throw new GObject.NotImplementedError(`process in ${this.constructor.name}`);
|
||||
}
|
||||
|
||||
runTask() {
|
||||
if (!(this._currentTaskIndex in this.tasks)) {
|
||||
@@ -142,11 +134,11 @@ var Batch = new Lang.Class({
|
||||
}
|
||||
|
||||
return this.tasks[this._currentTaskIndex].run();
|
||||
},
|
||||
}
|
||||
|
||||
_finish() {
|
||||
this.hold.release();
|
||||
},
|
||||
}
|
||||
|
||||
nextTask() {
|
||||
this._currentTaskIndex++;
|
||||
@@ -159,7 +151,7 @@ var Batch = new Lang.Class({
|
||||
}
|
||||
|
||||
this.process();
|
||||
},
|
||||
}
|
||||
|
||||
_start() {
|
||||
// acquire a hold to get released when the entire
|
||||
@@ -167,7 +159,7 @@ var Batch = new Lang.Class({
|
||||
this.hold = new Hold();
|
||||
this._currentTaskIndex = 0;
|
||||
this.process();
|
||||
},
|
||||
}
|
||||
|
||||
run() {
|
||||
this._start();
|
||||
@@ -175,52 +167,46 @@ var Batch = new Lang.Class({
|
||||
// hold may be destroyed at this point
|
||||
// if we're already done running
|
||||
return this.hold;
|
||||
},
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.tasks = this.tasks.splice(0, this._currentTaskIndex + 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(Batch.prototype);
|
||||
|
||||
var ConcurrentBatch = new Lang.Class({
|
||||
Name: 'ConcurrentBatch',
|
||||
Extends: Batch,
|
||||
|
||||
var ConcurrentBatch = class extends Batch {
|
||||
process() {
|
||||
let hold = this.runTask();
|
||||
let hold = this.runTask();
|
||||
|
||||
if (hold) {
|
||||
this.hold.acquireUntilAfter(hold);
|
||||
}
|
||||
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();
|
||||
// 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);
|
||||
|
||||
var ConsecutiveBatch = new Lang.Class({
|
||||
Name: 'ConsecutiveBatch',
|
||||
Extends: Batch,
|
||||
|
||||
var ConsecutiveBatch = class extends Batch {
|
||||
process() {
|
||||
let hold = this.runTask();
|
||||
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', () => {
|
||||
hold.disconnect(signalId);
|
||||
this.nextTask();
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
// This task finished, process the next one
|
||||
this.nextTask();
|
||||
}
|
||||
if (hold && hold.isAcquired()) {
|
||||
// This task is inhibiting the batch. Wait on it
|
||||
// before processing the next one.
|
||||
let signalId = hold.connect('release', () => {
|
||||
hold.disconnect(signalId);
|
||||
this.nextTask();
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
// This task finished, process the next one
|
||||
this.nextTask();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(ConsecutiveBatch.prototype);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported FprintManager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const FprintManagerIface = `
|
||||
<node>
|
||||
@@ -26,8 +24,8 @@ function FprintManager() {
|
||||
|
||||
try {
|
||||
self.init(null);
|
||||
} catch(e) {
|
||||
log('Failed to connect to Fprint service: ' + e.message);
|
||||
} catch (e) {
|
||||
log(`Failed to connect to Fprint service: ${e.message}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported LoginDialog */
|
||||
/*
|
||||
* Copyright 2011 Red Hat, Inc
|
||||
*
|
||||
@@ -16,20 +17,9 @@
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const AccountsService = imports.gi.AccountsService;
|
||||
const Atk = imports.gi.Atk;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gdm = imports.gi.Gdm;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const { AccountsService, Atk, Clutter, Gdm, Gio,
|
||||
GLib, GObject, Meta, Pango, Shell, St } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const AuthPrompt = imports.gdm.authPrompt;
|
||||
const Batch = imports.gdm.batch;
|
||||
@@ -41,22 +31,19 @@ const LoginManager = imports.misc.loginManager;
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Realmd = imports.gdm.realmd;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
|
||||
const _FADE_ANIMATION_TIME = 0.25;
|
||||
const _SCROLL_ANIMATION_TIME = 0.5;
|
||||
const _FADE_ANIMATION_TIME = 250;
|
||||
const _SCROLL_ANIMATION_TIME = 500;
|
||||
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
||||
const _LOGO_ICON_HEIGHT = 48;
|
||||
const _MAX_BOTTOM_MENU_ITEMS = 5;
|
||||
|
||||
var UserListItem = new Lang.Class({
|
||||
Name: 'UserListItem',
|
||||
|
||||
_init(user) {
|
||||
var UserListItem = class {
|
||||
constructor(user) {
|
||||
this.user = user;
|
||||
this._userChangedId = this.user.connect('changed',
|
||||
this._onUserChanged.bind(this));
|
||||
this._onUserChanged.bind(this));
|
||||
|
||||
let layout = new St.BoxLayout({ vertical: true });
|
||||
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
|
||||
@@ -91,26 +78,26 @@ var UserListItem = new Lang.Class({
|
||||
|
||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||
this._onUserChanged();
|
||||
},
|
||||
}
|
||||
|
||||
_onUserChanged() {
|
||||
this._updateLoggedIn();
|
||||
},
|
||||
}
|
||||
|
||||
_updateLoggedIn() {
|
||||
if (this.user.is_logged_in())
|
||||
this.actor.add_style_pseudo_class('logged-in');
|
||||
else
|
||||
this.actor.remove_style_pseudo_class('logged-in');
|
||||
},
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this.user.disconnect(this._userChangedId);
|
||||
},
|
||||
}
|
||||
|
||||
_onClicked() {
|
||||
this.emit('activate');
|
||||
},
|
||||
}
|
||||
|
||||
_setSelected(selected) {
|
||||
if (selected) {
|
||||
@@ -119,7 +106,7 @@ var UserListItem = new Lang.Class({
|
||||
} else {
|
||||
this.actor.remove_style_pseudo_class('selected');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
showTimedLoginIndicator(time) {
|
||||
let hold = new Batch.Hold();
|
||||
@@ -147,7 +134,7 @@ var UserListItem = new Lang.Class({
|
||||
GLib.Source.set_name_by_id(this._timedLoginTimeoutId, '[gnome-shell] this._timedLoginTimeoutId');
|
||||
|
||||
return hold;
|
||||
},
|
||||
}
|
||||
|
||||
hideTimedLoginIndicator() {
|
||||
if (this._timedLoginTimeoutId) {
|
||||
@@ -158,16 +145,14 @@ var UserListItem = new Lang.Class({
|
||||
this._timedLoginIndicator.visible = false;
|
||||
this._timedLoginIndicator.scale_x = 0.;
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(UserListItem.prototype);
|
||||
|
||||
var UserList = new Lang.Class({
|
||||
Name: 'UserList',
|
||||
|
||||
_init() {
|
||||
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
|
||||
this.actor.set_policy(Gtk.PolicyType.NEVER,
|
||||
Gtk.PolicyType.AUTOMATIC);
|
||||
var UserList = class {
|
||||
constructor() {
|
||||
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view' });
|
||||
this.actor.set_policy(St.PolicyType.NEVER,
|
||||
St.PolicyType.AUTOMATIC);
|
||||
|
||||
this._box = new St.BoxLayout({ vertical: true,
|
||||
style_class: 'login-dialog-user-list',
|
||||
@@ -177,7 +162,7 @@ var UserList = new Lang.Class({
|
||||
this._items = {};
|
||||
|
||||
this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_moveFocusToItems() {
|
||||
let hasItems = Object.keys(this._items).length > 0;
|
||||
@@ -188,22 +173,20 @@ var UserList = new Lang.Class({
|
||||
if (global.stage.get_key_focus() != this.actor)
|
||||
return;
|
||||
|
||||
let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||
let focusSet = this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
|
||||
if (!focusSet) {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this._moveFocusToItems();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_onItemActivated(activatedItem) {
|
||||
this.emit('activate', activatedItem);
|
||||
},
|
||||
}
|
||||
|
||||
updateStyle(isExpanded) {
|
||||
let tasks = [];
|
||||
|
||||
if (isExpanded)
|
||||
this._box.add_style_pseudo_class('expanded');
|
||||
else
|
||||
@@ -213,7 +196,7 @@ var UserList = new Lang.Class({
|
||||
let item = this._items[userName];
|
||||
item.actor.sync_hover();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
scrollToItem(item) {
|
||||
let box = item.actor.get_allocation_box();
|
||||
@@ -221,12 +204,11 @@ var UserList = new Lang.Class({
|
||||
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
|
||||
|
||||
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
Tweener.removeTweens(adjustment);
|
||||
Tweener.addTween (adjustment,
|
||||
{ value: value,
|
||||
time: _SCROLL_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
},
|
||||
adjustment.ease(value, {
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: _SCROLL_ANIMATION_TIME
|
||||
});
|
||||
}
|
||||
|
||||
jumpToItem(item) {
|
||||
let box = item.actor.get_allocation_box();
|
||||
@@ -236,7 +218,7 @@ var UserList = new Lang.Class({
|
||||
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
|
||||
adjustment.set_value(value);
|
||||
},
|
||||
}
|
||||
|
||||
getItemFromUserName(userName) {
|
||||
let item = this._items[userName];
|
||||
@@ -245,11 +227,11 @@ var UserList = new Lang.Class({
|
||||
return null;
|
||||
|
||||
return item;
|
||||
},
|
||||
}
|
||||
|
||||
containsUser(user) {
|
||||
return this._items[user.get_user_name()] != null;
|
||||
},
|
||||
}
|
||||
|
||||
addUser(user) {
|
||||
if (!user.is_loaded)
|
||||
@@ -259,7 +241,7 @@ var UserList = new Lang.Class({
|
||||
return;
|
||||
|
||||
if (user.locked)
|
||||
return;
|
||||
return;
|
||||
|
||||
let userName = user.get_user_name();
|
||||
|
||||
@@ -276,12 +258,12 @@ var UserList = new Lang.Class({
|
||||
item.connect('activate', this._onItemActivated.bind(this));
|
||||
|
||||
// Try to keep the focused item front-and-center
|
||||
item.actor.connect('key-focus-in', () => { this.scrollToItem(item); });
|
||||
item.actor.connect('key-focus-in', () => this.scrollToItem(item));
|
||||
|
||||
this._moveFocusToItems();
|
||||
|
||||
this.emit('item-added', item);
|
||||
},
|
||||
}
|
||||
|
||||
removeUser(user) {
|
||||
if (!user.is_loaded)
|
||||
@@ -299,18 +281,16 @@ var UserList = new Lang.Class({
|
||||
|
||||
item.actor.destroy();
|
||||
delete this._items[userName];
|
||||
},
|
||||
}
|
||||
|
||||
numItems() {
|
||||
return Object.keys(this._items).length;
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(UserList.prototype);
|
||||
|
||||
var SessionMenuButton = new Lang.Class({
|
||||
Name: 'SessionMenuButton',
|
||||
|
||||
_init() {
|
||||
var SessionMenuButton = class {
|
||||
constructor() {
|
||||
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
|
||||
this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
|
||||
reactive: true,
|
||||
@@ -336,27 +316,28 @@ var SessionMenuButton = new Lang.Class({
|
||||
this._menu.actor.hide();
|
||||
|
||||
this._menu.connect('open-state-changed', (menu, isOpen) => {
|
||||
if (isOpen)
|
||||
this._button.add_style_pseudo_class('active');
|
||||
else
|
||||
this._button.remove_style_pseudo_class('active');
|
||||
if (isOpen)
|
||||
this._button.add_style_pseudo_class('active');
|
||||
else
|
||||
this._button.remove_style_pseudo_class('active');
|
||||
});
|
||||
|
||||
this._manager = new PopupMenu.PopupMenuManager({ actor: this._button });
|
||||
this._manager = new PopupMenu.PopupMenuManager(this._button,
|
||||
{ actionMode: Shell.ActionMode.NONE });
|
||||
this._manager.addMenu(this._menu);
|
||||
|
||||
this._button.connect('clicked', () => { this._menu.toggle(); });
|
||||
this._button.connect('clicked', () => this._menu.toggle());
|
||||
|
||||
this._items = {};
|
||||
this._activeSessionId = null;
|
||||
this._populate();
|
||||
},
|
||||
}
|
||||
|
||||
updateSensitivity(sensitive) {
|
||||
this._button.reactive = sensitive;
|
||||
this._button.can_focus = sensitive;
|
||||
this._menu.close(BoxPointer.PopupAnimation.NONE);
|
||||
},
|
||||
}
|
||||
|
||||
_updateOrnament() {
|
||||
let itemIds = Object.keys(this._items);
|
||||
@@ -366,19 +347,19 @@ var SessionMenuButton = new Lang.Class({
|
||||
else
|
||||
this._items[itemIds[i]].setOrnament(PopupMenu.Ornament.NONE);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
setActiveSession(sessionId) {
|
||||
if (sessionId == this._activeSessionId)
|
||||
return;
|
||||
if (sessionId == this._activeSessionId)
|
||||
return;
|
||||
|
||||
this._activeSessionId = sessionId;
|
||||
this._updateOrnament();
|
||||
},
|
||||
this._activeSessionId = sessionId;
|
||||
this._updateOrnament();
|
||||
}
|
||||
|
||||
close() {
|
||||
this._menu.close();
|
||||
},
|
||||
}
|
||||
|
||||
_populate() {
|
||||
let ids = Gdm.get_session_ids();
|
||||
@@ -390,7 +371,7 @@ var SessionMenuButton = new Lang.Class({
|
||||
}
|
||||
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]);
|
||||
let [sessionName, sessionDescription_] = Gdm.get_session_name_and_description(ids[i]);
|
||||
|
||||
let id = ids[i];
|
||||
let item = new PopupMenu.PopupMenuItem(sessionName);
|
||||
@@ -403,16 +384,14 @@ var SessionMenuButton = new Lang.Class({
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(SessionMenuButton.prototype);
|
||||
|
||||
var LoginDialog = new Lang.Class({
|
||||
Name: 'LoginDialog',
|
||||
Extends: St.Widget,
|
||||
var LoginDialog = GObject.registerClass({
|
||||
Signals: { 'failed': {} },
|
||||
|
||||
}, class LoginDialog extends St.Widget {
|
||||
_init(parentActor) {
|
||||
this.parent({ style_class: 'login-dialog',
|
||||
super._init({ style_class: 'login-dialog',
|
||||
visible: false });
|
||||
|
||||
this.get_accessible().set_role(Atk.Role.WINDOW);
|
||||
@@ -421,18 +400,18 @@ var LoginDialog = new Lang.Class({
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
parentActor.add_child(this);
|
||||
|
||||
this._userManager = AccountsService.UserManager.get_default()
|
||||
this._userManager = AccountsService.UserManager.get_default();
|
||||
this._gdmClient = new Gdm.Client();
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
||||
|
||||
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
|
||||
this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_KEY}`,
|
||||
this._updateBanner.bind(this));
|
||||
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
|
||||
this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_TEXT_KEY}`,
|
||||
this._updateBanner.bind(this));
|
||||
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
|
||||
this._settings.connect(`changed::${GdmUtil.DISABLE_USER_LIST_KEY}`,
|
||||
this._updateDisableUserList.bind(this));
|
||||
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
||||
this._settings.connect(`changed::${GdmUtil.LOGO_KEY}`,
|
||||
this._updateLogo.bind(this));
|
||||
|
||||
this._textureCache = St.TextureCache.get_default();
|
||||
@@ -482,8 +461,8 @@ var LoginDialog = new Lang.Class({
|
||||
|
||||
this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
|
||||
opacity: 0,
|
||||
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
|
||||
hscrollbar_policy: Gtk.PolicyType.NEVER });
|
||||
vscrollbar_policy: St.PolicyType.AUTOMATIC,
|
||||
hscrollbar_policy: St.PolicyType.NEVER });
|
||||
this.add_child(this._bannerView);
|
||||
|
||||
let bannerBox = new St.BoxLayout({ vertical: true });
|
||||
@@ -499,6 +478,9 @@ var LoginDialog = new Lang.Class({
|
||||
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.END });
|
||||
this._logoBin.connect('resource-scale-changed', () => {
|
||||
this._updateLogoTexture(this._textureCache, this._logoFile);
|
||||
});
|
||||
this.add_child(this._logoBin);
|
||||
this._updateLogo();
|
||||
|
||||
@@ -530,12 +512,12 @@ var LoginDialog = new Lang.Class({
|
||||
// focus later
|
||||
this._startupCompleteId = Main.layoutManager.connect('startup-complete',
|
||||
this._updateDisableUserList.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_getBannerAllocation(dialogBox) {
|
||||
let actorBox = new Clutter.ActorBox();
|
||||
|
||||
let [minWidth, minHeight, natWidth, natHeight] = this._bannerView.get_preferred_size();
|
||||
let [, , natWidth, natHeight] = this._bannerView.get_preferred_size();
|
||||
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
||||
|
||||
actorBox.x1 = Math.floor(centerX - natWidth / 2);
|
||||
@@ -544,12 +526,12 @@ var LoginDialog = new Lang.Class({
|
||||
actorBox.y2 = actorBox.y1 + natHeight;
|
||||
|
||||
return actorBox;
|
||||
},
|
||||
}
|
||||
|
||||
_getLogoBinAllocation(dialogBox) {
|
||||
let actorBox = new Clutter.ActorBox();
|
||||
|
||||
let [minWidth, minHeight, natWidth, natHeight] = this._logoBin.get_preferred_size();
|
||||
let [, , natWidth, natHeight] = this._logoBin.get_preferred_size();
|
||||
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
||||
|
||||
actorBox.x1 = Math.floor(centerX - natWidth / 2);
|
||||
@@ -558,12 +540,12 @@ var LoginDialog = new Lang.Class({
|
||||
actorBox.y2 = actorBox.y1 + natHeight;
|
||||
|
||||
return actorBox;
|
||||
},
|
||||
}
|
||||
|
||||
_getCenterActorAllocation(dialogBox, actor) {
|
||||
let actorBox = new Clutter.ActorBox();
|
||||
|
||||
let [minWidth, minHeight, natWidth, natHeight] = actor.get_preferred_size();
|
||||
let [, , natWidth, natHeight] = actor.get_preferred_size();
|
||||
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
||||
let centerY = dialogBox.y1 + (dialogBox.y2 - dialogBox.y1) / 2;
|
||||
|
||||
@@ -576,7 +558,7 @@ var LoginDialog = new Lang.Class({
|
||||
actorBox.y2 = actorBox.y1 + natHeight;
|
||||
|
||||
return actorBox;
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_allocate(dialogBox, flags) {
|
||||
this.set_allocation(dialogBox, flags);
|
||||
@@ -590,19 +572,15 @@ var LoginDialog = new Lang.Class({
|
||||
// First find out what space the children require
|
||||
let bannerAllocation = null;
|
||||
let bannerHeight = 0;
|
||||
let bannerWidth = 0;
|
||||
if (this._bannerView.visible) {
|
||||
bannerAllocation = this._getBannerAllocation(dialogBox, this._bannerView);
|
||||
bannerHeight = bannerAllocation.y2 - bannerAllocation.y1;
|
||||
bannerWidth = bannerAllocation.x2 - bannerAllocation.x1;
|
||||
}
|
||||
|
||||
let authPromptAllocation = null;
|
||||
let authPromptHeight = 0;
|
||||
let authPromptWidth = 0;
|
||||
if (this._authPrompt.actor.visible) {
|
||||
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
|
||||
authPromptHeight = authPromptAllocation.y2 - authPromptAllocation.y1;
|
||||
authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1;
|
||||
}
|
||||
|
||||
@@ -634,64 +612,64 @@ var LoginDialog = new Lang.Class({
|
||||
let leftOverYSpace = bannerSpace - bannerHeight;
|
||||
|
||||
if (leftOverYSpace > 0) {
|
||||
// First figure out how much left over space is up top
|
||||
let leftOverTopSpace = leftOverYSpace / 2;
|
||||
// First figure out how much left over space is up top
|
||||
let leftOverTopSpace = leftOverYSpace / 2;
|
||||
|
||||
// Then, shift the banner into the middle of that extra space
|
||||
let yShift = Math.floor(leftOverTopSpace / 2);
|
||||
// Then, shift the banner into the middle of that extra space
|
||||
let yShift = Math.floor(leftOverTopSpace / 2);
|
||||
|
||||
bannerAllocation.y1 += yShift;
|
||||
bannerAllocation.y2 += yShift;
|
||||
bannerAllocation.y1 += yShift;
|
||||
bannerAllocation.y2 += yShift;
|
||||
} else {
|
||||
// Then figure out how much space there would be if we switched to a
|
||||
// wide layout with banner on one side and authprompt on the other.
|
||||
let leftOverXSpace = dialogWidth - authPromptWidth;
|
||||
// Then figure out how much space there would be if we switched to a
|
||||
// wide layout with banner on one side and authprompt on the other.
|
||||
let leftOverXSpace = dialogWidth - authPromptWidth;
|
||||
|
||||
// In a wide view, half of the available space goes to the banner,
|
||||
// and the other half goes to the margins.
|
||||
let wideBannerWidth = leftOverXSpace / 2;
|
||||
let wideSpacing = leftOverXSpace - wideBannerWidth;
|
||||
// In a wide view, half of the available space goes to the banner,
|
||||
// and the other half goes to the margins.
|
||||
let wideBannerWidth = leftOverXSpace / 2;
|
||||
let wideSpacing = leftOverXSpace - wideBannerWidth;
|
||||
|
||||
// If we do go with a wide layout, we need there to be at least enough
|
||||
// space for the banner and the auth prompt to be the same width,
|
||||
// so it doesn't look unbalanced.
|
||||
if (authPromptWidth > 0 && wideBannerWidth > authPromptWidth) {
|
||||
let centerX = dialogBox.x1 + dialogWidth / 2;
|
||||
let centerY = dialogBox.y1 + dialogHeight / 2;
|
||||
// If we do go with a wide layout, we need there to be at least enough
|
||||
// space for the banner and the auth prompt to be the same width,
|
||||
// so it doesn't look unbalanced.
|
||||
if (authPromptWidth > 0 && wideBannerWidth > authPromptWidth) {
|
||||
let centerX = dialogBox.x1 + dialogWidth / 2;
|
||||
let centerY = dialogBox.y1 + dialogHeight / 2;
|
||||
|
||||
// A small portion of the spacing goes down the center of the
|
||||
// screen to help delimit the two columns of the wide view
|
||||
let centerGap = wideSpacing / 8;
|
||||
// A small portion of the spacing goes down the center of the
|
||||
// screen to help delimit the two columns of the wide view
|
||||
let centerGap = wideSpacing / 8;
|
||||
|
||||
// place the banner along the left edge of the center margin
|
||||
bannerAllocation.x2 = Math.floor(centerX - centerGap / 2);
|
||||
bannerAllocation.x1 = Math.floor(bannerAllocation.x2 - wideBannerWidth);
|
||||
// place the banner along the left edge of the center margin
|
||||
bannerAllocation.x2 = Math.floor(centerX - centerGap / 2);
|
||||
bannerAllocation.x1 = Math.floor(bannerAllocation.x2 - wideBannerWidth);
|
||||
|
||||
// figure out how tall it would like to be and try to accomodate
|
||||
// but don't let it get too close to the logo
|
||||
let [wideMinHeight, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth);
|
||||
// figure out how tall it would like to be and try to accommodate
|
||||
// but don't let it get too close to the logo
|
||||
let [, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth);
|
||||
|
||||
let maxWideHeight = dialogHeight - 3 * logoHeight;
|
||||
wideBannerHeight = Math.min(maxWideHeight, wideBannerHeight);
|
||||
bannerAllocation.y1 = Math.floor(centerY - wideBannerHeight / 2);
|
||||
bannerAllocation.y2 = bannerAllocation.y1 + wideBannerHeight;
|
||||
let maxWideHeight = dialogHeight - 3 * logoHeight;
|
||||
wideBannerHeight = Math.min(maxWideHeight, wideBannerHeight);
|
||||
bannerAllocation.y1 = Math.floor(centerY - wideBannerHeight / 2);
|
||||
bannerAllocation.y2 = bannerAllocation.y1 + wideBannerHeight;
|
||||
|
||||
// place the auth prompt along the right edge of the center margin
|
||||
authPromptAllocation.x1 = Math.floor(centerX + centerGap / 2);
|
||||
authPromptAllocation.x2 = authPromptAllocation.x1 + authPromptWidth;
|
||||
} else {
|
||||
// If we aren't going to do a wide view, then we need to limit
|
||||
// the height of the banner so it will present scrollbars
|
||||
// place the auth prompt along the right edge of the center margin
|
||||
authPromptAllocation.x1 = Math.floor(centerX + centerGap / 2);
|
||||
authPromptAllocation.x2 = authPromptAllocation.x1 + authPromptWidth;
|
||||
} else {
|
||||
// If we aren't going to do a wide view, then we need to limit
|
||||
// the height of the banner so it will present scrollbars
|
||||
|
||||
// First figure out how much space there is without the banner
|
||||
leftOverYSpace += bannerHeight;
|
||||
// First figure out how much space there is without the banner
|
||||
leftOverYSpace += bannerHeight;
|
||||
|
||||
// Then figure out how much of that space is up top
|
||||
let availableTopSpace = Math.floor(leftOverYSpace / 2);
|
||||
// Then figure out how much of that space is up top
|
||||
let availableTopSpace = Math.floor(leftOverYSpace / 2);
|
||||
|
||||
// Then give all of that space to the banner
|
||||
bannerAllocation.y2 = bannerAllocation.y1 + availableTopSpace;
|
||||
}
|
||||
// Then give all of that space to the banner
|
||||
bannerAllocation.y2 = bannerAllocation.y1 + availableTopSpace;
|
||||
}
|
||||
}
|
||||
} else if (userSelectionAllocation) {
|
||||
// Grow the user list to fill the space
|
||||
@@ -719,7 +697,7 @@ var LoginDialog = new Lang.Class({
|
||||
|
||||
if (logoAllocation)
|
||||
this._logoBin.allocate(logoAllocation, flags);
|
||||
},
|
||||
}
|
||||
|
||||
_ensureUserListLoaded() {
|
||||
if (!this._userManager.is_loaded) {
|
||||
@@ -735,7 +713,7 @@ var LoginDialog = new Lang.Class({
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, this._loadUserList.bind(this));
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] _loadUserList');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_updateDisableUserList() {
|
||||
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
|
||||
@@ -750,7 +728,7 @@ var LoginDialog = new Lang.Class({
|
||||
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
this._authPrompt.reset();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_updateCancelButton() {
|
||||
let cancelVisible;
|
||||
@@ -763,7 +741,7 @@ var LoginDialog = new Lang.Class({
|
||||
cancelVisible = true;
|
||||
|
||||
this._authPrompt.cancelButton.visible = cancelVisible;
|
||||
},
|
||||
}
|
||||
|
||||
_updateBanner() {
|
||||
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
|
||||
@@ -775,41 +753,43 @@ var LoginDialog = new Lang.Class({
|
||||
} else {
|
||||
this._bannerLabel.hide();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_fadeInBannerView() {
|
||||
this._bannerView.show();
|
||||
Tweener.addTween(this._bannerView,
|
||||
{ opacity: 255,
|
||||
time: _FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
},
|
||||
this._bannerView.ease({
|
||||
opacity: 255,
|
||||
duration: _FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
});
|
||||
}
|
||||
|
||||
_hideBannerView() {
|
||||
Tweener.removeTweens(this._bannerView);
|
||||
this._bannerView.remove_all_transitions();
|
||||
this._bannerView.opacity = 0;
|
||||
this._bannerView.hide();
|
||||
},
|
||||
}
|
||||
|
||||
_updateLogoTexture(cache, file) {
|
||||
if (this._logoFile && !this._logoFile.equal(file))
|
||||
return;
|
||||
|
||||
this._logoBin.destroy_all_children();
|
||||
if (this._logoFile) {
|
||||
if (this._logoFile && this._logoBin.resource_scale > 0) {
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
|
||||
-1, _LOGO_ICON_HEIGHT,
|
||||
scaleFactor));
|
||||
scaleFactor,
|
||||
this._logoBin.resource_scale));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_updateLogo() {
|
||||
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
|
||||
|
||||
this._logoFile = path ? Gio.file_new_for_path(path) : null;
|
||||
this._updateLogoTexture(this._textureCache, this._logoFile);
|
||||
},
|
||||
}
|
||||
|
||||
_onPrompted() {
|
||||
if (this._shouldShowSessionMenuButton()) {
|
||||
@@ -819,7 +799,7 @@ var LoginDialog = new Lang.Class({
|
||||
this._sessionMenuButton.updateSensitivity(false);
|
||||
}
|
||||
this._showPrompt();
|
||||
},
|
||||
}
|
||||
|
||||
_resetGreeterProxy() {
|
||||
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
|
||||
@@ -835,7 +815,7 @@ var LoginDialog = new Lang.Class({
|
||||
this._timedLoginRequestedId = this._greeter.connect('timed-login-requested',
|
||||
this._onTimedLoginRequested.bind(this));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_onReset(authPrompt, beginRequest) {
|
||||
this._resetGreeterProxy();
|
||||
@@ -856,34 +836,35 @@ var LoginDialog = new Lang.Class({
|
||||
} else {
|
||||
this._hideUserListAndBeginVerification();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_onDefaultSessionChanged(client, sessionId) {
|
||||
this._sessionMenuButton.setActiveSession(sessionId);
|
||||
},
|
||||
}
|
||||
|
||||
_shouldShowSessionMenuButton() {
|
||||
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING &&
|
||||
this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_FAILED)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
if (this._user && this._user.is_loaded && this._user.is_logged_in())
|
||||
return false;
|
||||
return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
_showPrompt() {
|
||||
if (this._authPrompt.actor.visible)
|
||||
return;
|
||||
this._authPrompt.actor.opacity = 0;
|
||||
this._authPrompt.actor.show();
|
||||
Tweener.addTween(this._authPrompt.actor,
|
||||
{ opacity: 255,
|
||||
time: _FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
this._authPrompt.actor.ease({
|
||||
opacity: 255,
|
||||
duration: _FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD
|
||||
});
|
||||
this._fadeInBannerView();
|
||||
},
|
||||
}
|
||||
|
||||
_showRealmLoginHint(realmManager, hint) {
|
||||
if (!hint)
|
||||
@@ -896,7 +877,7 @@ var LoginDialog = new Lang.Class({
|
||||
// Translators: this message is shown below the username entry field
|
||||
// to clue the user in on how to login to the local network realm
|
||||
this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), GdmUtil.MessageType.HINT);
|
||||
},
|
||||
}
|
||||
|
||||
_askForUsernameAndBeginVerification() {
|
||||
this._authPrompt.setPasswordChar('');
|
||||
@@ -923,31 +904,34 @@ var LoginDialog = new Lang.Class({
|
||||
this._sessionMenuButton.updateSensitivity(false);
|
||||
this._authPrompt.updateSensitivity(true);
|
||||
this._showPrompt();
|
||||
},
|
||||
}
|
||||
|
||||
_bindOpacity() {
|
||||
this._bindings = Main.layoutManager.uiGroup.get_children()
|
||||
.filter(c => c != Main.layoutManager.screenShieldGroup)
|
||||
.map(c => this.bind_property('opacity', c, 'opacity', 0));
|
||||
}
|
||||
|
||||
_unbindOpacity() {
|
||||
this._bindings.forEach(b => b.unbind());
|
||||
}
|
||||
|
||||
_loginScreenSessionActivated() {
|
||||
if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
return;
|
||||
|
||||
Tweener.addTween(this,
|
||||
{ opacity: 255,
|
||||
time: _FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onUpdate() {
|
||||
let children = Main.layoutManager.uiGroup.get_children();
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (children[i] != Main.layoutManager.screenShieldGroup)
|
||||
children[i].opacity = this.opacity;
|
||||
}
|
||||
},
|
||||
onUpdateScope: this,
|
||||
onComplete() {
|
||||
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
this._authPrompt.reset();
|
||||
},
|
||||
onCompleteScope: this });
|
||||
},
|
||||
this._bindOpacity();
|
||||
this.actor.ease({
|
||||
opacity: 255,
|
||||
duration: _FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
this._authPrompt.reset();
|
||||
this._unbindOpacity();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_gotGreeterSessionProxy(proxy) {
|
||||
this._greeterSessionProxy = proxy;
|
||||
@@ -956,37 +940,30 @@ var LoginDialog = new Lang.Class({
|
||||
if (proxy.Active)
|
||||
this._loginScreenSessionActivated();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_startSession(serviceName) {
|
||||
Tweener.addTween(this,
|
||||
{ opacity: 0,
|
||||
time: _FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onUpdate() {
|
||||
let children = Main.layoutManager.uiGroup.get_children();
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (children[i] != Main.layoutManager.screenShieldGroup)
|
||||
children[i].opacity = this.opacity;
|
||||
}
|
||||
},
|
||||
onUpdateScope: this,
|
||||
onComplete() {
|
||||
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
|
||||
},
|
||||
onCompleteScope: this });
|
||||
},
|
||||
this._bindOpacity();
|
||||
this.actor.ease({
|
||||
opacity: 0,
|
||||
duration: _FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
|
||||
this._unbindOpacity();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_onSessionOpened(client, serviceName) {
|
||||
this._authPrompt.finish(() => { this._startSession(serviceName); });
|
||||
},
|
||||
this._authPrompt.finish(() => this._startSession(serviceName));
|
||||
}
|
||||
|
||||
_waitForItemForUser(userName) {
|
||||
let item = this._userList.getItemFromUserName(userName);
|
||||
|
||||
if (item)
|
||||
return null;
|
||||
return null;
|
||||
|
||||
let hold = new Batch.Hold();
|
||||
let signalId = this._userList.connect('item-added',
|
||||
@@ -997,10 +974,10 @@ var LoginDialog = new Lang.Class({
|
||||
hold.release();
|
||||
});
|
||||
|
||||
hold.connect('release', () => { this._userList.disconnect(signalId); });
|
||||
hold.connect('release', () => this._userList.disconnect(signalId));
|
||||
|
||||
return hold;
|
||||
},
|
||||
}
|
||||
|
||||
_blockTimedLoginUntilIdle() {
|
||||
let hold = new Batch.Hold();
|
||||
@@ -1013,7 +990,7 @@ var LoginDialog = new Lang.Class({
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginIdleTimeOutId');
|
||||
return hold;
|
||||
},
|
||||
}
|
||||
|
||||
_startTimedLogin(userName, delay) {
|
||||
let firstRun = true;
|
||||
@@ -1061,6 +1038,7 @@ var LoginDialog = new Lang.Class({
|
||||
return this._blockTimedLoginUntilIdle();
|
||||
} else {
|
||||
animationTime = delay;
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1086,7 +1064,7 @@ var LoginDialog = new Lang.Class({
|
||||
this._timedLoginBatch = new Batch.ConsecutiveBatch(this, tasks);
|
||||
|
||||
return this._timedLoginBatch.run();
|
||||
},
|
||||
}
|
||||
|
||||
_onTimedLoginRequested(client, userName, seconds) {
|
||||
if (this._timedLoginBatch)
|
||||
@@ -1096,35 +1074,35 @@ var LoginDialog = new Lang.Class({
|
||||
|
||||
// Restart timed login on user interaction
|
||||
global.stage.connect('captured-event', (actor, event) => {
|
||||
if (event.type() == Clutter.EventType.KEY_PRESS ||
|
||||
if (event.type() == Clutter.EventType.KEY_PRESS ||
|
||||
event.type() == Clutter.EventType.BUTTON_PRESS) {
|
||||
this._startTimedLogin(userName, seconds);
|
||||
}
|
||||
this._startTimedLogin(userName, seconds);
|
||||
}
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_setUserListExpanded(expanded) {
|
||||
this._userList.updateStyle(expanded);
|
||||
this._userSelectionBox.visible = expanded;
|
||||
},
|
||||
}
|
||||
|
||||
_hideUserList() {
|
||||
this._setUserListExpanded(false);
|
||||
if (this._userSelectionBox.visible)
|
||||
GdmUtil.cloneAndFadeOutActor(this._userSelectionBox);
|
||||
},
|
||||
}
|
||||
|
||||
_hideUserListAskForUsernameAndBeginVerification() {
|
||||
this._hideUserList();
|
||||
this._askForUsernameAndBeginVerification();
|
||||
},
|
||||
}
|
||||
|
||||
_hideUserListAndBeginVerification() {
|
||||
this._hideUserList();
|
||||
this._authPrompt.begin();
|
||||
},
|
||||
}
|
||||
|
||||
_showUserList() {
|
||||
this._ensureUserListLoaded();
|
||||
@@ -1134,7 +1112,7 @@ var LoginDialog = new Lang.Class({
|
||||
this._setUserListExpanded(true);
|
||||
this._notListedButton.show();
|
||||
this._userList.actor.grab_key_focus();
|
||||
},
|
||||
}
|
||||
|
||||
_beginVerificationForItem(item) {
|
||||
this._authPrompt.setUser(item.user);
|
||||
@@ -1145,7 +1123,7 @@ var LoginDialog = new Lang.Class({
|
||||
this._authPrompt.begin({ userName: userName,
|
||||
hold: hold });
|
||||
return hold;
|
||||
},
|
||||
}
|
||||
|
||||
_onUserListActivated(activatedItem) {
|
||||
this._user = activatedItem.user;
|
||||
@@ -1155,7 +1133,7 @@ var LoginDialog = new Lang.Class({
|
||||
let batch = new Batch.ConcurrentBatch(this, [GdmUtil.cloneAndFadeOutActor(this._userSelectionBox),
|
||||
this._beginVerificationForItem(activatedItem)]);
|
||||
batch.run();
|
||||
},
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (this._userManagerLoadedId) {
|
||||
@@ -1196,7 +1174,7 @@ var LoginDialog = new Lang.Class({
|
||||
this._realmManager.release();
|
||||
this._realmManager = null;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_loadUserList() {
|
||||
if (this._userListLoaded)
|
||||
@@ -1234,7 +1212,7 @@ var LoginDialog = new Lang.Class({
|
||||
});
|
||||
|
||||
return GLib.SOURCE_REMOVE;
|
||||
},
|
||||
}
|
||||
|
||||
open() {
|
||||
Main.ctrlAltTabManager.addGroup(this,
|
||||
@@ -1247,28 +1225,29 @@ var LoginDialog = new Lang.Class({
|
||||
|
||||
Main.pushModal(this, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
|
||||
|
||||
Tweener.addTween(this,
|
||||
{ opacity: 255,
|
||||
time: 1,
|
||||
transition: 'easeInQuad' });
|
||||
this.ease({
|
||||
opacity: 255,
|
||||
duration: 1000,
|
||||
mode: Clutter.AnimationMode.EASE_IN_QUAD
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
close() {
|
||||
Main.popModal(this);
|
||||
Main.ctrlAltTabManager.removeGroup(this);
|
||||
},
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this._authPrompt.cancel();
|
||||
},
|
||||
}
|
||||
|
||||
addCharacter(unichar) {
|
||||
addCharacter(_unichar) {
|
||||
// Don't allow type ahead at the login screen
|
||||
},
|
||||
}
|
||||
|
||||
finish(onComplete) {
|
||||
this._authPrompt.finish(onComplete);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getOVirtCredentialsManager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const OVirtCredentialsIface = `
|
||||
@@ -28,33 +28,32 @@ function OVirtCredentials() {
|
||||
return self;
|
||||
}
|
||||
|
||||
var OVirtCredentialsManager = new Lang.Class({
|
||||
Name: 'OVirtCredentialsManager',
|
||||
_init() {
|
||||
var OVirtCredentialsManager = class {
|
||||
constructor() {
|
||||
this._token = null;
|
||||
|
||||
this._credentials = new OVirtCredentials();
|
||||
this._credentials.connectSignal('UserAuthenticated',
|
||||
this._onUserAuthenticated.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_onUserAuthenticated(proxy, sender, [token]) {
|
||||
this._token = token;
|
||||
this.emit('user-authenticated', token);
|
||||
},
|
||||
}
|
||||
|
||||
hasToken() {
|
||||
return this._token != null;
|
||||
},
|
||||
}
|
||||
|
||||
getToken() {
|
||||
return this._token;
|
||||
},
|
||||
}
|
||||
|
||||
resetToken() {
|
||||
this._token = null;
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(OVirtCredentialsManager.prototype);
|
||||
|
||||
function getOVirtCredentialsManager() {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// -*- 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 { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
@@ -16,14 +14,12 @@ const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
|
||||
const RealmIface = loadInterfaceXML("org.freedesktop.realmd.Realm");
|
||||
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
|
||||
|
||||
var Manager = new Lang.Class({
|
||||
Name: 'Manager',
|
||||
|
||||
_init(parentActor) {
|
||||
var Manager = class {
|
||||
constructor() {
|
||||
this._aggregateProvider = Provider(Gio.DBus.system,
|
||||
'org.freedesktop.realmd',
|
||||
'/org/freedesktop/realmd',
|
||||
this._reloadRealms.bind(this))
|
||||
this._reloadRealms.bind(this));
|
||||
this._realms = {};
|
||||
|
||||
this._signalId = this._aggregateProvider.connect('g-properties-changed',
|
||||
@@ -31,7 +27,7 @@ var Manager = new Lang.Class({
|
||||
if ('Realms' in properties.deep_unpack())
|
||||
this._reloadRealms();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_reloadRealms() {
|
||||
let realmPaths = this._aggregateProvider.Realms;
|
||||
@@ -40,12 +36,12 @@ var Manager = new Lang.Class({
|
||||
return;
|
||||
|
||||
for (let i = 0; i < realmPaths.length; i++) {
|
||||
let realm = Realm(Gio.DBus.system,
|
||||
'org.freedesktop.realmd',
|
||||
realmPaths[i],
|
||||
this._onRealmLoaded.bind(this));
|
||||
Realm(Gio.DBus.system,
|
||||
'org.freedesktop.realmd',
|
||||
realmPaths[i],
|
||||
this._onRealmLoaded.bind(this));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_reloadRealm(realm) {
|
||||
if (!realm.Configured) {
|
||||
@@ -58,7 +54,7 @@ var Manager = new Lang.Class({
|
||||
this._realms[realm.get_object_path()] = realm;
|
||||
|
||||
this._updateLoginFormat();
|
||||
},
|
||||
}
|
||||
|
||||
_onRealmLoaded(realm, error) {
|
||||
if (error)
|
||||
@@ -70,7 +66,7 @@ var Manager = new Lang.Class({
|
||||
if ('Configured' in properties.deep_unpack())
|
||||
this._reloadRealm(realm);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_updateLoginFormat() {
|
||||
let newLoginFormat;
|
||||
@@ -87,7 +83,7 @@ var Manager = new Lang.Class({
|
||||
this._loginFormat = newLoginFormat;
|
||||
this.emit('login-format-changed', newLoginFormat);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
get loginFormat() {
|
||||
if (this._loginFormat !== undefined)
|
||||
@@ -96,16 +92,16 @@ var Manager = new Lang.Class({
|
||||
this._updateLoginFormat();
|
||||
|
||||
return this._loginFormat;
|
||||
},
|
||||
}
|
||||
|
||||
release() {
|
||||
Service(Gio.DBus.system,
|
||||
'org.freedesktop.realmd',
|
||||
'/org/freedesktop/realmd',
|
||||
service => { service.ReleaseRemote(); });
|
||||
service => service.ReleaseRemote());
|
||||
this._aggregateProvider.disconnect(this._signalId);
|
||||
this._realms = { };
|
||||
this._updateLoginFormat();
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(Manager.prototype)
|
||||
};
|
||||
Signals.addSignalMethods(Manager.prototype);
|
||||
|
||||
212
js/gdm/util.js
@@ -1,28 +1,23 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported BANNER_MESSAGE_KEY, BANNER_MESSAGE_TEXT_KEY, LOGO_KEY,
|
||||
DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const { Clutter, Gio, GLib } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Batch = imports.gdm.batch;
|
||||
const Fprint = imports.gdm.fingerprint;
|
||||
const OVirt = imports.gdm.oVirt;
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const SmartcardManager = imports.misc.smartcardManager;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
var PASSWORD_SERVICE_NAME = 'gdm-password';
|
||||
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
||||
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
|
||||
var OVIRT_SERVICE_NAME = 'gdm-ovirtcred';
|
||||
var FADE_ANIMATION_TIME = 0.16;
|
||||
var CLONE_FADE_ANIMATION_TIME = 0.25;
|
||||
var FADE_ANIMATION_TIME = 160;
|
||||
var CLONE_FADE_ANIMATION_TIME = 250;
|
||||
|
||||
var LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
|
||||
var PASSWORD_AUTHENTICATION_KEY = 'enable-password-authentication';
|
||||
@@ -36,7 +31,7 @@ var LOGO_KEY = 'logo';
|
||||
var DISABLE_USER_LIST_KEY = 'disable-user-list';
|
||||
|
||||
// Give user 48ms to read each character of a PAM message
|
||||
var USER_READ_TIME = 48
|
||||
var USER_READ_TIME = 48;
|
||||
|
||||
var MessageType = {
|
||||
NONE: 0,
|
||||
@@ -51,20 +46,20 @@ function fadeInActor(actor) {
|
||||
|
||||
let hold = new Batch.Hold();
|
||||
actor.show();
|
||||
let [minHeight, naturalHeight] = actor.get_preferred_height(-1);
|
||||
let [, naturalHeight] = actor.get_preferred_height(-1);
|
||||
|
||||
actor.opacity = 0;
|
||||
actor.set_height(0);
|
||||
Tweener.addTween(actor,
|
||||
{ opacity: 255,
|
||||
height: naturalHeight,
|
||||
time: FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete() {
|
||||
this.set_height(-1);
|
||||
hold.release();
|
||||
},
|
||||
});
|
||||
actor.ease({
|
||||
opacity: 255,
|
||||
height: naturalHeight,
|
||||
duration: FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
this.set_height(-1);
|
||||
hold.release();
|
||||
}
|
||||
});
|
||||
|
||||
return hold;
|
||||
}
|
||||
@@ -77,17 +72,17 @@ function fadeOutActor(actor) {
|
||||
}
|
||||
|
||||
let hold = new Batch.Hold();
|
||||
Tweener.addTween(actor,
|
||||
{ opacity: 0,
|
||||
height: 0,
|
||||
time: FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete() {
|
||||
this.hide();
|
||||
this.set_height(-1);
|
||||
hold.release();
|
||||
},
|
||||
});
|
||||
actor.ease({
|
||||
opacity: 0,
|
||||
height: 0,
|
||||
duration: FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
this.hide();
|
||||
this.set_height(-1);
|
||||
hold.release();
|
||||
}
|
||||
});
|
||||
return hold;
|
||||
}
|
||||
|
||||
@@ -107,22 +102,20 @@ function cloneAndFadeOutActor(actor) {
|
||||
clone.set_position(x, y);
|
||||
|
||||
let hold = new Batch.Hold();
|
||||
Tweener.addTween(clone,
|
||||
{ opacity: 0,
|
||||
time: CLONE_FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete() {
|
||||
clone.destroy();
|
||||
hold.release();
|
||||
}
|
||||
});
|
||||
clone.ease({
|
||||
opacity: 0,
|
||||
duration: CLONE_FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
clone.destroy();
|
||||
hold.release();
|
||||
}
|
||||
});
|
||||
return hold;
|
||||
}
|
||||
|
||||
var ShellUserVerifier = new Lang.Class({
|
||||
Name: 'ShellUserVerifier',
|
||||
|
||||
_init(client, params) {
|
||||
var ShellUserVerifier = class {
|
||||
constructor(client, params) {
|
||||
params = Params.parse(params, { reauthenticationOnly: false });
|
||||
this._reauthOnly = params.reauthenticationOnly;
|
||||
|
||||
@@ -165,7 +158,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this._oVirtUserAuthenticatedId = this._oVirtCredentialsManager.connect('user-authenticated',
|
||||
this._oVirtUserAuthenticated.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
begin(userName, hold) {
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
@@ -183,7 +176,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
} else {
|
||||
this._client.get_user_verifier(this._cancellable, this._userVerifierGot.bind(this));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cancel() {
|
||||
if (this._cancellable)
|
||||
@@ -193,14 +186,14 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._userVerifier.call_cancel_sync(null);
|
||||
this.clear();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_clearUserVerifier() {
|
||||
if (this._userVerifier) {
|
||||
this._userVerifier.run_dispose();
|
||||
this._userVerifier = null;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
clear() {
|
||||
if (this._cancellable) {
|
||||
@@ -210,7 +203,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this._clearUserVerifier();
|
||||
this._clearMessageQueue();
|
||||
},
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.clear();
|
||||
@@ -224,7 +217,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this._oVirtCredentialsManager.disconnect(this._oVirtUserAuthenticatedId);
|
||||
this._oVirtCredentialsManager = null;
|
||||
},
|
||||
}
|
||||
|
||||
answerQuery(serviceName, answer) {
|
||||
if (!this.hasPendingMessages) {
|
||||
@@ -235,12 +228,12 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_getIntervalForMessage(message) {
|
||||
// We probably could be smarter here
|
||||
return message.length * USER_READ_TIME;
|
||||
},
|
||||
}
|
||||
|
||||
finishMessageQueue() {
|
||||
if (!this.hasPendingMessages)
|
||||
@@ -250,7 +243,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this.hasPendingMessages = false;
|
||||
this.emit('no-more-messages');
|
||||
},
|
||||
}
|
||||
|
||||
_queueMessageTimeout() {
|
||||
if (this._messageQueue.length == 0) {
|
||||
@@ -273,7 +266,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._messageQueueTimeoutId, '[gnome-shell] this._queueMessageTimeout');
|
||||
},
|
||||
}
|
||||
|
||||
_queueMessage(message, messageType) {
|
||||
let interval = this._getIntervalForMessage(message);
|
||||
@@ -281,7 +274,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this.hasPendingMessages = true;
|
||||
this._messageQueue.push({ text: message, type: messageType, interval: interval });
|
||||
this._queueMessageTimeout();
|
||||
},
|
||||
}
|
||||
|
||||
_clearMessageQueue() {
|
||||
this.finishMessageQueue();
|
||||
@@ -291,7 +284,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._messageQueueTimeoutId = 0;
|
||||
}
|
||||
this.emit('show-message', null, MessageType.NONE);
|
||||
},
|
||||
}
|
||||
|
||||
_checkForFingerprintReader() {
|
||||
this._haveFingerprintReader = false;
|
||||
@@ -309,12 +302,12 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._updateDefaultService();
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_oVirtUserAuthenticated(token) {
|
||||
_oVirtUserAuthenticated(_token) {
|
||||
this._preemptingService = OVIRT_SERVICE_NAME;
|
||||
this.emit('ovirt-user-authenticated');
|
||||
},
|
||||
}
|
||||
|
||||
_checkForSmartcard() {
|
||||
let smartcardDetected;
|
||||
@@ -336,7 +329,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this.emit('smartcard-status-changed');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_reportInitError(where, error) {
|
||||
logError(error, where);
|
||||
@@ -344,13 +337,13 @@ var ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this._queueMessage(_("Authentication error"), MessageType.ERROR);
|
||||
this._verificationFailed(false);
|
||||
},
|
||||
}
|
||||
|
||||
_reauthenticationChannelOpened(client, result) {
|
||||
try {
|
||||
this._clearUserVerifier();
|
||||
this._userVerifier = client.open_reauthentication_channel_finish(result);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
if (e.matches(Gio.DBusError, Gio.DBusError.ACCESS_DENIED) &&
|
||||
@@ -371,13 +364,13 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._connectSignals();
|
||||
this._beginVerification();
|
||||
this._hold.release();
|
||||
},
|
||||
}
|
||||
|
||||
_userVerifierGot(client, result) {
|
||||
try {
|
||||
this._clearUserVerifier();
|
||||
this._userVerifier = client.get_user_verifier_finish(result);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
this._reportInitError('Failed to obtain user verifier', e);
|
||||
@@ -387,7 +380,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._connectSignals();
|
||||
this._beginVerification();
|
||||
this._hold.release();
|
||||
},
|
||||
}
|
||||
|
||||
_connectSignals() {
|
||||
this._userVerifier.connect('info', this._onInfo.bind(this));
|
||||
@@ -397,22 +390,22 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this));
|
||||
this._userVerifier.connect('reset', this._onReset.bind(this));
|
||||
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_getForegroundService() {
|
||||
if (this._preemptingService)
|
||||
return this._preemptingService;
|
||||
|
||||
return this._defaultService;
|
||||
},
|
||||
}
|
||||
|
||||
serviceIsForeground(serviceName) {
|
||||
return serviceName == this._getForegroundService();
|
||||
},
|
||||
}
|
||||
|
||||
serviceIsDefault(serviceName) {
|
||||
return serviceName == this._defaultService;
|
||||
},
|
||||
}
|
||||
|
||||
_updateDefaultService() {
|
||||
if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
|
||||
@@ -426,50 +419,45 @@ var ShellUserVerifier = new Lang.Class({
|
||||
log("no authentication service is enabled, using password authentication");
|
||||
this._defaultService = PASSWORD_SERVICE_NAME;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_startService(serviceName) {
|
||||
this._hold.acquire();
|
||||
if (this._userName) {
|
||||
this._userVerifier.call_begin_verification_for_user(serviceName,
|
||||
this._userName,
|
||||
this._cancellable,
|
||||
(obj, result) => {
|
||||
try {
|
||||
obj.call_begin_verification_for_user_finish(result);
|
||||
} catch(e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
this._reportInitError('Failed to start verification for user', e);
|
||||
return;
|
||||
}
|
||||
this._userVerifier.call_begin_verification_for_user(serviceName, this._userName, this._cancellable, (obj, result) => {
|
||||
try {
|
||||
obj.call_begin_verification_for_user_finish(result);
|
||||
} catch (e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
this._reportInitError('Failed to start verification for user', e);
|
||||
return;
|
||||
}
|
||||
|
||||
this._hold.release();
|
||||
});
|
||||
this._hold.release();
|
||||
});
|
||||
} else {
|
||||
this._userVerifier.call_begin_verification(serviceName,
|
||||
this._cancellable,
|
||||
(obj, result) => {
|
||||
try {
|
||||
obj.call_begin_verification_finish(result);
|
||||
} catch(e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
this._reportInitError('Failed to start verification', e);
|
||||
return;
|
||||
}
|
||||
this._userVerifier.call_begin_verification(serviceName, this._cancellable, (obj, result) => {
|
||||
try {
|
||||
obj.call_begin_verification_finish(result);
|
||||
} catch (e) {
|
||||
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
|
||||
return;
|
||||
this._reportInitError('Failed to start verification', e);
|
||||
return;
|
||||
}
|
||||
|
||||
this._hold.release();
|
||||
});
|
||||
this._hold.release();
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_beginVerification() {
|
||||
this._startService(this._getForegroundService());
|
||||
|
||||
if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME))
|
||||
this._startService(FINGERPRINT_SERVICE_NAME);
|
||||
},
|
||||
}
|
||||
|
||||
_onInfo(client, serviceName, info) {
|
||||
if (this.serviceIsForeground(serviceName)) {
|
||||
@@ -484,21 +472,21 @@ var ShellUserVerifier = new Lang.Class({
|
||||
// to indicate the user can swipe their finger instead
|
||||
this._queueMessage(_("(or swipe finger)"), MessageType.HINT);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_onProblem(client, serviceName, problem) {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
return;
|
||||
|
||||
this._queueMessage(problem, MessageType.ERROR);
|
||||
},
|
||||
}
|
||||
|
||||
_onInfoQuery(client, serviceName, question) {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
return;
|
||||
|
||||
this.emit('ask-question', serviceName, question, '');
|
||||
},
|
||||
}
|
||||
|
||||
_onSecretInfoQuery(client, serviceName, secretQuestion) {
|
||||
if (!this.serviceIsForeground(serviceName))
|
||||
@@ -511,7 +499,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
}
|
||||
|
||||
this.emit('ask-question', serviceName, secretQuestion, '\u25cf');
|
||||
},
|
||||
}
|
||||
|
||||
_onReset() {
|
||||
// Clear previous attempts to authenticate
|
||||
@@ -519,20 +507,20 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._updateDefaultService();
|
||||
|
||||
this.emit('reset');
|
||||
},
|
||||
}
|
||||
|
||||
_onVerificationComplete() {
|
||||
this.emit('verification-complete');
|
||||
},
|
||||
}
|
||||
|
||||
_cancelAndReset() {
|
||||
this.cancel();
|
||||
this._onReset();
|
||||
},
|
||||
}
|
||||
|
||||
_retry() {
|
||||
this.begin(this._userName, new Batch.Hold());
|
||||
},
|
||||
}
|
||||
|
||||
_verificationFailed(retry) {
|
||||
// For Not Listed / enterprise logins, immediately reset
|
||||
@@ -567,7 +555,7 @@ var ShellUserVerifier = new Lang.Class({
|
||||
}
|
||||
|
||||
this.emit('verification-failed', canRetry);
|
||||
},
|
||||
}
|
||||
|
||||
_onConversationStopped(client, serviceName) {
|
||||
// If the login failed with the preauthenticated oVirt credentials
|
||||
@@ -586,6 +574,6 @@ var ShellUserVerifier = new Lang.Class({
|
||||
if (this.serviceIsForeground(serviceName)) {
|
||||
this._verificationFailed(true);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ShellUserVerifier.prototype);
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
<file>ui/keyboard.js</file>
|
||||
<file>ui/layout.js</file>
|
||||
<file>ui/lightbox.js</file>
|
||||
<file>ui/locatePointer.js</file>
|
||||
<file>ui/lookingGlass.js</file>
|
||||
<file>ui/magnifier.js</file>
|
||||
<file>ui/magnifierDBus.js</file>
|
||||
@@ -78,12 +79,14 @@
|
||||
<file>ui/overview.js</file>
|
||||
<file>ui/overviewControls.js</file>
|
||||
<file>ui/padOsd.js</file>
|
||||
<file>ui/pageIndicators.js</file>
|
||||
<file>ui/panel.js</file>
|
||||
<file>ui/panelMenu.js</file>
|
||||
<file>ui/pointerA11yTimeout.js</file>
|
||||
<file>ui/pointerWatcher.js</file>
|
||||
<file>ui/popupMenu.js</file>
|
||||
<file>ui/remoteMenu.js</file>
|
||||
<file>ui/remoteSearch.js</file>
|
||||
<file>ui/ripples.js</file>
|
||||
<file>ui/runDialog.js</file>
|
||||
<file>ui/screenShield.js</file>
|
||||
<file>ui/screencast.js</file>
|
||||
@@ -120,6 +123,7 @@
|
||||
|
||||
<file>ui/status/accessibility.js</file>
|
||||
<file>ui/status/brightness.js</file>
|
||||
<file>ui/status/dwellClick.js</file>
|
||||
<file>ui/status/location.js</file>
|
||||
<file>ui/status/keyboard.js</file>
|
||||
<file>ui/status/nightLight.js</file>
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported ExtensionState, ExtensionType, getCurrentExtension,
|
||||
getSettings, initTranslations, isOutOfDate, installImporter,
|
||||
serializeExtension, deserializeExtension */
|
||||
|
||||
// Common utils for the extension system and the extension
|
||||
// preferences tool
|
||||
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
const { Gio, GLib } = imports.gi;
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gettext = imports.gettext;
|
||||
const Lang = imports.lang;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const FileUtils = imports.misc.fileUtils;
|
||||
|
||||
var ExtensionType = {
|
||||
SYSTEM: 1,
|
||||
PER_USER: 2
|
||||
};
|
||||
|
||||
// Maps uuid -> metadata object
|
||||
var extensions = {};
|
||||
var ExtensionState = {
|
||||
ENABLED: 1,
|
||||
DISABLED: 2,
|
||||
ERROR: 3,
|
||||
OUT_OF_DATE: 4,
|
||||
DOWNLOADING: 5,
|
||||
INITIALIZED: 6,
|
||||
|
||||
// Used as an error state for operations on unknown extensions,
|
||||
// should never be in a real extensionMeta object.
|
||||
UNINSTALLED: 99
|
||||
};
|
||||
|
||||
const SERIALIZED_PROPERTIES = ['type', 'state', 'path', 'error', 'hasPrefs', 'canChange', 'isRequested'];
|
||||
|
||||
/**
|
||||
* getCurrentExtension:
|
||||
@@ -31,7 +45,7 @@ function getCurrentExtension() {
|
||||
// Search for an occurrence of an extension stack frame
|
||||
// Start at 1 because 0 is the stack frame of this function
|
||||
for (let i = 1; i < stack.length; i++) {
|
||||
if (stack[i].indexOf('/gnome-shell/extensions/') > -1) {
|
||||
if (stack[i].includes('/gnome-shell/extensions/')) {
|
||||
extensionStackLine = stack[i];
|
||||
break;
|
||||
}
|
||||
@@ -49,13 +63,17 @@ function getCurrentExtension() {
|
||||
if (!match)
|
||||
return null;
|
||||
|
||||
// local import, as the module is used from outside the gnome-shell process
|
||||
// as well (not this function though)
|
||||
let extensionManager = imports.ui.main.extensionManager;
|
||||
|
||||
let path = match[1];
|
||||
let file = Gio.File.new_for_path(path);
|
||||
|
||||
// Walk up the directory tree, looking for an extension with
|
||||
// the same UUID as a directory name.
|
||||
while (file != null) {
|
||||
let extension = extensions[file.get_basename()];
|
||||
let extension = extensionManager.lookup(file.get_basename());
|
||||
if (extension !== undefined)
|
||||
return extension;
|
||||
file = file.get_parent();
|
||||
@@ -64,6 +82,66 @@ function getCurrentExtension() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* initTranslations:
|
||||
* @domain: (optional): the gettext domain to use
|
||||
*
|
||||
* Initialize Gettext to load translations from extensionsdir/locale.
|
||||
* If @domain is not provided, it will be taken from metadata['gettext-domain']
|
||||
*/
|
||||
function initTranslations(domain) {
|
||||
let extension = getCurrentExtension();
|
||||
|
||||
if (!extension)
|
||||
throw new Error('initTranslations() can only be called from extensions');
|
||||
|
||||
domain = domain || extension.metadata['gettext-domain'];
|
||||
|
||||
// Expect USER extensions to have a locale/ subfolder, otherwise assume a
|
||||
// SYSTEM extension that has been installed in the same prefix as the shell
|
||||
let localeDir = extension.dir.get_child('locale');
|
||||
if (localeDir.query_exists(null))
|
||||
Gettext.bindtextdomain(domain, localeDir.get_path());
|
||||
else
|
||||
Gettext.bindtextdomain(domain, Config.LOCALEDIR);
|
||||
}
|
||||
|
||||
/**
|
||||
* getSettings:
|
||||
* @schema: (optional): the GSettings schema id
|
||||
*
|
||||
* Builds and returns a GSettings schema for @schema, using schema files
|
||||
* in extensionsdir/schemas. If @schema is omitted, it is taken from
|
||||
* metadata['settings-schema'].
|
||||
*/
|
||||
function getSettings(schema) {
|
||||
let extension = getCurrentExtension();
|
||||
|
||||
if (!extension)
|
||||
throw new Error('getSettings() can only be called from extensions');
|
||||
|
||||
schema = schema || extension.metadata['settings-schema'];
|
||||
|
||||
const GioSSS = Gio.SettingsSchemaSource;
|
||||
|
||||
// Expect USER extensions to have a schemas/ subfolder, otherwise assume a
|
||||
// SYSTEM extension that has been installed in the same prefix as the shell
|
||||
let schemaDir = extension.dir.get_child('schemas');
|
||||
let schemaSource;
|
||||
if (schemaDir.query_exists(null))
|
||||
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
|
||||
GioSSS.get_default(),
|
||||
false);
|
||||
else
|
||||
schemaSource = GioSSS.get_default();
|
||||
|
||||
let schemaObj = schemaSource.lookup(schema, true);
|
||||
if (!schemaObj)
|
||||
throw new Error(`Schema ${schema} could not be found for extension ${extension.metadata.uuid}. Please check your installation`);
|
||||
|
||||
return new Gio.Settings({ settings_schema: schemaObj });
|
||||
}
|
||||
|
||||
/**
|
||||
* versionCheck:
|
||||
* @required: an array of versions we're compatible with
|
||||
@@ -101,54 +179,50 @@ function isOutOfDate(extension) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function createExtensionObject(uuid, dir, type) {
|
||||
let info;
|
||||
function serializeExtension(extension) {
|
||||
let obj = {};
|
||||
Lang.copyProperties(extension.metadata, obj);
|
||||
|
||||
let metadataFile = dir.get_child('metadata.json');
|
||||
if (!metadataFile.query_exists(null)) {
|
||||
throw new Error('Missing metadata.json');
|
||||
}
|
||||
SERIALIZED_PROPERTIES.forEach(prop => {
|
||||
obj[prop] = extension[prop];
|
||||
});
|
||||
|
||||
let metadataContents, success, tag;
|
||||
try {
|
||||
[success, metadataContents, tag] = metadataFile.load_contents(null);
|
||||
if (metadataContents instanceof Uint8Array)
|
||||
metadataContents = imports.byteArray.toString(metadataContents);
|
||||
} catch (e) {
|
||||
throw new Error('Failed to load metadata.json: ' + e);
|
||||
}
|
||||
let meta;
|
||||
try {
|
||||
meta = JSON.parse(metadataContents);
|
||||
} catch (e) {
|
||||
throw new Error('Failed to parse metadata.json: ' + e);
|
||||
}
|
||||
|
||||
let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
|
||||
for (let i = 0; i < requiredProperties.length; i++) {
|
||||
let prop = requiredProperties[i];
|
||||
if (!meta[prop]) {
|
||||
throw new Error('missing "' + prop + '" property in metadata.json');
|
||||
let res = {};
|
||||
for (let key in obj) {
|
||||
let val = obj[key];
|
||||
let type;
|
||||
switch (typeof val) {
|
||||
case 'string':
|
||||
type = 's';
|
||||
break;
|
||||
case 'number':
|
||||
type = 'd';
|
||||
break;
|
||||
case 'boolean':
|
||||
type = 'b';
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
res[key] = GLib.Variant.new(type, val);
|
||||
}
|
||||
|
||||
if (uuid != meta.uuid) {
|
||||
throw new Error('uuid "' + meta.uuid + '" from metadata.json does not match directory name "' + uuid + '"');
|
||||
return res;
|
||||
}
|
||||
|
||||
function deserializeExtension(variant) {
|
||||
let res = { metadata: {} };
|
||||
for (let prop in variant) {
|
||||
let val = variant[prop].unpack();
|
||||
if (SERIALIZED_PROPERTIES.includes(prop))
|
||||
res[prop] = val;
|
||||
else
|
||||
res.metadata[prop] = val;
|
||||
}
|
||||
|
||||
let extension = {};
|
||||
|
||||
extension.metadata = meta;
|
||||
extension.uuid = meta.uuid;
|
||||
extension.type = type;
|
||||
extension.dir = dir;
|
||||
extension.path = dir.get_path();
|
||||
extension.error = '';
|
||||
extension.hasPrefs = dir.get_child('prefs.js').query_exists(null);
|
||||
|
||||
extensions[uuid] = extension;
|
||||
|
||||
return extension;
|
||||
// add the 2 additional properties to create a valid extension object, as createExtensionObject()
|
||||
res.uuid = res.metadata.uuid;
|
||||
res.dir = Gio.File.new_for_path(res.path);
|
||||
return res;
|
||||
}
|
||||
|
||||
function installImporter(extension) {
|
||||
@@ -159,38 +233,3 @@ function installImporter(extension) {
|
||||
extension.imports = imports[extension.uuid];
|
||||
imports.searchPath = oldSearchPath;
|
||||
}
|
||||
|
||||
var ExtensionFinder = new Lang.Class({
|
||||
Name: 'ExtensionFinder',
|
||||
|
||||
_loadExtension(extensionDir, info, perUserDir) {
|
||||
let fileType = info.get_file_type();
|
||||
if (fileType != Gio.FileType.DIRECTORY)
|
||||
return;
|
||||
let uuid = info.get_name();
|
||||
let existing = extensions[uuid];
|
||||
if (existing) {
|
||||
log('Extension %s already installed in %s. %s will not be loaded'.format(uuid, existing.path, extensionDir.get_path()));
|
||||
return;
|
||||
}
|
||||
|
||||
let extension;
|
||||
let type = extensionDir.has_prefix(perUserDir) ? ExtensionType.PER_USER
|
||||
: ExtensionType.SYSTEM;
|
||||
try {
|
||||
extension = createExtensionObject(uuid, extensionDir, type);
|
||||
} catch(e) {
|
||||
logError(e, 'Could not load extension %s'.format(uuid));
|
||||
return;
|
||||
}
|
||||
this.emit('extension-found', extension);
|
||||
},
|
||||
|
||||
scanExtensions() {
|
||||
let perUserDir = Gio.File.new_for_path(global.userdatadir);
|
||||
FileUtils.collectFromDatadirs('extensions', true, (dir, info) => {
|
||||
this._loadExtension(dir, info, perUserDir);
|
||||
});
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ExtensionFinder.prototype);
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported collectFromDatadirs, deleteGFile, recursivelyDeleteDir,
|
||||
recursivelyMoveDir, loadInterfaceXML */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const { Gio, GLib } = imports.gi;
|
||||
const Config = imports.misc.config;
|
||||
const Params = imports.misc.params;
|
||||
|
||||
function collectFromDatadirs(subdir, includeUserDir, processFile) {
|
||||
let dataDirs = GLib.get_system_data_dirs();
|
||||
@@ -39,7 +38,7 @@ function recursivelyDeleteDir(dir, deleteParent) {
|
||||
let children = dir.enumerate_children('standard::name,standard::type',
|
||||
Gio.FileQueryInfoFlags.NONE, null);
|
||||
|
||||
let info, child;
|
||||
let info;
|
||||
while ((info = children.next_file(null)) != null) {
|
||||
let type = info.get_file_type();
|
||||
let child = dir.get_child(info.get_name());
|
||||
@@ -60,7 +59,7 @@ function recursivelyMoveDir(srcDir, destDir) {
|
||||
if (!destDir.query_exists(null))
|
||||
destDir.make_directory_with_parents(null);
|
||||
|
||||
let info, child;
|
||||
let info;
|
||||
while ((info = children.next_file(null)) != null) {
|
||||
let type = info.get_file_type();
|
||||
let srcChild = srcDir.get_child(info.get_name());
|
||||
@@ -87,13 +86,13 @@ function loadInterfaceXML(iface) {
|
||||
let f = Gio.File.new_for_uri(uri);
|
||||
|
||||
try {
|
||||
let [ok, bytes] = f.load_contents(null);
|
||||
let [ok_, bytes] = f.load_contents(null);
|
||||
if (bytes instanceof Uint8Array)
|
||||
xml = imports.byteArray.toString(bytes)
|
||||
xml = imports.byteArray.toString(bytes);
|
||||
else
|
||||
xml = bytes.toString();
|
||||
} catch (e) {
|
||||
log('Failed to load D-Bus interface ' + iface);
|
||||
log(`Failed to load D-Bus interface ${iface}`);
|
||||
}
|
||||
|
||||
return xml;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported PresenceStatus, Presence, Inhibitor, SessionManager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
// -*- 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;
|
||||
|
||||
var DEFAULT_LIMIT = 512;
|
||||
|
||||
var HistoryManager = new Lang.Class({
|
||||
Name: 'HistoryManager',
|
||||
|
||||
_init(params) {
|
||||
var HistoryManager = class {
|
||||
constructor(params) {
|
||||
params = Params.parse(params, { gsettingsKey: null,
|
||||
limit: DEFAULT_LIMIT,
|
||||
entry: null });
|
||||
@@ -21,7 +18,7 @@ var HistoryManager = new Lang.Class({
|
||||
this._historyIndex = 0;
|
||||
if (this._key) {
|
||||
this._history = global.settings.get_strv(this._key);
|
||||
global.settings.connect('changed::' + this._key,
|
||||
global.settings.connect(`changed::${this._key}`,
|
||||
this._historyChanged.bind(this));
|
||||
|
||||
} else {
|
||||
@@ -34,12 +31,12 @@ var HistoryManager = new Lang.Class({
|
||||
this._entry.connect('key-press-event',
|
||||
this._onEntryKeyPress.bind(this));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_historyChanged() {
|
||||
this._history = global.settings.get_strv(this._key);
|
||||
this._historyIndex = this._history.length;
|
||||
},
|
||||
}
|
||||
|
||||
_setPrevItem(text) {
|
||||
if (this._historyIndex <= 0)
|
||||
@@ -50,7 +47,7 @@ var HistoryManager = new Lang.Class({
|
||||
this._historyIndex--;
|
||||
this._indexChanged();
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
_setNextItem(text) {
|
||||
if (this._historyIndex >= this._history.length)
|
||||
@@ -61,7 +58,7 @@ var HistoryManager = new Lang.Class({
|
||||
this._historyIndex++;
|
||||
this._indexChanged();
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
lastItem() {
|
||||
if (this._historyIndex != this._history.length) {
|
||||
@@ -69,8 +66,8 @@ var HistoryManager = new Lang.Class({
|
||||
this._indexChanged();
|
||||
}
|
||||
|
||||
return this._historyIndex ? this._history[this._historyIndex -1] : null;
|
||||
},
|
||||
return this._historyIndex ? this._history[this._historyIndex - 1] : null;
|
||||
}
|
||||
|
||||
addItem(input) {
|
||||
if (this._history.length == 0 ||
|
||||
@@ -81,7 +78,7 @@ var HistoryManager = new Lang.Class({
|
||||
this._save();
|
||||
}
|
||||
this._historyIndex = this._history.length;
|
||||
},
|
||||
}
|
||||
|
||||
_onEntryKeyPress(entry, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
@@ -91,7 +88,7 @@ var HistoryManager = new Lang.Class({
|
||||
return this._setNextItem(entry.get_text());
|
||||
}
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
},
|
||||
}
|
||||
|
||||
_indexChanged() {
|
||||
let current = this._history[this._historyIndex] || '';
|
||||
@@ -99,7 +96,7 @@ var HistoryManager = new Lang.Class({
|
||||
|
||||
if (this._entry)
|
||||
this._entry.set_text(current);
|
||||
},
|
||||
}
|
||||
|
||||
_save() {
|
||||
if (this._history.length > this._limit)
|
||||
@@ -108,5 +105,5 @@ var HistoryManager = new Lang.Class({
|
||||
if (this._key)
|
||||
global.settings.set_strv(this._key, this._history);
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(HistoryManager.prototype);
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getIBusManager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const { Gio, GLib, IBus } = imports.gi;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const IBus = imports.gi.IBus;
|
||||
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
|
||||
|
||||
// Ensure runtime version matches
|
||||
@@ -32,21 +30,20 @@ function getIBusManager() {
|
||||
return _ibusManager;
|
||||
}
|
||||
|
||||
var IBusManager = new Lang.Class({
|
||||
Name: 'IBusManager',
|
||||
|
||||
// This is the longest we'll keep the keyboard frozen until an input
|
||||
// source is active.
|
||||
_MAX_INPUT_SOURCE_ACTIVATION_TIME: 4000, // ms
|
||||
_PRELOAD_ENGINES_DELAY_TIME: 30, // sec
|
||||
|
||||
_init() {
|
||||
var IBusManager = class {
|
||||
constructor() {
|
||||
IBus.init();
|
||||
|
||||
// This is the longest we'll keep the keyboard frozen until an input
|
||||
// source is active.
|
||||
this._MAX_INPUT_SOURCE_ACTIVATION_TIME = 4000; // ms
|
||||
this._PRELOAD_ENGINES_DELAY_TIME = 30; // sec
|
||||
|
||||
|
||||
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
|
||||
|
||||
this._panelService = null;
|
||||
this._engines = {};
|
||||
this._engines = new Map();
|
||||
this._ready = false;
|
||||
this._registerPropertiesId = 0;
|
||||
this._currentEngineName = null;
|
||||
@@ -60,16 +57,16 @@ var IBusManager = new Lang.Class({
|
||||
this._ibus.connect('global-engine-changed', this._engineChanged.bind(this));
|
||||
|
||||
this._spawn();
|
||||
},
|
||||
}
|
||||
|
||||
_spawn() {
|
||||
try {
|
||||
Gio.Subprocess.new(['ibus-daemon', '--xim', '--panel', 'disable'],
|
||||
Gio.SubprocessFlags.NONE);
|
||||
} catch(e) {
|
||||
log('Failed to launch ibus-daemon: ' + e.message);
|
||||
} catch (e) {
|
||||
log(`Failed to launch ibus-daemon: ${e.message}`);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_clear() {
|
||||
if (this._panelService)
|
||||
@@ -77,7 +74,7 @@ var IBusManager = new Lang.Class({
|
||||
|
||||
this._panelService = null;
|
||||
this._candidatePopup.setPanelService(null);
|
||||
this._engines = {};
|
||||
this._engines.clear();
|
||||
this._ready = false;
|
||||
this._registerPropertiesId = 0;
|
||||
this._currentEngineName = null;
|
||||
@@ -85,7 +82,7 @@ var IBusManager = new Lang.Class({
|
||||
this.emit('ready', false);
|
||||
|
||||
this._spawn();
|
||||
},
|
||||
}
|
||||
|
||||
_onConnected() {
|
||||
this._ibus.list_engines_async(-1, null, this._initEngines.bind(this));
|
||||
@@ -93,20 +90,20 @@ var IBusManager = new Lang.Class({
|
||||
IBus.BusNameFlag.REPLACE_EXISTING,
|
||||
-1, null,
|
||||
this._initPanelService.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_initEngines(ibus, result) {
|
||||
let enginesList = this._ibus.list_engines_async_finish(result);
|
||||
if (enginesList) {
|
||||
for (let i = 0; i < enginesList.length; ++i) {
|
||||
let name = enginesList[i].get_name();
|
||||
this._engines[name] = enginesList[i];
|
||||
this._engines.set(name, enginesList[i]);
|
||||
}
|
||||
this._updateReadiness();
|
||||
} else {
|
||||
this._clear();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_initPanelService(ibus, result) {
|
||||
let success = this._ibus.request_name_async_finish(result);
|
||||
@@ -123,7 +120,7 @@ var IBusManager = new Lang.Class({
|
||||
if (!GLib.str_has_suffix(path, '/InputContext_1'))
|
||||
this.emit ('focus-in');
|
||||
});
|
||||
this._panelService.connect('focus-out', () => { this.emit('focus-out'); });
|
||||
this._panelService.connect('focus-out', () => this.emit('focus-out'));
|
||||
|
||||
try {
|
||||
// IBus versions older than 1.5.10 have a bug which
|
||||
@@ -142,7 +139,7 @@ var IBusManager = new Lang.Class({
|
||||
engine = this._ibus.get_global_engine_async_finish(result);
|
||||
if (!engine)
|
||||
return;
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
this._engineChanged(this._ibus, engine.get_name());
|
||||
@@ -151,13 +148,12 @@ var IBusManager = new Lang.Class({
|
||||
} else {
|
||||
this._clear();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_updateReadiness() {
|
||||
this._ready = (Object.keys(this._engines).length > 0 &&
|
||||
this._panelService != null);
|
||||
this._ready = this._engines.size > 0 && this._panelService != null;
|
||||
this.emit('ready', this._ready);
|
||||
},
|
||||
}
|
||||
|
||||
_engineChanged(bus, engineName) {
|
||||
if (!this._ready)
|
||||
@@ -178,26 +174,26 @@ var IBusManager = new Lang.Class({
|
||||
|
||||
this.emit('properties-registered', this._currentEngineName, props);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_updateProperty(panel, prop) {
|
||||
this.emit('property-updated', this._currentEngineName, prop);
|
||||
},
|
||||
}
|
||||
|
||||
_setContentType(panel, purpose, hints) {
|
||||
this.emit('set-content-type', purpose, hints);
|
||||
},
|
||||
}
|
||||
|
||||
activateProperty(key, state) {
|
||||
this._panelService.property_activate(key, state);
|
||||
},
|
||||
}
|
||||
|
||||
getEngineDesc(id) {
|
||||
if (!this._ready || !this._engines.hasOwnProperty(id))
|
||||
if (!this._ready || !this._engines.has(id))
|
||||
return null;
|
||||
|
||||
return this._engines[id];
|
||||
},
|
||||
return this._engines.get(id);
|
||||
}
|
||||
|
||||
setEngine(id, callback) {
|
||||
// Send id even if id == this._currentEngineName
|
||||
@@ -211,7 +207,7 @@ var IBusManager = new Lang.Class({
|
||||
|
||||
this._ibus.set_global_engine_async(id, this._MAX_INPUT_SOURCE_ACTIVATION_TIME,
|
||||
null, callback || null);
|
||||
},
|
||||
}
|
||||
|
||||
preloadEngines(ids) {
|
||||
if (!this._ibus || ids.length == 0)
|
||||
@@ -233,6 +229,6 @@ var IBusManager = new Lang.Class({
|
||||
this._preloadEnginesId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(IBusManager.prototype);
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const IBus = imports.gi.IBus;
|
||||
/* exported InputMethod */
|
||||
const { Clutter, GLib, GObject, IBus } = imports.gi;
|
||||
|
||||
const Keyboard = imports.ui.status.keyboard;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
var InputMethod = new Lang.Class({
|
||||
Name: 'InputMethod',
|
||||
Extends: Clutter.InputMethod,
|
||||
var HIDE_PANEL_TIME = 50;
|
||||
|
||||
var InputMethod = GObject.registerClass(
|
||||
class InputMethod extends Clutter.InputMethod {
|
||||
_init() {
|
||||
this.parent();
|
||||
super._init();
|
||||
this._hints = 0;
|
||||
this._purpose = 0;
|
||||
this._enabled = true;
|
||||
this._currentFocus = null;
|
||||
this._preeditStr = '';
|
||||
this._preeditPos = 0;
|
||||
this._preeditVisible = false;
|
||||
this._hidePanelId = 0;
|
||||
this._ibus = IBus.Bus.new_async();
|
||||
this._ibus.connect('connected', this._onConnected.bind(this));
|
||||
this._ibus.connect('disconnected', this._clear.bind(this));
|
||||
@@ -30,11 +29,11 @@ var InputMethod = new Lang.Class({
|
||||
|
||||
if (this._ibus.is_connected())
|
||||
this._onConnected();
|
||||
},
|
||||
}
|
||||
|
||||
get currentFocus() {
|
||||
return this._currentFocus;
|
||||
},
|
||||
}
|
||||
|
||||
_updateCapabilities() {
|
||||
let caps = 0;
|
||||
@@ -49,21 +48,19 @@ var InputMethod = new Lang.Class({
|
||||
|
||||
if (this._context)
|
||||
this._context.set_capabilities(caps);
|
||||
},
|
||||
}
|
||||
|
||||
_onSourceChanged() {
|
||||
this._currentSource = this._inputSourceManager.currentSource;
|
||||
},
|
||||
}
|
||||
|
||||
_onConnected() {
|
||||
this._ibus.create_input_context_async ('gnome-shell', -1, null,
|
||||
this._setContext.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_setContext(bus, res) {
|
||||
this._context = this._ibus.create_input_context_async_finish(res);
|
||||
this._context.connect('enabled', () => { this._enabled = true });
|
||||
this._context.connect('disabled', () => { this._enabled = false });
|
||||
this._context.connect('commit-text', this._onCommitText.bind(this));
|
||||
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
|
||||
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
|
||||
@@ -72,32 +69,31 @@ var InputMethod = new Lang.Class({
|
||||
this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
|
||||
|
||||
this._updateCapabilities();
|
||||
},
|
||||
}
|
||||
|
||||
_clear() {
|
||||
this._context = null;
|
||||
this._hints = 0;
|
||||
this._purpose = 0;
|
||||
this._enabled = false;
|
||||
this._preeditStr = ''
|
||||
this._preeditStr = '';
|
||||
this._preeditPos = 0;
|
||||
this._preeditVisible = false;
|
||||
},
|
||||
}
|
||||
|
||||
_emitRequestSurrounding() {
|
||||
if (this._context.needs_surrounding_text())
|
||||
this.emit('request-surrounding');
|
||||
},
|
||||
}
|
||||
|
||||
_onCommitText(context, text) {
|
||||
_onCommitText(_context, text) {
|
||||
this.commit(text.get_text());
|
||||
},
|
||||
}
|
||||
|
||||
_onDeleteSurroundingText(context) {
|
||||
_onDeleteSurroundingText() {
|
||||
this.delete_surrounding();
|
||||
},
|
||||
}
|
||||
|
||||
_onUpdatePreeditText(context, text, pos, visible) {
|
||||
_onUpdatePreeditText(_context, text, pos, visible) {
|
||||
if (text == null)
|
||||
return;
|
||||
|
||||
@@ -111,19 +107,19 @@ var InputMethod = new Lang.Class({
|
||||
this._preeditStr = preedit;
|
||||
this._preeditPos = pos;
|
||||
this._preeditVisible = visible;
|
||||
},
|
||||
}
|
||||
|
||||
_onShowPreeditText(context) {
|
||||
_onShowPreeditText() {
|
||||
this._preeditVisible = true;
|
||||
this.set_preedit_text(this._preeditStr, this._preeditPos);
|
||||
},
|
||||
}
|
||||
|
||||
_onHidePreeditText(context) {
|
||||
_onHidePreeditText() {
|
||||
this.set_preedit_text(null, this._preeditPos);
|
||||
this._preeditVisible = false;
|
||||
},
|
||||
}
|
||||
|
||||
_onForwardKeyEvent(context, keyval, keycode, state) {
|
||||
_onForwardKeyEvent(_context, keyval, keycode, state) {
|
||||
let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
|
||||
state &= ~(IBus.ModifierType.RELEASE_MASK);
|
||||
|
||||
@@ -135,7 +131,7 @@ var InputMethod = new Lang.Class({
|
||||
time = global.display.get_current_time_roundtrip();
|
||||
|
||||
this.forward_key(keyval, keycode + 8, state & Clutter.ModifierType.MODIFIER_MASK, time, press);
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_focus_in(focus) {
|
||||
this._currentFocus = focus;
|
||||
@@ -144,7 +140,12 @@ var InputMethod = new Lang.Class({
|
||||
this._updateCapabilities();
|
||||
this._emitRequestSurrounding();
|
||||
}
|
||||
},
|
||||
|
||||
if (this._hidePanelId) {
|
||||
GLib.source_remove(this._hidePanelId);
|
||||
this._hidePanelId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
vfunc_focus_out() {
|
||||
this._currentFocus = null;
|
||||
@@ -158,7 +159,13 @@ var InputMethod = new Lang.Class({
|
||||
this.set_preedit_text(null, 0);
|
||||
this._preeditStr = null;
|
||||
}
|
||||
},
|
||||
|
||||
this._hidePanelId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, HIDE_PANEL_TIME, () => {
|
||||
this.set_input_panel_state(Clutter.InputPanelState.OFF);
|
||||
this._hidePanelId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
vfunc_reset() {
|
||||
if (this._context) {
|
||||
@@ -171,7 +178,7 @@ var InputMethod = new Lang.Class({
|
||||
this.set_preedit_text(null, 0);
|
||||
this._preeditStr = null;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_set_cursor_location(rect) {
|
||||
if (this._context) {
|
||||
@@ -179,7 +186,7 @@ var InputMethod = new Lang.Class({
|
||||
rect.get_width(), rect.get_height());
|
||||
this._emitRequestSurrounding();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_set_surrounding(text, cursor, anchor) {
|
||||
if (!this._context || !text)
|
||||
@@ -187,7 +194,7 @@ var InputMethod = new Lang.Class({
|
||||
|
||||
let ibusText = IBus.Text.new_from_string(text);
|
||||
this._context.set_surrounding_text(ibusText, cursor, anchor);
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_update_content_hints(hints) {
|
||||
let ibusHints = 0;
|
||||
@@ -207,7 +214,7 @@ var InputMethod = new Lang.Class({
|
||||
this._hints = ibusHints;
|
||||
if (this._context)
|
||||
this._context.set_content_type(this._purpose, this._hints);
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_update_content_purpose(purpose) {
|
||||
let ibusPurpose = 0;
|
||||
@@ -233,10 +240,10 @@ var InputMethod = new Lang.Class({
|
||||
this._purpose = ibusPurpose;
|
||||
if (this._context)
|
||||
this._context.set_content_type(this._purpose, this._hints);
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_filter_key_event(event) {
|
||||
if (!this._context || !this._enabled)
|
||||
if (!this._context)
|
||||
return false;
|
||||
if (!this._currentSource)
|
||||
return false;
|
||||
@@ -256,9 +263,9 @@ var InputMethod = new Lang.Class({
|
||||
let retval = context.process_key_event_async_finish(res);
|
||||
this.notify_key_event(event, retval);
|
||||
} catch (e) {
|
||||
log('Error processing key on IM: ' + e.message);
|
||||
log(`Error processing key on IM: ${e.message}`);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
/* exported IntrospectService */
|
||||
const { Gio, GLib, Meta, Shell } = imports.gi;
|
||||
|
||||
const INTROSPECT_SCHEMA = 'org.gnome.shell';
|
||||
const INTROSPECT_KEY = 'introspect';
|
||||
@@ -12,10 +9,8 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect');
|
||||
|
||||
var IntrospectService = new Lang.Class({
|
||||
Name: 'IntrospectService',
|
||||
|
||||
_init() {
|
||||
var IntrospectService = class {
|
||||
constructor() {
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(IntrospectDBusIface,
|
||||
this);
|
||||
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Introspect');
|
||||
@@ -45,21 +40,24 @@ var IntrospectService = new Lang.Class({
|
||||
});
|
||||
|
||||
this._syncRunningApplications();
|
||||
},
|
||||
}
|
||||
|
||||
_isStandaloneApp(app) {
|
||||
let windows = app.get_windows();
|
||||
|
||||
return app.get_windows().some(w => w.transient_for == null);
|
||||
},
|
||||
}
|
||||
|
||||
_isIntrospectEnabled() {
|
||||
return this._settings.get_boolean(INTROSPECT_KEY);
|
||||
},
|
||||
return this._settings.get_boolean(INTROSPECT_KEY);
|
||||
}
|
||||
|
||||
_isSenderWhitelisted(sender) {
|
||||
return APP_WHITELIST.includes(sender);
|
||||
},
|
||||
return APP_WHITELIST.includes(sender);
|
||||
}
|
||||
|
||||
_getSandboxedAppId(app) {
|
||||
let ids = app.get_windows().map(w => w.get_sandboxed_app_id());
|
||||
return ids.find(id => id != null);
|
||||
}
|
||||
|
||||
_syncRunningApplications() {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
@@ -82,6 +80,10 @@ var IntrospectService = new Lang.Class({
|
||||
newActiveApplication = app.get_id();
|
||||
}
|
||||
|
||||
let sandboxedAppId = this._getSandboxedAppId(app);
|
||||
if (sandboxedAppId)
|
||||
appInfo['sandboxed-app-id'] = new GLib.Variant('s', sandboxedAppId);
|
||||
|
||||
newRunningApplications[app.get_id()] = appInfo;
|
||||
}
|
||||
|
||||
@@ -95,7 +97,7 @@ var IntrospectService = new Lang.Class({
|
||||
}
|
||||
this._runningApplicationsDirty = false;
|
||||
this._activeApplicationDirty = false;
|
||||
},
|
||||
}
|
||||
|
||||
_isEligibleWindow(window) {
|
||||
if (window.is_override_redirect())
|
||||
@@ -106,7 +108,7 @@ var IntrospectService = new Lang.Class({
|
||||
type == Meta.WindowType.DIALOG ||
|
||||
type == Meta.WindowType.MODAL_DIALOG ||
|
||||
type == Meta.WindowType.UTILITY);
|
||||
},
|
||||
}
|
||||
|
||||
GetRunningApplicationsAsync(params, invocation) {
|
||||
if (!this._isIntrospectEnabled() &&
|
||||
@@ -118,7 +120,7 @@ var IntrospectService = new Lang.Class({
|
||||
}
|
||||
|
||||
invocation.return_value(new GLib.Variant('(a{sa{sv}})', [this._runningApplications]));
|
||||
},
|
||||
}
|
||||
|
||||
GetWindowsAsync(params, invocation) {
|
||||
let focusWindow = global.display.get_focus_window();
|
||||
@@ -143,6 +145,7 @@ var IntrospectService = new Lang.Class({
|
||||
let frameRect = window.get_frame_rect();
|
||||
let title = window.get_title();
|
||||
let wmClass = window.get_wm_class();
|
||||
let sandboxedAppId = window.get_sandboxed_app_id();
|
||||
|
||||
windowsList[windowId] = {
|
||||
'app-id': GLib.Variant.new('s', app.get_id()),
|
||||
@@ -159,8 +162,12 @@ var IntrospectService = new Lang.Class({
|
||||
|
||||
if (wmClass != null)
|
||||
windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass);
|
||||
|
||||
if (sandboxedAppId != null)
|
||||
windowsList[windowId]['sandboxed-app-id'] =
|
||||
GLib.Variant.new('s', sandboxedAppId);
|
||||
}
|
||||
}
|
||||
invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
/* exported getCompletions, getCommonPrefix, getDeclaredConstants */
|
||||
|
||||
// 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)
|
||||
@@ -8,7 +9,7 @@
|
||||
// This function is likely the one you want to call from external modules
|
||||
function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
let methods = [];
|
||||
let expr, base;
|
||||
let expr_, base;
|
||||
let attrHead = '';
|
||||
if (globalCompletionList == null) {
|
||||
globalCompletionList = [];
|
||||
@@ -21,7 +22,7 @@ function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
// Look for expressions like "Main.panel.foo" and match Main.panel and foo
|
||||
let matches = text.match(/(.*)\.(.*)/);
|
||||
if (matches) {
|
||||
[expr, base, attrHead] = matches;
|
||||
[expr_, base, attrHead] = matches;
|
||||
|
||||
methods = getPropertyNamesFromExpression(base, commandHeader).filter(
|
||||
attr => attr.slice(0, attrHead.length) == attrHead
|
||||
@@ -32,7 +33,7 @@ function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
// not proceeded by a dot and match them against global constants
|
||||
matches = text.match(/^(\w*)$/);
|
||||
if (text == '' || matches) {
|
||||
[expr, attrHead] = matches;
|
||||
[expr_, attrHead] = matches;
|
||||
methods = globalCompletionList.filter(
|
||||
attr => attr.slice(0, attrHead.length) == attrHead
|
||||
);
|
||||
@@ -51,14 +52,14 @@ function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
// if we encounter anything that isn't a letter, '.', ')', or ']',
|
||||
// we should stop parsing.
|
||||
function isStopChar(c) {
|
||||
return !c.match(/[\w\.\)\]]/);
|
||||
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) != '\\'){
|
||||
if (expr.charAt(i) == quoteChar && expr.charAt(i - 1) != '\\') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -68,7 +69,7 @@ function findMatchingQuote(expr, offset) {
|
||||
// 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) != '\\'){
|
||||
if (expr.charAt(i) == '/' && expr.charAt(i - 1) != '\\') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -81,7 +82,7 @@ function findMatchingSlash(expr, offset) {
|
||||
// findMatchingBrace("[(])", 3) returns 1.
|
||||
function findMatchingBrace(expr, offset) {
|
||||
let closeBrace = expr.charAt(offset);
|
||||
let openBrace = ({')': '(', ']': '['})[closeBrace];
|
||||
let openBrace = ({ ')': '(', ']': '[' })[closeBrace];
|
||||
|
||||
function findTheBrace(expr, offset) {
|
||||
if (offset < 0) {
|
||||
@@ -117,11 +118,11 @@ function getExpressionOffset(expr, offset) {
|
||||
while (offset >= 0) {
|
||||
let currChar = expr.charAt(offset);
|
||||
|
||||
if (isStopChar(currChar)){
|
||||
if (isStopChar(currChar)) {
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
if (currChar.match(/[\)\]]/)) {
|
||||
if (currChar.match(/[)\]]/)) {
|
||||
offset = findMatchingBrace(expr, offset);
|
||||
}
|
||||
|
||||
@@ -151,15 +152,11 @@ function getAllProps(obj) {
|
||||
// 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 = '';
|
||||
}
|
||||
|
||||
function getPropertyNamesFromExpression(expr, commandHeader = '') {
|
||||
let obj = {};
|
||||
if (!isUnsafeExpression(expr)) {
|
||||
try {
|
||||
obj = eval(commandHeader + expr);
|
||||
obj = eval(commandHeader + expr);
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
@@ -168,7 +165,7 @@ function getPropertyNamesFromExpression(expr, commandHeader) {
|
||||
}
|
||||
|
||||
let propsUnique = {};
|
||||
if (typeof obj === 'object'){
|
||||
if (typeof obj === 'object') {
|
||||
let allProps = getAllProps(obj);
|
||||
// Get only things we are allowed to complete following a '.'
|
||||
allProps = allProps.filter( isValidPropertyName );
|
||||
@@ -234,10 +231,10 @@ function isUnsafeExpression(str) {
|
||||
function getDeclaredConstants(str) {
|
||||
let ret = [];
|
||||
str.split(';').forEach(s => {
|
||||
let base, keyword;
|
||||
let base_, keyword;
|
||||
let match = s.match(/const\s+(\w+)\s*=/);
|
||||
if (match) {
|
||||
[base, keyword] = match;
|
||||
[base_, keyword] = match;
|
||||
ret.push(keyword);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getKeyboardManager, holdKeyboard, releaseKeyboard */
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const GnomeDesktop = imports.gi.GnomeDesktop;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const { GLib, GnomeDesktop, Meta } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
@@ -38,22 +36,20 @@ function holdKeyboard() {
|
||||
global.display.freeze_keyboard(global.get_current_time());
|
||||
}
|
||||
|
||||
var KeyboardManager = new Lang.Class({
|
||||
Name: 'KeyboardManager',
|
||||
var KeyboardManager = class {
|
||||
constructor() {
|
||||
// The XKB protocol doesn't allow for more that 4 layouts in a
|
||||
// keymap. Wayland doesn't impose this limit and libxkbcommon can
|
||||
// handle up to 32 layouts but since we need to support X clients
|
||||
// even as a Wayland compositor, we can't bump this.
|
||||
this.MAX_LAYOUTS_PER_GROUP = 4;
|
||||
|
||||
// The XKB protocol doesn't allow for more that 4 layouts in a
|
||||
// keymap. Wayland doesn't impose this limit and libxkbcommon can
|
||||
// handle up to 32 layouts but since we need to support X clients
|
||||
// even as a Wayland compositor, we can't bump this.
|
||||
MAX_LAYOUTS_PER_GROUP: 4,
|
||||
|
||||
_init() {
|
||||
this._xkbInfo = getXkbInfo();
|
||||
this._current = null;
|
||||
this._localeLayoutInfo = this._getLocaleLayout();
|
||||
this._layoutInfos = {};
|
||||
this._currentKeymap = null;
|
||||
},
|
||||
}
|
||||
|
||||
_applyLayoutGroup(group) {
|
||||
let options = this._buildOptionsString();
|
||||
@@ -65,13 +61,13 @@ var KeyboardManager = new Lang.Class({
|
||||
this._currentKeymap.options == options)
|
||||
return;
|
||||
|
||||
this._currentKeymap = {layouts, variants, options};
|
||||
this._currentKeymap = { layouts, variants, options };
|
||||
Meta.get_backend().set_keymap(layouts, variants, options);
|
||||
},
|
||||
}
|
||||
|
||||
_applyLayoutGroupIndex(idx) {
|
||||
Meta.get_backend().lock_layout_group(idx);
|
||||
},
|
||||
}
|
||||
|
||||
apply(id) {
|
||||
let info = this._layoutInfos[id];
|
||||
@@ -87,7 +83,7 @@ var KeyboardManager = new Lang.Class({
|
||||
}
|
||||
|
||||
this._current = info;
|
||||
},
|
||||
}
|
||||
|
||||
reapply() {
|
||||
if (!this._current)
|
||||
@@ -95,7 +91,7 @@ var KeyboardManager = new Lang.Class({
|
||||
|
||||
this._applyLayoutGroup(this._current.group);
|
||||
this._applyLayoutGroupIndex(this._current.groupIndex);
|
||||
},
|
||||
}
|
||||
|
||||
setUserLayouts(ids) {
|
||||
this._current = null;
|
||||
@@ -126,11 +122,11 @@ var KeyboardManager = new Lang.Class({
|
||||
|
||||
i += 1;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_getLocaleLayout() {
|
||||
let locale = GLib.get_language_names()[0];
|
||||
if (locale.indexOf('_') == -1)
|
||||
if (!locale.includes('_'))
|
||||
locale = DEFAULT_LOCALE;
|
||||
|
||||
let [found, , id] = GnomeDesktop.get_input_source_from_locale(locale);
|
||||
@@ -143,21 +139,21 @@ var KeyboardManager = new Lang.Class({
|
||||
return { layout: _layout, variant: _variant };
|
||||
else
|
||||
return { layout: DEFAULT_LAYOUT, variant: DEFAULT_VARIANT };
|
||||
},
|
||||
}
|
||||
|
||||
_buildGroupStrings(_group) {
|
||||
let group = _group.concat(this._localeLayoutInfo);
|
||||
let layouts = group.map(g => g.layout).join(',');
|
||||
let variants = group.map(g => g.variant).join(',');
|
||||
return [layouts, variants];
|
||||
},
|
||||
}
|
||||
|
||||
setKeyboardOptions(options) {
|
||||
this._xkbOptions = options;
|
||||
},
|
||||
}
|
||||
|
||||
_buildOptionsString() {
|
||||
let options = this._xkbOptions.join(',');
|
||||
return options;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported canLock, getLoginManager, registerSessionWithGDM */
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
const { GLib, Gio } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
@@ -47,11 +44,33 @@ function canLock() {
|
||||
|
||||
let version = result.deep_unpack()[0].deep_unpack();
|
||||
return haveSystemd() && versionCompare('3.5.91', version);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function registerSessionWithGDM() {
|
||||
log("Registering session with GDM");
|
||||
Gio.DBus.system.call('org.gnome.DisplayManager',
|
||||
'/org/gnome/DisplayManager/Manager',
|
||||
'org.gnome.DisplayManager.Manager',
|
||||
'RegisterSession',
|
||||
GLib.Variant.new('(a{sv})', [{}]), null,
|
||||
Gio.DBusCallFlags.NONE, -1, null,
|
||||
(source, result) => {
|
||||
try {
|
||||
source.call_finish(result);
|
||||
} catch (e) {
|
||||
if (!e.matches(Gio.DBusError, Gio.DBusError.UNKNOWN_METHOD))
|
||||
log(`Error registering session with GDM: ${e.message}`);
|
||||
else
|
||||
log("Not calling RegisterSession(): method not exported, GDM too old?");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let _loginManager = null;
|
||||
|
||||
/**
|
||||
@@ -70,10 +89,8 @@ function getLoginManager() {
|
||||
return _loginManager;
|
||||
}
|
||||
|
||||
var LoginManagerSystemd = new Lang.Class({
|
||||
Name: 'LoginManagerSystemd',
|
||||
|
||||
_init() {
|
||||
var LoginManagerSystemd = class {
|
||||
constructor() {
|
||||
this._proxy = new SystemdLoginManager(Gio.DBus.system,
|
||||
'org.freedesktop.login1',
|
||||
'/org/freedesktop/login1');
|
||||
@@ -82,7 +99,7 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
'/org/freedesktop/login1/user/self');
|
||||
this._proxy.connectSignal('PrepareForSleep',
|
||||
this._prepareForSleep.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
getCurrentSessionProxy(callback) {
|
||||
if (this._currentSession) {
|
||||
@@ -93,7 +110,7 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
let sessionId = GLib.getenv('XDG_SESSION_ID');
|
||||
if (!sessionId) {
|
||||
log('Unset XDG_SESSION_ID, getCurrentSessionProxy() called outside a user session. Asking logind directly.');
|
||||
let [session, objectPath] = this._userProxy.Display;
|
||||
let [session, objectPath_] = this._userProxy.Display;
|
||||
if (session) {
|
||||
log(`Will monitor session ${session}`);
|
||||
sessionId = session;
|
||||
@@ -129,7 +146,7 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
callback(this._currentSession);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
canSuspend(asyncCallback) {
|
||||
this._proxy.CanSuspendRemote((result, error) => {
|
||||
@@ -141,7 +158,7 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
asyncCallback(canSuspend, needsAuth);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
listSessions(asyncCallback) {
|
||||
this._proxy.ListSessionsRemote((result, error) => {
|
||||
@@ -150,11 +167,11 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
else
|
||||
asyncCallback(result[0]);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
suspend() {
|
||||
this._proxy.SuspendRemote(true);
|
||||
},
|
||||
}
|
||||
|
||||
inhibit(reason, callback) {
|
||||
let inVariant = GLib.Variant.new('(ssss)',
|
||||
@@ -166,46 +183,44 @@ var LoginManagerSystemd = new Lang.Class({
|
||||
(proxy, result) => {
|
||||
let fd = -1;
|
||||
try {
|
||||
let [outVariant, fdList] = proxy.call_with_unix_fd_list_finish(result);
|
||||
let [outVariant_, fdList] = proxy.call_with_unix_fd_list_finish(result);
|
||||
fd = fdList.steal_fds()[0];
|
||||
callback(new Gio.UnixInputStream({ fd: fd }));
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
logError(e, "Error getting systemd inhibitor");
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_prepareForSleep(proxy, sender, [aboutToSuspend]) {
|
||||
this.emit('prepare-for-sleep', aboutToSuspend);
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(LoginManagerSystemd.prototype);
|
||||
|
||||
var LoginManagerDummy = new Lang.Class({
|
||||
Name: 'LoginManagerDummy',
|
||||
|
||||
getCurrentSessionProxy(callback) {
|
||||
var LoginManagerDummy = class {
|
||||
getCurrentSessionProxy(_callback) {
|
||||
// we could return a DummySession object that fakes whatever callers
|
||||
// expect (at the time of writing: connect() and connectSignal()
|
||||
// methods), but just never calling the callback should be safer
|
||||
},
|
||||
}
|
||||
|
||||
canSuspend(asyncCallback) {
|
||||
asyncCallback(false, false);
|
||||
},
|
||||
}
|
||||
|
||||
listSessions(asyncCallback) {
|
||||
asyncCallback([]);
|
||||
},
|
||||
}
|
||||
|
||||
suspend() {
|
||||
this.emit('prepare-for-sleep', true);
|
||||
this.emit('prepare-for-sleep', false);
|
||||
},
|
||||
}
|
||||
|
||||
inhibit(reason, callback) {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(LoginManagerDummy.prototype);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const NMA = imports.gi.NMA;
|
||||
const { Gio, NMA } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
@@ -28,33 +26,33 @@ function _getMobileProvidersDatabase() {
|
||||
}
|
||||
|
||||
// _findProviderForMccMnc:
|
||||
// @operator_name: operator name
|
||||
// @operator_code: operator code
|
||||
// @operatorName: operator name
|
||||
// @operatorCode: operator code
|
||||
//
|
||||
// Given an operator name string (which may not be a real operator name) and an
|
||||
// operator code string, tries to find a proper operator name to display.
|
||||
//
|
||||
function _findProviderForMccMnc(operator_name, operator_code) {
|
||||
if (operator_name) {
|
||||
if (operator_name.length != 0 &&
|
||||
(operator_name.length > 6 || operator_name.length < 5)) {
|
||||
function _findProviderForMccMnc(operatorName, operatorCode) {
|
||||
if (operatorName) {
|
||||
if (operatorName.length != 0 &&
|
||||
(operatorName.length > 6 || operatorName.length < 5)) {
|
||||
// this looks like a valid name, i.e. not an MCCMNC (that some
|
||||
// devices return when not yet connected
|
||||
return operator_name;
|
||||
return operatorName;
|
||||
}
|
||||
|
||||
if (isNaN(parseInt(operator_name))) {
|
||||
if (isNaN(parseInt(operatorName))) {
|
||||
// name is definitely not a MCCMNC, so it may be a name
|
||||
// after all; return that
|
||||
return operator_name;
|
||||
return operatorName;
|
||||
}
|
||||
}
|
||||
|
||||
let needle;
|
||||
if ((!operator_name || operator_name.length == 0) && operator_code)
|
||||
needle = operator_code;
|
||||
else if (operator_name && (operator_name.length == 6 || operator_name.length == 5))
|
||||
needle = operator_name;
|
||||
if ((!operatorName || operatorName.length == 0) && operatorCode)
|
||||
needle = operatorCode;
|
||||
else if (operatorName && (operatorName.length == 6 || operatorName.length == 5))
|
||||
needle = operatorName;
|
||||
else // nothing to search
|
||||
return null;
|
||||
|
||||
@@ -73,7 +71,7 @@ function _findProviderForMccMnc(operator_name, operator_code) {
|
||||
// Tries to find the operator name corresponding to the given SID
|
||||
//
|
||||
function _findProviderForSid(sid) {
|
||||
if (sid == 0)
|
||||
if (!sid)
|
||||
return null;
|
||||
|
||||
let mpd = _getMobileProvidersDatabase();
|
||||
@@ -100,10 +98,8 @@ const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInter
|
||||
const ModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager.Modem.Cdma');
|
||||
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
|
||||
|
||||
var ModemGsm = new Lang.Class({
|
||||
Name: 'ModemGsm',
|
||||
|
||||
_init(path) {
|
||||
var ModemGsm = class {
|
||||
constructor(path) {
|
||||
this._proxy = new ModemGsmNetworkProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||
|
||||
this.signal_quality = 0;
|
||||
@@ -114,7 +110,7 @@ var ModemGsm = new Lang.Class({
|
||||
this.signal_quality = quality;
|
||||
this.emit('notify::signal-quality');
|
||||
});
|
||||
this._proxy.connectSignal('RegistrationInfo', (proxy, sender, [status, code, name]) => {
|
||||
this._proxy.connectSignal('RegistrationInfo', (proxy, sender, [_status, code, name]) => {
|
||||
this.operator_name = _findProviderForMccMnc(name, code);
|
||||
this.emit('notify::operator-name');
|
||||
});
|
||||
@@ -124,7 +120,7 @@ var ModemGsm = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
let [status, code, name] = result;
|
||||
let [status_, code, name] = result;
|
||||
this.operator_name = _findProviderForMccMnc(name, code);
|
||||
this.emit('notify::operator-name');
|
||||
});
|
||||
@@ -139,13 +135,11 @@ var ModemGsm = new Lang.Class({
|
||||
this.emit('notify::signal-quality');
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(ModemGsm.prototype);
|
||||
|
||||
var ModemCdma = new Lang.Class({
|
||||
Name: 'ModemCdma',
|
||||
|
||||
_init(path) {
|
||||
var ModemCdma = class {
|
||||
constructor(path) {
|
||||
this._proxy = new ModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager', path);
|
||||
|
||||
this.signal_quality = 0;
|
||||
@@ -169,7 +163,7 @@ var ModemCdma = new Lang.Class({
|
||||
}
|
||||
this.emit('notify::signal-quality');
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_refreshServingSystem() {
|
||||
this._proxy.GetServingSystemRemote(([result], err) => {
|
||||
@@ -177,14 +171,14 @@ var ModemCdma = new Lang.Class({
|
||||
// it will return an error if the device is not connected
|
||||
this.operator_name = null;
|
||||
} else {
|
||||
let [bandClass, band, sid] = result;
|
||||
let [bandClass_, band_, sid] = result;
|
||||
|
||||
this.operator_name = _findProviderForSid(sid)
|
||||
this.operator_name = _findProviderForSid(sid);
|
||||
}
|
||||
this.emit('notify::operator-name');
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(ModemCdma.prototype);
|
||||
|
||||
|
||||
@@ -201,10 +195,8 @@ const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gp
|
||||
const BroadbandModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager1.Modem.ModemCdma');
|
||||
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
|
||||
|
||||
var BroadbandModem = new Lang.Class({
|
||||
Name: 'BroadbandModem',
|
||||
|
||||
_init(path, capabilities) {
|
||||
var BroadbandModem = class {
|
||||
constructor(path, capabilities) {
|
||||
this._proxy = new BroadbandModemProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
|
||||
this._proxy_3gpp = new BroadbandModem3gppProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
|
||||
this._proxy_cdma = new BroadbandModemCdmaProxy(Gio.DBus.system, 'org.freedesktop.ModemManager1', path);
|
||||
@@ -229,40 +221,40 @@ var BroadbandModem = new Lang.Class({
|
||||
this._reloadCdmaOperatorName();
|
||||
});
|
||||
this._reloadCdmaOperatorName();
|
||||
},
|
||||
}
|
||||
|
||||
_reloadSignalQuality() {
|
||||
let [quality, recent] = this._proxy.SignalQuality;
|
||||
let [quality, recent_] = this._proxy.SignalQuality;
|
||||
this.signal_quality = quality;
|
||||
this.emit('notify::signal-quality');
|
||||
},
|
||||
}
|
||||
|
||||
_reloadOperatorName() {
|
||||
let new_name = "";
|
||||
let newName = "";
|
||||
if (this.operator_name_3gpp && this.operator_name_3gpp.length > 0)
|
||||
new_name += this.operator_name_3gpp;
|
||||
newName += this.operator_name_3gpp;
|
||||
|
||||
if (this.operator_name_cdma && this.operator_name_cdma.length > 0) {
|
||||
if (new_name != "")
|
||||
new_name += ", ";
|
||||
new_name += this.operator_name_cdma;
|
||||
if (newName != "")
|
||||
newName += ", ";
|
||||
newName += this.operator_name_cdma;
|
||||
}
|
||||
|
||||
this.operator_name = new_name;
|
||||
this.operator_name = newName;
|
||||
this.emit('notify::operator-name');
|
||||
},
|
||||
}
|
||||
|
||||
_reload3gppOperatorName() {
|
||||
let name = this._proxy_3gpp.OperatorName;
|
||||
let code = this._proxy_3gpp.OperatorCode;
|
||||
this.operator_name_3gpp = _findProviderForMccMnc(name, code);
|
||||
this._reloadOperatorName();
|
||||
},
|
||||
}
|
||||
|
||||
_reloadCdmaOperatorName() {
|
||||
let sid = this._proxy_cdma.Sid;
|
||||
this.operator_name_cdma = _findProviderForSid(sid);
|
||||
this._reloadOperatorName();
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(BroadbandModem.prototype);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const { Gio, GLib } = imports.gi;
|
||||
const Params = imports.misc.params;
|
||||
const Signals = imports.signals;
|
||||
|
||||
@@ -27,9 +25,8 @@ const ObjectManagerIface = `
|
||||
|
||||
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
|
||||
|
||||
var ObjectManager = new Lang.Class({
|
||||
Name: 'ObjectManager',
|
||||
_init(params) {
|
||||
var ObjectManager = class {
|
||||
constructor(params) {
|
||||
params = Params.parse(params, { connection: null,
|
||||
name: null,
|
||||
objectPath: null,
|
||||
@@ -63,7 +60,7 @@ var ObjectManager = new Lang.Class({
|
||||
this._managerProxy.init_async(GLib.PRIORITY_DEFAULT,
|
||||
this._cancellable,
|
||||
this._onManagerProxyLoaded.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_tryToCompleteLoad() {
|
||||
if (this._numLoadInhibitors == 0)
|
||||
@@ -74,62 +71,59 @@ var ObjectManager = new Lang.Class({
|
||||
if (this._onLoaded)
|
||||
this._onLoaded();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_addInterface(objectPath, interfaceName, onFinished) {
|
||||
let info = this._interfaceInfos[interfaceName];
|
||||
|
||||
if (!info) {
|
||||
if (onFinished)
|
||||
onFinished();
|
||||
return;
|
||||
if (onFinished)
|
||||
onFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
let proxy = new Gio.DBusProxy({ g_connection: this._connection,
|
||||
g_name: this._serviceName,
|
||||
g_object_path: objectPath,
|
||||
g_interface_name: interfaceName,
|
||||
g_interface_info: info,
|
||||
g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START });
|
||||
g_name: this._serviceName,
|
||||
g_object_path: objectPath,
|
||||
g_interface_name: interfaceName,
|
||||
g_interface_info: info,
|
||||
g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START });
|
||||
|
||||
proxy.init_async(GLib.PRIORITY_DEFAULT,
|
||||
this._cancellable,
|
||||
(initable, result) => {
|
||||
let error = null;
|
||||
try {
|
||||
initable.init_finish(result);
|
||||
} catch(e) {
|
||||
logError(e, 'could not initialize proxy for interface ' + interfaceName);
|
||||
proxy.init_async(GLib.PRIORITY_DEFAULT, this._cancellable, (initable, result) => {
|
||||
try {
|
||||
initable.init_finish(result);
|
||||
} catch (e) {
|
||||
logError(e, `could not initialize proxy for interface ${interfaceName}`);
|
||||
|
||||
if (onFinished)
|
||||
onFinished();
|
||||
return;
|
||||
}
|
||||
if (onFinished)
|
||||
onFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
let isNewObject;
|
||||
if (!this._objects[objectPath]) {
|
||||
this._objects[objectPath] = {};
|
||||
isNewObject = true;
|
||||
} else {
|
||||
isNewObject = false;
|
||||
}
|
||||
let isNewObject;
|
||||
if (!this._objects[objectPath]) {
|
||||
this._objects[objectPath] = {};
|
||||
isNewObject = true;
|
||||
} else {
|
||||
isNewObject = false;
|
||||
}
|
||||
|
||||
this._objects[objectPath][interfaceName] = proxy;
|
||||
this._objects[objectPath][interfaceName] = proxy;
|
||||
|
||||
if (!this._interfaces[interfaceName])
|
||||
this._interfaces[interfaceName] = [];
|
||||
if (!this._interfaces[interfaceName])
|
||||
this._interfaces[interfaceName] = [];
|
||||
|
||||
this._interfaces[interfaceName].push(proxy);
|
||||
this._interfaces[interfaceName].push(proxy);
|
||||
|
||||
if (isNewObject)
|
||||
this.emit('object-added', objectPath);
|
||||
if (isNewObject)
|
||||
this.emit('object-added', objectPath);
|
||||
|
||||
this.emit('interface-added', interfaceName, proxy);
|
||||
this.emit('interface-added', interfaceName, proxy);
|
||||
|
||||
if (onFinished)
|
||||
onFinished();
|
||||
if (onFinished)
|
||||
onFinished();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_removeInterface(objectPath, interfaceName) {
|
||||
if (!this._objects[objectPath])
|
||||
@@ -155,14 +149,13 @@ var ObjectManager = new Lang.Class({
|
||||
delete this._objects[objectPath];
|
||||
this.emit('object-removed', objectPath);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_onManagerProxyLoaded(initable, result) {
|
||||
let error = null;
|
||||
try {
|
||||
initable.init_finish(result);
|
||||
} catch(e) {
|
||||
logError(e, 'could not initialize object manager for object ' + params.name);
|
||||
} catch (e) {
|
||||
logError(e, `could not initialize object manager for object ${this._serviceName}`);
|
||||
|
||||
this._tryToCompleteLoad();
|
||||
return;
|
||||
@@ -194,13 +187,13 @@ var ObjectManager = new Lang.Class({
|
||||
|
||||
if (this._managerProxy.g_name_owner)
|
||||
this._onNameAppeared();
|
||||
},
|
||||
}
|
||||
|
||||
_onNameAppeared() {
|
||||
this._managerProxy.GetManagedObjectsRemote((result, error) => {
|
||||
if (!result) {
|
||||
if (error) {
|
||||
logError(error, 'could not get remote objects for service ' + this._serviceName + ' path ' + this._managerPath);
|
||||
logError(error, `could not get remote objects for service ${this._serviceName} path ${this._managerPath}`);
|
||||
}
|
||||
|
||||
this._tryToCompleteLoad();
|
||||
@@ -232,7 +225,7 @@ var ObjectManager = new Lang.Class({
|
||||
}
|
||||
this._tryToCompleteLoad();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_onNameVanished() {
|
||||
let objectPaths = Object.keys(this._objects);
|
||||
@@ -248,14 +241,14 @@ var ObjectManager = new Lang.Class({
|
||||
this._removeInterface(objectPath, interfaceName);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_registerInterfaces(interfaces) {
|
||||
for (let i = 0; i < interfaces.length; i++) {
|
||||
let info = Gio.DBusInterfaceInfo.new_for_xml(interfaces[i]);
|
||||
this._interfaceInfos[info.name] = info;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
getProxy(objectPath, interfaceName) {
|
||||
let object = this._objects[objectPath];
|
||||
@@ -264,7 +257,7 @@ var ObjectManager = new Lang.Class({
|
||||
return null;
|
||||
|
||||
return object[interfaceName];
|
||||
},
|
||||
}
|
||||
|
||||
getProxiesForInterface(interfaceName) {
|
||||
let proxyList = this._interfaces[interfaceName];
|
||||
@@ -273,7 +266,7 @@ var ObjectManager = new Lang.Class({
|
||||
return [];
|
||||
|
||||
return proxyList;
|
||||
},
|
||||
}
|
||||
|
||||
getAllProxies() {
|
||||
let proxies = [];
|
||||
@@ -283,8 +276,8 @@ var ObjectManager = new Lang.Class({
|
||||
let object = this._objects[objectPaths];
|
||||
|
||||
let interfaceNames = Object.keys(object);
|
||||
for (let j = 0; i < interfaceNames.length; i++) {
|
||||
let interfaceName = interfaceNames[i];
|
||||
for (let j = 0; j < interfaceNames.length; j++) {
|
||||
let interfaceName = interfaceNames[j];
|
||||
if (object[interfaceName])
|
||||
proxies.push(object(interfaceName));
|
||||
}
|
||||
@@ -292,5 +285,5 @@ var ObjectManager = new Lang.Class({
|
||||
|
||||
return proxies;
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(ObjectManager.prototype);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported parse */
|
||||
|
||||
// parse:
|
||||
// @params: caller-provided parameter object, or %null
|
||||
@@ -14,22 +15,13 @@
|
||||
//
|
||||
// Return value: a new object, containing the merged parameters from
|
||||
// @params and @defaults
|
||||
function parse(params, defaults, allowExtras) {
|
||||
let ret = {}, prop;
|
||||
|
||||
if (!params)
|
||||
params = {};
|
||||
|
||||
for (prop in params) {
|
||||
if (!(prop in defaults) && !allowExtras)
|
||||
throw new Error('Unrecognized parameter "' + prop + '"');
|
||||
ret[prop] = params[prop];
|
||||
function parse(params = {}, defaults, allowExtras) {
|
||||
if (!allowExtras) {
|
||||
for (let prop in params)
|
||||
if (!(prop in defaults))
|
||||
throw new Error(`Unrecognized parameter "${prop}"`);
|
||||
}
|
||||
|
||||
for (prop in defaults) {
|
||||
if (!(prop in params))
|
||||
ret[prop] = defaults[prop];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
let defaultsCopy = Object.assign({}, defaults);
|
||||
return Object.assign(defaultsCopy, params);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported PermissionStore */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
|
||||
@@ -12,4 +13,4 @@ function PermissionStore(initCallback, cancellable) {
|
||||
'org.freedesktop.impl.portal.PermissionStore',
|
||||
'/org/freedesktop/impl/portal/PermissionStore',
|
||||
initCallback, cancellable);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getSmartcardManager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const ObjectManager = imports.misc.objectManager;
|
||||
@@ -26,17 +25,16 @@ function getSmartcardManager() {
|
||||
return _smartcardManager;
|
||||
}
|
||||
|
||||
var SmartcardManager = new Lang.Class({
|
||||
Name: 'SmartcardManager',
|
||||
_init() {
|
||||
var SmartcardManager = class {
|
||||
constructor() {
|
||||
this._objectManager = new ObjectManager.ObjectManager({ connection: Gio.DBus.session,
|
||||
name: "org.gnome.SettingsDaemon.Smartcard",
|
||||
objectPath: '/org/gnome/SettingsDaemon/Smartcard',
|
||||
knownInterfaces: [ SmartcardTokenIface ],
|
||||
knownInterfaces: [SmartcardTokenIface],
|
||||
onLoaded: this._onLoaded.bind(this) });
|
||||
this._insertedTokens = {};
|
||||
this._loginToken = null;
|
||||
},
|
||||
}
|
||||
|
||||
_onLoaded() {
|
||||
let tokens = this._objectManager.getProxiesForInterface('org.gnome.SettingsDaemon.Smartcard.Token');
|
||||
@@ -53,7 +51,7 @@ var SmartcardManager = new Lang.Class({
|
||||
if (interfaceName == 'org.gnome.SettingsDaemon.Smartcard.Token')
|
||||
this._removeToken(proxy);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_updateToken(token) {
|
||||
let objectPath = token.get_object_path();
|
||||
@@ -65,7 +63,7 @@ var SmartcardManager = new Lang.Class({
|
||||
|
||||
if (token.UsedToLogin)
|
||||
this._loginToken = token;
|
||||
},
|
||||
}
|
||||
|
||||
_addToken(token) {
|
||||
this._updateToken(token);
|
||||
@@ -85,7 +83,7 @@ var SmartcardManager = new Lang.Class({
|
||||
// Emit a smartcard-inserted at startup if it's already plugged in
|
||||
if (token.IsInserted)
|
||||
this.emit('smartcard-inserted', token);
|
||||
},
|
||||
}
|
||||
|
||||
_removeToken(token) {
|
||||
let objectPath = token.get_object_path();
|
||||
@@ -99,11 +97,11 @@ var SmartcardManager = new Lang.Class({
|
||||
this._loginToken = null;
|
||||
|
||||
token.disconnectAll();
|
||||
},
|
||||
}
|
||||
|
||||
hasInsertedTokens() {
|
||||
return Object.keys(this._insertedTokens).length > 0;
|
||||
},
|
||||
}
|
||||
|
||||
hasInsertedLoginToken() {
|
||||
if (!this._loginToken)
|
||||
@@ -115,5 +113,5 @@ var SmartcardManager = new Lang.Class({
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(SmartcardManager.prototype);
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
const AccountsService = imports.gi.AccountsService;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gdm = imports.gi.Gdm;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const GObject = imports.gi.GObject;
|
||||
/* exported getDefault */
|
||||
const { AccountsService, Clutter, Gdm, Gio, GLib, GObject, Meta } = imports.gi;
|
||||
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
@@ -44,9 +38,7 @@ function getDefault() {
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
const SystemActions = new Lang.Class({
|
||||
Name: 'SystemActions',
|
||||
Extends: GObject.Object,
|
||||
const SystemActions = GObject.registerClass({
|
||||
Properties: {
|
||||
'can-power-off': GObject.ParamSpec.boolean('can-power-off',
|
||||
'can-power-off',
|
||||
@@ -83,57 +75,63 @@ const SystemActions = new Lang.Class({
|
||||
'orientation-lock-icon',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
null)
|
||||
},
|
||||
|
||||
}
|
||||
}, class SystemActions extends GObject.Object {
|
||||
_init() {
|
||||
this.parent();
|
||||
super._init();
|
||||
|
||||
this._canHavePowerOff = true;
|
||||
this._canHaveSuspend = true;
|
||||
|
||||
this._actions = new Map();
|
||||
this._actions.set(POWER_OFF_ACTION_ID,
|
||||
{ // Translators: The name of the power-off action in search
|
||||
name: C_("search-result", "Power Off"),
|
||||
iconName: 'system-shutdown-symbolic',
|
||||
// Translators: A list of keywords that match the power-off action, separated by semicolons
|
||||
keywords: _("power off;shutdown;reboot;restart").split(';'),
|
||||
available: false });
|
||||
this._actions.set(LOCK_SCREEN_ACTION_ID,
|
||||
{ // Translators: The name of the lock screen action in search
|
||||
name: C_("search-result", "Lock Screen"),
|
||||
iconName: 'system-lock-screen-symbolic',
|
||||
// Translators: A list of keywords that match the lock screen action, separated by semicolons
|
||||
keywords: _("lock screen").split(';'),
|
||||
available: false });
|
||||
this._actions.set(LOGOUT_ACTION_ID,
|
||||
{ // Translators: The name of the logout action in search
|
||||
name: C_("search-result", "Log Out"),
|
||||
iconName: 'application-exit-symbolic',
|
||||
// Translators: A list of keywords that match the logout action, separated by semicolons
|
||||
keywords: _("logout;sign off").split(';'),
|
||||
available: false });
|
||||
this._actions.set(SUSPEND_ACTION_ID,
|
||||
{ // Translators: The name of the suspend action in search
|
||||
name: C_("search-result", "Suspend"),
|
||||
iconName: 'media-playback-pause-symbolic',
|
||||
// Translators: A list of keywords that match the suspend action, separated by semicolons
|
||||
keywords: _("suspend;sleep").split(';'),
|
||||
available: false });
|
||||
this._actions.set(SWITCH_USER_ACTION_ID,
|
||||
{ // Translators: The name of the switch user action in search
|
||||
name: C_("search-result", "Switch User"),
|
||||
iconName: 'system-switch-user-symbolic',
|
||||
// Translators: A list of keywords that match the switch user action, separated by semicolons
|
||||
keywords: _("switch user").split(';'),
|
||||
available: false });
|
||||
this._actions.set(LOCK_ORIENTATION_ACTION_ID,
|
||||
{ // Translators: The name of the lock orientation action in search
|
||||
name: C_("search-result", "Lock Orientation"),
|
||||
iconName: '',
|
||||
// Translators: A list of keywords that match the lock orientation action, separated by semicolons
|
||||
keywords: _("lock orientation;screen;rotation").split(';'),
|
||||
available: false });
|
||||
this._actions.set(POWER_OFF_ACTION_ID, {
|
||||
// Translators: The name of the power-off action in search
|
||||
name: C_("search-result", "Power Off"),
|
||||
iconName: 'system-shutdown-symbolic',
|
||||
// Translators: A list of keywords that match the power-off action, separated by semicolons
|
||||
keywords: _("power off;shutdown;reboot;restart").split(/[; ]/),
|
||||
available: false
|
||||
});
|
||||
this._actions.set(LOCK_SCREEN_ACTION_ID, {
|
||||
// Translators: The name of the lock screen action in search
|
||||
name: C_("search-result", "Lock Screen"),
|
||||
iconName: 'system-lock-screen-symbolic',
|
||||
// Translators: A list of keywords that match the lock screen action, separated by semicolons
|
||||
keywords: _("lock screen").split(/[; ]/),
|
||||
available: false
|
||||
});
|
||||
this._actions.set(LOGOUT_ACTION_ID, {
|
||||
// Translators: The name of the logout action in search
|
||||
name: C_("search-result", "Log Out"),
|
||||
iconName: 'application-exit-symbolic',
|
||||
// Translators: A list of keywords that match the logout action, separated by semicolons
|
||||
keywords: _("logout;log out;sign off").split(/[; ]/),
|
||||
available: false
|
||||
});
|
||||
this._actions.set(SUSPEND_ACTION_ID, {
|
||||
// Translators: The name of the suspend action in search
|
||||
name: C_("search-result", "Suspend"),
|
||||
iconName: 'media-playback-pause-symbolic',
|
||||
// Translators: A list of keywords that match the suspend action, separated by semicolons
|
||||
keywords: _("suspend;sleep").split(/[; ]/),
|
||||
available: false
|
||||
});
|
||||
this._actions.set(SWITCH_USER_ACTION_ID, {
|
||||
// Translators: The name of the switch user action in search
|
||||
name: C_("search-result", "Switch User"),
|
||||
iconName: 'system-switch-user-symbolic',
|
||||
// Translators: A list of keywords that match the switch user action, separated by semicolons
|
||||
keywords: _("switch user").split(/[; ]/),
|
||||
available: false
|
||||
});
|
||||
this._actions.set(LOCK_ORIENTATION_ACTION_ID, {
|
||||
// Translators: The name of the lock orientation action in search
|
||||
name: C_("search-result", "Lock Orientation"),
|
||||
iconName: '',
|
||||
// Translators: A list of keywords that match the lock orientation action, separated by semicolons
|
||||
keywords: _("lock orientation;screen;rotation").split(/[; ]/),
|
||||
available: false
|
||||
});
|
||||
|
||||
this._loginScreenSettings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA });
|
||||
this._lockdownSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA });
|
||||
@@ -146,99 +144,103 @@ const SystemActions = new Lang.Class({
|
||||
this._userManager = AccountsService.UserManager.get_default();
|
||||
|
||||
this._userManager.connect('notify::is-loaded',
|
||||
() => { this._updateMultiUser(); });
|
||||
() => this._updateMultiUser());
|
||||
this._userManager.connect('notify::has-multiple-users',
|
||||
() => { this._updateMultiUser(); });
|
||||
() => this._updateMultiUser());
|
||||
this._userManager.connect('user-added',
|
||||
() => { this._updateMultiUser(); });
|
||||
() => this._updateMultiUser());
|
||||
this._userManager.connect('user-removed',
|
||||
() => { this._updateMultiUser(); });
|
||||
() => this._updateMultiUser());
|
||||
|
||||
this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY,
|
||||
() => { this._updateSwitchUser(); });
|
||||
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
|
||||
() => { this._updateLogout(); });
|
||||
global.settings.connect('changed::' + ALWAYS_SHOW_LOG_OUT_KEY,
|
||||
() => { this._updateLogout(); });
|
||||
this._lockdownSettings.connect(`changed::${DISABLE_USER_SWITCH_KEY}`,
|
||||
() => this._updateSwitchUser());
|
||||
this._lockdownSettings.connect(`changed::${DISABLE_LOG_OUT_KEY}`,
|
||||
() => this._updateLogout());
|
||||
global.settings.connect(`changed::${ALWAYS_SHOW_LOG_OUT_KEY}`,
|
||||
() => this._updateLogout());
|
||||
|
||||
this._lockdownSettings.connect('changed::' + DISABLE_LOCK_SCREEN_KEY,
|
||||
() => { this._updateLockScreen(); });
|
||||
this._lockdownSettings.connect(`changed::${DISABLE_LOCK_SCREEN_KEY}`,
|
||||
() => this._updateLockScreen());
|
||||
|
||||
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
|
||||
() => { this._updateHaveShutdown(); });
|
||||
this._lockdownSettings.connect(`changed::${DISABLE_LOG_OUT_KEY}`,
|
||||
() => this._updateHaveShutdown());
|
||||
|
||||
this.forceUpdate();
|
||||
|
||||
this._orientationSettings.connect('changed::orientation-lock',
|
||||
() => { this._updateOrientationLock();
|
||||
this._updateOrientationLockIcon(); });
|
||||
() => {
|
||||
this._updateOrientationLock();
|
||||
this._updateOrientationLockIcon();
|
||||
});
|
||||
Main.layoutManager.connect('monitors-changed',
|
||||
() => { this._updateOrientationLock(); });
|
||||
Gio.DBus.system.watch_name(SENSOR_BUS_NAME,
|
||||
Gio.BusNameWatcherFlags.NONE,
|
||||
() => { this._sensorProxyAppeared(); },
|
||||
() => {
|
||||
this._sensorProxy = null;
|
||||
this._updateOrientationLock();
|
||||
});
|
||||
() => this._updateOrientationLock());
|
||||
this._sensorProxy = new SensorProxy(Gio.DBus.system,
|
||||
SENSOR_BUS_NAME,
|
||||
SENSOR_OBJECT_PATH,
|
||||
(proxy, error) => {
|
||||
if (error)
|
||||
log(error.message);
|
||||
},
|
||||
null,
|
||||
Gio.DBusProxyFlags.DO_NOT_AUTO_START);
|
||||
this._sensorProxy.connect('g-properties-changed', () => {
|
||||
this._updateOrientationLock();
|
||||
});
|
||||
this._sensorProxy.connect('notify::g-name-owner', () => {
|
||||
this._updateOrientationLock();
|
||||
});
|
||||
this._updateOrientationLock();
|
||||
this._updateOrientationLockIcon();
|
||||
|
||||
Main.sessionMode.connect('updated', () => { this._sessionUpdated(); });
|
||||
Main.sessionMode.connect('updated', () => this._sessionUpdated());
|
||||
this._sessionUpdated();
|
||||
},
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get can_power_off() {
|
||||
return this._actions.get(POWER_OFF_ACTION_ID).available;
|
||||
},
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get can_suspend() {
|
||||
return this._actions.get(SUSPEND_ACTION_ID).available;
|
||||
},
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get can_lock_screen() {
|
||||
return this._actions.get(LOCK_SCREEN_ACTION_ID).available;
|
||||
},
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get can_switch_user() {
|
||||
return this._actions.get(SWITCH_USER_ACTION_ID).available;
|
||||
},
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get can_logout() {
|
||||
return this._actions.get(LOGOUT_ACTION_ID).available;
|
||||
},
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get can_lock_orientation() {
|
||||
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).available;
|
||||
},
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get orientation_lock_icon() {
|
||||
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName;
|
||||
},
|
||||
|
||||
_sensorProxyAppeared() {
|
||||
this._sensorProxy = new SensorProxy(Gio.DBus.system, SENSOR_BUS_NAME, SENSOR_OBJECT_PATH,
|
||||
(proxy, error) => {
|
||||
if (error) {
|
||||
log(error.message);
|
||||
return;
|
||||
}
|
||||
this._sensorProxy.connect('g-properties-changed',
|
||||
() => { this._updateOrientationLock(); });
|
||||
this._updateOrientationLock();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_updateOrientationLock() {
|
||||
let available = false;
|
||||
if (this._sensorProxy)
|
||||
if (this._sensorProxy.g_name_owner)
|
||||
available = this._sensorProxy.HasAccelerometer &&
|
||||
this._monitorManager.get_is_builtin_display_on();
|
||||
|
||||
this._actions.get(LOCK_ORIENTATION_ACTION_ID).available = available;
|
||||
|
||||
this.notify('can-lock-orientation');
|
||||
},
|
||||
}
|
||||
|
||||
_updateOrientationLockIcon() {
|
||||
let locked = this._orientationSettings.get_boolean('orientation-lock');
|
||||
@@ -247,14 +249,14 @@ const SystemActions = new Lang.Class({
|
||||
this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName = iconName;
|
||||
|
||||
this.notify('orientation-lock-icon');
|
||||
},
|
||||
}
|
||||
|
||||
_sessionUpdated() {
|
||||
this._updateLockScreen();
|
||||
this._updatePowerOff();
|
||||
this._updateSuspend();
|
||||
this._updateMultiUser();
|
||||
},
|
||||
}
|
||||
|
||||
forceUpdate() {
|
||||
// Whether those actions are available or not depends on both lockdown
|
||||
@@ -262,58 +264,58 @@ const SystemActions = new Lang.Class({
|
||||
// latter, so their value may be outdated; force an update now
|
||||
this._updateHaveShutdown();
|
||||
this._updateHaveSuspend();
|
||||
},
|
||||
}
|
||||
|
||||
getMatchingActions(terms) {
|
||||
// terms is a list of strings
|
||||
terms = terms.map((term) => { return term.toLowerCase(); });
|
||||
terms = terms.map((term) => term.toLowerCase());
|
||||
|
||||
let results = [];
|
||||
|
||||
for (let [key, {available, keywords}] of this._actions)
|
||||
if (available && terms.every(t => keywords.some(k => (k.indexOf(t) >= 0))))
|
||||
for (let [key, { available, keywords }] of this._actions)
|
||||
if (available && terms.every(t => keywords.some(k => k.startsWith(t))))
|
||||
results.push(key);
|
||||
|
||||
return results;
|
||||
},
|
||||
}
|
||||
|
||||
getName(id) {
|
||||
return this._actions.get(id).name;
|
||||
},
|
||||
}
|
||||
|
||||
getIconName(id) {
|
||||
return this._actions.get(id).iconName;
|
||||
},
|
||||
}
|
||||
|
||||
activateAction(id) {
|
||||
switch (id) {
|
||||
case POWER_OFF_ACTION_ID:
|
||||
this.activatePowerOff();
|
||||
break;
|
||||
case LOCK_SCREEN_ACTION_ID:
|
||||
this.activateLockScreen();
|
||||
break;
|
||||
case LOGOUT_ACTION_ID:
|
||||
this.activateLogout();
|
||||
break;
|
||||
case SUSPEND_ACTION_ID:
|
||||
this.activateSuspend();
|
||||
break;
|
||||
case SWITCH_USER_ACTION_ID:
|
||||
this.activateSwitchUser();
|
||||
break;
|
||||
case LOCK_ORIENTATION_ACTION_ID:
|
||||
this.activateLockOrientation();
|
||||
break;
|
||||
case POWER_OFF_ACTION_ID:
|
||||
this.activatePowerOff();
|
||||
break;
|
||||
case LOCK_SCREEN_ACTION_ID:
|
||||
this.activateLockScreen();
|
||||
break;
|
||||
case LOGOUT_ACTION_ID:
|
||||
this.activateLogout();
|
||||
break;
|
||||
case SUSPEND_ACTION_ID:
|
||||
this.activateSuspend();
|
||||
break;
|
||||
case SWITCH_USER_ACTION_ID:
|
||||
this.activateSwitchUser();
|
||||
break;
|
||||
case LOCK_ORIENTATION_ACTION_ID:
|
||||
this.activateLockOrientation();
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_updateLockScreen() {
|
||||
let showLock = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
|
||||
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
|
||||
this._actions.get(LOCK_SCREEN_ACTION_ID).available = showLock && allowLockScreen && LoginManager.canLock();
|
||||
this.notify('can-lock-screen');
|
||||
},
|
||||
}
|
||||
|
||||
_updateHaveShutdown() {
|
||||
this._session.CanShutdownRemote((result, error) => {
|
||||
@@ -323,7 +325,7 @@ const SystemActions = new Lang.Class({
|
||||
this._canHavePowerOff = result[0];
|
||||
this._updatePowerOff();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_updatePowerOff() {
|
||||
let disabled = Main.sessionMode.isLocked ||
|
||||
@@ -331,7 +333,7 @@ const SystemActions = new Lang.Class({
|
||||
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
|
||||
this._actions.get(POWER_OFF_ACTION_ID).available = this._canHavePowerOff && !disabled;
|
||||
this.notify('can-power-off');
|
||||
},
|
||||
}
|
||||
|
||||
_updateHaveSuspend() {
|
||||
this._loginManager.canSuspend(
|
||||
@@ -340,7 +342,7 @@ const SystemActions = new Lang.Class({
|
||||
this._suspendNeedsAuth = needsAuth;
|
||||
this._updateSuspend();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_updateSuspend() {
|
||||
let disabled = (Main.sessionMode.isLocked &&
|
||||
@@ -349,12 +351,12 @@ const SystemActions = new Lang.Class({
|
||||
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
|
||||
this._actions.get(SUSPEND_ACTION_ID).available = this._canHaveSuspend && !disabled;
|
||||
this.notify('can-suspend');
|
||||
},
|
||||
}
|
||||
|
||||
_updateMultiUser() {
|
||||
this._updateLogout();
|
||||
this._updateSwitchUser();
|
||||
},
|
||||
}
|
||||
|
||||
_updateSwitchUser() {
|
||||
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
|
||||
@@ -366,7 +368,7 @@ const SystemActions = new Lang.Class({
|
||||
this.notify('can-switch-user');
|
||||
|
||||
return visible;
|
||||
},
|
||||
}
|
||||
|
||||
_updateLogout() {
|
||||
let user = this._userManager.get_user(GLib.get_user_name());
|
||||
@@ -384,7 +386,7 @@ const SystemActions = new Lang.Class({
|
||||
this.notify('can-logout');
|
||||
|
||||
return visible;
|
||||
},
|
||||
}
|
||||
|
||||
activateLockOrientation() {
|
||||
if (!this._actions.get(LOCK_ORIENTATION_ACTION_ID).available)
|
||||
@@ -392,14 +394,14 @@ const SystemActions = new Lang.Class({
|
||||
|
||||
let locked = this._orientationSettings.get_boolean('orientation-lock');
|
||||
this._orientationSettings.set_boolean('orientation-lock', !locked);
|
||||
},
|
||||
}
|
||||
|
||||
activateLockScreen() {
|
||||
if (!this._actions.get(LOCK_SCREEN_ACTION_ID).available)
|
||||
throw new Error('The lock-screen action is not available!');
|
||||
|
||||
Main.screenShield.lock(true);
|
||||
},
|
||||
}
|
||||
|
||||
activateSwitchUser() {
|
||||
if (!this._actions.get(SWITCH_USER_ACTION_ID).available)
|
||||
@@ -412,7 +414,7 @@ const SystemActions = new Lang.Class({
|
||||
Gdm.goto_login_session_sync(null);
|
||||
return false;
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
activateLogout() {
|
||||
if (!this._actions.get(LOGOUT_ACTION_ID).available)
|
||||
@@ -420,14 +422,14 @@ const SystemActions = new Lang.Class({
|
||||
|
||||
Main.overview.hide();
|
||||
this._session.LogoutRemote(0);
|
||||
},
|
||||
}
|
||||
|
||||
activatePowerOff() {
|
||||
if (!this._actions.get(POWER_OFF_ACTION_ID).available)
|
||||
throw new Error('The power-off action is not available!');
|
||||
|
||||
this._session.ShutdownRemote(0);
|
||||
},
|
||||
}
|
||||
|
||||
activateSuspend() {
|
||||
if (!this._actions.get(SUSPEND_ACTION_ID).available)
|
||||
|
||||
186
js/misc/util.js
@@ -1,20 +1,16 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine,
|
||||
formatTime, formatTimeSpan, createTimeLabel, insertSorted,
|
||||
makeCloseButton, ensureActorVisibleInScrollView */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi;
|
||||
const Gettext = imports.gettext;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Signals = imports.signals;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Params = imports.misc.params;
|
||||
|
||||
var SCROLL_TIME = 0.1;
|
||||
var SCROLL_TIME = 100;
|
||||
|
||||
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||
const _balancedParens = '\\([^\\s()<>]+\\)';
|
||||
@@ -22,7 +18,7 @@ const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
|
||||
const _notTrailingJunk = '[^\\s`!()\\[\\]{};:\'\\".,<>?\u00AB\u00BB\u201C\u201D\u2018\u2019]';
|
||||
|
||||
const _urlRegexp = new RegExp(
|
||||
'(^|' + _leadingJunk + ')' +
|
||||
`(^|${_leadingJunk})` +
|
||||
'(' +
|
||||
'(?:' +
|
||||
'(?:http|https|ftp)://' + // scheme://
|
||||
@@ -34,12 +30,12 @@ const _urlRegexp = new RegExp(
|
||||
'(?:' + // one or more:
|
||||
'[^\\s()<>]+' + // run of non-space non-()
|
||||
'|' + // or
|
||||
_balancedParens + // balanced parens
|
||||
`${_balancedParens}` + // balanced parens
|
||||
')+' +
|
||||
'(?:' + // end with:
|
||||
_balancedParens + // balanced parens
|
||||
`${_balancedParens}` + // balanced parens
|
||||
'|' + // or
|
||||
_notTrailingJunk + // last non-junk char
|
||||
`${_notTrailingJunk}` + // last non-junk char
|
||||
')' +
|
||||
')', 'gi');
|
||||
|
||||
@@ -74,16 +70,16 @@ function spawn(argv) {
|
||||
}
|
||||
|
||||
// spawnCommandLine:
|
||||
// @command_line: a command line
|
||||
// @commandLine: a command line
|
||||
//
|
||||
// Runs @command_line in the background, handling any errors that
|
||||
// Runs @commandLine in the background, handling any errors that
|
||||
// occur when trying to parse or start the program.
|
||||
function spawnCommandLine(command_line) {
|
||||
function spawnCommandLine(commandLine) {
|
||||
try {
|
||||
let [success, argv] = GLib.shell_parse_argv(command_line);
|
||||
let [success_, argv] = GLib.shell_parse_argv(commandLine);
|
||||
trySpawn(argv);
|
||||
} catch (err) {
|
||||
_handleSpawnError(command_line, err);
|
||||
_handleSpawnError(commandLine, err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +94,7 @@ function spawnApp(argv) {
|
||||
|
||||
let context = global.create_app_launch_context(0, -1);
|
||||
app.launch([], context);
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
_handleSpawnError(argv[0], err);
|
||||
}
|
||||
}
|
||||
@@ -108,13 +104,12 @@ function spawnApp(argv) {
|
||||
//
|
||||
// Runs @argv in the background. If launching @argv fails,
|
||||
// this will throw an error.
|
||||
function trySpawn(argv)
|
||||
{
|
||||
var success, pid;
|
||||
function trySpawn(argv) {
|
||||
var success_, pid;
|
||||
try {
|
||||
[success, pid] = GLib.spawn_async(null, argv, null,
|
||||
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
|
||||
null);
|
||||
[success_, pid] = GLib.spawn_async(null, argv, null,
|
||||
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
|
||||
null);
|
||||
} catch (err) {
|
||||
/* Rewrite the error in case of ENOENT */
|
||||
if (err.matches(GLib.SpawnError, GLib.SpawnError.NOENT)) {
|
||||
@@ -140,19 +135,19 @@ function trySpawn(argv)
|
||||
}
|
||||
|
||||
// trySpawnCommandLine:
|
||||
// @command_line: a command line
|
||||
// @commandLine: a command line
|
||||
//
|
||||
// Runs @command_line in the background. If launching @command_line
|
||||
// Runs @commandLine in the background. If launching @commandLine
|
||||
// fails, this will throw an error.
|
||||
function trySpawnCommandLine(command_line) {
|
||||
let success, argv;
|
||||
function trySpawnCommandLine(commandLine) {
|
||||
let success_, argv;
|
||||
|
||||
try {
|
||||
[success, argv] = GLib.shell_parse_argv(command_line);
|
||||
[success_, argv] = GLib.shell_parse_argv(commandLine);
|
||||
} catch (err) {
|
||||
// Replace "Error invoking GLib.shell_parse_argv: " with
|
||||
// something nicer
|
||||
err.message = err.message.replace(/[^:]*: /, _("Could not parse command:") + "\n");
|
||||
err.message = err.message.replace(/[^:]*: /, `${_("Could not parse command:")}\n`);
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -227,7 +222,7 @@ function formatTime(time, params) {
|
||||
/* Translators: Time in 24h format */
|
||||
format = N_("%H\u2236%M");
|
||||
// Show the word "Yesterday" and time if date is on yesterday
|
||||
else if (daysAgo <2)
|
||||
else if (daysAgo < 2)
|
||||
/* Translators: this is the word "Yesterday" followed by a
|
||||
time string in 24h format. i.e. "Yesterday, 14:30" */
|
||||
// xgettext:no-c-format
|
||||
@@ -256,7 +251,7 @@ function formatTime(time, params) {
|
||||
/* Translators: Time in 12h format */
|
||||
format = N_("%l\u2236%M %p");
|
||||
// Show the word "Yesterday" and time if date is on yesterday
|
||||
else if (daysAgo <2)
|
||||
else if (daysAgo < 2)
|
||||
/* Translators: this is the word "Yesterday" followed by a
|
||||
time string in 12h format. i.e. "Yesterday, 2:30 pm" */
|
||||
// xgettext:no-c-format
|
||||
@@ -294,7 +289,7 @@ function createTimeLabel(date, params) {
|
||||
let id = _desktopSettings.connect('changed::clock-format', () => {
|
||||
label.text = formatTime(date, params);
|
||||
});
|
||||
label.connect('destroy', () => { _desktopSettings.disconnect(id); });
|
||||
label.connect('destroy', () => _desktopSettings.disconnect(id));
|
||||
return label;
|
||||
}
|
||||
|
||||
@@ -348,12 +343,10 @@ function insertSorted(array, val, cmp) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
var CloseButton = new Lang.Class({
|
||||
Name: 'CloseButton',
|
||||
Extends: St.Button,
|
||||
|
||||
var CloseButton = GObject.registerClass(
|
||||
class CloseButton extends St.Button {
|
||||
_init(boxpointer) {
|
||||
this.parent({ style_class: 'notification-close'});
|
||||
super._init({ style_class: 'notification-close' });
|
||||
|
||||
// This is a bit tricky. St.Bin has its own x-align/y-align properties
|
||||
// that compete with Clutter's properties. This should be fixed for
|
||||
@@ -370,10 +363,10 @@ var CloseButton = new Lang.Class({
|
||||
this._boxPointer = boxpointer;
|
||||
if (boxpointer)
|
||||
this._boxPointer.connect('arrow-side-changed', this._sync.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_computeBoxPointerOffset() {
|
||||
if (!this._boxPointer || !this._boxPointer.actor.get_stage())
|
||||
if (!this._boxPointer || !this._boxPointer.get_stage())
|
||||
return 0;
|
||||
|
||||
let side = this._boxPointer.arrowSide;
|
||||
@@ -381,20 +374,20 @@ var CloseButton = new Lang.Class({
|
||||
return this._boxPointer.getArrowHeight();
|
||||
else
|
||||
return 0;
|
||||
},
|
||||
}
|
||||
|
||||
_sync() {
|
||||
let themeNode = this.get_theme_node();
|
||||
|
||||
let offY = this._computeBoxPointerOffset();
|
||||
this.translation_x = themeNode.get_length('-shell-close-overlap-x')
|
||||
this.translation_x = themeNode.get_length('-shell-close-overlap-x');
|
||||
this.translation_y = themeNode.get_length('-shell-close-overlap-y') + offY;
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_style_changed() {
|
||||
this._sync();
|
||||
this.parent();
|
||||
},
|
||||
super.vfunc_style_changed();
|
||||
}
|
||||
});
|
||||
|
||||
function makeCloseButton(boxpointer) {
|
||||
@@ -403,7 +396,7 @@ function makeCloseButton(boxpointer) {
|
||||
|
||||
function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
let adjustment = scrollView.vscroll.adjustment;
|
||||
let [value, lower, upper, stepIncrement, pageIncrement, pageSize] = adjustment.get_values();
|
||||
let [value, lower_, upper, stepIncrement_, pageIncrement_, pageSize] = adjustment.get_values();
|
||||
|
||||
let offset = 0;
|
||||
let vfade = scrollView.get_effect("fade");
|
||||
@@ -431,99 +424,8 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
else
|
||||
return;
|
||||
|
||||
Tweener.addTween(adjustment,
|
||||
{ value: value,
|
||||
time: SCROLL_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
adjustment.ease(value, {
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
duration: SCROLL_TIME
|
||||
});
|
||||
}
|
||||
|
||||
var AppSettingsMonitor = new Lang.Class({
|
||||
Name: 'AppSettingsMonitor',
|
||||
|
||||
_init(appId, schemaId) {
|
||||
this._appId = appId;
|
||||
this._schemaId = schemaId;
|
||||
|
||||
this._app = null;
|
||||
this._settings = null;
|
||||
this._handlers = [];
|
||||
|
||||
this._schemaSource = Gio.SettingsSchemaSource.get_default();
|
||||
|
||||
this._appSystem = Shell.AppSystem.get_default();
|
||||
this._appSystem.connect('installed-changed',
|
||||
this._onInstalledChanged.bind(this));
|
||||
this._onInstalledChanged();
|
||||
},
|
||||
|
||||
get available() {
|
||||
return this._app != null && this._settings != null;
|
||||
},
|
||||
|
||||
activateApp() {
|
||||
if (this._app)
|
||||
this._app.activate();
|
||||
},
|
||||
|
||||
watchSetting(key, callback) {
|
||||
let handler = { id: 0, key: key, callback: callback };
|
||||
this._handlers.push(handler);
|
||||
|
||||
this._connectHandler(handler);
|
||||
},
|
||||
|
||||
_connectHandler(handler) {
|
||||
if (!this._settings || handler.id > 0)
|
||||
return;
|
||||
|
||||
handler.id = this._settings.connect('changed::' + handler.key,
|
||||
handler.callback);
|
||||
handler.callback(this._settings, handler.key);
|
||||
},
|
||||
|
||||
_disconnectHandler(handler) {
|
||||
if (this._settings && handler.id > 0)
|
||||
this._settings.disconnect(handler.id);
|
||||
handler.id = 0;
|
||||
},
|
||||
|
||||
_onInstalledChanged() {
|
||||
let hadApp = (this._app != null);
|
||||
this._app = this._appSystem.lookup_app(this._appId);
|
||||
let haveApp = (this._app != null);
|
||||
|
||||
if (hadApp == haveApp)
|
||||
return;
|
||||
|
||||
if (haveApp)
|
||||
this._checkSettings();
|
||||
else
|
||||
this._setSettings(null);
|
||||
},
|
||||
|
||||
_setSettings(settings) {
|
||||
this._handlers.forEach((handler) => { this._disconnectHandler(handler); });
|
||||
|
||||
let hadSettings = (this._settings != null);
|
||||
this._settings = settings;
|
||||
let haveSettings = (this._settings != null);
|
||||
|
||||
this._handlers.forEach((handler) => { this._connectHandler(handler); });
|
||||
|
||||
if (hadSettings != haveSettings)
|
||||
this.emit('available-changed');
|
||||
},
|
||||
|
||||
_checkSettings() {
|
||||
let schema = this._schemaSource.lookup(this._schemaId, true);
|
||||
if (schema) {
|
||||
this._setSettings(new Gio.Settings({ settings_schema: schema }));
|
||||
} else if (this._app) {
|
||||
Mainloop.timeout_add_seconds(1, () => {
|
||||
this._checkSettings();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(AppSettingsMonitor.prototype);
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Geoclue = imports.gi.Geoclue;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const GWeather = imports.gi.GWeather;
|
||||
const Lang = imports.lang;
|
||||
const { Geoclue, Gio, GLib, GWeather, Shell } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const PermissionStore = imports.misc.permissionStore;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
|
||||
const WeatherIntegrationIface = loadInterfaceXML('org.gnome.Shell.WeatherIntegration');
|
||||
|
||||
const WEATHER_BUS_NAME = 'org.gnome.Weather';
|
||||
const WEATHER_OBJECT_PATH = '/org/gnome/Weather';
|
||||
const WEATHER_INTEGRATION_IFACE = 'org.gnome.Shell.WeatherIntegration';
|
||||
|
||||
const WEATHER_APP_ID = 'org.gnome.Weather.desktop';
|
||||
|
||||
// Minimum time between updates to show loading indication
|
||||
var UPDATE_THRESHOLD = 10 * GLib.TIME_SPAN_MINUTE;
|
||||
|
||||
var WeatherClient = new Lang.Class({
|
||||
Name: 'WeatherClient',
|
||||
|
||||
_init() {
|
||||
var WeatherClient = class {
|
||||
constructor() {
|
||||
this._loading = false;
|
||||
this._locationValid = false;
|
||||
this._lastUpdate = GLib.DateTime.new_from_unix_local(0);
|
||||
@@ -32,13 +35,21 @@ var WeatherClient = new Lang.Class({
|
||||
this._weatherAuthorized = false;
|
||||
this._permStore = new PermissionStore.PermissionStore((proxy, error) => {
|
||||
if (error) {
|
||||
log('Failed to connect to permissionStore: ' + error.message);
|
||||
log(`Failed to connect to permissionStore: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._permStore.g_name_owner == null) {
|
||||
// Failed to auto-start, likely because xdg-desktop-portal
|
||||
// isn't installed; don't restrict access to location service
|
||||
this._weatherAuthorized = true;
|
||||
this._updateAutoLocation();
|
||||
return;
|
||||
}
|
||||
|
||||
this._permStore.LookupRemote('gnome', 'geolocation', (res, error) => {
|
||||
if (error)
|
||||
log('Error looking up permission: ' + error.message);
|
||||
log(`Error looking up permission: ${error.message}`);
|
||||
|
||||
let [perms, data] = error ? [{}, null] : res;
|
||||
let params = ['gnome', 'geolocation', false, data, perms];
|
||||
@@ -64,34 +75,56 @@ var WeatherClient = new Lang.Class({
|
||||
this.emit('changed');
|
||||
});
|
||||
|
||||
this._weatherAppMon = new Util.AppSettingsMonitor('org.gnome.Weather.Application.desktop',
|
||||
'org.gnome.Weather.Application');
|
||||
this._weatherAppMon.connect('available-changed', () => { this.emit('changed'); });
|
||||
this._weatherAppMon.watchSetting('automatic-location',
|
||||
this._onAutomaticLocationChanged.bind(this));
|
||||
this._weatherAppMon.watchSetting('locations',
|
||||
this._onLocationsChanged.bind(this));
|
||||
},
|
||||
this._weatherApp = null;
|
||||
this._weatherProxy = null;
|
||||
|
||||
let nodeInfo = Gio.DBusNodeInfo.new_for_xml(WeatherIntegrationIface);
|
||||
Gio.DBusProxy.new(
|
||||
Gio.DBus.session,
|
||||
Gio.DBusProxyFlags.DO_NOT_AUTO_START | Gio.DBusProxyFlags.GET_INVALIDATED_PROPERTIES,
|
||||
nodeInfo.lookup_interface(WEATHER_INTEGRATION_IFACE),
|
||||
WEATHER_BUS_NAME,
|
||||
WEATHER_OBJECT_PATH,
|
||||
WEATHER_INTEGRATION_IFACE,
|
||||
null,
|
||||
this._onWeatherProxyReady.bind(this));
|
||||
|
||||
this._settings = new Gio.Settings({
|
||||
schema_id: 'org.gnome.shell.weather'
|
||||
});
|
||||
this._settings.connect('changed::automatic-location',
|
||||
this._onAutomaticLocationChanged.bind(this));
|
||||
this._onAutomaticLocationChanged();
|
||||
this._settings.connect('changed::locations',
|
||||
this._onLocationsChanged.bind(this));
|
||||
this._onLocationsChanged();
|
||||
|
||||
this._appSystem = Shell.AppSystem.get_default();
|
||||
this._appSystem.connect('installed-changed',
|
||||
this._onInstalledChanged.bind(this));
|
||||
this._onInstalledChanged();
|
||||
}
|
||||
|
||||
get available() {
|
||||
return this._weatherAppMon.available;
|
||||
},
|
||||
return this._weatherApp != null;
|
||||
}
|
||||
|
||||
get loading() {
|
||||
return this._loading;
|
||||
},
|
||||
}
|
||||
|
||||
get hasLocation() {
|
||||
return this._locationValid;
|
||||
},
|
||||
}
|
||||
|
||||
get info() {
|
||||
return this._weatherInfo;
|
||||
},
|
||||
}
|
||||
|
||||
activateApp() {
|
||||
this._weatherAppMon.activateApp();
|
||||
},
|
||||
if (this._weatherApp)
|
||||
this._weatherApp.activate();
|
||||
}
|
||||
|
||||
update() {
|
||||
if (!this._locationValid)
|
||||
@@ -104,13 +137,45 @@ var WeatherClient = new Lang.Class({
|
||||
this._weatherInfo.update();
|
||||
else
|
||||
this._loadInfo();
|
||||
},
|
||||
}
|
||||
|
||||
get _useAutoLocation() {
|
||||
return this._autoLocationRequested &&
|
||||
this._locationSettings.get_boolean('enabled') &&
|
||||
this._weatherAuthorized;
|
||||
},
|
||||
}
|
||||
|
||||
_onWeatherProxyReady(o, res) {
|
||||
try {
|
||||
this._weatherProxy = Gio.DBusProxy.new_finish(res);
|
||||
} catch (e) {
|
||||
log(`Failed to create GNOME Weather proxy: ${e}`);
|
||||
return;
|
||||
}
|
||||
|
||||
this._weatherProxy.connect('g-properties-changed',
|
||||
this._onWeatherPropertiesChanged.bind(this));
|
||||
this._onWeatherPropertiesChanged();
|
||||
}
|
||||
|
||||
_onWeatherPropertiesChanged() {
|
||||
if (this._weatherProxy.g_name_owner == null)
|
||||
return;
|
||||
|
||||
this._settings.set_boolean('automatic-location',
|
||||
this._weatherProxy.AutomaticLocation);
|
||||
this._settings.set_value('locations',
|
||||
new GLib.Variant('av', this._weatherProxy.Locations));
|
||||
}
|
||||
|
||||
_onInstalledChanged() {
|
||||
let hadApp = (this._weatherApp != null);
|
||||
this._weatherApp = this._appSystem.lookup_app(WEATHER_APP_ID);
|
||||
let haveApp = (this._weatherApp != null);
|
||||
|
||||
if (hadApp !== haveApp)
|
||||
this.emit('changed');
|
||||
}
|
||||
|
||||
_loadInfo() {
|
||||
let id = this._weatherInfo.connect('updated', () => {
|
||||
@@ -122,7 +187,7 @@ var WeatherClient = new Lang.Class({
|
||||
this.emit('changed');
|
||||
|
||||
this._weatherInfo.update();
|
||||
},
|
||||
}
|
||||
|
||||
_locationsEqual(loc1, loc2) {
|
||||
if (loc1 == loc2)
|
||||
@@ -132,7 +197,7 @@ var WeatherClient = new Lang.Class({
|
||||
return false;
|
||||
|
||||
return loc1.equal(loc2);
|
||||
},
|
||||
}
|
||||
|
||||
_setLocation(location) {
|
||||
if (this._locationsEqual(this._weatherInfo.location, location))
|
||||
@@ -148,7 +213,7 @@ var WeatherClient = new Lang.Class({
|
||||
this._loadInfo();
|
||||
else
|
||||
this.emit('changed');
|
||||
},
|
||||
}
|
||||
|
||||
_updateLocationMonitoring() {
|
||||
if (this._useAutoLocation) {
|
||||
@@ -164,7 +229,7 @@ var WeatherClient = new Lang.Class({
|
||||
this._gclueService.disconnect(this._gclueLocationChangedId);
|
||||
this._gclueLocationChangedId = 0;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_startGClueService() {
|
||||
if (this._gclueStarting)
|
||||
@@ -176,8 +241,8 @@ var WeatherClient = new Lang.Class({
|
||||
(o, res) => {
|
||||
try {
|
||||
this._gclueService = Geoclue.Simple.new_finish(res);
|
||||
} catch(e) {
|
||||
log('Failed to connect to Geoclue2 service: ' + e.message);
|
||||
} catch (e) {
|
||||
log(`Failed to connect to Geoclue2 service: ${e.message}`);
|
||||
this._setLocation(this._mostRecentLocation);
|
||||
return;
|
||||
}
|
||||
@@ -185,7 +250,7 @@ var WeatherClient = new Lang.Class({
|
||||
this._gclueService.get_client().distance_threshold = 100;
|
||||
this._updateLocationMonitoring();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_onGClueLocationChanged() {
|
||||
let geoLocation = this._gclueService.location;
|
||||
@@ -194,17 +259,17 @@ var WeatherClient = new Lang.Class({
|
||||
geoLocation.latitude,
|
||||
geoLocation.longitude);
|
||||
this._setLocation(location);
|
||||
},
|
||||
}
|
||||
|
||||
_onAutomaticLocationChanged(settings, key) {
|
||||
let useAutoLocation = settings.get_boolean(key);
|
||||
_onAutomaticLocationChanged() {
|
||||
let useAutoLocation = this._settings.get_boolean('automatic-location');
|
||||
if (this._autoLocationRequested == useAutoLocation)
|
||||
return;
|
||||
|
||||
this._autoLocationRequested = useAutoLocation;
|
||||
|
||||
this._updateAutoLocation();
|
||||
},
|
||||
}
|
||||
|
||||
_updateAutoLocation() {
|
||||
this._updateLocationMonitoring();
|
||||
@@ -213,10 +278,11 @@ var WeatherClient = new Lang.Class({
|
||||
this._startGClueService();
|
||||
else
|
||||
this._setLocation(this._mostRecentLocation);
|
||||
},
|
||||
}
|
||||
|
||||
_onLocationsChanged(settings, key) {
|
||||
let serialized = settings.get_value(key).deep_unpack().shift();
|
||||
_onLocationsChanged() {
|
||||
let locations = this._settings.get_value('locations').deep_unpack();
|
||||
let serialized = locations.shift();
|
||||
let mostRecentLocation = null;
|
||||
|
||||
if (serialized)
|
||||
@@ -229,19 +295,19 @@ var WeatherClient = new Lang.Class({
|
||||
|
||||
if (!this._useAutoLocation || !this._gclueStarted)
|
||||
this._setLocation(this._mostRecentLocation);
|
||||
},
|
||||
}
|
||||
|
||||
_onPermStoreChanged(proxy, sender, params) {
|
||||
let [table, id, deleted, data, perms] = params;
|
||||
let [table, id, deleted_, data_, perms] = params;
|
||||
|
||||
if (table != 'gnome' || id != 'geolocation')
|
||||
return;
|
||||
|
||||
let permission = perms['org.gnome.Weather.Application'] || ['NONE'];
|
||||
let permission = perms['org.gnome.Weather'] || ['NONE'];
|
||||
let [accuracy] = permission;
|
||||
this._weatherAuthorized = accuracy != 'NONE';
|
||||
|
||||
this._updateAutoLocation();
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(WeatherClient.prototype);
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported run, script_overviewShowStart, script_overviewShowDone,
|
||||
script_applicationsShowStart, script_applicationsShowDone,
|
||||
script_afterShowHide, malloc_usedSize, glx_swapComplete,
|
||||
clutter_stagePaintDone */
|
||||
/* eslint camelcase: ["error", { properties: "never", allow: ["^script_", "^malloc", "^glx", "^clutter"] }] */
|
||||
|
||||
const System = imports.system;
|
||||
|
||||
@@ -10,7 +15,7 @@ const Scripting = imports.ui.scripting;
|
||||
// someone should be able to get an idea of how well the shell is performing
|
||||
// on a particular system.
|
||||
|
||||
let METRICS = {
|
||||
var METRICS = {
|
||||
overviewLatencyFirst:
|
||||
{ description: "Time to first frame after triggering overview, first time",
|
||||
units: "us" },
|
||||
@@ -19,7 +24,7 @@ let METRICS = {
|
||||
units: "frames / s" },
|
||||
overviewLatencySubsequent:
|
||||
{ description: "Time to first frame after triggering overview, second time",
|
||||
units: "us"},
|
||||
units: "us" },
|
||||
overviewFpsSubsequent:
|
||||
{ description: "Frames rate when going to the overview, second time",
|
||||
units: "frames / s" },
|
||||
@@ -52,7 +57,7 @@ let METRICS = {
|
||||
units: "us" },
|
||||
applicationsShowTimeSubsequent:
|
||||
{ description: "Time to switch to applications view, second time",
|
||||
units: "us"}
|
||||
units: "us" }
|
||||
};
|
||||
|
||||
let WINDOW_CONFIGS = [
|
||||
@@ -65,7 +70,7 @@ let WINDOW_CONFIGS = [
|
||||
{ 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("overviewShowDone", "Overview finished showing");
|
||||
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
|
||||
@@ -121,9 +126,11 @@ function run() {
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
Scripting.scriptEvent('applicationsShowStart');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview._dash.showAppsButton.checked = true;
|
||||
yield Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('applicationsShowDone');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview._dash.showAppsButton.checked = false;
|
||||
yield Scripting.waitLeisure();
|
||||
}
|
||||
@@ -136,7 +143,6 @@ let overviewFrames;
|
||||
let overviewLatency;
|
||||
let mallocUsedSize = 0;
|
||||
let overviewShowCount = 0;
|
||||
let firstOverviewUsedSize;
|
||||
let haveSwapComplete = false;
|
||||
let applicationsShowStart;
|
||||
let applicationsShowCount = 0;
|
||||
@@ -148,7 +154,7 @@ function script_overviewShowStart(time) {
|
||||
overviewFrames = 0;
|
||||
}
|
||||
|
||||
function script_overviewShowDone(time) {
|
||||
function script_overviewShowDone(_time) {
|
||||
// We've set up the state at the end of the zoom out, but we
|
||||
// need to wait for one more frame to paint before we count
|
||||
// ourselves as done.
|
||||
@@ -167,7 +173,7 @@ function script_applicationsShowDone(time) {
|
||||
METRICS.applicationsShowTimeSubsequent.value = time - applicationsShowStart;
|
||||
}
|
||||
|
||||
function script_afterShowHide(time) {
|
||||
function script_afterShowHide(_time) {
|
||||
if (overviewShowCount == 1) {
|
||||
METRICS.usedAfterOverview.value = mallocUsedSize;
|
||||
} else {
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Meta = imports.gi.Meta;
|
||||
/* exported run, script_desktopShown, script_overviewShowStart,
|
||||
script_overviewShowDone, script_applicationsShowStart,
|
||||
script_applicationsShowDone, script_mainViewDrawStart,
|
||||
script_mainViewDrawDone, script_overviewDrawStart,
|
||||
script_overviewDrawDone, script_redrawTestStart,
|
||||
script_redrawTestDone, script_collectTimings,
|
||||
script_geditLaunch, script_geditFirstFrame,
|
||||
clutter_stagePaintStart, clutter_paintCompletedTimestamp */
|
||||
/* eslint camelcase: ["error", { properties: "never", allow: ["^script_", "^clutter"] }] */
|
||||
const { Clutter, Gio, Shell } = imports.gi;
|
||||
const Main = imports.ui.main;
|
||||
const Scripting = imports.ui.scripting;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
let METRICS = {
|
||||
var METRICS = {
|
||||
timeToDesktop:
|
||||
{ description: "Time from starting graphical.target to desktop showing",
|
||||
units: "us" },
|
||||
@@ -34,7 +39,7 @@ let METRICS = {
|
||||
geditStartTime:
|
||||
{ description: "Time from gedit launch to window drawn",
|
||||
units: "us" },
|
||||
}
|
||||
};
|
||||
|
||||
function waitAndDraw(milliseconds) {
|
||||
let cb;
|
||||
@@ -42,7 +47,7 @@ function waitAndDraw(milliseconds) {
|
||||
let timeline = new Clutter.Timeline({ duration: milliseconds });
|
||||
timeline.start();
|
||||
|
||||
timeline.connect('new-frame', (timeline, frame) => {
|
||||
timeline.connect('new-frame', (_timeline, _frame) => {
|
||||
global.stage.queue_redraw();
|
||||
});
|
||||
|
||||
@@ -52,7 +57,7 @@ function waitAndDraw(milliseconds) {
|
||||
cb();
|
||||
});
|
||||
|
||||
return callback => { cb = callback; };
|
||||
return callback => cb = callback;
|
||||
}
|
||||
|
||||
function waitSignal(object, signal) {
|
||||
@@ -64,7 +69,7 @@ function waitSignal(object, signal) {
|
||||
cb();
|
||||
});
|
||||
|
||||
return callback => { cb = callback; };
|
||||
return callback => cb = callback;
|
||||
}
|
||||
|
||||
function extractBootTimestamp() {
|
||||
@@ -77,8 +82,8 @@ function extractBootTimestamp() {
|
||||
let result = null;
|
||||
|
||||
let datastream = Gio.DataInputStream.new(sp.get_stdout_pipe());
|
||||
while (true) {
|
||||
let [line, length] = datastream.read_line_utf8(null);
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
let [line, length_] = datastream.read_line_utf8(null);
|
||||
if (line === null)
|
||||
break;
|
||||
|
||||
@@ -89,7 +94,7 @@ function extractBootTimestamp() {
|
||||
return result;
|
||||
}
|
||||
|
||||
function run() {
|
||||
function *run() {
|
||||
Scripting.defineScriptEvent("desktopShown", "Finished initial animation");
|
||||
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
|
||||
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
|
||||
@@ -108,7 +113,10 @@ function run() {
|
||||
yield Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('desktopShown');
|
||||
|
||||
Gtk.Settings.get_default().gtk_enable_animations = false;
|
||||
let interfaceSettings = new Gio.Settings({
|
||||
schema_id: 'org.gnome.desktop.interface'
|
||||
});
|
||||
interfaceSettings.set_boolean('enable-animations', false);
|
||||
|
||||
Scripting.scriptEvent('overviewShowStart');
|
||||
Main.overview.show();
|
||||
@@ -118,6 +126,7 @@ function run() {
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
Scripting.scriptEvent('applicationsShowStart');
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
Main.overview._dash.showAppsButton.checked = true;
|
||||
|
||||
yield Scripting.waitLeisure();
|
||||
@@ -158,7 +167,7 @@ function run() {
|
||||
Main.overview.hide();
|
||||
|
||||
yield Scripting.createTestWindow({ maximized: true,
|
||||
redraws: true});
|
||||
redraws: true });
|
||||
yield Scripting.waitTestWindows();
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
@@ -204,7 +213,7 @@ function run() {
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
|
||||
Gtk.Settings.get_default().gtk_enable_animations = true;
|
||||
interfaceSettings.set_boolean('enable-animations', true);
|
||||
}
|
||||
|
||||
let overviewShowStart;
|
||||
@@ -235,31 +244,31 @@ function script_applicationsShowDone(time) {
|
||||
METRICS.applicationsShowTime.value = time - applicationsShowStart;
|
||||
}
|
||||
|
||||
function script_mainViewDrawStart(time) {
|
||||
function script_mainViewDrawStart(_time) {
|
||||
redrawTiming = 'mainView';
|
||||
}
|
||||
|
||||
function script_mainViewDrawDone(time) {
|
||||
function script_mainViewDrawDone(_time) {
|
||||
redrawTiming = null;
|
||||
}
|
||||
|
||||
function script_overviewDrawStart(time) {
|
||||
function script_overviewDrawStart(_time) {
|
||||
redrawTiming = 'overview';
|
||||
}
|
||||
|
||||
function script_overviewDrawDone(time) {
|
||||
function script_overviewDrawDone(_time) {
|
||||
redrawTiming = null;
|
||||
}
|
||||
|
||||
function script_redrawTestStart(time) {
|
||||
function script_redrawTestStart(_time) {
|
||||
redrawTiming = 'application';
|
||||
}
|
||||
|
||||
function script_redrawTestDone(time) {
|
||||
function script_redrawTestDone(_time) {
|
||||
redrawTiming = null;
|
||||
}
|
||||
|
||||
function script_collectTimings(time) {
|
||||
function script_collectTimings(_time) {
|
||||
for (let timing in redrawTimes) {
|
||||
let times = redrawTimes[timing];
|
||||
times.sort((a, b) => a - b);
|
||||
@@ -270,11 +279,11 @@ function script_collectTimings(time) {
|
||||
if (len == 0)
|
||||
median = -1;
|
||||
else if (len % 2 == 1)
|
||||
median = times[(len - 1)/ 2];
|
||||
median = times[(len - 1) / 2];
|
||||
else
|
||||
median = Math.round((times[len / 2 - 1] + times[len / 2]) / 2);
|
||||
|
||||
METRICS[timing + 'RedrawTime'].value = median;
|
||||
METRICS[`${timing}RedrawTime`].value = median;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
/* exported main */
|
||||
const Format = imports.format;
|
||||
const Gettext = imports.gettext;
|
||||
const GLib = imports.gi.GLib;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Soup = imports.gi.Soup;
|
||||
const WebKit = imports.gi.WebKit2;
|
||||
const { Gio, GLib, GObject, Gtk, Pango, Soup, WebKit2: WebKit } = imports.gi;
|
||||
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
@@ -26,19 +20,16 @@ const PortalHelperSecurityLevel = {
|
||||
INSECURE: 2
|
||||
};
|
||||
|
||||
const INACTIVITY_TIMEOUT = 30000; //ms
|
||||
const CONNECTIVITY_CHECK_HOST = 'nmcheck.gnome.org';
|
||||
const CONNECTIVITY_CHECK_URI = 'http://' + CONNECTIVITY_CHECK_HOST;
|
||||
const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
|
||||
|
||||
const HelperDBusInterface = loadInterfaceXML('org.gnome.Shell.PortalHelper');
|
||||
|
||||
var PortalHeaderBar = new Lang.Class({
|
||||
Name: 'PortalHeaderBar',
|
||||
Extends: Gtk.HeaderBar,
|
||||
|
||||
var PortalHeaderBar = GObject.registerClass(
|
||||
class PortalHeaderBar extends Gtk.HeaderBar {
|
||||
_init() {
|
||||
this.parent({ show_close_button: true });
|
||||
super._init({ show_close_button: true });
|
||||
|
||||
// See ephy-title-box.c in epiphany for the layout
|
||||
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
|
||||
@@ -68,16 +59,16 @@ var PortalHeaderBar = new Lang.Class({
|
||||
single_line_mode: true,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
valign: Gtk.Align.BASELINE,
|
||||
selectable: true});
|
||||
selectable: true });
|
||||
this.subtitleLabel.get_style_context().add_class('subtitle');
|
||||
hbox.add(this.subtitleLabel);
|
||||
|
||||
vbox.show_all();
|
||||
},
|
||||
}
|
||||
|
||||
setSubtitle(label) {
|
||||
this.subtitleLabel.set_text(label);
|
||||
},
|
||||
}
|
||||
|
||||
setSecurityIcon(securityLevel) {
|
||||
switch (securityLevel) {
|
||||
@@ -95,15 +86,13 @@ var PortalHeaderBar = new Lang.Class({
|
||||
this._lockImage.set_tooltip_text(_('Your connection to this hotspot login is not secure. Passwords or other information you enter on this page can be viewed by people nearby.'));
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
var PortalWindow = new Lang.Class({
|
||||
Name: 'PortalWindow',
|
||||
Extends: Gtk.ApplicationWindow,
|
||||
|
||||
var PortalWindow = GObject.registerClass(
|
||||
class PortalWindow extends Gtk.ApplicationWindow {
|
||||
_init(application, url, timestamp, doneCallback) {
|
||||
this.parent({ application: application });
|
||||
super._init({ application: application });
|
||||
|
||||
this.connect('delete-event', this.destroyWindow.bind(this));
|
||||
this._headerBar = new PortalHeaderBar();
|
||||
@@ -144,11 +133,11 @@ var PortalWindow = new Lang.Class({
|
||||
this.present_with_time(timestamp);
|
||||
|
||||
this.application.set_accels_for_action('app.quit', ['<Primary>q', '<Primary>w']);
|
||||
},
|
||||
}
|
||||
|
||||
destroyWindow() {
|
||||
this.destroy();
|
||||
},
|
||||
}
|
||||
|
||||
_syncUri() {
|
||||
let uri = this._webView.uri;
|
||||
@@ -156,20 +145,20 @@ var PortalWindow = new Lang.Class({
|
||||
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
|
||||
else
|
||||
this._headerBar.setSubtitle('');
|
||||
},
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this._everSeenRedirect = false;
|
||||
this._webView.load_uri(this._originalUrl);
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_delete_event(event) {
|
||||
vfunc_delete_event(_event) {
|
||||
if (this._recheckAtExit)
|
||||
this._doneCallback(PortalHelperResult.RECHECK);
|
||||
else
|
||||
this._doneCallback(PortalHelperResult.CANCELLED);
|
||||
return false;
|
||||
},
|
||||
}
|
||||
|
||||
_onLoadChanged(view, loadEvent) {
|
||||
if (loadEvent == WebKit.LoadEvent.STARTED) {
|
||||
@@ -183,19 +172,19 @@ var PortalWindow = new Lang.Class({
|
||||
else
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_onInsecureContentDetected() {
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||
},
|
||||
}
|
||||
|
||||
_onLoadFailedWithTlsErrors(view, failingURI, certificate, errors) {
|
||||
_onLoadFailedWithTlsErrors(view, failingURI, certificate, _errors) {
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||
let uri = new Soup.URI(failingURI);
|
||||
this._webContext.allow_tls_certificate_for_host(certificate, uri.get_host());
|
||||
this._webView.load_uri(failingURI);
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
_onDecidePolicy(view, decision, type) {
|
||||
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
|
||||
@@ -262,15 +251,13 @@ var PortalWindow = new Lang.Class({
|
||||
|
||||
decision.use();
|
||||
return true;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
var WebPortalHelper = new Lang.Class({
|
||||
Name: 'WebPortalHelper',
|
||||
Extends: Gtk.Application,
|
||||
|
||||
var WebPortalHelper = GObject.registerClass(
|
||||
class WebPortalHelper extends Gtk.Application {
|
||||
_init() {
|
||||
this.parent({ application_id: 'org.gnome.Shell.PortalHelper',
|
||||
super._init({ application_id: 'org.gnome.Shell.PortalHelper',
|
||||
flags: Gio.ApplicationFlags.IS_SERVICE,
|
||||
inactivity_timeout: 30000 });
|
||||
|
||||
@@ -278,32 +265,32 @@ var WebPortalHelper = new Lang.Class({
|
||||
this._queue = [];
|
||||
|
||||
let action = new Gio.SimpleAction({ name: 'quit' });
|
||||
action.connect('activate', () => { this.active_window.destroyWindow(); });
|
||||
action.connect('activate', () => this.active_window.destroyWindow());
|
||||
this.add_action(action);
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_dbus_register(connection, path) {
|
||||
this._dbusImpl.export(connection, path);
|
||||
this.parent(connection, path);
|
||||
super.vfunc_dbus_register(connection, path);
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_dbus_unregister(connection, path) {
|
||||
this._dbusImpl.unexport_from_connection(connection);
|
||||
this.parent(connection, path);
|
||||
},
|
||||
super.vfunc_dbus_unregister(connection, path);
|
||||
}
|
||||
|
||||
vfunc_activate() {
|
||||
// If launched manually (for example for testing), force a dummy authentication
|
||||
// session with the default url
|
||||
this.Authenticate('/org/gnome/dummy', '', 0);
|
||||
},
|
||||
}
|
||||
|
||||
Authenticate(connection, url, timestamp) {
|
||||
this._queue.push({ connection: connection, url: url, timestamp: timestamp });
|
||||
|
||||
this._processQueue();
|
||||
},
|
||||
}
|
||||
|
||||
Close(connection) {
|
||||
for (let i = 0; i < this._queue.length; i++) {
|
||||
@@ -318,7 +305,7 @@ var WebPortalHelper = new Lang.Class({
|
||||
}
|
||||
|
||||
this._processQueue();
|
||||
},
|
||||
}
|
||||
|
||||
Refresh(connection) {
|
||||
for (let i = 0; i < this._queue.length; i++) {
|
||||
@@ -330,7 +317,7 @@ var WebPortalHelper = new Lang.Class({
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_processQueue() {
|
||||
if (this._queue.length == 0)
|
||||
@@ -343,7 +330,7 @@ var WebPortalHelper = new Lang.Class({
|
||||
top.window = new PortalWindow(this, top.url, top.timestamp, result => {
|
||||
this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result]));
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
function initEnvironment() {
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
/* exported AccessDialogDBus */
|
||||
const { Clutter, Gio, GLib, GObject, Shell } = imports.gi;
|
||||
|
||||
const CheckBox = imports.ui.checkBox;
|
||||
const Dialog = imports.ui.dialog;
|
||||
@@ -21,12 +16,10 @@ var DialogResponse = {
|
||||
CLOSED: 2
|
||||
};
|
||||
|
||||
var AccessDialog = new Lang.Class({
|
||||
Name: 'AccessDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
var AccessDialog = GObject.registerClass(
|
||||
class AccessDialog extends ModalDialog.ModalDialog {
|
||||
_init(invocation, handle, title, subtitle, body, options) {
|
||||
this.parent({ styleClass: 'access-dialog' });
|
||||
super._init({ styleClass: 'access-dialog' });
|
||||
|
||||
this._invocation = invocation;
|
||||
this._handle = handle;
|
||||
@@ -38,7 +31,7 @@ var AccessDialog = new Lang.Class({
|
||||
options[option] = options[option].deep_unpack();
|
||||
|
||||
this._buildLayout(title, subtitle, body, options);
|
||||
},
|
||||
}
|
||||
|
||||
_buildLayout(title, subtitle, body, options) {
|
||||
// No support for non-modal system dialogs, so ignore the option
|
||||
@@ -77,17 +70,17 @@ var AccessDialog = new Lang.Class({
|
||||
this.addButton({ label: grantLabel,
|
||||
action: () => {
|
||||
this._sendResponse(DialogResponse.OK);
|
||||
}});
|
||||
},
|
||||
} });
|
||||
}
|
||||
|
||||
open() {
|
||||
this.parent();
|
||||
super.open();
|
||||
|
||||
let connection = this._invocation.get_connection();
|
||||
this._requestExported = this._request.export(connection, this._handle);
|
||||
},
|
||||
}
|
||||
|
||||
CloseAsync(invocation, params) {
|
||||
CloseAsync(invocation, _params) {
|
||||
if (this._invocation.get_sender() != invocation.get_sender()) {
|
||||
invocation.return_error_literal(Gio.DBusError,
|
||||
Gio.DBusError.ACCESS_DENIED,
|
||||
@@ -96,7 +89,7 @@ var AccessDialog = new Lang.Class({
|
||||
}
|
||||
|
||||
this._sendResponse(DialogResponse.CLOSED);
|
||||
},
|
||||
}
|
||||
|
||||
_sendResponse(response) {
|
||||
if (this._requestExported)
|
||||
@@ -120,10 +113,8 @@ var AccessDialog = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
var AccessDialogDBus = new Lang.Class({
|
||||
Name: 'AccessDialogDBus',
|
||||
|
||||
_init() {
|
||||
var AccessDialogDBus = class {
|
||||
constructor() {
|
||||
this._accessDialog = null;
|
||||
|
||||
this._windowTracker = Shell.WindowTracker.get_default();
|
||||
@@ -132,7 +123,7 @@ var AccessDialogDBus = new Lang.Class({
|
||||
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/portal/desktop');
|
||||
|
||||
Gio.DBus.session.own_name('org.freedesktop.impl.portal.desktop.gnome', Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||
},
|
||||
}
|
||||
|
||||
AccessDialogAsync(params, invocation) {
|
||||
if (this._accessDialog) {
|
||||
@@ -142,10 +133,10 @@ var AccessDialogDBus = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
let [handle, appId, parentWindow, title, subtitle, body, options] = params;
|
||||
let [handle, appId, parentWindow_, title, subtitle, body, options] = params;
|
||||
// We probably want to use parentWindow and global.display.focus_window
|
||||
// for this check in the future
|
||||
if (appId && appId + '.desktop' != this._windowTracker.focus_app.id) {
|
||||
if (appId && `${appId}.desktop` != this._windowTracker.focus_app.id) {
|
||||
invocation.return_error_literal(Gio.DBusError,
|
||||
Gio.DBusError.ACCESS_DENIED,
|
||||
'Only the focused app is allowed to show a system access dialog');
|
||||
@@ -156,8 +147,8 @@ var AccessDialogDBus = new Lang.Class({
|
||||
subtitle, body, options);
|
||||
dialog.open();
|
||||
|
||||
dialog.connect('closed', () => { this._accessDialog = null; });
|
||||
dialog.connect('closed', () => this._accessDialog = null);
|
||||
|
||||
this._accessDialog = dialog;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
353
js/ui/altTab.js
@@ -1,25 +1,18 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported AppSwitcherPopup, GroupCyclerPopup, WindowSwitcherPopup,
|
||||
WindowCyclerPopup */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Lang = imports.lang;
|
||||
const { Atk, Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Atk = imports.gi.Atk;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const SwitcherPopup = imports.ui.switcherPopup;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
var APP_ICON_HOVER_TIMEOUT = 200; // milliseconds
|
||||
|
||||
var THUMBNAIL_DEFAULT_SIZE = 256;
|
||||
var THUMBNAIL_POPUP_TIME = 500; // milliseconds
|
||||
var THUMBNAIL_FADE_TIME = 0.1; // seconds
|
||||
var THUMBNAIL_FADE_TIME = 100; // milliseconds
|
||||
|
||||
var WINDOW_PREVIEW_SIZE = 128;
|
||||
var APP_ICON_SIZE = 96;
|
||||
@@ -44,7 +37,7 @@ function _createWindowClone(window, size) {
|
||||
// usual hack for the usual bug in ClutterBinLayout...
|
||||
x_expand: true,
|
||||
y_expand: true });
|
||||
};
|
||||
}
|
||||
|
||||
function getWindows(workspace) {
|
||||
// We ignore skip-taskbar windows in switchers, but if they are attached
|
||||
@@ -59,12 +52,10 @@ function getWindows(workspace) {
|
||||
}).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) == i);
|
||||
}
|
||||
|
||||
var AppSwitcherPopup = new Lang.Class({
|
||||
Name: 'AppSwitcherPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
|
||||
var AppSwitcherPopup = GObject.registerClass(
|
||||
class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
|
||||
_init() {
|
||||
this.parent();
|
||||
super._init();
|
||||
|
||||
this._thumbnails = null;
|
||||
this._thumbnailTimeoutId = 0;
|
||||
@@ -79,10 +70,10 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
|
||||
this._switcherList = new AppSwitcher(apps, this);
|
||||
this._items = this._switcherList.icons;
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_allocate(box, flags) {
|
||||
this.parent(box, flags);
|
||||
super.vfunc_allocate(box, flags);
|
||||
|
||||
// Allocate the thumbnails
|
||||
// We try to avoid overflowing the screen so we base the resulting size on
|
||||
@@ -97,9 +88,9 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
let hPadding = leftPadding + rightPadding;
|
||||
|
||||
let icon = this._items[this._selectedIndex];
|
||||
let [posX, posY] = icon.get_transformed_position();
|
||||
let [posX] = icon.get_transformed_position();
|
||||
let thumbnailCenter = posX + icon.width / 2;
|
||||
let [childMinWidth, childNaturalWidth] = this._thumbnails.get_preferred_width(-1);
|
||||
let [, childNaturalWidth] = this._thumbnails.get_preferred_width(-1);
|
||||
childBox.x1 = Math.max(primary.x + leftPadding, Math.floor(thumbnailCenter - childNaturalWidth / 2));
|
||||
if (childBox.x1 + childNaturalWidth > primary.x + primary.width - hPadding) {
|
||||
let offset = childBox.x1 + childNaturalWidth - primary.width + hPadding;
|
||||
@@ -113,11 +104,11 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
childBox.x2 = primary.x + primary.width - rightPadding;
|
||||
childBox.y1 = this._switcherList.allocation.y2 + spacing;
|
||||
this._thumbnails.addClones(primary.y + primary.height - bottomPadding - childBox.y1);
|
||||
let [childMinHeight, childNaturalHeight] = this._thumbnails.get_preferred_height(-1);
|
||||
let [, childNaturalHeight] = this._thumbnails.get_preferred_height(-1);
|
||||
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||
this._thumbnails.allocate(childBox, flags);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_initialSelection(backward, binding) {
|
||||
if (binding == 'switch-group') {
|
||||
@@ -140,7 +131,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
} else {
|
||||
this._select(1);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_nextWindow() {
|
||||
// We actually want the second window if we're in the unset state
|
||||
@@ -148,14 +139,15 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._currentWindow = 0;
|
||||
return SwitcherPopup.mod(this._currentWindow + 1,
|
||||
this._items[this._selectedIndex].cachedWindows.length);
|
||||
},
|
||||
}
|
||||
|
||||
_previousWindow() {
|
||||
// Also assume second window here
|
||||
if (this._currentWindow == -1)
|
||||
this._currentWindow = 1;
|
||||
return SwitcherPopup.mod(this._currentWindow - 1,
|
||||
this._items[this._selectedIndex].cachedWindows.length);
|
||||
},
|
||||
}
|
||||
|
||||
_closeAppWindow(appIndex, windowIndex) {
|
||||
let appIcon = this._items[appIndex];
|
||||
@@ -167,7 +159,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
return;
|
||||
|
||||
window.delete(global.get_current_time());
|
||||
},
|
||||
}
|
||||
|
||||
_quitApplication(appIndex) {
|
||||
let appIcon = this._items[appIndex];
|
||||
@@ -175,7 +167,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
return;
|
||||
|
||||
appIcon.app.request_quit();
|
||||
},
|
||||
}
|
||||
|
||||
_keyPressHandler(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.SWITCH_GROUP) {
|
||||
@@ -214,7 +206,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
}
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
},
|
||||
}
|
||||
|
||||
_scrollHandler(direction) {
|
||||
if (direction == Clutter.ScrollDirection.UP) {
|
||||
@@ -244,7 +236,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._select(this._next());
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_itemActivatedHandler(n) {
|
||||
// If the user clicks on the selected app, activate the
|
||||
@@ -254,24 +246,24 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._select(n, this._currentWindow);
|
||||
else
|
||||
this._select(n);
|
||||
},
|
||||
}
|
||||
|
||||
_itemEnteredHandler(n) {
|
||||
this._select(n);
|
||||
},
|
||||
}
|
||||
|
||||
_windowActivated(thumbnailList, n) {
|
||||
let appIcon = this._items[this._selectedIndex];
|
||||
Main.activateWindow(appIcon.cachedWindows[n]);
|
||||
this.fadeAndDestroy();
|
||||
},
|
||||
}
|
||||
|
||||
_windowEntered(thumbnailList, n) {
|
||||
if (!this.mouseActive)
|
||||
return;
|
||||
|
||||
this._select(this._selectedIndex, n);
|
||||
},
|
||||
}
|
||||
|
||||
_windowRemoved(thumbnailList, n) {
|
||||
let appIcon = this._items[this._selectedIndex];
|
||||
@@ -282,7 +274,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
let newIndex = Math.min(n, appIcon.cachedWindows.length - 1);
|
||||
this._select(this._selectedIndex, newIndex);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_finish(timestamp) {
|
||||
let appIcon = this._items[this._selectedIndex];
|
||||
@@ -291,17 +283,17 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
else if (appIcon.cachedWindows[this._currentWindow])
|
||||
Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp);
|
||||
|
||||
this.parent();
|
||||
},
|
||||
super._finish(timestamp);
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this.parent();
|
||||
super._onDestroy();
|
||||
|
||||
if (this._thumbnails)
|
||||
this._destroyThumbnails();
|
||||
if (this._thumbnailTimeoutId != 0)
|
||||
Mainloop.source_remove(this._thumbnailTimeoutId);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* _select:
|
||||
@@ -357,7 +349,7 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._timeoutPopupThumbnails.bind(this));
|
||||
GLib.Source.set_name_by_id(this._thumbnailTimeoutId, '[gnome-shell] this._timeoutPopupThumbnails');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_timeoutPopupThumbnails() {
|
||||
if (!this._thumbnails)
|
||||
@@ -365,23 +357,23 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._thumbnailTimeoutId = 0;
|
||||
this._thumbnailsFocused = false;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
},
|
||||
}
|
||||
|
||||
_destroyThumbnails() {
|
||||
let thumbnailsActor = this._thumbnails;
|
||||
Tweener.addTween(thumbnailsActor,
|
||||
{ opacity: 0,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: () => {
|
||||
thumbnailsActor.destroy();
|
||||
this.thumbnailsVisible = false;
|
||||
}
|
||||
});
|
||||
this._thumbnails.ease({
|
||||
opacity: 0,
|
||||
duration: THUMBNAIL_FADE_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
thumbnailsActor.destroy();
|
||||
this.thumbnailsVisible = false;
|
||||
}
|
||||
});
|
||||
this._thumbnails = null;
|
||||
if (this._switcherList._items[this._selectedIndex])
|
||||
if (this._switcherList._items[this._selectedIndex])
|
||||
this._switcherList._items[this._selectedIndex].remove_accessible_state (Atk.StateType.EXPANDED);
|
||||
},
|
||||
}
|
||||
|
||||
_createThumbnails() {
|
||||
this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows);
|
||||
@@ -400,21 +392,21 @@ var AppSwitcherPopup = new Lang.Class({
|
||||
this._thumbnails.get_allocation_box();
|
||||
|
||||
this._thumbnails.opacity = 0;
|
||||
Tweener.addTween(this._thumbnails,
|
||||
{ opacity: 255,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: () => { this.thumbnailsVisible = true; }
|
||||
});
|
||||
this._thumbnails.ease({
|
||||
opacity: 255,
|
||||
duration: THUMBNAIL_FADE_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => {
|
||||
this.thumbnailsVisible = true;
|
||||
}
|
||||
});
|
||||
|
||||
this._switcherList._items[this._selectedIndex].add_accessible_state (Atk.StateType.EXPANDED);
|
||||
}
|
||||
});
|
||||
|
||||
var CyclerHighlight = new Lang.Class({
|
||||
Name: 'CyclerHighlight',
|
||||
|
||||
_init() {
|
||||
class CyclerHighlight {
|
||||
constructor() {
|
||||
this._window = null;
|
||||
|
||||
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
@@ -434,7 +426,7 @@ var CyclerHighlight = new Lang.Class({
|
||||
this.actor.connect('notify::allocation',
|
||||
this._onAllocationChanged.bind(this));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
set window(w) {
|
||||
if (this._window == w)
|
||||
@@ -452,7 +444,7 @@ var CyclerHighlight = new Lang.Class({
|
||||
windowActor.hide();
|
||||
|
||||
this._clone.source = windowActor;
|
||||
},
|
||||
}
|
||||
|
||||
_onAllocationChanged() {
|
||||
if (!this._window) {
|
||||
@@ -465,35 +457,31 @@ var CyclerHighlight = new Lang.Class({
|
||||
this._highlight.set_position(rect.x - x, rect.y - y);
|
||||
this._highlight.show();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this.window = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// We don't show an actual popup, so just provide what SwitcherPopup
|
||||
// expects instead of inheriting from SwitcherList
|
||||
var CyclerList = new Lang.Class({
|
||||
Name: 'CyclerList',
|
||||
Extends: St.Widget,
|
||||
var CyclerList = GObject.registerClass({
|
||||
Signals: { 'item-activated': { param_types: [GObject.TYPE_INT] },
|
||||
'item-entered': { param_types: [GObject.TYPE_INT] },
|
||||
'item-removed': { param_types: [GObject.TYPE_INT] },
|
||||
'item-highlighted': { param_types: [GObject.TYPE_INT] } },
|
||||
|
||||
highlight(index, justOutline) {
|
||||
}, class CyclerList extends St.Widget {
|
||||
highlight(index, _justOutline) {
|
||||
this.emit('item-highlighted', index);
|
||||
}
|
||||
});
|
||||
|
||||
var CyclerPopup = new Lang.Class({
|
||||
Name: 'CyclerPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
Abstract: true,
|
||||
|
||||
var CyclerPopup = GObject.registerClass({
|
||||
GTypeFlags: GObject.TypeFlags.ABSTRACT
|
||||
}, class CyclerPopup extends SwitcherPopup.SwitcherPopup {
|
||||
_init() {
|
||||
this.parent();
|
||||
super._init();
|
||||
|
||||
this._items = this._getWindows();
|
||||
|
||||
@@ -507,12 +495,12 @@ var CyclerPopup = new Lang.Class({
|
||||
this._switcherList.connect('item-highlighted', (list, index) => {
|
||||
this._highlightItem(index);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_highlightItem(index, justOutline) {
|
||||
_highlightItem(index, _justOutline) {
|
||||
this._highlight.window = this._items[index];
|
||||
global.window_group.set_child_above_sibling(this._highlight.actor, null);
|
||||
},
|
||||
}
|
||||
|
||||
_finish() {
|
||||
let window = this._items[this._selectedIndex];
|
||||
@@ -537,25 +525,23 @@ var CyclerPopup = new Lang.Class({
|
||||
Main.wm.actionMoveWindow(window, ws);
|
||||
}
|
||||
|
||||
this.parent();
|
||||
},
|
||||
super._finish();
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._highlight.actor.destroy();
|
||||
|
||||
this.parent();
|
||||
super._onDestroy();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var GroupCyclerPopup = new Lang.Class({
|
||||
Name: 'GroupCyclerPopup',
|
||||
Extends: CyclerPopup,
|
||||
|
||||
var GroupCyclerPopup = GObject.registerClass(
|
||||
class GroupCyclerPopup extends CyclerPopup {
|
||||
_getWindows() {
|
||||
let app = Shell.WindowTracker.get_default().focus_app;
|
||||
return app ? app.get_windows() : [];
|
||||
},
|
||||
}
|
||||
|
||||
_keyPressHandler(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.CYCLE_GROUP)
|
||||
@@ -569,12 +555,10 @@ var GroupCyclerPopup = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
var WindowSwitcherPopup = new Lang.Class({
|
||||
Name: 'WindowSwitcherPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
|
||||
var WindowSwitcherPopup = GObject.registerClass(
|
||||
class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
|
||||
_init() {
|
||||
this.parent();
|
||||
super._init();
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
|
||||
|
||||
let windows = this._getWindowList();
|
||||
@@ -585,7 +569,7 @@ var WindowSwitcherPopup = new Lang.Class({
|
||||
let mode = this._settings.get_enum('app-icon-mode');
|
||||
this._switcherList = new WindowList(windows, mode);
|
||||
this._items = this._switcherList.icons;
|
||||
},
|
||||
}
|
||||
|
||||
_getWindowList() {
|
||||
let workspace = null;
|
||||
@@ -597,7 +581,7 @@ var WindowSwitcherPopup = new Lang.Class({
|
||||
}
|
||||
|
||||
return getWindows(workspace);
|
||||
},
|
||||
}
|
||||
|
||||
_closeWindow(windowIndex) {
|
||||
let windowIcon = this._items[windowIndex];
|
||||
@@ -605,7 +589,7 @@ var WindowSwitcherPopup = new Lang.Class({
|
||||
return;
|
||||
|
||||
windowIcon.window.delete(global.get_current_time());
|
||||
},
|
||||
}
|
||||
|
||||
_keyPressHandler(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.SWITCH_WINDOWS) {
|
||||
@@ -624,23 +608,21 @@ var WindowSwitcherPopup = new Lang.Class({
|
||||
}
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
},
|
||||
}
|
||||
|
||||
_finish() {
|
||||
Main.activateWindow(this._items[this._selectedIndex].window);
|
||||
|
||||
this.parent();
|
||||
super._finish();
|
||||
}
|
||||
});
|
||||
|
||||
var WindowCyclerPopup = new Lang.Class({
|
||||
Name: 'WindowCyclerPopup',
|
||||
Extends: CyclerPopup,
|
||||
|
||||
var WindowCyclerPopup = GObject.registerClass(
|
||||
class WindowCyclerPopup extends CyclerPopup {
|
||||
_init() {
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
|
||||
this.parent();
|
||||
},
|
||||
super._init();
|
||||
}
|
||||
|
||||
_getWindows() {
|
||||
let workspace = null;
|
||||
@@ -652,7 +634,7 @@ var WindowCyclerPopup = new Lang.Class({
|
||||
}
|
||||
|
||||
return getWindows(workspace);
|
||||
},
|
||||
}
|
||||
|
||||
_keyPressHandler(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
|
||||
@@ -666,12 +648,10 @@ var WindowCyclerPopup = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
var AppIcon = new Lang.Class({
|
||||
Name: 'AppIcon',
|
||||
Extends: St.BoxLayout,
|
||||
|
||||
var AppIcon = GObject.registerClass(
|
||||
class AppIcon extends St.BoxLayout {
|
||||
_init(app) {
|
||||
this.parent({ style_class: 'alt-tab-app',
|
||||
super._init({ style_class: 'alt-tab-app',
|
||||
vertical: true });
|
||||
|
||||
this.app = app;
|
||||
@@ -681,28 +661,19 @@ var AppIcon = new Lang.Class({
|
||||
this.add(this._iconBin, { x_fill: false, y_fill: false } );
|
||||
this.label = new St.Label({ text: this.app.get_name() });
|
||||
this.add(this.label, { x_fill: false });
|
||||
},
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
set_size(size) {
|
||||
this.icon = this.app.create_icon_texture(size);
|
||||
this._iconBin.child = this.icon;
|
||||
this._iconBin.set_size(size, size);
|
||||
},
|
||||
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let [minWidth, ] = this.parent(forHeight);
|
||||
|
||||
minWidth = Math.max(minWidth, forHeight);
|
||||
return [minWidth, minWidth];
|
||||
}
|
||||
});
|
||||
|
||||
var AppSwitcher = new Lang.Class({
|
||||
Name: 'AppSwitcher',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
var AppSwitcher = GObject.registerClass(
|
||||
class AppSwitcher extends SwitcherPopup.SwitcherList {
|
||||
_init(apps, altTabPopup) {
|
||||
this.parent(true);
|
||||
super._init(true);
|
||||
|
||||
this.icons = [];
|
||||
this._arrows = [];
|
||||
@@ -736,7 +707,7 @@ var AppSwitcher = new Lang.Class({
|
||||
this._mouseTimeOutId = 0;
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (this._mouseTimeOutId != 0)
|
||||
@@ -745,19 +716,20 @@ var AppSwitcher = new Lang.Class({
|
||||
this.icons.forEach(icon => {
|
||||
icon.app.disconnect(icon._stateChangedId);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_setIconSize() {
|
||||
let j = 0;
|
||||
while(this._items.length > 1 && this._items[j].style_class != 'item-box') {
|
||||
j++;
|
||||
while (this._items.length > 1 && this._items[j].style_class != 'item-box') {
|
||||
j++;
|
||||
}
|
||||
let themeNode = this._items[j].get_theme_node();
|
||||
this._list.ensure_style();
|
||||
|
||||
let iconPadding = themeNode.get_horizontal_padding();
|
||||
let iconBorder = themeNode.get_border_width(St.Side.LEFT) + themeNode.get_border_width(St.Side.RIGHT);
|
||||
let [iconMinHeight, iconNaturalHeight] = this.icons[j].label.get_preferred_height(-1);
|
||||
let iconSpacing = iconNaturalHeight + iconPadding + iconBorder;
|
||||
let [, labelNaturalHeight] = this.icons[j].label.get_preferred_height(-1);
|
||||
let iconSpacing = labelNaturalHeight + iconPadding + iconBorder;
|
||||
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
||||
|
||||
// We just assume the whole screen here due to weirdness happing with the passed width
|
||||
@@ -770,7 +742,7 @@ var AppSwitcher = new Lang.Class({
|
||||
let iconSize = baseIconSizes[0];
|
||||
|
||||
if (this._items.length > 1) {
|
||||
for(let i = 0; i < baseIconSizes.length; i++) {
|
||||
for (let i = 0; i < baseIconSizes.length; i++) {
|
||||
iconSize = baseIconSizes[i];
|
||||
let height = iconSizes[i] + iconSpacing;
|
||||
let w = height * this._items.length + totalSpacing;
|
||||
@@ -781,21 +753,21 @@ var AppSwitcher = new Lang.Class({
|
||||
|
||||
this._iconSize = iconSize;
|
||||
|
||||
for(let i = 0; i < this.icons.length; i++) {
|
||||
for (let i = 0; i < this.icons.length; i++) {
|
||||
if (this.icons[i].icon != null)
|
||||
break;
|
||||
this.icons[i].set_size(iconSize);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
this._setIconSize();
|
||||
return this.parent(forWidth);
|
||||
},
|
||||
return super.vfunc_get_preferred_height(forWidth);
|
||||
}
|
||||
|
||||
vfunc_allocate(box, flags) {
|
||||
// Allocate the main list items
|
||||
this.parent(box, flags);
|
||||
super.vfunc_allocate(box, flags);
|
||||
|
||||
let contentBox = this.get_theme_node().get_content_box(box);
|
||||
|
||||
@@ -812,7 +784,7 @@ var AppSwitcher = new Lang.Class({
|
||||
childBox.y2 = childBox.y1 + arrowHeight;
|
||||
this._arrows[i].allocate(childBox, flags);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// We override SwitcherList's _onItemEnter method to delay
|
||||
// activation when the thumbnail list is open
|
||||
@@ -827,16 +799,17 @@ var AppSwitcher = new Lang.Class({
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._mouseTimeOutId, '[gnome-shell] this._enterItem');
|
||||
} else
|
||||
this._itemEntered(index);
|
||||
},
|
||||
} else {
|
||||
this._itemEntered(index);
|
||||
}
|
||||
}
|
||||
|
||||
_enterItem(index) {
|
||||
let [x, y, mask] = global.get_pointer();
|
||||
let [x, y] = 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
|
||||
// the AppSwitcher->ThumbnailList arrows. Apps with only 1 window
|
||||
@@ -853,7 +826,7 @@ var AppSwitcher = new Lang.Class({
|
||||
this._arrows[this._curApp].remove_style_pseudo_class('highlighted');
|
||||
}
|
||||
|
||||
this.parent(n, justOutline);
|
||||
super.highlight(n, justOutline);
|
||||
this._curApp = n;
|
||||
|
||||
if (this._curApp != -1) {
|
||||
@@ -862,7 +835,7 @@ var AppSwitcher = new Lang.Class({
|
||||
else
|
||||
this._arrows[this._curApp].add_style_pseudo_class('highlighted');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_addIcon(appIcon) {
|
||||
this.icons.push(appIcon);
|
||||
@@ -873,9 +846,8 @@ var AppSwitcher = new Lang.Class({
|
||||
this._removeIcon(app);
|
||||
});
|
||||
|
||||
let n = this._arrows.length;
|
||||
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
|
||||
arrow.connect('repaint', () => { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); });
|
||||
arrow.connect('repaint', () => SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM));
|
||||
this.add_actor(arrow);
|
||||
this._arrows.push(arrow);
|
||||
|
||||
@@ -883,7 +855,7 @@ var AppSwitcher = new Lang.Class({
|
||||
arrow.hide();
|
||||
else
|
||||
item.add_accessible_state (Atk.StateType.EXPANDABLE);
|
||||
},
|
||||
}
|
||||
|
||||
_removeIcon(app) {
|
||||
let index = this.icons.findIndex(icon => {
|
||||
@@ -894,15 +866,13 @@ var AppSwitcher = new Lang.Class({
|
||||
|
||||
this.icons.splice(index, 1);
|
||||
this.removeItem(index);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
var ThumbnailList = new Lang.Class({
|
||||
Name: 'ThumbnailList',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
var ThumbnailList = GObject.registerClass(
|
||||
class ThumbnailList extends SwitcherPopup.SwitcherList {
|
||||
_init(windows) {
|
||||
this.parent(false);
|
||||
super._init(false);
|
||||
|
||||
this._labels = new Array();
|
||||
this._thumbnailBins = new Array();
|
||||
@@ -935,14 +905,14 @@ var ThumbnailList = new Lang.Class({
|
||||
}
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
addClones(availHeight) {
|
||||
if (!this._thumbnailBins.length)
|
||||
return;
|
||||
let totalPadding = this._items[0].get_theme_node().get_horizontal_padding() + this._items[0].get_theme_node().get_vertical_padding();
|
||||
totalPadding += this.get_theme_node().get_horizontal_padding() + this.get_theme_node().get_vertical_padding();
|
||||
let [labelMinHeight, labelNaturalHeight] = this._labels[0].get_preferred_height(-1);
|
||||
let [, labelNaturalHeight] = this._labels[0].get_preferred_height(-1);
|
||||
let spacing = this._items[0].child.get_theme_node().get_length('spacing');
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
let thumbnailSize = THUMBNAIL_DEFAULT_SIZE * scaleFactor;
|
||||
@@ -968,7 +938,7 @@ var ThumbnailList = new Lang.Class({
|
||||
|
||||
// Make sure we only do this once
|
||||
this._thumbnailBins = new Array();
|
||||
},
|
||||
}
|
||||
|
||||
_removeThumbnail(source, clone) {
|
||||
let index = this._clones.indexOf(clone);
|
||||
@@ -984,23 +954,20 @@ var ThumbnailList = new Lang.Class({
|
||||
this.highlight(SwitcherPopup.mod(index, this._clones.length));
|
||||
else
|
||||
this.destroy();
|
||||
},
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._clones.forEach(clone => {
|
||||
if (clone.source)
|
||||
clone.source.disconnect(clone._destroyId);
|
||||
});
|
||||
},
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
var WindowIcon = new Lang.Class({
|
||||
Name: 'WindowIcon',
|
||||
Extends: St.BoxLayout,
|
||||
|
||||
var WindowIcon = GObject.registerClass(
|
||||
class WindowIcon extends St.BoxLayout {
|
||||
_init(window, mode) {
|
||||
this.parent({ style_class: 'alt-tab-app',
|
||||
super._init({ style_class: 'alt-tab-app',
|
||||
vertical: true });
|
||||
|
||||
this.window = window;
|
||||
@@ -1021,27 +988,27 @@ var WindowIcon = new Lang.Class({
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
|
||||
switch (mode) {
|
||||
case AppIconMode.THUMBNAIL_ONLY:
|
||||
size = WINDOW_PREVIEW_SIZE;
|
||||
this._icon.add_actor(_createWindowClone(mutterWindow, size * scaleFactor));
|
||||
break;
|
||||
case AppIconMode.THUMBNAIL_ONLY:
|
||||
size = WINDOW_PREVIEW_SIZE;
|
||||
this._icon.add_actor(_createWindowClone(mutterWindow, size * scaleFactor));
|
||||
break;
|
||||
|
||||
case AppIconMode.BOTH:
|
||||
size = WINDOW_PREVIEW_SIZE;
|
||||
this._icon.add_actor(_createWindowClone(mutterWindow, size * scaleFactor));
|
||||
case AppIconMode.BOTH:
|
||||
size = WINDOW_PREVIEW_SIZE;
|
||||
this._icon.add_actor(_createWindowClone(mutterWindow, size * scaleFactor));
|
||||
|
||||
if (this.app)
|
||||
this._icon.add_actor(this._createAppIcon(this.app,
|
||||
APP_ICON_SIZE_SMALL));
|
||||
break;
|
||||
if (this.app)
|
||||
this._icon.add_actor(this._createAppIcon(this.app,
|
||||
APP_ICON_SIZE_SMALL));
|
||||
break;
|
||||
|
||||
case AppIconMode.APP_ICON_ONLY:
|
||||
size = APP_ICON_SIZE;
|
||||
this._icon.add_actor(this._createAppIcon(this.app, size));
|
||||
case AppIconMode.APP_ICON_ONLY:
|
||||
size = APP_ICON_SIZE;
|
||||
this._icon.add_actor(this._createAppIcon(this.app, size));
|
||||
}
|
||||
|
||||
this._icon.set_size(size * scaleFactor, size * scaleFactor);
|
||||
},
|
||||
}
|
||||
|
||||
_createAppIcon(app, size) {
|
||||
let appIcon = app ? app.create_icon_texture(size)
|
||||
@@ -1054,12 +1021,10 @@ var WindowIcon = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
var WindowList = new Lang.Class({
|
||||
Name: 'WindowList',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
var WindowList = GObject.registerClass(
|
||||
class WindowList extends SwitcherPopup.SwitcherList {
|
||||
_init(windows, mode) {
|
||||
this.parent(true);
|
||||
super._init(true);
|
||||
|
||||
this._label = new St.Label({ x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
@@ -1076,21 +1041,21 @@ var WindowList = new Lang.Class({
|
||||
this.icons.push(icon);
|
||||
|
||||
icon._unmanagedSignalId = icon.window.connect('unmanaged', (window) => {
|
||||
this._removeWindow(window)
|
||||
this._removeWindow(window);
|
||||
});
|
||||
}
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this.icons.forEach(icon => {
|
||||
icon.window.disconnect(icon._unmanagedSignalId);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let [minHeight, natHeight] = this.parent(forWidth);
|
||||
let [minHeight, natHeight] = super.vfunc_get_preferred_height(forWidth);
|
||||
|
||||
let spacing = this.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
let [labelMin, labelNat] = this._label.get_preferred_height(-1);
|
||||
@@ -1099,7 +1064,7 @@ var WindowList = new Lang.Class({
|
||||
natHeight += labelNat + spacing;
|
||||
|
||||
return [minHeight, natHeight];
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_allocate(box, flags) {
|
||||
let themeNode = this.get_theme_node();
|
||||
@@ -1112,24 +1077,24 @@ var WindowList = new Lang.Class({
|
||||
childBox.y1 = childBox.y2 - this._label.height;
|
||||
this._label.allocate(childBox, flags);
|
||||
|
||||
let totalLabelHeight = this._label.height + themeNode.get_padding(St.Side.BOTTOM)
|
||||
let totalLabelHeight = this._label.height + themeNode.get_padding(St.Side.BOTTOM);
|
||||
childBox.x1 = box.x1;
|
||||
childBox.x2 = box.x2;
|
||||
childBox.y1 = box.y1;
|
||||
childBox.y2 = box.y2 - totalLabelHeight;
|
||||
this.parent(childBox, flags);
|
||||
super.vfunc_allocate(childBox, flags);
|
||||
|
||||
// Hooking up the parent vfunc will call this.set_allocation() with
|
||||
// the height without the label height, so call it again with the
|
||||
// correct size here.
|
||||
this.set_allocation(box, flags);
|
||||
},
|
||||
}
|
||||
|
||||
highlight(index, justOutline) {
|
||||
this.parent(index, justOutline);
|
||||
super.highlight(index, justOutline);
|
||||
|
||||
this._label.set_text(index == -1 ? '' : this.icons[index].label.text);
|
||||
},
|
||||
}
|
||||
|
||||
_removeWindow(window) {
|
||||
let index = this.icons.findIndex(icon => {
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Animation, AnimatedIcon, Spinner */
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const { Clutter, GLib, Gio, St } = imports.gi;
|
||||
const Mainloop = imports.mainloop;
|
||||
const St = imports.gi.St;
|
||||
const Signals = imports.signals;
|
||||
const Atk = imports.gi.Atk;
|
||||
|
||||
var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
|
||||
var SPINNER_ANIMATION_TIME = 300;
|
||||
var SPINNER_ANIMATION_DELAY = 1000;
|
||||
|
||||
var Animation = new Lang.Class({
|
||||
Name: 'Animation',
|
||||
|
||||
_init(file, width, height, speed) {
|
||||
var Animation = class {
|
||||
constructor(file, width, height, speed) {
|
||||
this.actor = new St.Bin();
|
||||
this.actor.set_size(width, height);
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this.actor.connect('notify::size', this._syncAnimationSize.bind(this));
|
||||
this.actor.connect('resource-scale-changed',
|
||||
this._loadFile.bind(this, file, width, height));
|
||||
|
||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
this._scaleChangedId = themeContext.connect('notify::scale-factor',
|
||||
this._loadFile.bind(this, file, width, height));
|
||||
|
||||
this._speed = speed;
|
||||
|
||||
this._isLoaded = false;
|
||||
@@ -22,11 +28,8 @@ var Animation = new Lang.Class({
|
||||
this._timeoutId = 0;
|
||||
this._frame = 0;
|
||||
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor,
|
||||
this._animationsLoaded.bind(this));
|
||||
this.actor.set_child(this._animations);
|
||||
},
|
||||
this._loadFile(file, width, height);
|
||||
}
|
||||
|
||||
play() {
|
||||
if (this._isLoaded && this._timeoutId == 0) {
|
||||
@@ -38,7 +41,7 @@ var Animation = new Lang.Class({
|
||||
}
|
||||
|
||||
this._isPlaying = true;
|
||||
},
|
||||
}
|
||||
|
||||
stop() {
|
||||
if (this._timeoutId > 0) {
|
||||
@@ -47,7 +50,24 @@ var Animation = new Lang.Class({
|
||||
}
|
||||
|
||||
this._isPlaying = false;
|
||||
},
|
||||
}
|
||||
|
||||
_loadFile(file, width, height) {
|
||||
let [validResourceScale, resourceScale] = this.actor.get_resource_scale();
|
||||
|
||||
this._isLoaded = false;
|
||||
this.actor.destroy_all_children();
|
||||
|
||||
if (!validResourceScale)
|
||||
return;
|
||||
|
||||
let textureCache = St.TextureCache.get_default();
|
||||
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||
this._animations = textureCache.load_sliced_image(file, width, height,
|
||||
scaleFactor, resourceScale,
|
||||
this._animationsLoaded.bind(this));
|
||||
this.actor.set_child(this._animations);
|
||||
}
|
||||
|
||||
_showFrame(frame) {
|
||||
let oldFrameActor = this._animations.get_child_at_index(this._frame);
|
||||
@@ -59,30 +79,92 @@ var Animation = new Lang.Class({
|
||||
let newFrameActor = this._animations.get_child_at_index(this._frame);
|
||||
if (newFrameActor)
|
||||
newFrameActor.show();
|
||||
},
|
||||
}
|
||||
|
||||
_update() {
|
||||
this._showFrame(this._frame + 1);
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
},
|
||||
}
|
||||
|
||||
_syncAnimationSize() {
|
||||
if (!this._isLoaded)
|
||||
return;
|
||||
|
||||
let [width, height] = this.actor.get_size();
|
||||
|
||||
for (let i = 0; i < this._animations.get_n_children(); ++i)
|
||||
this._animations.get_child_at_index(i).set_size(width, height);
|
||||
}
|
||||
|
||||
_animationsLoaded() {
|
||||
this._isLoaded = this._animations.get_n_children() > 0;
|
||||
|
||||
this._syncAnimationSize();
|
||||
|
||||
if (this._isPlaying)
|
||||
this.play();
|
||||
},
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this.stop();
|
||||
}
|
||||
});
|
||||
|
||||
var AnimatedIcon = new Lang.Class({
|
||||
Name: 'AnimatedIcon',
|
||||
Extends: Animation,
|
||||
|
||||
_init(file, size) {
|
||||
this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
|
||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
if (this._scaleChangedId)
|
||||
themeContext.disconnect(this._scaleChangedId);
|
||||
this._scaleChangedId = 0;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var AnimatedIcon = class extends Animation {
|
||||
constructor(file, size) {
|
||||
super(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
|
||||
}
|
||||
};
|
||||
|
||||
var Spinner = class extends AnimatedIcon {
|
||||
constructor(size, animate = false) {
|
||||
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/process-working.svg');
|
||||
super(file, size);
|
||||
|
||||
this.actor.opacity = 0;
|
||||
this._animate = animate;
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
this._animate = false;
|
||||
super._onDestroy();
|
||||
}
|
||||
|
||||
play() {
|
||||
this.actor.remove_all_transitions();
|
||||
|
||||
if (this._animate) {
|
||||
super.play();
|
||||
this.actor.ease({
|
||||
opacity: 255,
|
||||
delay: SPINNER_ANIMATION_DELAY,
|
||||
duration: SPINNER_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.LINEAR
|
||||
});
|
||||
} else {
|
||||
this.actor.opacity = 255;
|
||||
super.play();
|
||||
}
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.actor.remove_all_transitions();
|
||||
|
||||
if (this._animate) {
|
||||
this.actor.ease({
|
||||
opacity: 0,
|
||||
time: SPINNER_ANIMATION_TIME,
|
||||
transition: 'linear',
|
||||
onComplete: () => super.stop()
|
||||
});
|
||||
} else {
|
||||
this.actor.opacity = 0;
|
||||
super.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
1412
js/ui/appDisplay.js
@@ -1,7 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getAppFavorites */
|
||||
|
||||
const Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
@@ -15,53 +15,63 @@ const RENAMED_DESKTOP_IDS = {
|
||||
'epiphany.desktop': 'org.gnome.Epiphany.desktop',
|
||||
'evolution.desktop': 'org.gnome.Evolution.desktop',
|
||||
'file-roller.desktop': 'org.gnome.FileRoller.desktop',
|
||||
'five-or-more.desktop': 'org.gnome.five-or-more.desktop',
|
||||
'four-in-a-row.desktop': 'org.gnome.Four-in-a-row.desktop',
|
||||
'gcalctool.desktop': 'org.gnome.Calculator.desktop',
|
||||
'geary.desktop': 'org.gnome.Geary.desktop',
|
||||
'gedit.desktop': 'org.gnome.gedit.desktop',
|
||||
'glchess.desktop': 'gnome-chess.desktop',
|
||||
'glines.desktop': 'five-or-more.desktop',
|
||||
'gnect.desktop': 'four-in-a-row.desktop',
|
||||
'glchess.desktop': 'org.gnome.Chess.desktop',
|
||||
'glines.desktop': 'org.gnome.five-or-more.desktop',
|
||||
'gnect.desktop': 'org.gnome.Four-in-a-row.desktop',
|
||||
'gnibbles.desktop': 'org.gnome.Nibbles.desktop',
|
||||
'gnobots2.desktop': 'gnome-robots.desktop',
|
||||
'gnobots2.desktop': 'org.gnome.Robots.desktop',
|
||||
'gnome-boxes.desktop': 'org.gnome.Boxes.desktop',
|
||||
'gnome-calculator.desktop': 'org.gnome.Calculator.desktop',
|
||||
'gnome-chess.desktop': 'org.gnome.Chess.desktop',
|
||||
'gnome-clocks.desktop': 'org.gnome.clocks.desktop',
|
||||
'gnome-contacts.desktop': 'org.gnome.Contacts.desktop',
|
||||
'gnome-documents.desktop': 'org.gnome.Documents.desktop',
|
||||
'gnome-font-viewer.desktop': 'org.gnome.font-viewer.desktop',
|
||||
'gnome-klotski.desktop': 'org.gnome.Klotski.desktop',
|
||||
'gnome-nibbles.desktop': 'org.gnome.Nibbles.desktop',
|
||||
'gnome-mahjongg.desktop': 'org.gnome.Mahjongg.desktop',
|
||||
'gnome-mines.desktop': 'org.gnome.Mines.desktop',
|
||||
'gnome-music.desktop': 'org.gnome.Music.desktop',
|
||||
'gnome-photos.desktop': 'org.gnome.Photos.desktop',
|
||||
'gnome-robots.desktop': 'org.gnome.Robots.desktop',
|
||||
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
|
||||
'gnome-software.desktop': 'org.gnome.Software.desktop',
|
||||
'gnome-terminal.desktop': 'org.gnome.Terminal.desktop',
|
||||
'gnome-tetravex.desktop': 'org.gnome.Tetravex.desktop',
|
||||
'gnome-tweaks.desktop': 'org.gnome.tweaks.desktop',
|
||||
'gnome-weather.desktop': 'org.gnome.Weather.Application.desktop',
|
||||
'gnomine.desktop': 'gnome-mines.desktop',
|
||||
'gnotravex.desktop': 'gnome-tetravex.desktop',
|
||||
'gnotski.desktop': 'gnome-klotski.desktop',
|
||||
'gtali.desktop': 'tali.desktop',
|
||||
'gnome-weather.desktop': 'org.gnome.Weather.desktop',
|
||||
'gnomine.desktop': 'org.gnome.Mines.desktop',
|
||||
'gnotravex.desktop': 'org.gnome.Tetravex.desktop',
|
||||
'gnotski.desktop': 'org.gnome.Klotski.desktop',
|
||||
'gtali.desktop': 'org.gnome.Tali.desktop',
|
||||
'iagno.desktop': 'org.gnome.Reversi.desktop',
|
||||
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
|
||||
'org.gnome.gnome-2048.desktop': 'org.gnome.TwentyFortyEight.desktop',
|
||||
'org.gnome.taquin.desktop': 'org.gnome.Taquin.desktop',
|
||||
'org.gnome.Weather.Application.desktop': 'org.gnome.Weather.desktop',
|
||||
'polari.desktop': 'org.gnome.Polari.desktop',
|
||||
'tali.desktop': 'org.gnome.Tali.desktop',
|
||||
'totem.desktop': 'org.gnome.Totem.desktop',
|
||||
'evince.desktop': 'org.gnome.Evince.desktop',
|
||||
};
|
||||
|
||||
var AppFavorites = new Lang.Class({
|
||||
Name: 'AppFavorites',
|
||||
|
||||
FAVORITE_APPS_KEY: 'favorite-apps',
|
||||
|
||||
_init() {
|
||||
class AppFavorites {
|
||||
constructor() {
|
||||
this.FAVORITE_APPS_KEY = 'favorite-apps';
|
||||
this._favorites = {};
|
||||
global.settings.connect('changed::' + this.FAVORITE_APPS_KEY, this._onFavsChanged.bind(this));
|
||||
global.settings.connect(`changed::${this.FAVORITE_APPS_KEY}`, this._onFavsChanged.bind(this));
|
||||
this.reload();
|
||||
},
|
||||
}
|
||||
|
||||
_onFavsChanged() {
|
||||
this.reload();
|
||||
this.emit('changed');
|
||||
},
|
||||
}
|
||||
|
||||
reload() {
|
||||
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
|
||||
@@ -89,29 +99,29 @@ var AppFavorites = new Lang.Class({
|
||||
let app = apps[i];
|
||||
this._favorites[app.get_id()] = app;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_getIds() {
|
||||
let ret = [];
|
||||
for (let id in this._favorites)
|
||||
ret.push(id);
|
||||
return ret;
|
||||
},
|
||||
}
|
||||
|
||||
getFavoriteMap() {
|
||||
return this._favorites;
|
||||
},
|
||||
}
|
||||
|
||||
getFavorites() {
|
||||
let ret = [];
|
||||
for (let id in this._favorites)
|
||||
ret.push(this._favorites[id]);
|
||||
return ret;
|
||||
},
|
||||
}
|
||||
|
||||
isFavorite(appId) {
|
||||
return appId in this._favorites;
|
||||
},
|
||||
}
|
||||
|
||||
_addFavorite(appId, pos) {
|
||||
if (appId in this._favorites)
|
||||
@@ -129,7 +139,7 @@ var AppFavorites = new Lang.Class({
|
||||
ids.splice(pos, 0, appId);
|
||||
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
addFavoriteAtPos(appId, pos) {
|
||||
if (!this._addFavorite(appId, pos))
|
||||
@@ -143,25 +153,25 @@ var AppFavorites = new Lang.Class({
|
||||
this._removeFavorite(appId);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
addFavorite(appId) {
|
||||
this.addFavoriteAtPos(appId, -1);
|
||||
},
|
||||
}
|
||||
|
||||
moveFavoriteToPos(appId, pos) {
|
||||
this._removeFavorite(appId);
|
||||
this._addFavorite(appId, pos);
|
||||
},
|
||||
}
|
||||
|
||||
_removeFavorite(appId) {
|
||||
if (!appId in this._favorites)
|
||||
if (!(appId in this._favorites))
|
||||
return false;
|
||||
|
||||
let ids = this._getIds().filter(id => id != appId);
|
||||
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
removeFavorite(appId) {
|
||||
let ids = this._getIds();
|
||||
@@ -178,7 +188,7 @@ var AppFavorites = new Lang.Class({
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
Signals.addSignalMethods(AppFavorites.prototype);
|
||||
|
||||
var appFavoritesInstance = null;
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
/* exported AudioDeviceSelectionDBus */
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
@@ -19,12 +14,11 @@ var AudioDevice = {
|
||||
|
||||
const AudioDeviceSelectionIface = loadInterfaceXML('org.gnome.Shell.AudioDeviceSelection');
|
||||
|
||||
var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
Name: 'AudioDeviceSelectionDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
var AudioDeviceSelectionDialog = GObject.registerClass({
|
||||
Signals: { 'device-selected': { param_types: [GObject.TYPE_UINT] } }
|
||||
}, class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
|
||||
_init(devices) {
|
||||
this.parent({ styleClass: 'audio-device-selection-dialog' });
|
||||
super._init({ styleClass: 'audio-device-selection-dialog' });
|
||||
|
||||
this._deviceItems = {};
|
||||
|
||||
@@ -39,13 +33,9 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
|
||||
if (this._selectionBox.get_n_children() < 2)
|
||||
throw new Error('Too few devices for a selection');
|
||||
},
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.parent();
|
||||
},
|
||||
|
||||
_buildLayout(devices) {
|
||||
_buildLayout() {
|
||||
let title = new St.Label({ style_class: 'audio-selection-title',
|
||||
text: _("Select Audio Device"),
|
||||
x_align: Clutter.ActorAlign.CENTER });
|
||||
@@ -56,38 +46,39 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
this._selectionBox = new St.BoxLayout({ style_class: 'audio-selection-box' });
|
||||
this.contentLayout.add(this._selectionBox, { expand: true });
|
||||
|
||||
this.addButton({ action: this._openSettings.bind(this),
|
||||
label: _("Sound Settings") });
|
||||
if (Main.sessionMode.allowSettings)
|
||||
this.addButton({ action: this._openSettings.bind(this),
|
||||
label: _("Sound Settings") });
|
||||
this.addButton({ action: this.close.bind(this),
|
||||
label: _("Cancel"),
|
||||
key: Clutter.Escape });
|
||||
},
|
||||
}
|
||||
|
||||
_getDeviceLabel(device) {
|
||||
switch(device) {
|
||||
case AudioDevice.HEADPHONES:
|
||||
return _("Headphones");
|
||||
case AudioDevice.HEADSET:
|
||||
return _("Headset");
|
||||
case AudioDevice.MICROPHONE:
|
||||
return _("Microphone");
|
||||
default:
|
||||
return null;
|
||||
switch (device) {
|
||||
case AudioDevice.HEADPHONES:
|
||||
return _("Headphones");
|
||||
case AudioDevice.HEADSET:
|
||||
return _("Headset");
|
||||
case AudioDevice.MICROPHONE:
|
||||
return _("Microphone");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_getDeviceIcon(device) {
|
||||
switch(device) {
|
||||
case AudioDevice.HEADPHONES:
|
||||
return 'audio-headphones-symbolic';
|
||||
case AudioDevice.HEADSET:
|
||||
return 'audio-headset-symbolic';
|
||||
case AudioDevice.MICROPHONE:
|
||||
return 'audio-input-microphone-symbolic';
|
||||
default:
|
||||
return null;
|
||||
switch (device) {
|
||||
case AudioDevice.HEADPHONES:
|
||||
return 'audio-headphones-symbolic';
|
||||
case AudioDevice.HEADSET:
|
||||
return 'audio-headset-symbolic';
|
||||
case AudioDevice.MICROPHONE:
|
||||
return 'audio-input-microphone-symbolic';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_addDevice(device) {
|
||||
let box = new St.BoxLayout({ style_class: 'audio-selection-device-box',
|
||||
@@ -95,6 +86,7 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
box.connect('notify::height', () => {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
box.width = box.height;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -117,14 +109,14 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
this.close();
|
||||
Main.overview.hide();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_openSettings() {
|
||||
let desktopFile = 'gnome-sound-panel.desktop'
|
||||
let desktopFile = 'gnome-sound-panel.desktop';
|
||||
let app = Shell.AppSystem.get_default().lookup_app(desktopFile);
|
||||
|
||||
if (!app) {
|
||||
log('Settings panel for desktop file ' + desktopFile + ' could not be loaded!');
|
||||
log(`Settings panel for desktop file ${desktopFile} could not be loaded!`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,21 +126,19 @@ var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
Name: 'AudioDeviceSelectionDBus',
|
||||
|
||||
_init() {
|
||||
var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
|
||||
constructor() {
|
||||
this._audioSelectionDialog = null;
|
||||
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AudioDeviceSelectionIface, this);
|
||||
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/AudioDeviceSelection');
|
||||
|
||||
Gio.DBus.session.own_name('org.gnome.Shell.AudioDeviceSelection', Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||
},
|
||||
}
|
||||
|
||||
_onDialogClosed() {
|
||||
this._audioSelectionDialog = null;
|
||||
},
|
||||
}
|
||||
|
||||
_onDeviceSelected(dialog, device) {
|
||||
let connection = this._dbusImpl.get_connection();
|
||||
@@ -161,7 +151,7 @@ var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
info ? info.name : null,
|
||||
'DeviceSelected',
|
||||
GLib.Variant.new('(s)', [deviceName]));
|
||||
},
|
||||
}
|
||||
|
||||
OpenAsync(params, invocation) {
|
||||
if (this._audioSelectionDialog) {
|
||||
@@ -171,12 +161,12 @@ var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
|
||||
let [deviceNames] = params;
|
||||
let devices = 0;
|
||||
deviceNames.forEach(n => { devices |= AudioDevice[n.toUpperCase()]; });
|
||||
deviceNames.forEach(n => devices |= AudioDevice[n.toUpperCase()]);
|
||||
|
||||
let dialog;
|
||||
try {
|
||||
dialog = new AudioDeviceSelectionDialog(devices);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
invocation.return_value(null);
|
||||
return;
|
||||
}
|
||||
@@ -189,7 +179,7 @@ var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
|
||||
this._audioSelectionDialog = dialog;
|
||||
invocation.return_value(null);
|
||||
},
|
||||
}
|
||||
|
||||
CloseAsync(params, invocation) {
|
||||
if (this._audioSelectionDialog &&
|
||||
@@ -198,4 +188,4 @@ var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
|
||||
invocation.return_value(null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -93,19 +93,12 @@
|
||||
// MetaBackgroundImage MetaBackgroundImage
|
||||
// MetaBackgroundImage MetaBackgroundImage
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const GDesktopEnums = imports.gi.GDesktopEnums;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const GnomeDesktop = imports.gi.GnomeDesktop;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const { Clutter, GDesktopEnums, Gio, GLib, GnomeDesktop, Meta } = imports.gi;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
var DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
|
||||
|
||||
@@ -114,10 +107,9 @@ const PRIMARY_COLOR_KEY = 'primary-color';
|
||||
const SECONDARY_COLOR_KEY = 'secondary-color';
|
||||
const COLOR_SHADING_TYPE_KEY = 'color-shading-type';
|
||||
const BACKGROUND_STYLE_KEY = 'picture-options';
|
||||
const PICTURE_OPACITY_KEY = 'picture-opacity';
|
||||
const PICTURE_URI_KEY = 'picture-uri';
|
||||
|
||||
var FADE_ANIMATION_TIME = 1.0;
|
||||
var FADE_ANIMATION_TIME = 1000;
|
||||
|
||||
// These parameters affect how often we redraw.
|
||||
// The first is how different (percent crossfaded) the slide show
|
||||
@@ -138,14 +130,12 @@ function _fileEqual0(file1, file2) {
|
||||
return file1.equal(file2);
|
||||
}
|
||||
|
||||
var BackgroundCache = new Lang.Class({
|
||||
Name: 'BackgroundCache',
|
||||
|
||||
_init() {
|
||||
var BackgroundCache = class BackgroundCache {
|
||||
constructor() {
|
||||
this._fileMonitors = {};
|
||||
this._backgroundSources = {};
|
||||
this._animations = {};
|
||||
},
|
||||
}
|
||||
|
||||
monitorFile(file) {
|
||||
let key = file.hash();
|
||||
@@ -163,7 +153,7 @@ var BackgroundCache = new Lang.Class({
|
||||
});
|
||||
|
||||
this._fileMonitors[key] = monitor;
|
||||
},
|
||||
}
|
||||
|
||||
getAnimation(params) {
|
||||
params = Params.parse(params, { file: null,
|
||||
@@ -195,7 +185,7 @@ var BackgroundCache = new Lang.Class({
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
getBackgroundSource(layoutManager, settingsSchema) {
|
||||
// The layoutManager is always the same one; we pass in it since
|
||||
@@ -209,7 +199,7 @@ var BackgroundCache = new Lang.Class({
|
||||
}
|
||||
|
||||
return this._backgroundSources[settingsSchema];
|
||||
},
|
||||
}
|
||||
|
||||
releaseBackgroundSource(settingsSchema) {
|
||||
if (settingsSchema in this._backgroundSources) {
|
||||
@@ -221,7 +211,7 @@ var BackgroundCache = new Lang.Class({
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
Signals.addSignalMethods(BackgroundCache.prototype);
|
||||
|
||||
function getBackgroundCache() {
|
||||
@@ -230,10 +220,8 @@ function getBackgroundCache() {
|
||||
return _backgroundCache;
|
||||
}
|
||||
|
||||
var Background = new Lang.Class({
|
||||
Name: 'Background',
|
||||
|
||||
_init(params) {
|
||||
var Background = class Background {
|
||||
constructor(params) {
|
||||
params = Params.parse(params, { monitorIndex: 0,
|
||||
layoutManager: Main.layoutManager,
|
||||
settings: null,
|
||||
@@ -267,14 +255,15 @@ var Background = new Lang.Class({
|
||||
this._refreshAnimation();
|
||||
});
|
||||
|
||||
this._settingsChangedSignalId = this._settings.connect('changed', () => {
|
||||
this.emit('changed');
|
||||
});
|
||||
this._settingsChangedSignalId =
|
||||
this._settings.connect('changed', this._emitChangedSignal.bind(this));
|
||||
|
||||
this._load();
|
||||
},
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.background = null;
|
||||
|
||||
this._cancellable.cancel();
|
||||
this._removeAnimationTimeout();
|
||||
|
||||
@@ -298,12 +287,28 @@ var Background = new Lang.Class({
|
||||
if (this._settingsChangedSignalId != 0)
|
||||
this._settings.disconnect(this._settingsChangedSignalId);
|
||||
this._settingsChangedSignalId = 0;
|
||||
},
|
||||
|
||||
if (this._changedIdleId) {
|
||||
GLib.source_remove(this._changedIdleId);
|
||||
this._changedIdleId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_emitChangedSignal() {
|
||||
if (this._changedIdleId)
|
||||
return;
|
||||
|
||||
this._changedIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this._changedIdleId = 0;
|
||||
this.emit('changed');
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
updateResolution() {
|
||||
if (this._animation)
|
||||
this._refreshAnimation();
|
||||
},
|
||||
}
|
||||
|
||||
_refreshAnimation() {
|
||||
if (!this._animation)
|
||||
@@ -311,7 +316,7 @@ var Background = new Lang.Class({
|
||||
|
||||
this._removeAnimationTimeout();
|
||||
this._updateAnimation();
|
||||
},
|
||||
}
|
||||
|
||||
_setLoaded() {
|
||||
if (this.isLoaded)
|
||||
@@ -324,15 +329,15 @@ var Background = new Lang.Class({
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] this.emit');
|
||||
},
|
||||
}
|
||||
|
||||
_loadPattern() {
|
||||
let colorString, res, color, secondColor;
|
||||
let colorString, res_, color, secondColor;
|
||||
|
||||
colorString = this._settings.get_string(PRIMARY_COLOR_KEY);
|
||||
[res, color] = Clutter.Color.from_string(colorString);
|
||||
[res_, color] = Clutter.Color.from_string(colorString);
|
||||
colorString = this._settings.get_string(SECONDARY_COLOR_KEY);
|
||||
[res, secondColor] = Clutter.Color.from_string(colorString);
|
||||
[res_, secondColor] = Clutter.Color.from_string(colorString);
|
||||
|
||||
let shadingType = this._settings.get_enum(COLOR_SHADING_TYPE_KEY);
|
||||
|
||||
@@ -340,7 +345,7 @@ var Background = new Lang.Class({
|
||||
this.background.set_color(color);
|
||||
else
|
||||
this.background.set_gradient(shadingType, color, secondColor);
|
||||
},
|
||||
}
|
||||
|
||||
_watchFile(file) {
|
||||
let key = file.hash();
|
||||
@@ -353,18 +358,18 @@ var Background = new Lang.Class({
|
||||
if (changedFile.equal(file)) {
|
||||
let imageCache = Meta.BackgroundImageCache.get_default();
|
||||
imageCache.purge(changedFile);
|
||||
this.emit('changed');
|
||||
this._emitChangedSignal();
|
||||
}
|
||||
});
|
||||
this._fileWatches[key] = signalId;
|
||||
},
|
||||
}
|
||||
|
||||
_removeAnimationTimeout() {
|
||||
if (this._updateAnimationTimeoutId) {
|
||||
GLib.source_remove(this._updateAnimationTimeoutId);
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_updateAnimation() {
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
@@ -404,7 +409,7 @@ var Background = new Lang.Class({
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_queueUpdateAnimation() {
|
||||
if (this._updateAnimationTimeoutId != 0)
|
||||
@@ -426,14 +431,14 @@ var Background = new Lang.Class({
|
||||
return;
|
||||
|
||||
this._updateAnimationTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||
interval,
|
||||
() => {
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
this._updateAnimation();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
interval,
|
||||
() => {
|
||||
this._updateAnimationTimeoutId = 0;
|
||||
this._updateAnimation();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._updateAnimationTimeoutId, '[gnome-shell] this._updateAnimation');
|
||||
},
|
||||
}
|
||||
|
||||
_loadAnimation(file) {
|
||||
this._cache.getAnimation({ file: file,
|
||||
@@ -450,7 +455,7 @@ var Background = new Lang.Class({
|
||||
this._watchFile(file);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
_loadImage(file) {
|
||||
this.background.set_file(file, this._style);
|
||||
@@ -458,22 +463,22 @@ var Background = new Lang.Class({
|
||||
|
||||
let cache = Meta.BackgroundImageCache.get_default();
|
||||
let image = cache.load(file);
|
||||
if (image.is_loaded())
|
||||
if (image.is_loaded()) {
|
||||
this._setLoaded();
|
||||
else {
|
||||
} else {
|
||||
let id = image.connect('loaded', () => {
|
||||
this._setLoaded();
|
||||
image.disconnect(id);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_loadFile(file) {
|
||||
if (file.get_basename().endsWith('.xml'))
|
||||
this._loadAnimation(file);
|
||||
else
|
||||
this._loadImage(file);
|
||||
},
|
||||
}
|
||||
|
||||
_load() {
|
||||
this._cache = getBackgroundCache();
|
||||
@@ -486,16 +491,14 @@ var Background = new Lang.Class({
|
||||
}
|
||||
|
||||
this._loadFile(this._file);
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Background.prototype);
|
||||
|
||||
let _systemBackground;
|
||||
|
||||
var SystemBackground = new Lang.Class({
|
||||
Name: 'SystemBackground',
|
||||
|
||||
_init() {
|
||||
var SystemBackground = class SystemBackground {
|
||||
constructor() {
|
||||
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/noise-texture.png');
|
||||
|
||||
if (_systemBackground == null) {
|
||||
@@ -524,14 +527,12 @@ var SystemBackground = new Lang.Class({
|
||||
image = null;
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(SystemBackground.prototype);
|
||||
|
||||
var BackgroundSource = new Lang.Class({
|
||||
Name: 'BackgroundSource',
|
||||
|
||||
_init(layoutManager, settingsSchema) {
|
||||
var BackgroundSource = class BackgroundSource {
|
||||
constructor(layoutManager, settingsSchema) {
|
||||
// Allow override the background image setting for performance testing
|
||||
this._layoutManager = layoutManager;
|
||||
this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE');
|
||||
@@ -542,7 +543,7 @@ var BackgroundSource = new Lang.Class({
|
||||
this._monitorsChangedId =
|
||||
monitorManager.connect('monitors-changed',
|
||||
this._onMonitorsChanged.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
_onMonitorsChanged() {
|
||||
for (let monitorIndex in this._backgrounds) {
|
||||
@@ -556,7 +557,7 @@ var BackgroundSource = new Lang.Class({
|
||||
delete this._backgrounds[monitorIndex];
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
getBackground(monitorIndex) {
|
||||
let file = null;
|
||||
@@ -603,7 +604,7 @@ var BackgroundSource = new Lang.Class({
|
||||
}
|
||||
|
||||
return this._backgrounds[monitorIndex];
|
||||
},
|
||||
}
|
||||
|
||||
destroy() {
|
||||
let monitorManager = Meta.MonitorManager.get();
|
||||
@@ -617,12 +618,10 @@ var BackgroundSource = new Lang.Class({
|
||||
|
||||
this._backgrounds = null;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var Animation = new Lang.Class({
|
||||
Name: 'Animation',
|
||||
|
||||
_init(params) {
|
||||
var Animation = class Animation {
|
||||
constructor(params) {
|
||||
params = Params.parse(params, { file: null });
|
||||
|
||||
this.file = params.file;
|
||||
@@ -630,17 +629,17 @@ var Animation = new Lang.Class({
|
||||
this.transitionProgress = 0.0;
|
||||
this.transitionDuration = 0.0;
|
||||
this.loaded = false;
|
||||
},
|
||||
}
|
||||
|
||||
load(callback) {
|
||||
this._show = new GnomeDesktop.BGSlideShow({ filename: this.file.get_path() });
|
||||
this._show = new GnomeDesktop.BGSlideShow({ file: this.file });
|
||||
|
||||
this._show.load_async(null, (object, result) => {
|
||||
this._show.load_async(null, () => {
|
||||
this.loaded = true;
|
||||
if (callback)
|
||||
callback();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
update(monitor) {
|
||||
this.keyFrameFiles = [];
|
||||
@@ -651,7 +650,7 @@ var Animation = new Lang.Class({
|
||||
if (this._show.get_num_slides() < 1)
|
||||
return;
|
||||
|
||||
let [progress, duration, isFixed, filename1, filename2] = this._show.get_current_slide(monitor.width, monitor.height);
|
||||
let [progress, duration, isFixed_, filename1, filename2] = this._show.get_current_slide(monitor.width, monitor.height);
|
||||
|
||||
this.transitionDuration = duration;
|
||||
this.transitionProgress = progress;
|
||||
@@ -661,14 +660,12 @@ var Animation = new Lang.Class({
|
||||
|
||||
if (filename2)
|
||||
this.keyFrameFiles.push(Gio.File.new_for_path(filename2));
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Animation.prototype);
|
||||
|
||||
var BackgroundManager = new Lang.Class({
|
||||
Name: 'BackgroundManager',
|
||||
|
||||
_init(params) {
|
||||
var BackgroundManager = class BackgroundManager {
|
||||
constructor(params) {
|
||||
params = Params.parse(params, { container: null,
|
||||
layoutManager: Main.layoutManager,
|
||||
monitorIndex: null,
|
||||
@@ -688,7 +685,7 @@ var BackgroundManager = new Lang.Class({
|
||||
|
||||
this.backgroundActor = this._createBackgroundActor();
|
||||
this._newBackgroundActor = null;
|
||||
},
|
||||
}
|
||||
|
||||
destroy() {
|
||||
let cache = getBackgroundCache();
|
||||
@@ -704,7 +701,7 @@ var BackgroundManager = new Lang.Class({
|
||||
this.backgroundActor.destroy();
|
||||
this.backgroundActor = null;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_swapBackgroundActor() {
|
||||
let oldBackgroundActor = this.backgroundActor;
|
||||
@@ -712,16 +709,13 @@ var BackgroundManager = new Lang.Class({
|
||||
this._newBackgroundActor = null;
|
||||
this.emit('changed');
|
||||
|
||||
Tweener.addTween(oldBackgroundActor,
|
||||
{ opacity: 0,
|
||||
time: FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete() {
|
||||
oldBackgroundActor.background.run_dispose();
|
||||
oldBackgroundActor.destroy();
|
||||
}
|
||||
});
|
||||
},
|
||||
oldBackgroundActor.ease({
|
||||
opacity: 0,
|
||||
duration: FADE_ANIMATION_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => oldBackgroundActor.destroy()
|
||||
});
|
||||
}
|
||||
|
||||
_updateBackgroundActor() {
|
||||
if (this._newBackgroundActor) {
|
||||
@@ -750,7 +744,7 @@ var BackgroundManager = new Lang.Class({
|
||||
this._swapBackgroundActor();
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_createBackgroundActor() {
|
||||
let background = this._backgroundSource.getBackground(this._monitorIndex);
|
||||
@@ -764,10 +758,8 @@ var BackgroundManager = new Lang.Class({
|
||||
|
||||
this._container.add_child(backgroundActor);
|
||||
|
||||
let monitor = this._layoutManager.monitors[this._monitorIndex];
|
||||
|
||||
backgroundActor.set_size(monitor.width, monitor.height);
|
||||
if (this._controlPosition) {
|
||||
let monitor = this._layoutManager.monitors[this._monitorIndex];
|
||||
backgroundActor.set_position(monitor.x, monitor.y);
|
||||
backgroundActor.lower_bottom();
|
||||
}
|
||||
@@ -787,6 +779,6 @@ var BackgroundManager = new Lang.Class({
|
||||
});
|
||||
|
||||
return backgroundActor;
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(BackgroundManager.prototype);
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported addBackgroundMenu */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const St = imports.gi.St;
|
||||
const Shell = imports.gi.Shell;
|
||||
const { Clutter, St } = imports.gi;
|
||||
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
|
||||
var BackgroundMenu = new Lang.Class({
|
||||
Name: 'BackgroundMenu',
|
||||
Extends: PopupMenu.PopupMenu,
|
||||
|
||||
_init(layoutManager) {
|
||||
this.parent(layoutManager.dummyCursor, 0, St.Side.TOP);
|
||||
var BackgroundMenu = class BackgroundMenu extends PopupMenu.PopupMenu {
|
||||
constructor(layoutManager) {
|
||||
super(layoutManager.dummyCursor, 0, St.Side.TOP);
|
||||
|
||||
this.addSettingsAction(_("Change Background…"), 'gnome-background-panel.desktop');
|
||||
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||
@@ -26,12 +21,12 @@ var BackgroundMenu = new Lang.Class({
|
||||
layoutManager.uiGroup.add_actor(this.actor);
|
||||
this.actor.hide();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function addBackgroundMenu(actor, layoutManager) {
|
||||
actor.reactive = true;
|
||||
actor._backgroundMenu = new BackgroundMenu(layoutManager);
|
||||
actor._backgroundManager = new PopupMenu.PopupMenuManager({ actor: actor });
|
||||
actor._backgroundManager = new PopupMenu.PopupMenuManager(actor);
|
||||
actor._backgroundManager.addMenu(actor._backgroundMenu);
|
||||
|
||||
function openMenu(x, y) {
|
||||
|
||||
@@ -1,80 +1,106 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
/* exported BarLevel */
|
||||
|
||||
const Atk = imports.gi.Atk;
|
||||
const Cairo = imports.cairo;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const St = imports.gi.St;
|
||||
const Signals = imports.signals;
|
||||
const { Atk, Clutter, GObject, St } = imports.gi;
|
||||
|
||||
var BarLevel = new Lang.Class({
|
||||
Name: "BarLevel",
|
||||
|
||||
_init(value, params) {
|
||||
if (isNaN(value))
|
||||
// Avoid spreading NaNs around
|
||||
throw TypeError('The bar level value must be a number');
|
||||
var BarLevel = GObject.registerClass({
|
||||
Properties: {
|
||||
'value': GObject.ParamSpec.double(
|
||||
'value', 'value', 'value',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
0, 2, 0),
|
||||
'maximum-value': GObject.ParamSpec.double(
|
||||
'maximum-value', 'maximum-value', 'maximum-value',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
1, 2, 1),
|
||||
'overdrive-start': GObject.ParamSpec.double(
|
||||
'overdrive-start', 'overdrive-start', 'overdrive-start',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
1, 2, 1)
|
||||
}
|
||||
}, class BarLevel extends St.DrawingArea {
|
||||
_init(params) {
|
||||
this._maxValue = 1;
|
||||
this._value = Math.max(Math.min(value, this._maxValue), 0);
|
||||
this._value = 0;
|
||||
this._overdriveStart = 1;
|
||||
this._barLevelWidth = 0;
|
||||
|
||||
if (params == undefined)
|
||||
params = {}
|
||||
|
||||
this.actor = new St.DrawingArea({ styleClass: params['styleClass'] || 'barlevel',
|
||||
can_focus: params['canFocus'] || false,
|
||||
reactive: params['reactive'] || false,
|
||||
accessible_role: params['accessibleRole'] || Atk.Role.LEVEL_BAR });
|
||||
this.actor.connect('repaint', this._barLevelRepaint.bind(this));
|
||||
this.actor.connect('allocation-changed', (actor, box) => {
|
||||
let defaultParams = {
|
||||
style_class: 'barlevel',
|
||||
accessible_role: Atk.Role.LEVEL_BAR
|
||||
};
|
||||
super._init(Object.assign(defaultParams, params));
|
||||
this.connect('allocation-changed', (actor, box) => {
|
||||
this._barLevelWidth = box.get_width();
|
||||
});
|
||||
|
||||
this._customAccessible = St.GenericAccessible.new_for_actor(this.actor);
|
||||
this.actor.set_accessible(this._customAccessible);
|
||||
this._customAccessible = St.GenericAccessible.new_for_actor(this);
|
||||
this.set_accessible(this._customAccessible);
|
||||
|
||||
this._customAccessible.connect('get-current-value', this._getCurrentValue.bind(this));
|
||||
this._customAccessible.connect('get-minimum-value', this._getMinimumValue.bind(this));
|
||||
this._customAccessible.connect('get-maximum-value', this._getMaximumValue.bind(this));
|
||||
this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this));
|
||||
|
||||
this.connect('value-changed', this._valueChanged.bind(this));
|
||||
},
|
||||
this.connect('notify::value', this._valueChanged.bind(this));
|
||||
}
|
||||
|
||||
setValue(value) {
|
||||
if (isNaN(value))
|
||||
throw TypeError('The bar level value must be a number');
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
this._value = Math.max(Math.min(value, this._maxValue), 0);
|
||||
this.actor.queue_repaint();
|
||||
},
|
||||
set value(value) {
|
||||
value = Math.max(Math.min(value, this._maxValue), 0);
|
||||
|
||||
setMaximumValue(value) {
|
||||
if (isNaN(value))
|
||||
throw TypeError('The bar level max value must be a number');
|
||||
if (this._value == value)
|
||||
return;
|
||||
|
||||
this._maxValue = Math.max(value, 1);
|
||||
this._value = value;
|
||||
this.notify('value');
|
||||
this.queue_repaint();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get maximum_value() {
|
||||
return this._maxValue;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
set maximum_value(value) {
|
||||
value = Math.max(value, 1);
|
||||
|
||||
if (this._maxValue == value)
|
||||
return;
|
||||
|
||||
this._maxValue = value;
|
||||
this._overdriveStart = Math.min(this._overdriveStart, this._maxValue);
|
||||
this.actor.queue_repaint();
|
||||
},
|
||||
this.notify('maximum-value');
|
||||
this.queue_repaint();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
get overdrive_start() {
|
||||
return this._overdriveStart;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
set overdrive_start(value) {
|
||||
if (this._overdriveStart == value)
|
||||
return;
|
||||
|
||||
setOverdriveStart(value) {
|
||||
if (isNaN(value))
|
||||
throw TypeError('The overdrive limit value must be a number');
|
||||
if (value > this._maxValue)
|
||||
throw new Error(`Tried to set overdrive value to ${value}, ` +
|
||||
`which is a number greater than the maximum allowed value ${this._maxValue}`);
|
||||
|
||||
this._overdriveStart = value;
|
||||
this._value = Math.max(Math.min(value, this._maxValue), 0);
|
||||
this.actor.queue_repaint();
|
||||
},
|
||||
this.notify('overdrive-start');
|
||||
this.queue_repaint();
|
||||
}
|
||||
|
||||
_barLevelRepaint(area) {
|
||||
let cr = area.get_context();
|
||||
let themeNode = area.get_theme_node();
|
||||
let [width, height] = area.get_surface_size();
|
||||
vfunc_repaint() {
|
||||
let cr = this.get_context();
|
||||
let themeNode = this.get_theme_node();
|
||||
let [width, height] = this.get_surface_size();
|
||||
|
||||
let barLevelHeight = themeNode.get_length('-barlevel-height');
|
||||
let barLevelBorderRadius = Math.min(width, barLevelHeight) / 2;
|
||||
@@ -111,7 +137,7 @@ var BarLevel = new Lang.Class({
|
||||
overdriveSeparatorWidth = themeNode.get_length('-barlevel-overdrive-separator-width');
|
||||
|
||||
/* background bar */
|
||||
cr.arc(width - barLevelBorderRadius - barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
|
||||
cr.arc(width - barLevelBorderRadius - barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4));
|
||||
cr.lineTo(endX, (height + barLevelHeight) / 2);
|
||||
cr.lineTo(endX, (height - barLevelHeight) / 2);
|
||||
cr.lineTo(width - barLevelBorderRadius - barLevelBorderWidth, (height - barLevelHeight) / 2);
|
||||
@@ -123,11 +149,12 @@ var BarLevel = new Lang.Class({
|
||||
|
||||
/* normal progress bar */
|
||||
let x = Math.min(endX, overdriveSeparatorX - overdriveSeparatorWidth / 2);
|
||||
cr.arc(barLevelBorderRadius + barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 1 / 4, TAU * 3 / 4);
|
||||
cr.arc(barLevelBorderRadius + barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * (1 / 4), TAU * (3 / 4));
|
||||
cr.lineTo(x, (height - barLevelHeight) / 2);
|
||||
cr.lineTo(x, (height + barLevelHeight) / 2);
|
||||
cr.lineTo(barLevelBorderRadius + barLevelBorderWidth, (height + barLevelHeight) / 2);
|
||||
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
|
||||
if (this._value > 0)
|
||||
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
|
||||
cr.fillPreserve();
|
||||
Clutter.cairo_set_source_color(cr, barLevelActiveBorderColor);
|
||||
cr.setLineWidth(barLevelBorderWidth);
|
||||
@@ -149,17 +176,19 @@ var BarLevel = new Lang.Class({
|
||||
}
|
||||
|
||||
/* end progress bar arc */
|
||||
if (this._value <= this._overdriveStart)
|
||||
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
|
||||
else
|
||||
Clutter.cairo_set_source_color(cr, barLevelOverdriveColor);
|
||||
cr.arc(endX, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
|
||||
cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2);
|
||||
cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2);
|
||||
cr.lineTo(endX, (height - barLevelHeight) / 2);
|
||||
cr.fillPreserve();
|
||||
cr.setLineWidth(barLevelBorderWidth);
|
||||
cr.stroke();
|
||||
if (this._value > 0) {
|
||||
if (this._value <= this._overdriveStart)
|
||||
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
|
||||
else
|
||||
Clutter.cairo_set_source_color(cr, barLevelOverdriveColor);
|
||||
cr.arc(endX, height / 2, barLevelBorderRadius, TAU * (3 / 4), TAU * (1 / 4));
|
||||
cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2);
|
||||
cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2);
|
||||
cr.lineTo(endX, (height - barLevelHeight) / 2);
|
||||
cr.fillPreserve();
|
||||
cr.setLineWidth(barLevelBorderWidth);
|
||||
cr.stroke();
|
||||
}
|
||||
|
||||
/* draw overdrive separator */
|
||||
if (overdriveActive) {
|
||||
@@ -176,35 +205,29 @@ var BarLevel = new Lang.Class({
|
||||
}
|
||||
|
||||
cr.$dispose();
|
||||
},
|
||||
}
|
||||
|
||||
_getCurrentValue(actor) {
|
||||
return this._value;
|
||||
},
|
||||
|
||||
_getOverdriveStart(actor) {
|
||||
return this._overdriveStart;
|
||||
},
|
||||
|
||||
_getMinimumValue(actor) {
|
||||
return 0;
|
||||
},
|
||||
|
||||
_getMaximumValue(actor) {
|
||||
return this._maxValue;
|
||||
},
|
||||
|
||||
_setCurrentValue(actor, value) {
|
||||
this._value = value;
|
||||
},
|
||||
|
||||
_valueChanged(barLevel, value, property) {
|
||||
this._customAccessible.notify("accessible-value");
|
||||
},
|
||||
|
||||
get value() {
|
||||
_getCurrentValue() {
|
||||
return this._value;
|
||||
}
|
||||
});
|
||||
|
||||
Signals.addSignalMethods(BarLevel.prototype);
|
||||
_getOverdriveStart() {
|
||||
return this._overdriveStart;
|
||||
}
|
||||
|
||||
_getMinimumValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_getMaximumValue() {
|
||||
return this._maxValue;
|
||||
}
|
||||
|
||||
_setCurrentValue(_actor, value) {
|
||||
this._value = value;
|
||||
}
|
||||
|
||||
_valueChanged() {
|
||||
this._customAccessible.notify("accessible-value");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported BoxPointer */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const { Clutter, GObject, Shell, St } = imports.gi;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
var PopupAnimation = {
|
||||
NONE: 0,
|
||||
@@ -17,7 +12,7 @@ var PopupAnimation = {
|
||||
FULL: ~0,
|
||||
};
|
||||
|
||||
var POPUP_ANIMATION_TIME = 0.15;
|
||||
var POPUP_ANIMATION_TIME = 150;
|
||||
|
||||
/**
|
||||
* BoxPointer:
|
||||
@@ -29,18 +24,14 @@ var POPUP_ANIMATION_TIME = 0.15;
|
||||
* placed. The arrow position may be controlled via
|
||||
* setArrowOrigin(). The arrow side might be temporarily flipped
|
||||
* depending on the box size and source position to keep the box
|
||||
* totally inside the monitor if possible.
|
||||
* totally inside the monitor workarea if possible.
|
||||
*
|
||||
*/
|
||||
var BoxPointer = new Lang.Class({
|
||||
Name: 'BoxPointer',
|
||||
Extends: St.Widget,
|
||||
var BoxPointer = GObject.registerClass({
|
||||
Signals: { 'arrow-side-changed': {} },
|
||||
|
||||
}, class BoxPointer extends St.Widget {
|
||||
_init(arrowSide, binProperties) {
|
||||
this.parent();
|
||||
|
||||
this.actor = this;
|
||||
super._init();
|
||||
|
||||
this.set_offscreen_redirect(Clutter.OffscreenRedirect.ALWAYS);
|
||||
|
||||
@@ -54,61 +45,36 @@ var BoxPointer = new Lang.Class({
|
||||
this._border.connect('repaint', this._drawBorder.bind(this));
|
||||
this.add_actor(this._border);
|
||||
this.bin.raise(this._border);
|
||||
this._xOffset = 0;
|
||||
this._yOffset = 0;
|
||||
this._xPosition = 0;
|
||||
this._yPosition = 0;
|
||||
this._sourceAlignment = 0.5;
|
||||
this._capturedEventId = 0;
|
||||
this._muteInput();
|
||||
},
|
||||
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
if (this._sourceActorDestroyId) {
|
||||
this._sourceActor.disconnect(this._sourceActorDestroyId);
|
||||
delete this._sourceActorDestroyId;
|
||||
}
|
||||
}
|
||||
|
||||
get arrowSide() {
|
||||
return this._arrowSide;
|
||||
},
|
||||
}
|
||||
|
||||
_muteInput() {
|
||||
if (this._capturedEventId == 0)
|
||||
this._capturedEventId = this.connect('captured-event',
|
||||
() => Clutter.EVENT_STOP);
|
||||
},
|
||||
}
|
||||
|
||||
_unmuteInput() {
|
||||
if (this._capturedEventId != 0) {
|
||||
this.disconnect(this._capturedEventId);
|
||||
this._capturedEventId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
// BoxPointer.show() and BoxPointer.hide() are here for only compatibility
|
||||
// purposes, and will be removed in 3.32.
|
||||
show(animate, onComplete) {
|
||||
if (animate !== undefined) {
|
||||
try {
|
||||
throw new Error('BoxPointer.show() has been moved to BoxPointer.open(), this code will break in the future.');
|
||||
} catch(e) {
|
||||
logError(e);
|
||||
this.open(animate, onComplete);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.visible = true;
|
||||
},
|
||||
|
||||
hide(animate, onComplete) {
|
||||
if (animate !== undefined) {
|
||||
try {
|
||||
throw new Error('BoxPointer.hide() has been moved to BoxPointer.close(), this code will break in the future.');
|
||||
} catch(e) {
|
||||
logError(e);
|
||||
this.close(animate, onComplete);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.visible = false;
|
||||
},
|
||||
}
|
||||
|
||||
open(animate, onComplete) {
|
||||
let themeNode = this.get_theme_node();
|
||||
@@ -124,39 +90,41 @@ var BoxPointer = new Lang.Class({
|
||||
|
||||
if (animate & PopupAnimation.SLIDE) {
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
this.yOffset = -rise;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
this.yOffset = rise;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
this.xOffset = -rise;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
this.xOffset = rise;
|
||||
break;
|
||||
case St.Side.TOP:
|
||||
this.translation_y = -rise;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
this.translation_y = rise;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
this.translation_x = -rise;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
this.translation_x = rise;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Tweener.addTween(this, { opacity: 255,
|
||||
xOffset: 0,
|
||||
yOffset: 0,
|
||||
transition: 'linear',
|
||||
onComplete: () => {
|
||||
this._unmuteInput();
|
||||
if (onComplete)
|
||||
onComplete();
|
||||
},
|
||||
time: animationTime });
|
||||
},
|
||||
this.ease({
|
||||
opacity: 255,
|
||||
translation_x: 0,
|
||||
translation_y: 0,
|
||||
duration: animationTime,
|
||||
mode: Clutter.AnimationMode.LINEAR,
|
||||
onComplete: () => {
|
||||
this._unmuteInput();
|
||||
if (onComplete)
|
||||
onComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
close(animate, onComplete) {
|
||||
if (!this.visible)
|
||||
return;
|
||||
|
||||
let xOffset = 0;
|
||||
let yOffset = 0;
|
||||
let translationX = 0;
|
||||
let translationY = 0;
|
||||
let themeNode = this.get_theme_node();
|
||||
let rise = themeNode.get_length('-arrow-rise');
|
||||
let fade = (animate & PopupAnimation.FADE);
|
||||
@@ -164,39 +132,40 @@ var BoxPointer = new Lang.Class({
|
||||
|
||||
if (animate & PopupAnimation.SLIDE) {
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
yOffset = rise;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
yOffset = -rise;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
xOffset = rise;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
xOffset = -rise;
|
||||
break;
|
||||
case St.Side.TOP:
|
||||
translationY = rise;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
translationY = -rise;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
translationX = rise;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
translationX = -rise;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this._muteInput();
|
||||
|
||||
Tweener.removeTweens(this);
|
||||
Tweener.addTween(this, { opacity: fade ? 0 : 255,
|
||||
xOffset: xOffset,
|
||||
yOffset: yOffset,
|
||||
transition: 'linear',
|
||||
time: animationTime,
|
||||
onComplete: () => {
|
||||
this.hide();
|
||||
this.opacity = 0;
|
||||
this.xOffset = 0;
|
||||
this.yOffset = 0;
|
||||
if (onComplete)
|
||||
onComplete();
|
||||
}
|
||||
});
|
||||
},
|
||||
this.remove_all_transitions();
|
||||
this.ease({
|
||||
opacity: fade ? 0 : 255,
|
||||
translation_x: translationX,
|
||||
translation_y: translationY,
|
||||
duration: animationTime,
|
||||
mode: Clutter.AnimationMode.LINEAR,
|
||||
onComplete: () => {
|
||||
this.hide();
|
||||
this.opacity = 0;
|
||||
this.translation_x = 0;
|
||||
this.translation_y = 0;
|
||||
if (onComplete)
|
||||
onComplete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_adjustAllocationForArrow(isWidth, minSize, natSize) {
|
||||
let themeNode = this.get_theme_node();
|
||||
@@ -211,7 +180,7 @@ var BoxPointer = new Lang.Class({
|
||||
}
|
||||
|
||||
return [minSize, natSize];
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let themeNode = this.get_theme_node();
|
||||
@@ -221,7 +190,7 @@ var BoxPointer = new Lang.Class({
|
||||
width = this._adjustAllocationForArrow(true, ...width);
|
||||
|
||||
return themeNode.adjust_preferred_width(...width);
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let themeNode = this.get_theme_node();
|
||||
@@ -232,19 +201,16 @@ var BoxPointer = new Lang.Class({
|
||||
height = this._adjustAllocationForArrow(false, ...height);
|
||||
|
||||
return themeNode.adjust_preferred_height(...height);
|
||||
},
|
||||
}
|
||||
|
||||
vfunc_allocate(box, flags) {
|
||||
this.set_allocation(box, flags);
|
||||
|
||||
let themeNode = this.get_theme_node();
|
||||
box = themeNode.get_content_box(box);
|
||||
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
let rise = themeNode.get_length('-arrow-rise');
|
||||
let childBox = new Clutter.ActorBox();
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
let [availWidth, availHeight] = themeNode.get_content_box(box).get_size();
|
||||
|
||||
childBox.x1 = 0;
|
||||
childBox.y1 = 0;
|
||||
@@ -257,26 +223,27 @@ var BoxPointer = new Lang.Class({
|
||||
childBox.x2 = availWidth - borderWidth;
|
||||
childBox.y2 = availHeight - borderWidth;
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
childBox.y1 += rise;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
childBox.y2 -= rise;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
childBox.x1 += rise;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
childBox.x2 -= rise;
|
||||
break;
|
||||
case St.Side.TOP:
|
||||
childBox.y1 += rise;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
childBox.y2 -= rise;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
childBox.x1 += rise;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
childBox.x2 -= rise;
|
||||
break;
|
||||
}
|
||||
this.bin.allocate(childBox, flags);
|
||||
|
||||
if (this._sourceActor && this._sourceActor.mapped) {
|
||||
this._reposition();
|
||||
this._updateFlip();
|
||||
this._reposition(box);
|
||||
this._updateFlip(box);
|
||||
this.set_allocation(box, flags);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_drawBorder(area) {
|
||||
let themeNode = this.get_theme_node();
|
||||
@@ -300,7 +267,7 @@ var BoxPointer = new Lang.Class({
|
||||
let borderRadius = themeNode.get_length('-arrow-border-radius');
|
||||
|
||||
let halfBorder = borderWidth / 2;
|
||||
let halfBase = Math.floor(base/2);
|
||||
let halfBase = Math.floor(base / 2);
|
||||
|
||||
let backgroundColor = themeNode.get_color('-arrow-background-color');
|
||||
|
||||
@@ -381,7 +348,7 @@ var BoxPointer = new Lang.Class({
|
||||
if (!skipTopRight) {
|
||||
cr.lineTo(x2 - borderRadius, y1);
|
||||
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 && rise) {
|
||||
@@ -402,7 +369,7 @@ var BoxPointer = new Lang.Class({
|
||||
if (!skipBottomRight) {
|
||||
cr.lineTo(x2, y2 - borderRadius);
|
||||
cr.arc(x2 - borderRadius, y2 - borderRadius, borderRadius,
|
||||
0, Math.PI/2);
|
||||
0, Math.PI / 2);
|
||||
}
|
||||
|
||||
if (this._arrowSide == St.Side.BOTTOM && rise) {
|
||||
@@ -423,7 +390,7 @@ var BoxPointer = new Lang.Class({
|
||||
if (!skipBottomLeft) {
|
||||
cr.lineTo(x1 + borderRadius, y2);
|
||||
cr.arc(x1 + borderRadius, y2 - borderRadius, borderRadius,
|
||||
Math.PI/2, Math.PI);
|
||||
Math.PI / 2, Math.PI);
|
||||
}
|
||||
|
||||
if (this._arrowSide == St.Side.LEFT && rise) {
|
||||
@@ -432,7 +399,7 @@ var BoxPointer = new Lang.Class({
|
||||
cr.lineTo(x1 - rise, y1);
|
||||
cr.lineTo(x1 + borderRadius, y1);
|
||||
} else if (skipBottomLeft) {
|
||||
cr.lineTo(x1 - rise, y2)
|
||||
cr.lineTo(x1 - rise, y2);
|
||||
cr.lineTo(x1 - rise, y2 - halfBase);
|
||||
} else {
|
||||
cr.lineTo(x1, this._arrowOrigin + halfBase);
|
||||
@@ -444,7 +411,7 @@ var BoxPointer = new Lang.Class({
|
||||
if (!skipTopLeft) {
|
||||
cr.lineTo(x1, y1 + borderRadius);
|
||||
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);
|
||||
@@ -458,19 +425,29 @@ var BoxPointer = new Lang.Class({
|
||||
}
|
||||
|
||||
cr.$dispose();
|
||||
},
|
||||
}
|
||||
|
||||
setPosition(sourceActor, alignment) {
|
||||
// We need to show it now to force an allocation,
|
||||
// so that we can query the correct size.
|
||||
this.show();
|
||||
if (!this._sourceActor || sourceActor != this._sourceActor) {
|
||||
if (this._sourceActorDestroyId) {
|
||||
this._sourceActor.disconnect(this._sourceActorDestroyId);
|
||||
delete this._sourceActorDestroyId;
|
||||
}
|
||||
|
||||
this._sourceActor = sourceActor;
|
||||
|
||||
if (this._sourceActor) {
|
||||
this._sourceActorDestroyId = this._sourceActor.connect('destroy', () => {
|
||||
this._sourceActor = null;
|
||||
delete this._sourceActorDestroyId;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this._sourceActor = sourceActor;
|
||||
this._arrowAlignment = alignment;
|
||||
|
||||
this._reposition();
|
||||
this._updateFlip();
|
||||
},
|
||||
this.queue_relayout();
|
||||
}
|
||||
|
||||
setSourceAlignment(alignment) {
|
||||
this._sourceAlignment = alignment;
|
||||
@@ -479,24 +456,28 @@ var BoxPointer = new Lang.Class({
|
||||
return;
|
||||
|
||||
this.setPosition(this._sourceActor, this._arrowAlignment);
|
||||
},
|
||||
}
|
||||
|
||||
_reposition() {
|
||||
_reposition(allocationBox) {
|
||||
let sourceActor = this._sourceActor;
|
||||
let alignment = this._arrowAlignment;
|
||||
let monitorIndex = Main.layoutManager.findIndexForActor(sourceActor);
|
||||
|
||||
this._sourceAllocation = Shell.util_get_transformed_allocation(sourceActor);
|
||||
this._workArea = Main.layoutManager.getWorkAreaForMonitor(monitorIndex);
|
||||
|
||||
// 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 sourceAllocation = this._sourceAllocation;
|
||||
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.get_preferred_size();
|
||||
let [, , natWidth, natHeight] = this.get_preferred_size();
|
||||
|
||||
// We also want to keep it onscreen, and separated from the
|
||||
// edge by the same distance as the main part of the box is
|
||||
// separated from its sourceActor
|
||||
let monitor = Main.layoutManager.findMonitorForActor(sourceActor);
|
||||
let workarea = this._workArea;
|
||||
let themeNode = this.get_theme_node();
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
let arrowBase = themeNode.get_length('-arrow-base');
|
||||
@@ -535,7 +516,7 @@ var BoxPointer = new Lang.Class({
|
||||
// of the box to maintain the arrow's accuracy.
|
||||
|
||||
let arrowOrigin;
|
||||
let halfBase = Math.floor(arrowBase/2);
|
||||
let halfBase = Math.floor(arrowBase / 2);
|
||||
let halfBorder = borderWidth / 2;
|
||||
let halfMargin = margin / 2;
|
||||
let [x1, y1] = [halfBorder, halfBorder];
|
||||
@@ -546,8 +527,8 @@ var BoxPointer = new Lang.Class({
|
||||
case St.Side.BOTTOM:
|
||||
resX = sourceCenterX - (halfMargin + (natWidth - margin) * alignment);
|
||||
|
||||
resX = Math.max(resX, monitor.x + padding);
|
||||
resX = Math.min(resX, monitor.x + monitor.width - (padding + natWidth));
|
||||
resX = Math.max(resX, workarea.x + padding);
|
||||
resX = Math.min(resX, workarea.x + workarea.width - (padding + natWidth));
|
||||
|
||||
arrowOrigin = sourceCenterX - resX;
|
||||
if (arrowOrigin <= (x1 + (borderRadius + halfBase))) {
|
||||
@@ -565,8 +546,8 @@ var BoxPointer = new Lang.Class({
|
||||
case St.Side.RIGHT:
|
||||
resY = sourceCenterY - (halfMargin + (natHeight - margin) * alignment);
|
||||
|
||||
resY = Math.max(resY, monitor.y + padding);
|
||||
resY = Math.min(resY, monitor.y + monitor.height - (padding + natHeight));
|
||||
resY = Math.max(resY, workarea.y + padding);
|
||||
resY = Math.min(resY, workarea.y + workarea.height - (padding + natHeight));
|
||||
|
||||
arrowOrigin = sourceCenterY - resY;
|
||||
if (arrowOrigin <= (y1 + (borderRadius + halfBase))) {
|
||||
@@ -590,10 +571,9 @@ var BoxPointer = new Lang.Class({
|
||||
parent = parent.get_parent();
|
||||
}
|
||||
|
||||
this._xPosition = Math.floor(x);
|
||||
this._yPosition = Math.floor(y);
|
||||
this._shiftActor();
|
||||
},
|
||||
// Actually set the position
|
||||
allocationBox.set_origin(Math.floor(x), Math.floor(y));
|
||||
}
|
||||
|
||||
// @origin: Coordinate specifying middle of the arrow, along
|
||||
// the Y axis for St.Side.LEFT, St.Side.RIGHT from the top and X axis from
|
||||
@@ -603,7 +583,7 @@ var BoxPointer = new Lang.Class({
|
||||
this._arrowOrigin = origin;
|
||||
this._border.queue_repaint();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// @actor: an actor relative to which the arrow is positioned.
|
||||
// Differently from setPosition, this will not move the boxpointer itself,
|
||||
@@ -613,95 +593,59 @@ var BoxPointer = new Lang.Class({
|
||||
this._arrowActor = actor;
|
||||
this._border.queue_repaint();
|
||||
}
|
||||
},
|
||||
|
||||
_shiftActor() {
|
||||
// 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 BoxPointer 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.set_anchor_point(-(this._xPosition + this._xOffset),
|
||||
-(this._yPosition + this._yOffset));
|
||||
},
|
||||
}
|
||||
|
||||
_calculateArrowSide(arrowSide) {
|
||||
let sourceAllocation = Shell.util_get_transformed_allocation(this._sourceActor);
|
||||
let [minWidth, minHeight, boxWidth, boxHeight] = this.get_preferred_size();
|
||||
let monitorActor = this.sourceActor;
|
||||
if (!monitorActor)
|
||||
monitorActor = this;
|
||||
let monitor = Main.layoutManager.findMonitorForActor(monitorActor);
|
||||
let sourceAllocation = this._sourceAllocation;
|
||||
let [, , boxWidth, boxHeight] = this.get_preferred_size();
|
||||
let workarea = this._workArea;
|
||||
|
||||
switch (arrowSide) {
|
||||
case St.Side.TOP:
|
||||
if (sourceAllocation.y2 + boxHeight > monitor.y + monitor.height &&
|
||||
boxHeight < sourceAllocation.y1 - monitor.y)
|
||||
if (sourceAllocation.y2 + boxHeight > workarea.y + workarea.height &&
|
||||
boxHeight < sourceAllocation.y1 - workarea.y)
|
||||
return St.Side.BOTTOM;
|
||||
break;
|
||||
case St.Side.BOTTOM:
|
||||
if (sourceAllocation.y1 - boxHeight < monitor.y &&
|
||||
boxHeight < monitor.y + monitor.height - sourceAllocation.y2)
|
||||
if (sourceAllocation.y1 - boxHeight < workarea.y &&
|
||||
boxHeight < workarea.y + workarea.height - sourceAllocation.y2)
|
||||
return St.Side.TOP;
|
||||
break;
|
||||
case St.Side.LEFT:
|
||||
if (sourceAllocation.x2 + boxWidth > monitor.x + monitor.width &&
|
||||
boxWidth < sourceAllocation.x1 - monitor.x)
|
||||
if (sourceAllocation.x2 + boxWidth > workarea.x + workarea.width &&
|
||||
boxWidth < sourceAllocation.x1 - workarea.x)
|
||||
return St.Side.RIGHT;
|
||||
break;
|
||||
case St.Side.RIGHT:
|
||||
if (sourceAllocation.x1 - boxWidth < monitor.x &&
|
||||
boxWidth < monitor.x + monitor.width - sourceAllocation.x2)
|
||||
if (sourceAllocation.x1 - boxWidth < workarea.x &&
|
||||
boxWidth < workarea.x + workarea.width - sourceAllocation.x2)
|
||||
return St.Side.LEFT;
|
||||
break;
|
||||
}
|
||||
|
||||
return arrowSide;
|
||||
},
|
||||
}
|
||||
|
||||
_updateFlip() {
|
||||
_updateFlip(allocationBox) {
|
||||
let arrowSide = this._calculateArrowSide(this._userArrowSide);
|
||||
if (this._arrowSide != arrowSide) {
|
||||
this._arrowSide = arrowSide;
|
||||
this._reposition();
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
this.queue_relayout();
|
||||
return false;
|
||||
});
|
||||
this._reposition(allocationBox);
|
||||
|
||||
this.emit('arrow-side-changed');
|
||||
}
|
||||
},
|
||||
|
||||
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;
|
||||
},
|
||||
}
|
||||
|
||||
updateArrowSide(side) {
|
||||
this._arrowSide = side;
|
||||
this._border.queue_repaint();
|
||||
|
||||
this.emit('arrow-side-changed');
|
||||
},
|
||||
}
|
||||
|
||||
getPadding(side) {
|
||||
return this.bin.get_theme_node().get_padding(side);
|
||||
},
|
||||
}
|
||||
|
||||
getArrowHeight() {
|
||||
return this.get_theme_node().get_length('-arrow-rise');
|
||||
|
||||