Compare commits
682 Commits
wip/rtcm/m
...
3.25.4
Author | SHA1 | Date | |
---|---|---|---|
3b75881c05 | |||
c987d3d2c9 | |||
26e7962dfe | |||
7f4e914b00 | |||
6878ee99d9 | |||
865a1cf587 | |||
96a49770a4 | |||
c67eabaf62 | |||
6c9a7ce84e | |||
033277b68f | |||
2582d16ca7 | |||
9e32ba61fd | |||
6a2af25d48 | |||
a593e4587b | |||
76c4b0a960 | |||
5202181a4d | |||
c64a38f7da | |||
6b71b79d28 | |||
e845f4105a | |||
d461d02cdc | |||
88b1a5d3a0 | |||
8d6efde091 | |||
3ca77e9fe0 | |||
161926c581 | |||
59a70fbc63 | |||
d220e353e0 | |||
593b4318a3 | |||
f77333e4d7 | |||
b5860d687d | |||
fbf5f98eea | |||
1c7a3ee61b | |||
74bd009c86 | |||
516d19eb39 | |||
330a28742f | |||
90f7dfd783 | |||
69a9c222d0 | |||
b3d74bdb0f | |||
77e0c38d82 | |||
bcec9f35d5 | |||
150252391f | |||
d4541a6f81 | |||
c1eaa8e52d | |||
9d77fa8341 | |||
0a8d81c095 | |||
faa0ddafff | |||
a426295168 | |||
0d0e90ce9a | |||
7991a53189 | |||
4427197343 | |||
4c2fd513f4 | |||
b099e9a69c | |||
5962be3904 | |||
b18735da52 | |||
60e7db7126 | |||
ccaae5d3cc | |||
c1758c4d69 | |||
d815c5dfc0 | |||
b73c96d14c | |||
32fdc22811 | |||
4e57b45142 | |||
1ba014d9db | |||
f33560f014 | |||
b50d7143d1 | |||
28d098394a | |||
755698a756 | |||
2a01606c59 | |||
e2f88d67f7 | |||
358133e82f | |||
526f2c8bcf | |||
79aa404c14 | |||
2339c39ae6 | |||
a782de6e06 | |||
0f8718287a | |||
2b459ff202 | |||
fbc5e3709e | |||
326d5c7fb8 | |||
d1c71fd00d | |||
292ac413c8 | |||
fdf988c04d | |||
a00a186772 | |||
e3330b638a | |||
bdc15d680a | |||
82e20f94f4 | |||
5221744d1d | |||
293d1697fe | |||
9c8a470934 | |||
9c4e875de4 | |||
0e922eee36 | |||
875a1d6159 | |||
e995730a4d | |||
3d209838a1 | |||
69396bbc1f | |||
a0140fb2c7 | |||
d8e7fc403b | |||
3d6fdc8ae2 | |||
47b109d25b | |||
6ed7034a6b | |||
4e07d0b073 | |||
708f65e388 | |||
8783654b38 | |||
4c72244c2e | |||
9e0e7a4067 | |||
a256a35779 | |||
d5cac6559d | |||
ce262b36d4 | |||
02a72b12bb | |||
7f7d18749e | |||
2e1e00c3de | |||
e2838a7e06 | |||
ad2cb22785 | |||
7ad6bd95f7 | |||
50d37e74a3 | |||
c22287b517 | |||
73cffb3c7f | |||
4bada06917 | |||
31a4705789 | |||
60c00f0472 | |||
e7bf23890b | |||
15d387df5f | |||
e02d6e5285 | |||
19d0169de4 | |||
7a2d4959f2 | |||
6b3c9539f6 | |||
7e7e3ec016 | |||
83fb34608c | |||
a72f0604dc | |||
4dfad536a3 | |||
0dca5e513b | |||
7090592477 | |||
63f2fdd1a4 | |||
e94de67bd2 | |||
817ff52414 | |||
a55599a239 | |||
94114d82ff | |||
7cc88f96c4 | |||
447bf55e45 | |||
9d53a7700a | |||
51145a3d41 | |||
1297315cc2 | |||
b859a7f763 | |||
41baf0fc74 | |||
c324395ee6 | |||
aecd1c126a | |||
9b7304488e | |||
6362b3d057 | |||
0142fae742 | |||
73680e2433 | |||
e38c26894b | |||
28ca96064b | |||
be95a63a03 | |||
2a3a5dfc0b | |||
94a0ae1ec3 | |||
44fb014a0d | |||
8007f4dda3 | |||
ff425d1db7 | |||
9a65f20d91 | |||
0770383f78 | |||
06fdf2fdc8 | |||
7a20683728 | |||
8e443a2aff | |||
fcbb942e24 | |||
1508d76d32 | |||
ef9dee2a05 | |||
2714d8d0ce | |||
243dae14ea | |||
2cce1b9ea0 | |||
89f4e983d6 | |||
f680cf6050 | |||
4cd4678194 | |||
082bc20bb9 | |||
32ea7d763a | |||
44e80f4c46 | |||
cad5e06041 | |||
65d93eacd3 | |||
8369dc6b64 | |||
a0c31478c0 | |||
647c8df12f | |||
6ab045b9ad | |||
2ebac8c186 | |||
06478f242a | |||
6557ae0a2b | |||
adbec80596 | |||
2369ef1296 | |||
ce0ea0434e | |||
ede6ec2a28 | |||
b4b19b551d | |||
dc295927ed | |||
539cbf3593 | |||
b477d215a8 | |||
5de85c708f | |||
ad80cc8950 | |||
bc3a506e68 | |||
92d740ba21 | |||
d65199d2ac | |||
257b99ebd1 | |||
c8be854365 | |||
436b764952 | |||
86063f15ed | |||
716f209537 | |||
7bba7fbf37 | |||
a102c99c07 | |||
5761db5981 | |||
5d33820bd6 | |||
301acc920d | |||
495f9cba72 | |||
726fc1d4f7 | |||
dd6452fe2a | |||
19aa57454b | |||
c9555a3537 | |||
6f473a4f29 | |||
f785f4ad02 | |||
35d0ba4454 | |||
c3428f1efa | |||
9cc1e6b85c | |||
74e1058183 | |||
7c9f76944b | |||
d393ca4f09 | |||
a786f0bcd2 | |||
199bc85bce | |||
d15b46f5cb | |||
c0861b1227 | |||
f97a3522e5 | |||
577e261d1a | |||
33fcff8a1a | |||
cd30572b70 | |||
bc711b6dec | |||
01f5065b87 | |||
9c2bf17ad7 | |||
5385b36a81 | |||
72ed9da1fc | |||
d79924bdd1 | |||
3b7a4b08e2 | |||
09af4433b0 | |||
50df3084f7 | |||
e90734913d | |||
af18a0cf40 | |||
3d399796a6 | |||
60a2794c8b | |||
e039871298 | |||
e057333bf3 | |||
e0c0d9223e | |||
ada21c975f | |||
b4df747464 | |||
9a38011e1e | |||
e0f1fc2694 | |||
da5390340e | |||
3a6b41495a | |||
ce5875f365 | |||
4373d390dc | |||
9ed512e5c5 | |||
c5856196a7 | |||
afc3a8a7e7 | |||
4714c73f0f | |||
742155c384 | |||
2d814bfc5e | |||
8f8e512b37 | |||
3c828c8387 | |||
7c96b39bef | |||
64dbc8aa7f | |||
5649b9c64a | |||
3d0aab3b66 | |||
ce419da6ec | |||
63b49c65ab | |||
ff5bd0b925 | |||
0892220f63 | |||
1c95c9e3ff | |||
4b80cbe1cd | |||
46f3712421 | |||
18aa4ff30c | |||
8a75143a6e | |||
384a6e8684 | |||
a0008f7471 | |||
b53f95a9a0 | |||
1af88e52dd | |||
535028c9a7 | |||
df816368a5 | |||
f34202c3c8 | |||
28c61754a1 | |||
6e46166df4 | |||
15feaa1074 | |||
d7c532daee | |||
427ec6834d | |||
e594b30ead | |||
f43a8a75e4 | |||
645aa01efd | |||
252dce1ec2 | |||
da0066eb84 | |||
adc811ff8f | |||
5117ccdeef | |||
19816523c7 | |||
846e3f8243 | |||
d3c050b88d | |||
f3d1c78c7d | |||
c4f2bb5fe0 | |||
fec511c786 | |||
8a6157c7c1 | |||
d3bb7903e2 | |||
239b67eff6 | |||
0e0caee6ba | |||
62606c68b9 | |||
da831e894c | |||
4b166dcc79 | |||
796fdca5c5 | |||
c6f22826cf | |||
4e491b6f75 | |||
0569bb18f5 | |||
0353ebde5d | |||
b5130c5943 | |||
d54db8ffb3 | |||
0ff5fc8dbb | |||
32ec9959ef | |||
838721fc31 | |||
63e9c98248 | |||
6df30cbb64 | |||
c102a89962 | |||
ff5e39ab79 | |||
607b2efcce | |||
27d010110a | |||
e13602b896 | |||
6777670f0d | |||
b05739fa7e | |||
38854fb06a | |||
b091cfea80 | |||
a8955ffe05 | |||
475fd72ae1 | |||
31675d1812 | |||
cbb0c1c091 | |||
c1234f7793 | |||
1e6c44cb6b | |||
2202b9330f | |||
0b332fc019 | |||
4f4163eb05 | |||
649d360289 | |||
9bcdd9c274 | |||
fbc60199bc | |||
785c813771 | |||
75f8279a19 | |||
5d07832e96 | |||
7395aaf9b4 | |||
2c070d38fb | |||
2c5bc4a1a9 | |||
fa82af251f | |||
e08f2a4a04 | |||
30e17036e8 | |||
c75785efff | |||
3bf89055e3 | |||
a76869216a | |||
a9fd8bfa5e | |||
02a7b0dcfd | |||
dd8c06f2c5 | |||
c63b7f0c3f | |||
a46ea3f8a0 | |||
93071d9167 | |||
2b2e9d4098 | |||
0429aad8bf | |||
2e74920a64 | |||
b5bf82b5db | |||
98cdd44543 | |||
304b68eff9 | |||
18074951b9 | |||
0008ef70e1 | |||
c3cdbd0dac | |||
aefd61c3db | |||
f7752ac699 | |||
d017e6749c | |||
ddfdfaed78 | |||
a870a4d6de | |||
e6e786a19c | |||
01975b61f5 | |||
3c61bef92d | |||
050f2090fb | |||
7746f1a5c4 | |||
97a1cdbe7a | |||
b1dcea7cf1 | |||
9f6f48025d | |||
5e66ac2674 | |||
93c66b3537 | |||
e0d7d28c20 | |||
a82c564a73 | |||
6a40e72329 | |||
3737a9950c | |||
7784bc0905 | |||
49607e1313 | |||
a81f18592a | |||
2ff988ef37 | |||
5136369c18 | |||
7557207b47 | |||
f9d1e2fec0 | |||
f9a03f212c | |||
d200fb1d14 | |||
eb844b095a | |||
dc638c04a6 | |||
b3cbce97ed | |||
14a32c128d | |||
2e332ffd12 | |||
71d9d483f2 | |||
1ef6262139 | |||
da7db509e7 | |||
2a525bd8e8 | |||
51da2bf363 | |||
d2c0ade880 | |||
bcc3eccdab | |||
e581e249ad | |||
c131c44ef6 | |||
cdd23d9cc7 | |||
dc110db4e0 | |||
678670bf1b | |||
07fc15a1eb | |||
83005e27da | |||
56b20ef779 | |||
04adeec8f5 | |||
62d640cd9e | |||
9d7ad6748c | |||
accd24e379 | |||
75d797a0ac | |||
e1e321d3a7 | |||
f14f238150 | |||
ab3200019a | |||
28c028f7ac | |||
08a159d0d8 | |||
26aa32c6cc | |||
09e6bb5d56 | |||
e661d904de | |||
407d51e871 | |||
c4a07fad83 | |||
9ea8fdc1d1 | |||
3d6bf43649 | |||
7bc1d57ad7 | |||
68b671a4f4 | |||
1de1fd44c5 | |||
e5101eb407 | |||
48e0d86340 | |||
c64cf30160 | |||
ff9d777c01 | |||
d8c33deb33 | |||
c03ff0bd4f | |||
d597633d8f | |||
4f6eb49be3 | |||
d23bd4c4a6 | |||
7f12265685 | |||
250023b823 | |||
3b52691ab4 | |||
b6cd548186 | |||
b3fabf11b1 | |||
15be562fdf | |||
599fa0b76c | |||
c520eb4de0 | |||
e33c68a415 | |||
97bd224261 | |||
503e086c56 | |||
7dd6b7f04f | |||
0b05b7a527 | |||
7e5274619a | |||
900957d658 | |||
e006b9b400 | |||
d042dd73aa | |||
347972e45f | |||
7e803fdf23 | |||
ccacb5f6de | |||
5117139add | |||
d5c0514e21 | |||
d81a6bdf41 | |||
2812afed22 | |||
f5bd86fa11 | |||
b625f1692c | |||
36ac1f8902 | |||
bec4b5c127 | |||
78cd8b9f9a | |||
205880e74e | |||
009d021e4f | |||
39a840e2c3 | |||
56d0d7253b | |||
7a29cc47d4 | |||
d769b72c43 | |||
a3439a5230 | |||
9f45161133 | |||
ed99bef458 | |||
c9ad54cd82 | |||
d7e42d5d6e | |||
5b339c8371 | |||
9c6e68f3e7 | |||
70526a8025 | |||
c405081d89 | |||
384e01b368 | |||
f819654ec8 | |||
4670db6629 | |||
6ebabd50c6 | |||
0c22a21a24 | |||
70a0c4211c | |||
a21af541c4 | |||
e07ba91486 | |||
a22e9ce9cd | |||
d4ce51b1b7 | |||
830005069c | |||
8c49267658 | |||
d0bab1f7ac | |||
f00826f3fb | |||
717c0ea19f | |||
3cd8dd0f32 | |||
aedd616346 | |||
b3de3ff00b | |||
b66dff8aed | |||
ff814df03a | |||
c9a528025c | |||
5f3ec8a6f1 | |||
becd29c50a | |||
a029a35050 | |||
d6a78d61d1 | |||
9be46bd212 | |||
4df3afced0 | |||
90f8e1df80 | |||
ea2ac89e61 | |||
695bfb9616 | |||
5dbdde8c15 | |||
854bfc17ed | |||
c8b192bcae | |||
f07306897f | |||
44d731fff5 | |||
52f939f64c | |||
f1d12c18d8 | |||
373ebb50eb | |||
b0b5be63b9 | |||
68f439425b | |||
cae4d92191 | |||
f336295475 | |||
06d0e7d74a | |||
5e0e3edc7b | |||
02a51bfa65 | |||
dbd04df311 | |||
e6adcd99c7 | |||
3171819c36 | |||
e4976b535d | |||
06d1602f17 | |||
603d0dfbc3 | |||
0b6c5b4620 | |||
d7894dbc44 | |||
d25d8126ea | |||
2402d3e115 | |||
ac4284d348 | |||
f9ef80749a | |||
22f0d3076e | |||
127b6dca1c | |||
8cfff33291 | |||
21f534c7f0 | |||
9faa1db942 | |||
2fc9bffb23 | |||
f16eae45a2 | |||
622e73c34c | |||
eb1c3d7045 | |||
fc26895f70 | |||
ca224b379f | |||
42b609b852 | |||
a24169e2aa | |||
144d1dca88 | |||
38ab6ba3ec | |||
bc6a0626c1 | |||
497f4f4a3c | |||
8c8c89a5f1 | |||
d658a5148a | |||
2c3e0dab0f | |||
e2400e35bd | |||
fc4562491b | |||
6e3bedb888 | |||
2b8332df5e | |||
795e7d4b59 | |||
522d46a525 | |||
dcecf5e350 | |||
a61c929450 | |||
5992e9f524 | |||
ee4cd05ebd | |||
af5e65fd79 | |||
284cbf3ea7 | |||
c3e68955e3 | |||
ffa28e7ee7 | |||
78d81f909c | |||
34551bf48b | |||
e02cd53ac5 | |||
b7f5154bd3 | |||
d80247918c | |||
bb8c2d3e13 | |||
6e0e37519d | |||
5c19ae5878 | |||
8713473c64 | |||
a4b4f2f6fd | |||
03f22135b5 | |||
5b79f657eb | |||
4fc0c513af | |||
f5c058a036 | |||
0dac0ad516 | |||
5d4d1e26fd | |||
2f0039e7dd | |||
9202309bed | |||
7e0e224e0e | |||
35825cf0c7 | |||
b2d79b6362 | |||
f5e1dc86cd | |||
8c51f0076f | |||
8347152730 | |||
3d77dd8f51 | |||
82e6935281 | |||
61070e6ec0 | |||
128697d6a7 | |||
424fa01eca | |||
775187b2e4 | |||
99b5e10acf | |||
208ed6e90d | |||
de8d4c4cd8 | |||
3ae591434d | |||
61fb62f969 | |||
c4584c20dc | |||
c6eb95ff3a | |||
ab68360d53 | |||
58a733dc93 | |||
db8f6b4848 | |||
e72d388a67 | |||
b5dd4d1456 | |||
a7562b4148 | |||
358f64d66b | |||
2a7f9f70b8 | |||
c91085caf7 | |||
21ddbf0b8f | |||
2ad2853278 | |||
e16f63a8e4 | |||
c39ffa111f | |||
5182129196 | |||
02bad8e92b | |||
500ea13155 | |||
ce8e7481e7 | |||
528f2e3cdc | |||
408211ba73 | |||
e02467eada | |||
3e93a1bdd6 | |||
a69a9ba51a | |||
1c0e0191e0 | |||
f233122d4d | |||
72bfa91259 | |||
ef195f0185 | |||
47da6b139e | |||
2705434955 | |||
a7e030d0f9 | |||
8a44170f83 | |||
2ea6ae05e5 | |||
5c0eba7d3b | |||
f81887772a | |||
9aa3d864dc | |||
2425b11df6 | |||
1cb644529f | |||
6cff0fd994 | |||
437256e0f1 | |||
841e0132e9 | |||
1545596c7e | |||
38406e070c | |||
9b07ce1d0d | |||
bf8d30603e | |||
bd6e7f14d1 | |||
5226d8b086 | |||
bd92331780 | |||
387f5143f0 | |||
b7867fe44c | |||
ddea54a539 | |||
84da49c715 | |||
513dff45c1 | |||
3d697baa26 | |||
9eda10d091 | |||
0f82da8735 | |||
296b61b61c | |||
974a896dbc | |||
093fd54e2b | |||
5ae3e5aeb7 | |||
af28a219be | |||
1883df2927 | |||
3274f270e3 | |||
c97626e516 | |||
9c483dd9a6 | |||
8fd6e93fbe | |||
8416ba25de | |||
63f6ff9151 | |||
59c2ace98c | |||
cf4465027a | |||
a23b293fe2 | |||
c039a3ddda | |||
ebe071bd50 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -16,7 +16,6 @@ config.log
|
||||
config.status
|
||||
config
|
||||
configure
|
||||
data/50-gnome-shell-*.xml
|
||||
data/org.gnome.Shell.desktop
|
||||
data/org.gnome.Shell.desktop.in
|
||||
data/gnome-shell-extension-prefs.desktop
|
||||
@ -26,8 +25,6 @@ data/gschemas.compiled
|
||||
data/perf-background.xml
|
||||
data/org.gnome.shell.gschema.xml
|
||||
data/org.gnome.shell.gschema.valid
|
||||
data/org.gnome.shell.evolution.calendar.gschema.xml
|
||||
data/org.gnome.shell.evolution.calendar.gschema.valid
|
||||
data/org.gnome.Shell.PortalHelper.desktop
|
||||
data/org.gnome.Shell.PortalHelper.service
|
||||
data/theme/.sass-cache
|
||||
@ -74,7 +71,6 @@ src/*-marshal.[ch]
|
||||
src/Makefile
|
||||
src/Makefile.in
|
||||
src/calendar-server/evolution-calendar.desktop
|
||||
src/calendar-server/evolution-calendar.desktop.in
|
||||
src/calendar-server/org.gnome.Shell.CalendarServer.service
|
||||
src/gnome-shell
|
||||
src/gnome-shell-calendar-server
|
||||
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,6 +1,6 @@
|
||||
[submodule "src/gvc"]
|
||||
path = src/gvc
|
||||
url = git://git.gnome.org/libgnome-volume-control
|
||||
[submodule "data/theme/gnome-shell-sass"]
|
||||
path = data/theme/gnome-shell-sass
|
||||
url = git://git.gnome.org/gnome-shell-sass
|
||||
[submodule "subprojects/gvc"]
|
||||
path = subprojects/gvc
|
||||
url = git://git.gnome.org/libgnome-volume-control
|
||||
|
12
HACKING
12
HACKING
@ -132,7 +132,7 @@ There are many approaches to classes in JavaScript. We use our own class framewo
|
||||
(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.
|
||||
|
||||
const IconLabelMenuItem = new Lang.Class({
|
||||
var IconLabelMenuItem = new Lang.Class({
|
||||
Name: 'IconLabelMenuItem',
|
||||
Extends: PopupMenu.PopupMenuBaseItem,
|
||||
|
||||
@ -169,7 +169,7 @@ 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:
|
||||
|
||||
const MyClutterActor = new Lang.Class({
|
||||
var MyClutterActor = new Lang.Class({
|
||||
Name: 'MyClutterActor',
|
||||
Extends: Clutter.Actor,
|
||||
|
||||
@ -215,7 +215,7 @@ 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:
|
||||
|
||||
const MyClass = new Lang.Class({
|
||||
var MyClass = new Lang.Class({
|
||||
Name: 'MyClass',
|
||||
|
||||
_init: function() {
|
||||
@ -264,7 +264,7 @@ prototype:
|
||||
const Lang = imports.lang;
|
||||
const FnorbLib = imports.fborbLib;
|
||||
|
||||
const MyClass = new Lang.Class({
|
||||
var MyClass = new Lang.Class({
|
||||
_init: function() {
|
||||
let fnorb = new FnorbLib.Fnorb();
|
||||
fnorb.connect('frobate', Lang.bind(this, this._onFnorbFrobate));
|
||||
@ -304,9 +304,9 @@ 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.
|
||||
|
||||
const ANIMATION_TIME = 2000;
|
||||
var ANIMATION_TIME = 2000;
|
||||
|
||||
const MyClass = new Lang.Class({
|
||||
var MyClass = new Lang.Class({
|
||||
Name: 'MyClass',
|
||||
|
||||
_init: function() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Point to our macro directory and pick up user flags from the environment
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
SUBDIRS = data js src tests po docs
|
||||
SUBDIRS = data js subprojects/gvc src tests po docs
|
||||
|
||||
if BUILD_BROWSER_PLUGIN
|
||||
SUBDIRS += browser-plugin
|
||||
|
388
NEWS
388
NEWS
@ -1,3 +1,391 @@
|
||||
3.25.4
|
||||
======
|
||||
* gdm: Fix "Not listed" focus indication [Florian; #784040]
|
||||
* Fix missing icons in freedesktop notifications [Florian; #784245]
|
||||
* gdm: Disable user list when empty [Xiaoguang; #731320]
|
||||
* gdm: Allow empty reponse to PAM messages [Ray; #784360]
|
||||
* Fix blocked clicks in shutdown dialog [Florian; #781738]
|
||||
* Show OSD popup when changing volume via scroll wheel [Florian; #781028]
|
||||
* Refine list search results [Rares; #749957]
|
||||
* Replace mutter's unresponsive app dialog [Carlos; #762083]
|
||||
* Improve handling of extension errors [Florian; #781728]
|
||||
* Implement tablet rings/strips configuration [Carlos; #782033]
|
||||
* Adjust to mozjs52 update in gjs [Florian; #785084, #785090]
|
||||
* Support the meson build system [Florian; #783229]
|
||||
* Misc. bug fixes [Ray, Florian, Jonas, Marco, Shih-Yuan, Joaquim, Carlos S.;
|
||||
#780403, #772589, #784130, #783975, #784353, #784361, #772284, #765011,
|
||||
#765011, #765011, #784985, #781471, #785047, #736148, #736148]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Alessandro Bono, Michael Catanzaro, Carlos Garnacho,
|
||||
Shih-Yuan Lee (FourDollars), Florian Müllner, Joaquim Rocha,
|
||||
Mario Sanchez Prada, Carlos Soriano, Ray Strode, Marco Trevisan (Treviño),
|
||||
Rares Visalom, Xiaoguang Wang
|
||||
|
||||
Translations:
|
||||
Jeremy Bicha po/es, he.po, Kukuh Syafaat [id], Fabio Tomat [fur]
|
||||
|
||||
3.25.3
|
||||
======
|
||||
* Bypass proxies for captive portal [Bastien; #769692]
|
||||
* Correctly handle "text-shadow: none;" [Matt; #783485]
|
||||
* Add StEntry:hint-actor property [Mario; #783484]
|
||||
* Support text-shadow CSS property in StEntry [Mario; #783484]
|
||||
* Misc. bug fixes [Jonas, Florian, Bastien, Ting-Wei, Cosimo, Mario, Sebastian;
|
||||
#777732, #783202, #783210, #783206, #783286, #783439, #783483, #783823,
|
||||
#781950]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Cosimo Cecchi, Sebastian Keller, Ting-Wei Lan, Florian Müllner,
|
||||
Bastien Nocera, Mario Sanchez Prada, Matt Watson
|
||||
|
||||
3.25.2
|
||||
======
|
||||
* Fix StEntry::primary-icon-clicked emission [Florian; #782190]
|
||||
* Add an optional icon parameter to PopupMenu.addAction() [Mario; #782166]
|
||||
* Allow search providers to include clipboard text with results [Daiki; #775099]
|
||||
* Reduce dependency on Caribou [Carlos; #777342]
|
||||
* Add transparency to top bar when free floating [Alessandro; #747163]
|
||||
* Animate maximize/unmaximize operations [Alessandro; #766685]
|
||||
* Misc. bug fixes [Florian, Matthias, Jeremy, Michael, Carlos, Lan; #782000,
|
||||
#780215, #782802, #782637, #782930, #755164, #780215, #782982]
|
||||
|
||||
Contributors:
|
||||
Jeremy Bicha, Michael Biebl, Alessandro Bono, Carlos Garnacho, Ting-Wei Lan,
|
||||
Matthias Liertzer, Florian Müllner, Mario Sanchez Prada, Daiki Ueno
|
||||
|
||||
Translations:
|
||||
Jordi Mas [ca], Christian Stadelmann [de], Милош Поповић [sr],
|
||||
Милош Поповић [sr@latin], Furkan Ahmet Kara [tr]
|
||||
|
||||
3.25.1
|
||||
======
|
||||
* Close Wifi selection dialog on lock [Florian; #780054]
|
||||
* Fix DND over window previews in overview [Florian; #737166]
|
||||
* Do not lock the screen when disabled by lockdown settings [Florian; #780212]
|
||||
* Follow GNOME Weather's location permissions [Florian; #780252]
|
||||
* Fix portals that require a new window to be loaded [Catalin; #759044]
|
||||
* Fix restricting menus to screen height on HiDPI displays [Cosimo; #753305]
|
||||
* Misc. bug fixes and cleanups [Florian, Cosimo, Bastien, Catalin, Carlos G.,
|
||||
Jonas, Carlos S., Xiaoguang, Rares, Emilio; #780063, #780321, #780381,
|
||||
#780453, #758873, #780606, #642652, #777732, #780157, #781482, #780404,
|
||||
#781545, #781728]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Cosimo Cecchi, Philip Chimento, Carlos Garnacho, Catalin Iacob,
|
||||
Florian Müllner, Bastien Nocera, Emilio Pozuelo Monfort, Carlos Soriano,
|
||||
Rares Visalom, Xiaoguang Wang
|
||||
|
||||
Translations:
|
||||
Marek Cernocky [cs], Piotr Drąg [pl], Anders Jonsson [sv], Stas Solovey [ru],
|
||||
Rafael Fontenelle [pt_BR], Baurzhan Muftakhidinov [kk], Daniel Korostil [uk],
|
||||
Kukuh Syafaat [id], Milo Casagrande [it], Jiri Grönroos [fi],
|
||||
Daniel Mustieles [es], Balázs Úr [hu], Guillaume Bernard [fr],
|
||||
Changwoo Ryu [ko], Mario Blättermann [de], Fran Dieguez [gl],
|
||||
Dušan Kazik [sk], Yuras Shumovich [be], Fabio Tomat [fur],
|
||||
Kjartan Maraas [nb], Aurimas Černius [lt], Trần Ngọc Quân [vi],
|
||||
Rūdolfs Mazurs [lv], Γιάννης Κουτσούκος [el], gogo [hr], Марко Костић [sr],
|
||||
Jordi Mas [ca], Khaled Hosny [ar]
|
||||
|
||||
3.24.0
|
||||
======
|
||||
|
||||
Translations:
|
||||
GNOME Translation Robot [tg], Мирослав Николић [sr, sr@latin],
|
||||
Guillaume Bernard [fr], Rūdolfs Mazurs [lv], Emin Tufan Çetin [tr],
|
||||
sujiniku [ja], Daniel Korostil [uk]
|
||||
|
||||
3.23.92
|
||||
=======
|
||||
* Implement DND to overview on wayland [Hyungwon; #765003]
|
||||
* Make telepathy optional at runtime [Florian; #771721, #779878]
|
||||
* Don't show forecasts for NYC when geoclue gets stuck [Sebastian; #779898]
|
||||
* Add bottom edge drag gesture to bring up the OSK [Jan-Michael; #757712]
|
||||
* Allow switching between pads in the same group [Carlos; #779986]
|
||||
* Ignore showBanners policy for critical notifications [Florian; #779974]
|
||||
* Misc. bug fixes [Florian; #779435, #779819, #779820]
|
||||
|
||||
Contributors:
|
||||
Jan-Michael Brummer, Allan Day, Carlos Garnacho, Hyungwon Hwang,
|
||||
Sebastian Keller, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Enrico Nicoletto [pt_BR], Jiri Grönroos [fi], Chao-Hsiung Liao [zh_TW],
|
||||
Piotr Drąg [pl], Piotr Drąg [he], Balázs Meskó [hu], Kris Thomsen [da],
|
||||
Yuras Shumovich [be], Sveinn í Felli [is], Inaki Larranaga Murgoitio [eu],
|
||||
Changwoo Ryu [ko], Jordi Mas [ca], Aurimas Černius [lt],
|
||||
Мирослав Николић [sr, sr@latin], Christian Kirbach [de], Anders Jonsson [sv],
|
||||
Fabio Tomat [fur], GNOME Translation Robot [gd], Dušan Kazik [sk],
|
||||
Kukuh Syafaat [id], Marek Černocký [cs], Stas Solovey [ru],
|
||||
Milo Casagrande [it], Fran Dieguez [gl], Daniel Boles [gl], A S Alam [pa],
|
||||
Daniel Mustieles [es]
|
||||
|
||||
3.23.91
|
||||
=======
|
||||
* Use the original timestamps for restored notifications [Florian; #766410]
|
||||
* Add weather information to date+time drop-down [Florian; #754031]
|
||||
* Refine message list layout in date+time drop-down [Florian; #775763]
|
||||
* Make next/prev media controls insensitive when unavailable [Florian; #773884]
|
||||
* Misc. bug fixes [Piotr, Bastien, Florian; #772210, #769546, #775799]
|
||||
|
||||
Contributors:
|
||||
Piotr Drąg, Carlos Garnacho, Florian Müllner, Bastien Nocera
|
||||
|
||||
Translations:
|
||||
Baurzhan Muftakhidinov [kk], Jordi Mas [ca], Ask Hjorth Larsen [da],
|
||||
Inaki Larranaga Murgoitio [eu], Daniel Mustieles [es], Dušan Kazik [sk],
|
||||
Aurimas Černius [lt], Jiri Grönroos [fi], Kjartan Maraas [nb],
|
||||
Piotr Drąg [pl], Daniel Korostil [uk], Kukuh Syafaat [id],
|
||||
Milo Casagrande [it], Fabio Tomat [fur], Rafael Fontenelle [pt_BR],
|
||||
Fran Dieguez [gl], Мирослав Николић [sr, sr@latin], Balázs Meskó [hu],
|
||||
Chao-Hsiung Liao [zh_TW]
|
||||
|
||||
3.23.90
|
||||
=======
|
||||
* Handle Ctrl+Q and Ctrl+W in portal window [Bastien; #764133]
|
||||
* Allow to scroll through ibus candidates with mouse [Peng; #776032]
|
||||
* Reload apps on .desktop file content changes [Adrian; #773636]
|
||||
* Use private data/cache directories in portal helper [Bastien; #775639]
|
||||
* Fix subsurfaces not showing up in previews [Rui; #756715]
|
||||
* Fix theme node transitions [Florian; #778145]
|
||||
* Update pad (o)leds on mode switches [Carlos; #776543]
|
||||
* Add security indicators to defend against malicious portals [Bastien; #749197]
|
||||
* Don't allow type ahead at the login screen [Ray; #766139]
|
||||
* Don't fail to load because of TLS errors [Bastien; #778253]
|
||||
* Ensure the network lists remains sorted on rename [Benjamin; #778686]
|
||||
* Toggle power-off/suspend button on long-press [Florian; #721173]
|
||||
* Add "kill-switch" for user extensions [Florian; #778664]
|
||||
* Add night light indicator to status area [Florian; #741224]
|
||||
* Misc. bug fixes [Michael, Bastien, Carlos, Rui, Florian, Alan, Philip, Jonas;
|
||||
#759793, #735233, #762444, #777784, #777934, #778158, #776199, #778425,
|
||||
#771098, #778552, #777317, #778660, #778661, #745626, #778672]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Benjamin Berg, Michael Catanzaro, Philip Chimento,
|
||||
Alan Coopersmith, Piotr Drąg, Carlos Garnacho, Yuri Konotopov,
|
||||
Lionel Landwerlin, Rui Matos, Florian Müllner, Bastien Nocera,
|
||||
Adrian Perez de Castro, Robert Roth, Ray Strode, Peng Wu
|
||||
|
||||
Translations:
|
||||
Jiri Grönroos [fi], Balázs Meskó [hu], Gábor Kelemen [hu],
|
||||
Daniel Mustieles [es], Dušan Kazik [sk],
|
||||
Piotr Drąg [ar, eu, fa, hr, pa, pt, sr, sr@latin], Rafael Fontenelle [pt_BR],
|
||||
Jordi Mas [ca], Piotr Drąg [pl], Alexandre Franke [fr],
|
||||
Baurzhan Muftakhidinov [kk], Yuras Shumovich [be], Mandy Wang [zh_CN],
|
||||
Marek Černocký [cs], Kukuh Syafaat [id], Kjartan Maraas [nb],
|
||||
Daniel Korostil [uk]
|
||||
|
||||
3.23.3
|
||||
======
|
||||
* Fix replacing of GNotifications [Florian; #775149]
|
||||
* Prepare for mozjs31 GJS [Philip; #775374]
|
||||
* Misc. bug fixes [Niels, Jonas; #775507, #776130]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Michael Catanzaro, Philip Chimento, Niels De Graef,
|
||||
Carlos Garnacho, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Muhammet Kara [tr], Christian Kirbach [de], Baurzhan Muftakhidinov [kk],
|
||||
Cheng-Chia Tseng [zh_TW], A S Alam [pa], Gianvito Cavasoli [it]
|
||||
|
||||
3.23.2
|
||||
======
|
||||
* Implement Pad configuration OSD [Carlos; #771067]
|
||||
* Show overview on three-finger touchpad pinch [Carlos; #765937]
|
||||
* Summarize network sections with too many devices [Florian; #773892]
|
||||
* Always show primary network icon when connected [Florian; #773890]
|
||||
* Fix fullscreen transitions on wayland [Rui; #770345]
|
||||
* Work around portal failures by using a URL without HTPPS redirect [Debarshi; #769940]
|
||||
* Fix app view hiding when no usage data is available [Florian, Xiaoguang; #774381]
|
||||
* Misc. bug fixes [Florian, Ray; #773875, #740043, #773893, #774643, #774805]
|
||||
|
||||
Contributors:
|
||||
Carlos Garnacho, Rui Matos, Florian Müllner, Debarshi Ray, Ray Strode,
|
||||
Xiaoguang Wang
|
||||
|
||||
Translations:
|
||||
Balázs Meskó [hu], Fabio Tomat [fur], Marek Cernocky [cs], Stas Solovey [ru],
|
||||
Daniel Mustieles [es], Marek Černocký [cs], Piotr Drąg [pl],
|
||||
Rafael Fontenelle [pt_BR], Baurzhan Muftakhidinov [kk], Jiri Grönroos [fi],
|
||||
Kjartan Maraas [nb]
|
||||
|
||||
3.23.1
|
||||
======
|
||||
* Request periodic scans while WiFi list is open [Dan; #767918]
|
||||
* Include extension UUID in structured log metadata [Jonh; #770717]
|
||||
* Line-wrap PAM messages on login screen [Tao; #764445]
|
||||
* Add a way to launch an app on the discrete GPU [Bastien; #773117]
|
||||
* Only allow graphs to lift screen shield when locked [Florian; #773328]
|
||||
* Add reload option to gnome-shell-extension-tool [Jonh; #772593]
|
||||
* Update background animations when resuming from suspend [Florian; #773265]
|
||||
* Misc. bug fixes [Cosimo, Bastien, Florian, Philip, Carlos; #772723, #772287,
|
||||
#756432, #772386, #772386, #773085, #773634]
|
||||
|
||||
Contributors:
|
||||
Cosimo Cecchi, Philip Chimento, Carlos Garcia Campos, Florian Müllner,
|
||||
Bastien Nocera, Jonh Wendell, Dan Williams, Tao Yang
|
||||
|
||||
Translations:
|
||||
Fabio Tomat [fur], Philip Chimento [zh_CN], YunQiang Su [zh_CN],
|
||||
Jordi Mas [ca], Piotr Drąg [pl], Muhammet Kara [tr], Marek Černocký [cs],
|
||||
Daniel Korostil [uk], Dušan Kazik [sk]
|
||||
|
||||
3.22.1
|
||||
======
|
||||
* Fix hidden network indicator on startup [Florian; #772249]
|
||||
* Fix order of windows with modal dialogs in window switcher [Florian; #747153]
|
||||
* Fix feedback loop between StClipboard and X11 bridge [Carlos; #760745]
|
||||
* Reliably match windows from Flatpak apps [Florian; #772615]
|
||||
* Misc. bug fixes [Philip; #742249]
|
||||
|
||||
Contributors:
|
||||
Philip Chimento, Carlos Garnacho, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Inaki Larranaga Murgoitio [eu], Khaled Hosny [ar], BM [uz@cyrillic],
|
||||
Milo Casagrande [it], Cheng-Chia Tseng [zh_TW], gogo [hr]
|
||||
|
||||
3.22.0
|
||||
======
|
||||
* Misc. bug fixes [Florian, Rui; #771391, #771536] #771656]
|
||||
|
||||
Contributors:
|
||||
Rui Matos, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Ask Hjorth Larsen [da], GNOME Translation Robot [gd], Alexandre Franke [fr],
|
||||
Daniel Korostil [uk], Jordi Mas [ca], Khaled Hosny [ar], David King [en_GB]
|
||||
|
||||
3.21.92
|
||||
=======
|
||||
* Adjust screen capture to work with multiple stage views [Jonas; #770128]
|
||||
* Improve handling of cycle shortcuts [Florian; #771063]
|
||||
* Fix windows not getting undimmed in some cases [Rui; #770163, #752524]
|
||||
* Disable extension version check by default [Florian; #770887]
|
||||
* Misc. bug fixes [Rui, Florian, Michael; #770382, #770888, #770328]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Michael Catanzaro, Fran Dieguez, Olivier Fourdan, Rui Matos,
|
||||
Florian Müllner
|
||||
|
||||
Translations:
|
||||
Changwoo Ryu [ko], Baurzhan Muftakhidinov [kk], Aurimas Černius [lt],
|
||||
Muhammet Kara [tr], Trần Ngọc Quân [vi], A S Alam [pa], Yosef Or Boczko [he],
|
||||
Anders Jonsson [sv], Tiago Santos [pt], Hannie Dumoleyn [nl],
|
||||
Rūdolfs Mazurs [lv], Claude Paroz [fr], Arash Mousavi [fa],
|
||||
Fran Dieguez [gl], Stas Solovey [ru], Tom Tryfonidis [el]
|
||||
|
||||
3.21.91
|
||||
=======
|
||||
Translations:
|
||||
Mario Blättermann [de], Jiri Grönroos [fi], Dušan Kazik [sk],
|
||||
Andika Triwidada [id], Daniel Mustieles [es], Fabio Tomat [fur],
|
||||
Enrico Nicoletto [pt_BR], Matej Urbančič [sl], Мирослав Николић [sr, sr@latin]
|
||||
|
||||
3.21.90.1
|
||||
=========
|
||||
Contributors:
|
||||
Piotr Drąg
|
||||
|
||||
Translations:
|
||||
Marek Černocký [cs], Balázs Úr [hu]
|
||||
|
||||
3.21.90
|
||||
=======
|
||||
* Improve on-screen keyboard on wayland [Carlos; #765009]
|
||||
* Misc. bug fixes [Florian; #769156, #769216, #769074]
|
||||
|
||||
Contributors:
|
||||
Carlos Garnacho, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Fabio Tomat [fur], Tiago Santos [pt], Daniel Mustieles [es],
|
||||
Bernd Homuth [de], Aurimas Černius [lt], Balázs Úr [hu],
|
||||
Yosef Or Boczko [he], Jiri Grönroos [fi], Marek Cernocky [cs],
|
||||
Muhammet Kara [tr], Enrico Nicoletto [pt_BR], Andika Triwidada [id]
|
||||
|
||||
3.21.4
|
||||
======
|
||||
* overview: Fix switching workspaces when scrolling on non-primary monitors
|
||||
[Florian; #766883, #768316]
|
||||
* Fix crash when using screen recorder under wayland [Rui; #767001]
|
||||
* Update theme on video memory purge errors [Rui; #739178]
|
||||
* Free old backgrounds immediately [Hyungwon; #766353]
|
||||
* Add support for system upgrades to end session dialog [Kalev; #763611]
|
||||
* Fix maximized windows flickering to the wrong size on restart [Owen; #761566]
|
||||
* Hide ignored events in calendar as well [Florian; #768538]
|
||||
* calendar: Only hide dismissed occurrence of recurring event [Florian; #748226]
|
||||
* Provide org.freedesktop.impl.portal.access implementation [Florian; #768669]
|
||||
* Misc. bug fixes and cleanups [Rui, Florian, Marinus, Jonas; #767954, #768317,
|
||||
#746867, #762206, #768956, #768979]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Piotr Drąg, Hyungwon Hwang, Kalev Lember, Rui Matos,
|
||||
Florian Müllner, Marinus Schraal, Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Andika Triwidada [id], Daniel Mustieles [es], Bruce Cowan [en_GB],
|
||||
Dušan Kazik [sk], Piotr Drąg [pl], Chao-Hsiung Liao [zh_HK]
|
||||
|
||||
3.21.3
|
||||
======
|
||||
* Do not disable suspend action when locked [Florian; #725960]
|
||||
* Remember input sources MRU list [Cosimo; #766826]
|
||||
* networkAgent: Handle VPN service aliases [David; #658484]
|
||||
* Plug a memory leak [Hans; #710230]
|
||||
|
||||
Contributors:
|
||||
Cosimo Cecchi, Florian Müllner, Hans Petter Jansson, David Woodhouse
|
||||
|
||||
Translations:
|
||||
Tiago Santos [pt], Cédric Valmary [oc], Muhammet Kara [tr],
|
||||
Daniel Mustieles [es], Rafael Fontenelle [pt_BR]
|
||||
|
||||
3.21.2
|
||||
======
|
||||
* Fix sorting of hidden apps in app switcher [Florian; #766238]
|
||||
* Set logind's LockedHint property when locked [Victor; #764773]
|
||||
* Allocate framebuffers early to fix a crash on NVIDIA [Martin; #764898]
|
||||
* Fix cycle-windows/cycle-group keybindings [Florian; #730739]
|
||||
* Switch to shared desktop schema for calendar settings [Iain; #766318]
|
||||
* Misc. bug fixes [Florian, Cosimo, Michele; #766325, #758471, #757556,
|
||||
#757019, #766598]
|
||||
|
||||
Contributors:
|
||||
Cosimo Cecchi, Michele Gaio, Iain Lane, Florian Müllner, Martin Szulecki,
|
||||
Victor Toso
|
||||
|
||||
Translations:
|
||||
Tiago Santos [pt], Kjartan Maraas [nb], Jiro Matsuzawa [ja],
|
||||
Cédric Valmary [oc], Sveinn í Felli [is]
|
||||
|
||||
3.21.1
|
||||
======
|
||||
* Save screencasts in HOME if XDG_VIDEO_DIR doesn't exist [Florian; #765015]
|
||||
* Don't show orientation lock when g-s-d won't rotate [Florian; #765267]
|
||||
* Misc. bug fixes [Heiher, Florian, Marek, Rui; #722752, #765061, #763068,
|
||||
#765607, #757676, #760439]
|
||||
|
||||
Contributors:
|
||||
Heiher, Marek Chalupa, Rui Matos, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Arash Mousavi [fa], Kristjan SCHMIDT [eo], GNOME Translation Robot [gd]
|
||||
|
||||
3.20.1
|
||||
======
|
||||
* Plug a memory leak [Aaron; #735705]
|
||||
|
||||
Contributors:
|
||||
Aaron Plattner
|
||||
|
||||
Translations:
|
||||
Daniel Korostil [uk], Matej Urbančič [sl], Inaki Larranaga Murgoitio [eu],
|
||||
Cheng-Chia Tseng [zh_TW], Fabio Tomat [fur], Trần Ngọc Quân [vi],
|
||||
YunQiang Su [zh_CN], Marek Černocký [cs], Arash Mousavi [fa],
|
||||
Alexander Shopov [bg], Khaled Hosny [ar]
|
||||
|
||||
3.20.0
|
||||
======
|
||||
|
||||
|
26
autogen.sh
26
autogen.sh
@ -4,24 +4,32 @@
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -d $srcdir/src) || {
|
||||
olddir="$(pwd)"
|
||||
|
||||
cd "${srcdir}"
|
||||
|
||||
(test -f configure.ac \
|
||||
&& test -d src) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level gnome-shell directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Fetch submodules if needed
|
||||
if test ! -f src/gvc/Makefile.am || test ! -f data/theme/gnome-shell-sass/COPYING;
|
||||
if test ! -f subprojects/gvc/Makefile.am || test ! -f data/theme/gnome-shell-sass/COPYING;
|
||||
then
|
||||
echo "+ Setting up submodules"
|
||||
git submodule init
|
||||
fi
|
||||
git submodule update
|
||||
|
||||
which gnome-autogen.sh || {
|
||||
echo "You need to install gnome-common from GNOME Git (or from"
|
||||
echo "your OS vendor's package manager)."
|
||||
exit 1
|
||||
}
|
||||
. gnome-autogen.sh
|
||||
aclocal --install || exit 1
|
||||
gtkdocize --copy || exit 1
|
||||
intltoolize --force --copy --automake || exit 1
|
||||
autoreconf --verbose --force --install || exit 1
|
||||
|
||||
cd "${olddir}"
|
||||
|
||||
if [ "$NOCONFIGURE" = "" ]; then
|
||||
"${srcdir}/configure" "$@" || exit 1
|
||||
fi
|
||||
|
@ -1029,6 +1029,7 @@ NPP_GetValue(NPP instance,
|
||||
if (!instance->pdata)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
funcs.retainobject (instance->pdata);
|
||||
*(NPObject**)value = instance->pdata;
|
||||
break;
|
||||
|
||||
|
19
browser-plugin/meson.build
Normal file
19
browser-plugin/meson.build
Normal file
@ -0,0 +1,19 @@
|
||||
plugin_sources = [
|
||||
'browser-plugin.c',
|
||||
'npapi/npapi.h',
|
||||
'npapi/npfunctions.h',
|
||||
'npapi/npruntime.h',
|
||||
'npapi/nptypes.h'
|
||||
]
|
||||
|
||||
shared_module('gnome-shell-browser-plugin', plugin_sources,
|
||||
dependencies: [gio_dep, json_glib_dep],
|
||||
c_args: ['-DG_LOG_DOMAIN="GnomeShellBrowserPlugin"'],
|
||||
# Browsers can unload and reload the module while browsing, which is not
|
||||
# supported by GObject.
|
||||
# We pass -Wl,-z,nodelete to the linker to ensure the module is never
|
||||
# unloaded. See https://bugzilla.gnome.org/show_bug.cgi?id=737932.
|
||||
link_args: ['-Wl,-z,nodelete'],
|
||||
install: true,
|
||||
install_dir: plugindir
|
||||
)
|
26
config.h.meson
Normal file
26
config.h.meson
Normal file
@ -0,0 +1,26 @@
|
||||
/* The prefix for our gettext translation domains. */
|
||||
#mesondefine GETTEXT_PACKAGE
|
||||
|
||||
/* Version number of package */
|
||||
#mesondefine VERSION
|
||||
|
||||
/* Version number of package */
|
||||
#mesondefine PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the `fdwalk' function. */
|
||||
#mesondefine HAVE_FDWALK
|
||||
|
||||
/* Define to 1 if you have the `mallinfo' function. */
|
||||
#mesondefine HAVE_MALLINFO
|
||||
|
||||
/* Define to 1 fi you have the <sys/resource.h> header file. */
|
||||
#mesondefine HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define if we have NetworkManager */
|
||||
#mesondefine HAVE_NETWORKMANAGER
|
||||
|
||||
/* Define if we have systemd */
|
||||
#mesondefine HAVE_SYSTEMD
|
||||
|
||||
/* Define if _NL_TIME_FIRST_WEEKDATE is available */
|
||||
#mesondefine HAVE__NL_TIME_FIRST_WEEKDAY
|
65
configure.ac
65
configure.ac
@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.63)
|
||||
AC_INIT([gnome-shell],[3.20.0],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
AC_INIT([gnome-shell],[3.25.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
AX_IS_RELEASE([git-directory])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@ -17,20 +17,20 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
|
||||
# Initialize libtool
|
||||
LT_PREREQ([2.2.6])
|
||||
LT_INIT([disable-static])
|
||||
|
||||
# i18n
|
||||
IT_PROG_INTLTOOL([0.40])
|
||||
|
||||
GETTEXT_PACKAGE=gnome-shell
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
|
||||
[The prefix for our gettext translation domains.])
|
||||
|
||||
AM_GNU_GETTEXT_VERSION([0.19.6])
|
||||
AM_GNU_GETTEXT([external])
|
||||
|
||||
PKG_PROG_PKG_CONFIG([0.22])
|
||||
|
||||
AC_PATH_PROG([XSLTPROC], [xsltproc])
|
||||
@ -41,6 +41,15 @@ GLIB_GSETTINGS
|
||||
AM_PATH_PYTHON([3])
|
||||
AC_SUBST(PYTHON)
|
||||
|
||||
# We depend on a specific version of the libmutter API. The mutter variants of
|
||||
# the Cogl and Clutter libraries also use this API version.
|
||||
LIBMUTTER_API_VERSION=0
|
||||
|
||||
LIBMUTTER=libmutter-$LIBMUTTER_API_VERSION
|
||||
LIBMUTTER_COGL=mutter-cogl-$LIBMUTTER_API_VERSION
|
||||
LIBMUTTER_COGL_PANGO=mutter-cogl-pango-$LIBMUTTER_API_VERSION
|
||||
LIBMUTTER_CLUTTER=mutter-clutter-$LIBMUTTER_API_VERSION
|
||||
|
||||
# We need at least this, since gst_plugin_register_static() was added
|
||||
# in 0.10.16, but nothing older than 0.10.21 has been tested.
|
||||
GSTREAMER_MIN_VERSION=0.11.92
|
||||
@ -52,7 +61,6 @@ if $PKG_CONFIG --exists gstreamer-1.0 '>=' $GSTREAMER_MIN_VERSION ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
build_recorder=true
|
||||
recorder_modules="gstreamer-1.0 gstreamer-base-1.0 x11 gtk+-3.0"
|
||||
PKG_CHECK_MODULES(TEST_SHELL_RECORDER, $recorder_modules clutter-1.0)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
@ -74,15 +82,13 @@ AS_IF([test x$enable_systemd != xno], [
|
||||
|
||||
AC_MSG_RESULT($enable_systemd)
|
||||
|
||||
CLUTTER_MIN_VERSION=1.21.5
|
||||
GOBJECT_INTROSPECTION_MIN_VERSION=1.45.4
|
||||
GJS_MIN_VERSION=1.39.0
|
||||
MUTTER_MIN_VERSION=3.20.0
|
||||
GOBJECT_INTROSPECTION_MIN_VERSION=1.49.1
|
||||
GJS_MIN_VERSION=1.47.0
|
||||
MUTTER_MIN_VERSION=3.25.3
|
||||
GTK_MIN_VERSION=3.15.0
|
||||
GIO_MIN_VERSION=2.45.3
|
||||
GIO_MIN_VERSION=2.53.0
|
||||
LIBECAL_MIN_VERSION=3.5.3
|
||||
LIBEDATASERVER_MIN_VERSION=3.17.2
|
||||
TELEPATHY_GLIB_MIN_VERSION=0.17.5
|
||||
POLKIT_MIN_VERSION=0.100
|
||||
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
||||
GCR_MIN_VERSION=3.7.5
|
||||
@ -95,15 +101,14 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION
|
||||
libxml-2.0
|
||||
gtk+-3.0 >= $GTK_MIN_VERSION
|
||||
atk-bridge-2.0
|
||||
gjs-internals-1.0 >= $GJS_MIN_VERSION
|
||||
gjs-1.0 >= $GJS_MIN_VERSION
|
||||
$recorder_modules
|
||||
gdk-x11-3.0 libsoup-2.4
|
||||
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
|
||||
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
||||
$LIBMUTTER_CLUTTER >= $MUTTER_MIN_VERSION
|
||||
$LIBMUTTER_COGL_PANGO
|
||||
libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_MIN_VERSION
|
||||
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
|
||||
libcanberra libcanberra-gtk3
|
||||
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
|
||||
polkit-agent-1 >= $POLKIT_MIN_VERSION
|
||||
gcr-base-3 >= $GCR_MIN_VERSION"
|
||||
if test x$have_systemd = xyes; then
|
||||
@ -111,15 +116,17 @@ if test x$have_systemd = xyes; then
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(GNOME_SHELL, $SHARED_PCS)
|
||||
PKG_CHECK_MODULES(MUTTER, libmutter >= $MUTTER_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(MUTTER, $LIBMUTTER >= $MUTTER_MIN_VERSION)
|
||||
|
||||
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
|
||||
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-1.0 >= $GJS_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(ST, $LIBMUTTER_CLUTTER gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
|
||||
PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
||||
PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
|
||||
PKG_CHECK_MODULES(TRAY, clutter-1.0 gtk+-3.0)
|
||||
PKG_CHECK_MODULES(TRAY, $LIBMUTTER_CLUTTER gtk+-3.0)
|
||||
PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0)
|
||||
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.19.2)
|
||||
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.21.3)
|
||||
|
||||
AC_SUBST(LIBMUTTER_API_VERSION)
|
||||
|
||||
AC_ARG_ENABLE(browser-plugin,
|
||||
[AS_HELP_STRING([--enable-browser-plugin],
|
||||
@ -145,15 +152,12 @@ AC_SUBST([GNOME_KEYBINDINGS_KEYSDIR])
|
||||
|
||||
GOBJECT_INTROSPECTION_CHECK([$GOBJECT_INTROSPECTION_MIN_VERSION])
|
||||
|
||||
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir libmutter`
|
||||
MUTTER_GIR_DIR=`$PKG_CONFIG --variable=girdir $LIBMUTTER`
|
||||
AC_SUBST(MUTTER_GIR_DIR)
|
||||
|
||||
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir libmutter`
|
||||
MUTTER_TYPELIB_DIR=`$PKG_CONFIG --variable=typelibdir $LIBMUTTER`
|
||||
AC_SUBST(MUTTER_TYPELIB_DIR)
|
||||
|
||||
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
|
||||
AC_SUBST(GJS_CONSOLE)
|
||||
|
||||
GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable glib_compile_resources gio-2.0`
|
||||
AC_SUBST(GLIB_COMPILE_RESOURCES)
|
||||
|
||||
@ -182,7 +186,7 @@ if test "x$enable_networkmanager" != "xno"; then
|
||||
[libnm-glib
|
||||
libnm-util >= $NETWORKMANAGER_MIN_VERSION
|
||||
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
|
||||
libsecret-unstable],
|
||||
libsecret-1 >= 0.18],
|
||||
[have_networkmanager=yes],
|
||||
[have_networkmanager=no])
|
||||
|
||||
@ -242,7 +246,7 @@ if test -z "$GDBUS_CODEGEN"; then
|
||||
AC_MSG_ERROR([gdbus-codegen not found])
|
||||
fi
|
||||
|
||||
AC_PATH_PROG([SASS],[sass],[])
|
||||
AC_PATH_PROG([SASSC],[sassc],[])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
@ -250,13 +254,12 @@ AC_CONFIG_FILES([
|
||||
docs/Makefile
|
||||
docs/reference/Makefile
|
||||
docs/reference/shell/Makefile
|
||||
docs/reference/shell/shell-docs.sgml
|
||||
docs/reference/shell/version.xml
|
||||
docs/reference/st/Makefile
|
||||
docs/reference/st/st-docs.sgml
|
||||
docs/reference/st/version.xml
|
||||
js/Makefile
|
||||
src/calendar-server/evolution-calendar.desktop.in
|
||||
src/Makefile
|
||||
src/gvc/Makefile
|
||||
subprojects/gvc/Makefile
|
||||
browser-plugin/Makefile
|
||||
tests/Makefile
|
||||
po/Makefile.in
|
||||
|
@ -1,24 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<KeyListEntries schema="org.gnome.shell.keybindings"
|
||||
group="system"
|
||||
_name="System"
|
||||
name="System"
|
||||
wm_name="GNOME Shell"
|
||||
package="gnome-shell">
|
||||
|
||||
<KeyListEntry name="toggle-message-tray"
|
||||
_description="Show the notification list"/>
|
||||
description="Show the notification list"/>
|
||||
|
||||
<KeyListEntry name="focus-active-notification"
|
||||
_description="Focus the active notification"/>
|
||||
description="Focus the active notification"/>
|
||||
|
||||
<KeyListEntry name="toggle-overview"
|
||||
_description="Show the overview"/>
|
||||
description="Show the overview"/>
|
||||
|
||||
<KeyListEntry name="toggle-application-view"
|
||||
_description="Show all applications"/>
|
||||
description="Show all applications"/>
|
||||
|
||||
<KeyListEntry name="open-application-menu"
|
||||
_description="Open the application menu"/>
|
||||
description="Open the application menu"/>
|
||||
|
||||
</KeyListEntries>
|
||||
|
@ -1,6 +1,9 @@
|
||||
CLEANFILES =
|
||||
NULL =
|
||||
|
||||
portaldir = $(datadir)/xdg-desktop-portal/portals
|
||||
portal_DATA = gnome-shell.portal
|
||||
|
||||
desktopdir=$(datadir)/applications
|
||||
desktop_DATA = org.gnome.Shell.desktop gnome-shell-extension-prefs.desktop
|
||||
|
||||
@ -11,8 +14,9 @@ servicedir = $(datadir)/dbus-1/services
|
||||
service_DATA = org.gnome.Shell.PortalHelper.service
|
||||
|
||||
CLEANFILES += \
|
||||
org.gnome.Shell.PortalHelper.service \
|
||||
org.gnome.Shell.PortalHelper.desktop \
|
||||
org.gnome.Shell.PortalHelper.service \
|
||||
org.gnome.Shell.PortalHelper.desktop \
|
||||
org.gnome.Shell.PortalHelper.desktop.in \
|
||||
$(NULL)
|
||||
|
||||
endif
|
||||
@ -28,10 +32,13 @@ endif
|
||||
-e "s|@VERSION[@]|$(VERSION)|" \
|
||||
$< > $@ || rm $@
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
%.desktop:%.desktop.in
|
||||
$(AM_V_GEN) $(MSGFMT) --desktop --template $(builddir)/$< \
|
||||
-d $(top_srcdir)/po -o $@
|
||||
|
||||
introspectiondir = $(datadir)/dbus-1/interfaces
|
||||
introspection_DATA = \
|
||||
org.gnome.Shell.PadOsd.xml \
|
||||
org.gnome.Shell.Screencast.xml \
|
||||
org.gnome.Shell.Screenshot.xml \
|
||||
org.gnome.ShellSearchProvider.xml \
|
||||
@ -49,7 +56,6 @@ theme_sources = \
|
||||
|
||||
dist_theme_files = \
|
||||
$(theme_sources) \
|
||||
theme/Gemfile \
|
||||
theme/HACKING \
|
||||
theme/README \
|
||||
theme/gnome-shell-sass/COPYING \
|
||||
@ -57,13 +63,14 @@ dist_theme_files = \
|
||||
theme/gnome-shell-sass/NEWS \
|
||||
theme/gnome-shell-sass/README \
|
||||
theme/gnome-shell-sass/gnome-shell-sass.doap \
|
||||
theme/pad-osd.css \
|
||||
theme/parse-sass.sh \
|
||||
$(NULL)
|
||||
|
||||
%.css: %.scss $(theme_sources)
|
||||
@if test -n "$(SASS)"; then \
|
||||
@if test -n "$(SASSC)"; then \
|
||||
if $(AM_V_P); then PS4= set -x; else echo " GEN $@"; fi; \
|
||||
$(SASS) --sourcemap=none -f -q --update $<; \
|
||||
$(SASSC) -a $< $@; \
|
||||
fi
|
||||
|
||||
resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir)/theme --generate-dependencies $(srcdir)/gnome-shell-theme.gresource.xml)
|
||||
@ -80,14 +87,11 @@ perf-background.xml: perf-background.xml.in
|
||||
$< > $@ || rm $@
|
||||
|
||||
keysdir = @GNOME_KEYBINDINGS_KEYSDIR@
|
||||
keys_in_files = 50-gnome-shell-system.xml.in
|
||||
keys_DATA = $(keys_in_files:.xml.in=.xml)
|
||||
keys_DATA = 50-gnome-shell-system.xml
|
||||
|
||||
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
|
||||
|
||||
@INTLTOOL_XML_NOMERGE_RULE@
|
||||
|
||||
%.gschema.xml.in: %.gschema.xml.in.in Makefile
|
||||
%.gschema.xml: %.gschema.xml.in Makefile
|
||||
$(AM_V_GEN) sed -e 's|@GETTEXT_PACKAGE[@]|$(GETTEXT_PACKAGE)|g' \
|
||||
$< > $@ || rm $@
|
||||
|
||||
@ -106,15 +110,16 @@ convert_DATA = gnome-shell-overrides.convert
|
||||
EXTRA_DIST = \
|
||||
org.gnome.Shell.desktop.in.in \
|
||||
gnome-shell-extension-prefs.desktop.in.in \
|
||||
$(portal_DATA) \
|
||||
$(introspection_DATA) \
|
||||
$(menu_DATA) \
|
||||
$(convert_DATA) \
|
||||
$(keys_in_files) \
|
||||
$(keys_DATA) \
|
||||
$(dist_theme_files) \
|
||||
perf-background.xml.in \
|
||||
org.gnome.Shell.PortalHelper.desktop.in \
|
||||
org.gnome.Shell.PortalHelper.desktop.in.in \
|
||||
org.gnome.Shell.PortalHelper.service.in \
|
||||
org.gnome.shell.gschema.xml.in.in \
|
||||
org.gnome.shell.gschema.xml.in \
|
||||
gnome-shell-theme.gresource.xml \
|
||||
$(resource_files) \
|
||||
$(NULL)
|
||||
@ -123,11 +128,9 @@ CLEANFILES += \
|
||||
org.gnome.Shell.desktop.in \
|
||||
gnome-shell-extension-prefs.in \
|
||||
$(desktop_DATA) \
|
||||
$(keys_DATA) \
|
||||
$(gsettings_SCHEMAS) \
|
||||
perf-background.xml \
|
||||
gschemas.compiled \
|
||||
org.gnome.shell.gschema.valid \
|
||||
org.gnome.shell.gschema.xml.in \
|
||||
gnome-shell-theme.gresource \
|
||||
$(NULL)
|
||||
|
@ -1,7 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
_Name=GNOME Shell Extension Preferences
|
||||
_Comment=Configure GNOME Shell Extensions
|
||||
Name=Shell Extensions
|
||||
Comment=Configure GNOME Shell Extensions
|
||||
Exec=@bindir@/gnome-shell-extension-prefs %u
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-shell
|
||||
|
@ -18,10 +18,10 @@
|
||||
<file>gnome-shell.css</file>
|
||||
<file>gnome-shell-high-contrast.css</file>
|
||||
<file>logged-in-indicator.svg</file>
|
||||
<file>more-results.svg</file>
|
||||
<file>no-events.svg</file>
|
||||
<file>no-notifications.svg</file>
|
||||
<file>noise-texture.png</file>
|
||||
<file>pad-osd.css</file>
|
||||
<file>page-indicator-active.svg</file>
|
||||
<file>page-indicator-inactive.svg</file>
|
||||
<file>page-indicator-checked.svg</file>
|
||||
|
4
data/gnome-shell.portal
Normal file
4
data/gnome-shell.portal
Normal file
@ -0,0 +1,4 @@
|
||||
[portal]
|
||||
DBusName=org.freedesktop.impl.portal.desktop.gnome
|
||||
Interfaces=org.freedesktop.impl.portal.Access
|
||||
UseIn=gnome
|
87
data/meson.build
Normal file
87
data/meson.build
Normal file
@ -0,0 +1,87 @@
|
||||
desktop_files = [
|
||||
'org.gnome.Shell.desktop',
|
||||
'gnome-shell-extension-prefs.desktop'
|
||||
]
|
||||
service_files = []
|
||||
|
||||
if have_networkmanager
|
||||
desktop_files += 'org.gnome.Shell.PortalHelper.desktop'
|
||||
service_files += 'org.gnome.Shell.PortalHelper.service'
|
||||
endif
|
||||
|
||||
desktopconf = configuration_data()
|
||||
# We substitute in bindir so it works as an autostart
|
||||
# file when built in a non-system prefix
|
||||
desktopconf.set('bindir', bindir)
|
||||
desktopconf.set('VERSION', meson.project_version())
|
||||
foreach desktop_file : desktop_files
|
||||
i18n.merge_file('desktop',
|
||||
input: configure_file(
|
||||
input: desktop_file + '.in.in',
|
||||
output: desktop_file + '.in',
|
||||
configuration: desktopconf
|
||||
),
|
||||
output: desktop_file,
|
||||
po_dir: '../po',
|
||||
install: true,
|
||||
install_dir: desktopdir,
|
||||
type: 'desktop'
|
||||
)
|
||||
endforeach
|
||||
|
||||
serviceconf = configuration_data()
|
||||
serviceconf.set('libexecdir', libexecdir)
|
||||
foreach service_file : service_files
|
||||
configure_file(
|
||||
input: service_file + '.in',
|
||||
output: service_file,
|
||||
configuration: serviceconf,
|
||||
install_dir: servicedir
|
||||
)
|
||||
endforeach
|
||||
|
||||
|
||||
dbus_interfaces = [
|
||||
'org.gnome.Shell.PadOsd.xml',
|
||||
'org.gnome.Shell.Screencast.xml',
|
||||
'org.gnome.Shell.Screenshot.xml',
|
||||
'org.gnome.ShellSearchProvider.xml',
|
||||
'org.gnome.ShellSearchProvider2.xml'
|
||||
]
|
||||
install_data(dbus_interfaces, install_dir: ifacedir)
|
||||
|
||||
|
||||
subdir('theme')
|
||||
|
||||
theme_resources = gnome.compile_resources(
|
||||
'gnome-shell-theme', 'gnome-shell-theme.gresource.xml',
|
||||
source_dir: 'theme',
|
||||
dependencies: theme_deps,
|
||||
gresource_bundle: true,
|
||||
install: true,
|
||||
install_dir: pkgdatadir
|
||||
)
|
||||
|
||||
perfconf = configuration_data()
|
||||
perfconf.set('datadir', datadir)
|
||||
configure_file(
|
||||
input: 'perf-background.xml.in',
|
||||
output: 'perf-background.xml',
|
||||
configuration: perfconf,
|
||||
install_dir: pkgdatadir
|
||||
)
|
||||
|
||||
|
||||
install_data('50-gnome-shell-system.xml', install_dir: keysdir)
|
||||
|
||||
|
||||
schemaconf = configuration_data()
|
||||
schemaconf.set('GETTEXT_PACKAGE', meson.project_name())
|
||||
configure_file(
|
||||
input: 'org.gnome.shell.gschema.xml.in',
|
||||
output: 'org.gnome.shell.gschema.xml',
|
||||
configuration: schemaconf,
|
||||
install_dir: schemadir
|
||||
)
|
||||
|
||||
install_data('gnome-shell-overrides.convert', install_dir: convertdir)
|
28
data/org.gnome.Shell.PadOsd.xml
Normal file
28
data/org.gnome.Shell.PadOsd.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE node PUBLIC
|
||||
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
|
||||
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
|
||||
<node>
|
||||
|
||||
<!--
|
||||
org.gnome.Shell.PadOSD:
|
||||
@short_description: Pad OSD interface
|
||||
|
||||
The interface used to show button map OSD on pad devices.
|
||||
-->
|
||||
<interface name='org.gnome.Shell.Wacom.PadOsd'>
|
||||
|
||||
<!--
|
||||
Show:
|
||||
@device_node: device node file, usually in /dev/input/...
|
||||
@edition_mode: whether toggling edition mode on when showing
|
||||
|
||||
Shows the pad button map OSD for the requested device, the OSD
|
||||
will be shown according the current device settings (output
|
||||
mapping, left handed mode, ...)
|
||||
-->
|
||||
<method name='Show'>
|
||||
<arg name='device_node' direction='in' type='o'/>
|
||||
<arg name='edition_mode' direction='in' type='b'/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
@ -1,9 +1,10 @@
|
||||
[Desktop Entry]
|
||||
_Name=Network Login
|
||||
Name=Network Login
|
||||
Type=Application
|
||||
Exec=gapplication launch org.gnome.Shell.PortalHelper
|
||||
DBusActivatable=true
|
||||
NoDisplay=true
|
||||
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
|
||||
Icon=network-workgroup
|
||||
StartupNotify=true
|
||||
OnlyShowIn=GNOME;
|
@ -1,7 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
_Name=GNOME Shell
|
||||
_Comment=Window management and application launching
|
||||
Name=GNOME Shell
|
||||
Comment=Window management and application launching
|
||||
Exec=@bindir@/gnome-shell
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-shell
|
||||
|
@ -3,143 +3,139 @@
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="development-tools" type="b">
|
||||
<default>true</default>
|
||||
<_summary>
|
||||
<summary>
|
||||
Enable internal tools useful for developers and testers from Alt-F2
|
||||
</_summary>
|
||||
<_description>
|
||||
</summary>
|
||||
<description>
|
||||
Allows access to internal debugging and monitoring tools
|
||||
using the Alt-F2 dialog.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="enabled-extensions" type="as">
|
||||
<default>[]</default>
|
||||
<_summary>UUIDs of extensions to enable</_summary>
|
||||
<_description>
|
||||
<summary>UUIDs of extensions to enable</summary>
|
||||
<description>
|
||||
GNOME Shell extensions have a UUID property; this key lists extensions
|
||||
which should be loaded. Any extension that wants to be loaded needs
|
||||
to be in this list. You can also manipulate this list with the
|
||||
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="disable-user-extensions" type="b">
|
||||
<default>false</default>
|
||||
<summary>Disable user extensions</summary>
|
||||
<description>
|
||||
Disable all extensions the user has enabled without affecting
|
||||
the “enabled-extension” setting.
|
||||
</description>
|
||||
</key>
|
||||
<key name="disable-extension-version-validation" type="b">
|
||||
<default>false</default>
|
||||
<_summary>Disables the validation of extension version compatibility</_summary>
|
||||
<_description>
|
||||
<default>true</default>
|
||||
<summary>Disables the validation of extension version compatibility</summary>
|
||||
<description>
|
||||
GNOME Shell will only load extensions that claim to support the current
|
||||
running version. Enabling this option will disable this check and try to
|
||||
load all extensions regardless of the versions they claim to support.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="favorite-apps" type="as">
|
||||
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
|
||||
<_summary>List of desktop file IDs for favorite applications</_summary>
|
||||
<_description>
|
||||
<summary>List of desktop file IDs for favorite applications</summary>
|
||||
<description>
|
||||
The applications corresponding to these identifiers
|
||||
will be displayed in the favorites area.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="app-picker-view" type="u">
|
||||
<default>0</default>
|
||||
<_summary>App Picker View</_summary>
|
||||
<_description>
|
||||
<summary>App Picker View</summary>
|
||||
<description>
|
||||
Index of the currently selected view in the application picker.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="command-history" type="as">
|
||||
<default>[]</default>
|
||||
<_summary>History for command (Alt-F2) dialog</_summary>
|
||||
<summary>History for command (Alt-F2) dialog</summary>
|
||||
</key>
|
||||
<key name="looking-glass-history" type="as">
|
||||
<default>[]</default>
|
||||
<!-- Translators: looking glass is a debugger and inspector tool, see https://live.gnome.org/GnomeShell/LookingGlass -->
|
||||
<_summary>History for the looking glass dialog</_summary>
|
||||
<!-- Translators: looking glass is a debugger and inspector tool, see https://wiki.gnome.org/Projects/GnomeShell/LookingGlass -->
|
||||
<summary>History for the looking glass dialog</summary>
|
||||
</key>
|
||||
<key name="always-show-log-out" type="b">
|
||||
<default>false</default>
|
||||
<_summary>Always show the 'Log out' menu item in the user menu.</_summary>
|
||||
<_description>
|
||||
This key overrides the automatic hiding of the 'Log out'
|
||||
<summary>Always show the “Log out” menu item in the user menu.</summary>
|
||||
<description>
|
||||
This key overrides the automatic hiding of the “Log out”
|
||||
menu item in single-user, single-session situations.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="remember-mount-password" type="b">
|
||||
<default>false</default>
|
||||
<_summary>Whether to remember password for mounting encrypted or remote filesystems</_summary>
|
||||
<_description>
|
||||
<summary>Whether to remember password for mounting encrypted or remote filesystems</summary>
|
||||
<description>
|
||||
The shell will request a password when an encrypted device or a
|
||||
remote filesystem is mounted. If the password can be saved for
|
||||
future use a 'Remember Password' checkbox will be present.
|
||||
future use a “Remember Password” checkbox will be present.
|
||||
This key sets the default state of the checkbox.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="had-bluetooth-devices-setup" type="b">
|
||||
<default>false</default>
|
||||
<_summary>Whether the default Bluetooth adapter had set up devices associated to it</_summary>
|
||||
<_description>
|
||||
<summary>Whether the default Bluetooth adapter had set up devices associated to it</summary>
|
||||
<description>
|
||||
The shell will only show a Bluetooth menu item if a Bluetooth
|
||||
adapter is powered, or if there were devices set up associated
|
||||
with the default adapter. This will be reset if the default
|
||||
adapter is ever seen not to have devices associated to it.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<child name="calendar" schema="org.gnome.shell.calendar"/>
|
||||
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
|
||||
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
|
||||
</schema>
|
||||
|
||||
<schema id="org.gnome.shell.calendar" path="/org/gnome/shell/calendar/"
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="show-weekdate" type="b">
|
||||
<default>false</default>
|
||||
<_summary>Show the week date in the calendar</_summary>
|
||||
<_description>
|
||||
If true, display the ISO week date in the calendar.
|
||||
</_description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
<schema id="org.gnome.shell.keybindings" path="/org/gnome/shell/keybindings/"
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="open-application-menu" type="as">
|
||||
<default>["<Super>F10"]</default>
|
||||
<_summary>Keybinding to open the application menu</_summary>
|
||||
<_description>
|
||||
<summary>Keybinding to open the application menu</summary>
|
||||
<description>
|
||||
Keybinding to open the application menu.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="toggle-application-view" type="as">
|
||||
<default>["<Super>a"]</default>
|
||||
<_summary>Keybinding to open the "Show Applications" view</_summary>
|
||||
<_description>
|
||||
Keybinding to open the "Show Applications" view of the Activities
|
||||
<summary>Keybinding to open the “Show Applications” view</summary>
|
||||
<description>
|
||||
Keybinding to open the “Show Applications” view of the Activities
|
||||
Overview.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="toggle-overview" type="as">
|
||||
<default>["<Super>s"]</default>
|
||||
<_summary>Keybinding to open the overview</_summary>
|
||||
<_description>
|
||||
<summary>Keybinding to open the overview</summary>
|
||||
<description>
|
||||
Keybinding to open the Activities Overview.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="toggle-message-tray" type="as">
|
||||
<default>["<Super>v","<Super>m"]</default>
|
||||
<_summary>Keybinding to toggle the visibility of the notification list</_summary>
|
||||
<_description>
|
||||
<summary>Keybinding to toggle the visibility of the notification list</summary>
|
||||
<description>
|
||||
Keybinding to toggle the visibility of the notification list.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
<key name="focus-active-notification" type="as">
|
||||
<default>["<Super>n"]</default>
|
||||
<_summary>Keybinding to focus the active notification</_summary>
|
||||
<_description>
|
||||
<summary>Keybinding to focus the active notification</summary>
|
||||
<description>
|
||||
Keybinding to focus the active notification.
|
||||
</_description>
|
||||
</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>
|
||||
<summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary>
|
||||
<description></description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
@ -147,10 +143,10 @@
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="keyboard-type" type="s">
|
||||
<default>'touch'</default>
|
||||
<_summary>Which keyboard to use</_summary>
|
||||
<_description>
|
||||
<summary>Which keyboard to use</summary>
|
||||
<description>
|
||||
The type of keyboard to use.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
@ -159,11 +155,11 @@
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key type="b" name="current-workspace-only">
|
||||
<default>false</default>
|
||||
<_summary>Limit switcher to current workspace.</_summary>
|
||||
<_description>
|
||||
<summary>Limit switcher to current workspace.</summary>
|
||||
<description>
|
||||
If true, only applications that have windows on the current workspace are shown in the switcher.
|
||||
Otherwise, all applications are included.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
@ -177,20 +173,20 @@
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="app-icon-mode" enum="org.gnome.shell.window-switcher.AppIconMode">
|
||||
<default>'both'</default>
|
||||
<_summary>The application icon mode.</_summary>
|
||||
<_description>
|
||||
<summary>The application icon mode.</summary>
|
||||
<description>
|
||||
Configures how the windows are shown in the switcher. Valid possibilities
|
||||
are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-only'
|
||||
(shows only the application icon) or 'both'.
|
||||
</_description>
|
||||
are “thumbnail-only” (shows a thumbnail of the window), “app-icon-only”
|
||||
(shows only the application icon) or “both”.
|
||||
</description>
|
||||
</key>
|
||||
<key type="b" name="current-workspace-only">
|
||||
<default>true</default>
|
||||
<_summary>Limit switcher to current workspace.</_summary>
|
||||
<_description>
|
||||
<summary>Limit switcher to current workspace.</summary>
|
||||
<description>
|
||||
If true, only windows from the current workspace are shown in the switcher.
|
||||
Otherwise, all windows are included.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
@ -198,43 +194,43 @@
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="attach-modal-dialogs" type="b">
|
||||
<default>true</default>
|
||||
<_summary>Attach modal dialog to the parent window</_summary>
|
||||
<_description>
|
||||
<summary>Attach modal dialog to the parent window</summary>
|
||||
<description>
|
||||
This key overrides the key in org.gnome.mutter when running
|
||||
GNOME Shell.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
|
||||
<key name="edge-tiling" type="b">
|
||||
<default>true</default>
|
||||
<_summary>Enable edge tiling when dropping windows on screen edges</_summary>
|
||||
<_description>
|
||||
<summary>Enable edge tiling when dropping windows on screen edges</summary>
|
||||
<description>
|
||||
This key overrides the key in org.gnome.mutter when running GNOME Shell.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
|
||||
<key name="dynamic-workspaces" type="b">
|
||||
<default>true</default>
|
||||
<_summary>Workspaces are managed dynamically</_summary>
|
||||
<_description>
|
||||
<summary>Workspaces are managed dynamically</summary>
|
||||
<description>
|
||||
This key overrides the key in org.gnome.mutter when running GNOME Shell.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
|
||||
<key name="workspaces-only-on-primary" type="b">
|
||||
<default>true</default>
|
||||
<_summary>Workspaces only on primary monitor</_summary>
|
||||
<_description>
|
||||
<summary>Workspaces only on primary monitor</summary>
|
||||
<description>
|
||||
This key overrides the key in org.gnome.mutter when running GNOME Shell.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
|
||||
<key name="focus-change-on-pointer-rest" type="b">
|
||||
<default>true</default>
|
||||
<_summary>Delay focus changes in mouse mode until the pointer stops moving</_summary>
|
||||
<_description>
|
||||
<summary>Delay focus changes in mouse mode until the pointer stops moving</summary>
|
||||
<description>
|
||||
This key overrides the key in org.gnome.mutter when running GNOME Shell.
|
||||
</_description>
|
||||
</description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
@ -1 +0,0 @@
|
||||
gem "sass", "~> 3.4.0"
|
@ -3,10 +3,10 @@ Summary
|
||||
|
||||
* Do not edit the CSS directly, edit the source SCSS files and process them with SASS (running
|
||||
`make` should do that when you have the required software installed, as described below;
|
||||
run `/.parse-sass.sh` manually if it doesn't)
|
||||
* To be able to use the lates/adequate version of sass, install ruby, gem, sass & bundle.
|
||||
On Fedora F20, this is done with `sudo dnf install rubygems && gem install bundle && bundle install`
|
||||
from the same directory this README resides in.
|
||||
run `./parse-sass.sh` manually if it doesn't)
|
||||
* Most SASS preprocessors should produce similar results, however the build system
|
||||
integration and 'parse-sass.sh' script use sassc. You should be able to install
|
||||
it with `pkcon install sassc` or your distribution's package manager.
|
||||
|
||||
How to tweak the theme
|
||||
----------------------
|
||||
@ -31,6 +31,4 @@ _common.scss - actual definitions of style for each widget. This is where
|
||||
your changes.
|
||||
|
||||
You can read about SASS at http://sass-lang.com/documentation/. Once you make your changes to the
|
||||
_common.scss file, you can either run the ./parse-sass.sh script or keep SASS watching for changes as you
|
||||
edit. This is done by running `bundle exec sass --watch --sourcemap=none .` If sass is out of date, or is
|
||||
missing, you can install it with `bundle install`.
|
||||
_common.scss file, you can either run make or the ./parse-sass.sh script.
|
||||
|
@ -118,6 +118,7 @@ StEntry {
|
||||
/* Scrollbars */
|
||||
StScrollView.vfade {
|
||||
-st-vfade-offset: 68px; }
|
||||
|
||||
StScrollView.hfade {
|
||||
-st-hfade-offset: 68px; }
|
||||
|
||||
@ -152,14 +153,18 @@ StScrollBar {
|
||||
/* Check Boxes */
|
||||
.check-box StBoxLayout {
|
||||
spacing: .8em; }
|
||||
|
||||
.check-box StBin {
|
||||
width: 24px;
|
||||
height: 22px;
|
||||
background-image: url("resource:///org/gnome/shell/theme/checkbox-off.svg"); }
|
||||
|
||||
.check-box:focus StBin {
|
||||
background-image: url("resource:///org/gnome/shell/theme/checkbox-off-focused.svg"); }
|
||||
|
||||
.check-box:checked StBin {
|
||||
background-image: url("resource:///org/gnome/shell/theme/checkbox.svg"); }
|
||||
|
||||
.check-box:focus:checked StBin {
|
||||
background-image: url("resource:///org/gnome/shell/theme/checkbox-focused.svg"); }
|
||||
|
||||
@ -216,11 +221,30 @@ StScrollBar {
|
||||
color: #d6d6d1;
|
||||
padding-bottom: .4em; }
|
||||
|
||||
.show-processes-dialog-subject,
|
||||
.mount-question-dialog-subject,
|
||||
.mount-dialog-subject,
|
||||
.end-session-dialog-subject {
|
||||
font-size: 14pt; }
|
||||
|
||||
/* Message Dialog */
|
||||
.message-dialog-main-layout {
|
||||
padding: 12px 20px 0;
|
||||
spacing: 12px; }
|
||||
|
||||
.message-dialog-content {
|
||||
max-width: 28em;
|
||||
spacing: 20px; }
|
||||
|
||||
.message-dialog-icon {
|
||||
min-width: 48px;
|
||||
icon-size: 48px; }
|
||||
|
||||
.message-dialog-title {
|
||||
font-weight: bold; }
|
||||
|
||||
.message-dialog-subtitle {
|
||||
color: #999999;
|
||||
font-weight: bold; }
|
||||
|
||||
/* End Session Dialog */
|
||||
.end-session-dialog {
|
||||
spacing: 42px;
|
||||
@ -289,75 +313,62 @@ StScrollBar {
|
||||
.shell-mount-operation-icon {
|
||||
icon-size: 48px; }
|
||||
|
||||
.show-processes-dialog,
|
||||
.mount-question-dialog {
|
||||
.mount-dialog {
|
||||
spacing: 24px; }
|
||||
.mount-dialog .message-dialog-title {
|
||||
padding-top: 10px;
|
||||
padding-left: 17px;
|
||||
padding-bottom: 6px;
|
||||
max-width: 34em; }
|
||||
.mount-dialog .message-dialog-title:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 17px; }
|
||||
.mount-dialog .message-dialog-body {
|
||||
padding-left: 17px;
|
||||
width: 28em; }
|
||||
.mount-dialog .message-dialog-body:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 17px; }
|
||||
|
||||
.show-processes-dialog-subject,
|
||||
.mount-question-dialog-subject {
|
||||
padding-top: 10px;
|
||||
padding-left: 17px;
|
||||
padding-bottom: 6px; }
|
||||
|
||||
.mount-question-dialog-subject {
|
||||
max-width: 500px; }
|
||||
|
||||
.show-processes-dialog-subject:rtl,
|
||||
.mount-question-dialog-subject:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 17px; }
|
||||
|
||||
.show-processes-dialog-description,
|
||||
.mount-question-dialog-description {
|
||||
padding-left: 17px;
|
||||
width: 28em; }
|
||||
|
||||
.show-processes-dialog-description:rtl,
|
||||
.mount-question-dialog-description:rtl {
|
||||
padding-right: 17px; }
|
||||
|
||||
.show-processes-dialog-app-list {
|
||||
.mount-dialog-app-list {
|
||||
max-height: 200px;
|
||||
padding-top: 24px;
|
||||
padding-left: 49px;
|
||||
padding-right: 32px; }
|
||||
|
||||
.show-processes-dialog-app-list:rtl {
|
||||
.mount-dialog-app-list:rtl {
|
||||
padding-right: 49px;
|
||||
padding-left: 32px; }
|
||||
|
||||
.show-processes-dialog-app-list-item {
|
||||
.mount-dialog-app-list-item {
|
||||
color: #e6e6e6; }
|
||||
.show-processes-dialog-app-list-item:hover {
|
||||
.mount-dialog-app-list-item:hover {
|
||||
color: #fff; }
|
||||
.show-processes-dialog-app-list-item:ltr {
|
||||
.mount-dialog-app-list-item:ltr {
|
||||
padding-right: 1em; }
|
||||
.show-processes-dialog-app-list-item:rtl {
|
||||
.mount-dialog-app-list-item:rtl {
|
||||
padding-left: 1em; }
|
||||
|
||||
.show-processes-dialog-app-list-item-icon:ltr {
|
||||
.mount-dialog-app-list-item-icon:ltr {
|
||||
padding-right: 17px; }
|
||||
.show-processes-dialog-app-list-item-icon:rtl {
|
||||
|
||||
.mount-dialog-app-list-item-icon:rtl {
|
||||
padding-left: 17px; }
|
||||
|
||||
.show-processes-dialog-app-list-item-name {
|
||||
.mount-dialog-app-list-item-name {
|
||||
font-size: 10pt; }
|
||||
|
||||
/* Password or Authentication Dialog */
|
||||
.prompt-dialog {
|
||||
width: 500px;
|
||||
width: 34em;
|
||||
border: 3px solid rgba(238, 238, 236, 0.2); }
|
||||
|
||||
.prompt-dialog-main-layout {
|
||||
spacing: 24px;
|
||||
padding: 10px; }
|
||||
|
||||
.prompt-dialog-message-layout {
|
||||
spacing: 16px; }
|
||||
|
||||
.prompt-dialog-headline {
|
||||
font-weight: bold;
|
||||
color: #b2b2a9; }
|
||||
.prompt-dialog .message-dialog-main-layout {
|
||||
spacing: 24px;
|
||||
padding: 10px; }
|
||||
.prompt-dialog .message-dialog-content {
|
||||
spacing: 16px; }
|
||||
.prompt-dialog .message-dialog-title {
|
||||
color: #b2b2a9; }
|
||||
|
||||
.prompt-dialog-description:rtl {
|
||||
text-align: right; }
|
||||
@ -427,25 +438,21 @@ StScrollBar {
|
||||
.audio-selection-device-icon {
|
||||
icon-size: 64px; }
|
||||
|
||||
/* Access Dialog */
|
||||
.access-dialog {
|
||||
spacing: 30px; }
|
||||
|
||||
/* Geolocation Dialog */
|
||||
.geolocation-dialog {
|
||||
spacing: 30px; }
|
||||
|
||||
.geolocation-dialog-main-layout {
|
||||
spacing: 12px; }
|
||||
/* Extension Dialog */
|
||||
.extension-dialog .message-dialog-main-layout {
|
||||
spacing: 24px;
|
||||
padding: 10px; }
|
||||
|
||||
.geolocation-dialog-content {
|
||||
spacing: 20px; }
|
||||
|
||||
.geolocation-dialog-icon {
|
||||
icon-size: 48px; }
|
||||
|
||||
.geolocation-dialog-title {
|
||||
font-weight: bold; }
|
||||
|
||||
.geolocation-dialog-reason {
|
||||
color: #999999;
|
||||
font-weight: bold; }
|
||||
.extension-dialog .message-dialog-title {
|
||||
color: #b2b2a9; }
|
||||
|
||||
/* Network Agent Dialog */
|
||||
.network-dialog-secret-table {
|
||||
@ -535,6 +542,21 @@ StScrollBar {
|
||||
border-radius: 0.3em;
|
||||
background-color: rgba(11, 12, 13, 0.5);
|
||||
color: #eeeeec; }
|
||||
.osd-window .level-bar {
|
||||
background-color: #eeeeec;
|
||||
border-radius: 0.3em; }
|
||||
|
||||
/* Pad OSD */
|
||||
.pad-osd-window {
|
||||
padding: 32px;
|
||||
background-color: rgba(0, 0, 0, 0.8); }
|
||||
.pad-osd-window .pad-osd-title-box {
|
||||
spacing: 12px; }
|
||||
.pad-osd-window .pad-osd-title-menu-box {
|
||||
spacing: 6px; }
|
||||
|
||||
.combo-box-label {
|
||||
width: 15em; }
|
||||
|
||||
/* App Switcher */
|
||||
.switcher-popup {
|
||||
@ -578,6 +600,10 @@ StScrollBar {
|
||||
width: 96px;
|
||||
height: 96px; }
|
||||
|
||||
/* Window Cycler */
|
||||
.cycler-highlight {
|
||||
border: 5px solid #215d9c; }
|
||||
|
||||
/* Workspace Switcher */
|
||||
.workspace-switcher-group {
|
||||
padding: 12px; }
|
||||
@ -627,7 +653,9 @@ StScrollBar {
|
||||
|
||||
/* TOP BAR */
|
||||
#panel {
|
||||
background-color: black;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
/* transition from solid to transparent */
|
||||
transition-duration: 500ms;
|
||||
font-weight: bold;
|
||||
height: 1.86em; }
|
||||
#panel.unlock-screen, #panel.login-screen, #panel.lock-screen {
|
||||
@ -636,7 +664,7 @@ StScrollBar {
|
||||
spacing: 4px; }
|
||||
#panel .panel-corner {
|
||||
-panel-corner-radius: 6px;
|
||||
-panel-corner-background-color: black;
|
||||
-panel-corner-background-color: rgba(0, 0, 0, 0.2);
|
||||
-panel-corner-border-width: 2px;
|
||||
-panel-corner-border-color: transparent; }
|
||||
#panel .panel-corner:active, #panel .panel-corner:overview, #panel .panel-corner:focus {
|
||||
@ -649,14 +677,24 @@ StScrollBar {
|
||||
-natural-hpadding: 12px;
|
||||
-minimum-hpadding: 6px;
|
||||
font-weight: bold;
|
||||
color: #ccc;
|
||||
color: #eee;
|
||||
text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9);
|
||||
transition-duration: 100ms; }
|
||||
#panel .panel-button .app-menu-icon {
|
||||
-st-icon-style: symbolic;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px; }
|
||||
#panel .panel-button .system-status-icon,
|
||||
#panel .panel-button .app-menu-icon > StIcon,
|
||||
#panel .panel-button .popup-menu-arrow {
|
||||
icon-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); }
|
||||
#panel .panel-button:hover {
|
||||
color: white; }
|
||||
color: white;
|
||||
text-shadow: 0px 0px 8px black; }
|
||||
#panel .panel-button:hover .system-status-icon,
|
||||
#panel .panel-button:hover .app-menu-icon > StIcon,
|
||||
#panel .panel-button:hover .popup-menu-arrow {
|
||||
icon-shadow: 0px 0px 8px black; }
|
||||
#panel .panel-button:active, #panel .panel-button:overview, #panel .panel-button:focus, #panel .panel-button:checked {
|
||||
background-color: rgba(0, 0, 0, 0.01);
|
||||
box-shadow: inset 0 -2px 0px #256ab1;
|
||||
@ -666,9 +704,17 @@ StScrollBar {
|
||||
#panel .panel-button .system-status-icon {
|
||||
icon-size: 1.09em;
|
||||
padding: 0 5px; }
|
||||
.unlock-screen #panel .panel-button, .login-screen #panel .panel-button, .lock-screen #panel .panel-button {
|
||||
.unlock-screen #panel .panel-button,
|
||||
.login-screen #panel .panel-button,
|
||||
.lock-screen #panel .panel-button {
|
||||
color: white; }
|
||||
.unlock-screen #panel .panel-button:focus, .unlock-screen #panel .panel-button:hover, .unlock-screen #panel .panel-button:active, .login-screen #panel .panel-button:focus, .login-screen #panel .panel-button:hover, .login-screen #panel .panel-button:active, .lock-screen #panel .panel-button:focus, .lock-screen #panel .panel-button:hover, .lock-screen #panel .panel-button:active {
|
||||
.unlock-screen #panel .panel-button:focus, .unlock-screen #panel .panel-button:hover, .unlock-screen #panel .panel-button:active,
|
||||
.login-screen #panel .panel-button:focus,
|
||||
.login-screen #panel .panel-button:hover,
|
||||
.login-screen #panel .panel-button:active,
|
||||
.lock-screen #panel .panel-button:focus,
|
||||
.lock-screen #panel .panel-button:hover,
|
||||
.lock-screen #panel .panel-button:active {
|
||||
color: white; }
|
||||
#panel .panel-status-indicators-box,
|
||||
#panel .panel-status-menu-box {
|
||||
@ -677,6 +723,21 @@ StScrollBar {
|
||||
spacing: 0; }
|
||||
#panel .screencast-indicator {
|
||||
color: #f57900; }
|
||||
#panel.solid {
|
||||
background-color: black;
|
||||
/* transition from transparent to solid */
|
||||
transition-duration: 300ms; }
|
||||
#panel.solid .panel-corner {
|
||||
-panel-corner-background-color: black; }
|
||||
#panel.solid .panel-button {
|
||||
color: #ccc;
|
||||
text-shadow: none; }
|
||||
#panel.solid .panel-button:hover {
|
||||
color: white; }
|
||||
#panel.solid .system-status-icon,
|
||||
#panel.solid .app-menu-icon > StIcon,
|
||||
#panel.solid .popup-menu-arrow {
|
||||
icon-shadow: none; }
|
||||
|
||||
#calendarArea {
|
||||
padding: 0.75em 1.0em; }
|
||||
@ -696,9 +757,20 @@ StScrollBar {
|
||||
.datemenu-displays-section {
|
||||
padding-bottom: 3em; }
|
||||
|
||||
.datemenu-displays-box {
|
||||
spacing: 1em; }
|
||||
|
||||
.datemenu-calendar-column {
|
||||
border: 0 solid #0d0d0d; }
|
||||
.datemenu-calendar-column:ltr {
|
||||
border-left-width: 1px; }
|
||||
.datemenu-calendar-column:rtl {
|
||||
border-right-width: 1px; }
|
||||
|
||||
.datemenu-today-button,
|
||||
.world-clocks-button,
|
||||
.message-list-section-title {
|
||||
.weather-button,
|
||||
.events-section-title {
|
||||
border-radius: 4px;
|
||||
padding: .4em; }
|
||||
|
||||
@ -711,12 +783,16 @@ StScrollBar {
|
||||
.datemenu-today-button:hover, .datemenu-today-button:focus,
|
||||
.world-clocks-button:hover,
|
||||
.world-clocks-button:focus,
|
||||
.message-list-section-title:hover,
|
||||
.message-list-section-title:focus {
|
||||
.weather-button:hover,
|
||||
.weather-button:focus,
|
||||
.events-section-title:hover,
|
||||
.events-section-title:focus {
|
||||
background-color: #0d0d0d; }
|
||||
|
||||
.datemenu-today-button:active,
|
||||
.world-clocks-button:active,
|
||||
.message-list-section-title:active {
|
||||
.weather-button:active,
|
||||
.events-section-title:active {
|
||||
color: white;
|
||||
background-color: #215d9c; }
|
||||
|
||||
@ -724,13 +800,17 @@ StScrollBar {
|
||||
font-size: 1.5em; }
|
||||
|
||||
.world-clocks-header,
|
||||
.message-list-section-title {
|
||||
.weather-header,
|
||||
.events-section-title {
|
||||
color: #999999;
|
||||
font-weight: bold; }
|
||||
|
||||
.world-clocks-grid {
|
||||
spacing-rows: 0.4em; }
|
||||
|
||||
.weather-box {
|
||||
spacing: 0.4em; }
|
||||
|
||||
.calendar-month-label {
|
||||
color: #f2f2f2;
|
||||
font-weight: bold;
|
||||
@ -766,7 +846,7 @@ StScrollBar {
|
||||
border-radius: 1.4em; }
|
||||
.calendar-day-base:hover, .calendar-day-base:focus {
|
||||
background-color: #0d0d0d; }
|
||||
.calendar-day-base:active {
|
||||
.calendar-day-base:active, .calendar-day-base:selected {
|
||||
color: white;
|
||||
background-color: #215d9c;
|
||||
border-color: transparent; }
|
||||
@ -815,69 +895,68 @@ StScrollBar {
|
||||
.message-list {
|
||||
width: 31.5em; }
|
||||
|
||||
.message-list-clear-button.button {
|
||||
background-color: transparent;
|
||||
margin: 1.5em 1.5em 0; }
|
||||
.message-list-clear-button.button:hover, .message-list-clear-button.button:focus {
|
||||
background-color: #0d0d0d; }
|
||||
|
||||
.message-list-sections {
|
||||
spacing: 1.5em; }
|
||||
spacing: 1em; }
|
||||
|
||||
.message-list-section,
|
||||
.message-list-section-list {
|
||||
spacing: 0.7em; }
|
||||
|
||||
.message-list-section-title-box {
|
||||
spacing: 0.4em; }
|
||||
|
||||
.message-list-section-close > StIcon {
|
||||
icon-size: 16px;
|
||||
border-radius: 8px;
|
||||
color: #000;
|
||||
background-color: #666666; }
|
||||
|
||||
/* FIXME: how do you do this in sass? */
|
||||
.message-list-section-close:hover > StIcon,
|
||||
.message-list-section-close:focus > StIcon {
|
||||
background-color: #999999; }
|
||||
|
||||
.message {
|
||||
background-color: #0d0d0d;
|
||||
border-radius: 3px; }
|
||||
.message:hover, .message:focus {
|
||||
background-color: #262626; }
|
||||
background-color: #0d0d0d; }
|
||||
|
||||
.message-icon-bin {
|
||||
padding: 8px 0px 8px 8px; }
|
||||
padding: 10px 3px 10px 10px; }
|
||||
.message-icon-bin:rtl {
|
||||
padding: 8px 8px 8px 0px; }
|
||||
padding: 10px 10px 10px 3px; }
|
||||
|
||||
.message-icon-bin > StIcon {
|
||||
icon-size: 32px; }
|
||||
|
||||
.message-secondary-bin:ltr {
|
||||
padding-left: 8px; }
|
||||
.message-secondary-bin:rtl {
|
||||
padding-right: 8px; }
|
||||
color: #cccccc;
|
||||
icon-size: 16px;
|
||||
-st-icon-style: symbolic; }
|
||||
|
||||
.message-secondary-bin {
|
||||
color: #999999; }
|
||||
padding: 0 12px; }
|
||||
|
||||
.message-secondary-bin > .event-time {
|
||||
color: #999999;
|
||||
font-size: 0.7em;
|
||||
/* HACK: the label should be baseline-aligned with a 1em label,
|
||||
fake this with some bottom padding */
|
||||
padding-bottom: 0.13em; }
|
||||
|
||||
.message-secondary-bin > StIcon {
|
||||
icon-size: 16px; }
|
||||
|
||||
.message-title {
|
||||
font-weight: bold;
|
||||
font-size: 1.1em; }
|
||||
color: #f2f2f2; }
|
||||
|
||||
.message-content {
|
||||
padding: 8px;
|
||||
font-size: .9em; }
|
||||
color: #cccccc;
|
||||
padding: 10px; }
|
||||
|
||||
.message-media-control {
|
||||
padding: 6px; }
|
||||
padding: 12px;
|
||||
color: #cccccc; }
|
||||
.message-media-control:last-child:ltr {
|
||||
padding-right: 18px; }
|
||||
.message-media-control:last-child:rtl {
|
||||
padding-left: 18px; }
|
||||
.message-media-control:hover {
|
||||
color: #fff; }
|
||||
.message-media-control:insensitive {
|
||||
color: #999999; }
|
||||
|
||||
.media-message-cover-icon {
|
||||
icon-size: 32px; }
|
||||
icon-size: 48px !important; }
|
||||
.media-message-cover-icon.fallback {
|
||||
color: #1a1a1a;
|
||||
background-color: #000;
|
||||
@ -951,9 +1030,9 @@ StScrollBar {
|
||||
|
||||
/* NETWORK DIALOGS */
|
||||
.nm-dialog {
|
||||
max-height: 500px;
|
||||
min-height: 450px;
|
||||
min-width: 470px; }
|
||||
max-height: 34em;
|
||||
min-height: 31em;
|
||||
min-width: 32em; }
|
||||
|
||||
.nm-dialog-content {
|
||||
spacing: 20px;
|
||||
@ -1071,31 +1150,30 @@ StScrollBar {
|
||||
spacing: 3px; }
|
||||
|
||||
.search-section-separator {
|
||||
-gradient-height: 1px;
|
||||
-gradient-start: rgba(255, 255, 255, 0);
|
||||
-gradient-end: rgba(255, 255, 255, 0.1);
|
||||
-margin-horizontal: 1.5em;
|
||||
height: 1px; }
|
||||
height: 2px;
|
||||
background-color: rgba(255, 255, 255, 0.2); }
|
||||
|
||||
.list-search-result-content {
|
||||
spacing: 12px;
|
||||
padding: 12px; }
|
||||
spacing: 30px; }
|
||||
|
||||
.list-search-result-title {
|
||||
font-size: 1.5em;
|
||||
color: #e2e2df; }
|
||||
color: #e2e2df;
|
||||
spacing: 12px; }
|
||||
|
||||
.list-search-result-description {
|
||||
color: #cacac4; }
|
||||
color: rgba(202, 202, 196, 0.5); }
|
||||
|
||||
.list-search-provider-details {
|
||||
width: 150px;
|
||||
color: #e2e2df;
|
||||
margin-top: 0.24em; }
|
||||
|
||||
.list-search-provider-content {
|
||||
spacing: 20px; }
|
||||
|
||||
.search-provider-icon {
|
||||
padding: 15px; }
|
||||
|
||||
.search-provider-icon-more {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-image: url("resource:///org/gnome/shell/theme/more-results.svg"); }
|
||||
|
||||
/* DASHBOARD */
|
||||
#dash {
|
||||
font-size: 9pt;
|
||||
@ -1156,6 +1234,7 @@ StScrollBar {
|
||||
.list-search-result:active,
|
||||
.list-search-result:checked {
|
||||
background-color: rgba(23, 25, 26, 0.9); }
|
||||
|
||||
.search-provider-icon:focus, .search-provider-icon:selected, .search-provider-icon:hover,
|
||||
.list-search-result:focus,
|
||||
.list-search-result:selected,
|
||||
@ -1163,7 +1242,8 @@ StScrollBar {
|
||||
background-color: rgba(238, 238, 236, 0.1);
|
||||
transition-duration: 200ms; }
|
||||
|
||||
.app-well-app:active .overview-icon, .app-well-app:checked .overview-icon,
|
||||
.app-well-app:active .overview-icon,
|
||||
.app-well-app:checked .overview-icon,
|
||||
.app-well-app.app-folder:active .overview-icon,
|
||||
.app-well-app.app-folder:checked .overview-icon,
|
||||
.show-apps:active .overview-icon,
|
||||
@ -1172,7 +1252,10 @@ StScrollBar {
|
||||
.grid-search-result:checked .overview-icon {
|
||||
background-color: rgba(23, 25, 26, 0.9);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.7); }
|
||||
.app-well-app:hover .overview-icon, .app-well-app:focus .overview-icon, .app-well-app:selected .overview-icon,
|
||||
|
||||
.app-well-app:hover .overview-icon,
|
||||
.app-well-app:focus .overview-icon,
|
||||
.app-well-app:selected .overview-icon,
|
||||
.app-well-app.app-folder:hover .overview-icon,
|
||||
.app-well-app.app-folder:focus .overview-icon,
|
||||
.app-well-app.app-folder:selected .overview-icon,
|
||||
@ -1598,10 +1681,12 @@ StScrollBar {
|
||||
|
||||
.login-dialog-user-selection-box {
|
||||
padding: 100px 0px; }
|
||||
.login-dialog-user-selection-box .login-dialog-not-listed-label {
|
||||
padding-left: 2px; }
|
||||
.login-dialog-not-listed-button:focus .login-dialog-user-selection-box .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-user-selection-box .login-dialog-not-listed-label {
|
||||
color: #eeeeec; }
|
||||
|
||||
.login-dialog-not-listed-label {
|
||||
padding-left: 2px; }
|
||||
.login-dialog-not-listed-button:focus .login-dialog-not-listed-label,
|
||||
.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
|
||||
color: #eeeeec; }
|
||||
|
||||
.login-dialog-not-listed-label {
|
||||
font-size: 90%;
|
||||
@ -1616,7 +1701,7 @@ StScrollBar {
|
||||
spacing: 12px;
|
||||
padding: .2em;
|
||||
width: 23em; }
|
||||
.login-dialog-user-list:expanded .login-dialog-user-list-item:focus {
|
||||
.login-dialog-user-list:expanded .login-dialog-user-list-item:selected {
|
||||
background-color: #215d9c;
|
||||
color: #ffffff; }
|
||||
.login-dialog-user-list:expanded .login-dialog-user-list-item:logged-in {
|
||||
@ -1630,9 +1715,6 @@ StScrollBar {
|
||||
padding-right: 1em; }
|
||||
.login-dialog-user-list-item:rtl {
|
||||
padding-left: 1em; }
|
||||
.login-dialog-user-list-item:hover {
|
||||
background-color: #215d9c;
|
||||
color: #ffffff; }
|
||||
.login-dialog-user-list-item .login-dialog-timed-login-indicator {
|
||||
height: 2px;
|
||||
margin: 2px 0 0 0;
|
||||
@ -1650,6 +1732,7 @@ StScrollBar {
|
||||
|
||||
.user-widget-label:ltr {
|
||||
padding-left: 18px; }
|
||||
|
||||
.user-widget-label:rtl {
|
||||
padding-right: 18px; }
|
||||
|
||||
@ -1777,6 +1860,7 @@ StScrollBar {
|
||||
.lg-dialog StEntry {
|
||||
selection-background-color: #bbbbbb;
|
||||
selected-color: #333333; }
|
||||
|
||||
.lg-dialog .shell-link {
|
||||
color: #999999; }
|
||||
.lg-dialog .shell-link:hover {
|
||||
|
Submodule data/theme/gnome-shell-sass updated: 6ccc180811...82941c9d93
@ -118,6 +118,7 @@ StEntry {
|
||||
/* Scrollbars */
|
||||
StScrollView.vfade {
|
||||
-st-vfade-offset: 68px; }
|
||||
|
||||
StScrollView.hfade {
|
||||
-st-hfade-offset: 68px; }
|
||||
|
||||
@ -152,14 +153,18 @@ StScrollBar {
|
||||
/* Check Boxes */
|
||||
.check-box StBoxLayout {
|
||||
spacing: .8em; }
|
||||
|
||||
.check-box StBin {
|
||||
width: 24px;
|
||||
height: 22px;
|
||||
background-image: url("resource:///org/gnome/shell/theme/checkbox-off.svg"); }
|
||||
|
||||
.check-box:focus StBin {
|
||||
background-image: url("resource:///org/gnome/shell/theme/checkbox-off-focused.svg"); }
|
||||
|
||||
.check-box:checked StBin {
|
||||
background-image: url("resource:///org/gnome/shell/theme/checkbox.svg"); }
|
||||
|
||||
.check-box:focus:checked StBin {
|
||||
background-image: url("resource:///org/gnome/shell/theme/checkbox-focused.svg"); }
|
||||
|
||||
@ -216,11 +221,30 @@ StScrollBar {
|
||||
color: #d6d6d1;
|
||||
padding-bottom: .4em; }
|
||||
|
||||
.show-processes-dialog-subject,
|
||||
.mount-question-dialog-subject,
|
||||
.mount-dialog-subject,
|
||||
.end-session-dialog-subject {
|
||||
font-size: 14pt; }
|
||||
|
||||
/* Message Dialog */
|
||||
.message-dialog-main-layout {
|
||||
padding: 12px 20px 0;
|
||||
spacing: 12px; }
|
||||
|
||||
.message-dialog-content {
|
||||
max-width: 28em;
|
||||
spacing: 20px; }
|
||||
|
||||
.message-dialog-icon {
|
||||
min-width: 48px;
|
||||
icon-size: 48px; }
|
||||
|
||||
.message-dialog-title {
|
||||
font-weight: bold; }
|
||||
|
||||
.message-dialog-subtitle {
|
||||
color: #8e8e80;
|
||||
font-weight: bold; }
|
||||
|
||||
/* End Session Dialog */
|
||||
.end-session-dialog {
|
||||
spacing: 42px;
|
||||
@ -289,75 +313,62 @@ StScrollBar {
|
||||
.shell-mount-operation-icon {
|
||||
icon-size: 48px; }
|
||||
|
||||
.show-processes-dialog,
|
||||
.mount-question-dialog {
|
||||
.mount-dialog {
|
||||
spacing: 24px; }
|
||||
.mount-dialog .message-dialog-title {
|
||||
padding-top: 10px;
|
||||
padding-left: 17px;
|
||||
padding-bottom: 6px;
|
||||
max-width: 34em; }
|
||||
.mount-dialog .message-dialog-title:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 17px; }
|
||||
.mount-dialog .message-dialog-body {
|
||||
padding-left: 17px;
|
||||
width: 28em; }
|
||||
.mount-dialog .message-dialog-body:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 17px; }
|
||||
|
||||
.show-processes-dialog-subject,
|
||||
.mount-question-dialog-subject {
|
||||
padding-top: 10px;
|
||||
padding-left: 17px;
|
||||
padding-bottom: 6px; }
|
||||
|
||||
.mount-question-dialog-subject {
|
||||
max-width: 500px; }
|
||||
|
||||
.show-processes-dialog-subject:rtl,
|
||||
.mount-question-dialog-subject:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 17px; }
|
||||
|
||||
.show-processes-dialog-description,
|
||||
.mount-question-dialog-description {
|
||||
padding-left: 17px;
|
||||
width: 28em; }
|
||||
|
||||
.show-processes-dialog-description:rtl,
|
||||
.mount-question-dialog-description:rtl {
|
||||
padding-right: 17px; }
|
||||
|
||||
.show-processes-dialog-app-list {
|
||||
.mount-dialog-app-list {
|
||||
max-height: 200px;
|
||||
padding-top: 24px;
|
||||
padding-left: 49px;
|
||||
padding-right: 32px; }
|
||||
|
||||
.show-processes-dialog-app-list:rtl {
|
||||
.mount-dialog-app-list:rtl {
|
||||
padding-right: 49px;
|
||||
padding-left: 32px; }
|
||||
|
||||
.show-processes-dialog-app-list-item {
|
||||
.mount-dialog-app-list-item {
|
||||
color: #d6d6d1; }
|
||||
.show-processes-dialog-app-list-item:hover {
|
||||
.mount-dialog-app-list-item:hover {
|
||||
color: #eeeeec; }
|
||||
.show-processes-dialog-app-list-item:ltr {
|
||||
.mount-dialog-app-list-item:ltr {
|
||||
padding-right: 1em; }
|
||||
.show-processes-dialog-app-list-item:rtl {
|
||||
.mount-dialog-app-list-item:rtl {
|
||||
padding-left: 1em; }
|
||||
|
||||
.show-processes-dialog-app-list-item-icon:ltr {
|
||||
.mount-dialog-app-list-item-icon:ltr {
|
||||
padding-right: 17px; }
|
||||
.show-processes-dialog-app-list-item-icon:rtl {
|
||||
|
||||
.mount-dialog-app-list-item-icon:rtl {
|
||||
padding-left: 17px; }
|
||||
|
||||
.show-processes-dialog-app-list-item-name {
|
||||
.mount-dialog-app-list-item-name {
|
||||
font-size: 10pt; }
|
||||
|
||||
/* Password or Authentication Dialog */
|
||||
.prompt-dialog {
|
||||
width: 500px;
|
||||
width: 34em;
|
||||
border: 3px solid rgba(238, 238, 236, 0.2); }
|
||||
|
||||
.prompt-dialog-main-layout {
|
||||
spacing: 24px;
|
||||
padding: 10px; }
|
||||
|
||||
.prompt-dialog-message-layout {
|
||||
spacing: 16px; }
|
||||
|
||||
.prompt-dialog-headline {
|
||||
font-weight: bold;
|
||||
color: #b2b2a9; }
|
||||
.prompt-dialog .message-dialog-main-layout {
|
||||
spacing: 24px;
|
||||
padding: 10px; }
|
||||
.prompt-dialog .message-dialog-content {
|
||||
spacing: 16px; }
|
||||
.prompt-dialog .message-dialog-title {
|
||||
color: #b2b2a9; }
|
||||
|
||||
.prompt-dialog-description:rtl {
|
||||
text-align: right; }
|
||||
@ -427,25 +438,21 @@ StScrollBar {
|
||||
.audio-selection-device-icon {
|
||||
icon-size: 64px; }
|
||||
|
||||
/* Access Dialog */
|
||||
.access-dialog {
|
||||
spacing: 30px; }
|
||||
|
||||
/* Geolocation Dialog */
|
||||
.geolocation-dialog {
|
||||
spacing: 30px; }
|
||||
|
||||
.geolocation-dialog-main-layout {
|
||||
spacing: 12px; }
|
||||
/* Extension Dialog */
|
||||
.extension-dialog .message-dialog-main-layout {
|
||||
spacing: 24px;
|
||||
padding: 10px; }
|
||||
|
||||
.geolocation-dialog-content {
|
||||
spacing: 20px; }
|
||||
|
||||
.geolocation-dialog-icon {
|
||||
icon-size: 48px; }
|
||||
|
||||
.geolocation-dialog-title {
|
||||
font-weight: bold; }
|
||||
|
||||
.geolocation-dialog-reason {
|
||||
color: #8e8e80;
|
||||
font-weight: bold; }
|
||||
.extension-dialog .message-dialog-title {
|
||||
color: #b2b2a9; }
|
||||
|
||||
/* Network Agent Dialog */
|
||||
.network-dialog-secret-table {
|
||||
@ -535,6 +542,21 @@ StScrollBar {
|
||||
border-radius: 0.3em;
|
||||
background-color: rgba(11, 12, 13, 0.5);
|
||||
color: #eeeeec; }
|
||||
.osd-window .level-bar {
|
||||
background-color: #eeeeec;
|
||||
border-radius: 0.3em; }
|
||||
|
||||
/* Pad OSD */
|
||||
.pad-osd-window {
|
||||
padding: 32px;
|
||||
background-color: rgba(0, 0, 0, 0.8); }
|
||||
.pad-osd-window .pad-osd-title-box {
|
||||
spacing: 12px; }
|
||||
.pad-osd-window .pad-osd-title-menu-box {
|
||||
spacing: 6px; }
|
||||
|
||||
.combo-box-label {
|
||||
width: 15em; }
|
||||
|
||||
/* App Switcher */
|
||||
.switcher-popup {
|
||||
@ -578,6 +600,10 @@ StScrollBar {
|
||||
width: 96px;
|
||||
height: 96px; }
|
||||
|
||||
/* Window Cycler */
|
||||
.cycler-highlight {
|
||||
border: 5px solid #215d9c; }
|
||||
|
||||
/* Workspace Switcher */
|
||||
.workspace-switcher-group {
|
||||
padding: 12px; }
|
||||
@ -627,7 +653,9 @@ StScrollBar {
|
||||
|
||||
/* TOP BAR */
|
||||
#panel {
|
||||
background-color: black;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
/* transition from solid to transparent */
|
||||
transition-duration: 500ms;
|
||||
font-weight: bold;
|
||||
height: 1.86em; }
|
||||
#panel.unlock-screen, #panel.login-screen, #panel.lock-screen {
|
||||
@ -636,7 +664,7 @@ StScrollBar {
|
||||
spacing: 4px; }
|
||||
#panel .panel-corner {
|
||||
-panel-corner-radius: 6px;
|
||||
-panel-corner-background-color: black;
|
||||
-panel-corner-background-color: rgba(0, 0, 0, 0.2);
|
||||
-panel-corner-border-width: 2px;
|
||||
-panel-corner-border-color: transparent; }
|
||||
#panel .panel-corner:active, #panel .panel-corner:overview, #panel .panel-corner:focus {
|
||||
@ -649,14 +677,24 @@ StScrollBar {
|
||||
-natural-hpadding: 12px;
|
||||
-minimum-hpadding: 6px;
|
||||
font-weight: bold;
|
||||
color: #ccc;
|
||||
color: #eee;
|
||||
text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9);
|
||||
transition-duration: 100ms; }
|
||||
#panel .panel-button .app-menu-icon {
|
||||
-st-icon-style: symbolic;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px; }
|
||||
#panel .panel-button .system-status-icon,
|
||||
#panel .panel-button .app-menu-icon > StIcon,
|
||||
#panel .panel-button .popup-menu-arrow {
|
||||
icon-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); }
|
||||
#panel .panel-button:hover {
|
||||
color: white; }
|
||||
color: white;
|
||||
text-shadow: 0px 0px 8px black; }
|
||||
#panel .panel-button:hover .system-status-icon,
|
||||
#panel .panel-button:hover .app-menu-icon > StIcon,
|
||||
#panel .panel-button:hover .popup-menu-arrow {
|
||||
icon-shadow: 0px 0px 8px black; }
|
||||
#panel .panel-button:active, #panel .panel-button:overview, #panel .panel-button:focus, #panel .panel-button:checked {
|
||||
background-color: rgba(0, 0, 0, 0.01);
|
||||
box-shadow: inset 0 -2px 0px #256ab1;
|
||||
@ -666,9 +704,17 @@ StScrollBar {
|
||||
#panel .panel-button .system-status-icon {
|
||||
icon-size: 1.09em;
|
||||
padding: 0 5px; }
|
||||
.unlock-screen #panel .panel-button, .login-screen #panel .panel-button, .lock-screen #panel .panel-button {
|
||||
.unlock-screen #panel .panel-button,
|
||||
.login-screen #panel .panel-button,
|
||||
.lock-screen #panel .panel-button {
|
||||
color: white; }
|
||||
.unlock-screen #panel .panel-button:focus, .unlock-screen #panel .panel-button:hover, .unlock-screen #panel .panel-button:active, .login-screen #panel .panel-button:focus, .login-screen #panel .panel-button:hover, .login-screen #panel .panel-button:active, .lock-screen #panel .panel-button:focus, .lock-screen #panel .panel-button:hover, .lock-screen #panel .panel-button:active {
|
||||
.unlock-screen #panel .panel-button:focus, .unlock-screen #panel .panel-button:hover, .unlock-screen #panel .panel-button:active,
|
||||
.login-screen #panel .panel-button:focus,
|
||||
.login-screen #panel .panel-button:hover,
|
||||
.login-screen #panel .panel-button:active,
|
||||
.lock-screen #panel .panel-button:focus,
|
||||
.lock-screen #panel .panel-button:hover,
|
||||
.lock-screen #panel .panel-button:active {
|
||||
color: white; }
|
||||
#panel .panel-status-indicators-box,
|
||||
#panel .panel-status-menu-box {
|
||||
@ -677,6 +723,21 @@ StScrollBar {
|
||||
spacing: 0; }
|
||||
#panel .screencast-indicator {
|
||||
color: #f57900; }
|
||||
#panel.solid {
|
||||
background-color: black;
|
||||
/* transition from transparent to solid */
|
||||
transition-duration: 300ms; }
|
||||
#panel.solid .panel-corner {
|
||||
-panel-corner-background-color: black; }
|
||||
#panel.solid .panel-button {
|
||||
color: #ccc;
|
||||
text-shadow: none; }
|
||||
#panel.solid .panel-button:hover {
|
||||
color: white; }
|
||||
#panel.solid .system-status-icon,
|
||||
#panel.solid .app-menu-icon > StIcon,
|
||||
#panel.solid .popup-menu-arrow {
|
||||
icon-shadow: none; }
|
||||
|
||||
#calendarArea {
|
||||
padding: 0.75em 1.0em; }
|
||||
@ -696,9 +757,20 @@ StScrollBar {
|
||||
.datemenu-displays-section {
|
||||
padding-bottom: 3em; }
|
||||
|
||||
.datemenu-displays-box {
|
||||
spacing: 1em; }
|
||||
|
||||
.datemenu-calendar-column {
|
||||
border: 0 solid #454c4c; }
|
||||
.datemenu-calendar-column:ltr {
|
||||
border-left-width: 1px; }
|
||||
.datemenu-calendar-column:rtl {
|
||||
border-right-width: 1px; }
|
||||
|
||||
.datemenu-today-button,
|
||||
.world-clocks-button,
|
||||
.message-list-section-title {
|
||||
.weather-button,
|
||||
.events-section-title {
|
||||
border-radius: 4px;
|
||||
padding: .4em; }
|
||||
|
||||
@ -711,12 +783,16 @@ StScrollBar {
|
||||
.datemenu-today-button:hover, .datemenu-today-button:focus,
|
||||
.world-clocks-button:hover,
|
||||
.world-clocks-button:focus,
|
||||
.message-list-section-title:hover,
|
||||
.message-list-section-title:focus {
|
||||
.weather-button:hover,
|
||||
.weather-button:focus,
|
||||
.events-section-title:hover,
|
||||
.events-section-title:focus {
|
||||
background-color: #454c4c; }
|
||||
|
||||
.datemenu-today-button:active,
|
||||
.world-clocks-button:active,
|
||||
.message-list-section-title:active {
|
||||
.weather-button:active,
|
||||
.events-section-title:active {
|
||||
color: white;
|
||||
background-color: #215d9c; }
|
||||
|
||||
@ -724,13 +800,17 @@ StScrollBar {
|
||||
font-size: 1.5em; }
|
||||
|
||||
.world-clocks-header,
|
||||
.message-list-section-title {
|
||||
.weather-header,
|
||||
.events-section-title {
|
||||
color: #8e8e80;
|
||||
font-weight: bold; }
|
||||
|
||||
.world-clocks-grid {
|
||||
spacing-rows: 0.4em; }
|
||||
|
||||
.weather-box {
|
||||
spacing: 0.4em; }
|
||||
|
||||
.calendar-month-label {
|
||||
color: #e2e2df;
|
||||
font-weight: bold;
|
||||
@ -766,7 +846,7 @@ StScrollBar {
|
||||
border-radius: 1.4em; }
|
||||
.calendar-day-base:hover, .calendar-day-base:focus {
|
||||
background-color: #454c4c; }
|
||||
.calendar-day-base:active {
|
||||
.calendar-day-base:active, .calendar-day-base:selected {
|
||||
color: white;
|
||||
background-color: #215d9c;
|
||||
border-color: transparent; }
|
||||
@ -815,69 +895,68 @@ StScrollBar {
|
||||
.message-list {
|
||||
width: 31.5em; }
|
||||
|
||||
.message-list-clear-button.button {
|
||||
background-color: transparent;
|
||||
margin: 1.5em 1.5em 0; }
|
||||
.message-list-clear-button.button:hover, .message-list-clear-button.button:focus {
|
||||
background-color: #454c4c; }
|
||||
|
||||
.message-list-sections {
|
||||
spacing: 1.5em; }
|
||||
spacing: 1em; }
|
||||
|
||||
.message-list-section,
|
||||
.message-list-section-list {
|
||||
spacing: 0.7em; }
|
||||
|
||||
.message-list-section-title-box {
|
||||
spacing: 0.4em; }
|
||||
|
||||
.message-list-section-close > StIcon {
|
||||
icon-size: 16px;
|
||||
border-radius: 8px;
|
||||
color: #393f3f;
|
||||
background-color: #59594f; }
|
||||
|
||||
/* FIXME: how do you do this in sass? */
|
||||
.message-list-section-close:hover > StIcon,
|
||||
.message-list-section-close:focus > StIcon {
|
||||
background-color: #8e8e80; }
|
||||
|
||||
.message {
|
||||
background-color: #454c4c;
|
||||
border-radius: 3px; }
|
||||
.message:hover, .message:focus {
|
||||
background-color: #5d6767; }
|
||||
background-color: #454c4c; }
|
||||
|
||||
.message-icon-bin {
|
||||
padding: 8px 0px 8px 8px; }
|
||||
padding: 10px 3px 10px 10px; }
|
||||
.message-icon-bin:rtl {
|
||||
padding: 8px 8px 8px 0px; }
|
||||
padding: 10px 10px 10px 3px; }
|
||||
|
||||
.message-icon-bin > StIcon {
|
||||
icon-size: 32px; }
|
||||
|
||||
.message-secondary-bin:ltr {
|
||||
padding-left: 8px; }
|
||||
.message-secondary-bin:rtl {
|
||||
padding-right: 8px; }
|
||||
color: #bebeb6;
|
||||
icon-size: 16px;
|
||||
-st-icon-style: symbolic; }
|
||||
|
||||
.message-secondary-bin {
|
||||
color: #8e8e80; }
|
||||
padding: 0 12px; }
|
||||
|
||||
.message-secondary-bin > .event-time {
|
||||
color: #8e8e80;
|
||||
font-size: 0.7em;
|
||||
/* HACK: the label should be baseline-aligned with a 1em label,
|
||||
fake this with some bottom padding */
|
||||
padding-bottom: 0.13em; }
|
||||
|
||||
.message-secondary-bin > StIcon {
|
||||
icon-size: 16px; }
|
||||
|
||||
.message-title {
|
||||
font-weight: bold;
|
||||
font-size: 1.1em; }
|
||||
color: #e2e2df; }
|
||||
|
||||
.message-content {
|
||||
padding: 8px;
|
||||
font-size: .9em; }
|
||||
color: #bebeb6;
|
||||
padding: 10px; }
|
||||
|
||||
.message-media-control {
|
||||
padding: 6px; }
|
||||
padding: 12px;
|
||||
color: #bebeb6; }
|
||||
.message-media-control:last-child:ltr {
|
||||
padding-right: 18px; }
|
||||
.message-media-control:last-child:rtl {
|
||||
padding-left: 18px; }
|
||||
.message-media-control:hover {
|
||||
color: #eeeeec; }
|
||||
.message-media-control:insensitive {
|
||||
color: #8e8e80; }
|
||||
|
||||
.media-message-cover-icon {
|
||||
icon-size: 32px; }
|
||||
icon-size: 48px !important; }
|
||||
.media-message-cover-icon.fallback {
|
||||
color: #515a5a;
|
||||
background-color: #393f3f;
|
||||
@ -951,9 +1030,9 @@ StScrollBar {
|
||||
|
||||
/* NETWORK DIALOGS */
|
||||
.nm-dialog {
|
||||
max-height: 500px;
|
||||
min-height: 450px;
|
||||
min-width: 470px; }
|
||||
max-height: 34em;
|
||||
min-height: 31em;
|
||||
min-width: 32em; }
|
||||
|
||||
.nm-dialog-content {
|
||||
spacing: 20px;
|
||||
@ -1071,31 +1150,30 @@ StScrollBar {
|
||||
spacing: 3px; }
|
||||
|
||||
.search-section-separator {
|
||||
-gradient-height: 1px;
|
||||
-gradient-start: rgba(255, 255, 255, 0);
|
||||
-gradient-end: rgba(255, 255, 255, 0.1);
|
||||
-margin-horizontal: 1.5em;
|
||||
height: 1px; }
|
||||
height: 2px;
|
||||
background-color: rgba(255, 255, 255, 0.2); }
|
||||
|
||||
.list-search-result-content {
|
||||
spacing: 12px;
|
||||
padding: 12px; }
|
||||
spacing: 30px; }
|
||||
|
||||
.list-search-result-title {
|
||||
font-size: 1.5em;
|
||||
color: #e2e2df; }
|
||||
color: #e2e2df;
|
||||
spacing: 12px; }
|
||||
|
||||
.list-search-result-description {
|
||||
color: #cacac4; }
|
||||
color: rgba(202, 202, 196, 0.5); }
|
||||
|
||||
.list-search-provider-details {
|
||||
width: 150px;
|
||||
color: #e2e2df;
|
||||
margin-top: 0.24em; }
|
||||
|
||||
.list-search-provider-content {
|
||||
spacing: 20px; }
|
||||
|
||||
.search-provider-icon {
|
||||
padding: 15px; }
|
||||
|
||||
.search-provider-icon-more {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-image: url("resource:///org/gnome/shell/theme/more-results.svg"); }
|
||||
|
||||
/* DASHBOARD */
|
||||
#dash {
|
||||
font-size: 9pt;
|
||||
@ -1156,6 +1234,7 @@ StScrollBar {
|
||||
.list-search-result:active,
|
||||
.list-search-result:checked {
|
||||
background-color: rgba(23, 25, 26, 0.9); }
|
||||
|
||||
.search-provider-icon:focus, .search-provider-icon:selected, .search-provider-icon:hover,
|
||||
.list-search-result:focus,
|
||||
.list-search-result:selected,
|
||||
@ -1163,7 +1242,8 @@ StScrollBar {
|
||||
background-color: rgba(238, 238, 236, 0.1);
|
||||
transition-duration: 200ms; }
|
||||
|
||||
.app-well-app:active .overview-icon, .app-well-app:checked .overview-icon,
|
||||
.app-well-app:active .overview-icon,
|
||||
.app-well-app:checked .overview-icon,
|
||||
.app-well-app.app-folder:active .overview-icon,
|
||||
.app-well-app.app-folder:checked .overview-icon,
|
||||
.show-apps:active .overview-icon,
|
||||
@ -1172,7 +1252,10 @@ StScrollBar {
|
||||
.grid-search-result:checked .overview-icon {
|
||||
background-color: rgba(23, 25, 26, 0.9);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.7); }
|
||||
.app-well-app:hover .overview-icon, .app-well-app:focus .overview-icon, .app-well-app:selected .overview-icon,
|
||||
|
||||
.app-well-app:hover .overview-icon,
|
||||
.app-well-app:focus .overview-icon,
|
||||
.app-well-app:selected .overview-icon,
|
||||
.app-well-app.app-folder:hover .overview-icon,
|
||||
.app-well-app.app-folder:focus .overview-icon,
|
||||
.app-well-app.app-folder:selected .overview-icon,
|
||||
@ -1598,10 +1681,12 @@ StScrollBar {
|
||||
|
||||
.login-dialog-user-selection-box {
|
||||
padding: 100px 0px; }
|
||||
.login-dialog-user-selection-box .login-dialog-not-listed-label {
|
||||
padding-left: 2px; }
|
||||
.login-dialog-not-listed-button:focus .login-dialog-user-selection-box .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-user-selection-box .login-dialog-not-listed-label {
|
||||
color: #eeeeec; }
|
||||
|
||||
.login-dialog-not-listed-label {
|
||||
padding-left: 2px; }
|
||||
.login-dialog-not-listed-button:focus .login-dialog-not-listed-label,
|
||||
.login-dialog-not-listed-button:hover .login-dialog-not-listed-label {
|
||||
color: #eeeeec; }
|
||||
|
||||
.login-dialog-not-listed-label {
|
||||
font-size: 90%;
|
||||
@ -1616,7 +1701,7 @@ StScrollBar {
|
||||
spacing: 12px;
|
||||
padding: .2em;
|
||||
width: 23em; }
|
||||
.login-dialog-user-list:expanded .login-dialog-user-list-item:focus {
|
||||
.login-dialog-user-list:expanded .login-dialog-user-list-item:selected {
|
||||
background-color: #215d9c;
|
||||
color: #ffffff; }
|
||||
.login-dialog-user-list:expanded .login-dialog-user-list-item:logged-in {
|
||||
@ -1630,9 +1715,6 @@ StScrollBar {
|
||||
padding-right: 1em; }
|
||||
.login-dialog-user-list-item:rtl {
|
||||
padding-left: 1em; }
|
||||
.login-dialog-user-list-item:hover {
|
||||
background-color: #215d9c;
|
||||
color: #ffffff; }
|
||||
.login-dialog-user-list-item .login-dialog-timed-login-indicator {
|
||||
height: 2px;
|
||||
margin: 2px 0 0 0;
|
||||
@ -1650,6 +1732,7 @@ StScrollBar {
|
||||
|
||||
.user-widget-label:ltr {
|
||||
padding-left: 18px; }
|
||||
|
||||
.user-widget-label:rtl {
|
||||
padding-right: 18px; }
|
||||
|
||||
@ -1777,6 +1860,7 @@ StScrollBar {
|
||||
.lg-dialog StEntry {
|
||||
selection-background-color: #bbbbbb;
|
||||
selected-color: #333333; }
|
||||
|
||||
.lg-dialog .shell-link {
|
||||
color: #999999; }
|
||||
.lg-dialog .shell-link:hover {
|
||||
|
21
data/theme/meson.build
Normal file
21
data/theme/meson.build
Normal file
@ -0,0 +1,21 @@
|
||||
theme_sources = files([
|
||||
'gnome-shell-high-contrast.scss',
|
||||
'gnome-shell.scss',
|
||||
'gnome-shell-sass/_colors.scss',
|
||||
'gnome-shell-sass/_common.scss',
|
||||
'gnome-shell-sass/_drawing.scss',
|
||||
'gnome-shell-sass/_high-contrast-colors.scss'
|
||||
])
|
||||
|
||||
theme_deps = []
|
||||
|
||||
if sassc.found()
|
||||
parse_sass = files('parse-sass.sh')
|
||||
|
||||
theme_deps += custom_target('update-theme',
|
||||
output: 'theme-update.stamp',
|
||||
depend_files: theme_sources,
|
||||
command: [parse_sass, '@OUTPUT@'],
|
||||
build_by_default: true
|
||||
)
|
||||
endif
|
@ -1,114 +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="16"
|
||||
height="16"
|
||||
id="svg12430"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="more-results.svg">
|
||||
<defs
|
||||
id="defs12432" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#7a7a7a"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="90.509668"
|
||||
inkscape:cx="6.5009792"
|
||||
inkscape:cy="8.3589595"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g14642-3-0"
|
||||
showgrid="false"
|
||||
borderlayer="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="840"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid13002" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata12435">
|
||||
<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(0,-1036.3622)">
|
||||
<g
|
||||
style="display:inline"
|
||||
transform="translate(-141.99984,638.37113)"
|
||||
inkscape:label="zoom-in"
|
||||
id="g14642-3-0">
|
||||
<path
|
||||
sodipodi:type="inkscape:offset"
|
||||
inkscape:radius="0"
|
||||
inkscape:original="M 145.1875 400 C 144.5248 400 144 400.54899 144 401.21875 L 144 410.78125 C 144 411.45101 144.5248 412 145.1875 412 L 154.8125 412 C 155.4752 412 156 411.45101 156 410.78125 L 156 401.21875 C 156 400.54899 155.4752 400 154.8125 400 L 145.1875 400 z M 149 403 L 151 403 L 151 405 L 153 405 L 153 407 L 151 407 L 151 409 L 149 409 L 149 407 L 147 407 L 147 405 L 149 405 L 149 403 z "
|
||||
xlink:href="#rect11749-5-0-1-8"
|
||||
style="color:#bebebe;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;opacity:0.8"
|
||||
id="path13004"
|
||||
inkscape:href="#rect11749-5-0-1-8"
|
||||
d="M 145.1875,400 C 144.5248,400 144,400.54899 144,401.21875 l 0,9.5625 c 0,0.66976 0.5248,1.21875 1.1875,1.21875 l 9.625,0 c 0.6627,0 1.1875,-0.54899 1.1875,-1.21875 l 0,-9.5625 C 156,400.54899 155.4752,400 154.8125,400 L 145.1875,400 z m 3.8125,3 2,0 0,2 2,0 0,2 -2,0 0,2 -2,0 0,-2 -2,0 0,-2 2,0 L 149,403 Z"
|
||||
transform="translate(0,1)" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path13004"
|
||||
id="use11960"
|
||||
transform="translate(1,-1)"
|
||||
width="16"
|
||||
height="16" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#use11960"
|
||||
id="use11962"
|
||||
transform="translate(-2,0)"
|
||||
width="16"
|
||||
height="16" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
|
||||
d="M 7 5 L 7 7 L 5 7 L 5 9 L 7 9 L 7 11 L 9 11 L 9 9 L 11 9 L 11 7 L 9 7 L 9 5 L 7 5 z "
|
||||
transform="translate(141.99984,397.99107)"
|
||||
id="rect3757" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#bebebe;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||
d="M 145.1875,400 C 144.5248,400 144,400.54899 144,401.21875 l 0,9.5625 c 0,0.66976 0.5248,1.21875 1.1875,1.21875 l 9.625,0 c 0.6627,0 1.1875,-0.54899 1.1875,-1.21875 l 0,-9.5625 C 156,400.54899 155.4752,400 154.8125,400 L 145.1875,400 z m 3.8125,3 2,0 0,2 2,0 0,2 -2,0 0,2 -2,0 0,-2 -2,0 0,-2 2,0 L 149,403 Z"
|
||||
id="rect11749-5-0-1-8" />
|
||||
<rect
|
||||
style="fill:none;stroke:none"
|
||||
id="rect3620-5-4"
|
||||
width="15.981825"
|
||||
height="16"
|
||||
x="142"
|
||||
y="398"
|
||||
rx="0"
|
||||
ry="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 4.4 KiB |
30
data/theme/pad-osd.css
Normal file
30
data/theme/pad-osd.css
Normal file
@ -0,0 +1,30 @@
|
||||
.Leader {
|
||||
stroke-width: .5 !important;
|
||||
stroke: #535353;
|
||||
fill: none !important;
|
||||
}
|
||||
|
||||
.Button {
|
||||
stroke-width: .25;
|
||||
stroke: #ededed;
|
||||
fill: #ededed;
|
||||
}
|
||||
|
||||
.Ring {
|
||||
stroke-width: .5 !important;
|
||||
stroke: #535353 !important;
|
||||
fill: none !important;
|
||||
}
|
||||
|
||||
.Label {
|
||||
stroke: none !important;
|
||||
stroke-width: .1 !important;
|
||||
font-size: .1 !important;
|
||||
fill: transparent !important;
|
||||
}
|
||||
|
||||
.TouchStrip, .TouchRing {
|
||||
stroke-width: .1 !important;
|
||||
stroke: #ededed !important;
|
||||
fill: #535353 !important;
|
||||
}
|
@ -1,3 +1,10 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/sh
|
||||
|
||||
bundle exec sass --update --sourcemap=none .
|
||||
srcdir=`dirname $0`
|
||||
stamp=${1}
|
||||
for scss in $srcdir/*.scss
|
||||
do
|
||||
sassc -a $scss ${scss%%.scss}.css || exit 1
|
||||
done
|
||||
|
||||
[ "$stamp" ] && touch $stamp
|
||||
|
5
docs/reference/meson.build
Normal file
5
docs/reference/meson.build
Normal file
@ -0,0 +1,5 @@
|
||||
version_conf = configuration_data()
|
||||
version_conf.set('VERSION', meson.project_version())
|
||||
|
||||
subdir('shell')
|
||||
subdir('st')
|
@ -113,19 +113,19 @@ expand_content_files=
|
||||
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
|
||||
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
|
||||
GTKDOC_CFLAGS=$(GNOME_SHELL_CFLAGS)
|
||||
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell-base.la $(top_builddir)/src/libgnome-shell.la
|
||||
GTKDOC_LIBS=$(GNOME_SHELL_LIBS) $(top_builddir)/src/libgnome-shell-menu.la $(top_builddir)/src/libgnome-shell.la -rpath $(MUTTER_TYPELIB_DIR)
|
||||
|
||||
# This includes the standard gtk-doc make rules, copied by gtkdocize.
|
||||
include $(top_srcdir)/gtk-doc.make
|
||||
|
||||
# Other files to distribute
|
||||
# e.g. EXTRA_DIST += version.xml.in
|
||||
EXTRA_DIST +=
|
||||
EXTRA_DIST += version.xml.in
|
||||
|
||||
# Files not to distribute
|
||||
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
|
||||
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
|
||||
DISTCLEANFILES = $(DOC_MODULES).types
|
||||
DISTCLEANFILES = $(DOC_MODULE).types
|
||||
|
||||
# Comment this out if you want 'make check' to test you doc status
|
||||
# and run some sanity checks
|
||||
|
57
docs/reference/shell/meson.build
Normal file
57
docs/reference/shell/meson.build
Normal file
@ -0,0 +1,57 @@
|
||||
private_headers = [
|
||||
'gactionmuxer.h',
|
||||
'gactionobservable.h',
|
||||
'gactionobserver.h',
|
||||
'shell-network-agent.h',
|
||||
'shell-recorder-src.h'
|
||||
]
|
||||
|
||||
if not enable_recorder
|
||||
private_headers += 'shell-recorder.h'
|
||||
endif
|
||||
|
||||
exclude_directories = [
|
||||
'calendar-server',
|
||||
'hotplug-sniffer',
|
||||
'st',
|
||||
'tray'
|
||||
]
|
||||
|
||||
ifaces = [
|
||||
['org.gnome.Shell.Screenshot', 'org.gnome.Shell.Screenshot.xml'],
|
||||
['org.gnome.ShellSearchProvider', 'org.gnome.Shell.SearchProvider.xml'],
|
||||
['org.gnome.ShellSearchProvider2', 'org.gnome.Shell.SearchProvider2.xml']
|
||||
]
|
||||
foreach iface : ifaces
|
||||
custom_target(iface[0] + ' docs',
|
||||
input: '../../../data/@0@.xml'.format(iface[0]),
|
||||
output: 'doc-gen-' + iface[1],
|
||||
command: [
|
||||
'gdbus-codegen',
|
||||
'--interface-prefix=@0@.'.format(iface),
|
||||
'--generate-docbook', 'doc-gen',
|
||||
'--output-directory', '@OUTDIR@',
|
||||
'@INPUT@'
|
||||
],
|
||||
build_by_default: true
|
||||
)
|
||||
endforeach
|
||||
|
||||
configure_file(
|
||||
input: 'version.xml.in',
|
||||
output: 'version.xml',
|
||||
configuration: version_conf
|
||||
)
|
||||
|
||||
gnome.gtkdoc('shell',
|
||||
main_sgml: 'shell-docs.sgml',
|
||||
src_dir: [
|
||||
join_paths(meson.source_root(), 'src'),
|
||||
join_paths(meson.build_root(), 'src')
|
||||
],
|
||||
scan_args: [
|
||||
'--ignore-headers=' + ' '.join(private_headers + exclude_directories),
|
||||
'--rebuild-types'
|
||||
],
|
||||
install: true
|
||||
)
|
@ -3,12 +3,13 @@
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||
[
|
||||
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||||
<!ENTITY version SYSTEM "version.xml">
|
||||
]>
|
||||
<book id="index">
|
||||
<bookinfo>
|
||||
<title>Shell Reference Manual</title>
|
||||
<releaseinfo>
|
||||
for Shell @VERSION@.
|
||||
for Shell &version;.
|
||||
<!--The latest version of this documentation can be found on-line at
|
||||
<ulink role="online-location" url="http://[SERVER]/shell/index.html">http://[SERVER]/shell/</ulink>.-->
|
||||
</releaseinfo>
|
||||
@ -50,12 +51,16 @@
|
||||
<xi:include href="xml/shell-util.xml"/>
|
||||
<xi:include href="xml/shell-mount-operation.xml"/>
|
||||
<xi:include href="xml/shell-polkit-authentication-agent.xml"/>
|
||||
<xi:include href="xml/shell-tp-client.xml"/>
|
||||
</chapter>
|
||||
<!-- FIXME:
|
||||
Not generated at the moment, find out whether to blame gtk-doc or meson
|
||||
-->
|
||||
<!--
|
||||
<chapter id="object-tree">
|
||||
<title>Object Hierarchy</title>
|
||||
<xi:include href="xml/tree_index.sgml"/>
|
||||
</chapter>
|
||||
-->
|
||||
<index id="api-index-full">
|
||||
<title>API Index</title>
|
||||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
1
docs/reference/shell/version.xml.in
Normal file
1
docs/reference/shell/version.xml.in
Normal file
@ -0,0 +1 @@
|
||||
@VERSION@
|
@ -78,14 +78,14 @@ expand_content_files=
|
||||
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
|
||||
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
|
||||
GTKDOC_CFLAGS=
|
||||
GTKDOC_LIBS=$(top_builddir)/src/libst-1.0.la
|
||||
GTKDOC_LIBS=$(top_builddir)/src/libst-1.0.la -rpath $(MUTTER_TYPELIB_DIR)
|
||||
|
||||
# This includes the standard gtk-doc make rules, copied by gtkdocize.
|
||||
include $(top_srcdir)/gtk-doc.make
|
||||
|
||||
# Other files to distribute
|
||||
# e.g. EXTRA_DIST += version.xml.in
|
||||
EXTRA_DIST +=
|
||||
EXTRA_DIST += version.xml.in
|
||||
|
||||
# Files not to distribute
|
||||
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
|
||||
|
24
docs/reference/st/meson.build
Normal file
24
docs/reference/st/meson.build
Normal file
@ -0,0 +1,24 @@
|
||||
private_headers = [
|
||||
'st-private.h',
|
||||
'st-theme-node-private.h'
|
||||
]
|
||||
|
||||
configure_file(
|
||||
input: 'version.xml.in',
|
||||
output: 'version.xml',
|
||||
configuration: version_conf
|
||||
)
|
||||
|
||||
gnome.gtkdoc('st',
|
||||
main_sgml: 'st-docs.sgml',
|
||||
src_dir: [
|
||||
join_paths(meson.source_root(), 'src', 'st'),
|
||||
join_paths(meson.build_root(), 'src', 'st')
|
||||
],
|
||||
scan_args: [
|
||||
'--ignore-headers=' + ' '.join(private_headers),
|
||||
'--rebuild-sections',
|
||||
'--rebuild-types'
|
||||
],
|
||||
install: true
|
||||
)
|
@ -3,12 +3,13 @@
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||
[
|
||||
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||||
<!ENTITY version SYSTEM "version.xml">
|
||||
]>
|
||||
<book id="index">
|
||||
<bookinfo>
|
||||
<title>St Reference Manual</title>
|
||||
<releaseinfo>
|
||||
for St @VERSION@.
|
||||
for St &version;.
|
||||
<!--The latest version of this documentation can be found on-line at
|
||||
<ulink role="online-location" url="http://[SERVER]/st/index.html">http://[SERVER]/st/</ulink>.-->
|
||||
</releaseinfo>
|
||||
@ -46,10 +47,15 @@
|
||||
<xi:include href="xml/st-texture-cache.xml"/>
|
||||
</chapter>
|
||||
</part>
|
||||
<!-- FIXME:
|
||||
Not generated at the moment, find out whether to blame gtk-doc or meson
|
||||
-->
|
||||
<!--
|
||||
<chapter id="object-tree">
|
||||
<title>Object Hierarchy</title>
|
||||
<xi:include href="xml/tree_index.sgml"/>
|
||||
</chapter>
|
||||
-->
|
||||
<index id="api-index-full">
|
||||
<title>API Index</title>
|
||||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
1
docs/reference/st/version.xml.in
Normal file
1
docs/reference/st/version.xml.in
Normal file
@ -0,0 +1 @@
|
||||
@VERSION@
|
@ -11,6 +11,7 @@ misc/config.js: misc/config.js.in Makefile
|
||||
-e "s|[@]datadir@|$(datadir)|g" \
|
||||
-e "s|[@]libexecdir@|$(libexecdir)|g" \
|
||||
-e "s|[@]sysconfdir@|$(sysconfdir)|g" \
|
||||
-e "s|[@]LIBMUTTER_API_VERSION@|$(LIBMUTTER_API_VERSION)|g" \
|
||||
$< > $@
|
||||
|
||||
js_resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate-dependencies $(srcdir)/js-resources.gresource.xml)
|
||||
|
@ -5,6 +5,7 @@ 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 Format = imports.format;
|
||||
|
||||
@ -31,7 +32,7 @@ function stripPrefix(string, prefix) {
|
||||
return string;
|
||||
}
|
||||
|
||||
const Application = new Lang.Class({
|
||||
var Application = new Lang.Class({
|
||||
Name: 'Application',
|
||||
_init: function() {
|
||||
GLib.set_prgname('gnome-shell-extension-prefs');
|
||||
@ -92,9 +93,11 @@ const Application = new Lang.Class({
|
||||
widget = this._buildErrorUI(extension, e);
|
||||
}
|
||||
|
||||
let dialog = new Gtk.Dialog({ use_header_bar: true,
|
||||
modal: true,
|
||||
title: extension.metadata.name });
|
||||
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 }));
|
||||
|
||||
if (this._skipMainWindow) {
|
||||
this.application.add_window(dialog);
|
||||
@ -107,7 +110,7 @@ const Application = new Lang.Class({
|
||||
}
|
||||
|
||||
dialog.set_default_size(600, 400);
|
||||
dialog.get_content_area().add(widget);
|
||||
dialog.add(widget);
|
||||
dialog.show();
|
||||
},
|
||||
|
||||
@ -143,16 +146,21 @@ const Application = new Lang.Class({
|
||||
this._window = new Gtk.ApplicationWindow({ application: app,
|
||||
window_position: Gtk.WindowPosition.CENTER });
|
||||
|
||||
this._window.set_size_request(800, 500);
|
||||
this._window.set_default_size(800, 500);
|
||||
|
||||
this._titlebar = new Gtk.HeaderBar({ show_close_button: true,
|
||||
title: _("GNOME Shell Extensions") });
|
||||
title: _("Shell Extensions") });
|
||||
this._window.set_titlebar(this._titlebar);
|
||||
|
||||
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER,
|
||||
shadow_type: Gtk.ShadowType.IN,
|
||||
halign: Gtk.Align.CENTER,
|
||||
margin: 18 });
|
||||
let killSwitch = new Gtk.Switch({ valign: Gtk.Align.CENTER });
|
||||
this._titlebar.pack_end(killSwitch);
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
|
||||
this._settings.bind('disable-user-extensions', killSwitch, 'active',
|
||||
Gio.SettingsBindFlags.DEFAULT |
|
||||
Gio.SettingsBindFlags.INVERT_BOOLEAN);
|
||||
|
||||
let scroll = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
|
||||
this._window.add(scroll);
|
||||
|
||||
this._extensionSelector = new Gtk.ListBox({ selection_mode: Gtk.SelectionMode.NONE });
|
||||
@ -245,7 +253,19 @@ const Application = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const ExtensionRow = new Lang.Class({
|
||||
var DescriptionLabel = new Lang.Class({
|
||||
Name: 'DescriptionLabel',
|
||||
Extends: Gtk.Label,
|
||||
|
||||
vfunc_get_preferred_height_for_width: function(width) {
|
||||
// Hack: Request the maximum height allowed by the line limit
|
||||
if (this.lines > 0)
|
||||
return this.parent(0);
|
||||
return this.parent(width);
|
||||
}
|
||||
});
|
||||
|
||||
var ExtensionRow = new Lang.Class({
|
||||
Name: 'ExtensionRow',
|
||||
Extends: Gtk.ListBoxRow,
|
||||
|
||||
@ -263,6 +283,10 @@ const ExtensionRow = new Lang.Class({
|
||||
Lang.bind(this, function() {
|
||||
this._switch.sensitive = this._canEnable();
|
||||
}));
|
||||
this._settings.connect('changed::disable-user-extensions',
|
||||
Lang.bind(this, function() {
|
||||
this._switch.sensitive = this._canEnable();
|
||||
}));
|
||||
|
||||
this._buildUI();
|
||||
},
|
||||
@ -271,7 +295,8 @@ const ExtensionRow = new Lang.Class({
|
||||
let extension = ExtensionUtils.extensions[this.uuid];
|
||||
|
||||
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
|
||||
hexpand: true, margin: 12, spacing: 6 });
|
||||
hexpand: true, margin_end: 24, spacing: 24,
|
||||
margin: 12 });
|
||||
this.add(hbox);
|
||||
|
||||
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
|
||||
@ -285,9 +310,9 @@ const ExtensionRow = new Lang.Class({
|
||||
vbox.add(label);
|
||||
|
||||
let desc = extension.metadata.description.split('\n')[0];
|
||||
label = new Gtk.Label({ label: desc,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
halign: Gtk.Align.START });
|
||||
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,
|
||||
@ -318,7 +343,8 @@ const ExtensionRow = new Lang.Class({
|
||||
let extension = ExtensionUtils.extensions[this.uuid];
|
||||
let checkVersion = !this._settings.get_boolean('disable-extension-version-validation');
|
||||
|
||||
return !(checkVersion && ExtensionUtils.isOutOfDate(extension));
|
||||
return !this._settings.get_boolean('disable-user-extensions') &&
|
||||
!(checkVersion && ExtensionUtils.isOutOfDate(extension));
|
||||
},
|
||||
|
||||
_isEnabled: function() {
|
||||
|
@ -3,6 +3,7 @@
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
@ -14,30 +15,30 @@ const ShellEntry = imports.ui.shellEntry;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
|
||||
const DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
|
||||
const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
|
||||
const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3;
|
||||
var DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
|
||||
var DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
|
||||
var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3;
|
||||
|
||||
const MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5;
|
||||
var MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5;
|
||||
|
||||
const AuthPromptMode = {
|
||||
var AuthPromptMode = {
|
||||
UNLOCK_ONLY: 0,
|
||||
UNLOCK_OR_LOG_IN: 1
|
||||
};
|
||||
|
||||
const AuthPromptStatus = {
|
||||
var AuthPromptStatus = {
|
||||
NOT_VERIFYING: 0,
|
||||
VERIFYING: 1,
|
||||
VERIFICATION_FAILED: 2,
|
||||
VERIFICATION_SUCCEEDED: 3
|
||||
};
|
||||
|
||||
const BeginRequestType = {
|
||||
var BeginRequestType = {
|
||||
PROVIDE_USERNAME: 0,
|
||||
DONT_PROVIDE_USERNAME: 1
|
||||
};
|
||||
|
||||
const AuthPrompt = new Lang.Class({
|
||||
var AuthPrompt = new Lang.Class({
|
||||
Name: 'AuthPrompt',
|
||||
|
||||
_init: function(gdmClient, mode) {
|
||||
@ -113,6 +114,7 @@ const AuthPrompt = new Lang.Class({
|
||||
this._message = new St.Label({ opacity: 0,
|
||||
styleClass: 'login-dialog-message' });
|
||||
this._message.clutter_text.line_wrap = true;
|
||||
this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
|
||||
|
||||
this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',
|
||||
@ -186,7 +188,7 @@ const AuthPrompt = new Lang.Class({
|
||||
if (!this._userVerifier.hasPendingMessages)
|
||||
this._fadeOutMessage();
|
||||
|
||||
this._updateNextButtonSensitivity(this._entry.text.length > 0);
|
||||
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
|
||||
}));
|
||||
this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
|
||||
if (this.nextButton.reactive)
|
||||
@ -261,7 +263,7 @@ const AuthPrompt = new Lang.Class({
|
||||
_onVerificationComplete: function() {
|
||||
this.setActorInDefaultButtonWell(null);
|
||||
this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED;
|
||||
this.cancelButton.reactive = false;
|
||||
this.cancelButton.reactive = false;
|
||||
},
|
||||
|
||||
_onReset: function() {
|
||||
@ -414,7 +416,7 @@ const AuthPrompt = new Lang.Class({
|
||||
},
|
||||
|
||||
updateSensitivity: function(sensitive) {
|
||||
this._updateNextButtonSensitivity(sensitive && this._entry.text.length > 0);
|
||||
this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
|
||||
this._entry.reactive = sensitive;
|
||||
this._entry.clutter_text.editable = sensitive;
|
||||
},
|
||||
|
@ -47,7 +47,7 @@
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Task = new Lang.Class({
|
||||
var Task = new Lang.Class({
|
||||
Name: 'Task',
|
||||
|
||||
_init: function(scope, handler) {
|
||||
@ -68,7 +68,7 @@ const Task = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(Task.prototype);
|
||||
|
||||
const Hold = new Lang.Class({
|
||||
var Hold = new Lang.Class({
|
||||
Name: 'Hold',
|
||||
Extends: Task,
|
||||
|
||||
@ -110,7 +110,7 @@ const Hold = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(Hold.prototype);
|
||||
|
||||
const Batch = new Lang.Class({
|
||||
var Batch = new Lang.Class({
|
||||
Name: 'Batch',
|
||||
Extends: Task,
|
||||
|
||||
@ -185,7 +185,7 @@ const Batch = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(Batch.prototype);
|
||||
|
||||
const ConcurrentBatch = new Lang.Class({
|
||||
var ConcurrentBatch = new Lang.Class({
|
||||
Name: 'ConcurrentBatch',
|
||||
Extends: Batch,
|
||||
|
||||
@ -204,7 +204,7 @@ const ConcurrentBatch = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(ConcurrentBatch.prototype);
|
||||
|
||||
const ConsecutiveBatch = new Lang.Class({
|
||||
var ConsecutiveBatch = new Lang.Class({
|
||||
Name: 'ConsecutiveBatch',
|
||||
Extends: Batch,
|
||||
|
||||
|
@ -23,6 +23,12 @@ function FprintManager() {
|
||||
g_object_path: '/net/reactivated/Fprint/Manager',
|
||||
g_flags: (Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES) });
|
||||
|
||||
self.init(null);
|
||||
try {
|
||||
self.init(null);
|
||||
} catch(e) {
|
||||
log('Failed to connect to Fprint service: ' + e.message);
|
||||
return null;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
||||
const _LOGO_ICON_HEIGHT = 48;
|
||||
const _MAX_BOTTOM_MENU_ITEMS = 5;
|
||||
|
||||
const UserListItem = new Lang.Class({
|
||||
var UserListItem = new Lang.Class({
|
||||
Name: 'UserListItem',
|
||||
|
||||
_init: function(user) {
|
||||
@ -70,6 +70,16 @@ const UserListItem = new Lang.Class({
|
||||
this.actor.connect('destroy',
|
||||
Lang.bind(this, this._onDestroy));
|
||||
|
||||
this.actor.connect('key-focus-in', () => {
|
||||
this._setSelected(true);
|
||||
});
|
||||
this.actor.connect('key-focus-out', () => {
|
||||
this._setSelected(false);
|
||||
});
|
||||
this.actor.connect('notify::hover', () => {
|
||||
this._setSelected(this.actor.hover);
|
||||
});
|
||||
|
||||
this._userWidget = new UserWidget.UserWidget(this.user);
|
||||
layout.add(this._userWidget.actor);
|
||||
|
||||
@ -103,6 +113,15 @@ const UserListItem = new Lang.Class({
|
||||
this.emit('activate');
|
||||
},
|
||||
|
||||
_setSelected: function(selected) {
|
||||
if (selected) {
|
||||
this.actor.add_style_pseudo_class('selected');
|
||||
this.actor.grab_key_focus();
|
||||
} else {
|
||||
this.actor.remove_style_pseudo_class('selected');
|
||||
}
|
||||
},
|
||||
|
||||
showTimedLoginIndicator: function(time) {
|
||||
let hold = new Batch.Hold();
|
||||
|
||||
@ -126,7 +145,7 @@ const UserListItem = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(UserListItem.prototype);
|
||||
|
||||
const UserList = new Lang.Class({
|
||||
var UserList = new Lang.Class({
|
||||
Name: 'UserList',
|
||||
|
||||
_init: function() {
|
||||
@ -269,11 +288,15 @@ const UserList = new Lang.Class({
|
||||
|
||||
item.actor.destroy();
|
||||
delete this._items[userName];
|
||||
},
|
||||
|
||||
numItems: function() {
|
||||
return Object.keys(this._items).length;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(UserList.prototype);
|
||||
|
||||
const SessionMenuButton = new Lang.Class({
|
||||
var SessionMenuButton = new Lang.Class({
|
||||
Name: 'SessionMenuButton',
|
||||
|
||||
_init: function() {
|
||||
@ -379,7 +402,7 @@ const SessionMenuButton = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(SessionMenuButton.prototype);
|
||||
|
||||
const LoginDialog = new Lang.Class({
|
||||
var LoginDialog = new Lang.Class({
|
||||
Name: 'LoginDialog',
|
||||
|
||||
_init: function(parentActor) {
|
||||
@ -707,6 +730,10 @@ const LoginDialog = new Lang.Class({
|
||||
_updateDisableUserList: function() {
|
||||
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
|
||||
|
||||
// Disable user list when there are no users.
|
||||
if (this._userListLoaded && this._userList.numItems() == 0)
|
||||
disableUserList = true;
|
||||
|
||||
if (disableUserList != this._disableUserList) {
|
||||
this._disableUserList = disableUserList;
|
||||
|
||||
@ -775,10 +802,12 @@ const LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
_onPrompted: function() {
|
||||
this._sessionMenuButton.updateSensitivity(true);
|
||||
|
||||
if (this._shouldShowSessionMenuButton())
|
||||
if (this._shouldShowSessionMenuButton()) {
|
||||
this._sessionMenuButton.updateSensitivity(true);
|
||||
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor);
|
||||
} else {
|
||||
this._sessionMenuButton.updateSensitivity(false);
|
||||
}
|
||||
this._showPrompt();
|
||||
},
|
||||
|
||||
@ -804,6 +833,11 @@ const LoginDialog = new Lang.Class({
|
||||
|
||||
this._user = null;
|
||||
|
||||
if (this._nextSignalId) {
|
||||
this._authPrompt.disconnect(this._nextSignalId);
|
||||
this._nextSignalId = 0;
|
||||
}
|
||||
|
||||
if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
|
||||
if (!this._disableUserList)
|
||||
this._showUserList();
|
||||
@ -876,6 +910,7 @@ const LoginDialog = new Lang.Class({
|
||||
}));
|
||||
this._updateCancelButton();
|
||||
|
||||
this._sessionMenuButton.updateSensitivity(false);
|
||||
this._authPrompt.updateSensitivity(true);
|
||||
this._showPrompt();
|
||||
},
|
||||
@ -1170,14 +1205,18 @@ const LoginDialog = new Lang.Class({
|
||||
this._userList.addUser(users[i]);
|
||||
}
|
||||
|
||||
this._updateDisableUserList();
|
||||
|
||||
this._userAddedId = this._userManager.connect('user-added',
|
||||
Lang.bind(this, function(userManager, user) {
|
||||
this._userList.addUser(user);
|
||||
this._updateDisableUserList();
|
||||
}));
|
||||
|
||||
this._userRemovedId = this._userManager.connect('user-removed',
|
||||
Lang.bind(this, function(userManager, user) {
|
||||
this._userList.removeUser(user);
|
||||
this._updateDisableUserList();
|
||||
}));
|
||||
|
||||
this._userChangedId = this._userManager.connect('user-changed',
|
||||
@ -1186,6 +1225,7 @@ const LoginDialog = new Lang.Class({
|
||||
this._userList.removeUser(user);
|
||||
else if (!this._userList.containsUser(user) && !user.locked)
|
||||
this._userList.addUser(user);
|
||||
this._updateDisableUserList();
|
||||
}));
|
||||
|
||||
return GLib.SOURCE_REMOVE;
|
||||
@ -1220,7 +1260,7 @@ const LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
addCharacter: function(unichar) {
|
||||
this._authPrompt.addCharacter(unichar);
|
||||
// Don't allow type ahead at the login screen
|
||||
},
|
||||
|
||||
finish: function(onComplete) {
|
||||
|
@ -27,7 +27,7 @@ function OVirtCredentials() {
|
||||
return self;
|
||||
}
|
||||
|
||||
const OVirtCredentialsManager = new Lang.Class({
|
||||
var OVirtCredentialsManager = new Lang.Class({
|
||||
Name: 'OVirtCredentialsManager',
|
||||
_init: function() {
|
||||
this._token = null;
|
||||
|
@ -59,7 +59,7 @@ const RealmIface = '<node> \
|
||||
</node>';
|
||||
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
|
||||
|
||||
const Manager = new Lang.Class({
|
||||
var Manager = new Lang.Class({
|
||||
Name: 'Manager',
|
||||
|
||||
_init: function(parentActor) {
|
||||
|
@ -21,8 +21,8 @@ const PASSWORD_SERVICE_NAME = 'gdm-password';
|
||||
const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
||||
const SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
|
||||
const OVIRT_SERVICE_NAME = 'gdm-ovirtcred';
|
||||
const FADE_ANIMATION_TIME = 0.16;
|
||||
const CLONE_FADE_ANIMATION_TIME = 0.25;
|
||||
var FADE_ANIMATION_TIME = 0.16;
|
||||
var CLONE_FADE_ANIMATION_TIME = 0.25;
|
||||
|
||||
const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
|
||||
const PASSWORD_AUTHENTICATION_KEY = 'enable-password-authentication';
|
||||
@ -36,9 +36,9 @@ const LOGO_KEY = 'logo';
|
||||
const DISABLE_USER_LIST_KEY = 'disable-user-list';
|
||||
|
||||
// Give user 48ms to read each character of a PAM message
|
||||
const USER_READ_TIME = 48
|
||||
var USER_READ_TIME = 48
|
||||
|
||||
const MessageType = {
|
||||
var MessageType = {
|
||||
NONE: 0,
|
||||
ERROR: 1,
|
||||
INFO: 2,
|
||||
@ -119,7 +119,7 @@ function cloneAndFadeOutActor(actor) {
|
||||
return hold;
|
||||
}
|
||||
|
||||
const ShellUserVerifier = new Lang.Class({
|
||||
var ShellUserVerifier = new Lang.Class({
|
||||
Name: 'ShellUserVerifier',
|
||||
|
||||
_init: function(client, params) {
|
||||
@ -128,18 +128,22 @@ const ShellUserVerifier = new Lang.Class({
|
||||
|
||||
this._client = client;
|
||||
|
||||
this._defaultService = null;
|
||||
this._preemptingService = null;
|
||||
|
||||
this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA });
|
||||
this._settings.connect('changed',
|
||||
Lang.bind(this, this._updateDefaultService));
|
||||
this._updateDefaultService();
|
||||
|
||||
this._fprintManager = new Fprint.FprintManager();
|
||||
this._fprintManager = Fprint.FprintManager();
|
||||
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
||||
|
||||
// We check for smartcards right away, since an inserted smartcard
|
||||
// at startup should result in immediately initiating authentication.
|
||||
// This is different than fingeprint readers, where we only check them
|
||||
// This is different than fingerprint readers, where we only check them
|
||||
// after a user has been picked.
|
||||
this.smartcardDetected = false;
|
||||
this._checkForSmartcard();
|
||||
|
||||
this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted',
|
||||
@ -293,7 +297,8 @@ const ShellUserVerifier = new Lang.Class({
|
||||
_checkForFingerprintReader: function() {
|
||||
this._haveFingerprintReader = false;
|
||||
|
||||
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY)) {
|
||||
if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY) ||
|
||||
this._fprintManager == null) {
|
||||
this._updateDefaultService();
|
||||
return;
|
||||
}
|
||||
@ -539,7 +544,8 @@ const ShellUserVerifier = new Lang.Class({
|
||||
let signalId = this.connect('no-more-messages',
|
||||
Lang.bind(this, function() {
|
||||
this.disconnect(signalId);
|
||||
this._retry();
|
||||
if (this._cancellable && !this._cancellable.is_cancelled())
|
||||
this._retry();
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
|
@ -23,14 +23,17 @@
|
||||
<file>misc/modemManager.js</file>
|
||||
<file>misc/objectManager.js</file>
|
||||
<file>misc/params.js</file>
|
||||
<file>misc/permissionStore.js</file>
|
||||
<file>misc/smartcardManager.js</file>
|
||||
<file>misc/util.js</file>
|
||||
<file>misc/weather.js</file>
|
||||
|
||||
<file>perf/core.js</file>
|
||||
<file>perf/hwtest.js</file>
|
||||
|
||||
<file>portalHelper/main.js</file>
|
||||
|
||||
<file>ui/accessDialog.js</file>
|
||||
<file>ui/altTab.js</file>
|
||||
<file>ui/animation.js</file>
|
||||
<file>ui/appDisplay.js</file>
|
||||
@ -41,9 +44,11 @@
|
||||
<file>ui/boxpointer.js</file>
|
||||
<file>ui/calendar.js</file>
|
||||
<file>ui/checkBox.js</file>
|
||||
<file>ui/closeDialog.js</file>
|
||||
<file>ui/ctrlAltTab.js</file>
|
||||
<file>ui/dash.js</file>
|
||||
<file>ui/dateMenu.js</file>
|
||||
<file>ui/dialog.js</file>
|
||||
<file>ui/dnd.js</file>
|
||||
<file>ui/edgeDragAction.js</file>
|
||||
<file>ui/endSessionDialog.js</file>
|
||||
@ -71,6 +76,7 @@
|
||||
<file>ui/osdMonitorLabeler.js</file>
|
||||
<file>ui/overview.js</file>
|
||||
<file>ui/overviewControls.js</file>
|
||||
<file>ui/padOsd.js</file>
|
||||
<file>ui/panel.js</file>
|
||||
<file>ui/panelMenu.js</file>
|
||||
<file>ui/pointerWatcher.js</file>
|
||||
@ -83,7 +89,6 @@
|
||||
<file>ui/screenshot.js</file>
|
||||
<file>ui/scripting.js</file>
|
||||
<file>ui/search.js</file>
|
||||
<file>ui/separator.js</file>
|
||||
<file>ui/sessionMode.js</file>
|
||||
<file>ui/shellDBus.js</file>
|
||||
<file>ui/shellEntry.js</file>
|
||||
@ -115,6 +120,7 @@
|
||||
<file>ui/status/brightness.js</file>
|
||||
<file>ui/status/location.js</file>
|
||||
<file>ui/status/keyboard.js</file>
|
||||
<file>ui/status/nightLight.js</file>
|
||||
<file>ui/status/network.js</file>
|
||||
<file>ui/status/power.js</file>
|
||||
<file>ui/status/rfkill.js</file>
|
||||
|
8
js/meson.build
Normal file
8
js/meson.build
Normal file
@ -0,0 +1,8 @@
|
||||
subdir('misc')
|
||||
|
||||
js_resources = gnome.compile_resources(
|
||||
'js-resources', 'js-resources.gresource.xml',
|
||||
source_dir: ['.', meson.current_build_dir()],
|
||||
c_name: 'shell_js_resources',
|
||||
dependencies: [config_js]
|
||||
)
|
@ -1,17 +1,19 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
/* The name of this package (not localized) */
|
||||
const PACKAGE_NAME = '@PACKAGE_NAME@';
|
||||
var PACKAGE_NAME = '@PACKAGE_NAME@';
|
||||
/* The version of this package */
|
||||
const PACKAGE_VERSION = '@PACKAGE_VERSION@';
|
||||
var PACKAGE_VERSION = '@PACKAGE_VERSION@';
|
||||
/* 1 if gnome-bluetooth is available, 0 otherwise */
|
||||
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
|
||||
var HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
|
||||
/* 1 if networkmanager is available, 0 otherwise */
|
||||
const HAVE_NETWORKMANAGER = @HAVE_NETWORKMANAGER@;
|
||||
var HAVE_NETWORKMANAGER = @HAVE_NETWORKMANAGER@;
|
||||
/* gettext package */
|
||||
const GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@';
|
||||
var GETTEXT_PACKAGE = '@GETTEXT_PACKAGE@';
|
||||
/* locale dir */
|
||||
const LOCALEDIR = '@datadir@/locale';
|
||||
var LOCALEDIR = '@datadir@/locale';
|
||||
/* other standard directories */
|
||||
const LIBEXECDIR = '@libexecdir@';
|
||||
const SYSCONFDIR = '@sysconfdir@';
|
||||
var LIBEXECDIR = '@libexecdir@';
|
||||
var SYSCONFDIR = '@sysconfdir@';
|
||||
/* g-i package versions */
|
||||
var LIBMUTTER_API_VERSION = '@LIBMUTTER_API_VERSION@'
|
||||
|
@ -6,29 +6,38 @@
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const ShellJS = imports.gi.ShellJS;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const FileUtils = imports.misc.fileUtils;
|
||||
|
||||
const ExtensionType = {
|
||||
var ExtensionType = {
|
||||
SYSTEM: 1,
|
||||
PER_USER: 2
|
||||
};
|
||||
|
||||
// Maps uuid -> metadata object
|
||||
const extensions = {};
|
||||
var extensions = {};
|
||||
|
||||
/**
|
||||
* getCurrentExtension:
|
||||
*
|
||||
* Returns the current extension, or null if not called from an extension.
|
||||
*/
|
||||
function getCurrentExtension() {
|
||||
let stack = (new Error()).stack;
|
||||
let stack = (new Error()).stack.split('\n');
|
||||
let extensionStackLine;
|
||||
|
||||
// Assuming we're importing this directly from an extension (and we shouldn't
|
||||
// ever not be), its UUID should be directly in the path here.
|
||||
let extensionStackLine = stack.split('\n')[1];
|
||||
// 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) {
|
||||
extensionStackLine = stack[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!extensionStackLine)
|
||||
throw new Error('Could not find current extension');
|
||||
return null;
|
||||
|
||||
// The stack line is like:
|
||||
// init([object Object])@/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8
|
||||
@ -38,7 +47,7 @@ function getCurrentExtension() {
|
||||
// @/home/user/data/gnome-shell/extensions/u@u.id/prefs.js:8
|
||||
let match = new RegExp('@(.+):\\d+').exec(extensionStackLine);
|
||||
if (!match)
|
||||
throw new Error('Could not find current extension');
|
||||
return null;
|
||||
|
||||
let path = match[1];
|
||||
let file = Gio.File.new_for_path(path);
|
||||
@ -52,7 +61,7 @@ function getCurrentExtension() {
|
||||
file = file.get_parent();
|
||||
}
|
||||
|
||||
throw new Error('Could not find current extension');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,15 +149,16 @@ function createExtensionObject(uuid, dir, type) {
|
||||
return extension;
|
||||
}
|
||||
|
||||
var _extension = null;
|
||||
|
||||
function installImporter(extension) {
|
||||
_extension = extension;
|
||||
ShellJS.add_extension_importer('imports.misc.extensionUtils._extension', 'imports', extension.path);
|
||||
_extension = null;
|
||||
let oldSearchPath = imports.searchPath.slice(); // make a copy
|
||||
imports.searchPath = [extension.dir.get_parent().get_path()];
|
||||
// importing a "subdir" creates a new importer object that doesn't affect
|
||||
// the global one
|
||||
extension.imports = imports[extension.uuid];
|
||||
imports.searchPath = oldSearchPath;
|
||||
}
|
||||
|
||||
const ExtensionFinder = new Lang.Class({
|
||||
var ExtensionFinder = new Lang.Class({
|
||||
Name: 'ExtensionFinder',
|
||||
|
||||
_loadExtension: function(extensionDir, info, perUserDir) {
|
||||
|
@ -16,7 +16,7 @@ const PresenceIface = '<node> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const PresenceStatus = {
|
||||
var PresenceStatus = {
|
||||
AVAILABLE: 0,
|
||||
INVISIBLE: 1,
|
||||
BUSY: 2,
|
||||
|
@ -5,9 +5,9 @@ const Signals = imports.signals;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Params = imports.misc.params;
|
||||
|
||||
const DEFAULT_LIMIT = 512;
|
||||
var DEFAULT_LIMIT = 512;
|
||||
|
||||
const HistoryManager = new Lang.Class({
|
||||
var HistoryManager = new Lang.Class({
|
||||
Name: 'HistoryManager',
|
||||
|
||||
_init: function(params) {
|
||||
@ -69,7 +69,7 @@ const HistoryManager = new Lang.Class({
|
||||
this._indexChanged();
|
||||
}
|
||||
|
||||
return this._historyIndex[this._history.length];
|
||||
return this._historyIndex ? this._history[this._historyIndex -1] : null;
|
||||
},
|
||||
|
||||
addItem: function(input) {
|
||||
|
@ -6,10 +6,11 @@ const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Signals = imports.signals;
|
||||
|
||||
let IBusCandidatePopup;
|
||||
try {
|
||||
var IBus = imports.gi.IBus;
|
||||
_checkIBusVersion(1, 5, 2);
|
||||
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
|
||||
IBusCandidatePopup = imports.ui.ibusCandidatePopup;
|
||||
} catch (e) {
|
||||
var IBus = null;
|
||||
log(e);
|
||||
@ -35,7 +36,7 @@ function getIBusManager() {
|
||||
return _ibusManager;
|
||||
}
|
||||
|
||||
const IBusManager = new Lang.Class({
|
||||
var IBusManager = new Lang.Class({
|
||||
Name: 'IBusManager',
|
||||
|
||||
// This is the longest we'll keep the keyboard frozen until an input
|
||||
@ -189,7 +190,7 @@ const IBusManager = new Lang.Class({
|
||||
},
|
||||
|
||||
getEngineDesc: function(id) {
|
||||
if (!IBus || !this._ready)
|
||||
if (!IBus || !this._ready || !this._engines.hasOwnProperty(id))
|
||||
return null;
|
||||
|
||||
return this._engines[id];
|
||||
|
@ -7,9 +7,9 @@ const Meta = imports.gi.Meta;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const DEFAULT_LOCALE = 'en_US';
|
||||
const DEFAULT_LAYOUT = 'us';
|
||||
const DEFAULT_VARIANT = '';
|
||||
var DEFAULT_LOCALE = 'en_US';
|
||||
var DEFAULT_LAYOUT = 'us';
|
||||
var DEFAULT_VARIANT = '';
|
||||
|
||||
let _xkbInfo = null;
|
||||
|
||||
@ -38,7 +38,7 @@ function holdKeyboard() {
|
||||
global.display.freeze_keyboard(global.get_current_time());
|
||||
}
|
||||
|
||||
const KeyboardManager = new Lang.Class({
|
||||
var KeyboardManager = new Lang.Class({
|
||||
Name: 'KeyboardManager',
|
||||
|
||||
// The XKB protocol doesn't allow for more that 4 layouts in a
|
||||
@ -128,7 +128,8 @@ const KeyboardManager = new Lang.Class({
|
||||
if (!found)
|
||||
[, , id] = GnomeDesktop.get_input_source_from_locale(DEFAULT_LOCALE);
|
||||
|
||||
let [found, , , _layout, _variant] = this._xkbInfo.get_layout_info(id);
|
||||
let _layout, _variant;
|
||||
[found, , , _layout, _variant] = this._xkbInfo.get_layout_info(id);
|
||||
if (found)
|
||||
return { layout: _layout, variant: _variant };
|
||||
else
|
||||
|
@ -40,6 +40,9 @@ const SystemdLoginSessionIface = '<node> \
|
||||
<signal name="Lock" /> \
|
||||
<signal name="Unlock" /> \
|
||||
<property name="Active" type="b" access="read" /> \
|
||||
<method name="SetLockedHint"> \
|
||||
<arg type="b" direction="in"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
@ -99,7 +102,7 @@ function getLoginManager() {
|
||||
return _loginManager;
|
||||
}
|
||||
|
||||
const LoginManagerSystemd = new Lang.Class({
|
||||
var LoginManagerSystemd = new Lang.Class({
|
||||
Name: 'LoginManagerSystemd',
|
||||
|
||||
_init: function() {
|
||||
@ -131,10 +134,13 @@ const LoginManagerSystemd = new Lang.Class({
|
||||
|
||||
canSuspend: function(asyncCallback) {
|
||||
this._proxy.CanSuspendRemote(function(result, error) {
|
||||
if (error)
|
||||
asyncCallback(false);
|
||||
else
|
||||
asyncCallback(result[0] != 'no' && result[0] != 'na');
|
||||
if (error) {
|
||||
asyncCallback(false, false);
|
||||
} else {
|
||||
let needsAuth = result[0] == 'challenge';
|
||||
let canSuspend = needsAuth || result[0] == 'yes';
|
||||
asyncCallback(canSuspend, needsAuth);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@ -177,7 +183,7 @@ const LoginManagerSystemd = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(LoginManagerSystemd.prototype);
|
||||
|
||||
const LoginManagerDummy = new Lang.Class({
|
||||
var LoginManagerDummy = new Lang.Class({
|
||||
Name: 'LoginManagerDummy',
|
||||
|
||||
getCurrentSessionProxy: function(callback) {
|
||||
@ -187,7 +193,7 @@ const LoginManagerDummy = new Lang.Class({
|
||||
},
|
||||
|
||||
canSuspend: function(asyncCallback) {
|
||||
asyncCallback(false);
|
||||
asyncCallback(false, false);
|
||||
},
|
||||
|
||||
listSessions: function(asyncCallback) {
|
||||
|
16
js/misc/meson.build
Normal file
16
js/misc/meson.build
Normal file
@ -0,0 +1,16 @@
|
||||
jsconf = configuration_data()
|
||||
jsconf.set('PACKAGE_NAME', meson.project_name())
|
||||
jsconf.set('PACKAGE_VERSION', meson.project_version())
|
||||
jsconf.set('GETTEXT_PACKAGE', meson.project_name())
|
||||
jsconf.set('LIBMUTTER_API_VERSION', mutter_api_version)
|
||||
jsconf.set10('HAVE_BLUETOOTH', bt_dep.found())
|
||||
jsconf.set10('HAVE_NETWORKMANAGER', have_networkmanager)
|
||||
jsconf.set('datadir', datadir)
|
||||
jsconf.set('libexecdir', libexecdir)
|
||||
jsconf.set('sysconfdir', sysconfdir)
|
||||
|
||||
config_js = configure_file(
|
||||
input: 'config.js.in',
|
||||
output: 'config.js',
|
||||
configuration: jsconf
|
||||
)
|
@ -130,7 +130,7 @@ const ModemCdmaInterface = '<node> \
|
||||
|
||||
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
|
||||
|
||||
const ModemGsm = new Lang.Class({
|
||||
var ModemGsm = new Lang.Class({
|
||||
Name: 'ModemGsm',
|
||||
|
||||
_init: function(path) {
|
||||
@ -172,7 +172,7 @@ const ModemGsm = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(ModemGsm.prototype);
|
||||
|
||||
const ModemCdma = new Lang.Class({
|
||||
var ModemCdma = new Lang.Class({
|
||||
Name: 'ModemCdma',
|
||||
|
||||
_init: function(path) {
|
||||
@ -244,7 +244,7 @@ const BroadbandModemCdmaInterface = '<node> \
|
||||
</node>';
|
||||
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
|
||||
|
||||
const BroadbandModem = new Lang.Class({
|
||||
var BroadbandModem = new Lang.Class({
|
||||
Name: 'BroadbandModem',
|
||||
|
||||
_init: function(path, capabilities) {
|
||||
|
@ -26,7 +26,7 @@ const ObjectManagerIface = '<node> \
|
||||
|
||||
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
|
||||
|
||||
const ObjectManager = new Lang.Class({
|
||||
var ObjectManager = new Lang.Class({
|
||||
Name: 'ObjectManager',
|
||||
_init: function(params) {
|
||||
params = Params.parse(params, { connection: null,
|
||||
@ -46,7 +46,7 @@ const ObjectManager = new Lang.Class({
|
||||
g_interface_info: ObjectManagerInfo,
|
||||
g_name: this._serviceName,
|
||||
g_object_path: this._managerPath,
|
||||
g_flags: Gio.DBusProxyFlags.NONE });
|
||||
g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START });
|
||||
|
||||
this._interfaceInfos = {};
|
||||
this._objects = {};
|
||||
@ -65,6 +65,9 @@ const ObjectManager = new Lang.Class({
|
||||
},
|
||||
|
||||
_tryToCompleteLoad: function() {
|
||||
if (this._numLoadInhibitors == 0)
|
||||
return;
|
||||
|
||||
this._numLoadInhibitors--;
|
||||
if (this._numLoadInhibitors == 0) {
|
||||
if (this._onLoaded)
|
||||
@ -86,7 +89,7 @@ const ObjectManager = new Lang.Class({
|
||||
g_object_path: objectPath,
|
||||
g_interface_name: interfaceName,
|
||||
g_interface_info: info,
|
||||
g_flags: Gio.DBusProxyFlags.NONE });
|
||||
g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START });
|
||||
|
||||
proxy.init_async(GLib.PRIORITY_DEFAULT,
|
||||
this._cancellable,
|
||||
@ -181,6 +184,18 @@ const ObjectManager = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
this._managerProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
|
||||
if (this._managerProxy.g_name_owner)
|
||||
this._onNameAppeared();
|
||||
else
|
||||
this._onNameVanished();
|
||||
}));
|
||||
|
||||
if (this._managerProxy.g_name_owner)
|
||||
this._onNameAppeared();
|
||||
},
|
||||
|
||||
_onNameAppeared: function() {
|
||||
this._managerProxy.GetManagedObjectsRemote(Lang.bind(this, function(result, error) {
|
||||
if (!result) {
|
||||
if (error) {
|
||||
@ -193,6 +208,11 @@ const ObjectManager = new Lang.Class({
|
||||
|
||||
let [objects] = result;
|
||||
|
||||
if (!objects) {
|
||||
this._tryToCompleteLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
let objectPaths = Object.keys(objects);
|
||||
for (let i = 0; i < objectPaths.length; i++) {
|
||||
let objectPath = objectPaths[i];
|
||||
@ -213,6 +233,21 @@ const ObjectManager = new Lang.Class({
|
||||
}));
|
||||
},
|
||||
|
||||
_onNameVanished: function() {
|
||||
let objectPaths = Object.keys(this._objects);
|
||||
for (let i = 0; i < objectPaths.length; i++) {
|
||||
let object = this._objects[objectPaths];
|
||||
|
||||
let interfaceNames = Object.keys(object);
|
||||
for (let j = 0; i < interfaceNames.length; i++) {
|
||||
let interfaceName = interfaceNames[i];
|
||||
|
||||
if (object[interfaceName])
|
||||
this._removeInterface(objectPath, interfaceName);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_registerInterfaces: function(interfaces) {
|
||||
for (let i = 0; i < interfaces.length; i++) {
|
||||
let info = Gio.DBusInterfaceInfo.new_for_xml(interfaces[i]);
|
||||
|
37
js/misc/permissionStore.js
Normal file
37
js/misc/permissionStore.js
Normal file
@ -0,0 +1,37 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
|
||||
const PermissionStoreIface = '<node> \
|
||||
<interface name="org.freedesktop.impl.portal.PermissionStore"> \
|
||||
<method name="Lookup"> \
|
||||
<arg name="table" type="s" direction="in"/> \
|
||||
<arg name="id" type="s" direction="in"/> \
|
||||
<arg name="permissions" type="a{sas}" direction="out"/> \
|
||||
<arg name="data" type="v" direction="out"/> \
|
||||
</method> \
|
||||
<method name="Set"> \
|
||||
<arg name="table" type="s" direction="in"/> \
|
||||
<arg name="create" type="b" direction="in"/> \
|
||||
<arg name="id" type="s" direction="in"/> \
|
||||
<arg name="app_permissions" type="a{sas}" direction="in"/> \
|
||||
<arg name="data" type="v" direction="in"/> \
|
||||
</method> \
|
||||
<signal name="Changed"> \
|
||||
<arg name="table" type="s" direction="out"/> \
|
||||
<arg name="id" type="s" direction="out"/> \
|
||||
<arg name="deleted" type="b" direction="out"/> \
|
||||
<arg name="data" type="v" direction="out"/> \
|
||||
<arg name="permissions" type="a{sas}" direction="out"/> \
|
||||
</signal> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const PermissionStoreProxy = Gio.DBusProxy.makeProxyWrapper(PermissionStoreIface);
|
||||
|
||||
function PermissionStore(initCallback, cancellable) {
|
||||
return new PermissionStoreProxy(Gio.DBus.session,
|
||||
'org.freedesktop.impl.portal.PermissionStore',
|
||||
'/org/freedesktop/impl/portal/PermissionStore',
|
||||
initCallback, cancellable);
|
||||
};
|
@ -25,7 +25,7 @@ function getSmartcardManager() {
|
||||
return _smartcardManager;
|
||||
}
|
||||
|
||||
const SmartcardManager = new Lang.Class({
|
||||
var SmartcardManager = new Lang.Class({
|
||||
Name: 'SmartcardManager',
|
||||
_init: function() {
|
||||
this._objectManager = new ObjectManager.ObjectManager({ connection: Gio.DBus.session,
|
||||
|
141
js/misc/util.js
141
js/misc/util.js
@ -1,9 +1,12 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
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;
|
||||
|
||||
@ -11,7 +14,7 @@ const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Params = imports.misc.params;
|
||||
|
||||
const SCROLL_TIME = 0.1;
|
||||
var SCROLL_TIME = 0.1;
|
||||
|
||||
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
|
||||
@ -161,6 +164,41 @@ function _handleSpawnError(command, err) {
|
||||
Main.notifyError(title, err.message);
|
||||
}
|
||||
|
||||
function formatTimeSpan(date) {
|
||||
let now = GLib.DateTime.new_now_local();
|
||||
|
||||
let timespan = now.difference(date);
|
||||
|
||||
let minutesAgo = timespan / GLib.TIME_SPAN_MINUTE;
|
||||
let hoursAgo = timespan / GLib.TIME_SPAN_HOUR;
|
||||
let daysAgo = timespan / GLib.TIME_SPAN_DAY;
|
||||
let weeksAgo = daysAgo / 7;
|
||||
let monthsAgo = daysAgo / 30;
|
||||
let yearsAgo = weeksAgo / 52;
|
||||
|
||||
if (minutesAgo < 5)
|
||||
return _("Just now");
|
||||
if (hoursAgo < 1)
|
||||
return Gettext.ngettext("%d minute ago",
|
||||
"%d minutes ago", minutesAgo).format(minutesAgo);
|
||||
if (daysAgo < 1)
|
||||
return Gettext.ngettext("%d hour ago",
|
||||
"%d hours ago", hoursAgo).format(hoursAgo);
|
||||
if (daysAgo < 2)
|
||||
return _("Yesterday");
|
||||
if (daysAgo < 15)
|
||||
return Gettext.ngettext("%d day ago",
|
||||
"%d days ago", daysAgo).format(daysAgo);
|
||||
if (weeksAgo < 8)
|
||||
return Gettext.ngettext("%d week ago",
|
||||
"%d weeks ago", weeksAgo).format(weeksAgo);
|
||||
if (yearsAgo < 1)
|
||||
return Gettext.ngettext("%d month ago",
|
||||
"%d months ago", monthsAgo).format(monthsAgo);
|
||||
return Gettext.ngettext("%d year ago",
|
||||
"%d years ago", yearsAgo).format(yearsAgo);
|
||||
}
|
||||
|
||||
function formatTime(time, params) {
|
||||
let date;
|
||||
// HACK: The built-in Date type sucks at timezones, which we need for the
|
||||
@ -180,11 +218,10 @@ function formatTime(time, params) {
|
||||
if (_desktopSettings == null)
|
||||
_desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
|
||||
let clockFormat = _desktopSettings.get_string('clock-format');
|
||||
let hasAmPm = date.format('%p') != '';
|
||||
|
||||
params = Params.parse(params, { timeOnly: false });
|
||||
|
||||
if (clockFormat == '24h' || !hasAmPm) {
|
||||
if (clockFormat == '24h') {
|
||||
// Show only the time if date is on today
|
||||
if (daysAgo < 1 || params.timeOnly)
|
||||
/* Translators: Time in 24h format */
|
||||
@ -243,7 +280,10 @@ function formatTime(time, params) {
|
||||
// xgettext:no-c-format
|
||||
format = N_("%B %d %Y, %l\u2236%M %p");
|
||||
}
|
||||
return date.format(Shell.util_translate_time_string(format));
|
||||
|
||||
let formattedTime = date.format(Shell.util_translate_time_string(format));
|
||||
// prepend LTR-mark to colon/ratio to force a text direction on times
|
||||
return formattedTime.replace(/([:\u2236])/g, '\u200e$1');
|
||||
}
|
||||
|
||||
function createTimeLabel(date, params) {
|
||||
@ -310,7 +350,7 @@ function insertSorted(array, val, cmp) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
const CloseButton = new Lang.Class({
|
||||
var CloseButton = new Lang.Class({
|
||||
Name: 'CloseButton',
|
||||
Extends: St.Button,
|
||||
|
||||
@ -398,3 +438,94 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
time: SCROLL_TIME,
|
||||
transition: 'easeOutQuad' });
|
||||
}
|
||||
|
||||
var AppSettingsMonitor = new Lang.Class({
|
||||
Name: 'AppSettingsMonitor',
|
||||
|
||||
_init: function(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',
|
||||
Lang.bind(this, this._onInstalledChanged));
|
||||
this._onInstalledChanged();
|
||||
},
|
||||
|
||||
get available() {
|
||||
return this._app != null && this._settings != null;
|
||||
},
|
||||
|
||||
activateApp: function() {
|
||||
if (this._app)
|
||||
this._app.activate();
|
||||
},
|
||||
|
||||
watchSetting: function(key, callback) {
|
||||
let handler = { id: 0, key: key, callback: callback };
|
||||
this._handlers.push(handler);
|
||||
|
||||
this._connectHandler(handler);
|
||||
},
|
||||
|
||||
_connectHandler: function(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: function(handler) {
|
||||
if (this._settings && handler.id > 0)
|
||||
this._settings.disconnect(handler.id);
|
||||
handler.id = 0;
|
||||
},
|
||||
|
||||
_onInstalledChanged: function() {
|
||||
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: function(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: function() {
|
||||
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);
|
||||
|
247
js/misc/weather.js
Normal file
247
js/misc/weather.js
Normal file
@ -0,0 +1,247 @@
|
||||
// -*- 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 Signals = imports.signals;
|
||||
|
||||
const PermissionStore = imports.misc.permissionStore;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
// Minimum time between updates to show loading indication
|
||||
var UPDATE_THRESHOLD = 10 * GLib.TIME_SPAN_MINUTE;
|
||||
|
||||
var WeatherClient = new Lang.Class({
|
||||
Name: 'WeatherClient',
|
||||
|
||||
_init: function() {
|
||||
this._loading = false;
|
||||
this._locationValid = false;
|
||||
this._lastUpdate = GLib.DateTime.new_from_unix_local(0);
|
||||
|
||||
this._autoLocationRequested = false;
|
||||
this._mostRecentLocation = null;
|
||||
|
||||
this._gclueService = null;
|
||||
this._gclueStarted = false;
|
||||
this._gclueStarting = false;
|
||||
this._gclueLocationChangedId = 0;
|
||||
|
||||
this._weatherAuthorized = false;
|
||||
this._permStore = new PermissionStore.PermissionStore((proxy, error) => {
|
||||
if (error) {
|
||||
log('Failed to connect to permissionStore: ' + error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
this._permStore.LookupRemote('gnome', 'geolocation', (res, error) => {
|
||||
if (error)
|
||||
log('Error looking up permission: ' + error.message);
|
||||
|
||||
let [perms, data] = error ? [{}, null] : res;
|
||||
let params = ['gnome', 'geolocation', false, data, perms];
|
||||
this._onPermStoreChanged(this._permStore, '', params);
|
||||
});
|
||||
});
|
||||
this._permStore.connectSignal('Changed',
|
||||
Lang.bind(this, this._onPermStoreChanged));
|
||||
|
||||
this._locationSettings = new Gio.Settings({ schema_id: 'org.gnome.system.location' });
|
||||
this._locationSettings.connect('changed::enabled',
|
||||
Lang.bind(this, this._updateAutoLocation));
|
||||
|
||||
this._world = GWeather.Location.get_world();
|
||||
|
||||
this._providers = GWeather.Provider.METAR |
|
||||
GWeather.Provider.YR_NO |
|
||||
GWeather.Provider.OWM;
|
||||
|
||||
this._weatherInfo = new GWeather.Info({ enabled_providers: 0 });
|
||||
this._weatherInfo.connect_after('updated', () => {
|
||||
this._lastUpdate = GLib.DateTime.new_now_local();
|
||||
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',
|
||||
Lang.bind(this, this._onAutomaticLocationChanged));
|
||||
this._weatherAppMon.watchSetting('locations',
|
||||
Lang.bind(this, this._onLocationsChanged));
|
||||
},
|
||||
|
||||
get available() {
|
||||
return this._weatherAppMon.available;
|
||||
},
|
||||
|
||||
get loading() {
|
||||
return this._loading;
|
||||
},
|
||||
|
||||
get hasLocation() {
|
||||
return this._locationValid;
|
||||
},
|
||||
|
||||
get info() {
|
||||
return this._weatherInfo;
|
||||
},
|
||||
|
||||
activateApp: function() {
|
||||
this._weatherAppMon.activateApp();
|
||||
},
|
||||
|
||||
update: function() {
|
||||
if (!this._locationValid)
|
||||
return;
|
||||
|
||||
let now = GLib.DateTime.new_now_local();
|
||||
// Update without loading indication if the current info is recent enough
|
||||
if (this._weatherInfo.is_valid() &&
|
||||
now.difference(this._lastUpdate) < UPDATE_THRESHOLD)
|
||||
this._weatherInfo.update();
|
||||
else
|
||||
this._loadInfo();
|
||||
},
|
||||
|
||||
get _useAutoLocation() {
|
||||
return this._autoLocationRequested &&
|
||||
this._locationSettings.get_boolean('enabled') &&
|
||||
this._weatherAuthorized;
|
||||
},
|
||||
|
||||
_loadInfo: function() {
|
||||
let id = this._weatherInfo.connect('updated', () => {
|
||||
this._weatherInfo.disconnect(id);
|
||||
this._loading = false;
|
||||
});
|
||||
|
||||
this._loading = true;
|
||||
this.emit('changed');
|
||||
|
||||
this._weatherInfo.update();
|
||||
},
|
||||
|
||||
_locationsEqual: function(loc1, loc2) {
|
||||
if (loc1 == loc2)
|
||||
return true;
|
||||
|
||||
if (loc1 == null || loc2 == null)
|
||||
return false;
|
||||
|
||||
return loc1.equal(loc2);
|
||||
},
|
||||
|
||||
_setLocation: function(location) {
|
||||
if (this._locationsEqual(this._weatherInfo.location, location))
|
||||
return;
|
||||
|
||||
this._weatherInfo.abort();
|
||||
this._weatherInfo.set_location(location);
|
||||
this._locationValid = (location != null);
|
||||
|
||||
this._weatherInfo.set_enabled_providers(location ? this._providers : 0);
|
||||
|
||||
if (location)
|
||||
this._loadInfo();
|
||||
else
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
_updateLocationMonitoring: function() {
|
||||
if (this._useAutoLocation) {
|
||||
if (this._gclueLocationChangedId != 0 || this._gclueService == null)
|
||||
return;
|
||||
|
||||
this._gclueLocationChangedId =
|
||||
this._gclueService.connect('notify::location',
|
||||
Lang.bind(this, this._onGClueLocationChanged));
|
||||
this._onGClueLocationChanged();
|
||||
} else {
|
||||
if (this._gclueLocationChangedId)
|
||||
this._gclueService.disconnect(this._gclueLocationChangedId);
|
||||
this._gclueLocationChangedId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_startGClueService: function() {
|
||||
if (this._gclueStarting)
|
||||
return;
|
||||
|
||||
this._gclueStarting = true;
|
||||
|
||||
Geoclue.Simple.new('org.gnome.Shell', Geoclue.AccuracyLevel.CITY, null,
|
||||
(o, res) => {
|
||||
try {
|
||||
this._gclueService = Geoclue.Simple.new_finish(res);
|
||||
} catch(e) {
|
||||
log('Failed to connect to Geoclue2 service: ' + e.message);
|
||||
this._setLocation(this._mostRecentLocation);
|
||||
return;
|
||||
}
|
||||
this._gclueStarted = true;
|
||||
this._gclueService.get_client().distance_threshold = 100;
|
||||
this._updateLocationMonitoring();
|
||||
});
|
||||
},
|
||||
|
||||
_onGClueLocationChanged: function() {
|
||||
let geoLocation = this._gclueService.location;
|
||||
let location = GWeather.Location.new_detached(geoLocation.description,
|
||||
null,
|
||||
geoLocation.latitude,
|
||||
geoLocation.longitude);
|
||||
this._setLocation(location);
|
||||
},
|
||||
|
||||
_onAutomaticLocationChanged: function(settings, key) {
|
||||
let useAutoLocation = settings.get_boolean(key);
|
||||
if (this._autoLocationRequested == useAutoLocation)
|
||||
return;
|
||||
|
||||
this._autoLocationRequested = useAutoLocation;
|
||||
|
||||
this._updateAutoLocation();
|
||||
},
|
||||
|
||||
_updateAutoLocation: function() {
|
||||
this._updateLocationMonitoring();
|
||||
|
||||
if (this._useAutoLocation)
|
||||
this._startGClueService();
|
||||
else
|
||||
this._setLocation(this._mostRecentLocation);
|
||||
},
|
||||
|
||||
_onLocationsChanged: function(settings, key) {
|
||||
let serialized = settings.get_value(key).deep_unpack().shift();
|
||||
let mostRecentLocation = null;
|
||||
|
||||
if (serialized)
|
||||
mostRecentLocation = this._world.deserialize(serialized);
|
||||
|
||||
if (this._locationsEqual(this._mostRecentLocation, mostRecentLocation))
|
||||
return;
|
||||
|
||||
this._mostRecentLocation = mostRecentLocation;
|
||||
|
||||
if (!this._useAutoLocation || !this._gclueStarted)
|
||||
this._setLocation(this._mostRecentLocation);
|
||||
},
|
||||
|
||||
_onPermStoreChanged: function(proxy, sender, params) {
|
||||
let [table, id, deleted, data, perms] = params;
|
||||
|
||||
if (table != 'gnome' || id != 'geolocation')
|
||||
return;
|
||||
|
||||
let permission = perms['org.gnome.Weather.Application'] || ['NONE'];
|
||||
let [accuracy] = permission;
|
||||
this._weatherAuthorized = accuracy != 'NONE';
|
||||
|
||||
this._updateAutoLocation();
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(WeatherClient.prototype);
|
@ -19,7 +19,15 @@ const PortalHelperResult = {
|
||||
RECHECK: 2
|
||||
};
|
||||
|
||||
const PortalHelperSecurityLevel = {
|
||||
NOT_YET_DETERMINED: 0,
|
||||
SECURE: 1,
|
||||
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 = '<node> \
|
||||
@ -42,15 +50,86 @@ const HelperDBusInterface = '<node> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const PortalWindow = new Lang.Class({
|
||||
var PortalHeaderBar = new Lang.Class({
|
||||
Name: 'PortalHeaderBar',
|
||||
Extends: Gtk.HeaderBar,
|
||||
|
||||
_init: function() {
|
||||
this.parent({ show_close_button: true });
|
||||
|
||||
// See ephy-title-box.c in epiphany for the layout
|
||||
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 0 });
|
||||
this.set_custom_title(vbox);
|
||||
|
||||
/* TRANSLATORS: this is the title of the wifi captive portal login window */
|
||||
let titleLabel = new Gtk.Label({ label: _("Hotspot Login"),
|
||||
wrap: false,
|
||||
single_line_mode: true,
|
||||
ellipsize: Pango.EllipsizeMode.END });
|
||||
titleLabel.get_style_context().add_class('title');
|
||||
vbox.add(titleLabel);
|
||||
|
||||
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
|
||||
spacing: 4,
|
||||
halign: Gtk.Align.CENTER,
|
||||
valign: Gtk.Align.BASELINE });
|
||||
hbox.get_style_context().add_class('subtitle');
|
||||
vbox.add(hbox);
|
||||
|
||||
this._lockImage = new Gtk.Image({ icon_size: Gtk.IconSize.MENU,
|
||||
valign: Gtk.Align.BASELINE });
|
||||
hbox.add(this._lockImage);
|
||||
|
||||
this.subtitleLabel = new Gtk.Label({ wrap: false,
|
||||
single_line_mode: true,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
valign: Gtk.Align.BASELINE,
|
||||
selectable: true});
|
||||
this.subtitleLabel.get_style_context().add_class('subtitle');
|
||||
hbox.add(this.subtitleLabel);
|
||||
|
||||
vbox.show_all();
|
||||
},
|
||||
|
||||
setSubtitle: function(label) {
|
||||
this.subtitleLabel.set_text(label);
|
||||
},
|
||||
|
||||
setSecurityIcon: function(securityLevel) {
|
||||
switch (securityLevel) {
|
||||
case PortalHelperSecurityLevel.NOT_YET_DETERMINED:
|
||||
this._lockImage.hide();
|
||||
break;
|
||||
case PortalHelperSecurityLevel.SECURE:
|
||||
this._lockImage.show();
|
||||
this._lockImage.set_from_icon_name("channel-secure-symbolic", Gtk.IconSize.MENU);
|
||||
this._lockImage.set_tooltip_text(null);
|
||||
break;
|
||||
case PortalHelperSecurityLevel.INSECURE:
|
||||
this._lockImage.show();
|
||||
this._lockImage.set_from_icon_name("channel-insecure-symbolic", Gtk.IconSize.MENU);
|
||||
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,
|
||||
|
||||
_init: function(application, url, timestamp, doneCallback) {
|
||||
this.parent({ application: application });
|
||||
|
||||
this.connect('delete-event', Lang.bind(this, this.destroyWindow));
|
||||
this._headerBar = new PortalHeaderBar();
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
||||
this.set_titlebar(this._headerBar);
|
||||
this._headerBar.show();
|
||||
|
||||
if (!url) {
|
||||
url = 'http://www.gnome.org';
|
||||
url = CONNECTIVITY_CHECK_URI;
|
||||
this._originalUrlWasGnome = true;
|
||||
} else {
|
||||
this._originalUrlWasGnome = false;
|
||||
@ -62,28 +141,38 @@ const PortalWindow = new Lang.Class({
|
||||
this._lastRecheck = 0;
|
||||
this._recheckAtExit = false;
|
||||
|
||||
this._webView = new WebKit.WebView();
|
||||
this._webContext = WebKit.WebContext.new_ephemeral();
|
||||
this._webContext.set_cache_model(WebKit.CacheModel.DOCUMENT_VIEWER);
|
||||
this._webContext.set_network_proxy_settings(WebKit.NetworkProxyMode.NO_PROXY, null);
|
||||
|
||||
this._webView = WebKit.WebView.new_with_context(this._webContext);
|
||||
this._webView.connect('decide-policy', Lang.bind(this, this._onDecidePolicy));
|
||||
this._webView.connect('load-changed', Lang.bind(this, this._onLoadChanged));
|
||||
this._webView.connect('insecure-content-detected', Lang.bind(this, this._onInsecureContentDetected));
|
||||
this._webView.connect('load-failed-with-tls-errors', Lang.bind(this, this._onLoadFailedWithTlsErrors));
|
||||
this._webView.load_uri(url);
|
||||
this._webView.connect('notify::title', Lang.bind(this, this._syncTitle));
|
||||
this._syncTitle();
|
||||
this._webView.connect('notify::uri', Lang.bind(this, this._syncUri));
|
||||
this._syncUri();
|
||||
|
||||
this.add(this._webView);
|
||||
this._webView.show();
|
||||
this.set_size_request(600, 450);
|
||||
this.maximize();
|
||||
this.present_with_time(timestamp);
|
||||
|
||||
this.application.set_accels_for_action('app.quit', ['<Primary>q', '<Primary>w']);
|
||||
},
|
||||
|
||||
_syncTitle: function() {
|
||||
let title = this._webView.title;
|
||||
destroyWindow: function() {
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
if (title) {
|
||||
this.title = title;
|
||||
} else {
|
||||
/* TRANSLATORS: this is the title of the wifi captive portal login
|
||||
* window, until we know the title of the actual login page */
|
||||
this.title = _("Web Authentication Redirect");
|
||||
}
|
||||
_syncUri: function() {
|
||||
let uri = this._webView.uri;
|
||||
if (uri)
|
||||
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
|
||||
else
|
||||
this._headerBar.setSubtitle('');
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
@ -99,8 +188,46 @@ const PortalWindow = new Lang.Class({
|
||||
return false;
|
||||
},
|
||||
|
||||
_onLoadChanged: function(view, loadEvent) {
|
||||
if (loadEvent == WebKit.LoadEvent.STARTED) {
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
||||
} else if (loadEvent == WebKit.LoadEvent.COMMITTED) {
|
||||
let tlsInfo = this._webView.get_tls_info();
|
||||
let ret = tlsInfo[0];
|
||||
let flags = tlsInfo[2];
|
||||
if (ret && flags == 0)
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.SECURE);
|
||||
else
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||
}
|
||||
},
|
||||
|
||||
_onInsecureContentDetected: function () {
|
||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||
},
|
||||
|
||||
_onLoadFailedWithTlsErrors: function (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: function(view, decision, type) {
|
||||
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
|
||||
let navigationAction = decision.get_navigation_action();
|
||||
if (navigationAction.is_user_gesture()) {
|
||||
// Even though the portal asks for a new window,
|
||||
// perform the navigation in the current one. Some
|
||||
// portals open a window as their last login step and
|
||||
// ignoring that window causes them to not let the
|
||||
// user go through. We don't risk popups taking over
|
||||
// the page because we check that the navigation is
|
||||
// user initiated.
|
||||
this._webView.load_request(navigationAction.get_request());
|
||||
}
|
||||
|
||||
decision.ignore();
|
||||
return true;
|
||||
}
|
||||
@ -112,12 +239,12 @@ const PortalWindow = new Lang.Class({
|
||||
let uri = new Soup.URI(request.get_uri());
|
||||
|
||||
if (!uri.host_equal(this._uri) && this._originalUrlWasGnome) {
|
||||
if (uri.get_host() == 'www.gnome.org' && this._everSeenRedirect) {
|
||||
if (uri.get_host() == CONNECTIVITY_CHECK_HOST && this._everSeenRedirect) {
|
||||
// Yay, we got to gnome!
|
||||
decision.ignore();
|
||||
this._doneCallback(PortalHelperResult.COMPLETED);
|
||||
return true;
|
||||
} else if (uri.get_host() != 'www.gnome.org') {
|
||||
} else if (uri.get_host() != CONNECTIVITY_CHECK_HOST) {
|
||||
this._everSeenRedirect = true;
|
||||
}
|
||||
}
|
||||
@ -155,7 +282,7 @@ const PortalWindow = new Lang.Class({
|
||||
},
|
||||
});
|
||||
|
||||
const WebPortalHelper = new Lang.Class({
|
||||
var WebPortalHelper = new Lang.Class({
|
||||
Name: 'WebPortalHelper',
|
||||
Extends: Gtk.Application,
|
||||
|
||||
@ -166,6 +293,10 @@ const WebPortalHelper = new Lang.Class({
|
||||
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(HelperDBusInterface, this);
|
||||
this._queue = [];
|
||||
|
||||
let action = new Gio.SimpleAction({ name: 'quit' });
|
||||
action.connect('activate', () => { this.active_window.destroyWindow(); });
|
||||
this.add_action(action);
|
||||
},
|
||||
|
||||
vfunc_dbus_register: function(connection, path) {
|
||||
@ -197,7 +328,7 @@ const WebPortalHelper = new Lang.Class({
|
||||
|
||||
if (obj.connection == connection) {
|
||||
if (obj.window)
|
||||
obj.window.destroy();
|
||||
obj.window.destroyWindow();
|
||||
this._queue.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
@ -226,7 +357,7 @@ const WebPortalHelper = new Lang.Class({
|
||||
if (top.window != null)
|
||||
return;
|
||||
|
||||
top.window = new PortalWindow(this, top.uri, top.timestamp, Lang.bind(this, function(result) {
|
||||
top.window = new PortalWindow(this, top.url, top.timestamp, Lang.bind(this, function(result) {
|
||||
this._dbusImpl.emit_signal('Done', new GLib.Variant('(ou)', [top.connection, result]));
|
||||
}));
|
||||
},
|
||||
@ -239,6 +370,11 @@ function initEnvironment() {
|
||||
function main(argv) {
|
||||
initEnvironment();
|
||||
|
||||
if (!WebKit.WebContext.new_ephemeral) {
|
||||
log('WebKitGTK 2.16 is required for the portal-helper, see https://bugzilla.gnome.org/show_bug.cgi?id=780453');
|
||||
return 1;
|
||||
}
|
||||
|
||||
Gettext.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
||||
Gettext.textdomain(Config.GETTEXT_PACKAGE);
|
||||
|
||||
|
180
js/ui/accessDialog.js
Normal file
180
js/ui/accessDialog.js
Normal file
@ -0,0 +1,180 @@
|
||||
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;
|
||||
|
||||
const CheckBox = imports.ui.checkBox;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
|
||||
const RequestIface = '<node> \
|
||||
<interface name="org.freedesktop.impl.portal.Request"> \
|
||||
<method name="Close"/> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const AccessIface = '<node> \
|
||||
<interface name="org.freedesktop.impl.portal.Access"> \
|
||||
<method name="AccessDialog"> \
|
||||
<arg type="o" name="handle" direction="in"/> \
|
||||
<arg type="s" name="app_id" direction="in"/> \
|
||||
<arg type="s" name="parent_window" direction="in"/> \
|
||||
<arg type="s" name="title" direction="in"/> \
|
||||
<arg type="s" name="subtitle" direction="in"/> \
|
||||
<arg type="s" name="body" direction="in"/> \
|
||||
<arg type="a{sv}" name="options" direction="in"/> \
|
||||
<arg type="u" name="response" direction="out"/> \
|
||||
<arg type="a{sv}" name="results" direction="out"/> \
|
||||
</method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
var DialogResponse = {
|
||||
OK: 0,
|
||||
CANCEL: 1,
|
||||
CLOSED: 2
|
||||
};
|
||||
|
||||
var AccessDialog = new Lang.Class({
|
||||
Name: 'AccessDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
_init: function(invocation, handle, title, subtitle, body, options) {
|
||||
this.parent({ styleClass: 'access-dialog' });
|
||||
|
||||
this._invocation = invocation;
|
||||
this._handle = handle;
|
||||
|
||||
this._requestExported = false;
|
||||
this._request = Gio.DBusExportedObject.wrapJSObject(RequestIface, this);
|
||||
|
||||
for (let option in options)
|
||||
options[option] = options[option].deep_unpack();
|
||||
|
||||
this._buildLayout(title, subtitle, body, options);
|
||||
},
|
||||
|
||||
_buildLayout: function(title, subtitle, body, options) {
|
||||
// No support for non-modal system dialogs, so ignore the option
|
||||
//let modal = options['modal'] || true;
|
||||
let denyLabel = options['deny_label'] || _("Deny Access");
|
||||
let grantLabel = options['grant_label'] || _("Grant Access");
|
||||
let iconName = options['icon'] || null;
|
||||
let choices = options['choices'] || [];
|
||||
|
||||
let contentParams = { title, subtitle, body };
|
||||
if (iconName)
|
||||
contentParams.icon = new Gio.ThemedIcon({ name: iconName });
|
||||
let content = new Dialog.MessageDialogContent(contentParams);
|
||||
this.contentLayout.add_actor(content);
|
||||
|
||||
this._choices = new Map();
|
||||
|
||||
for (let i = 0; i < choices.length; i++) {
|
||||
let [id, name, opts, selected] = choices[i];
|
||||
if (opts.length > 0)
|
||||
continue; // radio buttons, not implemented
|
||||
|
||||
let check = new CheckBox.CheckBox();
|
||||
check.getLabelActor().text = name;
|
||||
check.actor.checked = selected == "true";
|
||||
content.insertBeforeBody(check.actor);
|
||||
|
||||
this._choices.set(id, check);
|
||||
}
|
||||
|
||||
this.addButton({ label: denyLabel,
|
||||
action: () => {
|
||||
this._sendResponse(DialogResponse.CANCEL);
|
||||
},
|
||||
key: Clutter.KEY_Escape });
|
||||
this.addButton({ label: grantLabel,
|
||||
action: () => {
|
||||
this._sendResponse(DialogResponse.OK);
|
||||
}});
|
||||
},
|
||||
|
||||
open: function() {
|
||||
this.parent();
|
||||
|
||||
let connection = this._invocation.get_connection();
|
||||
this._requestExported = this._request.export(connection, this._handle);
|
||||
},
|
||||
|
||||
CloseAsync: function(invocation, params) {
|
||||
if (this._invocation.get_sender() != invocation.get_sender()) {
|
||||
invocation.return_error_literal(Gio.DBusError,
|
||||
Gio.DBusError.ACCESS_DENIED,
|
||||
'');
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendResponse(DialogResponse.CLOSED);
|
||||
},
|
||||
|
||||
_sendResponse: function(response) {
|
||||
if (this._requestExported)
|
||||
this._request.unexport();
|
||||
this._requestExported = false;
|
||||
|
||||
let results = {};
|
||||
if (response == DialogResponse.OK) {
|
||||
for (let [id, check] of this._choices) {
|
||||
let checked = check.actor.checked ? 'true' : 'false';
|
||||
results[id] = new GLib.Variant('s', checked);
|
||||
}
|
||||
}
|
||||
|
||||
// Delay actual response until the end of the close animation (if any)
|
||||
this.connect('closed', () => {
|
||||
this._invocation.return_value(new GLib.Variant('(ua{sv})',
|
||||
[response, results]));
|
||||
});
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
|
||||
var AccessDialogDBus = new Lang.Class({
|
||||
Name: 'AccessDialogDBus',
|
||||
|
||||
_init: function() {
|
||||
this._accessDialog = null;
|
||||
|
||||
this._windowTracker = Shell.WindowTracker.get_default();
|
||||
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AccessIface, this);
|
||||
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: function(params, invocation) {
|
||||
if (this._accessDialog) {
|
||||
invocation.return_error_literal(Gio.DBusError,
|
||||
Gio.DBusError.LIMITS_EXCEEDED,
|
||||
'Already showing a system access dialog');
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
invocation.return_error_literal(Gio.DBusError,
|
||||
Gio.DBusError.ACCESS_DENIED,
|
||||
'Only the focused app is allowed to show a system access dialog');
|
||||
return;
|
||||
}
|
||||
|
||||
let dialog = new AccessDialog(invocation, handle, title,
|
||||
subtitle, body, options);
|
||||
dialog.open();
|
||||
|
||||
dialog.connect('closed', () => { this._accessDialog = null; });
|
||||
|
||||
this._accessDialog = dialog;
|
||||
}
|
||||
});
|
219
js/ui/altTab.js
219
js/ui/altTab.js
@ -14,29 +14,28 @@ const Main = imports.ui.main;
|
||||
const SwitcherPopup = imports.ui.switcherPopup;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const APP_ICON_HOVER_TIMEOUT = 200; // milliseconds
|
||||
var APP_ICON_HOVER_TIMEOUT = 200; // milliseconds
|
||||
|
||||
const THUMBNAIL_DEFAULT_SIZE = 256;
|
||||
const THUMBNAIL_POPUP_TIME = 500; // milliseconds
|
||||
const THUMBNAIL_FADE_TIME = 0.1; // seconds
|
||||
var THUMBNAIL_DEFAULT_SIZE = 256;
|
||||
var THUMBNAIL_POPUP_TIME = 500; // milliseconds
|
||||
var THUMBNAIL_FADE_TIME = 0.1; // seconds
|
||||
|
||||
const WINDOW_PREVIEW_SIZE = 128;
|
||||
const APP_ICON_SIZE = 96;
|
||||
const APP_ICON_SIZE_SMALL = 48;
|
||||
var WINDOW_PREVIEW_SIZE = 128;
|
||||
var APP_ICON_SIZE = 96;
|
||||
var APP_ICON_SIZE_SMALL = 48;
|
||||
|
||||
const baseIconSizes = [96, 64, 48, 32, 22];
|
||||
|
||||
const AppIconMode = {
|
||||
var AppIconMode = {
|
||||
THUMBNAIL_ONLY: 1,
|
||||
APP_ICON_ONLY: 2,
|
||||
BOTH: 3,
|
||||
};
|
||||
|
||||
function _createWindowClone(window, size) {
|
||||
let windowTexture = window.get_texture();
|
||||
let [width, height] = windowTexture.get_size();
|
||||
let [width, height] = window.get_size();
|
||||
let scale = Math.min(1.0, size / width, size / height);
|
||||
return new Clutter.Clone({ source: windowTexture,
|
||||
return new Clutter.Clone({ source: window,
|
||||
width: width * scale,
|
||||
height: height * scale,
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
@ -46,7 +45,20 @@ function _createWindowClone(window, size) {
|
||||
y_expand: true });
|
||||
};
|
||||
|
||||
const AppSwitcherPopup = new Lang.Class({
|
||||
function getWindows(workspace) {
|
||||
// We ignore skip-taskbar windows in switchers, but if they are attached
|
||||
// to their parent, their position in the MRU list may be more appropriate
|
||||
// than the parent; so start with the complete list ...
|
||||
let windows = global.display.get_tab_list(Meta.TabList.NORMAL_ALL,
|
||||
workspace);
|
||||
// ... map windows to their parent where appropriate ...
|
||||
return windows.map(w => {
|
||||
return w.is_attached_dialog() ? w.get_transient_for() : w;
|
||||
// ... and filter out skip-taskbar windows and duplicates
|
||||
}).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) == i);
|
||||
}
|
||||
|
||||
var AppSwitcherPopup = new Lang.Class({
|
||||
Name: 'AppSwitcherPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
|
||||
@ -354,7 +366,150 @@ const AppSwitcherPopup = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const WindowSwitcherPopup = new Lang.Class({
|
||||
var CyclerHighlight = new Lang.Class({
|
||||
Name: 'CyclerHighlight',
|
||||
|
||||
_init: function() {
|
||||
this._window = null;
|
||||
|
||||
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
|
||||
this._clone = new Clutter.Clone();
|
||||
this.actor.add_actor(this._clone);
|
||||
|
||||
this._highlight = new St.Widget({ style_class: 'cycler-highlight' });
|
||||
this.actor.add_actor(this._highlight);
|
||||
|
||||
let coordinate = Clutter.BindCoordinate.ALL;
|
||||
let constraint = new Clutter.BindConstraint({ coordinate: coordinate });
|
||||
this._clone.bind_property('source', constraint, 'source', 0);
|
||||
|
||||
this.actor.add_constraint(constraint);
|
||||
|
||||
this.actor.connect('notify::allocation',
|
||||
Lang.bind(this, this._onAllocationChanged));
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
},
|
||||
|
||||
set window(w) {
|
||||
if (this._window == w)
|
||||
return;
|
||||
|
||||
this._window = w;
|
||||
|
||||
if (this._clone.source)
|
||||
this._clone.source.sync_visibility();
|
||||
|
||||
let windowActor = this._window ? this._window.get_compositor_private()
|
||||
: null;
|
||||
|
||||
if (windowActor)
|
||||
windowActor.hide();
|
||||
|
||||
this._clone.source = windowActor;
|
||||
},
|
||||
|
||||
_onAllocationChanged: function() {
|
||||
if (!this._window) {
|
||||
this._highlight.set_size(0, 0);
|
||||
this._highlight.hide();
|
||||
} else {
|
||||
let [x, y] = this.actor.allocation.get_origin();
|
||||
let rect = this._window.get_frame_rect();
|
||||
this._highlight.set_size(rect.width, rect.height);
|
||||
this._highlight.set_position(rect.x - x, rect.y - y);
|
||||
this._highlight.show();
|
||||
}
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
this.window = null;
|
||||
}
|
||||
});
|
||||
|
||||
var CyclerPopup = new Lang.Class({
|
||||
Name: 'CyclerPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
Abstract: true,
|
||||
|
||||
_init : function() {
|
||||
this.parent();
|
||||
|
||||
this._items = this._getWindows();
|
||||
|
||||
if (this._items.length == 0)
|
||||
return;
|
||||
|
||||
this._highlight = new CyclerHighlight();
|
||||
global.window_group.add_actor(this._highlight.actor);
|
||||
|
||||
// We don't show an actual popup, so just provide what SwitcherPopup
|
||||
// expects instead of inheriting from SwitcherList
|
||||
this._switcherList = { actor: new St.Widget(),
|
||||
highlight: Lang.bind(this, this._highlightItem),
|
||||
connect: function() {} };
|
||||
},
|
||||
|
||||
_highlightItem: function(index, justOutline) {
|
||||
this._highlight.window = this._items[index];
|
||||
global.window_group.set_child_above_sibling(this._highlight.actor, null);
|
||||
},
|
||||
|
||||
_finish: function() {
|
||||
let window = this._items[this._selectedIndex];
|
||||
let ws = window.get_workspace();
|
||||
let activeWs = global.screen.get_active_workspace();
|
||||
|
||||
if (window.minimized) {
|
||||
Main.wm.skipNextEffect(window.get_compositor_private());
|
||||
window.unminimize();
|
||||
}
|
||||
|
||||
if (activeWs == ws) {
|
||||
Main.activateWindow(window);
|
||||
} else {
|
||||
// If the selected window is on a different workspace, we don't
|
||||
// want it to disappear, then slide in with the workspace; instead,
|
||||
// always activate it on the active workspace ...
|
||||
activeWs.activate_with_focus(window, global.get_current_time());
|
||||
|
||||
// ... then slide it over to the original workspace if necessary
|
||||
Main.wm.actionMoveWindow(window, ws);
|
||||
}
|
||||
|
||||
this.parent();
|
||||
},
|
||||
|
||||
_onDestroy: function() {
|
||||
this._highlight.actor.destroy();
|
||||
|
||||
this.parent();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var GroupCyclerPopup = new Lang.Class({
|
||||
Name: 'GroupCyclerPopup',
|
||||
Extends: CyclerPopup,
|
||||
|
||||
_getWindows: function() {
|
||||
let app = Shell.WindowTracker.get_default().focus_app;
|
||||
return app ? app.get_windows() : [];
|
||||
},
|
||||
|
||||
_keyPressHandler: function(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.CYCLE_GROUP)
|
||||
this._select(this._next());
|
||||
else if (action == Meta.KeyBindingAction.CYCLE_GROUP_BACKWARD)
|
||||
this._select(this._previous());
|
||||
else
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
});
|
||||
|
||||
var WindowSwitcherPopup = new Lang.Class({
|
||||
Name: 'WindowSwitcherPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
|
||||
@ -374,7 +529,7 @@ const WindowSwitcherPopup = new Lang.Class({
|
||||
|
||||
_getWindowList: function() {
|
||||
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
|
||||
return global.display.get_tab_list(Meta.TabList.NORMAL, workspace);
|
||||
return getWindows(workspace);
|
||||
},
|
||||
|
||||
_keyPressHandler: function(keysym, action) {
|
||||
@ -401,7 +556,33 @@ const WindowSwitcherPopup = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const AppIcon = new Lang.Class({
|
||||
var WindowCyclerPopup = new Lang.Class({
|
||||
Name: 'WindowCyclerPopup',
|
||||
Extends: CyclerPopup,
|
||||
|
||||
_init: function() {
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
|
||||
this.parent();
|
||||
},
|
||||
|
||||
_getWindows: function() {
|
||||
let workspace = this._settings.get_boolean('current-workspace-only') ? global.screen.get_active_workspace() : null;
|
||||
return getWindows(workspace);
|
||||
},
|
||||
|
||||
_keyPressHandler: function(keysym, action) {
|
||||
if (action == Meta.KeyBindingAction.CYCLE_WINDOWS)
|
||||
this._select(this._next());
|
||||
else if (action == Meta.KeyBindingAction.CYCLE_WINDOWS_BACKWARD)
|
||||
this._select(this._previous());
|
||||
else
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
});
|
||||
|
||||
var AppIcon = new Lang.Class({
|
||||
Name: 'AppIcon',
|
||||
|
||||
_init: function(app) {
|
||||
@ -422,7 +603,7 @@ const AppIcon = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const AppSwitcher = new Lang.Class({
|
||||
var AppSwitcher = new Lang.Class({
|
||||
Name: 'AppSwitcher',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
@ -596,7 +777,7 @@ const AppSwitcher = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const ThumbnailList = new Lang.Class({
|
||||
var ThumbnailList = new Lang.Class({
|
||||
Name: 'ThumbnailList',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
@ -664,7 +845,7 @@ const ThumbnailList = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const WindowIcon = new Lang.Class({
|
||||
var WindowIcon = new Lang.Class({
|
||||
Name: 'WindowIcon',
|
||||
|
||||
_init: function(window, mode) {
|
||||
@ -721,7 +902,7 @@ const WindowIcon = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const WindowList = new Lang.Class({
|
||||
var WindowList = new Lang.Class({
|
||||
Name: 'WindowList',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
|
@ -7,9 +7,9 @@ const St = imports.gi.St;
|
||||
const Signals = imports.signals;
|
||||
const Atk = imports.gi.Atk;
|
||||
|
||||
const ANIMATED_ICON_UPDATE_TIMEOUT = 16;
|
||||
var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
|
||||
|
||||
const Animation = new Lang.Class({
|
||||
var Animation = new Lang.Class({
|
||||
Name: 'Animation',
|
||||
|
||||
_init: function(file, width, height, speed) {
|
||||
@ -67,7 +67,7 @@ const Animation = new Lang.Class({
|
||||
},
|
||||
|
||||
_animationsLoaded: function() {
|
||||
this._isLoaded = true;
|
||||
this._isLoaded = this._animations.get_n_children() > 0;
|
||||
|
||||
if (this._isPlaying)
|
||||
this.play();
|
||||
@ -78,7 +78,7 @@ const Animation = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const AnimatedIcon = new Lang.Class({
|
||||
var AnimatedIcon = new Lang.Class({
|
||||
Name: 'AnimatedIcon',
|
||||
Extends: Animation,
|
||||
|
||||
|
@ -27,38 +27,50 @@ const Workspace = imports.ui.workspace;
|
||||
const Params = imports.misc.params;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const MAX_APPLICATION_WORK_MILLIS = 75;
|
||||
const MENU_POPUP_TIMEOUT = 600;
|
||||
const MAX_COLUMNS = 6;
|
||||
const MIN_COLUMNS = 4;
|
||||
const MIN_ROWS = 4;
|
||||
var MAX_APPLICATION_WORK_MILLIS = 75;
|
||||
var MENU_POPUP_TIMEOUT = 600;
|
||||
var MAX_COLUMNS = 6;
|
||||
var MIN_COLUMNS = 4;
|
||||
var MIN_ROWS = 4;
|
||||
|
||||
const INACTIVE_GRID_OPACITY = 77;
|
||||
var INACTIVE_GRID_OPACITY = 77;
|
||||
// This time needs to be less than IconGrid.EXTRA_SPACE_ANIMATION_TIME
|
||||
// to not clash with other animations
|
||||
const INACTIVE_GRID_OPACITY_ANIMATION_TIME = 0.24;
|
||||
const FOLDER_SUBICON_FRACTION = .4;
|
||||
var INACTIVE_GRID_OPACITY_ANIMATION_TIME = 0.24;
|
||||
var FOLDER_SUBICON_FRACTION = .4;
|
||||
|
||||
const MIN_FREQUENT_APPS_COUNT = 3;
|
||||
var MIN_FREQUENT_APPS_COUNT = 3;
|
||||
|
||||
const INDICATORS_BASE_TIME = 0.25;
|
||||
const INDICATORS_ANIMATION_DELAY = 0.125;
|
||||
const INDICATORS_ANIMATION_MAX_TIME = 0.75;
|
||||
var INDICATORS_BASE_TIME = 0.25;
|
||||
var INDICATORS_ANIMATION_DELAY = 0.125;
|
||||
var INDICATORS_ANIMATION_MAX_TIME = 0.75;
|
||||
|
||||
var VIEWS_SWITCH_TIME = 0.4;
|
||||
var VIEWS_SWITCH_ANIMATION_DELAY = 0.1;
|
||||
|
||||
// Follow iconGrid animations approach and divide by 2 to animate out to
|
||||
// not annoy the user when the user wants to quit appDisplay.
|
||||
// Also, make sure we don't exceed iconGrid animation total time or
|
||||
// views switch time.
|
||||
const INDICATORS_BASE_TIME_OUT = 0.125;
|
||||
const INDICATORS_ANIMATION_DELAY_OUT = 0.0625;
|
||||
const INDICATORS_ANIMATION_MAX_TIME_OUT =
|
||||
var INDICATORS_BASE_TIME_OUT = 0.125;
|
||||
var INDICATORS_ANIMATION_DELAY_OUT = 0.0625;
|
||||
var INDICATORS_ANIMATION_MAX_TIME_OUT =
|
||||
Math.min (VIEWS_SWITCH_TIME,
|
||||
IconGrid.ANIMATION_TIME_OUT + IconGrid.ANIMATION_MAX_DELAY_OUT_FOR_ITEM);
|
||||
|
||||
const PAGE_SWITCH_TIME = 0.3;
|
||||
var PAGE_SWITCH_TIME = 0.3;
|
||||
|
||||
const VIEWS_SWITCH_TIME = 0.4;
|
||||
const VIEWS_SWITCH_ANIMATION_DELAY = 0.1;
|
||||
const SWITCHEROO_BUS_NAME = 'net.hadess.SwitcherooControl';
|
||||
const SWITCHEROO_OBJECT_PATH = '/net/hadess/SwitcherooControl';
|
||||
|
||||
const SwitcherooProxyInterface = '<node> \
|
||||
<interface name="net.hadess.SwitcherooControl"> \
|
||||
<property name="HasDualGpu" type="b" access="read"/> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const SwitcherooProxy = Gio.DBusProxy.makeProxyWrapper(SwitcherooProxyInterface);
|
||||
let discreteGpuAvailable = false;
|
||||
|
||||
function _getCategories(info) {
|
||||
let categoriesStr = info.get_categories();
|
||||
@ -96,7 +108,7 @@ function clamp(value, min, max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
|
||||
const BaseAppView = new Lang.Class({
|
||||
var BaseAppView = new Lang.Class({
|
||||
Name: 'BaseAppView',
|
||||
Abstract: true,
|
||||
|
||||
@ -198,22 +210,6 @@ const BaseAppView = new Lang.Class({
|
||||
},
|
||||
|
||||
animate: function(animationDirection, onComplete) {
|
||||
if (animationDirection == IconGrid.AnimationDirection.IN) {
|
||||
let toAnimate = this._grid.actor.connect('notify::allocation', Lang.bind(this,
|
||||
function() {
|
||||
this._grid.actor.disconnect(toAnimate);
|
||||
// We need to hide the grid temporary to not flash it
|
||||
// for a frame
|
||||
this._grid.actor.opacity = 0;
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
||||
Lang.bind(this, function() {
|
||||
this._doSpringAnimation(animationDirection)
|
||||
}));
|
||||
}));
|
||||
} else {
|
||||
this._doSpringAnimation(animationDirection);
|
||||
}
|
||||
|
||||
if (onComplete) {
|
||||
let animationDoneId = this._grid.connect('animation-done', Lang.bind(this,
|
||||
function () {
|
||||
@ -221,6 +217,15 @@ const BaseAppView = new Lang.Class({
|
||||
onComplete();
|
||||
}));
|
||||
}
|
||||
|
||||
if (animationDirection == IconGrid.AnimationDirection.IN) {
|
||||
let id = this._grid.actor.connect('paint', () => {
|
||||
this._grid.actor.disconnect(id);
|
||||
this._doSpringAnimation(animationDirection);
|
||||
});
|
||||
} else {
|
||||
this._doSpringAnimation(animationDirection);
|
||||
}
|
||||
},
|
||||
|
||||
animateSwitch: function(animationDirection) {
|
||||
@ -244,7 +249,7 @@ const BaseAppView = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(BaseAppView.prototype);
|
||||
|
||||
const PageIndicatorsActor = new Lang.Class({
|
||||
var PageIndicatorsActor = new Lang.Class({
|
||||
Name:'PageIndicatorsActor',
|
||||
Extends: St.BoxLayout,
|
||||
|
||||
@ -268,7 +273,7 @@ const PageIndicatorsActor = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const PageIndicators = new Lang.Class({
|
||||
var PageIndicators = new Lang.Class({
|
||||
Name:'PageIndicators',
|
||||
|
||||
_init: function() {
|
||||
@ -361,7 +366,7 @@ const PageIndicators = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(PageIndicators.prototype);
|
||||
|
||||
const AllView = new Lang.Class({
|
||||
var AllView = new Lang.Class({
|
||||
Name: 'AllView',
|
||||
Extends: BaseAppView,
|
||||
|
||||
@ -435,7 +440,10 @@ const AllView = new Lang.Class({
|
||||
}));
|
||||
this._grid.connect('space-opened', Lang.bind(this,
|
||||
function() {
|
||||
this._scrollView.get_effect('fade').enabled = false;
|
||||
let fadeEffect = this._scrollView.get_effect('fade');
|
||||
if (fadeEffect)
|
||||
fadeEffect.enabled = false;
|
||||
|
||||
this.emit('space-ready');
|
||||
}));
|
||||
this._grid.connect('space-closed', Lang.bind(this,
|
||||
@ -646,7 +654,11 @@ const AllView = new Lang.Class({
|
||||
|
||||
_closeSpaceForPopup: function() {
|
||||
this._updateIconOpacities(false);
|
||||
this._scrollView.get_effect('fade').enabled = true;
|
||||
|
||||
let fadeEffect = this._scrollView.get_effect('fade');
|
||||
if (fadeEffect)
|
||||
fadeEffect.enabled = true;
|
||||
|
||||
this._grid.closeExtraSpace();
|
||||
},
|
||||
|
||||
@ -780,7 +792,7 @@ const AllView = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(AllView.prototype);
|
||||
|
||||
const FrequentView = new Lang.Class({
|
||||
var FrequentView = new Lang.Class({
|
||||
Name: 'FrequentView',
|
||||
Extends: BaseAppView,
|
||||
|
||||
@ -854,12 +866,12 @@ const FrequentView = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const Views = {
|
||||
var Views = {
|
||||
FREQUENT: 0,
|
||||
ALL: 1
|
||||
};
|
||||
|
||||
const ControlsBoxLayout = Lang.Class({
|
||||
var ControlsBoxLayout = Lang.Class({
|
||||
Name: 'ControlsBoxLayout',
|
||||
Extends: Clutter.BoxLayout,
|
||||
|
||||
@ -884,9 +896,11 @@ const ControlsBoxLayout = Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const ViewStackLayout = new Lang.Class({
|
||||
var ViewStackLayout = new Lang.Class({
|
||||
Name: 'ViewStackLayout',
|
||||
Extends: Clutter.BinLayout,
|
||||
Signals: { 'allocated-size-changed': { param_types: [GObject.TYPE_INT,
|
||||
GObject.TYPE_INT] } },
|
||||
|
||||
vfunc_allocate: function (actor, box, flags) {
|
||||
let availWidth = box.x2 - box.x1;
|
||||
@ -897,9 +911,8 @@ const ViewStackLayout = new Lang.Class({
|
||||
this.parent(actor, box, flags);
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ViewStackLayout.prototype);
|
||||
|
||||
const AppDisplay = new Lang.Class({
|
||||
var AppDisplay = new Lang.Class({
|
||||
Name: 'AppDisplay',
|
||||
|
||||
_init: function() {
|
||||
@ -969,10 +982,36 @@ const AppDisplay = new Lang.Class({
|
||||
initialView = Views.ALL;
|
||||
this._showView(initialView);
|
||||
this._updateFrequentVisibility();
|
||||
|
||||
Gio.DBus.system.watch_name(SWITCHEROO_BUS_NAME,
|
||||
Gio.BusNameWatcherFlags.NONE,
|
||||
Lang.bind(this, this._switcherooProxyAppeared),
|
||||
Lang.bind(this, function() {
|
||||
this._switcherooProxy = null;
|
||||
this._updateDiscreteGpuAvailable();
|
||||
}));
|
||||
},
|
||||
|
||||
_updateDiscreteGpuAvailable: function() {
|
||||
if (!this._switcherooProxy)
|
||||
discreteGpuAvailable = false;
|
||||
else
|
||||
discreteGpuAvailable = this._switcherooProxy.HasDualGpu;
|
||||
},
|
||||
|
||||
_switcherooProxyAppeared: function() {
|
||||
this._switcherooProxy = new SwitcherooProxy(Gio.DBus.system, SWITCHEROO_BUS_NAME, SWITCHEROO_OBJECT_PATH,
|
||||
Lang.bind(this, function(proxy, error) {
|
||||
if (error) {
|
||||
log(error.message);
|
||||
return;
|
||||
}
|
||||
this._updateDiscreteGpuAvailable();
|
||||
}));
|
||||
},
|
||||
|
||||
animate: function(animationDirection, onComplete) {
|
||||
let currentView = this._views[global.settings.get_uint('app-picker-view')].view;
|
||||
let currentView = this._views.filter(v => v.control.has_style_pseudo_class('checked')).pop().view;
|
||||
|
||||
// Animate controls opacity using iconGrid animation time, since
|
||||
// it will be the time the AllView or FrequentView takes to show
|
||||
@ -1038,12 +1077,14 @@ const AppDisplay = new Lang.Class({
|
||||
}
|
||||
})
|
||||
|
||||
const AppSearchProvider = new Lang.Class({
|
||||
var AppSearchProvider = new Lang.Class({
|
||||
Name: 'AppSearchProvider',
|
||||
|
||||
_init: function() {
|
||||
this._appSys = Shell.AppSystem.get_default();
|
||||
this.id = 'applications';
|
||||
this.isRemoteProvider = false;
|
||||
this.canLaunchSearch = false;
|
||||
},
|
||||
|
||||
getResultMetas: function(apps, callback) {
|
||||
@ -1091,7 +1132,7 @@ const AppSearchProvider = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const FolderView = new Lang.Class({
|
||||
var FolderView = new Lang.Class({
|
||||
Name: 'FolderView',
|
||||
Extends: BaseAppView,
|
||||
|
||||
@ -1207,11 +1248,12 @@ const FolderView = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const FolderIcon = new Lang.Class({
|
||||
var FolderIcon = new Lang.Class({
|
||||
Name: 'FolderIcon',
|
||||
|
||||
_init: function(id, path, parentView) {
|
||||
this.id = id;
|
||||
this.name = '';
|
||||
this._parentView = parentView;
|
||||
|
||||
this._folder = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders.folder',
|
||||
@ -1384,7 +1426,7 @@ const FolderIcon = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(FolderIcon.prototype);
|
||||
|
||||
const AppFolderPopup = new Lang.Class({
|
||||
var AppFolderPopup = new Lang.Class({
|
||||
Name: 'AppFolderPopup',
|
||||
|
||||
_init: function(source, side) {
|
||||
@ -1545,7 +1587,7 @@ const AppFolderPopup = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(AppFolderPopup.prototype);
|
||||
|
||||
const AppIcon = new Lang.Class({
|
||||
var AppIcon = new Lang.Class({
|
||||
Name: 'AppIcon',
|
||||
|
||||
_init : function(app, iconParams) {
|
||||
@ -1791,7 +1833,7 @@ const AppIcon = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(AppIcon.prototype);
|
||||
|
||||
const AppIconMenu = new Lang.Class({
|
||||
var AppIconMenu = new Lang.Class({
|
||||
Name: 'AppIconMenu',
|
||||
Extends: PopupMenu.PopupMenu,
|
||||
|
||||
@ -1814,7 +1856,7 @@ const AppIconMenu = new Lang.Class({
|
||||
if (!source.actor.mapped)
|
||||
this.close();
|
||||
}));
|
||||
source.actor.connect('destroy', Lang.bind(this, function () { this.actor.destroy(); }));
|
||||
source.actor.connect('destroy', Lang.bind(this, this.destroy));
|
||||
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
},
|
||||
@ -1861,6 +1903,19 @@ const AppIconMenu = new Lang.Class({
|
||||
this._appendSeparator();
|
||||
}
|
||||
|
||||
if (discreteGpuAvailable &&
|
||||
this._source.app.state == Shell.AppState.STOPPED &&
|
||||
actions.indexOf('activate-discrete-gpu') == -1) {
|
||||
this._onDiscreteGpuMenuItem = this._appendMenuItem(_("Launch using Dedicated Graphics Card"));
|
||||
this._onDiscreteGpuMenuItem.connect('activate', Lang.bind(this, function() {
|
||||
if (this._source.app.state == Shell.AppState.STOPPED)
|
||||
this._source.animateLaunch();
|
||||
|
||||
this._source.app.launch(0, -1, true);
|
||||
this.emit('activate-window', null);
|
||||
}));
|
||||
}
|
||||
|
||||
for (let i = 0; i < actions.length; i++) {
|
||||
let action = actions[i];
|
||||
let item = this._appendMenuItem(appInfo.get_action_name(action));
|
||||
|
@ -6,12 +6,15 @@ const Signals = imports.signals;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
// In alphabetical order
|
||||
const RENAMED_DESKTOP_IDS = {
|
||||
'baobab.desktop': 'org.gnome.baobab.desktop',
|
||||
'cheese.desktop': 'org.gnome.Cheese.desktop',
|
||||
'dconf-editor.desktop': 'ca.desrt.dconf-editor.desktop',
|
||||
'epiphany.desktop': 'org.gnome.Epiphany.desktop',
|
||||
'file-roller.desktop': 'org.gnome.FileRoller.desktop',
|
||||
'gcalctool.desktop': 'gnome-calculator.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',
|
||||
@ -19,11 +22,13 @@ const RENAMED_DESKTOP_IDS = {
|
||||
'gnibbles.desktop': 'org.gnome.Nibbles.desktop',
|
||||
'gnobots2.desktop': 'gnome-robots.desktop',
|
||||
'gnome-boxes.desktop': 'org.gnome.Boxes.desktop',
|
||||
'gnome-calculator.desktop': 'org.gnome.Calculator.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-nibbles.desktop': 'org.gnome.Nibbles.desktop',
|
||||
'gnome-music.desktop': 'org.gnome.Music.desktop',
|
||||
'gnome-photos.desktop': 'org.gnome.Photos.desktop',
|
||||
'gnome-screenshot.desktop': 'org.gnome.Screenshot.desktop',
|
||||
'gnome-software.desktop': 'org.gnome.Software.desktop',
|
||||
@ -38,7 +43,7 @@ const RENAMED_DESKTOP_IDS = {
|
||||
'totem.desktop': 'org.gnome.Totem.desktop',
|
||||
};
|
||||
|
||||
const AppFavorites = new Lang.Class({
|
||||
var AppFavorites = new Lang.Class({
|
||||
Name: 'AppFavorites',
|
||||
|
||||
FAVORITE_APPS_KEY: 'favorite-apps',
|
||||
@ -56,12 +61,14 @@ const AppFavorites = new Lang.Class({
|
||||
|
||||
reload: function() {
|
||||
let ids = global.settings.get_strv(this.FAVORITE_APPS_KEY);
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
|
||||
// Map old desktop file names to the current ones
|
||||
let updated = false;
|
||||
ids = ids.map(function (id) {
|
||||
let newId = RENAMED_DESKTOP_IDS[id];
|
||||
if (newId !== undefined) {
|
||||
if (newId !== undefined &&
|
||||
appSys.lookup_app(newId) != null) {
|
||||
updated = true;
|
||||
return newId;
|
||||
}
|
||||
@ -71,7 +78,6 @@ const AppFavorites = new Lang.Class({
|
||||
if (updated)
|
||||
global.settings.set_strv(this.FAVORITE_APPS_KEY, ids);
|
||||
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
let apps = ids.map(function (id) {
|
||||
return appSys.lookup_app(id);
|
||||
}).filter(function (app) {
|
||||
|
@ -9,7 +9,7 @@ const St = imports.gi.St;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
|
||||
const AudioDevice = {
|
||||
var AudioDevice = {
|
||||
HEADPHONES: 1 << 0,
|
||||
HEADSET: 1 << 1,
|
||||
MICROPHONE: 1 << 2
|
||||
@ -28,7 +28,7 @@ const AudioDeviceSelectionIface = '<node> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const AudioDeviceSelectionDialog = new Lang.Class({
|
||||
var AudioDeviceSelectionDialog = new Lang.Class({
|
||||
Name: 'AudioDeviceSelectionDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
@ -146,7 +146,7 @@ const AudioDeviceSelectionDialog = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const AudioDeviceSelectionDBus = new Lang.Class({
|
||||
var AudioDeviceSelectionDBus = new Lang.Class({
|
||||
Name: 'AudioDeviceSelectionDBus',
|
||||
|
||||
_init: function() {
|
||||
|
@ -102,11 +102,12 @@ const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
|
||||
var DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
|
||||
|
||||
const BACKGROUND_SCHEMA = 'org.gnome.desktop.background';
|
||||
const PRIMARY_COLOR_KEY = 'primary-color';
|
||||
@ -116,14 +117,14 @@ const BACKGROUND_STYLE_KEY = 'picture-options';
|
||||
const PICTURE_OPACITY_KEY = 'picture-opacity';
|
||||
const PICTURE_URI_KEY = 'picture-uri';
|
||||
|
||||
const FADE_ANIMATION_TIME = 1.0;
|
||||
var FADE_ANIMATION_TIME = 1.0;
|
||||
|
||||
// These parameters affect how often we redraw.
|
||||
// The first is how different (percent crossfaded) the slide show
|
||||
// has to look before redrawing and the second is the minimum
|
||||
// frequency (in seconds) we're willing to wake up
|
||||
const ANIMATION_OPACITY_STEP_INCREMENT = 4.0;
|
||||
const ANIMATION_MIN_WAKEUP_INTERVAL = 1.0;
|
||||
var ANIMATION_OPACITY_STEP_INCREMENT = 4.0;
|
||||
var ANIMATION_MIN_WAKEUP_INTERVAL = 1.0;
|
||||
|
||||
let _backgroundCache = null;
|
||||
|
||||
@ -137,11 +138,10 @@ function _fileEqual0(file1, file2) {
|
||||
return file1.equal(file2);
|
||||
}
|
||||
|
||||
const BackgroundCache = new Lang.Class({
|
||||
var BackgroundCache = new Lang.Class({
|
||||
Name: 'BackgroundCache',
|
||||
|
||||
_init: function() {
|
||||
this._pendingFileLoads = [];
|
||||
this._fileMonitors = {};
|
||||
this._backgroundSources = {};
|
||||
this._animations = {};
|
||||
@ -166,7 +166,8 @@ const BackgroundCache = new Lang.Class({
|
||||
settingsSchema: null,
|
||||
onLoaded: null });
|
||||
|
||||
if (this._animations[params.settingsSchema] && _fileEqual0(this._animationFile, params.file)) {
|
||||
let animation = this._animations[params.settingsSchema];
|
||||
if (animation && _fileEqual0(animation.file, params.file)) {
|
||||
if (params.onLoaded) {
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
|
||||
params.onLoaded(this._animations[params.settingsSchema]);
|
||||
@ -177,7 +178,7 @@ const BackgroundCache = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
let animation = new Animation({ file: params.file });
|
||||
animation = new Animation({ file: params.file });
|
||||
|
||||
animation.load(Lang.bind(this, function() {
|
||||
this._animations[params.settingsSchema] = animation;
|
||||
@ -225,7 +226,7 @@ function getBackgroundCache() {
|
||||
return _backgroundCache;
|
||||
}
|
||||
|
||||
const Background = new Lang.Class({
|
||||
var Background = new Lang.Class({
|
||||
Name: 'Background',
|
||||
|
||||
_init: function(params) {
|
||||
@ -254,6 +255,14 @@ const Background = new Lang.Class({
|
||||
this._loadAnimation(this._animation.file);
|
||||
}));
|
||||
|
||||
let loginManager = LoginManager.getLoginManager();
|
||||
this._prepareForSleepId = loginManager.connect('prepare-for-sleep',
|
||||
(lm, aboutToSuspend) => {
|
||||
if (aboutToSuspend)
|
||||
return;
|
||||
this._refreshAnimation();
|
||||
});
|
||||
|
||||
this._settingsChangedSignalId = this._settings.connect('changed', Lang.bind(this, function() {
|
||||
this.emit('changed');
|
||||
}));
|
||||
@ -276,16 +285,26 @@ const Background = new Lang.Class({
|
||||
this._clock.disconnect(this._timezoneChangedId);
|
||||
this._timezoneChangedId = 0;
|
||||
|
||||
if (this._prepareForSleepId != 0)
|
||||
LoginManager.getLoginManager().disconnect(this._prepareForSleepId);
|
||||
this._prepareForSleepId = 0;
|
||||
|
||||
if (this._settingsChangedSignalId != 0)
|
||||
this._settings.disconnect(this._settingsChangedSignalId);
|
||||
this._settingsChangedSignalId = 0;
|
||||
},
|
||||
|
||||
updateResolution: function() {
|
||||
if (this._animation) {
|
||||
this._removeAnimationTimeout();
|
||||
this._updateAnimation();
|
||||
}
|
||||
if (this._animation)
|
||||
this._refreshAnimation();
|
||||
},
|
||||
|
||||
_refreshAnimation: function() {
|
||||
if (!this._animation)
|
||||
return;
|
||||
|
||||
this._removeAnimationTimeout();
|
||||
this._updateAnimation();
|
||||
},
|
||||
|
||||
_setLoaded: function() {
|
||||
@ -363,11 +382,9 @@ const Background = new Lang.Class({
|
||||
|
||||
let cache = Meta.BackgroundImageCache.get_default();
|
||||
let numPendingImages = files.length;
|
||||
let images = [];
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
this._watchFile(files[i]);
|
||||
let image = cache.load(files[i]);
|
||||
images.push(image);
|
||||
if (image.is_loaded()) {
|
||||
numPendingImages--;
|
||||
if (numPendingImages == 0)
|
||||
@ -471,7 +488,7 @@ Signals.addSignalMethods(Background.prototype);
|
||||
|
||||
let _systemBackground;
|
||||
|
||||
const SystemBackground = new Lang.Class({
|
||||
var SystemBackground = new Lang.Class({
|
||||
Name: 'SystemBackground',
|
||||
|
||||
_init: function() {
|
||||
@ -508,7 +525,7 @@ const SystemBackground = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(SystemBackground.prototype);
|
||||
|
||||
const BackgroundSource = new Lang.Class({
|
||||
var BackgroundSource = new Lang.Class({
|
||||
Name: 'BackgroundSource',
|
||||
|
||||
_init: function(layoutManager, settingsSchema) {
|
||||
@ -596,7 +613,7 @@ const BackgroundSource = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const Animation = new Lang.Class({
|
||||
var Animation = new Lang.Class({
|
||||
Name: 'Animation',
|
||||
|
||||
_init: function(params) {
|
||||
@ -644,7 +661,7 @@ const Animation = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(Animation.prototype);
|
||||
|
||||
const BackgroundManager = new Lang.Class({
|
||||
var BackgroundManager = new Lang.Class({
|
||||
Name: 'BackgroundManager',
|
||||
|
||||
_init: function(params) {
|
||||
@ -696,6 +713,7 @@ const BackgroundManager = new Lang.Class({
|
||||
time: FADE_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: function() {
|
||||
oldBackgroundActor.background.run_dispose();
|
||||
oldBackgroundActor.destroy();
|
||||
}
|
||||
});
|
||||
|
@ -9,7 +9,7 @@ const BoxPointer = imports.ui.boxpointer;
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
|
||||
const BackgroundMenu = new Lang.Class({
|
||||
var BackgroundMenu = new Lang.Class({
|
||||
Name: 'BackgroundMenu',
|
||||
Extends: PopupMenu.PopupMenu,
|
||||
|
||||
|
@ -10,14 +10,14 @@ const St = imports.gi.St;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const PopupAnimation = {
|
||||
var PopupAnimation = {
|
||||
NONE: 0,
|
||||
SLIDE: 1 << 0,
|
||||
FADE: 1 << 1,
|
||||
FULL: ~0,
|
||||
};
|
||||
|
||||
const POPUP_ANIMATION_TIME = 0.15;
|
||||
var POPUP_ANIMATION_TIME = 0.15;
|
||||
|
||||
/**
|
||||
* BoxPointer:
|
||||
@ -32,7 +32,7 @@ const POPUP_ANIMATION_TIME = 0.15;
|
||||
* totally inside the monitor if possible.
|
||||
*
|
||||
*/
|
||||
const BoxPointer = new Lang.Class({
|
||||
var BoxPointer = new Lang.Class({
|
||||
Name: 'BoxPointer',
|
||||
|
||||
_init: function(arrowSide, binProperties) {
|
||||
|
@ -16,15 +16,15 @@ const MessageTray = imports.ui.messageTray;
|
||||
const Mpris = imports.ui.mpris;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||
const ELLIPSIS_CHAR = '\u2026';
|
||||
var MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
var SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||
var ELLIPSIS_CHAR = '\u2026';
|
||||
|
||||
const MESSAGE_ICON_SIZE = 32;
|
||||
var MESSAGE_ICON_SIZE = 16;
|
||||
|
||||
// alias to prevent xgettext from picking up strings translated in GTK+
|
||||
const gtk30_ = Gettext_gtk30.gettext;
|
||||
const NC_ = function(context, str) { return context + '\u0004' + str; };
|
||||
var NC_ = function(context, str) { return context + '\u0004' + str; };
|
||||
|
||||
function sameYear(dateA, dateB) {
|
||||
return (dateA.getYear() == dateB.getYear());
|
||||
@ -92,7 +92,7 @@ function _getCalendarDayAbbreviation(dayNumber) {
|
||||
|
||||
// Abstraction for an appointment/event in a calendar
|
||||
|
||||
const CalendarEvent = new Lang.Class({
|
||||
var CalendarEvent = new Lang.Class({
|
||||
Name: 'CalendarEvent',
|
||||
|
||||
_init: function(id, date, end, summary, allDay) {
|
||||
@ -108,7 +108,7 @@ const CalendarEvent = new Lang.Class({
|
||||
//
|
||||
|
||||
// First, an implementation with no events
|
||||
const EmptyEventSource = new Lang.Class({
|
||||
var EmptyEventSource = new Lang.Class({
|
||||
Name: 'EmptyEventSource',
|
||||
|
||||
_init: function() {
|
||||
@ -120,6 +120,9 @@ const EmptyEventSource = new Lang.Class({
|
||||
destroy: function() {
|
||||
},
|
||||
|
||||
ignoreEvent: function(event) {
|
||||
},
|
||||
|
||||
requestRange: function(begin, end) {
|
||||
},
|
||||
|
||||
@ -176,7 +179,7 @@ function _dateIntervalsOverlap(a0, a1, b0, b1)
|
||||
}
|
||||
|
||||
// an implementation that reads data from a session bus service
|
||||
const DBusEventSource = new Lang.Class({
|
||||
var DBusEventSource = new Lang.Class({
|
||||
Name: 'DBusEventSource',
|
||||
|
||||
_init: function() {
|
||||
@ -184,6 +187,15 @@ const DBusEventSource = new Lang.Class({
|
||||
this.isLoading = false;
|
||||
this.isDummy = false;
|
||||
|
||||
this._ignoredEvents = new Map();
|
||||
|
||||
let savedState = global.get_persistent_state('as', 'ignored_events');
|
||||
if (savedState)
|
||||
savedState.deep_unpack().forEach(Lang.bind(this,
|
||||
function(eventId) {
|
||||
this._ignoredEvents.set(eventId, true);
|
||||
}));
|
||||
|
||||
this._initialized = false;
|
||||
this._dbusProxy = new CalendarServer();
|
||||
this._dbusProxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(object, result) {
|
||||
@ -298,6 +310,16 @@ const DBusEventSource = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
ignoreEvent: function(event) {
|
||||
if (this._ignoredEvents.get(event.id))
|
||||
return;
|
||||
|
||||
this._ignoredEvents.set(event.id, true);
|
||||
let savedState = new GLib.Variant('as', [...this._ignoredEvents.keys()]);
|
||||
global.set_persistent_state('ignored_events', savedState);
|
||||
this.emit('changed');
|
||||
},
|
||||
|
||||
requestRange: function(begin, end) {
|
||||
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
|
||||
this.isLoading = true;
|
||||
@ -313,6 +335,10 @@ const DBusEventSource = new Lang.Class({
|
||||
let result = [];
|
||||
for(let n = 0; n < this._events.length; n++) {
|
||||
let event = this._events[n];
|
||||
|
||||
if (this._ignoredEvents.has(event.id))
|
||||
continue;
|
||||
|
||||
if (_dateIntervalsOverlap (event.date, event.end, begin, end)) {
|
||||
result.push(event);
|
||||
}
|
||||
@ -340,12 +366,12 @@ const DBusEventSource = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(DBusEventSource.prototype);
|
||||
|
||||
const Calendar = new Lang.Class({
|
||||
var Calendar = new Lang.Class({
|
||||
Name: 'Calendar',
|
||||
|
||||
_init: function() {
|
||||
this._weekStart = Shell.util_get_week_start();
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.calendar' });
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
|
||||
|
||||
this._settings.connect('changed::' + SHOW_WEEKDATE_KEY, Lang.bind(this, this._onSettingsChange));
|
||||
this._useWeekdate = this._settings.get_boolean(SHOW_WEEKDATE_KEY);
|
||||
@ -660,18 +686,18 @@ const Calendar = new Lang.Class({
|
||||
|
||||
this._buttons.forEach(Lang.bind(this, function(button) {
|
||||
if (sameDay(button._date, this._selectedDate)) {
|
||||
button.add_style_pseudo_class('active');
|
||||
button.add_style_pseudo_class('selected');
|
||||
if (this._shouldDateGrabFocus)
|
||||
button.grab_key_focus();
|
||||
}
|
||||
else
|
||||
button.remove_style_pseudo_class('active');
|
||||
button.remove_style_pseudo_class('selected');
|
||||
}));
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(Calendar.prototype);
|
||||
|
||||
const EventMessage = new Lang.Class({
|
||||
var EventMessage = new Lang.Class({
|
||||
Name: 'EventMessage',
|
||||
Extends: MessageList.Message,
|
||||
|
||||
@ -680,6 +706,14 @@ const EventMessage = new Lang.Class({
|
||||
this._date = date;
|
||||
|
||||
this.parent(this._formatEventTime(), event.summary);
|
||||
|
||||
this._icon = new St.Icon({ icon_name: 'x-office-calendar-symbolic' });
|
||||
this.setIcon(this._icon);
|
||||
|
||||
this.actor.connect('style-changed', () => {
|
||||
let iconVisible = this.actor.get_parent().has_style_pseudo_class('first-child');
|
||||
this._icon.opacity = (iconVisible ? 255 : 0);
|
||||
});
|
||||
},
|
||||
|
||||
_formatEventTime: function() {
|
||||
@ -720,15 +754,15 @@ const EventMessage = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const NotificationMessage = new Lang.Class({
|
||||
var NotificationMessage = new Lang.Class({
|
||||
Name: 'NotificationMessage',
|
||||
Extends: MessageList.Message,
|
||||
|
||||
_init: function(notification) {
|
||||
this.notification = notification;
|
||||
|
||||
this.setUseBodyMarkup(notification.bannerBodyMarkup);
|
||||
this.parent(notification.title, notification.bannerBodyText);
|
||||
this.setUseBodyMarkup(notification.bannerBodyMarkup);
|
||||
|
||||
this.setIcon(this._getIcon());
|
||||
|
||||
@ -776,7 +810,7 @@ const NotificationMessage = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const EventsSection = new Lang.Class({
|
||||
var EventsSection = new Lang.Class({
|
||||
Name: 'EventsSection',
|
||||
Extends: MessageList.MessageListSection,
|
||||
|
||||
@ -785,16 +819,16 @@ const EventsSection = new Lang.Class({
|
||||
this._desktopSettings.connect('changed', Lang.bind(this, this._reloadEvents));
|
||||
this._eventSource = new EmptyEventSource();
|
||||
|
||||
this._ignoredEvents = new Map();
|
||||
this.parent();
|
||||
|
||||
let savedState = global.get_persistent_state('as', 'ignored_events');
|
||||
if (savedState)
|
||||
savedState.deep_unpack().forEach(Lang.bind(this,
|
||||
function(eventId) {
|
||||
this._ignoredEvents.set(eventId, true);
|
||||
}));
|
||||
this._title = new St.Button({ style_class: 'events-section-title',
|
||||
label: '',
|
||||
x_align: St.Align.START,
|
||||
can_focus: true });
|
||||
this.actor.insert_child_below(this._title, null);
|
||||
|
||||
this.parent('');
|
||||
this._title.connect('clicked', Lang.bind(this, this._onTitleClicked));
|
||||
this._title.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
|
||||
|
||||
Shell.AppSystem.get_default().connect('installed-changed',
|
||||
Lang.bind(this, this._appInstalledChanged));
|
||||
@ -802,9 +836,7 @@ const EventsSection = new Lang.Class({
|
||||
},
|
||||
|
||||
_ignoreEvent: function(event) {
|
||||
this._ignoredEvents.set(event.id, true);
|
||||
let savedState = new GLib.Variant('as', [...this._ignoredEvents.keys()]);
|
||||
global.set_persistent_state('ignored_events', savedState);
|
||||
this._eventSource.ignoreEvent(event);
|
||||
},
|
||||
|
||||
setEventSource: function(eventSource) {
|
||||
@ -817,10 +849,10 @@ const EventsSection = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateTitle: function() {
|
||||
if (isToday(this._date)) {
|
||||
this._title.label = _("Events");
|
||||
this._title.visible = !isToday(this._date);
|
||||
|
||||
if (!this._title.visible)
|
||||
return;
|
||||
}
|
||||
|
||||
let dayFormat;
|
||||
let now = new Date();
|
||||
@ -850,9 +882,6 @@ const EventsSection = new Lang.Class({
|
||||
for (let i = 0; i < events.length; i++) {
|
||||
let event = events[i];
|
||||
|
||||
if (this._ignoredEvents.has(event.id))
|
||||
continue;
|
||||
|
||||
let message = new EventMessage(event, this._date);
|
||||
message.connect('close', Lang.bind(this, function() {
|
||||
this._ignoreEvent(event);
|
||||
@ -885,7 +914,8 @@ const EventsSection = new Lang.Class({
|
||||
},
|
||||
|
||||
_onTitleClicked: function() {
|
||||
this.parent();
|
||||
Main.overview.hide();
|
||||
Main.panel.closeCalendar();
|
||||
|
||||
let app = this._getCalendarApp();
|
||||
if (app.get_id() == 'evolution.desktop')
|
||||
@ -911,12 +941,12 @@ const EventsSection = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const NotificationSection = new Lang.Class({
|
||||
var NotificationSection = new Lang.Class({
|
||||
Name: 'NotificationSection',
|
||||
Extends: MessageList.MessageListSection,
|
||||
|
||||
_init: function() {
|
||||
this.parent(_("Notifications"));
|
||||
this.parent();
|
||||
|
||||
this._sources = new Map();
|
||||
this._nUrgent = 0;
|
||||
@ -934,10 +964,14 @@ const NotificationSection = new Lang.Class({
|
||||
!Main.sessionMode.isGreeter;
|
||||
},
|
||||
|
||||
_createTimeLabel: function() {
|
||||
let label = Util.createTimeLabel(new Date());
|
||||
label.style_class = 'event-time',
|
||||
label.x_align = Clutter.ActorAlign.END;
|
||||
_createTimeLabel: function(datetime) {
|
||||
let label = new St.Label({ style_class: 'event-time',
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
y_align: Clutter.ActorAlign.END });
|
||||
label.connect('notify::mapped', () => {
|
||||
if (label.mapped)
|
||||
label.text = Util.formatTimeSpan(datetime);
|
||||
});
|
||||
return label;
|
||||
},
|
||||
|
||||
@ -958,13 +992,13 @@ const NotificationSection = new Lang.Class({
|
||||
|
||||
_onNotificationAdded: function(source, notification) {
|
||||
let message = new NotificationMessage(notification);
|
||||
message.setSecondaryActor(this._createTimeLabel());
|
||||
message.setSecondaryActor(this._createTimeLabel(notification.datetime));
|
||||
|
||||
let isUrgent = notification.urgency == MessageTray.Urgency.CRITICAL;
|
||||
|
||||
let updatedId = notification.connect('updated', Lang.bind(this,
|
||||
function() {
|
||||
message.setSecondaryActor(this._createTimeLabel());
|
||||
message.setSecondaryActor(this._createTimeLabel(notification.datetime));
|
||||
this.moveMessage(message, isUrgent ? 0 : this._nUrgent, this.actor.mapped);
|
||||
}));
|
||||
let destroyId = notification.connect('destroy', Lang.bind(this,
|
||||
@ -1005,30 +1039,12 @@ const NotificationSection = new Lang.Class({
|
||||
message.notification.acknowledged = true;
|
||||
},
|
||||
|
||||
_onTitleClicked: function() {
|
||||
this.parent();
|
||||
|
||||
let app = Shell.AppSystem.get_default().lookup_app('gnome-notifications-panel.desktop');
|
||||
|
||||
if (!app) {
|
||||
log('Settings panel for desktop file ' + desktopFile + ' could not be loaded!');
|
||||
return;
|
||||
}
|
||||
|
||||
app.activate();
|
||||
},
|
||||
|
||||
_shouldShow: function() {
|
||||
return !this.empty && isToday(this._date);
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
this.parent();
|
||||
this._title.reactive = Main.sessionMode.allowSettings;
|
||||
}
|
||||
});
|
||||
|
||||
const Placeholder = new Lang.Class({
|
||||
var Placeholder = new Lang.Class({
|
||||
Name: 'Placeholder',
|
||||
|
||||
_init: function() {
|
||||
@ -1075,7 +1091,7 @@ const Placeholder = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const CalendarMessageList = new Lang.Class({
|
||||
var CalendarMessageList = new Lang.Class({
|
||||
Name: 'CalendarMessageList',
|
||||
|
||||
_init: function() {
|
||||
@ -1086,12 +1102,26 @@ const CalendarMessageList = new Lang.Class({
|
||||
this._placeholder = new Placeholder();
|
||||
this.actor.add_actor(this._placeholder.actor);
|
||||
|
||||
let box = new St.BoxLayout({ vertical: true,
|
||||
x_expand: true, y_expand: true });
|
||||
this.actor.add_actor(box);
|
||||
|
||||
this._scrollView = new St.ScrollView({ style_class: 'vfade',
|
||||
overlay_scrollbars: true,
|
||||
x_expand: true, y_expand: true,
|
||||
x_fill: true, y_fill: true });
|
||||
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||
this.actor.add_actor(this._scrollView);
|
||||
box.add_actor(this._scrollView);
|
||||
|
||||
this._clearButton = new St.Button({ style_class: 'message-list-clear-button button',
|
||||
label: _("Clear All"),
|
||||
can_focus: true });
|
||||
this._clearButton.set_x_align(Clutter.ActorAlign.END);
|
||||
this._clearButton.connect('clicked', () => {
|
||||
let sections = [...this._sections.keys()];
|
||||
sections.forEach((s) => { s.clear(); });
|
||||
});
|
||||
box.add_actor(this._clearButton);
|
||||
|
||||
this._sectionList = new St.BoxLayout({ style_class: 'message-list-sections',
|
||||
vertical: true,
|
||||
@ -1117,6 +1147,7 @@ const CalendarMessageList = new Lang.Class({
|
||||
destroyId: 0,
|
||||
visibleId: 0,
|
||||
emptyChangedId: 0,
|
||||
canClearChangedId: 0,
|
||||
keyFocusId: 0
|
||||
};
|
||||
obj.destroyId = section.actor.connect('destroy', Lang.bind(this,
|
||||
@ -1127,6 +1158,8 @@ const CalendarMessageList = new Lang.Class({
|
||||
Lang.bind(this, this._sync));
|
||||
obj.emptyChangedId = section.connect('empty-changed',
|
||||
Lang.bind(this, this._sync));
|
||||
obj.canClearChangedId = section.connect('can-clear-changed',
|
||||
Lang.bind(this, this._sync));
|
||||
obj.keyFocusId = section.connect('key-focus-in',
|
||||
Lang.bind(this, this._onKeyFocusIn));
|
||||
|
||||
@ -1140,6 +1173,7 @@ const CalendarMessageList = new Lang.Class({
|
||||
section.actor.disconnect(obj.destroyId);
|
||||
section.actor.disconnect(obj.visibleId);
|
||||
section.disconnect(obj.emptyChangedId);
|
||||
section.disconnect(obj.canClearChangedId);
|
||||
section.disconnect(obj.keyFocusId);
|
||||
|
||||
this._sections.delete(section);
|
||||
@ -1160,10 +1194,16 @@ const CalendarMessageList = new Lang.Class({
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
let showPlaceholder = sections.every(function(s) {
|
||||
let empty = sections.every(function(s) {
|
||||
return s.empty || !s.actor.visible;
|
||||
});
|
||||
this._placeholder.actor.visible = showPlaceholder;
|
||||
this._placeholder.actor.visible = empty;
|
||||
this._clearButton.visible = !empty;
|
||||
|
||||
let canClear = sections.some(function(s) {
|
||||
return s.canClear && s.actor.visible;
|
||||
});
|
||||
this._clearButton.reactive = canClear;
|
||||
},
|
||||
|
||||
setEventSource: function(eventSource) {
|
||||
|
@ -4,7 +4,7 @@ const St = imports.gi.St;
|
||||
|
||||
const Lang = imports.lang;
|
||||
|
||||
const CheckBox = new Lang.Class({
|
||||
var CheckBox = new Lang.Class({
|
||||
Name: 'CheckBox',
|
||||
|
||||
_init: function(label) {
|
||||
|
138
js/ui/closeDialog.js
Normal file
138
js/ui/closeDialog.js
Normal file
@ -0,0 +1,138 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
var FROZEN_WINDOW_BRIGHTNESS = -0.3
|
||||
var DIALOG_TRANSITION_TIME = 0.15
|
||||
|
||||
var CloseDialog = new Lang.Class({
|
||||
Name: 'CloseDialog',
|
||||
Extends: GObject.Object,
|
||||
Implements: [ Meta.CloseDialog ],
|
||||
Properties: {
|
||||
'window': GObject.ParamSpec.override('window', Meta.CloseDialog)
|
||||
},
|
||||
|
||||
_init: function (window) {
|
||||
this.parent();
|
||||
this._window = window;
|
||||
this._dialog = null;
|
||||
},
|
||||
|
||||
get window() {
|
||||
return this._window;
|
||||
},
|
||||
|
||||
set window(window) {
|
||||
this._window = window;
|
||||
},
|
||||
|
||||
_createDialogContent: function () {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let windowApp = tracker.get_window_app(this._window);
|
||||
|
||||
/* Translators: %s is an application name */
|
||||
let title = _("“%s” is not responding.").format(windowApp.get_name());
|
||||
let subtitle = _("You may choose to wait a short while for it to " +
|
||||
"continue or force the application to quit entirely.");
|
||||
let icon = new Gio.ThemedIcon({ name: 'dialog-warning-symbolic' });
|
||||
return new Dialog.MessageDialogContent({ icon, title, subtitle });
|
||||
},
|
||||
|
||||
_initDialog: function () {
|
||||
if (this._dialog)
|
||||
return;
|
||||
|
||||
let windowActor = this._window.get_compositor_private();
|
||||
this._dialog = new Dialog.Dialog(windowActor, 'close-dialog');
|
||||
this._dialog.width = windowActor.width;
|
||||
this._dialog.height = windowActor.height;
|
||||
|
||||
this._dialog.addContent(this._createDialogContent());
|
||||
this._dialog.addButton({ label: _('Force Quit'),
|
||||
action: Lang.bind(this, this._onClose),
|
||||
default: true });
|
||||
this._dialog.addButton({ label: _('Wait'),
|
||||
action: Lang.bind(this, this._onWait),
|
||||
key: Clutter.Escape });
|
||||
|
||||
global.focus_manager.add_group(this._dialog);
|
||||
},
|
||||
|
||||
_addWindowEffect: function () {
|
||||
// We set the effect on the surface actor, so the dialog itself
|
||||
// (which is a child of the MetaWindowActor) does not get the
|
||||
// effect applied itself.
|
||||
let windowActor = this._window.get_compositor_private();
|
||||
let surfaceActor = windowActor.get_first_child();
|
||||
let effect = new Clutter.BrightnessContrastEffect();
|
||||
effect.set_brightness(FROZEN_WINDOW_BRIGHTNESS);
|
||||
surfaceActor.add_effect_with_name("gnome-shell-frozen-window", effect);
|
||||
},
|
||||
|
||||
_removeWindowEffect: function () {
|
||||
let windowActor = this._window.get_compositor_private();
|
||||
let surfaceActor = windowActor.get_first_child();
|
||||
surfaceActor.remove_effect_by_name("gnome-shell-frozen-window");
|
||||
},
|
||||
|
||||
_onWait: function () {
|
||||
this.response(Meta.CloseDialogResponse.WAIT);
|
||||
},
|
||||
|
||||
_onClose: function () {
|
||||
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
|
||||
},
|
||||
|
||||
vfunc_show: function () {
|
||||
if (this._dialog != null)
|
||||
return;
|
||||
|
||||
this._addWindowEffect();
|
||||
this._initDialog();
|
||||
|
||||
this._dialog.scale_y = 0;
|
||||
this._dialog.set_pivot_point(0.5, 0.5);
|
||||
|
||||
Tweener.addTween(this._dialog,
|
||||
{ scale_y: 1,
|
||||
transition: 'linear',
|
||||
time: DIALOG_TRANSITION_TIME,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
Main.layoutManager.trackChrome(this._dialog, { affectsInputRegion: true });
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
vfunc_hide: function () {
|
||||
if (this._dialog == null)
|
||||
return;
|
||||
|
||||
let dialog = this._dialog;
|
||||
this._dialog = null;
|
||||
this._removeWindowEffect();
|
||||
|
||||
Tweener.addTween(dialog,
|
||||
{ scale_y: 0,
|
||||
transition: 'linear',
|
||||
time: DIALOG_TRANSITION_TIME,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
dialog.destroy();
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
vfunc_focus: function () {
|
||||
if (this._dialog)
|
||||
this._dialog.grab_key_focus();
|
||||
}
|
||||
});
|
@ -2,7 +2,7 @@
|
||||
const Lang = imports.lang;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const ComponentManager = new Lang.Class({
|
||||
var ComponentManager = new Lang.Class({
|
||||
Name: 'ComponentManager',
|
||||
|
||||
_init: function() {
|
||||
|
@ -11,15 +11,15 @@ const GnomeSession = imports.misc.gnomeSession;
|
||||
const Main = imports.ui.main;
|
||||
const ShellMountOperation = imports.ui.shellMountOperation;
|
||||
|
||||
const GNOME_SESSION_AUTOMOUNT_INHIBIT = 16;
|
||||
var GNOME_SESSION_AUTOMOUNT_INHIBIT = 16;
|
||||
|
||||
// GSettings keys
|
||||
const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling';
|
||||
const SETTING_ENABLE_AUTOMOUNT = 'automount';
|
||||
|
||||
const AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
|
||||
var AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
|
||||
|
||||
const AutomountManager = new Lang.Class({
|
||||
var AutomountManager = new Lang.Class({
|
||||
Name: 'AutomountManager',
|
||||
|
||||
_init: function() {
|
||||
@ -242,4 +242,4 @@ const AutomountManager = new Lang.Class({
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
|
||||
}
|
||||
});
|
||||
const Component = AutomountManager;
|
||||
var Component = AutomountManager;
|
||||
|
@ -7,7 +7,6 @@ const St = imports.gi.St;
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const ShellMountOperation = imports.ui.shellMountOperation;
|
||||
|
||||
// GSettings keys
|
||||
const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling';
|
||||
@ -16,7 +15,7 @@ const SETTING_START_APP = 'autorun-x-content-start-app';
|
||||
const SETTING_IGNORE = 'autorun-x-content-ignore';
|
||||
const SETTING_OPEN_FOLDER = 'autorun-x-content-open-folder';
|
||||
|
||||
const AutorunSetting = {
|
||||
var AutorunSetting = {
|
||||
RUN: 0,
|
||||
IGNORE: 1,
|
||||
FILES: 2,
|
||||
@ -64,7 +63,7 @@ function startAppForMount(app, mount) {
|
||||
|
||||
try {
|
||||
retval = app.launch(files,
|
||||
global.create_app_launch_context(0, -1))
|
||||
global.create_app_launch_context(0, -1));
|
||||
} catch (e) {
|
||||
log('Unable to launch the application ' + app.get_name()
|
||||
+ ': ' + e.toString());
|
||||
@ -91,7 +90,7 @@ function HotplugSniffer() {
|
||||
'/org/gnome/Shell/HotplugSniffer');
|
||||
}
|
||||
|
||||
const ContentTypeDiscoverer = new Lang.Class({
|
||||
var ContentTypeDiscoverer = new Lang.Class({
|
||||
Name: 'ContentTypeDiscoverer',
|
||||
|
||||
_init: function(callback) {
|
||||
@ -160,7 +159,7 @@ const ContentTypeDiscoverer = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const AutorunManager = new Lang.Class({
|
||||
var AutorunManager = new Lang.Class({
|
||||
Name: 'AutorunManager',
|
||||
|
||||
_init: function() {
|
||||
@ -197,7 +196,7 @@ const AutorunManager = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const AutorunDispatcher = new Lang.Class({
|
||||
var AutorunDispatcher = new Lang.Class({
|
||||
Name: 'AutorunDispatcher',
|
||||
|
||||
_init: function(manager) {
|
||||
@ -293,7 +292,7 @@ const AutorunDispatcher = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const AutorunSource = new Lang.Class({
|
||||
var AutorunSource = new Lang.Class({
|
||||
Name: 'AutorunSource',
|
||||
Extends: MessageTray.Source,
|
||||
|
||||
@ -320,7 +319,7 @@ const AutorunSource = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const AutorunNotification = new Lang.Class({
|
||||
var AutorunNotification = new Lang.Class({
|
||||
Name: 'AutorunNotification',
|
||||
Extends: MessageTray.Notification,
|
||||
|
||||
@ -379,4 +378,4 @@ const AutorunNotification = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const Component = AutorunManager;
|
||||
var Component = AutorunManager;
|
||||
|
@ -10,16 +10,17 @@ const GObject = imports.gi.GObject;
|
||||
const Gcr = imports.gi.Gcr;
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const CheckBox = imports.ui.checkBox;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const WORK_SPINNER_ICON_SIZE = 16;
|
||||
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
|
||||
const WORK_SPINNER_ANIMATION_TIME = 0.3;
|
||||
var WORK_SPINNER_ICON_SIZE = 16;
|
||||
var WORK_SPINNER_ANIMATION_DELAY = 1.0;
|
||||
var WORK_SPINNER_ANIMATION_TIME = 0.3;
|
||||
|
||||
const KeyringDialog = new Lang.Class({
|
||||
var KeyringDialog = new Lang.Class({
|
||||
Name: 'KeyringDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
@ -31,38 +32,24 @@ const KeyringDialog = new Lang.Class({
|
||||
this.prompt.connect('show-confirm', Lang.bind(this, this._onShowConfirm));
|
||||
this.prompt.connect('prompt-close', Lang.bind(this, this._onHidePrompt));
|
||||
|
||||
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
||||
vertical: false });
|
||||
this.contentLayout.add(mainContentBox);
|
||||
let icon = new Gio.ThemedIcon({ name: 'dialog-password-symbolic' });
|
||||
this._content = new Dialog.MessageDialogContent({ icon });
|
||||
this.contentLayout.add(this._content);
|
||||
|
||||
let icon = new St.Icon({ icon_name: 'dialog-password-symbolic' });
|
||||
mainContentBox.add(icon,
|
||||
{ x_fill: true,
|
||||
y_fill: false,
|
||||
x_align: St.Align.END,
|
||||
y_align: St.Align.START });
|
||||
// FIXME: Why does this break now?
|
||||
/*
|
||||
this.prompt.bind_property('message', this._content, 'title', GObject.BindingFlags.SYNC_CREATE);
|
||||
this.prompt.bind_property('description', this._content, 'body', GObject.BindingFlags.SYNC_CREATE);
|
||||
*/
|
||||
this.prompt.connect('notify::message', () => {
|
||||
this._content.title = this.prompt.message;
|
||||
});
|
||||
this._content.title = this.prompt.message;
|
||||
|
||||
this._messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
|
||||
vertical: true });
|
||||
mainContentBox.add(this._messageBox,
|
||||
{ y_align: St.Align.START, expand: true, x_fill: true, y_fill: true });
|
||||
|
||||
let subject = new St.Label({ style_class: 'prompt-dialog-headline headline' });
|
||||
this.prompt.bind_property('message', subject, 'text', GObject.BindingFlags.SYNC_CREATE);
|
||||
|
||||
this._messageBox.add(subject,
|
||||
{ x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
|
||||
let description = new St.Label({ style_class: 'prompt-dialog-description' });
|
||||
description.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
description.clutter_text.line_wrap = true;
|
||||
this.prompt.bind_property('description', description, 'text', GObject.BindingFlags.SYNC_CREATE);
|
||||
this._messageBox.add(description,
|
||||
{ y_fill: true,
|
||||
y_align: St.Align.START });
|
||||
this.prompt.connect('notify::description', () => {
|
||||
this._content.body = this.prompt.description;
|
||||
});
|
||||
this._content.body = this.prompt.description;
|
||||
|
||||
this._workSpinner = null;
|
||||
this._controlTable = null;
|
||||
@ -195,7 +182,7 @@ const KeyringDialog = new Lang.Class({
|
||||
}
|
||||
|
||||
this._controlTable = table;
|
||||
this._messageBox.add(table, { x_fill: true, y_fill: true });
|
||||
this._content.messageBox.add(table, { x_fill: true, y_fill: true });
|
||||
},
|
||||
|
||||
_updateSensitivity: function(sensitive) {
|
||||
@ -271,7 +258,7 @@ const KeyringDialog = new Lang.Class({
|
||||
},
|
||||
});
|
||||
|
||||
const KeyringDummyDialog = new Lang.Class({
|
||||
var KeyringDummyDialog = new Lang.Class({
|
||||
Name: 'KeyringDummyDialog',
|
||||
|
||||
_init: function() {
|
||||
@ -287,7 +274,7 @@ const KeyringDummyDialog = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const KeyringPrompter = new Lang.Class({
|
||||
var KeyringPrompter = new Lang.Class({
|
||||
Name: 'KeyringPrompter',
|
||||
|
||||
_init: function() {
|
||||
@ -324,4 +311,4 @@ const KeyringPrompter = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const Component = KeyringPrompter;
|
||||
var Component = KeyringPrompter;
|
||||
|
@ -12,6 +12,7 @@ const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
@ -20,7 +21,7 @@ const ShellEntry = imports.ui.shellEntry;
|
||||
|
||||
const VPN_UI_GROUP = 'VPN Plugin UI';
|
||||
|
||||
const NetworkSecretDialog = new Lang.Class({
|
||||
var NetworkSecretDialog = new Lang.Class({
|
||||
Name: 'NetworkSecretDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
@ -38,41 +39,12 @@ const NetworkSecretDialog = new Lang.Class({
|
||||
else
|
||||
this._content = this._getContent();
|
||||
|
||||
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
||||
vertical: false });
|
||||
this.contentLayout.add(mainContentBox,
|
||||
{ x_fill: true,
|
||||
y_fill: true });
|
||||
|
||||
let icon = new St.Icon({ icon_name: 'dialog-password-symbolic' });
|
||||
mainContentBox.add(icon,
|
||||
{ x_fill: true,
|
||||
y_fill: false,
|
||||
x_align: St.Align.END,
|
||||
y_align: St.Align.START });
|
||||
|
||||
let messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
|
||||
vertical: true });
|
||||
mainContentBox.add(messageBox,
|
||||
{ y_align: St.Align.START });
|
||||
|
||||
let subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline headline',
|
||||
text: this._content.title });
|
||||
messageBox.add(subjectLabel,
|
||||
{ y_fill: false,
|
||||
y_align: St.Align.START });
|
||||
|
||||
if (this._content.message != null) {
|
||||
let descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
|
||||
text: this._content.message });
|
||||
descriptionLabel.clutter_text.line_wrap = true;
|
||||
descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
|
||||
messageBox.add(descriptionLabel,
|
||||
{ y_fill: true,
|
||||
y_align: St.Align.START,
|
||||
expand: true });
|
||||
}
|
||||
let icon = new Gio.ThemedIcon({ name: 'dialog-password-symbolic' });
|
||||
let contentParams = { icon,
|
||||
title: this._content.title,
|
||||
body: this._content.message };
|
||||
let contentBox = new Dialog.MessageDialogContent(contentParams);
|
||||
this.contentLayout.add_actor(contentBox);
|
||||
|
||||
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
|
||||
let secretTable = new St.Widget({ style_class: 'network-dialog-secret-table',
|
||||
@ -135,7 +107,7 @@ const NetworkSecretDialog = new Lang.Class({
|
||||
secret.entry.clutter_text.set_password_char('\u25cf');
|
||||
}
|
||||
|
||||
messageBox.add(secretTable);
|
||||
contentBox.messageBox.add(secretTable);
|
||||
|
||||
this._okButton = { label: _("Connect"),
|
||||
action: Lang.bind(this, this._onOk),
|
||||
@ -357,7 +329,7 @@ const NetworkSecretDialog = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const VPNRequestHandler = new Lang.Class({
|
||||
var VPNRequestHandler = new Lang.Class({
|
||||
Name: 'VPNRequestHandler',
|
||||
|
||||
_init: function(agent, requestId, authHelper, serviceType, connection, hints, flags) {
|
||||
@ -603,7 +575,7 @@ const VPNRequestHandler = new Lang.Class({
|
||||
},
|
||||
});
|
||||
|
||||
const NetworkAgent = new Lang.Class({
|
||||
var NetworkAgent = new Lang.Class({
|
||||
Name: 'NetworkAgent',
|
||||
|
||||
_init: function() {
|
||||
@ -615,6 +587,14 @@ const NetworkAgent = new Lang.Class({
|
||||
this._vpnRequests = { };
|
||||
this._notifications = { };
|
||||
|
||||
this._pluginDir = Gio.file_new_for_path(GLib.build_filenamev([Config.SYSCONFDIR, 'NetworkManager/VPN']));
|
||||
try {
|
||||
let monitor = this._pluginDir.monitor(Gio.FileMonitorFlags.NONE, null);
|
||||
monitor.connect('changed', () => { this._vpnCacheBuilt = false; });
|
||||
} catch(e) {
|
||||
log('Failed to create monitor for VPN plugin dir: ' + e.message);
|
||||
}
|
||||
|
||||
this._native.connect('new-request', Lang.bind(this, this._newRequest));
|
||||
this._native.connect('cancel-request', Lang.bind(this, this._cancelRequest));
|
||||
|
||||
@ -765,9 +745,8 @@ const NetworkAgent = new Lang.Class({
|
||||
this._vpnCacheBuilt = true;
|
||||
this._vpnBinaries = { };
|
||||
|
||||
let dir = Gio.file_new_for_path(GLib.build_filenamev([Config.SYSCONFDIR, 'NetworkManager/VPN']));
|
||||
try {
|
||||
let fileEnum = dir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
|
||||
let fileEnum = this._pluginDir.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
|
||||
let info;
|
||||
|
||||
while ((info = fileEnum.next_file(null))) {
|
||||
@ -777,7 +756,7 @@ const NetworkAgent = new Lang.Class({
|
||||
|
||||
try {
|
||||
let keyfile = new GLib.KeyFile();
|
||||
keyfile.load_from_file(dir.get_child(name).get_path(), GLib.KeyFileFlags.NONE);
|
||||
keyfile.load_from_file(this._pluginDir.get_child(name).get_path(), GLib.KeyFileFlags.NONE);
|
||||
let service = keyfile.get_string('VPN Connection', 'service');
|
||||
let binary = keyfile.get_string('GNOME', 'auth-dialog');
|
||||
let externalUIMode = false;
|
||||
@ -796,13 +775,21 @@ const NetworkAgent = new Lang.Class({
|
||||
path = GLib.build_filenamev([Config.LIBEXECDIR, path]);
|
||||
}
|
||||
|
||||
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE))
|
||||
if (GLib.file_test(path, GLib.FileTest.IS_EXECUTABLE)) {
|
||||
this._vpnBinaries[service] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
|
||||
else
|
||||
try {
|
||||
let aliases = keyfile.get_string_list('VPN Connection', 'aliases');
|
||||
|
||||
for (let alias of aliases) {
|
||||
this._vpnBinaries[alias] = { fileName: path, externalUIMode: externalUIMode, supportsHints: hints };
|
||||
}
|
||||
} catch(e) { } // ignore errors if key does not exist
|
||||
} else {
|
||||
throw new Error('VPN plugin at %s is not executable'.format(path));
|
||||
}
|
||||
} catch(e) {
|
||||
log('Error \'%s\' while processing VPN keyfile \'%s\''.
|
||||
format(e.message, dir.get_child(name).get_path()));
|
||||
format(e.message, this._pluginDir.get_child(name).get_path()));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -811,4 +798,4 @@ const NetworkAgent = new Lang.Class({
|
||||
}
|
||||
}
|
||||
});
|
||||
const Component = NetworkAgent;
|
||||
var Component = NetworkAgent;
|
||||
|
@ -15,66 +15,35 @@ const PolkitAgent = imports.gi.PolkitAgent;
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
const Components = imports.ui.components;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const DIALOG_ICON_SIZE = 48;
|
||||
var DIALOG_ICON_SIZE = 48;
|
||||
|
||||
const WORK_SPINNER_ICON_SIZE = 16;
|
||||
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
|
||||
const WORK_SPINNER_ANIMATION_TIME = 0.3;
|
||||
var WORK_SPINNER_ICON_SIZE = 16;
|
||||
var WORK_SPINNER_ANIMATION_DELAY = 1.0;
|
||||
var WORK_SPINNER_ANIMATION_TIME = 0.3;
|
||||
|
||||
const AuthenticationDialog = new Lang.Class({
|
||||
var AuthenticationDialog = new Lang.Class({
|
||||
Name: 'AuthenticationDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
_init: function(actionId, message, cookie, userNames) {
|
||||
_init: function(actionId, body, cookie, userNames) {
|
||||
this.parent({ styleClass: 'prompt-dialog' });
|
||||
|
||||
this.actionId = actionId;
|
||||
this.message = message;
|
||||
this.message = body;
|
||||
this.userNames = userNames;
|
||||
this._wasDismissed = false;
|
||||
|
||||
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
||||
vertical: false });
|
||||
this.contentLayout.add(mainContentBox,
|
||||
{ x_fill: true,
|
||||
y_fill: true });
|
||||
let icon = new Gio.ThemedIcon({ name: 'dialog-password-symbolic' });
|
||||
let title = _("Authentication Required");
|
||||
|
||||
let icon = new St.Icon({ icon_name: 'dialog-password-symbolic' });
|
||||
mainContentBox.add(icon,
|
||||
{ x_fill: true,
|
||||
y_fill: false,
|
||||
x_align: St.Align.END,
|
||||
y_align: St.Align.START });
|
||||
|
||||
let messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
|
||||
vertical: true });
|
||||
mainContentBox.add(messageBox,
|
||||
{ expand: true, y_align: St.Align.START });
|
||||
|
||||
this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline headline',
|
||||
text: _("Authentication Required") });
|
||||
|
||||
messageBox.add(this._subjectLabel,
|
||||
{ x_fill: false,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
|
||||
this._descriptionLabel = new St.Label({ style_class: 'prompt-dialog-description',
|
||||
text: message });
|
||||
this._descriptionLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._descriptionLabel.clutter_text.line_wrap = true;
|
||||
|
||||
messageBox.add(this._descriptionLabel,
|
||||
{ x_fill: false,
|
||||
y_fill: true,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START });
|
||||
let content = new Dialog.MessageDialogContent({ icon, title, body });
|
||||
this.contentLayout.add_actor(content);
|
||||
|
||||
if (userNames.length > 1) {
|
||||
log('polkitAuthenticationAgent: Received ' + userNames.length +
|
||||
@ -105,12 +74,12 @@ const AuthenticationDialog = new Lang.Class({
|
||||
if (userIsRoot) {
|
||||
let userLabel = new St.Label(({ style_class: 'polkit-dialog-user-root-label',
|
||||
text: userRealName }));
|
||||
messageBox.add(userLabel, { x_fill: false,
|
||||
x_align: St.Align.START });
|
||||
content.messageBox.add(userLabel, { x_fill: false,
|
||||
x_align: St.Align.START });
|
||||
} else {
|
||||
let userBox = new St.BoxLayout({ style_class: 'polkit-dialog-user-layout',
|
||||
vertical: false });
|
||||
messageBox.add(userBox);
|
||||
content.messageBox.add(userBox);
|
||||
this._userAvatar = new UserWidget.Avatar(this._user,
|
||||
{ iconSize: DIALOG_ICON_SIZE,
|
||||
styleClass: 'polkit-dialog-user-icon' });
|
||||
@ -132,7 +101,7 @@ const AuthenticationDialog = new Lang.Class({
|
||||
this._onUserChanged();
|
||||
|
||||
this._passwordBox = new St.BoxLayout({ vertical: false, style_class: 'prompt-dialog-password-box' });
|
||||
messageBox.add(this._passwordBox);
|
||||
content.messageBox.add(this._passwordBox);
|
||||
this._passwordLabel = new St.Label(({ style_class: 'prompt-dialog-password-label' }));
|
||||
this._passwordBox.add(this._passwordLabel, { y_fill: false, y_align: St.Align.MIDDLE });
|
||||
this._passwordEntry = new St.Entry({ style_class: 'prompt-dialog-password-entry',
|
||||
@ -155,13 +124,13 @@ const AuthenticationDialog = new Lang.Class({
|
||||
this._errorMessageLabel = new St.Label({ style_class: 'prompt-dialog-error-label' });
|
||||
this._errorMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._errorMessageLabel.clutter_text.line_wrap = true;
|
||||
messageBox.add(this._errorMessageLabel, { x_fill: false, x_align: St.Align.START });
|
||||
content.messageBox.add(this._errorMessageLabel, { x_fill: false, x_align: St.Align.START });
|
||||
this._errorMessageLabel.hide();
|
||||
|
||||
this._infoMessageLabel = new St.Label({ style_class: 'prompt-dialog-info-label' });
|
||||
this._infoMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._infoMessageLabel.clutter_text.line_wrap = true;
|
||||
messageBox.add(this._infoMessageLabel);
|
||||
content.messageBox.add(this._infoMessageLabel);
|
||||
this._infoMessageLabel.hide();
|
||||
|
||||
/* text is intentionally non-blank otherwise the height is not the same as for
|
||||
@ -173,7 +142,7 @@ const AuthenticationDialog = new Lang.Class({
|
||||
this._nullMessageLabel.add_style_class_name('hidden');
|
||||
this._nullMessageLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._nullMessageLabel.clutter_text.line_wrap = true;
|
||||
messageBox.add(this._nullMessageLabel);
|
||||
content.messageBox.add(this._nullMessageLabel);
|
||||
this._nullMessageLabel.show();
|
||||
|
||||
this._cancelButton = this.addButton({ label: _("Cancel"),
|
||||
@ -298,7 +267,7 @@ const AuthenticationDialog = new Lang.Class({
|
||||
* requested authentication was not gained; this can happen
|
||||
* because of an authentication error (like invalid password),
|
||||
* for instance. */
|
||||
this._errorMessageLabel.set_text(_("Sorry, that didn\'t work. Please try again."));
|
||||
this._errorMessageLabel.set_text(_("Sorry, that didn’t work. Please try again."));
|
||||
this._errorMessageLabel.show();
|
||||
this._infoMessageLabel.hide();
|
||||
this._nullMessageLabel.hide();
|
||||
@ -370,7 +339,7 @@ const AuthenticationDialog = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(AuthenticationDialog.prototype);
|
||||
|
||||
const AuthenticationAgent = new Lang.Class({
|
||||
var AuthenticationAgent = new Lang.Class({
|
||||
Name: 'AuthenticationAgent',
|
||||
|
||||
_init: function() {
|
||||
@ -431,4 +400,4 @@ const AuthenticationAgent = new Lang.Class({
|
||||
},
|
||||
});
|
||||
|
||||
const Component = AuthenticationAgent;
|
||||
var Component = AuthenticationAgent;
|
||||
|
@ -6,11 +6,17 @@ const GLib = imports.gi.GLib;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Tpl = imports.gi.TelepathyLogger;
|
||||
const Tp = imports.gi.TelepathyGLib;
|
||||
|
||||
var Tpl = null;
|
||||
var Tp = null;
|
||||
try {
|
||||
Tpl = imports.gi.TelepathyLogger;
|
||||
Tp = imports.gi.TelepathyGLib;
|
||||
} catch(e) {
|
||||
log('Telepathy is not available, chat integration will be disabled.');
|
||||
}
|
||||
|
||||
const History = imports.misc.history;
|
||||
const Main = imports.ui.main;
|
||||
@ -20,26 +26,28 @@ const Params = imports.misc.params;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const HAVE_TP = (Tp != null && Tpl != null);
|
||||
|
||||
// See Notification.appendMessage
|
||||
const SCROLLBACK_IMMEDIATE_TIME = 3 * 60; // 3 minutes
|
||||
const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
||||
const SCROLLBACK_RECENT_LENGTH = 20;
|
||||
const SCROLLBACK_IDLE_LENGTH = 5;
|
||||
var SCROLLBACK_IMMEDIATE_TIME = 3 * 60; // 3 minutes
|
||||
var SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
||||
var SCROLLBACK_RECENT_LENGTH = 20;
|
||||
var SCROLLBACK_IDLE_LENGTH = 5;
|
||||
|
||||
// See Source._displayPendingMessages
|
||||
const SCROLLBACK_HISTORY_LINES = 10;
|
||||
var SCROLLBACK_HISTORY_LINES = 10;
|
||||
|
||||
// See Notification._onEntryChanged
|
||||
const COMPOSING_STOP_TIMEOUT = 5;
|
||||
var COMPOSING_STOP_TIMEOUT = 5;
|
||||
|
||||
const CHAT_EXPAND_LINES = 12;
|
||||
var CHAT_EXPAND_LINES = 12;
|
||||
|
||||
const NotificationDirection = {
|
||||
var NotificationDirection = {
|
||||
SENT: 'chat-sent',
|
||||
RECEIVED: 'chat-received'
|
||||
};
|
||||
|
||||
const N_ = function(s) { return s; };
|
||||
var N_ = function(s) { return s; };
|
||||
|
||||
function makeMessageFromTpMessage(tpMessage, direction) {
|
||||
let [text, flags] = tpMessage.to_text();
|
||||
@ -71,8 +79,43 @@ function makeMessageFromTplEvent(event) {
|
||||
};
|
||||
}
|
||||
|
||||
const TelepathyClient = new Lang.Class({
|
||||
var TelepathyComponent = new Lang.Class({
|
||||
Name: 'TelepathyComponent',
|
||||
|
||||
_init: function() {
|
||||
this._client = null;
|
||||
|
||||
if (!HAVE_TP)
|
||||
return; // Telepathy isn't available
|
||||
|
||||
this._client = new TelepathyClient();
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
if (!this._client)
|
||||
return;
|
||||
|
||||
try {
|
||||
this._client.register();
|
||||
} catch (e) {
|
||||
throw new Error('Couldn\'t register Telepathy client. Error: \n' + e);
|
||||
}
|
||||
|
||||
if (!this._client.account_manager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
|
||||
this._client.account_manager.prepare_async(null, null);
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
if (!this._client)
|
||||
return;
|
||||
|
||||
this._client.unregister();
|
||||
}
|
||||
});
|
||||
|
||||
var TelepathyClient = HAVE_TP ? new Lang.Class({
|
||||
Name: 'TelepathyClient',
|
||||
Extends: Tp.BaseClient,
|
||||
|
||||
_init: function() {
|
||||
// channel path -> ChatSource
|
||||
@ -97,39 +140,28 @@ const TelepathyClient = new Lang.Class({
|
||||
// channel matching its filters is detected.
|
||||
// The second argument, recover, means _observeChannels will be run
|
||||
// for any existing channel as well.
|
||||
this._tpClient = new Shell.TpClient({ name: 'GnomeShell',
|
||||
account_manager: this._accountManager,
|
||||
uniquify_name: true });
|
||||
this._tpClient.set_observe_channels_func(
|
||||
Lang.bind(this, this._observeChannels));
|
||||
this._tpClient.set_approve_channels_func(
|
||||
Lang.bind(this, this._approveChannels));
|
||||
this._tpClient.set_handle_channels_func(
|
||||
Lang.bind(this, this._handleChannels));
|
||||
this.parent({ name: 'GnomeShell',
|
||||
account_manager: this._accountManager,
|
||||
uniquify_name: true });
|
||||
|
||||
// We only care about single-user text-based chats
|
||||
let filter = {};
|
||||
filter[Tp.PROP_CHANNEL_CHANNEL_TYPE] = Tp.IFACE_CHANNEL_TYPE_TEXT;
|
||||
filter[Tp.PROP_CHANNEL_TARGET_HANDLE_TYPE] = Tp.HandleType.CONTACT;
|
||||
|
||||
this.set_observer_recover(true);
|
||||
this.add_observer_filter(filter);
|
||||
this.add_approver_filter(filter);
|
||||
this.add_handler_filter(filter);
|
||||
|
||||
// Allow other clients (such as Empathy) to pre-empt our channels if
|
||||
// needed
|
||||
this._tpClient.set_delegated_channels_callback(
|
||||
this.set_delegated_channels_callback(
|
||||
Lang.bind(this, this._delegatedChannelsCb));
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
try {
|
||||
this._tpClient.register();
|
||||
} catch (e) {
|
||||
throw new Error('Couldn\'t register Telepathy client. Error: \n' + e);
|
||||
}
|
||||
|
||||
if (!this._accountManager.is_prepared(Tp.AccountManager.get_feature_quark_core()))
|
||||
this._accountManager.prepare_async(null, null);
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
this._tpClient.unregister();
|
||||
},
|
||||
|
||||
_observeChannels: function(observer, account, conn, channels,
|
||||
dispatchOp, requests, context) {
|
||||
vfunc_observe_channels: function(account, conn, channels,
|
||||
dispatchOp, requests, context) {
|
||||
let len = channels.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
let channel = channels[i];
|
||||
@ -153,7 +185,7 @@ const TelepathyClient = new Lang.Class({
|
||||
if (this._chatSources[channel.get_object_path()])
|
||||
return;
|
||||
|
||||
let source = new ChatSource(account, conn, channel, contact, this._tpClient);
|
||||
let source = new ChatSource(account, conn, channel, contact, this);
|
||||
|
||||
this._chatSources[channel.get_object_path()] = source;
|
||||
source.connect('destroy', Lang.bind(this,
|
||||
@ -162,8 +194,8 @@ const TelepathyClient = new Lang.Class({
|
||||
}));
|
||||
},
|
||||
|
||||
_handleChannels: function(handler, account, conn, channels,
|
||||
requests, user_action_time, context) {
|
||||
vfunc_handle_channels: function(account, conn, channels, requests,
|
||||
user_action_time, context) {
|
||||
this._handlingChannels(account, conn, channels, true);
|
||||
context.accept();
|
||||
},
|
||||
@ -193,7 +225,7 @@ const TelepathyClient = new Lang.Class({
|
||||
// Telepathy spec states that handlers must foreground channels
|
||||
// in HandleChannels calls which are already being handled.
|
||||
|
||||
if (notify && this._tpClient.is_handling_channel(channel)) {
|
||||
if (notify && this.is_handling_channel(channel)) {
|
||||
// We are already handling the channel, display the source
|
||||
let source = this._chatSources[channel.get_object_path()];
|
||||
if (source)
|
||||
@ -202,8 +234,8 @@ const TelepathyClient = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
_approveChannels: function(approver, account, conn, channels,
|
||||
dispatchOp, context) {
|
||||
vfunc_add_dispatch_operation: function(account, conn, channels,
|
||||
dispatchOp, context) {
|
||||
let channel = channels[0];
|
||||
let chanType = channel.get_channel_type();
|
||||
|
||||
@ -230,7 +262,7 @@ const TelepathyClient = new Lang.Class({
|
||||
}
|
||||
|
||||
// Approve private text channels right away as we are going to handle it
|
||||
dispatchOp.claim_with_async(this._tpClient, Lang.bind(this, function(dispatchOp, result) {
|
||||
dispatchOp.claim_with_async(this, Lang.bind(this, function(dispatchOp, result) {
|
||||
try {
|
||||
dispatchOp.claim_with_finish(result);
|
||||
this._handlingChannels(account, conn, [channel], false);
|
||||
@ -246,9 +278,9 @@ const TelepathyClient = new Lang.Class({
|
||||
// Nothing to do as we don't make a distinction between observed and
|
||||
// handled channels.
|
||||
},
|
||||
});
|
||||
}) : null;
|
||||
|
||||
const ChatSource = new Lang.Class({
|
||||
var ChatSource = new Lang.Class({
|
||||
Name: 'ChatSource',
|
||||
Extends: MessageTray.Source,
|
||||
|
||||
@ -475,6 +507,11 @@ const ChatSource = new Lang.Class({
|
||||
this._channel.close_async(function(channel, result) {
|
||||
channel.close_finish(result);
|
||||
});
|
||||
} else {
|
||||
// Don't indicate any unread messages when the notification
|
||||
// that represents them has been destroyed.
|
||||
this._pendingMessages = [];
|
||||
this.countUpdated();
|
||||
}
|
||||
|
||||
// Keep source alive while the channel is open
|
||||
@ -610,7 +647,7 @@ const ChatSource = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const ChatNotification = new Lang.Class({
|
||||
var ChatNotification = new Lang.Class({
|
||||
Name: 'ChatNotification',
|
||||
Extends: MessageTray.Notification,
|
||||
|
||||
@ -655,7 +692,9 @@ const ChatNotification = new Lang.Class({
|
||||
}
|
||||
|
||||
if (message.direction == NotificationDirection.RECEIVED)
|
||||
this.update(this.source.title, messageBody, { bannerMarkup: true });
|
||||
this.update(this.source.title, messageBody,
|
||||
{ datetime: GLib.DateTime.new_from_unix_local (message.timestamp),
|
||||
bannerMarkup: true });
|
||||
|
||||
let group = (message.direction == NotificationDirection.RECEIVED ?
|
||||
'received' : 'sent');
|
||||
@ -767,7 +806,7 @@ const ChatNotification = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const ChatLineBox = new Lang.Class({
|
||||
var ChatLineBox = new Lang.Class({
|
||||
Name: 'ChatLineBox',
|
||||
Extends: St.BoxLayout,
|
||||
|
||||
@ -777,7 +816,7 @@ const ChatLineBox = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const ChatNotificationBanner = new Lang.Class({
|
||||
var ChatNotificationBanner = new Lang.Class({
|
||||
Name: 'ChatNotificationBanner',
|
||||
Extends: MessageTray.NotificationBanner,
|
||||
|
||||
@ -957,4 +996,4 @@ const ChatNotificationBanner = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const Component = TelepathyClient;
|
||||
var Component = TelepathyComponent;
|
||||
|
@ -12,16 +12,16 @@ const SwitcherPopup = imports.ui.switcherPopup;
|
||||
const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const POPUP_APPICON_SIZE = 96;
|
||||
const POPUP_FADE_TIME = 0.1; // seconds
|
||||
var POPUP_APPICON_SIZE = 96;
|
||||
var POPUP_FADE_TIME = 0.1; // seconds
|
||||
|
||||
const SortGroup = {
|
||||
var SortGroup = {
|
||||
TOP: 0,
|
||||
MIDDLE: 1,
|
||||
BOTTOM: 2
|
||||
};
|
||||
|
||||
const CtrlAltTabManager = new Lang.Class({
|
||||
var CtrlAltTabManager = new Lang.Class({
|
||||
Name: 'CtrlAltTabManager',
|
||||
|
||||
_init: function() {
|
||||
@ -136,7 +136,7 @@ const CtrlAltTabManager = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const CtrlAltTabPopup = new Lang.Class({
|
||||
var CtrlAltTabPopup = new Lang.Class({
|
||||
Name: 'CtrlAltTabPopup',
|
||||
Extends: SwitcherPopup.SwitcherPopup,
|
||||
|
||||
@ -167,7 +167,7 @@ const CtrlAltTabPopup = new Lang.Class({
|
||||
},
|
||||
});
|
||||
|
||||
const CtrlAltTabSwitcher = new Lang.Class({
|
||||
var CtrlAltTabSwitcher = new Lang.Class({
|
||||
Name: 'CtrlAltTabSwitcher',
|
||||
Extends: SwitcherPopup.SwitcherList,
|
||||
|
||||
|
@ -18,10 +18,10 @@ const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Workspace = imports.ui.workspace;
|
||||
|
||||
const DASH_ANIMATION_TIME = 0.2;
|
||||
const DASH_ITEM_LABEL_SHOW_TIME = 0.15;
|
||||
const DASH_ITEM_LABEL_HIDE_TIME = 0.1;
|
||||
const DASH_ITEM_HOVER_TIMEOUT = 300;
|
||||
var DASH_ANIMATION_TIME = 0.2;
|
||||
var DASH_ITEM_LABEL_SHOW_TIME = 0.15;
|
||||
var DASH_ITEM_LABEL_HIDE_TIME = 0.1;
|
||||
var DASH_ITEM_HOVER_TIMEOUT = 300;
|
||||
|
||||
function getAppFromSource(source) {
|
||||
if (source instanceof AppDisplay.AppIcon) {
|
||||
@ -33,7 +33,7 @@ function getAppFromSource(source) {
|
||||
|
||||
// A container like StBin, but taking the child's scale into account
|
||||
// when requesting a size
|
||||
const DashItemContainer = new Lang.Class({
|
||||
var DashItemContainer = new Lang.Class({
|
||||
Name: 'DashItemContainer',
|
||||
Extends: St.Widget,
|
||||
|
||||
@ -235,7 +235,7 @@ const DashItemContainer = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const ShowAppsIcon = new Lang.Class({
|
||||
var ShowAppsIcon = new Lang.Class({
|
||||
Name: 'ShowAppsIcon',
|
||||
Extends: DashItemContainer,
|
||||
|
||||
@ -315,7 +315,7 @@ const ShowAppsIcon = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const DragPlaceholderItem = new Lang.Class({
|
||||
var DragPlaceholderItem = new Lang.Class({
|
||||
Name: 'DragPlaceholderItem',
|
||||
Extends: DashItemContainer,
|
||||
|
||||
@ -325,7 +325,7 @@ const DragPlaceholderItem = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const EmptyDropTargetItem = new Lang.Class({
|
||||
var EmptyDropTargetItem = new Lang.Class({
|
||||
Name: 'EmptyDropTargetItem',
|
||||
Extends: DashItemContainer,
|
||||
|
||||
@ -335,7 +335,7 @@ const EmptyDropTargetItem = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const DashActor = new Lang.Class({
|
||||
var DashActor = new Lang.Class({
|
||||
Name: 'DashActor',
|
||||
Extends: St.Widget,
|
||||
|
||||
@ -387,7 +387,7 @@ const DashActor = new Lang.Class({
|
||||
|
||||
const baseIconSizes = [ 16, 22, 24, 32, 48, 64 ];
|
||||
|
||||
const Dash = new Lang.Class({
|
||||
var Dash = new Lang.Class({
|
||||
Name: 'Dash',
|
||||
|
||||
_init : function() {
|
||||
@ -756,42 +756,44 @@ const Dash = new Lang.Class({
|
||||
let newIndex = 0;
|
||||
let oldIndex = 0;
|
||||
while (newIndex < newApps.length || oldIndex < oldApps.length) {
|
||||
let oldApp = oldApps.length > oldIndex ? oldApps[oldIndex] : null;
|
||||
let newApp = newApps.length > newIndex ? newApps[newIndex] : null;
|
||||
|
||||
// No change at oldIndex/newIndex
|
||||
if (oldApps[oldIndex] == newApps[newIndex]) {
|
||||
if (oldApp == newApp) {
|
||||
oldIndex++;
|
||||
newIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// App removed at oldIndex
|
||||
if (oldApps[oldIndex] &&
|
||||
newApps.indexOf(oldApps[oldIndex]) == -1) {
|
||||
if (oldApp && newApps.indexOf(oldApp) == -1) {
|
||||
removedActors.push(children[oldIndex]);
|
||||
oldIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// App added at newIndex
|
||||
if (newApps[newIndex] &&
|
||||
oldApps.indexOf(newApps[newIndex]) == -1) {
|
||||
addedItems.push({ app: newApps[newIndex],
|
||||
item: this._createAppItem(newApps[newIndex]),
|
||||
if (newApp && oldApps.indexOf(newApp) == -1) {
|
||||
addedItems.push({ app: newApp,
|
||||
item: this._createAppItem(newApp),
|
||||
pos: newIndex });
|
||||
newIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// App moved
|
||||
let insertHere = newApps[newIndex + 1] &&
|
||||
newApps[newIndex + 1] == oldApps[oldIndex];
|
||||
let nextApp = newApps.length > newIndex + 1 ? newApps[newIndex + 1]
|
||||
: null;
|
||||
let insertHere = nextApp && nextApp == oldApp;
|
||||
let alreadyRemoved = removedActors.reduce(function(result, actor) {
|
||||
let removedApp = actor.child._delegate.app;
|
||||
return result || removedApp == newApps[newIndex];
|
||||
return result || removedApp == newApp;
|
||||
}, false);
|
||||
|
||||
if (insertHere || alreadyRemoved) {
|
||||
let newItem = this._createAppItem(newApps[newIndex]);
|
||||
addedItems.push({ app: newApps[newIndex],
|
||||
let newItem = this._createAppItem(newApp);
|
||||
addedItems.push({ app: newApp,
|
||||
item: newItem,
|
||||
pos: newIndex + removedActors.length });
|
||||
newIndex++;
|
||||
|
@ -8,6 +8,7 @@ const Gtk = imports.gi.Gtk;
|
||||
const GWeather = imports.gi.GWeather;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Cairo = imports.cairo;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Shell = imports.gi.Shell;
|
||||
@ -20,6 +21,7 @@ const Main = imports.ui.main;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Calendar = imports.ui.calendar;
|
||||
const Weather = imports.misc.weather;
|
||||
|
||||
function _isToday(date) {
|
||||
let now = new Date();
|
||||
@ -28,7 +30,7 @@ function _isToday(date) {
|
||||
now.getDate() == date.getDate();
|
||||
}
|
||||
|
||||
const TodayButton = new Lang.Class({
|
||||
var TodayButton = new Lang.Class({
|
||||
Name: 'TodayButton',
|
||||
|
||||
_init: function(calendar) {
|
||||
@ -36,7 +38,7 @@ const TodayButton = new Lang.Class({
|
||||
// on the current date can be confusing. So don't make the button reactive
|
||||
// until the selected date changes.
|
||||
this.actor = new St.Button({ style_class: 'datemenu-today-button',
|
||||
x_align: St.Align.START,
|
||||
x_expand: true, x_align: St.Align.START,
|
||||
can_focus: true,
|
||||
reactive: false
|
||||
});
|
||||
@ -77,19 +79,17 @@ const TodayButton = new Lang.Class({
|
||||
* below the time in the shell; it should combine the weekday and the
|
||||
* date, e.g. "Tuesday February 17 2015".
|
||||
*/
|
||||
let dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
|
||||
dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
|
||||
this.actor.accessible_name = date.toLocaleFormat(dateFormat);
|
||||
}
|
||||
});
|
||||
|
||||
const WorldClocksSection = new Lang.Class({
|
||||
var WorldClocksSection = new Lang.Class({
|
||||
Name: 'WorldClocksSection',
|
||||
|
||||
_init: function() {
|
||||
this._clock = new GnomeDesktop.WallClock();
|
||||
this._settings = null;
|
||||
this._clockNotifyId = 0;
|
||||
this._changedId = 0;
|
||||
|
||||
this._locations = [];
|
||||
|
||||
@ -98,8 +98,7 @@ const WorldClocksSection = new Lang.Class({
|
||||
can_focus: true });
|
||||
this.actor.connect('clicked', Lang.bind(this,
|
||||
function() {
|
||||
let app = this._getClockApp();
|
||||
app.activate();
|
||||
this._clockAppMon.activateApp();
|
||||
|
||||
Main.overview.hide();
|
||||
Main.panel.closeCalendar();
|
||||
@ -112,40 +111,25 @@ const WorldClocksSection = new Lang.Class({
|
||||
|
||||
this.actor.child = this._grid;
|
||||
|
||||
Shell.AppSystem.get_default().connect('installed-changed',
|
||||
Lang.bind(this, this._sync));
|
||||
this._clockAppMon = new Util.AppSettingsMonitor('org.gnome.clocks.desktop',
|
||||
'org.gnome.clocks');
|
||||
this._clockAppMon.connect('available-changed',
|
||||
Lang.bind(this, this._sync));
|
||||
this._clockAppMon.watchSetting('world-clocks',
|
||||
Lang.bind(this, this._clocksChanged));
|
||||
this._sync();
|
||||
},
|
||||
|
||||
_getClockApp: function() {
|
||||
return Shell.AppSystem.get_default().lookup_app('org.gnome.clocks.desktop');
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
this.actor.visible = (this._getClockApp() != null);
|
||||
|
||||
if (this.actor.visible) {
|
||||
if (!this._settings) {
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.clocks' });
|
||||
this._changedId =
|
||||
this._settings.connect('changed::world-clocks',
|
||||
Lang.bind(this, this._clocksChanged));
|
||||
this._clocksChanged();
|
||||
}
|
||||
} else {
|
||||
if (this._settings)
|
||||
this._settings.disconnect(this._changedId);
|
||||
this._settings = null;
|
||||
this._changedId = 0;
|
||||
}
|
||||
this.actor.visible = this._clockAppMon.available;
|
||||
},
|
||||
|
||||
_clocksChanged: function() {
|
||||
_clocksChanged: function(settings) {
|
||||
this._grid.destroy_all_children();
|
||||
this._locations = [];
|
||||
|
||||
let world = GWeather.Location.get_world();
|
||||
let clocks = this._settings.get_value('world-clocks').deep_unpack();
|
||||
let clocks = settings.get_value('world-clocks').deep_unpack();
|
||||
for (let i = 0; i < clocks.length; i++) {
|
||||
let l = world.deserialize(clocks[i].location);
|
||||
this._locations.push({ location: l });
|
||||
@ -210,7 +194,137 @@ const WorldClocksSection = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const MessagesIndicator = new Lang.Class({
|
||||
var WeatherSection = new Lang.Class({
|
||||
Name: 'WeatherSection',
|
||||
|
||||
_init: function() {
|
||||
this._weatherClient = new Weather.WeatherClient();
|
||||
|
||||
this.actor = new St.Button({ style_class: 'weather-button',
|
||||
x_fill: true,
|
||||
can_focus: true });
|
||||
this.actor.connect('clicked', () => {
|
||||
this._weatherClient.activateApp();
|
||||
|
||||
Main.overview.hide();
|
||||
Main.panel.closeCalendar();
|
||||
});
|
||||
this.actor.connect('notify::mapped', () => {
|
||||
if (this.actor.mapped)
|
||||
this._weatherClient.update();
|
||||
});
|
||||
|
||||
let box = new St.BoxLayout({ style_class: 'weather-box',
|
||||
vertical: true });
|
||||
|
||||
this.actor.child = box;
|
||||
|
||||
box.add_child(new St.Label({ style_class: 'weather-header',
|
||||
x_align: Clutter.ActorAlign.START,
|
||||
text: _("Weather") }));
|
||||
|
||||
this._conditionsLabel = new St.Label({ style_class: 'weather-conditions',
|
||||
x_align: Clutter.ActorAlign.START });
|
||||
this._conditionsLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||
this._conditionsLabel.clutter_text.line_wrap = true;
|
||||
box.add_child(this._conditionsLabel);
|
||||
|
||||
this._weatherClient.connect('changed', Lang.bind(this, this._sync));
|
||||
this._sync();
|
||||
},
|
||||
|
||||
_getSummary: function(info) {
|
||||
let summary = info.get_conditions();
|
||||
if (summary == '-')
|
||||
return info.get_sky();
|
||||
return summary;
|
||||
},
|
||||
|
||||
_sameSummary: function(info1, info2) {
|
||||
let [ok1, phenom1, qualifier1] = info1.get_value_conditions();
|
||||
let [ok2, phenom2, qualifier2] = info2.get_value_conditions();
|
||||
if (ok1 || ok2)
|
||||
return ok1 == ok2 && phenom1 == phenom2 && qualifier1 == qualifier2;
|
||||
|
||||
let [, sky1] = info1.get_value_sky();
|
||||
let [, sky2] = info2.get_value_sky();
|
||||
return sky1 == sky2;
|
||||
},
|
||||
|
||||
_getSummaryText: function() {
|
||||
let info = this._weatherClient.info;
|
||||
let forecasts = info.get_forecast_list();
|
||||
if (forecasts.length == 0) // No forecasts, just current conditions
|
||||
return '%s.'.format(this._getSummary(info));
|
||||
|
||||
let current = info;
|
||||
let summaries = [this._getSummary(info)];
|
||||
for (let i = 0; i < forecasts.length; i++) {
|
||||
let [ok, timestamp] = forecasts[i].get_value_update();
|
||||
if (!_isToday(new Date(timestamp * 1000)))
|
||||
continue; // Ignore forecasts from other days
|
||||
|
||||
if (this._sameSummary(current, forecasts[i]))
|
||||
continue; // Ignore consecutive runs of equal summaries
|
||||
|
||||
current = forecasts[i];
|
||||
if (summaries.push(this._getSummary(current)) == 3)
|
||||
break; // Use a maximum of three summaries
|
||||
}
|
||||
|
||||
let fmt;
|
||||
switch(summaries.length) {
|
||||
/* Translators: %s is a weather condition like "Clear sky"; see
|
||||
libgweather for the possible condition strings. If at all
|
||||
possible, the sentence should match the grammatical case etc. of
|
||||
the inserted conditions. */
|
||||
case 1: fmt = _("%s all day."); break;
|
||||
|
||||
/* Translators: %s is a weather condition like "Clear sky"; see
|
||||
libgweather for the possible condition strings. If at all
|
||||
possible, the sentence should match the grammatical case etc. of
|
||||
the inserted conditions. */
|
||||
case 2: fmt = _("%s, then %s later."); break;
|
||||
|
||||
/* Translators: %s is a weather condition like "Clear sky"; see
|
||||
libgweather for the possible condition strings. If at all
|
||||
possible, the sentence should match the grammatical case etc. of
|
||||
the inserted conditions. */
|
||||
case 3: fmt = _("%s, then %s, followed by %s later."); break;
|
||||
}
|
||||
return String.prototype.format.apply(fmt, summaries);
|
||||
},
|
||||
|
||||
_getLabelText: function() {
|
||||
if (!this._weatherClient.hasLocation)
|
||||
return _("Select a location…");
|
||||
|
||||
if (this._weatherClient.loading)
|
||||
return _("Loading…");
|
||||
|
||||
let info = this._weatherClient.info;
|
||||
if (info.is_valid())
|
||||
return this._getSummaryText() + ' ' +
|
||||
/* Translators: %s is a temperature with unit, e.g. "23℃" */
|
||||
_("Feels like %s.").format(info.get_apparent());
|
||||
|
||||
if (info.network_error())
|
||||
return _("Go online for weather information");
|
||||
|
||||
return _("Weather information is currently unavailable");
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
this.actor.visible = this._weatherClient.available;
|
||||
|
||||
if (!this.actor.visible)
|
||||
return;
|
||||
|
||||
this._conditionsLabel.text = this._getLabelText();
|
||||
}
|
||||
});
|
||||
|
||||
var MessagesIndicator = new Lang.Class({
|
||||
Name: 'MessagesIndicator',
|
||||
|
||||
_init: function() {
|
||||
@ -250,14 +364,13 @@ const MessagesIndicator = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const IndicatorPad = new Lang.Class({
|
||||
var IndicatorPad = new Lang.Class({
|
||||
Name: 'IndicatorPad',
|
||||
Extends: St.Widget,
|
||||
|
||||
_init: function(actor) {
|
||||
this._source = actor;
|
||||
this._source.connect('notify::visible',
|
||||
Lang.bind(this, this.queue_relayout));
|
||||
this._source.connect('notify::visible', () => { this.queue_relayout(); });
|
||||
this.parent();
|
||||
},
|
||||
|
||||
@ -274,7 +387,7 @@ const IndicatorPad = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const FreezableBinLayout = new Lang.Class({
|
||||
var FreezableBinLayout = new Lang.Class({
|
||||
Name: 'FreezableBinLayout',
|
||||
Extends: Clutter.BinLayout,
|
||||
|
||||
@ -297,18 +410,42 @@ const FreezableBinLayout = new Lang.Class({
|
||||
|
||||
vfunc_get_preferred_width: function(container, forHeight) {
|
||||
if (!this._frozen || this._savedWidth.some(isNaN))
|
||||
this._savedWidth = this.parent(container, forHeight);
|
||||
return this.parent(container, forHeight);
|
||||
return this._savedWidth;
|
||||
},
|
||||
|
||||
vfunc_get_preferred_height: function(container, forWidth) {
|
||||
if (!this._frozen || this._savedHeight.some(isNaN))
|
||||
this._savedHeight = this.parent(container, forWidth);
|
||||
return this.parent(container, forWidth);
|
||||
return this._savedHeight;
|
||||
},
|
||||
|
||||
vfunc_allocate: function(container, allocation, flags) {
|
||||
this.parent(container, allocation, flags);
|
||||
|
||||
let [width, height] = allocation.get_size();
|
||||
this._savedWidth = [width, width];
|
||||
this._savedHeight = [height, height];
|
||||
}
|
||||
});
|
||||
|
||||
const DateMenuButton = new Lang.Class({
|
||||
var CalendarColumnLayout = new Lang.Class({
|
||||
Name: 'CalendarColumnLayout',
|
||||
Extends: Clutter.BoxLayout,
|
||||
|
||||
_init: function(actor) {
|
||||
this.parent({ orientation: Clutter.Orientation.VERTICAL });
|
||||
this._calActor = actor;
|
||||
},
|
||||
|
||||
vfunc_get_preferred_width: function(container, forHeight) {
|
||||
if (!this._calActor || this._calActor.get_parent() != container)
|
||||
return this.parent(container, forHeight);
|
||||
return this._calActor.get_preferred_width(forHeight);
|
||||
}
|
||||
});
|
||||
|
||||
var DateMenuButton = new Lang.Class({
|
||||
Name: 'DateMenuButton',
|
||||
Extends: PanelMenu.Button,
|
||||
|
||||
@ -337,6 +474,8 @@ const DateMenuButton = new Lang.Class({
|
||||
|
||||
let layout = new FreezableBinLayout();
|
||||
let bin = new St.Widget({ layout_manager: layout });
|
||||
// For some minimal compatibility with PopupMenuItem
|
||||
bin._delegate = this;
|
||||
this.menu.box.add_child(bin);
|
||||
|
||||
hbox = new St.BoxLayout({ name: 'calendarArea' });
|
||||
@ -364,14 +503,16 @@ const DateMenuButton = new Lang.Class({
|
||||
hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
|
||||
|
||||
// Fill up the second column
|
||||
vbox = new St.BoxLayout({ style_class: 'datemenu-calendar-column',
|
||||
vertical: true });
|
||||
let boxLayout = new CalendarColumnLayout(this._calendar.actor);
|
||||
vbox = new St.Widget({ style_class: 'datemenu-calendar-column',
|
||||
layout_manager: boxLayout });
|
||||
boxLayout.hookup_style(vbox);
|
||||
hbox.add(vbox);
|
||||
|
||||
this._date = new TodayButton(this._calendar);
|
||||
vbox.add_actor(this._date.actor);
|
||||
|
||||
vbox.add(this._calendar.actor);
|
||||
vbox.add_actor(this._calendar.actor);
|
||||
|
||||
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
|
||||
x_expand: true, x_fill: true,
|
||||
@ -386,6 +527,8 @@ const DateMenuButton = new Lang.Class({
|
||||
this._clocksItem = new WorldClocksSection();
|
||||
displaysBox.add(this._clocksItem.actor, { x_fill: true });
|
||||
|
||||
this._weatherItem = new WeatherSection();
|
||||
displaysBox.add(this._weatherItem.actor, { x_fill: true });
|
||||
|
||||
// Done with hbox for calendar and event list
|
||||
|
||||
|
231
js/ui/dialog.js
Normal file
231
js/ui/dialog.js
Normal file
@ -0,0 +1,231 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Pango = imports.gi.Pango;
|
||||
const St = imports.gi.St;
|
||||
const Lang = imports.lang;
|
||||
|
||||
var Dialog = new Lang.Class({
|
||||
Name: 'Dialog',
|
||||
Extends: St.Widget,
|
||||
|
||||
_init: function (parentActor, styleClass) {
|
||||
this.parent({ layout_manager: new Clutter.BinLayout() });
|
||||
this.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
this._pressedKey = null;
|
||||
this._buttonKeys = {};
|
||||
this._createDialog();
|
||||
this.add_child(this._dialog);
|
||||
|
||||
if (styleClass != null)
|
||||
this._dialog.add_style_class_name(styleClass);
|
||||
|
||||
this._parentActor = parentActor;
|
||||
this._eventId = this._parentActor.connect('event', Lang.bind(this, this._modalEventHandler));
|
||||
this._parentActor.add_child(this);
|
||||
},
|
||||
|
||||
_createDialog: function () {
|
||||
this._dialog = new St.BoxLayout({ style_class: 'modal-dialog',
|
||||
x_align: Clutter.ActorAlign.CENTER,
|
||||
y_align: Clutter.ActorAlign.CENTER,
|
||||
vertical: true });
|
||||
|
||||
// modal dialogs are fixed width and grow vertically; set the request
|
||||
// mode accordingly so wrapped labels are handled correctly during
|
||||
// size requests.
|
||||
this._dialog.request_mode = Clutter.RequestMode.HEIGHT_FOR_WIDTH;
|
||||
|
||||
this.contentLayout = new St.BoxLayout({ vertical: true,
|
||||
style_class: "modal-dialog-content-box" });
|
||||
this._dialog.add(this.contentLayout,
|
||||
{ expand: true,
|
||||
x_fill: true,
|
||||
y_fill: true,
|
||||
x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.START });
|
||||
|
||||
this.buttonLayout = new St.Widget ({ layout_manager: new Clutter.BoxLayout({ homogeneous:true }) });
|
||||
this._dialog.add(this.buttonLayout,
|
||||
{ x_align: St.Align.MIDDLE,
|
||||
y_align: St.Align.START });
|
||||
},
|
||||
|
||||
_onDestroy: function () {
|
||||
if (this._eventId != 0)
|
||||
this._parentActor.disconnect(this._eventId);
|
||||
this._eventId = 0;
|
||||
},
|
||||
|
||||
_modalEventHandler: function (actor, event) {
|
||||
if (event.type() == Clutter.EventType.KEY_PRESS) {
|
||||
this._pressedKey = event.get_key_symbol();
|
||||
} else if (event.type() == Clutter.EventType.KEY_RELEASE) {
|
||||
let pressedKey = this._pressedKey;
|
||||
this._pressedKey = null;
|
||||
|
||||
let symbol = event.get_key_symbol();
|
||||
if (symbol != pressedKey)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
let buttonInfo = this._buttonKeys[symbol];
|
||||
if (!buttonInfo)
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
|
||||
let { button, action } = buttonInfo;
|
||||
|
||||
if (action && button.reactive) {
|
||||
action();
|
||||
return Clutter.EVENT_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
},
|
||||
|
||||
addContent: function (actor) {
|
||||
this.contentLayout.add (actor, { expand: true });
|
||||
},
|
||||
|
||||
addButton: function (buttonInfo) {
|
||||
let { label, action, key } = buttonInfo;
|
||||
let isDefault = buttonInfo['default'];
|
||||
let keys;
|
||||
|
||||
if (key)
|
||||
keys = [key];
|
||||
else if (isDefault)
|
||||
keys = [Clutter.KEY_Return, Clutter.KEY_KP_Enter, Clutter.KEY_ISO_Enter];
|
||||
else
|
||||
keys = [];
|
||||
|
||||
let button = new St.Button({ style_class: 'modal-dialog-linked-button',
|
||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
x_expand: true,
|
||||
y_expand: true,
|
||||
label: label });
|
||||
button.connect('clicked', action);
|
||||
|
||||
buttonInfo['button'] = button;
|
||||
|
||||
if (isDefault)
|
||||
button.add_style_pseudo_class('default');
|
||||
|
||||
if (!this._initialKeyFocusDestroyId)
|
||||
this._initialKeyFocus = button;
|
||||
|
||||
for (let i in keys)
|
||||
this._buttonKeys[keys[i]] = buttonInfo;
|
||||
|
||||
this.buttonLayout.add_actor(button);
|
||||
|
||||
return button;
|
||||
},
|
||||
|
||||
clearButtons: function () {
|
||||
this.buttonLayout.destroy_all_children();
|
||||
this._buttonKeys = {};
|
||||
},
|
||||
});
|
||||
|
||||
var MessageDialogContent = new Lang.Class({
|
||||
Name: 'MessageDialogContent',
|
||||
Extends: St.BoxLayout,
|
||||
Properties: {
|
||||
'icon': GObject.ParamSpec.object('icon', 'icon', 'icon',
|
||||
GObject.ParamFlags.READWRITE |
|
||||
GObject.ParamFlags.CONSTRUCT,
|
||||
Gio.Icon.$gtype),
|
||||
'title': GObject.ParamSpec.string('title', 'title', 'title',
|
||||
GObject.ParamFlags.READWRITE |
|
||||
GObject.ParamFlags.CONSTRUCT,
|
||||
null),
|
||||
'subtitle': GObject.ParamSpec.string('subtitle', 'subtitle', 'subtitle',
|
||||
GObject.ParamFlags.READWRITE |
|
||||
GObject.ParamFlags.CONSTRUCT,
|
||||
null),
|
||||
'body': GObject.ParamSpec.string('body', 'body', 'body',
|
||||
GObject.ParamFlags.READWRITE |
|
||||
GObject.ParamFlags.CONSTRUCT,
|
||||
null)
|
||||
},
|
||||
|
||||
_init: function(params) {
|
||||
this._icon = new St.Icon({ y_align: Clutter.ActorAlign.START });
|
||||
this._title = new St.Label({ style_class: 'headline' });
|
||||
this._subtitle = new St.Label();
|
||||
this._body = new St.Label();
|
||||
|
||||
['icon', 'title', 'subtitle', 'body'].forEach(prop => {
|
||||
this[`_${prop}`].add_style_class_name(`message-dialog-${prop}`);
|
||||
});
|
||||
|
||||
let textProps = { ellipsize_mode: Pango.EllipsizeMode.NONE,
|
||||
line_wrap: true };
|
||||
Object.assign(this._subtitle.clutter_text, textProps);
|
||||
Object.assign(this._body.clutter_text, textProps);
|
||||
|
||||
if (!params.hasOwnProperty('style_class'))
|
||||
params.style_class = 'message-dialog-main-layout';
|
||||
|
||||
this.parent(params);
|
||||
|
||||
this.messageBox = new St.BoxLayout({ style_class: 'message-dialog-content',
|
||||
x_expand: true,
|
||||
vertical: true });
|
||||
|
||||
this.messageBox.add_actor(this._title);
|
||||
this.messageBox.add_actor(this._subtitle);
|
||||
this.messageBox.add_actor(this._body);
|
||||
|
||||
this.add_actor(this._icon);
|
||||
this.add_actor(this.messageBox);
|
||||
},
|
||||
|
||||
get icon() {
|
||||
return this._icon.gicon;
|
||||
},
|
||||
|
||||
get title() {
|
||||
return this._title.text;
|
||||
},
|
||||
|
||||
get subtitle() {
|
||||
return this._subtitle.text;
|
||||
},
|
||||
|
||||
get body() {
|
||||
return this._body.text;
|
||||
},
|
||||
|
||||
set icon(icon) {
|
||||
Object.assign(this._icon, { gicon: icon, visible: icon != null });
|
||||
this.notify('icon');
|
||||
},
|
||||
|
||||
set title(title) {
|
||||
this._setLabel(this._title, 'title', title);
|
||||
},
|
||||
|
||||
set subtitle(subtitle) {
|
||||
this._setLabel(this._subtitle, 'subtitle', subtitle);
|
||||
},
|
||||
|
||||
set body(body) {
|
||||
this._setLabel(this._body, 'body', body);
|
||||
},
|
||||
|
||||
_setLabel(label, prop, value) {
|
||||
Object.assign(label, { text: value || '', visible: value != null });
|
||||
this.notify(prop);
|
||||
},
|
||||
|
||||
insertBeforeBody: function(actor) {
|
||||
this.messageBox.insert_child_below(actor, this._body);
|
||||
}
|
||||
});
|
84
js/ui/dnd.js
84
js/ui/dnd.js
@ -14,26 +14,26 @@ const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
|
||||
// Time to scale down to maxDragActorSize
|
||||
const SCALE_ANIMATION_TIME = 0.25;
|
||||
var SCALE_ANIMATION_TIME = 0.25;
|
||||
// Time to animate to original position on cancel
|
||||
const SNAP_BACK_ANIMATION_TIME = 0.25;
|
||||
var SNAP_BACK_ANIMATION_TIME = 0.25;
|
||||
// Time to animate to original position on success
|
||||
const REVERT_ANIMATION_TIME = 0.75;
|
||||
var REVERT_ANIMATION_TIME = 0.75;
|
||||
|
||||
const DragMotionResult = {
|
||||
var DragMotionResult = {
|
||||
NO_DROP: 0,
|
||||
COPY_DROP: 1,
|
||||
MOVE_DROP: 2,
|
||||
CONTINUE: 3
|
||||
};
|
||||
|
||||
const DRAG_CURSOR_MAP = {
|
||||
var DRAG_CURSOR_MAP = {
|
||||
0: Meta.Cursor.DND_UNSUPPORTED_TARGET,
|
||||
1: Meta.Cursor.DND_COPY,
|
||||
2: Meta.Cursor.DND_MOVE
|
||||
};
|
||||
|
||||
const DragDropResult = {
|
||||
var DragDropResult = {
|
||||
FAILURE: 0,
|
||||
SUCCESS: 1,
|
||||
CONTINUE: 2
|
||||
@ -69,7 +69,7 @@ function removeDragMonitor(monitor) {
|
||||
}
|
||||
}
|
||||
|
||||
const _Draggable = new Lang.Class({
|
||||
var _Draggable = new Lang.Class({
|
||||
Name: 'Draggable',
|
||||
|
||||
_init : function(actor, params) {
|
||||
@ -571,20 +571,13 @@ const _Draggable = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
this._animationInProgress = true;
|
||||
// No target, so snap back
|
||||
Tweener.addTween(this._dragActor,
|
||||
{ x: snapBackX,
|
||||
y: snapBackY,
|
||||
scale_x: snapBackScale,
|
||||
scale_y: snapBackScale,
|
||||
opacity: this._dragOrigOpacity,
|
||||
time: SNAP_BACK_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._onAnimationComplete,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [this._dragActor, eventTime]
|
||||
});
|
||||
this._animateDragEnd(eventTime,
|
||||
{ x: snapBackX,
|
||||
y: snapBackY,
|
||||
scale_x: snapBackScale,
|
||||
scale_y: snapBackScale,
|
||||
time: SNAP_BACK_ANIMATION_TIME,
|
||||
});
|
||||
},
|
||||
|
||||
_restoreDragActor: function(eventTime) {
|
||||
@ -596,18 +589,44 @@ const _Draggable = new Lang.Class({
|
||||
this._dragActor.set_scale(restoreScale, restoreScale);
|
||||
this._dragActor.opacity = 0;
|
||||
|
||||
this._animateDragEnd(eventTime,
|
||||
{ time: REVERT_ANIMATION_TIME });
|
||||
},
|
||||
|
||||
_animateDragEnd: function (eventTime, params) {
|
||||
this._animationInProgress = true;
|
||||
Tweener.addTween(this._dragActor,
|
||||
{ opacity: this._dragOrigOpacity,
|
||||
time: REVERT_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._onAnimationComplete,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [this._dragActor, eventTime]
|
||||
});
|
||||
|
||||
// finish animation if the actor gets destroyed
|
||||
// during it
|
||||
this._dragActorDestroyId =
|
||||
this._dragActor.connect('destroy',
|
||||
Lang.bind(this, this._finishAnimation));
|
||||
|
||||
params['opacity'] = this._dragOrigOpacity;
|
||||
params['transition'] = 'easeOutQuad';
|
||||
params['onComplete'] = this._onAnimationComplete;
|
||||
params['onCompleteScope'] = this;
|
||||
params['onCompleteParams'] = [this._dragActor, eventTime];
|
||||
|
||||
// start the animation
|
||||
Tweener.addTween(this._dragActor, params)
|
||||
},
|
||||
|
||||
_finishAnimation : function () {
|
||||
if (!this._animationInProgress)
|
||||
return
|
||||
|
||||
this._animationInProgress = false;
|
||||
if (!this._buttonDown)
|
||||
this._dragComplete();
|
||||
|
||||
global.screen.set_cursor(Meta.Cursor.DEFAULT);
|
||||
},
|
||||
|
||||
_onAnimationComplete : function (dragActor, eventTime) {
|
||||
dragActor.disconnect(this._dragActorDestroyId);
|
||||
this._dragActorDestroyId = 0;
|
||||
|
||||
if (this._dragOrigParent) {
|
||||
Main.uiGroup.remove_child(this._dragActor);
|
||||
this._dragOrigParent.add_actor(this._dragActor);
|
||||
@ -616,12 +635,9 @@ const _Draggable = new Lang.Class({
|
||||
} else {
|
||||
dragActor.destroy();
|
||||
}
|
||||
global.screen.set_cursor(Meta.Cursor.DEFAULT);
|
||||
this.emit('drag-end', eventTime, false);
|
||||
|
||||
this._animationInProgress = false;
|
||||
if (!this._buttonDown)
|
||||
this._dragComplete();
|
||||
this.emit('drag-end', eventTime, false);
|
||||
this._finishAnimation();
|
||||
},
|
||||
|
||||
_dragComplete: function() {
|
||||
|
@ -8,12 +8,13 @@ const St = imports.gi.St;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const EDGE_THRESHOLD = 20;
|
||||
const DRAG_DISTANCE = 80;
|
||||
var EDGE_THRESHOLD = 20;
|
||||
var DRAG_DISTANCE = 80;
|
||||
|
||||
const EdgeDragAction = new Lang.Class({
|
||||
var EdgeDragAction = new Lang.Class({
|
||||
Name: 'EdgeDragAction',
|
||||
Extends: Clutter.GestureAction,
|
||||
Signals: { 'activated': {} },
|
||||
|
||||
_init : function(side, allowedModes) {
|
||||
this.parent();
|
||||
@ -81,4 +82,3 @@ const EdgeDragAction = new Lang.Class({
|
||||
this.emit('activated');
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(EdgeDragAction.prototype);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/*
|
||||
* Copyright 2010 Red Hat, Inc
|
||||
* Copyright 2010-2016 Red Hat, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -41,7 +41,7 @@ let _endSessionDialog = null;
|
||||
const _ITEM_ICON_SIZE = 48;
|
||||
const _DIALOG_ICON_SIZE = 48;
|
||||
|
||||
const GSM_SESSION_MANAGER_LOGOUT_FORCE = 2;
|
||||
var GSM_SESSION_MANAGER_LOGOUT_FORCE = 2;
|
||||
|
||||
const EndSessionDialogIface = '<node> \
|
||||
<interface name="org.gnome.SessionManager.EndSessionDialog"> \
|
||||
@ -114,7 +114,7 @@ const restartDialogContent = {
|
||||
showOtherSessions: true,
|
||||
};
|
||||
|
||||
const restartInstallDialogContent = {
|
||||
const restartUpdateDialogContent = {
|
||||
|
||||
subject: C_("title", "Restart & Install Updates"),
|
||||
description: function(seconds) {
|
||||
@ -132,21 +132,41 @@ const restartInstallDialogContent = {
|
||||
showOtherSessions: true,
|
||||
};
|
||||
|
||||
const restartUpgradeDialogContent = {
|
||||
|
||||
subject: C_("title", "Restart & Install Upgrade"),
|
||||
upgradeDescription: function(distroName, distroVersion) {
|
||||
/* Translators: This is the text displayed for system upgrades in the
|
||||
shut down dialog. First %s gets replaced with the distro name and
|
||||
second %s with the distro version to upgrade to */
|
||||
return _("%s %s will be installed after restart. Upgrade installation can take a long time: ensure that you have backed up and that the computer is plugged in.").format(distroName, distroVersion);
|
||||
},
|
||||
disableTimer: true,
|
||||
showBatteryWarning: false,
|
||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||
label: C_("button", "Restart & Install") }],
|
||||
iconName: 'view-refresh-symbolic',
|
||||
iconStyleClass: 'end-session-dialog-shutdown-icon',
|
||||
showOtherSessions: true,
|
||||
};
|
||||
|
||||
const DialogType = {
|
||||
LOGOUT: 0 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_LOGOUT */,
|
||||
SHUTDOWN: 1 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_SHUTDOWN */,
|
||||
RESTART: 2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */,
|
||||
UPDATE_RESTART: 3
|
||||
UPDATE_RESTART: 3,
|
||||
UPGRADE_RESTART: 4
|
||||
};
|
||||
|
||||
const DialogContent = {
|
||||
0 /* DialogType.LOGOUT */: logoutDialogContent,
|
||||
1 /* DialogType.SHUTDOWN */: shutdownDialogContent,
|
||||
2 /* DialogType.RESTART */: restartDialogContent,
|
||||
3 /* DialogType.UPDATE_RESTART */: restartInstallDialogContent
|
||||
3 /* DialogType.UPDATE_RESTART */: restartUpdateDialogContent,
|
||||
4 /* DialogType.UPGRADE_RESTART */: restartUpgradeDialogContent
|
||||
};
|
||||
|
||||
const MAX_USERS_IN_SESSION_DIALOG = 5;
|
||||
var MAX_USERS_IN_SESSION_DIALOG = 5;
|
||||
|
||||
const LogindSessionIface = '<node> \
|
||||
<interface name="org.freedesktop.login1.Session"> \
|
||||
@ -163,7 +183,10 @@ const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
|
||||
const PkOfflineIface = '<node> \
|
||||
<interface name="org.freedesktop.PackageKit.Offline"> \
|
||||
<property name="UpdatePrepared" type="b" access="read"/> \
|
||||
<property name="TriggerAction" type="s" access="read"/> \
|
||||
<property name="UpdateTriggered" type="b" access="read"/> \
|
||||
<property name="UpgradePrepared" type="b" access="read"/> \
|
||||
<property name="UpgradeTriggered" type="b" access="read"/> \
|
||||
<property name="PreparedUpgrade" type="a{sv}" access="read"/> \
|
||||
<method name="Trigger"> \
|
||||
<arg type="s" name="action" direction="in"/> \
|
||||
</method> \
|
||||
@ -252,7 +275,7 @@ function init() {
|
||||
_endSessionDialog = new EndSessionDialog();
|
||||
}
|
||||
|
||||
const EndSessionDialog = new Lang.Class({
|
||||
var EndSessionDialog = new Lang.Class({
|
||||
Name: 'EndSessionDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
@ -415,18 +438,25 @@ const EndSessionDialog = new Lang.Class({
|
||||
|
||||
if (dialogContent.descriptionWithUser)
|
||||
description = dialogContent.descriptionWithUser(realName, displayTime);
|
||||
else
|
||||
description = dialogContent.description(displayTime);
|
||||
}
|
||||
}
|
||||
|
||||
// Use a different description when we are installing a system upgrade
|
||||
if (dialogContent.upgradeDescription) {
|
||||
let name = this._pkOfflineProxy.PreparedUpgrade['name'].deep_unpack();
|
||||
let version = this._pkOfflineProxy.PreparedUpgrade['version'].deep_unpack();
|
||||
|
||||
if (name != null && version != null)
|
||||
description = dialogContent.upgradeDescription(name, version);
|
||||
}
|
||||
|
||||
// Fall back to regular description
|
||||
if (!description)
|
||||
description = dialogContent.description(displayTime);
|
||||
|
||||
_setLabelText(this._descriptionLabel, description);
|
||||
_setLabelText(this._subjectLabel, subject);
|
||||
|
||||
let dialogContent = DialogContent[this._type];
|
||||
if (dialogContent.iconName) {
|
||||
this._iconBin.child = new St.Icon({ icon_name: dialogContent.iconName,
|
||||
icon_size: _DIALOG_ICON_SIZE,
|
||||
@ -698,9 +728,12 @@ const EndSessionDialog = new Lang.Class({
|
||||
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
|
||||
this._type = type;
|
||||
|
||||
if (this._type == DialogType.RESTART &&
|
||||
this._pkOfflineProxy.TriggerAction == 'reboot')
|
||||
this._type = DialogType.UPDATE_RESTART;
|
||||
if (this._type == DialogType.RESTART) {
|
||||
if (this._pkOfflineProxy.UpdateTriggered)
|
||||
this._type = DialogType.UPDATE_RESTART;
|
||||
else if (this._pkOfflineProxy.UpgradeTriggered)
|
||||
this._type = DialogType.UPGRADE_RESTART;
|
||||
}
|
||||
|
||||
this._applications = [];
|
||||
this._applicationList.destroy_all_children();
|
||||
@ -727,19 +760,19 @@ const EndSessionDialog = new Lang.Class({
|
||||
if (dialogContent.showOtherSessions)
|
||||
this._loadSessions();
|
||||
|
||||
let updateAlreadyTriggered = this._pkOfflineProxy.TriggerAction == 'power-off' || this._pkOfflineProxy.TriggerAction == 'reboot';
|
||||
let updateTriggered = this._pkOfflineProxy.UpdateTriggered;
|
||||
let updatePrepared = this._pkOfflineProxy.UpdatePrepared;
|
||||
let updatesAllowed = this._updatesPermission && this._updatesPermission.allowed;
|
||||
|
||||
_setCheckBoxLabel(this._checkBox, dialogContent.checkBoxText);
|
||||
this._checkBox.actor.visible = (dialogContent.checkBoxText && updatePrepared && updatesAllowed);
|
||||
this._checkBox.actor.checked = (updatePrepared && updateAlreadyTriggered);
|
||||
this._checkBox.actor.checked = (updatePrepared && updateTriggered);
|
||||
|
||||
// We show the warning either together with the checkbox, or when
|
||||
// updates have already been triggered, but the user doesn't have
|
||||
// enough permissions to cancel them.
|
||||
this._batteryWarning.visible = (dialogContent.showBatteryWarning &&
|
||||
(this._checkBox.actor.visible || updatePrepared && updateAlreadyTriggered && !updatesAllowed));
|
||||
(this._checkBox.actor.visible || updatePrepared && updateTriggered && !updatesAllowed));
|
||||
|
||||
this._updateButtons();
|
||||
|
||||
@ -749,7 +782,9 @@ const EndSessionDialog = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
this._startTimer();
|
||||
if (!dialogContent.disableTimer)
|
||||
this._startTimer();
|
||||
|
||||
this._sync();
|
||||
|
||||
let signalId = this.connect('opened',
|
||||
|
@ -1,6 +1,8 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
imports.gi.versions.Clutter = '1.0';
|
||||
const Config = imports.misc.config;
|
||||
|
||||
imports.gi.versions.Clutter = Config.LIBMUTTER_API_VERSION;
|
||||
imports.gi.versions.Gio = '2.0';
|
||||
imports.gi.versions.Gdk = '3.0';
|
||||
imports.gi.versions.GdkPixbuf = '2.0';
|
||||
@ -8,7 +10,7 @@ imports.gi.versions.Gtk = '3.0';
|
||||
imports.gi.versions.TelepathyGLib = '0.12';
|
||||
imports.gi.versions.TelepathyLogger = '0.2';
|
||||
|
||||
const Clutter = imports.gi.Clutter;;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gettext = imports.gettext;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
@ -61,10 +63,19 @@ function _patchLayoutClass(layoutClass, styleProps) {
|
||||
};
|
||||
}
|
||||
|
||||
function _makeLoggingFunc(func) {
|
||||
return function() {
|
||||
return func([].join.call(arguments, ', '));
|
||||
};
|
||||
function _loggingFunc() {
|
||||
let fields = {'MESSAGE': [].join.call(arguments, ', ')};
|
||||
let domain = "GNOME Shell";
|
||||
|
||||
// If the caller is an extension, add it as metadata
|
||||
let extension = imports.misc.extensionUtils.getCurrentExtension();
|
||||
if (extension != null) {
|
||||
domain = extension.metadata.name;
|
||||
fields['GNOME_SHELL_EXTENSION_UUID'] = extension.uuid;
|
||||
fields['GNOME_SHELL_EXTENSION_NAME'] = extension.metadata.name;
|
||||
}
|
||||
|
||||
GLib.log_structured(domain, GLib.LogLevelFlags.LEVEL_MESSAGE, fields);
|
||||
}
|
||||
|
||||
function init() {
|
||||
@ -72,7 +83,7 @@ function init() {
|
||||
// browser convention of having that namespace be called 'window'.)
|
||||
window.global = Shell.Global.get();
|
||||
|
||||
window.log = _makeLoggingFunc(window.log);
|
||||
window.log = _loggingFunc;
|
||||
|
||||
window._ = Gettext.gettext;
|
||||
window.C_ = Gettext.pgettext;
|
||||
|
@ -17,10 +17,10 @@ const ModalDialog = imports.ui.modalDialog;
|
||||
|
||||
const _signals = ExtensionSystem._signals;
|
||||
|
||||
const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
|
||||
const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
|
||||
const REPOSITORY_URL_INFO = REPOSITORY_URL_BASE + '/extension-info/';
|
||||
const REPOSITORY_URL_UPDATE = REPOSITORY_URL_BASE + '/update-info/';
|
||||
var REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
|
||||
var REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
|
||||
var REPOSITORY_URL_INFO = REPOSITORY_URL_BASE + '/extension-info/';
|
||||
var REPOSITORY_URL_UPDATE = REPOSITORY_URL_BASE + '/update-info/';
|
||||
|
||||
let _httpSession;
|
||||
|
||||
@ -130,12 +130,14 @@ function updateExtension(uuid) {
|
||||
FileUtils.recursivelyMoveDir(extensionDir, oldExtensionTmpDir);
|
||||
FileUtils.recursivelyMoveDir(newExtensionTmpDir, extensionDir);
|
||||
|
||||
let extension = ExtensionUtils.createExtensionObject(uuid, extensionDir, ExtensionUtils.ExtensionType.PER_USER);
|
||||
let extension = null;
|
||||
|
||||
try {
|
||||
extension = ExtensionUtils.createExtensionObject(uuid, extensionDir, ExtensionUtils.ExtensionType.PER_USER);
|
||||
ExtensionSystem.loadExtension(extension);
|
||||
} catch(e) {
|
||||
ExtensionSystem.unloadExtension(extension);
|
||||
if (extension)
|
||||
ExtensionSystem.unloadExtension(extension);
|
||||
|
||||
logError(e, 'Error loading extension %s'.format(uuid));
|
||||
|
||||
@ -181,7 +183,7 @@ function checkForUpdates() {
|
||||
});
|
||||
}
|
||||
|
||||
const InstallExtensionDialog = new Lang.Class({
|
||||
var InstallExtensionDialog = new Lang.Class({
|
||||
Name: 'InstallExtensionDialog',
|
||||
Extends: ModalDialog.ModalDialog,
|
||||
|
||||
@ -203,7 +205,7 @@ const InstallExtensionDialog = new Lang.Class({
|
||||
|
||||
let message = _("Download and install “%s” from extensions.gnome.org?").format(info.name);
|
||||
|
||||
let box = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
||||
let box = new St.BoxLayout({ style_class: 'message-dialog-main-layout',
|
||||
vertical: false });
|
||||
this.contentLayout.add(box);
|
||||
|
||||
@ -211,7 +213,7 @@ const InstallExtensionDialog = new Lang.Class({
|
||||
let icon = new St.Icon({ gicon: gicon });
|
||||
box.add(icon);
|
||||
|
||||
let label = new St.Label({ style_class: 'prompt-dialog-headline headline',
|
||||
let label = new St.Label({ style_class: 'message-dialog-title headline',
|
||||
text: message });
|
||||
box.add(label);
|
||||
},
|
||||
@ -242,9 +244,8 @@ const InstallExtensionDialog = new Lang.Class({
|
||||
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
||||
}
|
||||
|
||||
let extension = ExtensionUtils.createExtensionObject(uuid, dir, ExtensionUtils.ExtensionType.PER_USER);
|
||||
|
||||
try {
|
||||
let extension = ExtensionUtils.createExtensionObject(uuid, dir, ExtensionUtils.ExtensionType.PER_USER);
|
||||
ExtensionSystem.loadExtension(extension);
|
||||
} catch(e) {
|
||||
uninstallExtension(uuid);
|
||||
@ -252,7 +253,7 @@ const InstallExtensionDialog = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
invocation.return_value(GLib.Variant.new('(s)', 'successful'));
|
||||
invocation.return_value(GLib.Variant.new('(s)', ['successful']));
|
||||
}
|
||||
|
||||
_httpSession.queue_message(message, Lang.bind(this, function(session, message) {
|
||||
|
@ -10,7 +10,7 @@ const St = imports.gi.St;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const ExtensionState = {
|
||||
var ExtensionState = {
|
||||
ENABLED: 1,
|
||||
DISABLED: 2,
|
||||
ERROR: 3,
|
||||
@ -26,7 +26,7 @@ const ExtensionState = {
|
||||
// Arrays of uuids
|
||||
var enabledExtensions;
|
||||
// Contains the order that extensions were enabled in.
|
||||
const extensionOrder = [];
|
||||
var extensionOrder = [];
|
||||
|
||||
// We don't really have a class to add signals on. So, create
|
||||
// a simple dummy object, add the signal methods, and export those
|
||||
@ -34,10 +34,11 @@ const extensionOrder = [];
|
||||
var _signals = {};
|
||||
Signals.addSignalMethods(_signals);
|
||||
|
||||
const connect = Lang.bind(_signals, _signals.connect);
|
||||
const disconnect = Lang.bind(_signals, _signals.disconnect);
|
||||
var connect = Lang.bind(_signals, _signals.connect);
|
||||
var disconnect = Lang.bind(_signals, _signals.disconnect);
|
||||
|
||||
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
|
||||
const DISABLE_USER_EXTENSIONS_KEY = 'disable-user-extensions';
|
||||
const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validation';
|
||||
|
||||
var initted = false;
|
||||
@ -198,7 +199,14 @@ function reloadExtension(oldExtension) {
|
||||
unloadExtension(oldExtension);
|
||||
|
||||
// Now, recreate the extension and load it.
|
||||
let newExtension = ExtensionUtils.createExtensionObject(uuid, dir, type);
|
||||
let newExtension;
|
||||
try {
|
||||
newExtension = ExtensionUtils.createExtensionObject(uuid, dir, type);
|
||||
} catch(e) {
|
||||
logExtensionError(uuid, e);
|
||||
return;
|
||||
}
|
||||
|
||||
loadExtension(newExtension);
|
||||
}
|
||||
|
||||
@ -210,14 +218,21 @@ function initExtension(uuid) {
|
||||
throw new Error("Extension was not properly created. Call loadExtension first");
|
||||
|
||||
let extensionJs = dir.get_child('extension.js');
|
||||
if (!extensionJs.query_exists(null))
|
||||
throw new Error('Missing extension.js');
|
||||
if (!extensionJs.query_exists(null)) {
|
||||
logExtensionError(uuid, new Error('Missing extension.js'));
|
||||
return false;
|
||||
}
|
||||
|
||||
let extensionModule;
|
||||
let extensionState = null;
|
||||
|
||||
ExtensionUtils.installImporter(extension);
|
||||
extensionModule = extension.imports.extension;
|
||||
try {
|
||||
extensionModule = extension.imports.extension;
|
||||
} catch(e) {
|
||||
logExtensionError(uuid, e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extensionModule.init) {
|
||||
try {
|
||||
@ -238,11 +253,16 @@ function initExtension(uuid) {
|
||||
}
|
||||
|
||||
function getEnabledExtensions() {
|
||||
let extensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
|
||||
if (!Array.isArray(Main.sessionMode.enabledExtensions))
|
||||
let extensions;
|
||||
if (Array.isArray(Main.sessionMode.enabledExtensions))
|
||||
extensions = Main.sessionMode.enabledExtensions;
|
||||
else
|
||||
extensions = [];
|
||||
|
||||
if (global.settings.get_boolean(DISABLE_USER_EXTENSIONS_KEY))
|
||||
return extensions;
|
||||
|
||||
return Main.sessionMode.enabledExtensions.concat(extensions);
|
||||
return extensions.concat(global.settings.get_strv(ENABLED_EXTENSIONS_KEY));
|
||||
}
|
||||
|
||||
function onEnabledExtensionsChanged() {
|
||||
@ -288,6 +308,7 @@ function _onVersionValidationChanged() {
|
||||
|
||||
function _loadExtensions() {
|
||||
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||
global.settings.connect('changed::' + DISABLE_USER_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||
global.settings.connect('changed::' + EXTENSION_DISABLE_VERSION_CHECK_KEY, _onVersionValidationChanged);
|
||||
|
||||
enabledExtensions = getEnabledExtensions();
|
||||
|
@ -28,7 +28,7 @@ const Signals = imports.signals;
|
||||
const CARETMOVED = 'object:text-caret-moved';
|
||||
const STATECHANGED = 'object:state-changed';
|
||||
|
||||
const FocusCaretTracker = new Lang.Class({
|
||||
var FocusCaretTracker = new Lang.Class({
|
||||
Name: 'FocusCaretTracker',
|
||||
|
||||
_init: function() {
|
||||
@ -47,30 +47,27 @@ const FocusCaretTracker = new Lang.Class({
|
||||
},
|
||||
|
||||
_initAtspi: function() {
|
||||
if (!this._atspiInited) {
|
||||
Atspi.init();
|
||||
if (!this._atspiInited && Atspi.init() == 0) {
|
||||
Atspi.set_timeout(250, 250);
|
||||
this._atspiInited = true;
|
||||
}
|
||||
|
||||
return this._atspiInited;
|
||||
},
|
||||
|
||||
registerFocusListener: function() {
|
||||
if (this._focusListenerRegistered)
|
||||
if (!this._initAtspi() || this._focusListenerRegistered)
|
||||
return;
|
||||
|
||||
this._initAtspi();
|
||||
|
||||
this._atspiListener.register(STATECHANGED + ':focused');
|
||||
this._atspiListener.register(STATECHANGED + ':selected');
|
||||
this._focusListenerRegistered = true;
|
||||
},
|
||||
|
||||
registerCaretListener: function() {
|
||||
if (this._caretListenerRegistered)
|
||||
if (!this._initAtspi() || this._caretListenerRegistered)
|
||||
return;
|
||||
|
||||
this._initAtspi();
|
||||
|
||||
this._atspiListener.register(CARETMOVED);
|
||||
this._caretListenerRegistered = true;
|
||||
},
|
||||
|
@ -46,7 +46,7 @@ function _popGrabHelper(grabHelper) {
|
||||
// your code just needs to deal with it; you shouldn't adjust behavior directly
|
||||
// after you call ungrab(), but instead pass an 'onUngrab' callback when you
|
||||
// call grab().
|
||||
const GrabHelper = new Lang.Class({
|
||||
var GrabHelper = new Lang.Class({
|
||||
Name: 'GrabHelper',
|
||||
|
||||
_init: function(owner, params) {
|
||||
|
@ -9,16 +9,17 @@ const St = imports.gi.St;
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const MAX_CANDIDATES_PER_PAGE = 16;
|
||||
var MAX_CANDIDATES_PER_PAGE = 16;
|
||||
|
||||
const DEFAULT_INDEX_LABELS = [ '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f' ];
|
||||
var DEFAULT_INDEX_LABELS = [ '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f' ];
|
||||
|
||||
const CandidateArea = new Lang.Class({
|
||||
var CandidateArea = new Lang.Class({
|
||||
Name: 'CandidateArea',
|
||||
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ vertical: true,
|
||||
reactive: true,
|
||||
visible: false });
|
||||
this._candidateBoxes = [];
|
||||
for (let i = 0; i < MAX_CANDIDATES_PER_PAGE; ++i) {
|
||||
@ -39,6 +40,19 @@ const CandidateArea = new Lang.Class({
|
||||
}));
|
||||
}
|
||||
|
||||
this.actor.connect('scroll-event', Lang.bind(this, function(actor, event) {
|
||||
let direction = event.get_scroll_direction();
|
||||
switch(direction) {
|
||||
case Clutter.ScrollDirection.UP:
|
||||
this.emit('cursor-up');
|
||||
break;
|
||||
case Clutter.ScrollDirection.DOWN:
|
||||
this.emit('cursor-down');
|
||||
break;
|
||||
};
|
||||
return Clutter.EVENT_PROPAGATE;
|
||||
}));
|
||||
|
||||
this._buttonBox = new St.BoxLayout({ style_class: 'candidate-page-button-box' });
|
||||
|
||||
this._previousButton = new St.Button({ style_class: 'candidate-page-button candidate-page-button-previous button' });
|
||||
@ -114,7 +128,7 @@ const CandidateArea = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(CandidateArea.prototype);
|
||||
|
||||
const CandidatePopup = new Lang.Class({
|
||||
var CandidatePopup = new Lang.Class({
|
||||
Name: 'CandidatePopup',
|
||||
|
||||
_init: function() {
|
||||
@ -144,6 +158,14 @@ const CandidatePopup = new Lang.Class({
|
||||
this._candidateArea.connect('next-page', Lang.bind(this, function() {
|
||||
this._panelService.page_down();
|
||||
}));
|
||||
|
||||
this._candidateArea.connect('cursor-up', Lang.bind(this, function() {
|
||||
this._panelService.cursor_up();
|
||||
}));
|
||||
this._candidateArea.connect('cursor-down', Lang.bind(this, function() {
|
||||
this._panelService.cursor_down();
|
||||
}));
|
||||
|
||||
this._candidateArea.connect('candidate-clicked', Lang.bind(this, function(ca, index, button, state) {
|
||||
this._panelService.candidate_clicked(index, button, state);
|
||||
}));
|
||||
|
@ -12,29 +12,29 @@ const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const ICON_SIZE = 96;
|
||||
const MIN_ICON_SIZE = 16;
|
||||
var ICON_SIZE = 96;
|
||||
var MIN_ICON_SIZE = 16;
|
||||
|
||||
const EXTRA_SPACE_ANIMATION_TIME = 0.25;
|
||||
var EXTRA_SPACE_ANIMATION_TIME = 0.25;
|
||||
|
||||
const ANIMATION_TIME_IN = 0.350;
|
||||
const ANIMATION_TIME_OUT = 1/2 * ANIMATION_TIME_IN;
|
||||
const ANIMATION_MAX_DELAY_FOR_ITEM = 2/3 * ANIMATION_TIME_IN;
|
||||
const ANIMATION_BASE_DELAY_FOR_ITEM = 1/4 * ANIMATION_MAX_DELAY_FOR_ITEM;
|
||||
const ANIMATION_MAX_DELAY_OUT_FOR_ITEM = 2/3 * ANIMATION_TIME_OUT;
|
||||
const ANIMATION_FADE_IN_TIME_FOR_ITEM = 1/4 * ANIMATION_TIME_IN;
|
||||
var ANIMATION_TIME_IN = 0.350;
|
||||
var ANIMATION_TIME_OUT = 1/2 * ANIMATION_TIME_IN;
|
||||
var ANIMATION_MAX_DELAY_FOR_ITEM = 2/3 * ANIMATION_TIME_IN;
|
||||
var ANIMATION_BASE_DELAY_FOR_ITEM = 1/4 * ANIMATION_MAX_DELAY_FOR_ITEM;
|
||||
var ANIMATION_MAX_DELAY_OUT_FOR_ITEM = 2/3 * ANIMATION_TIME_OUT;
|
||||
var ANIMATION_FADE_IN_TIME_FOR_ITEM = 1/4 * ANIMATION_TIME_IN;
|
||||
|
||||
const ANIMATION_BOUNCE_ICON_SCALE = 1.1;
|
||||
var ANIMATION_BOUNCE_ICON_SCALE = 1.1;
|
||||
|
||||
const AnimationDirection = {
|
||||
var AnimationDirection = {
|
||||
IN: 0,
|
||||
OUT: 1
|
||||
};
|
||||
|
||||
const APPICON_ANIMATION_OUT_SCALE = 3;
|
||||
const APPICON_ANIMATION_OUT_TIME = 0.25;
|
||||
var APPICON_ANIMATION_OUT_SCALE = 3;
|
||||
var APPICON_ANIMATION_OUT_TIME = 0.25;
|
||||
|
||||
const BaseIcon = new Lang.Class({
|
||||
var BaseIcon = new Lang.Class({
|
||||
Name: 'BaseIcon',
|
||||
|
||||
_init : function(label, params) {
|
||||
@ -240,7 +240,7 @@ function zoomOutActor(actor) {
|
||||
});
|
||||
}
|
||||
|
||||
const IconGrid = new Lang.Class({
|
||||
var IconGrid = new Lang.Class({
|
||||
Name: 'IconGrid',
|
||||
|
||||
_init: function(params) {
|
||||
@ -267,6 +267,7 @@ const IconGrid = new Lang.Class({
|
||||
this.actor = new St.BoxLayout({ style_class: 'icon-grid',
|
||||
vertical: true });
|
||||
this._items = [];
|
||||
this._clonesAnimating = [];
|
||||
// Pulled from CSS, but hardcode some defaults here
|
||||
this._spacing = 0;
|
||||
this._hItemSize = this._vItemSize = ICON_SIZE;
|
||||
@ -275,6 +276,13 @@ const IconGrid = new Lang.Class({
|
||||
this.actor.add(this._grid, { expand: true, y_align: St.Align.START });
|
||||
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChanged));
|
||||
|
||||
// Cancel animations when hiding the overview, to avoid icons
|
||||
// swarming into the void ...
|
||||
this.actor.connect('notify::mapped', () => {
|
||||
if (!this.actor.mapped)
|
||||
this._cancelAnimation();
|
||||
});
|
||||
|
||||
this._grid.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this._grid.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
this._grid.connect('allocate', Lang.bind(this, this._allocate));
|
||||
@ -410,8 +418,13 @@ const IconGrid = new Lang.Class({
|
||||
return this._getVisibleChildren();
|
||||
},
|
||||
|
||||
_cancelAnimation: function() {
|
||||
this._clonesAnimating.forEach(clone => { clone.destroy(); });
|
||||
this._clonesAnimating = [];
|
||||
},
|
||||
|
||||
_animationDone: function() {
|
||||
this._animating = false;
|
||||
this._clonesAnimating = [];
|
||||
this.emit('animation-done');
|
||||
},
|
||||
|
||||
@ -419,10 +432,7 @@ const IconGrid = new Lang.Class({
|
||||
if (animationDirection != AnimationDirection.IN)
|
||||
throw new Error("Pulse animation only implements 'in' animation direction");
|
||||
|
||||
if (this._animating)
|
||||
return;
|
||||
|
||||
this._animating = true;
|
||||
this._cancelAnimation();
|
||||
|
||||
let actors = this._getChildrenToAnimate();
|
||||
if (actors.length == 0) {
|
||||
@ -470,10 +480,7 @@ const IconGrid = new Lang.Class({
|
||||
},
|
||||
|
||||
animateSpring: function(animationDirection, sourceActor) {
|
||||
if (this._animating)
|
||||
return;
|
||||
|
||||
this._animating = true;
|
||||
this._cancelAnimation();
|
||||
|
||||
let actors = this._getChildrenToAnimate();
|
||||
if (actors.length == 0) {
|
||||
@ -507,6 +514,7 @@ const IconGrid = new Lang.Class({
|
||||
actor.reactive = false;
|
||||
|
||||
let actorClone = new Clutter.Clone({ source: actor });
|
||||
this._clonesAnimating.push(actorClone);
|
||||
Main.uiGroup.add_actor(actorClone);
|
||||
|
||||
let [width, height,,] = this._getAllocatedChildSizeAndSpacing(actor);
|
||||
@ -790,7 +798,7 @@ const IconGrid = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(IconGrid.prototype);
|
||||
|
||||
const PaginatedIconGrid = new Lang.Class({
|
||||
var PaginatedIconGrid = new Lang.Class({
|
||||
Name: 'PaginatedIconGrid',
|
||||
Extends: IconGrid,
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const FocusCaretTracker = imports.ui.focusCaretTracker;
|
||||
const Atspi = imports.gi.Atspi;
|
||||
const Caribou = imports.gi.Caribou;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gdk = imports.gi.Gdk;
|
||||
@ -10,13 +12,14 @@ const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const InputSourceManager = imports.ui.status.keyboard;
|
||||
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
|
||||
const KEYBOARD_REST_TIME = Layout.KEYBOARD_ANIMATION_TIME * 2 * 1000;
|
||||
var KEYBOARD_REST_TIME = Layout.KEYBOARD_ANIMATION_TIME * 2 * 1000;
|
||||
|
||||
const KEYBOARD_SCHEMA = 'org.gnome.shell.keyboard';
|
||||
const KEYBOARD_TYPE = 'keyboard-type';
|
||||
@ -24,43 +27,7 @@ const KEYBOARD_TYPE = 'keyboard-type';
|
||||
const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
|
||||
const SHOW_KEYBOARD = 'screen-keyboard-enabled';
|
||||
|
||||
const CARIBOU_BUS_NAME = 'org.gnome.Caribou.Daemon';
|
||||
const CARIBOU_OBJECT_PATH = '/org/gnome/Caribou/Daemon';
|
||||
|
||||
const CaribouKeyboardIface = '<node> \
|
||||
<interface name="org.gnome.Caribou.Keyboard"> \
|
||||
<method name="Show"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
<method name="Hide"> \
|
||||
<arg type="u" direction="in" /> \
|
||||
</method> \
|
||||
<method name="SetCursorLocation"> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
</method> \
|
||||
<method name="SetEntryLocation"> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
<arg type="i" direction="in" /> \
|
||||
</method> \
|
||||
<property name="Name" access="read" type="s" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const CaribouDaemonIface = '<node> \
|
||||
<interface name="org.gnome.Caribou.Daemon"> \
|
||||
<method name="Run" /> \
|
||||
<method name="Quit" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
const CaribouDaemonProxy = Gio.DBusProxy.makeProxyWrapper(CaribouDaemonIface);
|
||||
|
||||
const Key = new Lang.Class({
|
||||
var Key = new Lang.Class({
|
||||
Name: 'Key',
|
||||
|
||||
_init : function(key) {
|
||||
@ -186,19 +153,20 @@ const Key = new Lang.Class({
|
||||
});
|
||||
Signals.addSignalMethods(Key.prototype);
|
||||
|
||||
const Keyboard = new Lang.Class({
|
||||
// HACK: we can't set Name, because it collides with Name dbus property
|
||||
// Name: 'Keyboard',
|
||||
var Keyboard = new Lang.Class({
|
||||
Name: 'Keyboard',
|
||||
|
||||
_init: function () {
|
||||
this._impl = Gio.DBusExportedObject.wrapJSObject(CaribouKeyboardIface, this);
|
||||
this._impl.export(Gio.DBus.session, '/org/gnome/Caribou/Keyboard');
|
||||
|
||||
this.actor = null;
|
||||
this._focusInTray = false;
|
||||
this._focusInExtendedKeys = false;
|
||||
|
||||
this._timestamp = global.display.get_current_time_roundtrip();
|
||||
this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker();
|
||||
this._focusCaretTracker.connect('focus-changed', Lang.bind(this, this._onFocusChanged));
|
||||
this._focusCaretTracker.connect('caret-moved', Lang.bind(this, this._onCaretMoved));
|
||||
this._currentAccessible = null;
|
||||
this._caretTrackingEnabled = false;
|
||||
this._updateCaretPositionId = 0;
|
||||
|
||||
this._keyboardSettings = new Gio.Settings({ schema_id: KEYBOARD_SCHEMA });
|
||||
this._keyboardSettings.connect('changed', Lang.bind(this, this._sync));
|
||||
@ -207,9 +175,7 @@ const Keyboard = new Lang.Class({
|
||||
this._daemonProxy = null;
|
||||
this._lastDeviceId = null;
|
||||
|
||||
if (Meta.is_wayland_compositor() &&
|
||||
Caribou.DisplayAdapter.set_default)
|
||||
Caribou.DisplayAdapter.set_default(new ShellWaylandAdapter());
|
||||
Caribou.DisplayAdapter.set_default(new LocalAdapter());
|
||||
|
||||
Meta.get_backend().connect('last-device-changed', Lang.bind(this,
|
||||
function (backend, deviceId) {
|
||||
@ -239,6 +205,93 @@ const Keyboard = new Lang.Class({
|
||||
this._redraw();
|
||||
},
|
||||
|
||||
_setCaretTrackerEnabled: function (enabled) {
|
||||
if (this._caretTrackingEnabled == enabled)
|
||||
return;
|
||||
|
||||
this._caretTrackingEnabled = enabled;
|
||||
|
||||
if (enabled) {
|
||||
this._focusCaretTracker.registerFocusListener();
|
||||
this._focusCaretTracker.registerCaretListener();
|
||||
} else {
|
||||
this._focusCaretTracker.deregisterFocusListener();
|
||||
this._focusCaretTracker.deregisterCaretListener();
|
||||
}
|
||||
},
|
||||
|
||||
_updateCaretPosition: function (accessible) {
|
||||
if (this._updateCaretPositionId)
|
||||
GLib.source_remove(this._updateCaretPositionId);
|
||||
this._updateCaretPositionId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, Lang.bind(this, function() {
|
||||
this._updateCaretPositionId = 0;
|
||||
|
||||
let currentWindow = global.screen.get_display().focus_window;
|
||||
if (!currentWindow)
|
||||
return GLib.SOURCE_REMOVE;
|
||||
|
||||
let windowRect = currentWindow.get_frame_rect();
|
||||
let text = accessible.get_text_iface();
|
||||
let component = accessible.get_component_iface();
|
||||
|
||||
try {
|
||||
let caretOffset = text.get_caret_offset();
|
||||
let caretRect = text.get_character_extents(caretOffset, Atspi.CoordType.WINDOW);
|
||||
let focusRect = component.get_extents(Atspi.CoordType.WINDOW);
|
||||
|
||||
caretRect.x += windowRect.x;
|
||||
caretRect.y += windowRect.y;
|
||||
focusRect.x += windowRect.x;
|
||||
focusRect.y += windowRect.y;
|
||||
|
||||
if (caretRect.width == 0 && caretRect.height == 0)
|
||||
caretRect = focusRect;
|
||||
|
||||
this.setEntryLocation(focusRect.x, focusRect.y, focusRect.width, focusRect.height);
|
||||
this.setCursorLocation(caretRect.x, caretRect.y, caretRect.width, caretRect.height);
|
||||
} catch (e) {
|
||||
log('Error updating caret position for OSK: ' + e.message);
|
||||
}
|
||||
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
|
||||
GLib.Source.set_name_by_id(this._updateCaretPositionId, '[gnome-shell] this._updateCaretPosition');
|
||||
},
|
||||
|
||||
_focusIsTextEntry: function (accessible) {
|
||||
try {
|
||||
let role = accessible.get_role();
|
||||
let stateSet = accessible.get_state_set();
|
||||
return stateSet.contains(Atspi.StateType.EDITABLE) || role == Atspi.Role.TERMINAL;
|
||||
} catch (e) {
|
||||
log('Error determining accessible role: ' + e.message);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
_onFocusChanged: function (caretTracker, event) {
|
||||
let accessible = event.source;
|
||||
if (!this._focusIsTextEntry(accessible))
|
||||
return;
|
||||
|
||||
let focused = event.detail1 != 0;
|
||||
if (focused) {
|
||||
this._currentAccessible = accessible;
|
||||
this._updateCaretPosition(accessible);
|
||||
this.show(Main.layoutManager.focusIndex);
|
||||
} else if (this._currentAccessible == accessible) {
|
||||
this._currentAccessible = null;
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_onCaretMoved: function (caretTracker, event) {
|
||||
let accessible = event.source;
|
||||
if (this._currentAccessible == accessible)
|
||||
this._updateCaretPosition(accessible);
|
||||
},
|
||||
|
||||
_lastDeviceIsTouchscreen: function () {
|
||||
if (!this._lastDeviceId)
|
||||
return false;
|
||||
@ -261,6 +314,8 @@ const Keyboard = new Lang.Class({
|
||||
this._keyboard.keyboard_type == this._keyboardSettings.get_string(KEYBOARD_TYPE))
|
||||
return;
|
||||
|
||||
this._setCaretTrackerEnabled(this._enableKeyboard);
|
||||
|
||||
if (this._keyboard)
|
||||
this._destroyKeyboard();
|
||||
|
||||
@ -296,23 +351,6 @@ const Keyboard = new Lang.Class({
|
||||
},
|
||||
|
||||
_setupKeyboard: function() {
|
||||
if (!this._daemonProxy) {
|
||||
this._daemonProxy = new CaribouDaemonProxy(Gio.DBus.session, CARIBOU_BUS_NAME,
|
||||
CARIBOU_OBJECT_PATH,
|
||||
Lang.bind(this, function(proxy, error) {
|
||||
if (error) {
|
||||
log(error.message);
|
||||
return;
|
||||
}
|
||||
}));
|
||||
}
|
||||
this._daemonProxy.RunRemote(function (result, error) {
|
||||
if (error) {
|
||||
log(error.message);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
|
||||
Main.layoutManager.keyboardBox.add_actor(this.actor);
|
||||
Main.layoutManager.trackChrome(this.actor);
|
||||
@ -358,17 +396,17 @@ const Keyboard = new Lang.Class({
|
||||
|
||||
let time = global.get_current_time();
|
||||
if (!(focus instanceof Clutter.Text)) {
|
||||
this.Hide(time);
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._showIdleId) {
|
||||
this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE,
|
||||
Lang.bind(this, function() {
|
||||
this.Show(time);
|
||||
this.show(Main.layoutManager.focusIndex);
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.Show');
|
||||
GLib.Source.set_name_by_id(this._showIdleId, '[gnome-shell] this.show');
|
||||
}
|
||||
},
|
||||
|
||||
@ -569,7 +607,7 @@ const Keyboard = new Lang.Class({
|
||||
shouldTakeEvent: function(event) {
|
||||
let actor = event.get_source();
|
||||
return Main.layoutManager.keyboardBox.contains(actor) ||
|
||||
actor._extended_keys || actor.extended_key;
|
||||
!!actor._extended_keys || !!actor.extended_key;
|
||||
},
|
||||
|
||||
_clearKeyboardRestTimer: function() {
|
||||
@ -580,6 +618,10 @@ const Keyboard = new Lang.Class({
|
||||
},
|
||||
|
||||
show: function (monitor) {
|
||||
if (!this._enableKeyboard)
|
||||
return;
|
||||
|
||||
this._clearShowIdle();
|
||||
this._keyboardRequested = true;
|
||||
|
||||
if (this._keyboardVisible) {
|
||||
@ -612,6 +654,10 @@ const Keyboard = new Lang.Class({
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
if (!this._enableKeyboard)
|
||||
return;
|
||||
|
||||
this._clearShowIdle();
|
||||
this._keyboardRequested = false;
|
||||
|
||||
if (!this._keyboardVisible)
|
||||
@ -663,20 +709,6 @@ const Keyboard = new Lang.Class({
|
||||
this._moveTemporarily();
|
||||
},
|
||||
|
||||
// _compareTimestamp:
|
||||
//
|
||||
// Compare two timestamps taking into account
|
||||
// CURRENT_TIME (0)
|
||||
_compareTimestamp: function(one, two) {
|
||||
if (one == two)
|
||||
return 0;
|
||||
if (one == Clutter.CURRENT_TIME)
|
||||
return 1;
|
||||
if (two == Clutter.CURRENT_TIME)
|
||||
return -1;
|
||||
return one - two;
|
||||
},
|
||||
|
||||
_clearShowIdle: function() {
|
||||
if (!this._showIdleId)
|
||||
return;
|
||||
@ -684,55 +716,22 @@ const Keyboard = new Lang.Class({
|
||||
this._showIdleId = 0;
|
||||
},
|
||||
|
||||
// D-Bus methods
|
||||
Show: function(timestamp) {
|
||||
if (!this._enableKeyboard)
|
||||
return;
|
||||
|
||||
if (this._compareTimestamp(timestamp, this._timestamp) < 0)
|
||||
return;
|
||||
|
||||
this._clearShowIdle();
|
||||
|
||||
if (timestamp != Clutter.CURRENT_TIME)
|
||||
this._timestamp = timestamp;
|
||||
this.show(Main.layoutManager.focusIndex);
|
||||
},
|
||||
|
||||
Hide: function(timestamp) {
|
||||
if (!this._enableKeyboard)
|
||||
return;
|
||||
|
||||
if (this._compareTimestamp(timestamp, this._timestamp) < 0)
|
||||
return;
|
||||
|
||||
this._clearShowIdle();
|
||||
|
||||
if (timestamp != Clutter.CURRENT_TIME)
|
||||
this._timestamp = timestamp;
|
||||
this.hide();
|
||||
},
|
||||
|
||||
SetCursorLocation: function(x, y, w, h) {
|
||||
setCursorLocation: function(x, y, w, h) {
|
||||
if (!this._enableKeyboard)
|
||||
return;
|
||||
|
||||
// this._setLocation(x, y);
|
||||
},
|
||||
|
||||
SetEntryLocation: function(x, y, w, h) {
|
||||
setEntryLocation: function(x, y, w, h) {
|
||||
if (!this._enableKeyboard)
|
||||
return;
|
||||
|
||||
// this._setLocation(x, y);
|
||||
},
|
||||
|
||||
get Name() {
|
||||
return 'gnome-shell';
|
||||
}
|
||||
});
|
||||
|
||||
const KeyboardSource = new Lang.Class({
|
||||
var KeyboardSource = new Lang.Class({
|
||||
Name: 'KeyboardSource',
|
||||
Extends: MessageTray.Source,
|
||||
|
||||
@ -753,23 +752,52 @@ const KeyboardSource = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const ShellWaylandAdapter = new Lang.Class({
|
||||
Name: 'ShellWaylandAdapter',
|
||||
var LocalAdapter = new Lang.Class({
|
||||
Name: 'LocalAdapter',
|
||||
Extends: Caribou.XAdapter,
|
||||
|
||||
_init: function () {
|
||||
this.parent();
|
||||
let deviceManager = Clutter.DeviceManager.get_default();
|
||||
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
|
||||
|
||||
this._inputSourceManager = InputSourceManager.getInputSourceManager();
|
||||
this._sourceChangedId = this._inputSourceManager.connect('current-source-changed',
|
||||
Lang.bind(this, this._onSourceChanged));
|
||||
this._sourcesModifiedId = this._inputSourceManager.connect ('sources-changed',
|
||||
Lang.bind(this, this._onSourcesModified));
|
||||
},
|
||||
|
||||
_onSourcesModified: function () {
|
||||
this.emit('config-changed');
|
||||
},
|
||||
|
||||
_onSourceChanged: function (inputSourceManager, oldSource) {
|
||||
let source = inputSourceManager.currentSource;
|
||||
this.emit('group-changed', source.index, source.id, '');
|
||||
},
|
||||
|
||||
vfunc_get_groups: function () {
|
||||
let inputSources = this._inputSourceManager.inputSources;
|
||||
let groups = []
|
||||
let variants = [];
|
||||
|
||||
for (let i in inputSources) {
|
||||
let is = inputSources[i];
|
||||
groups[is.index] = is.id;
|
||||
variants[is.index] = '';
|
||||
}
|
||||
|
||||
return [groups, groups.length, variants, variants.length];
|
||||
},
|
||||
|
||||
vfunc_keyval_press: function(keyval) {
|
||||
let focus = global.stage.get_key_focus();
|
||||
if (focus instanceof Clutter.Text)
|
||||
Shell.util_text_insert_keyval(focus, keyval);
|
||||
else
|
||||
this.parent(keyval);
|
||||
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
|
||||
keyval, Clutter.KeyState.PRESSED);
|
||||
},
|
||||
|
||||
vfunc_keyval_release: function(keyval) {
|
||||
let focus = global.stage.get_key_focus();
|
||||
if (focus instanceof Clutter.Text)
|
||||
return; // do nothing
|
||||
else
|
||||
this.parent(keyval);
|
||||
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
|
||||
keyval, Clutter.KeyState.RELEASED);
|
||||
},
|
||||
});
|
||||
|
@ -18,12 +18,12 @@ const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const STARTUP_ANIMATION_TIME = 0.5;
|
||||
const KEYBOARD_ANIMATION_TIME = 0.15;
|
||||
const BACKGROUND_FADE_ANIMATION_TIME = 1.0;
|
||||
var STARTUP_ANIMATION_TIME = 0.5;
|
||||
var KEYBOARD_ANIMATION_TIME = 0.15;
|
||||
var BACKGROUND_FADE_ANIMATION_TIME = 1.0;
|
||||
|
||||
const HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
|
||||
const HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
|
||||
var HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
|
||||
var HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
|
||||
|
||||
function isPopupMetaWindow(actor) {
|
||||
switch(actor.meta_window.get_window_type()) {
|
||||
@ -36,7 +36,7 @@ function isPopupMetaWindow(actor) {
|
||||
}
|
||||
}
|
||||
|
||||
const MonitorConstraint = new Lang.Class({
|
||||
var MonitorConstraint = new Lang.Class({
|
||||
Name: 'MonitorConstraint',
|
||||
Extends: Clutter.Constraint,
|
||||
Properties: {'primary': GObject.ParamSpec.boolean('primary',
|
||||
@ -147,7 +147,7 @@ const MonitorConstraint = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const Monitor = new Lang.Class({
|
||||
var Monitor = new Lang.Class({
|
||||
Name: 'Monitor',
|
||||
|
||||
_init: function(index, geometry) {
|
||||
@ -169,7 +169,7 @@ const defaultParams = {
|
||||
affectsInputRegion: true
|
||||
};
|
||||
|
||||
const LayoutManager = new Lang.Class({
|
||||
var LayoutManager = new Lang.Class({
|
||||
Name: 'LayoutManager',
|
||||
|
||||
_init: function () {
|
||||
@ -220,7 +220,8 @@ const LayoutManager = new Lang.Class({
|
||||
global.stage.add_child(this.uiGroup);
|
||||
|
||||
this.overviewGroup = new St.Widget({ name: 'overviewGroup',
|
||||
visible: false });
|
||||
visible: false,
|
||||
reactive: true });
|
||||
this.addChrome(this.overviewGroup);
|
||||
|
||||
this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup',
|
||||
@ -591,7 +592,10 @@ const LayoutManager = new Lang.Class({
|
||||
this.addChrome(this._coverPane);
|
||||
|
||||
if (Meta.is_restart()) {
|
||||
// On restart, we don't do an animation
|
||||
// On restart, we don't do an animation. Force an update of the
|
||||
// regions immediately so that maximized windows restore to the
|
||||
// right size taking struts into account.
|
||||
this._updateRegions();
|
||||
} else if (Main.sessionMode.isGreeter) {
|
||||
this.panelBox.translation_y = -this.panelBox.height;
|
||||
} else {
|
||||
@ -765,8 +769,7 @@ const LayoutManager = new Lang.Class({
|
||||
// @actor: a descendant of the chrome to begin tracking
|
||||
// @params: parameters describing how to track @actor
|
||||
//
|
||||
// Tells the chrome to track @actor, which must be a descendant
|
||||
// of an actor added via addChrome(). This can be used to extend the
|
||||
// Tells the chrome to track @actor. This can be used to extend the
|
||||
// struts or input region to cover specific children.
|
||||
//
|
||||
// @params can have any of the same values as in addChrome(),
|
||||
@ -779,10 +782,9 @@ const LayoutManager = new Lang.Class({
|
||||
ancestor = ancestor.get_parent();
|
||||
index = this._findActor(ancestor);
|
||||
}
|
||||
if (!ancestor)
|
||||
throw new Error('actor is not a descendent of a chrome actor');
|
||||
|
||||
let ancestorData = this._trackedActors[index];
|
||||
let ancestorData = ancestor ? this._trackedActors[index]
|
||||
: defaultParams;
|
||||
if (!params)
|
||||
params = {};
|
||||
// We can't use Params.parse here because we want to drop
|
||||
@ -892,7 +894,10 @@ const LayoutManager = new Lang.Class({
|
||||
},
|
||||
|
||||
findMonitorForActor: function(actor) {
|
||||
return this.monitors[this.findIndexForActor(actor)];
|
||||
let index = this.findIndexForActor(actor);
|
||||
if (index >= 0 && index < this.monitors.length)
|
||||
return this.monitors[index];
|
||||
return null;
|
||||
},
|
||||
|
||||
_queueUpdateRegions: function() {
|
||||
@ -938,6 +943,11 @@ const LayoutManager = new Lang.Class({
|
||||
if (Main.modalCount > 0)
|
||||
return GLib.SOURCE_REMOVE;
|
||||
|
||||
// Bug workaround - get_transformed_position()/get_transformed_size() don't work after
|
||||
// a change in stage size until the first pick or paint.
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=761565
|
||||
global.stage.get_actor_at_pos(Clutter.PickMode.ALL, 0, 0);
|
||||
|
||||
let rects = [], struts = [], i;
|
||||
let isPopupMenuVisible = global.top_window_group.get_children().some(isPopupMetaWindow);
|
||||
let wantsInputRegion = !isPopupMenuVisible;
|
||||
@ -957,7 +967,11 @@ const LayoutManager = new Lang.Class({
|
||||
if (actorData.affectsInputRegion && wantsInputRegion && actorData.actor.get_paint_visibility())
|
||||
rects.push(new Meta.Rectangle({ x: x, y: y, width: w, height: h }));
|
||||
|
||||
if (actorData.affectsStruts) {
|
||||
let monitor = null;
|
||||
if (actorData.affectsStruts)
|
||||
monitor = this.findMonitorForActor(actorData.actor);
|
||||
|
||||
if (monitor) {
|
||||
// Limit struts to the size of the screen
|
||||
let x1 = Math.max(x, 0);
|
||||
let x2 = Math.min(x + w, global.screen_width);
|
||||
@ -974,7 +988,6 @@ const LayoutManager = new Lang.Class({
|
||||
// spans the width/height across the middle of the
|
||||
// screen, then we don't create a strut for it at all.
|
||||
|
||||
let monitor = this.findMonitorForActor(actorData.actor);
|
||||
let side;
|
||||
if (x1 <= monitor.x && x2 >= monitor.x + monitor.width) {
|
||||
if (y1 <= monitor.y)
|
||||
@ -1032,7 +1045,7 @@ Signals.addSignalMethods(LayoutManager.prototype);
|
||||
//
|
||||
// This class manages a "hot corner" that can toggle switching to
|
||||
// overview.
|
||||
const HotCorner = new Lang.Class({
|
||||
var HotCorner = new Lang.Class({
|
||||
Name: 'HotCorner',
|
||||
|
||||
_init : function(layoutManager, monitor, x, y) {
|
||||
@ -1226,7 +1239,7 @@ const HotCorner = new Lang.Class({
|
||||
}
|
||||
});
|
||||
|
||||
const PressureBarrier = new Lang.Class({
|
||||
var PressureBarrier = new Lang.Class({
|
||||
Name: 'PressureBarrier',
|
||||
|
||||
_init: function(threshold, timeout, actionMode) {
|
||||
|
@ -13,7 +13,7 @@ const Overview = imports.ui.overview;
|
||||
const OverviewControls = imports.ui.overviewControls;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
|
||||
var STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
|
||||
'bluetooth-applet': 'bluetooth',
|
||||
'gnome-volume-control-applet': 'volume', // renamed to gnome-sound-applet
|
||||
// when moved to control center
|
||||
@ -29,14 +29,14 @@ const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
|
||||
};
|
||||
|
||||
// Offset of the original position from the bottom-right corner
|
||||
const CONCEALED_WIDTH = 3;
|
||||
const REVEAL_ANIMATION_TIME = 0.2;
|
||||
const TEMP_REVEAL_TIME = 2;
|
||||
var CONCEALED_WIDTH = 3;
|
||||
var REVEAL_ANIMATION_TIME = 0.2;
|
||||
var TEMP_REVEAL_TIME = 2;
|
||||
|
||||
const BARRIER_THRESHOLD = 70;
|
||||
const BARRIER_TIMEOUT = 1000;
|
||||
var BARRIER_THRESHOLD = 70;
|
||||
var BARRIER_TIMEOUT = 1000;
|
||||
|
||||
const LegacyTray = new Lang.Class({
|
||||
var LegacyTray = new Lang.Class({
|
||||
Name: 'LegacyTray',
|
||||
|
||||
_init: function() {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user