Compare commits
312 Commits
3.7.90
...
wip/is-swi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11bf65e2b4 | ||
|
|
a8b7e559aa | ||
|
|
b733e30a4a | ||
|
|
b607958134 | ||
|
|
14189e6827 | ||
|
|
3dd6113a0a | ||
|
|
ae5cdea5af | ||
|
|
3c1f389e25 | ||
|
|
284d821233 | ||
|
|
78272e5592 | ||
|
|
098bc41083 | ||
|
|
c837090282 | ||
|
|
cdc1678e6f | ||
|
|
2a3d76b0cc | ||
|
|
29e89491de | ||
|
|
d63947aec4 | ||
|
|
512f0a67fb | ||
|
|
a7cd4657f5 | ||
|
|
bf02cde598 | ||
|
|
b7dbb35546 | ||
|
|
6fd5f0e3de | ||
|
|
e6469df065 | ||
|
|
d61fe357f6 | ||
|
|
965dd2ab67 | ||
|
|
78e011d558 | ||
|
|
76590d6c69 | ||
|
|
16dc6ce41a | ||
|
|
1dadcee5c9 | ||
|
|
bed3bb45f7 | ||
|
|
18d850d7d6 | ||
|
|
f920fd8b6f | ||
|
|
b9da6d9ef6 | ||
|
|
3be489c69e | ||
|
|
cab092aad7 | ||
|
|
0451cba343 | ||
|
|
12334cd9ad | ||
|
|
9d18a2dff4 | ||
|
|
869e1dc241 | ||
|
|
b878f3fc4a | ||
|
|
2aeabcc38b | ||
|
|
94778c0dac | ||
|
|
390491b37a | ||
|
|
f8ea825577 | ||
|
|
f77ad7d184 | ||
|
|
e467a53def | ||
|
|
9cd2e12915 | ||
|
|
627a6587b4 | ||
|
|
9b3b419f7a | ||
|
|
f37ed44837 | ||
|
|
dddc333407 | ||
|
|
75714fb784 | ||
|
|
5a6342a5fe | ||
|
|
e07379b406 | ||
|
|
54bfe34273 | ||
|
|
bef876e4b4 | ||
|
|
6ef9ab6a0b | ||
|
|
53ffdd8d68 | ||
|
|
ba198034cb | ||
|
|
58e66b9e1b | ||
|
|
ac7efcb43a | ||
|
|
b514b9ec7c | ||
|
|
f69942eb35 | ||
|
|
f28827f625 | ||
|
|
f20a6b3635 | ||
|
|
7f7ff3ce3e | ||
|
|
0abb0756ba | ||
|
|
070ed9396c | ||
|
|
307004a455 | ||
|
|
d097327bd8 | ||
|
|
f72f501931 | ||
|
|
e9584cfcab | ||
|
|
aec0e75d73 | ||
|
|
a6b4d49454 | ||
|
|
1cc726593e | ||
|
|
5001bd8810 | ||
|
|
46aa70aa09 | ||
|
|
41cf447c45 | ||
|
|
b328fd7aed | ||
|
|
917a24580b | ||
|
|
af36182879 | ||
|
|
160c721afc | ||
|
|
ee0040ef1c | ||
|
|
9e60a55dd7 | ||
|
|
57f27572ae | ||
|
|
ceae032112 | ||
|
|
d3ab367fcd | ||
|
|
0ceefb48c8 | ||
|
|
a9815ae1e9 | ||
|
|
79140fd132 | ||
|
|
6c0f48ce25 | ||
|
|
da7ab7057d | ||
|
|
499ae609dd | ||
|
|
e78b3644e4 | ||
|
|
ce6b39bd1c | ||
|
|
603f528b47 | ||
|
|
5fecd07045 | ||
|
|
8edd7ad32e | ||
|
|
3a27d0b849 | ||
|
|
b351536dee | ||
|
|
eeea8559b6 | ||
|
|
17591117c1 | ||
|
|
c4470fd1e6 | ||
|
|
45fc7ec01f | ||
|
|
dc54472ca5 | ||
|
|
4b3bf05aaf | ||
|
|
ec014a7ecf | ||
|
|
a8c87f3bab | ||
|
|
b39e76200a | ||
|
|
01deb9ef7d | ||
|
|
5c89568cca | ||
|
|
6119b44746 | ||
|
|
7af4a7bf88 | ||
|
|
04e4d69662 | ||
|
|
a87e0f028a | ||
|
|
31774a7711 | ||
|
|
a32f27a2aa | ||
|
|
805a409318 | ||
|
|
42d45bd14a | ||
|
|
5870709fbc | ||
|
|
0fdb7430ff | ||
|
|
4771f80d6f | ||
|
|
91405583fd | ||
|
|
f864303aac | ||
|
|
e5ebf4a2b2 | ||
|
|
725a36e37a | ||
|
|
78dacfa865 | ||
|
|
16547fb3c2 | ||
|
|
9eeabf79f9 | ||
|
|
81b71cc143 | ||
|
|
8301acd4d6 | ||
|
|
f80afb1755 | ||
|
|
71c6b60054 | ||
|
|
95a1b874d8 | ||
|
|
07de96ede9 | ||
|
|
209014b083 | ||
|
|
127f10e7a8 | ||
|
|
67615a0cbc | ||
|
|
dde20f0c76 | ||
|
|
ddced79475 | ||
|
|
e80795b7f0 | ||
|
|
080337a4e8 | ||
|
|
884af3c986 | ||
|
|
edc95b2cb7 | ||
|
|
96239e95ec | ||
|
|
331ad76675 | ||
|
|
29152d3022 | ||
|
|
73fa4b1cbd | ||
|
|
7766a91e8c | ||
|
|
b7bad765aa | ||
|
|
5af09a60e9 | ||
|
|
ef623cfbbd | ||
|
|
ce5faba185 | ||
|
|
40d9ed535b | ||
|
|
d5675765f3 | ||
|
|
65067c24cc | ||
|
|
e2463cb501 | ||
|
|
de2f2d7ef1 | ||
|
|
7cdb75e7ce | ||
|
|
1502e308b8 | ||
|
|
dd1fe68e5c | ||
|
|
85c1dc5a0c | ||
|
|
7b3a689aad | ||
|
|
2c28a12cca | ||
|
|
324021fd64 | ||
|
|
1dceae97c6 | ||
|
|
0bef925b51 | ||
|
|
0ba1f29e40 | ||
|
|
3b1e536822 | ||
|
|
9a83662a18 | ||
|
|
5bcead5b5c | ||
|
|
d8f9502ea2 | ||
|
|
020128b9ca | ||
|
|
1566a4e607 | ||
|
|
fbd59631ee | ||
|
|
6c36856499 | ||
|
|
f4cda49988 | ||
|
|
a6b49fe7d6 | ||
|
|
26966b2bf3 | ||
|
|
36a7429aa0 | ||
|
|
7be1fe09f1 | ||
|
|
62bf08d323 | ||
|
|
260c082c4e | ||
|
|
5e0ff7fd56 | ||
|
|
aac312ca34 | ||
|
|
a90401454a | ||
|
|
5679e6b3a9 | ||
|
|
194574bb0e | ||
|
|
337d2da38a | ||
|
|
df848aa084 | ||
|
|
0cc1615252 | ||
|
|
d4259fa8aa | ||
|
|
157d7e2b59 | ||
|
|
ee50904147 | ||
|
|
ec39aa3890 | ||
|
|
beb0fdf4b8 | ||
|
|
443fe813c3 | ||
|
|
69cdc5a9b9 | ||
|
|
dac54a6019 | ||
|
|
e5ca53e56c | ||
|
|
7a79236bab | ||
|
|
cd37e2908f | ||
|
|
3368e49aa7 | ||
|
|
9e31f05861 | ||
|
|
b52f4ed25b | ||
|
|
00eb764880 | ||
|
|
6d011a3700 | ||
|
|
f9d9caf417 | ||
|
|
b50702dd52 | ||
|
|
e74a82b9d6 | ||
|
|
12fa983242 | ||
|
|
1607df835a | ||
|
|
7b705dd670 | ||
|
|
323e3028b6 | ||
|
|
7e1b4692e2 | ||
|
|
c1dd971ce9 | ||
|
|
39610e6933 | ||
|
|
fdb189102d | ||
|
|
e54d095064 | ||
|
|
e6634c56d3 | ||
|
|
deb77a4dde | ||
|
|
90ea27c423 | ||
|
|
19533f87e3 | ||
|
|
e6c5c84133 | ||
|
|
404aaa5658 | ||
|
|
2c70df25f5 | ||
|
|
db959ac2eb | ||
|
|
bbf0dce390 | ||
|
|
1cbb8b9851 | ||
|
|
96387cce47 | ||
|
|
570fc68cb1 | ||
|
|
e6ce0057af | ||
|
|
a3f625fe39 | ||
|
|
bdfe459d64 | ||
|
|
95ec8ef5e1 | ||
|
|
b8198716d9 | ||
|
|
071a4e5f83 | ||
|
|
d99cd71408 | ||
|
|
030e6aa507 | ||
|
|
f146b01e3e | ||
|
|
c249ff9046 | ||
|
|
8b48560c81 | ||
|
|
bdbea2463b | ||
|
|
8fb2263471 | ||
|
|
ea55c36a3a | ||
|
|
37595ff3e7 | ||
|
|
cca008b73c | ||
|
|
b9dcbd9d33 | ||
|
|
b6bf8d5b2d | ||
|
|
43ed66cf26 | ||
|
|
57eae1be43 | ||
|
|
b394d184cc | ||
|
|
81e01b6f88 | ||
|
|
52efe32e0f | ||
|
|
e7886734c4 | ||
|
|
083c37a7b2 | ||
|
|
b24a10aa00 | ||
|
|
e1ef14d12b | ||
|
|
1a33de91e2 | ||
|
|
6e15e2d72a | ||
|
|
d58b715c52 | ||
|
|
804ff8b5a5 | ||
|
|
6e89d2f46a | ||
|
|
e99d69b7d9 | ||
|
|
f25416c3f5 | ||
|
|
a7bb6a2781 | ||
|
|
41f14e0e89 | ||
|
|
01bd10f485 | ||
|
|
476eacd5ca | ||
|
|
ca2fb74f41 | ||
|
|
8a2baf5b6e | ||
|
|
d44fc3aa1b | ||
|
|
7d78c42dfc | ||
|
|
a361180745 | ||
|
|
310dc10c4d | ||
|
|
96e02c4c2e | ||
|
|
afb3b9f029 | ||
|
|
d5e647a191 | ||
|
|
a1d37617a8 | ||
|
|
2541f85942 | ||
|
|
07fd23dc5e | ||
|
|
946311b2a3 | ||
|
|
4868032215 | ||
|
|
fb0cf64536 | ||
|
|
b37afcdba1 | ||
|
|
f644bee831 | ||
|
|
6fcc7e3e23 | ||
|
|
95602eb85d | ||
|
|
9f3afdf928 | ||
|
|
627a2412d2 | ||
|
|
acffd1e792 | ||
|
|
62ca4ba624 | ||
|
|
6ea8f35343 | ||
|
|
1bd8c67041 | ||
|
|
7425b382d6 | ||
|
|
5f61b57d63 | ||
|
|
9db73767d9 | ||
|
|
c562245c16 | ||
|
|
9525216d78 | ||
|
|
28a71a29e6 | ||
|
|
7b06d34ba4 | ||
|
|
656d24e477 | ||
|
|
df0f03d831 | ||
|
|
1db6d15677 | ||
|
|
08a0479c9e | ||
|
|
6682b7dfa5 | ||
|
|
aad5d98b43 | ||
|
|
a8a4a85dac | ||
|
|
ad71b969b2 | ||
|
|
8bcb10391e | ||
|
|
8e7d74bc3b | ||
|
|
629b6faa22 | ||
|
|
ef1e27966d |
102
NEWS
102
NEWS
@@ -1,3 +1,105 @@
|
|||||||
|
3.8.0.1
|
||||||
|
=======
|
||||||
|
* Background bug fixes [Ray; #696712]
|
||||||
|
|
||||||
|
3.8.0
|
||||||
|
=====
|
||||||
|
* Remove blur and desaturation from lock screen [Jasper; #696322]
|
||||||
|
* Remove scroll view fade near edges [Adel; #696404]
|
||||||
|
* dateMenu: Open calendar component when using Evolution [Florian; #696432]
|
||||||
|
* Fix unlocking on fast user switch [Cosimo; #696287]
|
||||||
|
* Tweak screen shield animation [Rui; #696380]
|
||||||
|
* Fix major memory leak when changing backgrounds [Ray; #696157]
|
||||||
|
* Miscellaneous bug fixes [Jasper, Adel, Florian; #696199, #696212, #696422,
|
||||||
|
#696447, #696235]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Adel Gadllah, Rui Matos, Florian Müllner,
|
||||||
|
Jasper St. Pierre, Ray Strode
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Alexandre Franke [fr], Victor Ibragimov [tg], Arash Mousavi [fa],
|
||||||
|
Gabor Kelemen [hu], Sandeep Sheshrao Shedmake [mr], ManojKumar Giri [or],
|
||||||
|
Shantha kumar [ta], Rajesh Ranjan [hi], Stas Solovey [ru],
|
||||||
|
Shankar Prasad [kn], Dušan Kazik [sk], Ihar Hrachyshka [be],
|
||||||
|
Wouter Bolsterlee [nl], Kris Thomsen [da], Jiro Matsuzawa [ja],
|
||||||
|
Daniel Korostil [uk], Ani Peter [ml], Krishnababu Krothapalli [te],
|
||||||
|
Mantas Kriaučiūnas [lt], Praveen Illa [te]
|
||||||
|
|
||||||
|
3.7.92
|
||||||
|
======
|
||||||
|
* Drop fallback lock implementation [Florian; #693403]
|
||||||
|
* Don't let the user trigger message-tray when in fullscreen [Jasper; #694997]
|
||||||
|
* Scroll search results when using keynav [Jasper; #689681]
|
||||||
|
* Allow raising the shield by starting to type the password [Jasper; #686740]
|
||||||
|
* Improve tracking of fullscreen windows [Owen; #649748]
|
||||||
|
* Improve animation of new windows in overview [Giovanni; #695582]
|
||||||
|
* workspace switcher: Animate new workspaces created by DND [Giovanni; #685285]
|
||||||
|
* Give user time to read messages on login screen [Ray; #694688]
|
||||||
|
* Misc bug fixes and cleanups [Jasper, Ray, Florian, Cosimo, Giovanni, Adel,
|
||||||
|
Stef, Takao, Rui, Neil; #695154, #694993, #695272, #691578, #694321, #695338,
|
||||||
|
#695409, #695458, #695526, #695601, #695471, #695324, #695650, #695656,
|
||||||
|
#695659, #695485, #695395, #694951, #695824, #695841, #695801, #694321,
|
||||||
|
#693708, #695800, #695607, #695882, #691578, #685851, #694371, #690857,
|
||||||
|
#694092, #695747, #696007, #693438, #696064, #696102
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Allan Day, Takao Fujiwara, Adel Gadllah,
|
||||||
|
Tim Lunn, Rui Matos, Florian Müllner, Neil Roberts, Jasper St. Pierre,
|
||||||
|
Ray Strode, Stef Walter, Colin Walters, Owen W. Taylor
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Nilamdyuti Goswami [as], Chao-Hsiung Liao [zh_HK, zh_TW],
|
||||||
|
Yuri Myasoedov [ru], Gheyret Kenji [ug], Baurzhan Muftakhidinov [kk],
|
||||||
|
Ville-Pekka Vainio [fi], Matej Urbančič [sl],
|
||||||
|
Мирослав Николић [sr, sr@latin], Rūdolfs Mazurs [lv], Christian Kirbach [de],
|
||||||
|
Andika Triwidada [id], Gil Forcada [ca], Mattias Põldaru [et],
|
||||||
|
Duarte Loreto [pt], Adam Matoušek [cs], Changwoo Ryu [ko],
|
||||||
|
Ihar Hrachyshka [be], Carles Ferrando [ca@valencia], Sweta Kothari [gu]
|
||||||
|
|
||||||
|
3.7.91
|
||||||
|
======
|
||||||
|
* overview: Fade out controls during DND that are not targets [Cosimo; #686984]
|
||||||
|
* overview: Keep open when a Control key is held [Florian; #686984]
|
||||||
|
* Improve login screen => session transition [Ray; #694321]
|
||||||
|
* Center application grid horizontally [Florian; #694261]
|
||||||
|
* Fix hiding panel when fullscreen windows span multiple monitors [Adel; 646861]
|
||||||
|
* Tweak thresholds of pressure barrier [Jasper; #694467]
|
||||||
|
* Tweak window picker layout [Jasper; #694902]
|
||||||
|
* Expose key grab DBus API to gnome-settings-daemon [Florian; #643111]
|
||||||
|
* Don't always show message tray in overview, add message indicator
|
||||||
|
[Cosimo; #687787]
|
||||||
|
* Tweak startup animation [Ray; #694326]
|
||||||
|
* Add OSD popups and expose them to gnome-settings-daemon [Florian; #613543]
|
||||||
|
* Move loupe icon to the start of the search entry [Jasper; #695069]
|
||||||
|
* Don't show the input switcher with less than 2 items [Rui; 695000]
|
||||||
|
* Fix auto-completion of system modals immediately upon display [Stef; #692937]
|
||||||
|
* Ignore workspaces in alt-tab [Florian; #661156]
|
||||||
|
* Disable copying text from password entries [Florian; #695104]
|
||||||
|
* Use standard styling for ibus candidate popups [Allan; #694796]
|
||||||
|
* Fix calendar changing height on month changes [Giovanni; #641383]
|
||||||
|
* Port the hot corner to use pressure barriers [Jasper; #663661]
|
||||||
|
* Misc bug fixes and cleanups: [Hashem, Giovanni, Alban, Jasper, Cosimo,
|
||||||
|
Florian, Adel, Daniel, Matthias, Ray, Rui, Guillaume, Stef; #685849, #690643,
|
||||||
|
#694292, #693814, #694234, #694365, #694287, #694336, #694256, #694261,
|
||||||
|
#663601, #694441, #694284, #694463, #694475, #687248, #694394, #694320,
|
||||||
|
#694701, #694784, #694858, #694906, #694327, #694876, #694905, #694969,
|
||||||
|
#694970, #694988, #695006, #695001, #694998, #695023, #695002, #695073,
|
||||||
|
#695126, #687748, #694837, #693907, #679851, #694988]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Matthias Clasen, Alban Crequy, Allan Day,
|
||||||
|
Guillaume Desmottes, Adel Gadllah, Rui Matos, Daniel Mustieles,
|
||||||
|
Hashem Nasarat, Jasper St. Pierre, Ray Strode, Stef Walter
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Yuri Myasoedov [ru], Adam Matoušek [cs], Piotr Drąg [pl], Matej Urbančič [sl],
|
||||||
|
Sweta Kothari [gu], Kjartan Maraas [nb], Nguyễn Thái Ngọc Duy [vi],
|
||||||
|
Chao-Hsiung Liao [zh_HK, zh_TW], Dimitris Spingos [el],
|
||||||
|
Inaki Larranaga Murgoitio [eu], Luca Ferretti [it], A S Alam [pa],
|
||||||
|
Gheyret Kenji [ug], Stas Solovey [ru], Enrico Nicoletto [pt_BR],
|
||||||
|
Fran Diéguez [gl], Daniel Mustieles [es], Aurimas Černius [lt]
|
||||||
|
|
||||||
3.7.90
|
3.7.90
|
||||||
======
|
======
|
||||||
* Let GNOME Shell work on EGL and GLES2 [Neil; #693225, #693438, #693339]
|
* Let GNOME Shell work on EGL and GLES2 [Neil; #693225, #693438, #693339]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
AC_PREREQ(2.63)
|
AC_PREREQ(2.63)
|
||||||
AC_INIT([gnome-shell],[3.7.90],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
AC_INIT([gnome-shell],[3.8.0.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||||
@@ -63,13 +63,12 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
|||||||
CLUTTER_MIN_VERSION=1.13.4
|
CLUTTER_MIN_VERSION=1.13.4
|
||||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||||
GJS_MIN_VERSION=1.35.4
|
GJS_MIN_VERSION=1.35.4
|
||||||
MUTTER_MIN_VERSION=3.7.90
|
MUTTER_MIN_VERSION=3.8.0
|
||||||
GTK_MIN_VERSION=3.7.9
|
GTK_MIN_VERSION=3.7.9
|
||||||
GIO_MIN_VERSION=2.35.0
|
GIO_MIN_VERSION=2.35.0
|
||||||
LIBECAL_MIN_VERSION=3.5.3
|
LIBECAL_MIN_VERSION=3.5.3
|
||||||
LIBEDATASERVER_MIN_VERSION=3.5.3
|
LIBEDATASERVER_MIN_VERSION=3.5.3
|
||||||
TELEPATHY_GLIB_MIN_VERSION=0.17.5
|
TELEPATHY_GLIB_MIN_VERSION=0.17.5
|
||||||
TELEPATHY_LOGGER_MIN_VERSION=0.2.4
|
|
||||||
POLKIT_MIN_VERSION=0.100
|
POLKIT_MIN_VERSION=0.100
|
||||||
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
STARTUP_NOTIFICATION_MIN_VERSION=0.11
|
||||||
GCR_MIN_VERSION=3.3.90
|
GCR_MIN_VERSION=3.3.90
|
||||||
@@ -94,11 +93,10 @@ PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
|
|||||||
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
|
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
|
||||||
libcanberra libcanberra-gtk3
|
libcanberra libcanberra-gtk3
|
||||||
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
|
telepathy-glib >= $TELEPATHY_GLIB_MIN_VERSION
|
||||||
telepathy-logger-0.2 >= $TELEPATHY_LOGGER_MIN_VERSION
|
|
||||||
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
polkit-agent-1 >= $POLKIT_MIN_VERSION xfixes
|
||||||
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
|
libnm-glib libnm-util >= $NETWORKMANAGER_MIN_VERSION
|
||||||
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
|
libnm-gtk >= $NETWORKMANAGER_MIN_VERSION
|
||||||
gnome-keyring-1 gcr-3 >= $GCR_MIN_VERSION)
|
libsecret-unstable gcr-3 >= $GCR_MIN_VERSION)
|
||||||
|
|
||||||
PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_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(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
wandadir = $(pkgdatadir)
|
||||||
|
dist_wanda_DATA = wanda.png
|
||||||
|
|
||||||
desktopdir=$(datadir)/applications
|
desktopdir=$(datadir)/applications
|
||||||
desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
|
desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,8 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
/* PopupMenu */
|
/* PopupMenu */
|
||||||
|
|
||||||
.popup-menu-boxpointer {
|
.popup-menu-boxpointer,
|
||||||
|
.candidate-popup-boxpointer {
|
||||||
-arrow-border-radius: 8px;
|
-arrow-border-radius: 8px;
|
||||||
-arrow-background-color: rgba(0,0,0,0.9);
|
-arrow-background-color: rgba(0,0,0,0.9);
|
||||||
-arrow-border-width: 2px;
|
-arrow-border-width: 2px;
|
||||||
@@ -315,10 +316,20 @@ StScrollBar StButton#vhandle:active {
|
|||||||
.notification-button:focus,
|
.notification-button:focus,
|
||||||
.notification-icon-button:focus,
|
.notification-icon-button:focus,
|
||||||
.hotplug-notification-item:focus,
|
.hotplug-notification-item:focus,
|
||||||
.modal-dialog-button:focus {
|
.modal-dialog-button:focus,
|
||||||
|
.app-view-control:focus {
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-view-control:focus {
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-view-control:first-child:ltr:focus,
|
||||||
|
.app-view-control:last-child:rtl:focus {
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
.candidate-page-button:active,
|
.candidate-page-button:active,
|
||||||
.candidate-page-button:pressed,
|
.candidate-page-button:pressed,
|
||||||
.notification-button:active,
|
.notification-button:active,
|
||||||
@@ -644,6 +655,9 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
#overview {
|
#overview {
|
||||||
spacing: 24px;
|
spacing: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overview-controls {
|
||||||
padding-bottom: 32px;
|
padding-bottom: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -731,13 +745,36 @@ StScrollBar StButton#vhandle:active {
|
|||||||
-vertical-spacing: 32px;
|
-vertical-spacing: 32px;
|
||||||
padding-left: 32px;
|
padding-left: 32px;
|
||||||
padding-right: 32px;
|
padding-right: 32px;
|
||||||
padding-bottom: 32px;
|
padding-bottom: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.window-picker.external-monitor {
|
.window-picker.external-monitor {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.messages-indicator {
|
||||||
|
color: #999999;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messages-indicator-contents {
|
||||||
|
spacing: 12px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messages-indicator-contents:hover {
|
||||||
|
color: white;
|
||||||
|
text-shadow: black 0px 2px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messages-indicator-highlight {
|
||||||
|
background-gradient-start: transparent;
|
||||||
|
background-gradient-end: #999999;
|
||||||
|
background-gradient-direction: vertical;
|
||||||
|
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Dash */
|
/* Dash */
|
||||||
|
|
||||||
#dash {
|
#dash {
|
||||||
@@ -781,7 +818,7 @@ StScrollBar StButton#vhandle:active {
|
|||||||
/* Search Results */
|
/* Search Results */
|
||||||
|
|
||||||
#searchResults {
|
#searchResults {
|
||||||
padding: 20px 10px 10px 10px;
|
padding: 20px 10px 0px 10px;
|
||||||
spacing: 18px;
|
spacing: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -850,15 +887,18 @@ StScrollBar StButton#vhandle:active {
|
|||||||
|
|
||||||
.app-view-controls {
|
.app-view-controls {
|
||||||
width: 250px;
|
width: 250px;
|
||||||
|
padding-bottom: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-view-control {
|
.app-view-control {
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
StScrollView.frequent-apps StScrollBar {
|
.search-display > StBoxLayout,
|
||||||
min-width: 0px;
|
.all-apps > StBoxLayout,
|
||||||
width: 0px;
|
.frequent-apps > StBoxLayout {
|
||||||
|
/* horizontal padding to make sure scrollbars or dash don't overlap content */
|
||||||
|
padding: 0px 88px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-folder-icon {
|
.app-folder-icon {
|
||||||
@@ -881,8 +921,6 @@ StScrollView.frequent-apps StScrollBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.list-search-result-description {
|
.list-search-result-description {
|
||||||
font-weight: bold;
|
|
||||||
font-size: 12pt;
|
|
||||||
color: #eeeeec;
|
color: #eeeeec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,6 +974,14 @@ StScrollView.frequent-apps StScrollBar {
|
|||||||
color:white;
|
color:white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-display .app-well-app > .overview-icon {
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-search-result:hover .list-search-result-description {
|
||||||
|
text-shadow: rgba(0,0,0,0.8) 0px 1px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.show-apps {
|
.show-apps {
|
||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
}
|
}
|
||||||
@@ -1226,15 +1272,15 @@ StScrollView.frequent-apps StScrollBar {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-other-month-day {
|
|
||||||
color: #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.calendar-day-with-events {
|
.calendar-day-with-events {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.calendar-other-month-day {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
.events-header-vbox {
|
.events-header-vbox {
|
||||||
spacing: 6pt;
|
spacing: 6pt;
|
||||||
padding-right: .5em;
|
padding-right: .5em;
|
||||||
@@ -1577,12 +1623,26 @@ StScrollView.frequent-apps StScrollBar {
|
|||||||
-shell-counter-overlap-y: 13px;
|
-shell-counter-overlap-y: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* OSD */
|
||||||
|
.osd-window {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
spacing: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.osd-window .level {
|
||||||
|
height: 0.6em;
|
||||||
|
border-radius: 0.3em;
|
||||||
|
background-color: rgba(190,190,190,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
/* App Switcher */
|
/* App Switcher */
|
||||||
.switcher-popup {
|
.switcher-popup {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
spacing: 16px;
|
spacing: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.osd-window,
|
||||||
.switcher-list {
|
.switcher-list {
|
||||||
background: rgba(0,0,0,0.8);
|
background: rgba(0,0,0,0.8);
|
||||||
border: 1px solid rgba(128,128,128,0.40);
|
border: 1px solid rgba(128,128,128,0.40);
|
||||||
@@ -2084,23 +2144,12 @@ StScrollView.frequent-apps StScrollBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* IBus Candidate Popup */
|
/* IBus Candidate Popup */
|
||||||
.candidate-popup-boxpointer {
|
|
||||||
-arrow-border-radius: 8px;
|
|
||||||
-arrow-background-color: #707070;
|
|
||||||
-arrow-border-width: 0px;
|
|
||||||
-arrow-base: 24px;
|
|
||||||
-arrow-rise: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.candidate-popup-content {
|
.candidate-popup-content {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
spacing: 0.3em;
|
spacing: 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.candidate-popup-text {
|
|
||||||
font-size: 9pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
.candidate-index {
|
.candidate-index {
|
||||||
padding: 0 0.5em 0 0;
|
padding: 0 0.5em 0 0;
|
||||||
color: #cccccc;
|
color: #cccccc;
|
||||||
@@ -2166,6 +2215,9 @@ StScrollView.frequent-apps StScrollBar {
|
|||||||
border: none;
|
border: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
|
padding-bottom: 80px;
|
||||||
|
padding-top: 80px;
|
||||||
|
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
max-height: 700px;
|
max-height: 700px;
|
||||||
@@ -2480,7 +2532,7 @@ StScrollView.frequent-apps StScrollBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-source-switcher-symbol {
|
.input-source-switcher-symbol {
|
||||||
font-size: 42pt;
|
font-size: 34pt;
|
||||||
width: 96px;
|
width: 96px;
|
||||||
height: 96px;
|
height: 96px;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
data/wanda.png
Normal file
BIN
data/wanda.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -66,11 +66,4 @@ its dependencies to build from tarballs.</description>
|
|||||||
<gnome:userid>fmuellner</gnome:userid>
|
<gnome:userid>fmuellner</gnome:userid>
|
||||||
</foaf:Person>
|
</foaf:Person>
|
||||||
</maintainer>
|
</maintainer>
|
||||||
<maintainer>
|
|
||||||
<foaf:Person>
|
|
||||||
<foaf:name>Ray Strode</foaf:name>
|
|
||||||
<foaf:mbox rdf:resource="mailto:halfline@gmail.com" />
|
|
||||||
<gnome:userid>halfline</gnome:userid>
|
|
||||||
</foaf:Person>
|
|
||||||
</maintainer>
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/shellEntry.js \
|
ui/shellEntry.js \
|
||||||
ui/shellMountOperation.js \
|
ui/shellMountOperation.js \
|
||||||
ui/notificationDaemon.js \
|
ui/notificationDaemon.js \
|
||||||
|
ui/osdWindow.js \
|
||||||
ui/overview.js \
|
ui/overview.js \
|
||||||
ui/overviewControls.js \
|
ui/overviewControls.js \
|
||||||
ui/panel.js \
|
ui/panel.js \
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ const Application = new Lang.Class({
|
|||||||
this._extensionPrefsModules = {};
|
this._extensionPrefsModules = {};
|
||||||
|
|
||||||
this._extensionIters = {};
|
this._extensionIters = {};
|
||||||
|
this._startupUuid = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildModel: function() {
|
_buildModel: function() {
|
||||||
@@ -203,6 +204,7 @@ const Application = new Lang.Class({
|
|||||||
_scanExtensions: function() {
|
_scanExtensions: function() {
|
||||||
let finder = new ExtensionUtils.ExtensionFinder();
|
let finder = new ExtensionUtils.ExtensionFinder();
|
||||||
finder.connect('extension-found', Lang.bind(this, this._extensionFound));
|
finder.connect('extension-found', Lang.bind(this, this._extensionFound));
|
||||||
|
finder.connect('extensions-loaded', Lang.bind(this, this._extensionsLoaded));
|
||||||
finder.scanExtensions();
|
finder.scanExtensions();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -212,6 +214,11 @@ const Application = new Lang.Class({
|
|||||||
this._extensionIters[extension.uuid] = iter;
|
this._extensionIters[extension.uuid] = iter;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_extensionsLoaded: function() {
|
||||||
|
if (this._startupUuid && this._extensionAvailable(this._startupUuid))
|
||||||
|
this._selectExtension(this._startupUuid);
|
||||||
|
this._startupUuid = null;
|
||||||
|
},
|
||||||
|
|
||||||
_onActivate: function() {
|
_onActivate: function() {
|
||||||
this._window.present();
|
this._window.present();
|
||||||
@@ -232,10 +239,10 @@ const Application = new Lang.Class({
|
|||||||
// Strip off "extension:///" prefix which fakes a URI, if it exists
|
// Strip off "extension:///" prefix which fakes a URI, if it exists
|
||||||
uuid = stripPrefix(uuid, "extension:///");
|
uuid = stripPrefix(uuid, "extension:///");
|
||||||
|
|
||||||
if (!this._extensionAvailable(uuid))
|
if (this._extensionAvailable(uuid))
|
||||||
return 1;
|
this._selectExtension(uuid);
|
||||||
|
else
|
||||||
this._selectExtension(uuid);
|
this._startupUuid = uuid;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -594,6 +594,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
|
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
|
||||||
can_focus: true });
|
can_focus: true });
|
||||||
this._promptEntryTextChangedId = 0;
|
this._promptEntryTextChangedId = 0;
|
||||||
|
this._promptEntryActivateId = 0;
|
||||||
this._promptBox.add(this._promptEntry,
|
this._promptBox.add(this._promptEntry,
|
||||||
{ expand: true,
|
{ expand: true,
|
||||||
x_fill: true,
|
x_fill: true,
|
||||||
@@ -690,6 +691,8 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_reset: function() {
|
_reset: function() {
|
||||||
|
this._userVerifier.clear();
|
||||||
|
|
||||||
this._updateSensitivity(true);
|
this._updateSensitivity(true);
|
||||||
this._promptMessage.hide();
|
this._promptMessage.hide();
|
||||||
this._user = null;
|
this._user = null;
|
||||||
@@ -753,7 +756,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
time: _FADE_ANIMATION_TIME,
|
time: _FADE_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad' });
|
transition: 'easeOutQuad' });
|
||||||
|
|
||||||
if (!this._user || (this._user.is_logged_in() && this._verifyingUser))
|
if ((this._user && !this._user.is_logged_in()) || this._verifyingUser)
|
||||||
this._sessionList.actor.show();
|
this._sessionList.actor.show();
|
||||||
|
|
||||||
this._promptEntry.grab_key_focus();
|
this._promptEntry.grab_key_focus();
|
||||||
@@ -811,6 +814,11 @@ const LoginDialog = new Lang.Class({
|
|||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0);
|
this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
this._promptEntryActivateId =
|
||||||
|
this._promptEntry.clutter_text.connect('activate', function() {
|
||||||
|
hold.release();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateSensitivity: function(sensitive) {
|
_updateSensitivity: function(sensitive) {
|
||||||
@@ -835,6 +843,11 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._promptEntryTextChangedId = 0;
|
this._promptEntryTextChangedId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._promptEntryActivateId > 0) {
|
||||||
|
this._promptEntry.clutter_text.disconnect(this._promptEntryActivateId);
|
||||||
|
this._promptEntryActivateId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
this._setWorking(false);
|
this._setWorking(false);
|
||||||
this._promptBox.hide();
|
this._promptBox.hide();
|
||||||
this._promptLoginHint.hide();
|
this._promptLoginHint.hide();
|
||||||
@@ -917,7 +930,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
return batch.run();
|
return batch.run();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onSessionOpened: function(client, serviceName) {
|
_startSession: function(serviceName) {
|
||||||
Tweener.addTween(this.dialogLayout,
|
Tweener.addTween(this.dialogLayout,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
time: _FADE_ANIMATION_TIME,
|
time: _FADE_ANIMATION_TIME,
|
||||||
@@ -940,6 +953,18 @@ const LoginDialog = new Lang.Class({
|
|||||||
onCompleteScope: this });
|
onCompleteScope: this });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onSessionOpened: function(client, serviceName) {
|
||||||
|
if (!this._userVerifier.hasPendingMessages) {
|
||||||
|
this._startSession(serviceName);
|
||||||
|
} else {
|
||||||
|
let signalId = this._userVerifier.connect('no-more-messages',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._userVerifier.disconnect(signalId);
|
||||||
|
this._startSession(serviceName);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_waitForItemForUser: function(userName) {
|
_waitForItemForUser: function(userName) {
|
||||||
let item = this._userList.getItemFromUserName(userName);
|
let item = this._userList.getItemFromUserName(userName);
|
||||||
|
|
||||||
@@ -1003,7 +1028,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
function() {
|
function() {
|
||||||
// If we're just starting out, start on the right
|
// If we're just starting out, start on the right
|
||||||
// item.
|
// item.
|
||||||
if (!this.is_loaded) {
|
if (!this._userManager.is_loaded) {
|
||||||
this._userList.jumpToItem(this._timedLoginItem);
|
this._userList.jumpToItem(this._timedLoginItem);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1141,15 +1166,6 @@ const LoginDialog = new Lang.Class({
|
|||||||
Lang.bind(this, function(userManager, user) {
|
Lang.bind(this, function(userManager, user) {
|
||||||
this._userList.removeUser(user);
|
this._userList.removeUser(user);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// emitted in idle so caller doesn't have to explicitly check if
|
|
||||||
// it's loaded immediately after construction
|
|
||||||
// (since there's no way the caller could be listening for
|
|
||||||
// 'loaded' yet)
|
|
||||||
Mainloop.idle_add(Lang.bind(this, function() {
|
|
||||||
this.emit('loaded');
|
|
||||||
this.is_loaded = true;
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onOpened: function() {
|
_onOpened: function() {
|
||||||
@@ -1164,5 +1180,9 @@ const LoginDialog = new Lang.Class({
|
|||||||
this.parent();
|
this.parent();
|
||||||
|
|
||||||
Main.ctrlAltTabManager.removeGroup(this.dialogLayout);
|
Main.ctrlAltTabManager.removeGroup(this.dialogLayout);
|
||||||
}
|
},
|
||||||
|
|
||||||
|
addCharacter: function(unichar) {
|
||||||
|
this._promptEntry.clutter_text.insert_unichar(unichar);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
116
js/gdm/util.js
116
js/gdm/util.js
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
@@ -27,6 +28,9 @@ const ALLOWED_FAILURES_KEY = 'allowed-failures';
|
|||||||
const LOGO_KEY = 'logo';
|
const LOGO_KEY = 'logo';
|
||||||
const DISABLE_USER_LIST_KEY = 'disable-user-list';
|
const DISABLE_USER_LIST_KEY = 'disable-user-list';
|
||||||
|
|
||||||
|
// Give user 16ms to read each character of a PAM message
|
||||||
|
const USER_READ_TIME = 16
|
||||||
|
|
||||||
function fadeInActor(actor) {
|
function fadeInActor(actor) {
|
||||||
if (actor.opacity == 255 && actor.visible)
|
if (actor.opacity == 255 && actor.visible)
|
||||||
return null;
|
return null;
|
||||||
@@ -114,6 +118,9 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
|
|
||||||
this._fprintManager = new Fprint.FprintManager();
|
this._fprintManager = new Fprint.FprintManager();
|
||||||
this._realmManager = new Realmd.Manager();
|
this._realmManager = new Realmd.Manager();
|
||||||
|
this._messageQueue = [];
|
||||||
|
this._messageQueueTimeoutId = 0;
|
||||||
|
this.hasPendingMessages = false;
|
||||||
|
|
||||||
this._failCounter = 0;
|
this._failCounter = 0;
|
||||||
},
|
},
|
||||||
@@ -153,13 +160,73 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
this._userVerifier.run_dispose();
|
this._userVerifier.run_dispose();
|
||||||
this._userVerifier = null;
|
this._userVerifier = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._clearMessageQueue();
|
||||||
},
|
},
|
||||||
|
|
||||||
answerQuery: function(serviceName, answer) {
|
answerQuery: function(serviceName, answer) {
|
||||||
// Clear any previous message
|
if (!this._userVerifier.hasPendingMessages) {
|
||||||
this.emit('show-message', null, null);
|
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||||
|
} else {
|
||||||
|
let signalId = this._userVerifier.connect('no-more-messages',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._userVerifier.disconnect(signalId);
|
||||||
|
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
_getIntervalForMessage: function(message) {
|
||||||
|
// We probably could be smarter here
|
||||||
|
return message.length * USER_READ_TIME;
|
||||||
|
},
|
||||||
|
|
||||||
|
finishMessageQueue: function() {
|
||||||
|
if (!this.hasPendingMessages)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._messageQueue = [];
|
||||||
|
|
||||||
|
this.hasPendingMessages = false;
|
||||||
|
this.emit('no-more-messages');
|
||||||
|
},
|
||||||
|
|
||||||
|
_queueMessageTimeout: function() {
|
||||||
|
if (this._messageQueue.length == 0) {
|
||||||
|
this.finishMessageQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._messageQueueTimeoutId != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let message = this._messageQueue.shift();
|
||||||
|
this.emit('show-message', message.text, message.iconName);
|
||||||
|
|
||||||
|
this._messageQueueTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||||
|
message.interval,
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._messageQueueTimeoutId = 0;
|
||||||
|
this._queueMessageTimeout();
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_queueMessage: function(message, iconName) {
|
||||||
|
let interval = this._getIntervalForMessage(message);
|
||||||
|
|
||||||
|
this.hasPendingMessages = true;
|
||||||
|
this._messageQueue.push({ text: message, interval: interval, iconName: iconName });
|
||||||
|
this._queueMessageTimeout();
|
||||||
|
},
|
||||||
|
|
||||||
|
_clearMessageQueue: function() {
|
||||||
|
this.finishMessageQueue();
|
||||||
|
|
||||||
|
if (this._messageQueueTimeoutId != 0) {
|
||||||
|
GLib.source_remove(this._messageQueueTimeoutId);
|
||||||
|
this._messageQueueTimeoutId = 0;
|
||||||
|
}
|
||||||
|
this.emit('show-message', null, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
_checkForFingerprintReader: function() {
|
_checkForFingerprintReader: function() {
|
||||||
@@ -179,7 +246,7 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
logError(error, where);
|
logError(error, where);
|
||||||
this._hold.release();
|
this._hold.release();
|
||||||
|
|
||||||
this.emit('show-message', _("Authentication error"), 'login-dialog-message-warning');
|
this._queueMessage(_("Authentication error"), 'login-dialog-message-warning');
|
||||||
this._verificationFailed(false);
|
this._verificationFailed(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -298,7 +365,7 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
// to indicate the user can swipe their finger instead
|
// to indicate the user can swipe their finger instead
|
||||||
this.emit('show-login-hint', _("(or swipe finger)"));
|
this.emit('show-login-hint', _("(or swipe finger)"));
|
||||||
} else if (serviceName == PASSWORD_SERVICE_NAME) {
|
} else if (serviceName == PASSWORD_SERVICE_NAME) {
|
||||||
this.emit('show-message', info, 'login-dialog-message-info');
|
this._queueMessage(info, 'login-dialog-message-info');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -307,7 +374,7 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
// users who haven't enrolled their fingerprint.
|
// users who haven't enrolled their fingerprint.
|
||||||
if (serviceName != PASSWORD_SERVICE_NAME)
|
if (serviceName != PASSWORD_SERVICE_NAME)
|
||||||
return;
|
return;
|
||||||
this.emit('show-message', problem, 'login-dialog-message-warning');
|
this._queueMessage(problem, 'login-dialog-message-warning');
|
||||||
},
|
},
|
||||||
|
|
||||||
_showRealmLoginHint: function() {
|
_showRealmLoginHint: function() {
|
||||||
@@ -346,8 +413,6 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onReset: function() {
|
_onReset: function() {
|
||||||
this.clear();
|
|
||||||
|
|
||||||
// Clear previous attempts to authenticate
|
// Clear previous attempts to authenticate
|
||||||
this._failCounter = 0;
|
this._failCounter = 0;
|
||||||
|
|
||||||
@@ -358,6 +423,15 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
this.emit('verification-complete');
|
this.emit('verification-complete');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_cancelAndReset: function() {
|
||||||
|
this.cancel();
|
||||||
|
this._onReset();
|
||||||
|
},
|
||||||
|
|
||||||
|
_retry: function() {
|
||||||
|
this.begin(this._userName, new Batch.Hold());
|
||||||
|
},
|
||||||
|
|
||||||
_verificationFailed: function(retry) {
|
_verificationFailed: function(retry) {
|
||||||
// For Not Listed / enterprise logins, immediately reset
|
// For Not Listed / enterprise logins, immediately reset
|
||||||
// the dialog
|
// the dialog
|
||||||
@@ -369,15 +443,25 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
|
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY);
|
||||||
|
|
||||||
if (canRetry) {
|
if (canRetry) {
|
||||||
this.clear();
|
if (!this._userVerifier.hasPendingMessages) {
|
||||||
this.begin(this._userName, new Batch.Hold());
|
this._retry();
|
||||||
|
} else {
|
||||||
|
let signalId = this._userVerifier.connect('no-more-messages',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._userVerifier.disconnect(signalId);
|
||||||
|
this._retry();
|
||||||
|
}));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Allow some time to see the message, then reset everything
|
if (!this._userVerifier.hasPendingMessages) {
|
||||||
Mainloop.timeout_add(3000, Lang.bind(this, function() {
|
this._cancelAndReset();
|
||||||
this.cancel();
|
} else {
|
||||||
|
let signalId = this._userVerifier.connect('no-more-messages',
|
||||||
this._onReset();
|
Lang.bind(this, function() {
|
||||||
}));
|
this._userVerifier.disconnect(signalId);
|
||||||
|
this._cancelAndReset();
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('verification-failed');
|
this.emit('verification-failed');
|
||||||
|
|||||||
@@ -174,10 +174,15 @@ const ExtensionFinder = new Lang.Class({
|
|||||||
this.emit('extension-found', extension);
|
this.emit('extension-found', extension);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_extensionsLoaded: function() {
|
||||||
|
this.emit('extensions-loaded');
|
||||||
|
},
|
||||||
|
|
||||||
scanExtensions: function() {
|
scanExtensions: function() {
|
||||||
let perUserDir = Gio.File.new_for_path(global.userdatadir);
|
let perUserDir = Gio.File.new_for_path(global.userdatadir);
|
||||||
FileUtils.collectFromDatadirsAsync('extensions',
|
FileUtils.collectFromDatadirsAsync('extensions',
|
||||||
{ processFile: Lang.bind(this, this._loadExtension),
|
{ processFile: Lang.bind(this, this._loadExtension),
|
||||||
|
loadedCallback: Lang.bind(this, this._extensionsLoaded),
|
||||||
includeUserDir: true,
|
includeUserDir: true,
|
||||||
data: perUserDir });
|
data: perUserDir });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager
|
|||||||
<arg type='s' direction='in'/>
|
<arg type='s' direction='in'/>
|
||||||
<arg type='h' direction='out'/>
|
<arg type='h' direction='out'/>
|
||||||
</method>
|
</method>
|
||||||
|
<method name='GetSession'>
|
||||||
|
<arg type='s' direction='in'/>
|
||||||
|
<arg type='o' direction='out'/>
|
||||||
|
</method>
|
||||||
<method name='ListSessions'>
|
<method name='ListSessions'>
|
||||||
<arg name='sessions' type='a(susso)' direction='out'/>
|
<arg name='sessions' type='a(susso)' direction='out'/>
|
||||||
</method>
|
</method>
|
||||||
@@ -72,7 +76,36 @@ const ConsoleKitSession = Gio.DBusProxy.makeProxyWrapper(ConsoleKitSessionIface)
|
|||||||
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
|
const ConsoleKitManager = Gio.DBusProxy.makeProxyWrapper(ConsoleKitManagerIface);
|
||||||
|
|
||||||
function haveSystemd() {
|
function haveSystemd() {
|
||||||
return GLib.access("/sys/fs/cgroup/systemd", 0) >= 0;
|
return GLib.access("/run/systemd/seats", 0) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function versionCompare(required, reference) {
|
||||||
|
required = required.split('.');
|
||||||
|
reference = reference.split('.');
|
||||||
|
|
||||||
|
for (let i = 0; i < required.length; i++) {
|
||||||
|
if (required[i] != reference[i])
|
||||||
|
return required[i] < reference[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canLock() {
|
||||||
|
try {
|
||||||
|
let params = GLib.Variant.new('(ss)', ['org.gnome.DisplayManager.Manager', 'Version']);
|
||||||
|
let result = Gio.DBus.system.call_sync('org.gnome.DisplayManager',
|
||||||
|
'/org/gnome/DisplayManager/Manager',
|
||||||
|
'org.freedesktop.DBus.Properties',
|
||||||
|
'Get', params, null,
|
||||||
|
Gio.DBusCallFlags.NONE,
|
||||||
|
-1, null);
|
||||||
|
|
||||||
|
let version = result.deep_unpack()[0].deep_unpack();
|
||||||
|
return versionCompare('3.5.91', version);
|
||||||
|
} catch(e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _loginManager = null;
|
let _loginManager = null;
|
||||||
@@ -107,15 +140,23 @@ const LoginManagerSystemd = new Lang.Class({
|
|||||||
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
||||||
// session objects have different interfaces - but in both cases there are
|
// session objects have different interfaces - but in both cases there are
|
||||||
// Lock/Unlock signals, and that's all we count upon at the moment.
|
// Lock/Unlock signals, and that's all we count upon at the moment.
|
||||||
getCurrentSessionProxy: function() {
|
getCurrentSessionProxy: function(callback) {
|
||||||
if (!this._currentSession) {
|
if (this._currentSession) {
|
||||||
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
|
callback (this._currentSession);
|
||||||
'org.freedesktop.login1',
|
return;
|
||||||
'/org/freedesktop/login1/session/' +
|
|
||||||
GLib.getenv('XDG_SESSION_ID'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._currentSession;
|
this._proxy.GetSessionRemote(GLib.getenv('XDG_SESSION_ID'), Lang.bind(this,
|
||||||
|
function(result, error) {
|
||||||
|
if (error) {
|
||||||
|
logError(error, 'Could not get a proxy for the current session');
|
||||||
|
} else {
|
||||||
|
this._currentSession = new SystemdLoginSession(Gio.DBus.system,
|
||||||
|
'org.freedesktop.login1',
|
||||||
|
result[0]);
|
||||||
|
callback(this._currentSession);
|
||||||
|
}
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
canPowerOff: function(asyncCallback) {
|
canPowerOff: function(asyncCallback) {
|
||||||
@@ -204,15 +245,23 @@ const LoginManagerConsoleKit = new Lang.Class({
|
|||||||
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
// Having this function is a bit of a hack since the Systemd and ConsoleKit
|
||||||
// session objects have different interfaces - but in both cases there are
|
// session objects have different interfaces - but in both cases there are
|
||||||
// Lock/Unlock signals, and that's all we count upon at the moment.
|
// Lock/Unlock signals, and that's all we count upon at the moment.
|
||||||
getCurrentSessionProxy: function() {
|
getCurrentSessionProxy: function(callback) {
|
||||||
if (!this._currentSession) {
|
if (this._currentSession) {
|
||||||
let [currentSessionId] = this._proxy.GetCurrentSessionSync();
|
callback (this._currentSession);
|
||||||
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
|
return;
|
||||||
'org.freedesktop.ConsoleKit',
|
|
||||||
currentSessionId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._currentSession;
|
this._proxy.GetCurrentSessionRemote(Lang.bind(this,
|
||||||
|
function(result, error) {
|
||||||
|
if (error) {
|
||||||
|
logError(error, 'Could not get a proxy for the current session');
|
||||||
|
} else {
|
||||||
|
this._currentSession = new ConsoleKitSession(Gio.DBus.system,
|
||||||
|
'org.freedesktop.ConsoleKit',
|
||||||
|
result[0]);
|
||||||
|
callback(this._currentSession);
|
||||||
|
}
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
canPowerOff: function(asyncCallback) {
|
canPowerOff: function(asyncCallback) {
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ const GLib = imports.gi.GLib;
|
|||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const SCROLL_TIME = 0.1;
|
||||||
|
|
||||||
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||||
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
|
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
|
||||||
@@ -234,3 +237,39 @@ function makeCloseButton() {
|
|||||||
|
|
||||||
return closeButton;
|
return closeButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||||
|
let adjustment = scrollView.vscroll.adjustment;
|
||||||
|
let [value, lower, upper, stepIncrement, pageIncrement, pageSize] = adjustment.get_values();
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
|
let vfade = scrollView.get_effect("fade");
|
||||||
|
if (vfade)
|
||||||
|
offset = vfade.vfade_offset;
|
||||||
|
|
||||||
|
let box = actor.get_allocation_box();
|
||||||
|
let y1 = box.y1, y2 = box.y2;
|
||||||
|
|
||||||
|
let parent = actor.get_parent();
|
||||||
|
while (parent != scrollView) {
|
||||||
|
if (!parent)
|
||||||
|
throw new Error("actor not in scroll view");
|
||||||
|
|
||||||
|
let box = parent.get_allocation_box();
|
||||||
|
y1 += box.y1;
|
||||||
|
y2 += box.y1;
|
||||||
|
parent = parent.get_parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y1 < value + offset)
|
||||||
|
value = Math.max(0, y1 - offset);
|
||||||
|
else if (y2 > value + pageSize - offset)
|
||||||
|
value = Math.min(upper, y2 + offset - pageSize);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
Tweener.addTween(adjustment,
|
||||||
|
{ value: value,
|
||||||
|
time: SCROLL_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
}
|
||||||
|
|||||||
106
js/ui/altTab.js
106
js/ui/altTab.js
@@ -98,43 +98,13 @@ const AppSwitcherPopup = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_getAppLists: function() {
|
|
||||||
let tracker = Shell.WindowTracker.get_default();
|
|
||||||
let appSys = Shell.AppSystem.get_default();
|
|
||||||
let allApps = appSys.get_running ();
|
|
||||||
|
|
||||||
let screen = global.screen;
|
|
||||||
let display = screen.get_display();
|
|
||||||
let windows = display.get_tab_list(Meta.TabList.NORMAL_ALL, screen,
|
|
||||||
screen.get_active_workspace());
|
|
||||||
|
|
||||||
// windows is only the windows on the current workspace. For
|
|
||||||
// each one, if it corresponds to an app we know, move that
|
|
||||||
// app from allApps to apps.
|
|
||||||
let apps = [];
|
|
||||||
for (let i = 0; i < windows.length && allApps.length != 0; i++) {
|
|
||||||
let app = tracker.get_window_app(windows[i]);
|
|
||||||
let index = allApps.indexOf(app);
|
|
||||||
if (index != -1) {
|
|
||||||
apps.push(app);
|
|
||||||
allApps.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now @apps is a list of apps on the current workspace, in
|
|
||||||
// standard Alt+Tab order (MRU except for minimized windows),
|
|
||||||
// and allApps is a list of apps that only appear on other
|
|
||||||
// workspaces, sorted by user_time, which is good enough.
|
|
||||||
return [apps, allApps];
|
|
||||||
},
|
|
||||||
|
|
||||||
_createSwitcher: function() {
|
_createSwitcher: function() {
|
||||||
let [localApps, otherApps] = this._getAppLists();
|
let apps = Shell.AppSystem.get_default().get_running ();
|
||||||
|
|
||||||
if (localApps.length == 0 && otherApps.length == 0)
|
if (apps.length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
this._switcherList = new AppSwitcher(localApps, otherApps, this);
|
this._switcherList = new AppSwitcher(apps, this);
|
||||||
this._items = this._switcherList.icons;
|
this._items = this._switcherList.icons;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -262,15 +232,11 @@ const AppSwitcherPopup = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_finish : function(timestamp) {
|
_finish : function(timestamp) {
|
||||||
this.parent();
|
|
||||||
|
|
||||||
let appIcon = this._items[this._selectedIndex];
|
let appIcon = this._items[this._selectedIndex];
|
||||||
let window;
|
let window = this._currentWindow > 0 ? this._currentWindow : 0;
|
||||||
if (this._currentWindow >= 0)
|
appIcon.app.activate_window(appIcon.cachedWindows[window], timestamp);
|
||||||
window = appIcon.cachedWindows[this._currentWindow];
|
|
||||||
else
|
this.parent();
|
||||||
window = null;
|
|
||||||
appIcon.app.activate_window(window, timestamp);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy : function() {
|
_onDestroy : function() {
|
||||||
@@ -429,9 +395,9 @@ const WindowSwitcherPopup = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_finish: function() {
|
_finish: function() {
|
||||||
this.parent();
|
|
||||||
|
|
||||||
Main.activateWindow(this._items[this._selectedIndex].window);
|
Main.activateWindow(this._items[this._selectedIndex].window);
|
||||||
|
|
||||||
|
this.parent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -461,34 +427,26 @@ const AppSwitcher = new Lang.Class({
|
|||||||
Name: 'AppSwitcher',
|
Name: 'AppSwitcher',
|
||||||
Extends: SwitcherPopup.SwitcherList,
|
Extends: SwitcherPopup.SwitcherList,
|
||||||
|
|
||||||
_init : function(localApps, otherApps, altTabPopup) {
|
_init : function(apps, altTabPopup) {
|
||||||
this.parent(true);
|
this.parent(true);
|
||||||
|
|
||||||
// Construct the AppIcons, add to the popup
|
|
||||||
let activeWorkspace = global.screen.get_active_workspace();
|
|
||||||
let workspaceIcons = [];
|
|
||||||
let otherIcons = [];
|
|
||||||
for (let i = 0; i < localApps.length; i++) {
|
|
||||||
let appIcon = new AppIcon(localApps[i]);
|
|
||||||
// Cache the window list now; we don't handle dynamic changes here,
|
|
||||||
// and we don't want to be continually retrieving it
|
|
||||||
appIcon.cachedWindows = appIcon.app.get_windows();
|
|
||||||
workspaceIcons.push(appIcon);
|
|
||||||
}
|
|
||||||
for (let i = 0; i < otherApps.length; i++) {
|
|
||||||
let appIcon = new AppIcon(otherApps[i]);
|
|
||||||
appIcon.cachedWindows = appIcon.app.get_windows();
|
|
||||||
otherIcons.push(appIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.icons = [];
|
this.icons = [];
|
||||||
this._arrows = [];
|
this._arrows = [];
|
||||||
for (let i = 0; i < workspaceIcons.length; i++)
|
|
||||||
this._addIcon(workspaceIcons[i]);
|
let windowTracker = Shell.WindowTracker.get_default();
|
||||||
if (workspaceIcons.length > 0 && otherIcons.length > 0)
|
let allWindows = global.display.get_tab_list(Meta.TabList.NORMAL,
|
||||||
this.addSeparator();
|
global.screen, null);
|
||||||
for (let i = 0; i < otherIcons.length; i++)
|
|
||||||
this._addIcon(otherIcons[i]);
|
// Construct the AppIcons, add to the popup
|
||||||
|
for (let i = 0; i < apps.length; i++) {
|
||||||
|
let appIcon = new AppIcon(apps[i]);
|
||||||
|
// Cache the window list now; we don't handle dynamic changes here,
|
||||||
|
// and we don't want to be continually retrieving it
|
||||||
|
appIcon.cachedWindows = allWindows.filter(function(w) {
|
||||||
|
return windowTracker.get_window_app (w) == appIcon.app;
|
||||||
|
});
|
||||||
|
this._addIcon(appIcon);
|
||||||
|
}
|
||||||
|
|
||||||
this._curApp = -1;
|
this._curApp = -1;
|
||||||
this._iconSize = 0;
|
this._iconSize = 0;
|
||||||
@@ -514,8 +472,6 @@ const AppSwitcher = new Lang.Class({
|
|||||||
let [iconMinHeight, iconNaturalHeight] = this.icons[j].label.get_preferred_height(-1);
|
let [iconMinHeight, iconNaturalHeight] = this.icons[j].label.get_preferred_height(-1);
|
||||||
let iconSpacing = iconNaturalHeight + iconPadding + iconBorder;
|
let iconSpacing = iconNaturalHeight + iconPadding + iconBorder;
|
||||||
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
||||||
if (this._separator)
|
|
||||||
totalSpacing += this._separator.width + this._list.spacing;
|
|
||||||
|
|
||||||
// We just assume the whole screen here due to weirdness happing with the passed width
|
// We just assume the whole screen here due to weirdness happing with the passed width
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
let primary = Main.layoutManager.primaryMonitor;
|
||||||
@@ -638,24 +594,12 @@ const ThumbnailList = new Lang.Class({
|
|||||||
_init : function(windows) {
|
_init : function(windows) {
|
||||||
this.parent(false);
|
this.parent(false);
|
||||||
|
|
||||||
let activeWorkspace = global.screen.get_active_workspace();
|
|
||||||
|
|
||||||
// We fake the value of 'separatorAdded' when the app has no window
|
|
||||||
// on the current workspace, to avoid displaying a useless separator in
|
|
||||||
// that case.
|
|
||||||
let separatorAdded = windows.length == 0 || windows[0].get_workspace() != activeWorkspace;
|
|
||||||
|
|
||||||
this._labels = new Array();
|
this._labels = new Array();
|
||||||
this._thumbnailBins = new Array();
|
this._thumbnailBins = new Array();
|
||||||
this._clones = new Array();
|
this._clones = new Array();
|
||||||
this._windows = windows;
|
this._windows = windows;
|
||||||
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
if (!separatorAdded && windows[i].get_workspace() != activeWorkspace) {
|
|
||||||
this.addSeparator();
|
|
||||||
separatorAdded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let box = new St.BoxLayout({ style_class: 'thumbnail-box',
|
let box = new St.BoxLayout({ style_class: 'thumbnail-box',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ const Util = imports.misc.util;
|
|||||||
|
|
||||||
const MAX_APPLICATION_WORK_MILLIS = 75;
|
const MAX_APPLICATION_WORK_MILLIS = 75;
|
||||||
const MENU_POPUP_TIMEOUT = 600;
|
const MENU_POPUP_TIMEOUT = 600;
|
||||||
const SCROLL_TIME = 0.1;
|
|
||||||
const MAX_COLUMNS = 6;
|
const MAX_COLUMNS = 6;
|
||||||
|
|
||||||
const INACTIVE_GRID_OPACITY = 77;
|
const INACTIVE_GRID_OPACITY = 77;
|
||||||
@@ -157,6 +156,30 @@ const FolderView = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const AllViewLayout = new Lang.Class({
|
||||||
|
Name: 'AllViewLayout',
|
||||||
|
Extends: Clutter.BinLayout,
|
||||||
|
|
||||||
|
vfunc_get_preferred_height: function(container, forWidth) {
|
||||||
|
let minBottom = 0;
|
||||||
|
let naturalBottom = 0;
|
||||||
|
|
||||||
|
for (let child = container.get_first_child();
|
||||||
|
child;
|
||||||
|
child = child.get_next_sibling()) {
|
||||||
|
let childY = child.y;
|
||||||
|
let [childMin, childNatural] = child.get_preferred_height(forWidth);
|
||||||
|
|
||||||
|
if (childMin + childY > minBottom)
|
||||||
|
minBottom = childMin + childY;
|
||||||
|
|
||||||
|
if (childNatural + childY > naturalBottom)
|
||||||
|
naturalBottom = childNatural + childY;
|
||||||
|
}
|
||||||
|
return [minBottom, naturalBottom];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const AllView = new Lang.Class({
|
const AllView = new Lang.Class({
|
||||||
Name: 'AllView',
|
Name: 'AllView',
|
||||||
Extends: AlphabeticalView,
|
Extends: AlphabeticalView,
|
||||||
@@ -165,7 +188,7 @@ const AllView = new Lang.Class({
|
|||||||
this.parent();
|
this.parent();
|
||||||
|
|
||||||
let box = new St.BoxLayout({ vertical: true });
|
let box = new St.BoxLayout({ vertical: true });
|
||||||
this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
this._stack = new St.Widget({ layout_manager: new AllViewLayout() });
|
||||||
this._stack.add_actor(this._grid.actor);
|
this._stack.add_actor(this._grid.actor);
|
||||||
this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true });
|
this._eventBlocker = new St.Widget({ x_expand: true, y_expand: true });
|
||||||
this._stack.add_actor(this._eventBlocker);
|
this._stack.add_actor(this._eventBlocker);
|
||||||
@@ -175,7 +198,9 @@ const AllView = new Lang.Class({
|
|||||||
y_fill: false,
|
y_fill: false,
|
||||||
y_align: St.Align.START,
|
y_align: St.Align.START,
|
||||||
x_expand: true,
|
x_expand: true,
|
||||||
style_class: 'vfade' });
|
y_expand: true,
|
||||||
|
overlay_scrollbars: true,
|
||||||
|
style_class: 'all-apps vfade' });
|
||||||
this.actor.add_actor(box);
|
this.actor.add_actor(box);
|
||||||
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||||
let action = new Clutter.PanAction({ interpolate: true });
|
let action = new Clutter.PanAction({ interpolate: true });
|
||||||
@@ -257,29 +282,7 @@ const AllView = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_ensureIconVisible: function(icon) {
|
_ensureIconVisible: function(icon) {
|
||||||
let adjustment = this.actor.vscroll.adjustment;
|
Util.ensureActorVisibleInScrollView(this.actor, icon);
|
||||||
let [value, lower, upper, stepIncrement, pageIncrement, pageSize] = adjustment.get_values();
|
|
||||||
|
|
||||||
let offset = 0;
|
|
||||||
let vfade = this.actor.get_effect("fade");
|
|
||||||
if (vfade)
|
|
||||||
offset = vfade.vfade_offset;
|
|
||||||
|
|
||||||
// If this gets called as part of a right-click, the actor
|
|
||||||
// will be needs_allocation, and so "icon.y" would return 0
|
|
||||||
let box = icon.get_allocation_box();
|
|
||||||
|
|
||||||
if (box.y1 < value + offset)
|
|
||||||
value = Math.max(0, box.y1 - offset);
|
|
||||||
else if (box.y2 > value + pageSize - offset)
|
|
||||||
value = Math.min(upper, box.y2 + offset - pageSize);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
Tweener.addTween(adjustment,
|
|
||||||
{ value: value,
|
|
||||||
time: SCROLL_TIME,
|
|
||||||
transition: 'easeOutQuad' });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateIconOpacities: function(folderOpen) {
|
_updateIconOpacities: function(folderOpen) {
|
||||||
@@ -297,22 +300,11 @@ const FrequentView = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._grid = new IconGrid.IconGrid({ xAlign: St.Align.MIDDLE,
|
this._grid = new IconGrid.IconGrid({ xAlign: St.Align.MIDDLE,
|
||||||
|
fillParent: true,
|
||||||
columnLimit: MAX_COLUMNS });
|
columnLimit: MAX_COLUMNS });
|
||||||
let box = new St.BoxLayout({ vertical: true });
|
this.actor = new St.Widget({ style_class: 'frequent-apps',
|
||||||
box.add(this._grid.actor);
|
x_expand: true, y_expand: true });
|
||||||
|
this.actor.add_actor(this._grid.actor);
|
||||||
// HACK: IconGrid currently lacks API to only display items that match
|
|
||||||
// the allocation, so rather than clipping away eventual overflow, we
|
|
||||||
// use an unscrollable ScrollView with hidden scrollbars to nicely
|
|
||||||
// fade out cut off items
|
|
||||||
this.actor = new St.ScrollView({ x_fill: true,
|
|
||||||
y_fill: false,
|
|
||||||
y_align: St.Align.START,
|
|
||||||
x_expand: true,
|
|
||||||
reactive: false,
|
|
||||||
style_class: 'frequent-apps vfade' });
|
|
||||||
this.actor.add_actor(box);
|
|
||||||
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
|
||||||
|
|
||||||
this._usage = Shell.AppUsage.get_default();
|
this._usage = Shell.AppUsage.get_default();
|
||||||
},
|
},
|
||||||
@@ -373,10 +365,7 @@ const AppDisplay = new Lang.Class({
|
|||||||
|
|
||||||
this._viewStack = new St.Widget({ layout_manager: new Clutter.BinLayout(),
|
this._viewStack = new St.Widget({ layout_manager: new Clutter.BinLayout(),
|
||||||
x_expand: true, y_expand: true });
|
x_expand: true, y_expand: true });
|
||||||
let bin = new St.Bin({ child: this._viewStack,
|
this.actor.add(this._viewStack, { expand: true });
|
||||||
clip_to_allocation: true,
|
|
||||||
x_fill: true, y_fill: true });
|
|
||||||
this.actor.add(bin, { expand: true });
|
|
||||||
|
|
||||||
let layout = new Clutter.BoxLayout({ homogeneous: true });
|
let layout = new Clutter.BoxLayout({ homogeneous: true });
|
||||||
this._controls = new St.Widget({ style_class: 'app-view-controls',
|
this._controls = new St.Widget({ style_class: 'app-view-controls',
|
||||||
@@ -579,10 +568,6 @@ const FolderIcon = new Lang.Class({
|
|||||||
|
|
||||||
this._popup = new AppFolderPopup(this, side);
|
this._popup = new AppFolderPopup(this, side);
|
||||||
this._parentView.addFolderPopup(this._popup);
|
this._parentView.addFolderPopup(this._popup);
|
||||||
let constraint = new Clutter.AlignConstraint({ source: this._parentView.actor,
|
|
||||||
align_axis: Clutter.AlignAxis.X_AXIS,
|
|
||||||
factor: 0.5 });
|
|
||||||
this._popup.actor.add_constraint(constraint);
|
|
||||||
|
|
||||||
// Position the popup above or below the source icon
|
// Position the popup above or below the source icon
|
||||||
if (side == St.Side.BOTTOM) {
|
if (side == St.Side.BOTTOM) {
|
||||||
@@ -612,7 +597,17 @@ const AppFolderPopup = new Lang.Class({
|
|||||||
this._isOpen = false;
|
this._isOpen = false;
|
||||||
|
|
||||||
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
|
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
|
||||||
visible: false });
|
visible: false,
|
||||||
|
// We don't want to expand really, but look
|
||||||
|
// at the layout manager of our parent...
|
||||||
|
//
|
||||||
|
// DOUBLE HACK: if you set one, you automatically
|
||||||
|
// get the effect for the other direction too, so
|
||||||
|
// we need to set the y_align
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.CENTER,
|
||||||
|
y_align: Clutter.ActorAlign.START });
|
||||||
this._boxPointer = new BoxPointer.BoxPointer(this._arrowSide,
|
this._boxPointer = new BoxPointer.BoxPointer(this._arrowSide,
|
||||||
{ style_class: 'app-folder-popup-bin',
|
{ style_class: 'app-folder-popup-bin',
|
||||||
x_fill: true,
|
x_fill: true,
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ const Params = imports.misc.params;
|
|||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const BACKGROUND_SCHEMA = 'org.gnome.desktop.background';
|
const BACKGROUND_SCHEMA = 'org.gnome.desktop.background';
|
||||||
const DRAW_BACKGROUND_KEY = 'draw-background';
|
|
||||||
const PRIMARY_COLOR_KEY = 'primary-color';
|
const PRIMARY_COLOR_KEY = 'primary-color';
|
||||||
const SECONDARY_COLOR_KEY = 'secondary-color';
|
const SECONDARY_COLOR_KEY = 'secondary-color';
|
||||||
const COLOR_SHADING_TYPE_KEY = 'color-shading-type';
|
const COLOR_SHADING_TYPE_KEY = 'color-shading-type';
|
||||||
@@ -39,6 +38,7 @@ const BackgroundCache = new Lang.Class({
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
this._patterns = [];
|
this._patterns = [];
|
||||||
this._images = [];
|
this._images = [];
|
||||||
|
this._pendingFileLoads = [];
|
||||||
this._fileMonitors = {};
|
this._fileMonitors = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -85,10 +85,10 @@ const BackgroundCache = new Lang.Class({
|
|||||||
} else {
|
} else {
|
||||||
content.load_gradient(params.shadingType, params.color, params.secondColor);
|
content.load_gradient(params.shadingType, params.color, params.secondColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._patterns.push(content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._patterns.push(content);
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -129,6 +129,73 @@ const BackgroundCache = new Lang.Class({
|
|||||||
this._removeContent(this._images, content);
|
this._removeContent(this._images, content);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_loadImageContent: function(params) {
|
||||||
|
params = Params.parse(params, { monitorIndex: 0,
|
||||||
|
style: null,
|
||||||
|
filename: null,
|
||||||
|
effects: Meta.BackgroundEffects.NONE,
|
||||||
|
cancellable: null,
|
||||||
|
onFinished: null });
|
||||||
|
|
||||||
|
for (let i = 0; i < this._pendingFileLoads.length; i++) {
|
||||||
|
if (this._pendingFileLoads[i].filename == params.filename &&
|
||||||
|
this._pendingFileLoads[i].style == params.style) {
|
||||||
|
this._pendingFileLoads[i].callers.push({ shouldCopy: true,
|
||||||
|
monitorIndex: params.monitorIndex,
|
||||||
|
effects: params.effects,
|
||||||
|
onFinished: params.onFinished });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._pendingFileLoads.push({ filename: params.filename,
|
||||||
|
style: params.style,
|
||||||
|
callers: [{ shouldCopy: false,
|
||||||
|
monitorIndex: params.monitorIndex,
|
||||||
|
effects: params.effects,
|
||||||
|
onFinished: params.onFinished }] });
|
||||||
|
|
||||||
|
let content = new Meta.Background({ meta_screen: global.screen,
|
||||||
|
monitor: params.monitorIndex,
|
||||||
|
effects: params.effects });
|
||||||
|
|
||||||
|
content.load_file_async(params.filename,
|
||||||
|
params.style,
|
||||||
|
params.cancellable,
|
||||||
|
Lang.bind(this,
|
||||||
|
function(object, result) {
|
||||||
|
try {
|
||||||
|
content.load_file_finish(result);
|
||||||
|
|
||||||
|
this._monitorFile(params.filename);
|
||||||
|
this._images.push(content);
|
||||||
|
} catch(e) {
|
||||||
|
content = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this._pendingFileLoads.length; i++) {
|
||||||
|
let pendingLoad = this._pendingFileLoads[i];
|
||||||
|
if (pendingLoad.filename != params.filename ||
|
||||||
|
pendingLoad.style != params.style)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (let j = 0; j < pendingLoad.callers.length; j++) {
|
||||||
|
if (pendingLoad.callers[j].onFinished) {
|
||||||
|
if (content && pendingLoad.callers[j].shouldCopy) {
|
||||||
|
content = object.copy(pendingLoad.callers[j].monitorIndex,
|
||||||
|
pendingLoad.callers[j].effects);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingLoad.callers[j].onFinished(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._pendingFileLoads.splice(i, 1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
getImageContent: function(params) {
|
getImageContent: function(params) {
|
||||||
params = Params.parse(params, { monitorIndex: 0,
|
params = Params.parse(params, { monitorIndex: 0,
|
||||||
style: null,
|
style: null,
|
||||||
@@ -166,31 +233,19 @@ const BackgroundCache = new Lang.Class({
|
|||||||
|
|
||||||
if (params.cancellable && params.cancellable.is_cancelled())
|
if (params.cancellable && params.cancellable.is_cancelled())
|
||||||
content = null;
|
content = null;
|
||||||
|
else
|
||||||
|
this._images.push(content);
|
||||||
|
|
||||||
if (params.onFinished)
|
if (params.onFinished)
|
||||||
params.onFinished(content);
|
params.onFinished(content);
|
||||||
} else {
|
} else {
|
||||||
content = new Meta.Background({ meta_screen: global.screen,
|
this._loadImageContent({ filename: params.filename,
|
||||||
monitor: params.monitorIndex,
|
style: params.style,
|
||||||
effects: params.effects });
|
effects: params.effects,
|
||||||
|
monitorIndex: params.monitorIndex,
|
||||||
|
cancellable: params.cancellable,
|
||||||
|
onFinished: params.onFinished });
|
||||||
|
|
||||||
content.load_file_async(params.filename,
|
|
||||||
params.style,
|
|
||||||
params.cancellable,
|
|
||||||
Lang.bind(this,
|
|
||||||
function(object, result) {
|
|
||||||
try {
|
|
||||||
content.load_file_finish(result);
|
|
||||||
|
|
||||||
this._monitorFile(params.filename);
|
|
||||||
this._images.push(content);
|
|
||||||
} catch(e) {
|
|
||||||
content = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.onFinished)
|
|
||||||
params.onFinished(content);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -268,9 +323,9 @@ const Background = new Lang.Class({
|
|||||||
_destroy: function() {
|
_destroy: function() {
|
||||||
this._cancellable.cancel();
|
this._cancellable.cancel();
|
||||||
|
|
||||||
if (this._animationUpdateTimeoutId) {
|
if (this._updateAnimationTimeoutId) {
|
||||||
GLib.source_remove (this._animationUpdateTimeoutId);
|
GLib.source_remove (this._updateAnimationTimeoutId);
|
||||||
this._animationUpdateTimeoutId = 0
|
this._updateAnimationTimeoutId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let i;
|
let i;
|
||||||
@@ -357,7 +412,10 @@ const Background = new Lang.Class({
|
|||||||
|
|
||||||
let actor = new Meta.BackgroundActor();
|
let actor = new Meta.BackgroundActor();
|
||||||
actor.content = content;
|
actor.content = content;
|
||||||
this.actor.add_child(actor);
|
|
||||||
|
// The background pattern is the first actor in
|
||||||
|
// the group, and all images should be above that.
|
||||||
|
this.actor.insert_child_at_index(actor, index + 1);
|
||||||
|
|
||||||
this._images[index] = actor;
|
this._images[index] = actor;
|
||||||
this._watchCacheFile(filename);
|
this._watchCacheFile(filename);
|
||||||
@@ -368,27 +426,27 @@ const Background = new Lang.Class({
|
|||||||
content.brightness = this._brightness;
|
content.brightness = this._brightness;
|
||||||
content.vignette_sharpness = this._vignetteSharpness;
|
content.vignette_sharpness = this._vignetteSharpness;
|
||||||
|
|
||||||
|
this._cache.removeImageContent(content);
|
||||||
this._images[index].content = content;
|
this._images[index].content = content;
|
||||||
this._watchCacheFile(filename);
|
this._watchCacheFile(filename);
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateAnimationProgress: function() {
|
_updateAnimationProgress: function() {
|
||||||
if (this._images[1]) {
|
if (this._images[1])
|
||||||
this._images[1].raise_top();
|
|
||||||
this._images[1].opacity = this._animation.transitionProgress * 255;
|
this._images[1].opacity = this._animation.transitionProgress * 255;
|
||||||
}
|
|
||||||
|
|
||||||
this._queueAnimationUpdate();
|
this._queueUpdateAnimation();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateAnimation: function() {
|
_updateAnimation: function() {
|
||||||
this._animationUpdateTimeoutId = 0;
|
this._updateAnimationTimeoutId = 0;
|
||||||
|
|
||||||
let files = this._animation.getKeyFrameFiles(this._layoutManager.monitors[this._monitorIndex]);
|
this._animation.update(this._layoutManager.monitors[this._monitorIndex]);
|
||||||
|
let files = this._animation.keyFrameFiles;
|
||||||
|
|
||||||
if (!files) {
|
if (files.length == 0) {
|
||||||
this._setLoaded();
|
this._setLoaded();
|
||||||
this._queueAnimationUpdate();
|
this._queueUpdateAnimation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,7 +465,7 @@ const Background = new Lang.Class({
|
|||||||
style: this._style,
|
style: this._style,
|
||||||
filename: files[i],
|
filename: files[i],
|
||||||
cancellable: this._cancellable,
|
cancellable: this._cancellable,
|
||||||
onFinished: Lang.bind(this, function(content) {
|
onFinished: Lang.bind(this, function(content, i) {
|
||||||
numPendingImages--;
|
numPendingImages--;
|
||||||
|
|
||||||
if (!content) {
|
if (!content) {
|
||||||
@@ -427,27 +485,34 @@ const Background = new Lang.Class({
|
|||||||
this._setLoaded();
|
this._setLoaded();
|
||||||
this._updateAnimationProgress();
|
this._updateAnimationProgress();
|
||||||
}
|
}
|
||||||
})
|
}, i)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_queueAnimationUpdate: function() {
|
_queueUpdateAnimation: function() {
|
||||||
if (this._animationUpdateTimeoutId != 0)
|
if (this._updateAnimationTimeoutId != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!this._cancellable || this._cancellable.is_cancelled())
|
if (!this._cancellable || this._cancellable.is_cancelled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!this._animation.duration)
|
if (!this._animation.transitionDuration)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
let nSteps = 255 / ANIMATION_OPACITY_STEP_INCREMENT;
|
||||||
|
let timePerStep = (this._animation.transitionDuration * 1000) / nSteps;
|
||||||
|
|
||||||
let interval = Math.max(ANIMATION_MIN_WAKEUP_INTERVAL * 1000,
|
let interval = Math.max(ANIMATION_MIN_WAKEUP_INTERVAL * 1000,
|
||||||
ANIMATION_OPACITY_STEP_INCREMENT / this._animation.duration);
|
timePerStep);
|
||||||
this._animationUpdateTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
|
||||||
|
if (interval > GLib.MAXUINT32)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._updateAnimationTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
||||||
interval,
|
interval,
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this._animationUpdateTimeoutId = 0;
|
this._updateAnimationTimeoutId = 0;
|
||||||
this._updateAnimation();
|
this._updateAnimation();
|
||||||
return false;
|
return false;
|
||||||
}));
|
}));
|
||||||
@@ -490,11 +555,6 @@ const Background = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_load: function () {
|
_load: function () {
|
||||||
if (!this._settings.get_boolean(DRAW_BACKGROUND_KEY)) {
|
|
||||||
this._setLoaded();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._cache = getBackgroundCache();
|
this._cache = getBackgroundCache();
|
||||||
|
|
||||||
this._loadPattern(this._cache);
|
this._loadPattern(this._cache);
|
||||||
@@ -565,22 +625,24 @@ const Background = new Lang.Class({
|
|||||||
});
|
});
|
||||||
Signals.addSignalMethods(Background.prototype);
|
Signals.addSignalMethods(Background.prototype);
|
||||||
|
|
||||||
const StillFrame = new Lang.Class({
|
const SystemBackground = new Lang.Class({
|
||||||
Name: 'StillFrame',
|
Name: 'SystemBackground',
|
||||||
|
|
||||||
_init: function(monitorIndex) {
|
_init: function() {
|
||||||
|
this._cache = getBackgroundCache();
|
||||||
this.actor = new Meta.BackgroundActor();
|
this.actor = new Meta.BackgroundActor();
|
||||||
this.actor._delegate = this;
|
|
||||||
|
|
||||||
let content = new Meta.Background({ meta_screen: global.screen,
|
this._cache.getImageContent({ style: GDesktopEnums.BackgroundStyle.WALLPAPER,
|
||||||
monitor: monitorIndex,
|
filename: global.datadir + '/theme/noise-texture.png',
|
||||||
effects: Meta.BackgroundEffects.NONE });
|
effects: Meta.BackgroundEffects.NONE,
|
||||||
content.load_still_frame();
|
onFinished: Lang.bind(this, function(content) {
|
||||||
|
this.actor.content = content;
|
||||||
this.actor.content = content;
|
this.emit('loaded');
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(StillFrame.prototype);
|
Signals.addSignalMethods(SystemBackground.prototype);
|
||||||
|
|
||||||
const Animation = new Lang.Class({
|
const Animation = new Lang.Class({
|
||||||
Name: 'Animation',
|
Name: 'Animation',
|
||||||
@@ -589,9 +651,9 @@ const Animation = new Lang.Class({
|
|||||||
params = Params.parse(params, { filename: null });
|
params = Params.parse(params, { filename: null });
|
||||||
|
|
||||||
this.filename = params.filename;
|
this.filename = params.filename;
|
||||||
this._keyFrames = [];
|
this.keyFrameFiles = [];
|
||||||
this.duration = 0.0;
|
|
||||||
this.transitionProgress = 0.0;
|
this.transitionProgress = 0.0;
|
||||||
|
this.transitionDuration = 0.0;
|
||||||
this.loaded = false;
|
this.loaded = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -603,33 +665,31 @@ const Animation = new Lang.Class({
|
|||||||
this._show.load_async(null,
|
this._show.load_async(null,
|
||||||
Lang.bind(this,
|
Lang.bind(this,
|
||||||
function(object, result) {
|
function(object, result) {
|
||||||
this.duration = this._show.get_total_duration();
|
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
if (callback)
|
if (callback)
|
||||||
callback();
|
callback();
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
getKeyFrameFiles: function(monitor) {
|
update: function(monitor) {
|
||||||
|
this.keyFrameFiles = [];
|
||||||
|
|
||||||
if (!this._show)
|
if (!this._show)
|
||||||
return null;
|
return;
|
||||||
|
|
||||||
if (this._show.get_num_slides() < 1)
|
if (this._show.get_num_slides() < 1)
|
||||||
return null;
|
return;
|
||||||
|
|
||||||
let [progress, duration, isFixed, file1, file2] = this._show.get_current_slide(monitor.width, monitor.height);
|
let [progress, duration, isFixed, file1, file2] = this._show.get_current_slide(monitor.width, monitor.height);
|
||||||
|
|
||||||
|
this.transitionDuration = duration;
|
||||||
this.transitionProgress = progress;
|
this.transitionProgress = progress;
|
||||||
|
|
||||||
let files = [];
|
|
||||||
|
|
||||||
if (file1)
|
if (file1)
|
||||||
files.push(file1);
|
this.keyFrameFiles.push(file1);
|
||||||
|
|
||||||
if (file2)
|
if (file2)
|
||||||
files.push(file2);
|
this.keyFrameFiles.push(file2);
|
||||||
|
|
||||||
return files;
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(Animation.prototype);
|
Signals.addSignalMethods(Animation.prototype);
|
||||||
@@ -641,26 +701,20 @@ const BackgroundManager = new Lang.Class({
|
|||||||
params = Params.parse(params, { container: null,
|
params = Params.parse(params, { container: null,
|
||||||
layoutManager: Main.layoutManager,
|
layoutManager: Main.layoutManager,
|
||||||
monitorIndex: null,
|
monitorIndex: null,
|
||||||
effects: Meta.BackgroundEffects.NONE });
|
effects: Meta.BackgroundEffects.NONE,
|
||||||
|
controlPosition: true });
|
||||||
|
|
||||||
this._container = params.container;
|
this._container = params.container;
|
||||||
this._layoutManager = params.layoutManager;
|
this._layoutManager = params.layoutManager;
|
||||||
this._effects = params.effects;
|
this._effects = params.effects;
|
||||||
this._monitorIndex = params.monitorIndex;
|
this._monitorIndex = params.monitorIndex;
|
||||||
|
this._controlPosition = params.controlPosition;
|
||||||
|
|
||||||
this.background = this._createBackground();
|
this.background = this._createBackground();
|
||||||
this._newBackground = null;
|
this._newBackground = null;
|
||||||
this._loadedSignalId = 0;
|
|
||||||
this._changedSignalId = 0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
if (this._loadedSignalId)
|
|
||||||
this._newBackground.disconnect(this._loadedSignalId);
|
|
||||||
|
|
||||||
if (this._changedSignalId)
|
|
||||||
this.background.disconnect(this._changedSignalId);
|
|
||||||
|
|
||||||
if (this._newBackground) {
|
if (this._newBackground) {
|
||||||
this._newBackground.actor.destroy();
|
this._newBackground.actor.destroy();
|
||||||
this._newBackground = null;
|
this._newBackground = null;
|
||||||
@@ -679,22 +733,24 @@ const BackgroundManager = new Lang.Class({
|
|||||||
newBackground.saturation = background.saturation;
|
newBackground.saturation = background.saturation;
|
||||||
newBackground.visible = background.visible;
|
newBackground.visible = background.visible;
|
||||||
|
|
||||||
let signalId = newBackground.connect('loaded',
|
newBackground.loadedSignalId = newBackground.connect('loaded',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
newBackground.disconnect(signalId);
|
newBackground.disconnect(newBackground.loadedSignalId);
|
||||||
|
newBackground.loadedSignalId = 0;
|
||||||
Tweener.addTween(background.actor,
|
Tweener.addTween(background.actor,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
time: FADE_ANIMATION_TIME,
|
time: FADE_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: Lang.bind(this, function() {
|
onComplete: Lang.bind(this, function() {
|
||||||
this.background = newBackground;
|
if (this.background == background) {
|
||||||
this._newBackground = null;
|
this.background = newBackground;
|
||||||
background.actor.destroy();
|
this._newBackground = null;
|
||||||
|
background.actor.destroy();
|
||||||
|
}
|
||||||
this.emit('changed');
|
this.emit('changed');
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
this._loadedSignalId = signalId;
|
|
||||||
|
|
||||||
this._newBackground = newBackground;
|
this._newBackground = newBackground;
|
||||||
},
|
},
|
||||||
@@ -706,16 +762,26 @@ const BackgroundManager = new Lang.Class({
|
|||||||
this._container.add_child(background.actor);
|
this._container.add_child(background.actor);
|
||||||
|
|
||||||
let monitor = this._layoutManager.monitors[this._monitorIndex];
|
let monitor = this._layoutManager.monitors[this._monitorIndex];
|
||||||
background.actor.set_position(monitor.x, monitor.y);
|
|
||||||
background.actor.set_size(monitor.width, monitor.height);
|
|
||||||
background.actor.lower_bottom();
|
|
||||||
|
|
||||||
let signalId = background.connect('changed', Lang.bind(this, function() {
|
background.actor.set_size(monitor.width, monitor.height);
|
||||||
background.disconnect(signalId);
|
if (this._controlPosition) {
|
||||||
|
background.actor.set_position(monitor.x, monitor.y);
|
||||||
|
background.actor.lower_bottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
background.changeSignalId = background.connect('changed', Lang.bind(this, function() {
|
||||||
|
background.disconnect(background.changeSignalId);
|
||||||
|
background.changeSignalId = 0;
|
||||||
this._updateBackground(background, this._monitorIndex);
|
this._updateBackground(background, this._monitorIndex);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._changedSignalId = signalId;
|
background.actor.connect('destroy', Lang.bind(this, function() {
|
||||||
|
if (background.changeSignalId)
|
||||||
|
background.disconnect(background.changeSignalId);
|
||||||
|
|
||||||
|
if (background.loadedSignalId)
|
||||||
|
background.disconnect(background.loadedSignalId);
|
||||||
|
}));
|
||||||
|
|
||||||
return background;
|
return background;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -55,4 +55,10 @@ function addBackgroundMenu(actor) {
|
|||||||
openMenu();
|
openMenu();
|
||||||
});
|
});
|
||||||
actor.add_action(clickAction);
|
actor.add_action(clickAction);
|
||||||
|
|
||||||
|
actor.connect('destroy', function() {
|
||||||
|
actor._backgroundMenu.destroy();
|
||||||
|
actor._backgroundMenu = null;
|
||||||
|
actor._backgroundManager = null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ function _formatEventTime(event, clockFormat) {
|
|||||||
default:
|
default:
|
||||||
/* explicit fall-through */
|
/* explicit fall-through */
|
||||||
case '12h':
|
case '12h':
|
||||||
/* Transators: Shown in calendar event list, if 12h format,
|
/* Translators: Shown in calendar event list, if 12h format,
|
||||||
\u2236 is a ratio character, similar to : and \u2009 is
|
\u2236 is a ratio character, similar to : and \u2009 is
|
||||||
a thin space */
|
a thin space */
|
||||||
ret = event.date.toLocaleFormat(C_("event list time", "%l\u2236%M\u2009%p"));
|
ret = event.date.toLocaleFormat(C_("event list time", "%l\u2236%M\u2009%p"));
|
||||||
@@ -168,6 +168,12 @@ const EmptyEventSource = new Lang.Class({
|
|||||||
Name: 'EmptyEventSource',
|
Name: 'EmptyEventSource',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
|
this.isLoading = false;
|
||||||
|
this.isDummy = true;
|
||||||
|
this.hasCalendars = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
},
|
},
|
||||||
|
|
||||||
requestRange: function(begin, end) {
|
requestRange: function(begin, end) {
|
||||||
@@ -191,6 +197,7 @@ const CalendarServerIface = <interface name="org.gnome.Shell.CalendarServer">
|
|||||||
<arg type="b" direction="in" />
|
<arg type="b" direction="in" />
|
||||||
<arg type="a(sssbxxa{sv})" direction="out" />
|
<arg type="a(sssbxxa{sv})" direction="out" />
|
||||||
</method>
|
</method>
|
||||||
|
<property name="HasCalendars" type="b" access="read" />
|
||||||
<signal name="Changed" />
|
<signal name="Changed" />
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
@@ -201,8 +208,7 @@ function CalendarServer() {
|
|||||||
g_interface_name: CalendarServerInfo.name,
|
g_interface_name: CalendarServerInfo.name,
|
||||||
g_interface_info: CalendarServerInfo,
|
g_interface_info: CalendarServerInfo,
|
||||||
g_name: 'org.gnome.Shell.CalendarServer',
|
g_name: 'org.gnome.Shell.CalendarServer',
|
||||||
g_object_path: '/org/gnome/Shell/CalendarServer',
|
g_object_path: '/org/gnome/Shell/CalendarServer' });
|
||||||
g_flags: Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _datesEqual(a, b) {
|
function _datesEqual(a, b) {
|
||||||
@@ -229,6 +235,8 @@ const DBusEventSource = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._resetCache();
|
this._resetCache();
|
||||||
|
this.isLoading = false;
|
||||||
|
this.isDummy = false;
|
||||||
|
|
||||||
this._initialized = false;
|
this._initialized = false;
|
||||||
this._dbusProxy = new CalendarServer();
|
this._dbusProxy = new CalendarServer();
|
||||||
@@ -249,11 +257,27 @@ const DBusEventSource = new Lang.Class({
|
|||||||
this._onNameVanished();
|
this._onNameVanished();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
this._dbusProxy.connect('g-properties-changed', Lang.bind(this, function() {
|
||||||
|
this.emit('notify::has-calendars');
|
||||||
|
}));
|
||||||
|
|
||||||
this._initialized = true;
|
this._initialized = true;
|
||||||
|
this.emit('notify::has-calendars');
|
||||||
this._onNameAppeared();
|
this._onNameAppeared();
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
this._dbusProxy.run_dispose();
|
||||||
|
},
|
||||||
|
|
||||||
|
get hasCalendars() {
|
||||||
|
if (this._initialized)
|
||||||
|
return this._dbusProxy.HasCalendars;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
_resetCache: function() {
|
_resetCache: function() {
|
||||||
this._events = [];
|
this._events = [];
|
||||||
this._lastRequestBegin = null;
|
this._lastRequestBegin = null;
|
||||||
@@ -293,6 +317,7 @@ const DBusEventSource = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._events = newEvents;
|
this._events = newEvents;
|
||||||
|
this.isLoading = false;
|
||||||
this.emit('changed');
|
this.emit('changed');
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -315,6 +340,7 @@ const DBusEventSource = new Lang.Class({
|
|||||||
|
|
||||||
requestRange: function(begin, end, forceReload) {
|
requestRange: function(begin, end, forceReload) {
|
||||||
if (forceReload || !(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
|
if (forceReload || !(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
|
||||||
|
this.isLoading = true;
|
||||||
this._lastRequestBegin = begin;
|
this._lastRequestBegin = begin;
|
||||||
this._lastRequestEnd = end;
|
this._lastRequestEnd = end;
|
||||||
this._curRequestBegin = begin;
|
this._curRequestBegin = begin;
|
||||||
@@ -389,19 +415,11 @@ const Calendar = new Lang.Class({
|
|||||||
// @eventSource: is an object implementing the EventSource API, e.g. the
|
// @eventSource: is an object implementing the EventSource API, e.g. the
|
||||||
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
|
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
|
||||||
setEventSource: function(eventSource) {
|
setEventSource: function(eventSource) {
|
||||||
if (this._eventSource) {
|
|
||||||
this._eventSource.disconnect(this._eventSourceChangedId);
|
|
||||||
this._eventSource = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._eventSource = eventSource;
|
this._eventSource = eventSource;
|
||||||
|
this._eventSource.connect('changed', Lang.bind(this, function() {
|
||||||
if (this._eventSource) {
|
this._update(false);
|
||||||
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, function() {
|
}));
|
||||||
this._update(false);
|
this._update(true);
|
||||||
}));
|
|
||||||
this._update(true);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Sets the calendar to show a specific date
|
// Sets the calendar to show a specific date
|
||||||
@@ -538,20 +556,44 @@ const Calendar = new Lang.Class({
|
|||||||
children[i].destroy();
|
children[i].destroy();
|
||||||
|
|
||||||
// Start at the beginning of the week before the start of the month
|
// Start at the beginning of the week before the start of the month
|
||||||
|
//
|
||||||
|
// We want to show always 6 weeks (to keep the calendar menu at the same
|
||||||
|
// height if there are no events), so we pad it according to the following
|
||||||
|
// policy:
|
||||||
|
//
|
||||||
|
// 1 - If a month has 6 weeks, we place no padding (example: Dec 2012)
|
||||||
|
// 2 - If a month has 5 weeks and it starts on week start, we pad one week
|
||||||
|
// before it (example: Apr 2012)
|
||||||
|
// 3 - If a month has 5 weeks and it starts on any other day, we pad one week
|
||||||
|
// after it (example: Nov 2012)
|
||||||
|
// 4 - If a month has 4 weeks, we pad one week before and one after it
|
||||||
|
// (example: Feb 2010)
|
||||||
|
//
|
||||||
|
// Actually computing the number of weeks is complex, but we know that the
|
||||||
|
// problematic categories (2 and 4) always start on week start, and that
|
||||||
|
// all months at the end have 6 weeks.
|
||||||
|
|
||||||
let beginDate = new Date(this._selectedDate);
|
let beginDate = new Date(this._selectedDate);
|
||||||
beginDate.setDate(1);
|
beginDate.setDate(1);
|
||||||
beginDate.setSeconds(0);
|
beginDate.setSeconds(0);
|
||||||
beginDate.setHours(12);
|
beginDate.setHours(12);
|
||||||
|
let year = beginDate.getYear();
|
||||||
|
|
||||||
let daysToWeekStart = (7 + beginDate.getDay() - this._weekStart) % 7;
|
let daysToWeekStart = (7 + beginDate.getDay() - this._weekStart) % 7;
|
||||||
beginDate.setTime(beginDate.getTime() - daysToWeekStart * MSECS_IN_DAY);
|
let startsOnWeekStart = daysToWeekStart == 0;
|
||||||
|
let weekPadding = startsOnWeekStart ? 7 : 0;
|
||||||
|
|
||||||
|
beginDate.setTime(beginDate.getTime() - (weekPadding + daysToWeekStart) * MSECS_IN_DAY);
|
||||||
|
|
||||||
let iter = new Date(beginDate);
|
let iter = new Date(beginDate);
|
||||||
let row = 2;
|
let row = 2;
|
||||||
while (true) {
|
// nRows here means 6 weeks + one header + one navbar
|
||||||
|
let nRows = 8;
|
||||||
|
while (row < 8) {
|
||||||
let button = new St.Button({ label: iter.getDate().toString() });
|
let button = new St.Button({ label: iter.getDate().toString() });
|
||||||
let rtl = button.get_text_direction() == Clutter.TextDirection.RTL;
|
let rtl = button.get_text_direction() == Clutter.TextDirection.RTL;
|
||||||
|
|
||||||
if (!this._eventSource)
|
if (this._eventSource.isDummy)
|
||||||
button.reactive = false;
|
button.reactive = false;
|
||||||
|
|
||||||
let iterStr = iter.toUTCString();
|
let iterStr = iter.toUTCString();
|
||||||
@@ -560,8 +602,9 @@ const Calendar = new Lang.Class({
|
|||||||
this.setDate(newlySelectedDate, false);
|
this.setDate(newlySelectedDate, false);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let hasEvents = this._eventSource && this._eventSource.hasEvents(iter);
|
let hasEvents = this._eventSource.hasEvents(iter);
|
||||||
let styleClass = 'calendar-day-base calendar-day';
|
let styleClass = 'calendar-day-base calendar-day';
|
||||||
|
|
||||||
if (_isWorkDay(iter))
|
if (_isWorkDay(iter))
|
||||||
styleClass += ' calendar-work-day'
|
styleClass += ' calendar-work-day'
|
||||||
else
|
else
|
||||||
@@ -601,17 +644,13 @@ const Calendar = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
iter.setTime(iter.getTime() + MSECS_IN_DAY);
|
||||||
if (iter.getDay() == this._weekStart) {
|
|
||||||
// We stop on the first "first day of the week" after the month we are displaying
|
if (iter.getDay() == this._weekStart)
|
||||||
if (iter.getMonth() > this._selectedDate.getMonth() || iter.getYear() > this._selectedDate.getYear())
|
|
||||||
break;
|
|
||||||
row++;
|
row++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Signal to the event source that we are interested in events
|
// Signal to the event source that we are interested in events
|
||||||
// only from this date range
|
// only from this date range
|
||||||
if (this._eventSource)
|
this._eventSource.requestRange(beginDate, iter, forceReload);
|
||||||
this._eventSource.requestRange(beginDate, iter, forceReload);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -629,16 +668,8 @@ const EventsList = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setEventSource: function(eventSource) {
|
setEventSource: function(eventSource) {
|
||||||
if (this._eventSource) {
|
|
||||||
this._eventSource.disconnect(this._eventSourceChangedId);
|
|
||||||
this._eventSource = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._eventSource = eventSource;
|
this._eventSource = eventSource;
|
||||||
|
this._eventSource.connect('changed', Lang.bind(this, this._update));
|
||||||
if (this._eventSource) {
|
|
||||||
this._eventSourceChangedId = this._eventSource.connect('changed', Lang.bind(this, this._update));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_addEvent: function(dayNameBox, timeBox, eventTitleBox, includeDayName, day, time, desc) {
|
_addEvent: function(dayNameBox, timeBox, eventTitleBox, includeDayName, day, time, desc) {
|
||||||
@@ -655,9 +686,6 @@ const EventsList = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_addPeriod: function(header, begin, end, includeDayName, showNothingScheduled) {
|
_addPeriod: function(header, begin, end, includeDayName, showNothingScheduled) {
|
||||||
if (!this._eventSource)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let events = this._eventSource.getEvents(begin, end);
|
let events = this._eventSource.getEvents(begin, end);
|
||||||
|
|
||||||
let clockFormat = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);;
|
let clockFormat = this._desktopSettings.get_string(CLOCK_FORMAT_KEY);;
|
||||||
@@ -754,6 +782,9 @@ const EventsList = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_update: function() {
|
_update: function() {
|
||||||
|
if (this._eventSource.isLoading)
|
||||||
|
return;
|
||||||
|
|
||||||
let today = new Date();
|
let today = new Date();
|
||||||
if (_sameDay (this._date, today)) {
|
if (_sameDay (this._date, today)) {
|
||||||
this._showToday();
|
this._showToday();
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ const AutorunResidentSource = new Lang.Class({
|
|||||||
|
|
||||||
_init: function(manager) {
|
_init: function(manager) {
|
||||||
this.parent(_("Removable Devices"), 'media-removable');
|
this.parent(_("Removable Devices"), 'media-removable');
|
||||||
|
this.resident = true;
|
||||||
|
|
||||||
this._mounts = [];
|
this._mounts = [];
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ const KeyringPrompter = new Lang.Class({
|
|||||||
enable: function() {
|
enable: function() {
|
||||||
this._prompter.register(Gio.DBus.session);
|
this._prompter.register(Gio.DBus.session);
|
||||||
this._dbusId = Gio.DBus.session.own_name('org.gnome.keyring.SystemPrompter',
|
this._dbusId = Gio.DBus.session.own_name('org.gnome.keyring.SystemPrompter',
|
||||||
Gio.BusNameOwnerFlags.REPLACE, null, null);
|
Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT, null, null);
|
||||||
},
|
},
|
||||||
|
|
||||||
disable: function() {
|
disable: function() {
|
||||||
|
|||||||
@@ -640,6 +640,10 @@ const ChatSource = new Lang.Class({
|
|||||||
return this._pendingMessages.length;
|
return this._pendingMessages.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get indicatorCount() {
|
||||||
|
return this.count;
|
||||||
|
},
|
||||||
|
|
||||||
get unseenCount() {
|
get unseenCount() {
|
||||||
return this.count;
|
return this.count;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -103,6 +103,11 @@ const CtrlAltTabManager = new Lang.Class({
|
|||||||
else
|
else
|
||||||
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
||||||
items.push({ name: windows[i].title,
|
items.push({ name: windows[i].title,
|
||||||
|
proxy: windows[i].get_compositor_private(),
|
||||||
|
focusCallback: Lang.bind(windows[i],
|
||||||
|
function(timestamp) {
|
||||||
|
Main.activateWindow(this, timestamp);
|
||||||
|
}),
|
||||||
iconActor: icon,
|
iconActor: icon,
|
||||||
sortGroup: SortGroup.MIDDLE });
|
sortGroup: SortGroup.MIDDLE });
|
||||||
}
|
}
|
||||||
|
|||||||
183
js/ui/dash.js
183
js/ui/dash.js
@@ -33,30 +33,26 @@ function getAppFromSource(source) {
|
|||||||
// when requesting a size
|
// when requesting a size
|
||||||
const DashItemContainer = new Lang.Class({
|
const DashItemContainer = new Lang.Class({
|
||||||
Name: 'DashItemContainer',
|
Name: 'DashItemContainer',
|
||||||
|
Extends: St.Widget,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.actor = new Shell.GenericContainer({ style_class: 'dash-item-container' });
|
this.parent({ style_class: 'dash-item-container' });
|
||||||
this.actor.connect('get-preferred-width',
|
|
||||||
Lang.bind(this, this._getPreferredWidth));
|
|
||||||
this.actor.connect('get-preferred-height',
|
|
||||||
Lang.bind(this, this._getPreferredHeight));
|
|
||||||
this.actor.connect('allocate',
|
|
||||||
Lang.bind(this, this._allocate));
|
|
||||||
this.actor._delegate = this;
|
|
||||||
|
|
||||||
this._labelText = "";
|
this._labelText = "";
|
||||||
this.label = new St.Label({ style_class: 'dash-label'});
|
this.label = new St.Label({ style_class: 'dash-label'});
|
||||||
this.label.hide();
|
this.label.hide();
|
||||||
Main.layoutManager.addChrome(this.label);
|
Main.layoutManager.addChrome(this.label);
|
||||||
this.actor.label_actor = this.label;
|
this.label_actor = this.label;
|
||||||
|
|
||||||
this.child = null;
|
this.child = null;
|
||||||
this._childScale = 1;
|
this._childScale = 0;
|
||||||
this._childOpacity = 255;
|
this._childOpacity = 0;
|
||||||
this.animatingOut = false;
|
this.animatingOut = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
vfunc_allocate: function(box, flags) {
|
||||||
|
this.set_allocation(box, flags);
|
||||||
|
|
||||||
if (this.child == null)
|
if (this.child == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -78,28 +74,28 @@ const DashItemContainer = new Lang.Class({
|
|||||||
this.child.allocate(childBox, flags);
|
this.child.allocate(childBox, flags);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
vfunc_get_preferred_height: function(forWidth) {
|
||||||
alloc.min_size = 0;
|
let themeNode = this.get_theme_node();
|
||||||
alloc.natural_size = 0;
|
|
||||||
|
|
||||||
if (this.child == null)
|
if (this.child == null)
|
||||||
return;
|
return [0, 0];
|
||||||
|
|
||||||
|
forWidth = themeNode.adjust_for_width(forWidth);
|
||||||
let [minHeight, natHeight] = this.child.get_preferred_height(forWidth);
|
let [minHeight, natHeight] = this.child.get_preferred_height(forWidth);
|
||||||
alloc.min_size += minHeight * this.child.scale_y;
|
return themeNode.adjust_preferred_height(minHeight * this.child.scale_y,
|
||||||
alloc.natural_size += natHeight * this.child.scale_y;
|
natHeight * this.child.scale_y);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
vfunc_get_preferred_width: function(forHeight) {
|
||||||
alloc.min_size = 0;
|
let themeNode = this.get_theme_node();
|
||||||
alloc.natural_size = 0;
|
|
||||||
|
|
||||||
if (this.child == null)
|
if (this.child == null)
|
||||||
return;
|
return [0, 0];
|
||||||
|
|
||||||
|
forHeight = themeNode.adjust_for_height(forHeight);
|
||||||
let [minWidth, natWidth] = this.child.get_preferred_width(forHeight);
|
let [minWidth, natWidth] = this.child.get_preferred_width(forHeight);
|
||||||
alloc.min_size = minWidth * this.child.scale_y;
|
return themeNode.adjust_preferred_width(minWidth * this.child.scale_y,
|
||||||
alloc.natural_size = natWidth * this.child.scale_y;
|
natWidth * this.child.scale_y);
|
||||||
},
|
},
|
||||||
|
|
||||||
showLabel: function() {
|
showLabel: function() {
|
||||||
@@ -110,9 +106,9 @@ const DashItemContainer = new Lang.Class({
|
|||||||
this.label.opacity = 0;
|
this.label.opacity = 0;
|
||||||
this.label.show();
|
this.label.show();
|
||||||
|
|
||||||
let [stageX, stageY] = this.actor.get_transformed_position();
|
let [stageX, stageY] = this.get_transformed_position();
|
||||||
|
|
||||||
let itemHeight = this.actor.allocation.y2 - this.actor.allocation.y1;
|
let itemHeight = this.allocation.y2 - this.allocation.y1;
|
||||||
|
|
||||||
let labelHeight = this.label.get_height();
|
let labelHeight = this.label.get_height();
|
||||||
let yOffset = Math.floor((itemHeight - labelHeight) / 2)
|
let yOffset = Math.floor((itemHeight - labelHeight) / 2)
|
||||||
@@ -126,7 +122,7 @@ const DashItemContainer = new Lang.Class({
|
|||||||
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
|
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
|
||||||
x = stageX - this.label.get_width() - xOffset;
|
x = stageX - this.label.get_width() - xOffset;
|
||||||
else
|
else
|
||||||
x = stageX + this.actor.get_width() + xOffset;
|
x = stageX + this.get_width() + xOffset;
|
||||||
|
|
||||||
this.label.set_position(x, y);
|
this.label.set_position(x, y);
|
||||||
Tweener.addTween(this.label,
|
Tweener.addTween(this.label,
|
||||||
@@ -156,22 +152,25 @@ const DashItemContainer = new Lang.Class({
|
|||||||
if (this.child == actor)
|
if (this.child == actor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.actor.destroy_all_children();
|
this.destroy_all_children();
|
||||||
|
|
||||||
this.child = actor;
|
this.child = actor;
|
||||||
this.actor.add_actor(this.child);
|
this.add_actor(this.child);
|
||||||
|
|
||||||
|
this.child.set_scale_with_gravity(this._childScale, this._childScale,
|
||||||
|
Clutter.Gravity.CENTER);
|
||||||
|
this.child.set_opacity(this._childOpacity);
|
||||||
},
|
},
|
||||||
|
|
||||||
animateIn: function() {
|
show: function(animate) {
|
||||||
if (this.child == null)
|
if (this.child == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.childScale = 0;
|
let time = animate ? DASH_ANIMATION_TIME : 0;
|
||||||
this.childOpacity = 0;
|
|
||||||
Tweener.addTween(this,
|
Tweener.addTween(this,
|
||||||
{ childScale: 1.0,
|
{ childScale: 1.0,
|
||||||
childOpacity: 255,
|
childOpacity: 255,
|
||||||
time: DASH_ANIMATION_TIME,
|
time: time,
|
||||||
transition: 'easeOutQuad'
|
transition: 'easeOutQuad'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -180,7 +179,7 @@ const DashItemContainer = new Lang.Class({
|
|||||||
if (this.label)
|
if (this.label)
|
||||||
this.label.destroy();
|
this.label.destroy();
|
||||||
|
|
||||||
this.actor.destroy();
|
this.parent();
|
||||||
},
|
},
|
||||||
|
|
||||||
animateOutAndDestroy: function() {
|
animateOutAndDestroy: function() {
|
||||||
@@ -188,19 +187,18 @@ const DashItemContainer = new Lang.Class({
|
|||||||
this.label.destroy();
|
this.label.destroy();
|
||||||
|
|
||||||
if (this.child == null) {
|
if (this.child == null) {
|
||||||
this.actor.destroy();
|
this.destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.animatingOut = true;
|
this.animatingOut = true;
|
||||||
this.childScale = 1.0;
|
|
||||||
Tweener.addTween(this,
|
Tweener.addTween(this,
|
||||||
{ childScale: 0.0,
|
{ childScale: 0.0,
|
||||||
childOpacity: 0,
|
childOpacity: 0,
|
||||||
time: DASH_ANIMATION_TIME,
|
time: DASH_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: Lang.bind(this, function() {
|
onComplete: Lang.bind(this, function() {
|
||||||
this.actor.destroy();
|
this.destroy();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -213,7 +211,7 @@ const DashItemContainer = new Lang.Class({
|
|||||||
|
|
||||||
this.child.set_scale_with_gravity(scale, scale,
|
this.child.set_scale_with_gravity(scale, scale,
|
||||||
Clutter.Gravity.CENTER);
|
Clutter.Gravity.CENTER);
|
||||||
this.actor.queue_relayout();
|
this.queue_relayout();
|
||||||
},
|
},
|
||||||
|
|
||||||
get childScale() {
|
get childScale() {
|
||||||
@@ -227,7 +225,7 @@ const DashItemContainer = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this.child.set_opacity(opacity);
|
this.child.set_opacity(opacity);
|
||||||
this.actor.queue_redraw();
|
this.queue_redraw();
|
||||||
},
|
},
|
||||||
|
|
||||||
get childOpacity() {
|
get childOpacity() {
|
||||||
@@ -358,6 +356,23 @@ const DashActor = new Lang.Class({
|
|||||||
childBox.y1 = contentBox.y2 - showAppsNatHeight;
|
childBox.y1 = contentBox.y2 - showAppsNatHeight;
|
||||||
childBox.y2 = contentBox.y2;
|
childBox.y2 = contentBox.y2;
|
||||||
showAppsButton.allocate(childBox, flags);
|
showAppsButton.allocate(childBox, flags);
|
||||||
|
},
|
||||||
|
|
||||||
|
vfunc_get_preferred_height: function(forWidth) {
|
||||||
|
// We want to request the natural height of all our children
|
||||||
|
// as our natural height, so we chain up to StWidget (which
|
||||||
|
// then calls BoxLayout), but we only request the showApps
|
||||||
|
// button as the minimum size
|
||||||
|
|
||||||
|
let [, natHeight] = this.parent(forWidth);
|
||||||
|
|
||||||
|
let themeNode = this.get_theme_node();
|
||||||
|
let adjustedForWidth = themeNode.adjust_for_width(forWidth);
|
||||||
|
let [, showAppsButton] = this.get_children();
|
||||||
|
let [minHeight, ] = showAppsButton.get_preferred_height(adjustedForWidth);
|
||||||
|
[minHeight, ] = themeNode.adjust_preferred_height(minHeight, natHeight);
|
||||||
|
|
||||||
|
return [minHeight, natHeight];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -383,12 +398,14 @@ const Dash = new Lang.Class({
|
|||||||
this._container.add_actor(this._box);
|
this._container.add_actor(this._box);
|
||||||
|
|
||||||
this._showAppsIcon = new ShowAppsIcon();
|
this._showAppsIcon = new ShowAppsIcon();
|
||||||
|
this._showAppsIcon.childScale = 1;
|
||||||
|
this._showAppsIcon.childOpacity = 255;
|
||||||
this._showAppsIcon.icon.setIconSize(this.iconSize);
|
this._showAppsIcon.icon.setIconSize(this.iconSize);
|
||||||
this._hookUpLabel(this._showAppsIcon);
|
this._hookUpLabel(this._showAppsIcon);
|
||||||
|
|
||||||
this.showAppsButton = this._showAppsIcon.toggleButton;
|
this.showAppsButton = this._showAppsIcon.toggleButton;
|
||||||
|
|
||||||
this._container.add_actor(this._showAppsIcon.actor);
|
this._container.add_actor(this._showAppsIcon);
|
||||||
|
|
||||||
this.actor = new St.Bin({ child: this._container });
|
this.actor = new St.Bin({ child: this._container });
|
||||||
this.actor.connect('notify::height', Lang.bind(this,
|
this.actor.connect('notify::height', Lang.bind(this,
|
||||||
@@ -450,7 +467,7 @@ const Dash = new Lang.Class({
|
|||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
|
|
||||||
let showAppsHovered =
|
let showAppsHovered =
|
||||||
this._showAppsIcon.actor.contains(dragEvent.targetActor);
|
this._showAppsIcon.contains(dragEvent.targetActor);
|
||||||
|
|
||||||
if (!this._box.contains(dragEvent.targetActor) || showAppsHovered)
|
if (!this._box.contains(dragEvent.targetActor) || showAppsHovered)
|
||||||
this._clearDragPlaceholder();
|
this._clearDragPlaceholder();
|
||||||
@@ -565,13 +582,13 @@ const Dash = new Lang.Class({
|
|||||||
// animating out (which means they will be destroyed at the end of
|
// animating out (which means they will be destroyed at the end of
|
||||||
// the animation)
|
// the animation)
|
||||||
let iconChildren = this._box.get_children().filter(function(actor) {
|
let iconChildren = this._box.get_children().filter(function(actor) {
|
||||||
return actor._delegate.child &&
|
return actor.child &&
|
||||||
actor._delegate.child._delegate &&
|
actor.child._delegate &&
|
||||||
actor._delegate.child._delegate.icon &&
|
actor.child._delegate.icon &&
|
||||||
!actor._delegate.animatingOut;
|
!actor.animatingOut;
|
||||||
});
|
});
|
||||||
|
|
||||||
iconChildren.push(this._showAppsIcon.actor);
|
iconChildren.push(this._showAppsIcon);
|
||||||
|
|
||||||
if (this._maxHeight == -1)
|
if (this._maxHeight == -1)
|
||||||
return;
|
return;
|
||||||
@@ -584,23 +601,18 @@ const Dash = new Lang.Class({
|
|||||||
let availHeight = maxContent.y2 - maxContent.y1;
|
let availHeight = maxContent.y2 - maxContent.y1;
|
||||||
let spacing = themeNode.get_length('spacing');
|
let spacing = themeNode.get_length('spacing');
|
||||||
|
|
||||||
|
let firstButton = iconChildren[0].child;
|
||||||
let firstIcon = iconChildren[0]._delegate.child._delegate.icon;
|
let firstIcon = firstButton._delegate.icon;
|
||||||
|
|
||||||
let minHeight, natHeight;
|
let minHeight, natHeight;
|
||||||
|
|
||||||
// Enforce the current icon size during the size request if
|
// Enforce the current icon size during the size request
|
||||||
// the icon is animating
|
let [currentWidth, currentHeight] = firstIcon.icon.get_size();
|
||||||
if (firstIcon._animating) {
|
|
||||||
let [currentWidth, currentHeight] = firstIcon.icon.get_size();
|
|
||||||
|
|
||||||
firstIcon.icon.set_size(this.iconSize, this.iconSize);
|
firstIcon.icon.set_size(this.iconSize, this.iconSize);
|
||||||
[minHeight, natHeight] = iconChildren[0].get_preferred_height(-1);
|
[minHeight, natHeight] = firstButton.get_preferred_height(-1);
|
||||||
|
|
||||||
firstIcon.icon.set_size(currentWidth, currentHeight);
|
firstIcon.icon.set_size(currentWidth, currentHeight);
|
||||||
} else {
|
|
||||||
[minHeight, natHeight] = iconChildren[0].get_preferred_height(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtract icon padding and box spacing from the available height
|
// Subtract icon padding and box spacing from the available height
|
||||||
availHeight -= iconChildren.length * (natHeight - this.iconSize) +
|
availHeight -= iconChildren.length * (natHeight - this.iconSize) +
|
||||||
@@ -625,7 +637,7 @@ const Dash = new Lang.Class({
|
|||||||
|
|
||||||
let scale = oldIconSize / newIconSize;
|
let scale = oldIconSize / newIconSize;
|
||||||
for (let i = 0; i < iconChildren.length; i++) {
|
for (let i = 0; i < iconChildren.length; i++) {
|
||||||
let icon = iconChildren[i]._delegate.child._delegate.icon;
|
let icon = iconChildren[i].child._delegate.icon;
|
||||||
|
|
||||||
// Set the new size immediately, to keep the icons' sizes
|
// Set the new size immediately, to keep the icons' sizes
|
||||||
// in sync with this.iconSize
|
// in sync with this.iconSize
|
||||||
@@ -645,15 +657,11 @@ const Dash = new Lang.Class({
|
|||||||
icon.icon.set_size(icon.icon.width * scale,
|
icon.icon.set_size(icon.icon.width * scale,
|
||||||
icon.icon.height * scale);
|
icon.icon.height * scale);
|
||||||
|
|
||||||
icon._animating = true;
|
|
||||||
Tweener.addTween(icon.icon,
|
Tweener.addTween(icon.icon,
|
||||||
{ width: targetWidth,
|
{ width: targetWidth,
|
||||||
height: targetHeight,
|
height: targetHeight,
|
||||||
time: DASH_ANIMATION_TIME,
|
time: DASH_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: function() {
|
|
||||||
icon._animating = false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -664,13 +672,13 @@ const Dash = new Lang.Class({
|
|||||||
let running = this._appSystem.get_running();
|
let running = this._appSystem.get_running();
|
||||||
|
|
||||||
let children = this._box.get_children().filter(function(actor) {
|
let children = this._box.get_children().filter(function(actor) {
|
||||||
return actor._delegate.child &&
|
return actor.child &&
|
||||||
actor._delegate.child._delegate &&
|
actor.child._delegate &&
|
||||||
actor._delegate.child._delegate.app;
|
actor.child._delegate.app;
|
||||||
});
|
});
|
||||||
// Apps currently in the dash
|
// Apps currently in the dash
|
||||||
let oldApps = children.map(function(actor) {
|
let oldApps = children.map(function(actor) {
|
||||||
return actor._delegate.child._delegate.app;
|
return actor.child._delegate.app;
|
||||||
});
|
});
|
||||||
// Apps supposed to be in the dash
|
// Apps supposed to be in the dash
|
||||||
let newApps = [];
|
let newApps = [];
|
||||||
@@ -736,7 +744,7 @@ const Dash = new Lang.Class({
|
|||||||
let insertHere = newApps[newIndex + 1] &&
|
let insertHere = newApps[newIndex + 1] &&
|
||||||
newApps[newIndex + 1] == oldApps[oldIndex];
|
newApps[newIndex + 1] == oldApps[oldIndex];
|
||||||
let alreadyRemoved = removedActors.reduce(function(result, actor) {
|
let alreadyRemoved = removedActors.reduce(function(result, actor) {
|
||||||
let removedApp = actor._delegate.child._delegate.app;
|
let removedApp = actor.child._delegate.app;
|
||||||
return result || removedApp == newApps[newIndex];
|
return result || removedApp == newApps[newIndex];
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
@@ -753,11 +761,11 @@ const Dash = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < addedItems.length; i++)
|
for (let i = 0; i < addedItems.length; i++)
|
||||||
this._box.insert_child_at_index(addedItems[i].item.actor,
|
this._box.insert_child_at_index(addedItems[i].item,
|
||||||
addedItems[i].pos);
|
addedItems[i].pos);
|
||||||
|
|
||||||
for (let i = 0; i < removedActors.length; i++) {
|
for (let i = 0; i < removedActors.length; i++) {
|
||||||
let item = removedActors[i]._delegate;
|
let item = removedActors[i];
|
||||||
|
|
||||||
// Don't animate item removal when the overview is transitioning
|
// Don't animate item removal when the overview is transitioning
|
||||||
// or hidden
|
// or hidden
|
||||||
@@ -771,18 +779,20 @@ const Dash = new Lang.Class({
|
|||||||
|
|
||||||
// Skip animations on first run when adding the initial set
|
// Skip animations on first run when adding the initial set
|
||||||
// of items, to avoid all items zooming in at once
|
// of items, to avoid all items zooming in at once
|
||||||
if (!this._shownInitially) {
|
|
||||||
|
let animate = this._shownInitially && Main.overview.visible &&
|
||||||
|
!Main.overview.animationInProgress;
|
||||||
|
|
||||||
|
if (!this._shownInitially)
|
||||||
this._shownInitially = true;
|
this._shownInitially = true;
|
||||||
return;
|
|
||||||
|
for (let i = 0; i < addedItems.length; i++) {
|
||||||
|
addedItems[i].item.show(animate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't animate item addition when the overview is transitioning
|
// Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=692744
|
||||||
// or hidden
|
// Without it, StBoxLayout may use a stale size cache
|
||||||
if (!Main.overview.visible || Main.overview.animationInProgress)
|
this._box.queue_relayout();
|
||||||
return;
|
|
||||||
|
|
||||||
for (let i = 0; i < addedItems.length; i++)
|
|
||||||
addedItems[i].item.animateIn();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_clearDragPlaceholder: function() {
|
_clearDragPlaceholder: function() {
|
||||||
@@ -813,7 +823,7 @@ const Dash = new Lang.Class({
|
|||||||
// the remove target has the same size as "normal" items, we don't
|
// the remove target has the same size as "normal" items, we don't
|
||||||
// need to do the same adjustment there.
|
// need to do the same adjustment there.
|
||||||
if (this._dragPlaceholder) {
|
if (this._dragPlaceholder) {
|
||||||
boxHeight -= this._dragPlaceholder.actor.height;
|
boxHeight -= this._dragPlaceholder.height;
|
||||||
numChildren--;
|
numChildren--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,7 +837,7 @@ const Dash = new Lang.Class({
|
|||||||
if (this._dragPlaceholder) {
|
if (this._dragPlaceholder) {
|
||||||
this._dragPlaceholder.animateOutAndDestroy();
|
this._dragPlaceholder.animateOutAndDestroy();
|
||||||
this._animatingPlaceholdersCount++;
|
this._animatingPlaceholdersCount++;
|
||||||
this._dragPlaceholder.actor.connect('destroy',
|
this._dragPlaceholder.connect('destroy',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this._animatingPlaceholdersCount--;
|
this._animatingPlaceholdersCount--;
|
||||||
}));
|
}));
|
||||||
@@ -842,7 +852,7 @@ const Dash = new Lang.Class({
|
|||||||
// an animation
|
// an animation
|
||||||
let fadeIn;
|
let fadeIn;
|
||||||
if (this._dragPlaceholder) {
|
if (this._dragPlaceholder) {
|
||||||
this._dragPlaceholder.actor.destroy();
|
this._dragPlaceholder.destroy();
|
||||||
fadeIn = false;
|
fadeIn = false;
|
||||||
} else {
|
} else {
|
||||||
fadeIn = true;
|
fadeIn = true;
|
||||||
@@ -851,10 +861,9 @@ const Dash = new Lang.Class({
|
|||||||
this._dragPlaceholder = new DragPlaceholderItem();
|
this._dragPlaceholder = new DragPlaceholderItem();
|
||||||
this._dragPlaceholder.child.set_width (this.iconSize);
|
this._dragPlaceholder.child.set_width (this.iconSize);
|
||||||
this._dragPlaceholder.child.set_height (this.iconSize / 2);
|
this._dragPlaceholder.child.set_height (this.iconSize / 2);
|
||||||
this._box.insert_child_at_index(this._dragPlaceholder.actor,
|
this._box.insert_child_at_index(this._dragPlaceholder,
|
||||||
this._dragPlaceholderPos);
|
this._dragPlaceholderPos);
|
||||||
if (fadeIn)
|
this._dragPlaceholder.show(fadeIn);
|
||||||
this._dragPlaceholder.animateIn();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the drag placeholder if we are not in the
|
// Remove the drag placeholder if we are not in the
|
||||||
@@ -892,10 +901,10 @@ const Dash = new Lang.Class({
|
|||||||
let children = this._box.get_children();
|
let children = this._box.get_children();
|
||||||
for (let i = 0; i < this._dragPlaceholderPos; i++) {
|
for (let i = 0; i < this._dragPlaceholderPos; i++) {
|
||||||
if (this._dragPlaceholder &&
|
if (this._dragPlaceholder &&
|
||||||
children[i] == this._dragPlaceholder.actor)
|
children[i] == this._dragPlaceholder)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
let childId = children[i]._delegate.child._delegate.app.get_id();
|
let childId = children[i].child._delegate.app.get_id();
|
||||||
if (childId == id)
|
if (childId == id)
|
||||||
continue;
|
continue;
|
||||||
if (childId in favorites)
|
if (childId in favorites)
|
||||||
|
|||||||
@@ -161,8 +161,10 @@ const DateMenuButton = new Lang.Class({
|
|||||||
this._openClocksItem.actor.visible = app !== null;
|
this._openClocksItem.actor.visible = app !== null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_setEventsVisibility: function(visible) {
|
_updateEventsVisibility: function() {
|
||||||
|
let visible = this._eventSource.hasCalendars;
|
||||||
this._openCalendarItem.actor.visible = visible;
|
this._openCalendarItem.actor.visible = visible;
|
||||||
|
this._openClocksItem.actor.visible = visible;
|
||||||
this._separator.visible = visible;
|
this._separator.visible = visible;
|
||||||
if (visible) {
|
if (visible) {
|
||||||
let alignment = 0.25;
|
let alignment = 0.25;
|
||||||
@@ -177,8 +179,16 @@ const DateMenuButton = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_setEventSource: function(eventSource) {
|
_setEventSource: function(eventSource) {
|
||||||
|
if (this._eventSource)
|
||||||
|
this._eventSource.destroy();
|
||||||
|
|
||||||
this._calendar.setEventSource(eventSource);
|
this._calendar.setEventSource(eventSource);
|
||||||
this._eventList.setEventSource(eventSource);
|
this._eventList.setEventSource(eventSource);
|
||||||
|
|
||||||
|
this._eventSource = eventSource;
|
||||||
|
this._eventSource.connect('notify::has-calendars', Lang.bind(this, function() {
|
||||||
|
this._updateEventsVisibility();
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_sessionUpdated: function() {
|
_sessionUpdated: function() {
|
||||||
@@ -187,10 +197,10 @@ const DateMenuButton = new Lang.Class({
|
|||||||
if (showEvents) {
|
if (showEvents) {
|
||||||
eventSource = new Calendar.DBusEventSource();
|
eventSource = new Calendar.DBusEventSource();
|
||||||
} else {
|
} else {
|
||||||
eventSource = null;
|
eventSource = new Calendar.EmptyEventSource();
|
||||||
}
|
}
|
||||||
this._setEventSource(eventSource);
|
this._setEventSource(eventSource);
|
||||||
this._setEventsVisibility(showEvents);
|
this._updateEventsVisibility();
|
||||||
|
|
||||||
// This needs to be handled manually, as the code to
|
// This needs to be handled manually, as the code to
|
||||||
// autohide separators doesn't work across the vbox
|
// autohide separators doesn't work across the vbox
|
||||||
@@ -211,6 +221,8 @@ const DateMenuButton = new Lang.Class({
|
|||||||
this.menu.close();
|
this.menu.close();
|
||||||
|
|
||||||
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
|
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
|
||||||
|
if (app.get_id() == 'evolution')
|
||||||
|
app = Gio.DesktopAppInfo.new('evolution-calendar');
|
||||||
app.launch([], global.create_app_launch_context());
|
app.launch([], global.create_app_launch_context());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
12
js/ui/dnd.js
12
js/ui/dnd.js
@@ -85,11 +85,13 @@ const _Draggable = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, function() {
|
this.actor.connect('destroy', Lang.bind(this, function() {
|
||||||
this._actorDestroyed = true;
|
this._actorDestroyed = true;
|
||||||
|
|
||||||
// If the drag actor is destroyed and we were going to fix
|
// If the drag actor is destroyed and we were going to fix
|
||||||
// up its hover state, fix up the parent hover state instead
|
// up its hover state, fix up the parent hover state instead
|
||||||
if (this.actor == this._firstLeaveActor)
|
if (this.actor == this._firstLeaveActor)
|
||||||
this._firstLeaveActor = this._dragOrigParent;
|
this._firstLeaveActor = this._dragOrigParent;
|
||||||
if (this._dragInProgress)
|
|
||||||
|
if (this._dragInProgress && this._dragCancellable)
|
||||||
this._cancelDrag(global.get_current_time());
|
this._cancelDrag(global.get_current_time());
|
||||||
this.disconnectAll();
|
this.disconnectAll();
|
||||||
}));
|
}));
|
||||||
@@ -102,6 +104,7 @@ const _Draggable = new Lang.Class({
|
|||||||
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
||||||
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
|
this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
|
||||||
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
||||||
|
this._dragCancellable = true;
|
||||||
|
|
||||||
// During the drag, we eat enter/leave events so that actors don't prelight.
|
// During the drag, we eat enter/leave events so that actors don't prelight.
|
||||||
// But we remember the actors that we first left/last entered so we can
|
// But we remember the actors that we first left/last entered so we can
|
||||||
@@ -439,6 +442,11 @@ const _Draggable = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At this point it is too late to cancel a drag by destroying
|
||||||
|
// the actor, the fate of which is decided by acceptDrop and its
|
||||||
|
// side-effects
|
||||||
|
this._dragCancellable = false;
|
||||||
|
|
||||||
while (target) {
|
while (target) {
|
||||||
if (target._delegate && target._delegate.acceptDrop) {
|
if (target._delegate && target._delegate.acceptDrop) {
|
||||||
let [r, targX, targY] = target.transform_stage_point(dropX, dropY);
|
let [r, targX, targY] = target.transform_stage_point(dropX, dropY);
|
||||||
@@ -447,8 +455,6 @@ const _Draggable = new Lang.Class({
|
|||||||
targX,
|
targX,
|
||||||
targY,
|
targY,
|
||||||
event.get_time())) {
|
event.get_time())) {
|
||||||
if (this._actorDestroyed)
|
|
||||||
return true;
|
|
||||||
// If it accepted the drop without taking the actor,
|
// If it accepted the drop without taking the actor,
|
||||||
// handle it ourselves.
|
// handle it ourselves.
|
||||||
if (this._dragActor.get_parent() == Main.uiGroup) {
|
if (this._dragActor.get_parent() == Main.uiGroup) {
|
||||||
|
|||||||
@@ -225,7 +225,8 @@ const EndSessionDialog = new Lang.Class({
|
|||||||
Extends: ModalDialog.ModalDialog,
|
Extends: ModalDialog.ModalDialog,
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent({ styleClass: 'end-session-dialog' });
|
this.parent({ styleClass: 'end-session-dialog',
|
||||||
|
destroyOnClose: false });
|
||||||
|
|
||||||
this._user = AccountsService.UserManager.get_default().get_user(GLib.get_user_name());
|
this._user = AccountsService.UserManager.get_default().get_user(GLib.get_user_name());
|
||||||
|
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ const GrabHelper = new Lang.Class({
|
|||||||
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
|
global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
global.screen.focus_default_window(global.get_current_time());
|
global.screen.focus_default_window(global.display.get_current_time_roundtrip());
|
||||||
},
|
},
|
||||||
|
|
||||||
// ignoreRelease:
|
// ignoreRelease:
|
||||||
@@ -308,6 +308,8 @@ const GrabHelper = new Lang.Class({
|
|||||||
if (!this.grabbed && this._capturedEventId > 0) {
|
if (!this.grabbed && this._capturedEventId > 0) {
|
||||||
global.stage.disconnect(this._capturedEventId);
|
global.stage.disconnect(this._capturedEventId);
|
||||||
this._capturedEventId = 0;
|
this._capturedEventId = 0;
|
||||||
|
|
||||||
|
this._ignoreRelease = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hadFocus) {
|
if (hadFocus) {
|
||||||
@@ -353,6 +355,7 @@ const GrabHelper = new Lang.Class({
|
|||||||
this._ignoreRelease = true;
|
this._ignoreRelease = true;
|
||||||
let i = this._actorInGrabStack(event.get_source()) + 1;
|
let i = this._actorInGrabStack(event.get_source()) + 1;
|
||||||
this.ungrab({ actor: this._grabStack[i].actor, isUser: true });
|
this.ungrab({ actor: this._grabStack[i].actor, isUser: true });
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._modalCount > 0;
|
return this._modalCount > 0;
|
||||||
|
|||||||
@@ -176,13 +176,16 @@ const IconGrid = new Lang.Class({
|
|||||||
_init: function(params) {
|
_init: function(params) {
|
||||||
params = Params.parse(params, { rowLimit: null,
|
params = Params.parse(params, { rowLimit: null,
|
||||||
columnLimit: null,
|
columnLimit: null,
|
||||||
|
fillParent: false,
|
||||||
xAlign: St.Align.MIDDLE });
|
xAlign: St.Align.MIDDLE });
|
||||||
this._rowLimit = params.rowLimit;
|
this._rowLimit = params.rowLimit;
|
||||||
this._colLimit = params.columnLimit;
|
this._colLimit = params.columnLimit;
|
||||||
this._xAlign = params.xAlign;
|
this._xAlign = params.xAlign;
|
||||||
|
this._fillParent = params.fillParent;
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ style_class: 'icon-grid',
|
this.actor = new St.BoxLayout({ style_class: 'icon-grid',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
|
|
||||||
// Pulled from CSS, but hardcode some defaults here
|
// Pulled from CSS, but hardcode some defaults here
|
||||||
this._spacing = 0;
|
this._spacing = 0;
|
||||||
this._hItemSize = this._vItemSize = ICON_SIZE;
|
this._hItemSize = this._vItemSize = ICON_SIZE;
|
||||||
@@ -196,6 +199,11 @@ const IconGrid = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredWidth: function (grid, forHeight, alloc) {
|
_getPreferredWidth: function (grid, forHeight, alloc) {
|
||||||
|
if (this._fillParent)
|
||||||
|
// Ignore all size requests of children and request a size of 0;
|
||||||
|
// later we'll allocate as many children as fit the parent
|
||||||
|
return;
|
||||||
|
|
||||||
let children = this._grid.get_children();
|
let children = this._grid.get_children();
|
||||||
let nColumns = this._colLimit ? Math.min(this._colLimit,
|
let nColumns = this._colLimit ? Math.min(this._colLimit,
|
||||||
children.length)
|
children.length)
|
||||||
@@ -217,12 +225,20 @@ const IconGrid = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_getPreferredHeight: function (grid, forWidth, alloc) {
|
_getPreferredHeight: function (grid, forWidth, alloc) {
|
||||||
|
if (this._fillParent)
|
||||||
|
// Ignore all size requests of children and request a size of 0;
|
||||||
|
// later we'll allocate as many children as fit the parent
|
||||||
|
return;
|
||||||
|
|
||||||
let children = this._getVisibleChildren();
|
let children = this._getVisibleChildren();
|
||||||
let nColumns;
|
let nColumns, spacing;
|
||||||
if (forWidth < 0)
|
if (forWidth < 0) {
|
||||||
nColumns = children.length;
|
nColumns = children.length;
|
||||||
else
|
spacing = this._spacing;
|
||||||
nColumns = this._computeLayout(forWidth)[0];
|
} else {
|
||||||
|
[nColumns, , spacing] = this._computeLayout(forWidth);
|
||||||
|
}
|
||||||
|
|
||||||
let nRows;
|
let nRows;
|
||||||
if (nColumns > 0)
|
if (nColumns > 0)
|
||||||
nRows = Math.ceil(children.length / nColumns);
|
nRows = Math.ceil(children.length / nColumns);
|
||||||
@@ -230,13 +246,20 @@ const IconGrid = new Lang.Class({
|
|||||||
nRows = 0;
|
nRows = 0;
|
||||||
if (this._rowLimit)
|
if (this._rowLimit)
|
||||||
nRows = Math.min(nRows, this._rowLimit);
|
nRows = Math.min(nRows, this._rowLimit);
|
||||||
let totalSpacing = Math.max(0, nRows - 1) * this._spacing;
|
let totalSpacing = Math.max(0, nRows - 1) * spacing;
|
||||||
let height = nRows * this._vItemSize + totalSpacing;
|
let height = nRows * this._vItemSize + totalSpacing;
|
||||||
alloc.min_size = height;
|
alloc.min_size = height;
|
||||||
alloc.natural_size = height;
|
alloc.natural_size = height;
|
||||||
},
|
},
|
||||||
|
|
||||||
_allocate: function (grid, box, flags) {
|
_allocate: function (grid, box, flags) {
|
||||||
|
if (this._fillParent) {
|
||||||
|
// Reset the passed in box to fill the parent
|
||||||
|
let parentBox = this.actor.get_parent().allocation;
|
||||||
|
let gridBox = this.actor.get_theme_node().get_content_box(parentBox);
|
||||||
|
box = this._grid.get_theme_node().get_content_box(gridBox);
|
||||||
|
}
|
||||||
|
|
||||||
let children = this._getVisibleChildren();
|
let children = this._getVisibleChildren();
|
||||||
let availWidth = box.x2 - box.x1;
|
let availWidth = box.x2 - box.x1;
|
||||||
let availHeight = box.y2 - box.y1;
|
let availHeight = box.y2 - box.y1;
|
||||||
@@ -280,7 +303,8 @@ const IconGrid = new Lang.Class({
|
|||||||
childBox.x2 = childBox.x1 + width;
|
childBox.x2 = childBox.x1 + width;
|
||||||
childBox.y2 = childBox.y1 + height;
|
childBox.y2 = childBox.y1 + height;
|
||||||
|
|
||||||
if (this._rowLimit && rowIndex >= this._rowLimit) {
|
if (this._rowLimit && rowIndex >= this._rowLimit ||
|
||||||
|
this._fillParent && childBox.y2 > availHeight) {
|
||||||
this._grid.set_skip_paint(children[i], true);
|
this._grid.set_skip_paint(children[i], true);
|
||||||
} else {
|
} else {
|
||||||
children[i].allocate(childBox, flags);
|
children[i].allocate(childBox, flags);
|
||||||
|
|||||||
567
js/ui/layout.js
567
js/ui/layout.js
@@ -1,6 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
const GObject = imports.gi.GObject;
|
const GObject = imports.gi.GObject;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
@@ -17,7 +18,6 @@ const Main = imports.ui.main;
|
|||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5;
|
|
||||||
const STARTUP_ANIMATION_TIME = 0.5;
|
const STARTUP_ANIMATION_TIME = 0.5;
|
||||||
const KEYBOARD_ANIMATION_TIME = 0.15;
|
const KEYBOARD_ANIMATION_TIME = 0.15;
|
||||||
const BACKGROUND_FADE_ANIMATION_TIME = 1.0;
|
const BACKGROUND_FADE_ANIMATION_TIME = 1.0;
|
||||||
@@ -25,8 +25,11 @@ const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
|
|||||||
|
|
||||||
// The message tray takes this much pressure
|
// The message tray takes this much pressure
|
||||||
// in the pressure barrier at once to release it.
|
// in the pressure barrier at once to release it.
|
||||||
const MESSAGE_TRAY_PRESSURE_THRESHOLD = 200; // pixels
|
const MESSAGE_TRAY_PRESSURE_THRESHOLD = 250; // pixels
|
||||||
const MESSAGE_TRAY_PRESSURE_TIMEOUT = 3000; // ms
|
const MESSAGE_TRAY_PRESSURE_TIMEOUT = 1000; // ms
|
||||||
|
|
||||||
|
const HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
|
||||||
|
const HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
|
||||||
|
|
||||||
function isPopupMetaWindow(actor) {
|
function isPopupMetaWindow(actor) {
|
||||||
switch(actor.meta_window.get_window_type()) {
|
switch(actor.meta_window.get_window_type()) {
|
||||||
@@ -129,9 +132,9 @@ const LayoutManager = new Lang.Class({
|
|||||||
this.monitors = [];
|
this.monitors = [];
|
||||||
this.primaryMonitor = null;
|
this.primaryMonitor = null;
|
||||||
this.primaryIndex = -1;
|
this.primaryIndex = -1;
|
||||||
|
this.hotCorners = [];
|
||||||
|
|
||||||
this._keyboardIndex = -1;
|
this._keyboardIndex = -1;
|
||||||
this._hotCorners = [];
|
|
||||||
this._leftPanelBarrier = null;
|
|
||||||
this._rightPanelBarrier = null;
|
this._rightPanelBarrier = null;
|
||||||
this._trayBarrier = null;
|
this._trayBarrier = null;
|
||||||
|
|
||||||
@@ -139,6 +142,7 @@ const LayoutManager = new Lang.Class({
|
|||||||
this._updateRegionIdle = 0;
|
this._updateRegionIdle = 0;
|
||||||
|
|
||||||
this._trackedActors = [];
|
this._trackedActors = [];
|
||||||
|
this._topActors = [];
|
||||||
this._isPopupWindowVisible = false;
|
this._isPopupWindowVisible = false;
|
||||||
this._startingUp = true;
|
this._startingUp = true;
|
||||||
|
|
||||||
@@ -190,6 +194,7 @@ const LayoutManager = new Lang.Class({
|
|||||||
this.trayBox = new St.Widget({ name: 'trayBox',
|
this.trayBox = new St.Widget({ name: 'trayBox',
|
||||||
layout_manager: new Clutter.BinLayout() });
|
layout_manager: new Clutter.BinLayout() });
|
||||||
this.addChrome(this.trayBox);
|
this.addChrome(this.trayBox);
|
||||||
|
this._setupTrayPressure();
|
||||||
|
|
||||||
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
|
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
@@ -200,9 +205,6 @@ const LayoutManager = new Lang.Class({
|
|||||||
global.stage.remove_actor(global.top_window_group);
|
global.stage.remove_actor(global.top_window_group);
|
||||||
this.uiGroup.add_actor(global.top_window_group);
|
this.uiGroup.add_actor(global.top_window_group);
|
||||||
|
|
||||||
this._consoleBackgroundGroup = new Meta.BackgroundGroup();
|
|
||||||
global.stage.insert_child_below(this._consoleBackgroundGroup, null);
|
|
||||||
|
|
||||||
this._backgroundGroup = new Meta.BackgroundGroup();
|
this._backgroundGroup = new Meta.BackgroundGroup();
|
||||||
global.window_group.add_child(this._backgroundGroup);
|
global.window_group.add_child(this._backgroundGroup);
|
||||||
this._backgroundGroup.lower_bottom();
|
this._backgroundGroup.lower_bottom();
|
||||||
@@ -220,6 +222,8 @@ const LayoutManager = new Lang.Class({
|
|||||||
Lang.bind(this, this._windowsRestacked));
|
Lang.bind(this, this._windowsRestacked));
|
||||||
global.screen.connect('monitors-changed',
|
global.screen.connect('monitors-changed',
|
||||||
Lang.bind(this, this._monitorsChanged));
|
Lang.bind(this, this._monitorsChanged));
|
||||||
|
global.screen.connect('in-fullscreen-changed',
|
||||||
|
Lang.bind(this, this._updateFullscreen));
|
||||||
this._monitorsChanged();
|
this._monitorsChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -230,6 +234,8 @@ const LayoutManager = new Lang.Class({
|
|||||||
Main.overview.connect('showing', Lang.bind(this, this._overviewShowing));
|
Main.overview.connect('showing', Lang.bind(this, this._overviewShowing));
|
||||||
Main.overview.connect('hidden', Lang.bind(this, this._overviewHidden));
|
Main.overview.connect('hidden', Lang.bind(this, this._overviewHidden));
|
||||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||||
|
|
||||||
|
this._prepareStartupAnimation();
|
||||||
},
|
},
|
||||||
|
|
||||||
_overviewShowing: function() {
|
_overviewShowing: function() {
|
||||||
@@ -277,56 +283,58 @@ const LayoutManager = new Lang.Class({
|
|||||||
|
|
||||||
_updateHotCorners: function() {
|
_updateHotCorners: function() {
|
||||||
// destroy old hot corners
|
// destroy old hot corners
|
||||||
for (let i = 0; i < this._hotCorners.length; i++)
|
for (let i = 0; i < this.hotCorners.length; i++)
|
||||||
this._hotCorners[i].destroy();
|
this.hotCorners[i].destroy();
|
||||||
this._hotCorners = [];
|
this.hotCorners = [];
|
||||||
|
|
||||||
|
let size = this.panelBox.height;
|
||||||
|
|
||||||
// build new hot corners
|
// build new hot corners
|
||||||
for (let i = 0; i < this.monitors.length; i++) {
|
for (let i = 0; i < this.monitors.length; i++) {
|
||||||
if (i == this.primaryIndex)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
let monitor = this.monitors[i];
|
let monitor = this.monitors[i];
|
||||||
let cornerX = this._rtl ? monitor.x + monitor.width : monitor.x;
|
let cornerX = this._rtl ? monitor.x + monitor.width : monitor.x;
|
||||||
let cornerY = monitor.y;
|
let cornerY = monitor.y;
|
||||||
|
|
||||||
let haveTopLeftCorner = true;
|
if (i != this.primaryIndex) {
|
||||||
|
let haveTopLeftCorner = true;
|
||||||
|
|
||||||
// Check if we have a top left (right for RTL) corner.
|
// Check if we have a top left (right for RTL) corner.
|
||||||
// I.e. if there is no monitor directly above or to the left(right)
|
// I.e. if there is no monitor directly above or to the left(right)
|
||||||
let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
|
let besideX = this._rtl ? monitor.x + 1 : cornerX - 1;
|
||||||
let besideY = cornerY;
|
let besideY = cornerY;
|
||||||
let aboveX = cornerX;
|
let aboveX = cornerX;
|
||||||
let aboveY = cornerY - 1;
|
let aboveY = cornerY - 1;
|
||||||
|
|
||||||
for (let j = 0; j < this.monitors.length; j++) {
|
for (let j = 0; j < this.monitors.length; j++) {
|
||||||
if (i == j)
|
if (i == j)
|
||||||
|
continue;
|
||||||
|
let otherMonitor = this.monitors[j];
|
||||||
|
if (besideX >= otherMonitor.x &&
|
||||||
|
besideX < otherMonitor.x + otherMonitor.width &&
|
||||||
|
besideY >= otherMonitor.y &&
|
||||||
|
besideY < otherMonitor.y + otherMonitor.height) {
|
||||||
|
haveTopLeftCorner = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (aboveX >= otherMonitor.x &&
|
||||||
|
aboveX < otherMonitor.x + otherMonitor.width &&
|
||||||
|
aboveY >= otherMonitor.y &&
|
||||||
|
aboveY < otherMonitor.y + otherMonitor.height) {
|
||||||
|
haveTopLeftCorner = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!haveTopLeftCorner)
|
||||||
continue;
|
continue;
|
||||||
let otherMonitor = this.monitors[j];
|
|
||||||
if (besideX >= otherMonitor.x &&
|
|
||||||
besideX < otherMonitor.x + otherMonitor.width &&
|
|
||||||
besideY >= otherMonitor.y &&
|
|
||||||
besideY < otherMonitor.y + otherMonitor.height) {
|
|
||||||
haveTopLeftCorner = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (aboveX >= otherMonitor.x &&
|
|
||||||
aboveX < otherMonitor.x + otherMonitor.width &&
|
|
||||||
aboveY >= otherMonitor.y &&
|
|
||||||
aboveY < otherMonitor.y + otherMonitor.height) {
|
|
||||||
haveTopLeftCorner = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!haveTopLeftCorner)
|
let corner = new HotCorner(this, monitor, cornerX, cornerY);
|
||||||
continue;
|
corner.setBarrierSize(size);
|
||||||
|
this.hotCorners.push(corner);
|
||||||
let corner = new HotCorner(this);
|
|
||||||
this._hotCorners.push(corner);
|
|
||||||
corner.actor.set_position(cornerX, cornerY);
|
|
||||||
this.addChrome(corner.actor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.emit('hot-corners-changed');
|
||||||
},
|
},
|
||||||
|
|
||||||
_createBackground: function(monitorIndex) {
|
_createBackground: function(monitorIndex) {
|
||||||
@@ -396,16 +404,15 @@ const LayoutManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_panelBoxChanged: function() {
|
_panelBoxChanged: function() {
|
||||||
this.emit('panel-box-changed');
|
this._updatePanelBarrier();
|
||||||
this._updatePanelBarriers();
|
|
||||||
|
let size = this.panelBox.height;
|
||||||
|
this.hotCorners.forEach(function(corner) {
|
||||||
|
corner.setBarrierSize(size);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_updatePanelBarriers: function() {
|
_updatePanelBarrier: function() {
|
||||||
if (this._leftPanelBarrier) {
|
|
||||||
this._leftPanelBarrier.destroy();
|
|
||||||
this._leftPanelBarrier = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._rightPanelBarrier) {
|
if (this._rightPanelBarrier) {
|
||||||
this._rightPanelBarrier.destroy();
|
this._rightPanelBarrier.destroy();
|
||||||
this._rightPanelBarrier = null;
|
this._rightPanelBarrier = null;
|
||||||
@@ -414,10 +421,6 @@ const LayoutManager = new Lang.Class({
|
|||||||
if (this.panelBox.height) {
|
if (this.panelBox.height) {
|
||||||
let primary = this.primaryMonitor;
|
let primary = this.primaryMonitor;
|
||||||
|
|
||||||
this._leftPanelBarrier = new Meta.Barrier({ display: global.display,
|
|
||||||
x1: primary.x, y1: primary.y,
|
|
||||||
x2: primary.x, y2: primary.y + this.panelBox.height,
|
|
||||||
directions: Meta.BarrierDirection.POSITIVE_X });
|
|
||||||
this._rightPanelBarrier = new Meta.Barrier({ display: global.display,
|
this._rightPanelBarrier = new Meta.Barrier({ display: global.display,
|
||||||
x1: primary.x + primary.width, y1: primary.y,
|
x1: primary.x + primary.width, y1: primary.y,
|
||||||
x2: primary.x + primary.width, y2: primary.y + this.panelBox.height,
|
x2: primary.x + primary.width, y2: primary.y + this.panelBox.height,
|
||||||
@@ -425,28 +428,44 @@ const LayoutManager = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_setupTrayPressure: function() {
|
||||||
|
this._trayPressure = new PressureBarrier(MESSAGE_TRAY_PRESSURE_THRESHOLD,
|
||||||
|
MESSAGE_TRAY_PRESSURE_TIMEOUT,
|
||||||
|
Shell.KeyBindingMode.NORMAL |
|
||||||
|
Shell.KeyBindingMode.OVERVIEW);
|
||||||
|
this._trayPressure.setEventFilter(this._trayBarrierEventFilter);
|
||||||
|
this._trayPressure.connect('trigger', function(barrier) {
|
||||||
|
if (Main.layoutManager.bottomMonitor.inFullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Main.messageTray.openTray();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
_updateTrayBarrier: function() {
|
_updateTrayBarrier: function() {
|
||||||
let monitor = this.bottomMonitor;
|
let monitor = this.bottomMonitor;
|
||||||
|
|
||||||
if (this._trayBarrier) {
|
if (this._trayBarrier) {
|
||||||
|
this._trayPressure.removeBarrier(this._trayBarrier);
|
||||||
this._trayBarrier.destroy();
|
this._trayBarrier.destroy();
|
||||||
this._trayBarrier = null;
|
this._trayBarrier = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._trayPressure) {
|
|
||||||
this._trayPressure.destroy();
|
|
||||||
this._trayPressure = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._trayBarrier = new Meta.Barrier({ display: global.display,
|
this._trayBarrier = new Meta.Barrier({ display: global.display,
|
||||||
x1: monitor.x, x2: monitor.x + monitor.width,
|
x1: monitor.x, x2: monitor.x + monitor.width,
|
||||||
y1: monitor.y + monitor.height, y2: monitor.y + monitor.height,
|
y1: monitor.y + monitor.height, y2: monitor.y + monitor.height,
|
||||||
directions: Meta.BarrierDirection.NEGATIVE_Y });
|
directions: Meta.BarrierDirection.NEGATIVE_Y });
|
||||||
|
this._trayPressure.addBarrier(this._trayBarrier);
|
||||||
|
},
|
||||||
|
|
||||||
this._trayPressure = new PressureBarrier(this._trayBarrier, MESSAGE_TRAY_PRESSURE_THRESHOLD, MESSAGE_TRAY_PRESSURE_TIMEOUT);
|
_trayBarrierEventFilter: function(event) {
|
||||||
this._trayPressure.connect('trigger', function(barrier) {
|
// Throw out all events where the pointer was grabbed by another
|
||||||
Main.messageTray.openTray();
|
// client, as the client that grabbed the pointer expects to have
|
||||||
});
|
// complete control over it
|
||||||
|
if (event.grabbed && Main.modalCount == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_monitorsChanged: function() {
|
_monitorsChanged: function() {
|
||||||
@@ -536,22 +555,11 @@ const LayoutManager = new Lang.Class({
|
|||||||
// MetaBackgroundActor inside global.window_group covers the entirety of the
|
// MetaBackgroundActor inside global.window_group covers the entirety of the
|
||||||
// screen. So, we set no_clear_hint at the end of the animation.
|
// screen. So, we set no_clear_hint at the end of the animation.
|
||||||
|
|
||||||
prepareStartupAnimation: function() {
|
_prepareStartupAnimation: function() {
|
||||||
// Set ourselves to FULLSCREEN input mode while the animation is running
|
// Set ourselves to FULLSCREEN input mode while the animation is running
|
||||||
// so events don't get delivered to X11 windows (which are distorted by the animation)
|
// so events don't get delivered to X11 windows (which are distorted by the animation)
|
||||||
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
||||||
|
|
||||||
// build new backgrounds
|
|
||||||
for (let i = 0; i < this.monitors.length; i++) {
|
|
||||||
let monitor = this.monitors[i];
|
|
||||||
|
|
||||||
let stillFrame = new Background.StillFrame(i);
|
|
||||||
this._consoleBackgroundGroup.add_child(stillFrame.actor);
|
|
||||||
|
|
||||||
stillFrame.actor.set_size(this.monitors[i].width, this.monitors[i].height);
|
|
||||||
stillFrame.actor.set_position(this.monitors[i].x, this.monitors[i].y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Main.sessionMode.isGreeter) {
|
if (Main.sessionMode.isGreeter) {
|
||||||
this.panelBox.translation_y = -this.panelBox.height;
|
this.panelBox.translation_y = -this.panelBox.height;
|
||||||
} else {
|
} else {
|
||||||
@@ -568,11 +576,43 @@ const LayoutManager = new Lang.Class({
|
|||||||
|
|
||||||
this.uiGroup.set_pivot_point(x / global.screen_width,
|
this.uiGroup.set_pivot_point(x / global.screen_width,
|
||||||
y / global.screen_height);
|
y / global.screen_height);
|
||||||
this.uiGroup.scale_x = this.uiGroup.scale_y = 0;
|
this.uiGroup.scale_x = this.uiGroup.scale_y = 0.5;
|
||||||
|
this.uiGroup.opacity = 0;
|
||||||
|
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._systemBackground = new Background.SystemBackground();
|
||||||
|
this._systemBackground.actor.hide();
|
||||||
|
|
||||||
|
global.stage.insert_child_below(this._systemBackground.actor, null);
|
||||||
|
|
||||||
|
let constraint = new Clutter.BindConstraint({ source: global.stage,
|
||||||
|
coordinate: Clutter.BindCoordinate.ALL });
|
||||||
|
this._systemBackground.actor.add_constraint(constraint);
|
||||||
|
|
||||||
|
let signalId = this._systemBackground.connect('loaded',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._systemBackground.disconnect(signalId);
|
||||||
|
this._systemBackground.actor.show();
|
||||||
|
global.stage.show();
|
||||||
|
|
||||||
|
this.emit('startup-prepared');
|
||||||
|
|
||||||
|
// We're mostly prepared for the startup animation
|
||||||
|
// now, but since a lot is going on asynchronously
|
||||||
|
// during startup, let's defer the startup animation
|
||||||
|
// until the event loop is uncontended and idle.
|
||||||
|
// This helps to prevent us from running the animation
|
||||||
|
// when the system is bogged down
|
||||||
|
GLib.idle_add(GLib.PRIORITY_LOW,
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._startupAnimation();
|
||||||
|
return false;
|
||||||
|
}));
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
startupAnimation: function() {
|
_startupAnimation: function() {
|
||||||
if (Main.sessionMode.isGreeter)
|
if (Main.sessionMode.isGreeter)
|
||||||
this._startupAnimationGreeter();
|
this._startupAnimationGreeter();
|
||||||
else
|
else
|
||||||
@@ -593,6 +633,7 @@ const LayoutManager = new Lang.Class({
|
|||||||
Tweener.addTween(this.uiGroup,
|
Tweener.addTween(this.uiGroup,
|
||||||
{ scale_x: 1,
|
{ scale_x: 1,
|
||||||
scale_y: 1,
|
scale_y: 1,
|
||||||
|
opacity: 255,
|
||||||
time: STARTUP_ANIMATION_TIME,
|
time: STARTUP_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: this._startupAnimationComplete,
|
onComplete: this._startupAnimationComplete,
|
||||||
@@ -606,20 +647,22 @@ const LayoutManager = new Lang.Class({
|
|||||||
|
|
||||||
global.stage_input_mode = Shell.StageInputMode.NORMAL;
|
global.stage_input_mode = Shell.StageInputMode.NORMAL;
|
||||||
|
|
||||||
this._consoleBackgroundGroup.destroy();
|
this._systemBackground.actor.destroy();
|
||||||
this._consoleBackgroundGroup = null;
|
this._systemBackground = null;
|
||||||
|
|
||||||
this._startingUp = false;
|
this._startingUp = false;
|
||||||
|
|
||||||
this.trayBox.show();
|
this.trayBox.show();
|
||||||
this.keyboardBox.show();
|
this.keyboardBox.show();
|
||||||
|
|
||||||
if (!Main.sessionMode.isGreeter)
|
if (!Main.sessionMode.isGreeter) {
|
||||||
this._createSecondaryBackgrounds();
|
this._createSecondaryBackgrounds();
|
||||||
|
global.window_group.remove_clip();
|
||||||
this.emit('panel-box-changed');
|
}
|
||||||
|
|
||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
|
|
||||||
|
this.emit('startup-complete');
|
||||||
},
|
},
|
||||||
|
|
||||||
showKeyboard: function () {
|
showKeyboard: function () {
|
||||||
@@ -795,6 +838,11 @@ const LayoutManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateVisibility: function() {
|
_updateVisibility: function() {
|
||||||
|
let windowsVisible = Main.sessionMode.hasWindows && !this._inOverview;
|
||||||
|
|
||||||
|
global.window_group.visible = windowsVisible;
|
||||||
|
global.top_window_group.visible = windowsVisible;
|
||||||
|
|
||||||
for (let i = 0; i < this._trackedActors.length; i++) {
|
for (let i = 0; i < this._trackedActors.length; i++) {
|
||||||
let actorData = this._trackedActors[i], visible;
|
let actorData = this._trackedActors[i], visible;
|
||||||
if (!actorData.trackFullscreen)
|
if (!actorData.trackFullscreen)
|
||||||
@@ -802,7 +850,7 @@ const LayoutManager = new Lang.Class({
|
|||||||
if (!actorData.isToplevel)
|
if (!actorData.isToplevel)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (this._inOverview || !Main.sessionMode.hasWindows)
|
if (!windowsVisible)
|
||||||
visible = true;
|
visible = true;
|
||||||
else if (this.findMonitorForActor(actorData.actor).inFullscreen)
|
else if (this.findMonitorForActor(actorData.actor).inFullscreen)
|
||||||
visible = false;
|
visible = false;
|
||||||
@@ -852,92 +900,25 @@ const LayoutManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateFullscreen: function() {
|
_updateFullscreen: function() {
|
||||||
let windows = this._getWindowActorsForWorkspace(global.screen.get_active_workspace());
|
|
||||||
|
|
||||||
// Reset all monitors to not fullscreen
|
|
||||||
for (let i = 0; i < this.monitors.length; i++)
|
for (let i = 0; i < this.monitors.length; i++)
|
||||||
this.monitors[i].inFullscreen = false;
|
this.monitors[i].inFullscreen = global.screen.get_monitor_in_fullscreen (i);
|
||||||
|
|
||||||
// Ordinary chrome should be visible unless there is a window
|
this._updateVisibility();
|
||||||
// with layer FULLSCREEN, or a window with layer
|
this._queueUpdateRegions();
|
||||||
// OVERRIDE_REDIRECT that covers the whole screen.
|
|
||||||
// ('override_redirect' is not actually a layer above all
|
|
||||||
// other windows, but this seems to be how mutter treats it
|
|
||||||
// currently...) If we wanted to be extra clever, we could
|
|
||||||
// figure out when an OVERRIDE_REDIRECT window was trying to
|
|
||||||
// partially overlap us, and then adjust the input region and
|
|
||||||
// our clip region accordingly...
|
|
||||||
|
|
||||||
// @windows is sorted bottom to top.
|
this.emit('fullscreen-changed');
|
||||||
|
|
||||||
for (let i = windows.length - 1; i > -1; i--) {
|
|
||||||
let window = windows[i];
|
|
||||||
let metaWindow = window.meta_window;
|
|
||||||
let layer = metaWindow.get_layer();
|
|
||||||
|
|
||||||
// Skip minimized windows
|
|
||||||
if (!metaWindow.showing_on_its_workspace())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (layer == Meta.StackLayer.FULLSCREEN ||
|
|
||||||
(layer == Meta.StackLayer.OVERRIDE_REDIRECT && metaWindow.is_monitor_sized())) {
|
|
||||||
if (metaWindow.is_screen_sized()) {
|
|
||||||
for (let i = 0; i < this.monitors.length; i++)
|
|
||||||
this.monitors[i].inFullscreen = true;
|
|
||||||
} else {
|
|
||||||
let monitor = this.monitors[metaWindow.get_monitor()];
|
|
||||||
if (monitor)
|
|
||||||
monitor.inFullscreen = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_windowsRestacked: function() {
|
_windowsRestacked: function() {
|
||||||
let wasInFullscreen = [];
|
|
||||||
for (let i = 0; i < this.monitors.length; i++)
|
|
||||||
wasInFullscreen[i] = this.monitors[i].inFullscreen;
|
|
||||||
|
|
||||||
let primaryWasInFullscreen = this.primaryMonitor.inFullscreen;
|
|
||||||
|
|
||||||
this._updateFullscreen();
|
|
||||||
|
|
||||||
let changed = false;
|
let changed = false;
|
||||||
for (let i = 0; i < wasInFullscreen.length; i++) {
|
|
||||||
if (wasInFullscreen[i] != this.monitors[i].inFullscreen) {
|
|
||||||
changed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!changed && (this._isPopupWindowVisible != global.top_window_group.get_children().some(isPopupMetaWindow)))
|
if (this._isPopupWindowVisible != global.top_window_group.get_children().some(isPopupMetaWindow))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
this._updateVisibility();
|
this._updateVisibility();
|
||||||
this._queueUpdateRegions();
|
this._queueUpdateRegions();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primaryWasInFullscreen != this.primaryMonitor.inFullscreen) {
|
|
||||||
let windows = this._getWindowActorsForWorkspace(global.screen.get_active_workspace());
|
|
||||||
for (let i = 0; i < windows.length - 1; i++) {
|
|
||||||
let window = windows[i];
|
|
||||||
let metaWindow = window.meta_window;
|
|
||||||
|
|
||||||
// Skip minimized windows
|
|
||||||
if (!metaWindow.showing_on_its_workspace())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Skip windows that aren't on the primary monitor
|
|
||||||
if (!metaWindow.is_on_primary_monitor())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Minimize monitor sized windows
|
|
||||||
if (metaWindow.is_monitor_sized())
|
|
||||||
metaWindow.minimize();
|
|
||||||
}
|
|
||||||
this.emit('primary-fullscreen-changed', this.primaryMonitor.inFullscreen);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateRegions: function() {
|
_updateRegions: function() {
|
||||||
@@ -1067,54 +1048,25 @@ Signals.addSignalMethods(LayoutManager.prototype);
|
|||||||
const HotCorner = new Lang.Class({
|
const HotCorner = new Lang.Class({
|
||||||
Name: 'HotCorner',
|
Name: 'HotCorner',
|
||||||
|
|
||||||
_init : function(layoutManager) {
|
_init : function(layoutManager, monitor, x, y) {
|
||||||
// We use this flag to mark the case where the user has entered the
|
// We use this flag to mark the case where the user has entered the
|
||||||
// hot corner and has not left both the hot corner and a surrounding
|
// hot corner and has not left both the hot corner and a surrounding
|
||||||
// guard area (the "environs"). This avoids triggering the hot corner
|
// guard area (the "environs"). This avoids triggering the hot corner
|
||||||
// multiple times due to an accidental jitter.
|
// multiple times due to an accidental jitter.
|
||||||
this._entered = false;
|
this._entered = false;
|
||||||
|
|
||||||
this.actor = new Clutter.Group({ name: 'hot-corner-environs',
|
this._monitor = monitor;
|
||||||
width: 3,
|
|
||||||
height: 3,
|
|
||||||
reactive: true });
|
|
||||||
|
|
||||||
this._corner = new Clutter.Rectangle({ name: 'hot-corner',
|
this._x = x;
|
||||||
width: 1,
|
this._y = y;
|
||||||
height: 1,
|
|
||||||
opacity: 0,
|
|
||||||
reactive: true });
|
|
||||||
this._corner._delegate = this;
|
|
||||||
|
|
||||||
this.actor.add_actor(this._corner);
|
this._setupFallbackCornerIfNeeded(layoutManager);
|
||||||
|
|
||||||
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
|
this._pressureBarrier = new PressureBarrier(HOT_CORNER_PRESSURE_THRESHOLD,
|
||||||
this._corner.set_position(this.actor.width - this._corner.width, 0);
|
HOT_CORNER_PRESSURE_TIMEOUT,
|
||||||
this.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
|
Shell.KeyBindingMode.NORMAL |
|
||||||
} else {
|
Shell.KeyBindingMode.OVERVIEW);
|
||||||
this._corner.set_position(0, 0);
|
this._pressureBarrier.connect('trigger', Lang.bind(this, this._toggleOverview));
|
||||||
}
|
|
||||||
|
|
||||||
this._activationTime = 0;
|
|
||||||
|
|
||||||
this.actor.connect('leave-event',
|
|
||||||
Lang.bind(this, this._onEnvironsLeft));
|
|
||||||
|
|
||||||
// Clicking on the hot corner environs should result in the
|
|
||||||
// same behavior as clicking on the hot corner.
|
|
||||||
this.actor.connect('button-release-event',
|
|
||||||
Lang.bind(this, this._onCornerClicked));
|
|
||||||
|
|
||||||
// In addition to being triggered by the mouse enter event,
|
|
||||||
// the hot corner can be triggered by clicking on it. This is
|
|
||||||
// useful if the user wants to undo the effect of triggering
|
|
||||||
// the hot corner once in the hot corner.
|
|
||||||
this._corner.connect('enter-event',
|
|
||||||
Lang.bind(this, this._onCornerEntered));
|
|
||||||
this._corner.connect('button-release-event',
|
|
||||||
Lang.bind(this, this._onCornerClicked));
|
|
||||||
this._corner.connect('leave-event',
|
|
||||||
Lang.bind(this, this._onCornerLeft));
|
|
||||||
|
|
||||||
// Cache the three ripples instead of dynamically creating and destroying them.
|
// Cache the three ripples instead of dynamically creating and destroying them.
|
||||||
this._ripple1 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false });
|
this._ripple1 = new St.BoxLayout({ style_class: 'ripple-box', opacity: 0, visible: false });
|
||||||
@@ -1126,8 +1078,74 @@ const HotCorner = new Lang.Class({
|
|||||||
layoutManager.uiGroup.add_actor(this._ripple3);
|
layoutManager.uiGroup.add_actor(this._ripple3);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setBarrierSize: function(size) {
|
||||||
|
if (this._verticalBarrier) {
|
||||||
|
this._pressureBarrier.removeBarrier(this._verticalBarrier);
|
||||||
|
this._verticalBarrier.destroy();
|
||||||
|
this._verticalBarrier = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._horizontalBarrier) {
|
||||||
|
this._pressureBarrier.removeBarrier(this._horizontalBarrier);
|
||||||
|
this._horizontalBarrier.destroy();
|
||||||
|
this._horizontalBarrier = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size > 0) {
|
||||||
|
this._verticalBarrier = new Meta.Barrier({ display: global.display,
|
||||||
|
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
|
||||||
|
directions: Meta.BarrierDirection.POSITIVE_X });
|
||||||
|
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
|
||||||
|
x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
|
||||||
|
directions: Meta.BarrierDirection.POSITIVE_Y });
|
||||||
|
|
||||||
|
this._pressureBarrier.addBarrier(this._verticalBarrier);
|
||||||
|
this._pressureBarrier.addBarrier(this._horizontalBarrier);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_setupFallbackCornerIfNeeded: function(layoutManager) {
|
||||||
|
if (!global.display.supports_extended_barriers()) {
|
||||||
|
this.actor = new Clutter.Actor({ name: 'hot-corner-environs',
|
||||||
|
x: this._x, y: this._y,
|
||||||
|
width: 3,
|
||||||
|
height: 3,
|
||||||
|
reactive: true });
|
||||||
|
|
||||||
|
this._corner = new Clutter.Rectangle({ name: 'hot-corner',
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
opacity: 0,
|
||||||
|
reactive: true });
|
||||||
|
this._corner._delegate = this;
|
||||||
|
|
||||||
|
this.actor.add_child(this._corner);
|
||||||
|
layoutManager.addChrome(this.actor);
|
||||||
|
|
||||||
|
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
|
||||||
|
this._corner.set_position(this.actor.width - this._corner.width, 0);
|
||||||
|
this.actor.set_anchor_point_from_gravity(Clutter.Gravity.NORTH_EAST);
|
||||||
|
} else {
|
||||||
|
this._corner.set_position(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.actor.connect('leave-event',
|
||||||
|
Lang.bind(this, this._onEnvironsLeft));
|
||||||
|
|
||||||
|
this._corner.connect('enter-event',
|
||||||
|
Lang.bind(this, this._onCornerEntered));
|
||||||
|
this._corner.connect('leave-event',
|
||||||
|
Lang.bind(this, this._onCornerLeft));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
this.actor.destroy();
|
this.setBarrierSize(0);
|
||||||
|
this._pressureBarrier.destroy();
|
||||||
|
this._pressureBarrier = null;
|
||||||
|
|
||||||
|
if (this.actor)
|
||||||
|
this.actor.destroy();
|
||||||
},
|
},
|
||||||
|
|
||||||
_animRipple : function(ripple, delay, time, startScale, startOpacity, finalScale) {
|
_animRipple : function(ripple, delay, time, startScale, startOpacity, finalScale) {
|
||||||
@@ -1147,9 +1165,8 @@ const HotCorner = new Lang.Class({
|
|||||||
ripple.opacity = 255 * Math.sqrt(startOpacity);
|
ripple.opacity = 255 * Math.sqrt(startOpacity);
|
||||||
ripple.scale_x = ripple.scale_y = startScale;
|
ripple.scale_x = ripple.scale_y = startScale;
|
||||||
|
|
||||||
let [x, y] = this._corner.get_transformed_position();
|
ripple.x = this._x;
|
||||||
ripple.x = x;
|
ripple.y = this._y;
|
||||||
ripple.y = y;
|
|
||||||
|
|
||||||
Tweener.addTween(ripple, { _opacity: 0,
|
Tweener.addTween(ripple, { _opacity: 0,
|
||||||
scale_x: finalScale,
|
scale_x: finalScale,
|
||||||
@@ -1161,7 +1178,7 @@ const HotCorner = new Lang.Class({
|
|||||||
onComplete: function() { ripple.visible = false; } });
|
onComplete: function() { ripple.visible = false; } });
|
||||||
},
|
},
|
||||||
|
|
||||||
rippleAnimation: function() {
|
_rippleAnimation: function() {
|
||||||
// Show three concentric ripples expanding outwards; the exact
|
// Show three concentric ripples expanding outwards; the exact
|
||||||
// parameters were found by trial and error, so don't look
|
// parameters were found by trial and error, so don't look
|
||||||
// for them to make perfect sense mathematically
|
// for them to make perfect sense mathematically
|
||||||
@@ -1172,14 +1189,21 @@ const HotCorner = new Lang.Class({
|
|||||||
this._animRipple(this._ripple3, 0.35, 1.0, 0.0, 0.3, 1);
|
this._animRipple(this._ripple3, 0.35, 1.0, 0.0, 0.3, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_toggleOverview: function() {
|
||||||
|
if (this._monitor.inFullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Main.overview.shouldToggleByCornerOrButton()) {
|
||||||
|
this._rippleAnimation();
|
||||||
|
Main.overview.toggle();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
handleDragOver: function(source, actor, x, y, time) {
|
handleDragOver: function(source, actor, x, y, time) {
|
||||||
if (source != Main.xdndHandler)
|
if (source != Main.xdndHandler)
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
|
|
||||||
if (!Main.overview.visible && !Main.overview.animationInProgress) {
|
this._toggleOverview();
|
||||||
this.rippleAnimation();
|
|
||||||
Main.overview.showTemporarily();
|
|
||||||
}
|
|
||||||
|
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
},
|
},
|
||||||
@@ -1187,22 +1211,11 @@ const HotCorner = new Lang.Class({
|
|||||||
_onCornerEntered : function() {
|
_onCornerEntered : function() {
|
||||||
if (!this._entered) {
|
if (!this._entered) {
|
||||||
this._entered = true;
|
this._entered = true;
|
||||||
if (!Main.overview.animationInProgress) {
|
this._toggleOverview();
|
||||||
this._activationTime = Date.now() / 1000;
|
|
||||||
|
|
||||||
this.rippleAnimation();
|
|
||||||
Main.overview.toggle();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onCornerClicked : function() {
|
|
||||||
if (this.shouldToggleOverviewOnClick())
|
|
||||||
Main.overview.toggle();
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_onCornerLeft : function(actor, event) {
|
_onCornerLeft : function(actor, event) {
|
||||||
if (event.get_related() != this.actor)
|
if (event.get_related() != this.actor)
|
||||||
this._entered = false;
|
this._entered = false;
|
||||||
@@ -1214,42 +1227,47 @@ const HotCorner = new Lang.Class({
|
|||||||
if (event.get_related() != this._corner)
|
if (event.get_related() != this._corner)
|
||||||
this._entered = false;
|
this._entered = false;
|
||||||
return false;
|
return false;
|
||||||
},
|
|
||||||
|
|
||||||
// Checks if the Activities button is currently sensitive to
|
|
||||||
// clicks. The first call to this function within the
|
|
||||||
// HOT_CORNER_ACTIVATION_TIMEOUT time of the hot corner being
|
|
||||||
// triggered will return false. This avoids opening and closing
|
|
||||||
// the overview if the user both triggered the hot corner and
|
|
||||||
// clicked the Activities button.
|
|
||||||
shouldToggleOverviewOnClick: function() {
|
|
||||||
if (Main.overview.animationInProgress)
|
|
||||||
return false;
|
|
||||||
if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > HOT_CORNER_ACTIVATION_TIMEOUT)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const PressureBarrier = new Lang.Class({
|
const PressureBarrier = new Lang.Class({
|
||||||
Name: 'PressureBarrier',
|
Name: 'PressureBarrier',
|
||||||
|
|
||||||
_init: function(barrier, threshold, timeout) {
|
_init: function(threshold, timeout, keybindingMode) {
|
||||||
this._barrier = barrier;
|
|
||||||
this._threshold = threshold;
|
this._threshold = threshold;
|
||||||
this._timeout = timeout;
|
this._timeout = timeout;
|
||||||
this._orientation = (barrier.y1 == barrier.y2) ? Clutter.Orientation.HORIZONTAL : Clutter.Orientation.VERTICAL;
|
this._keybindingMode = keybindingMode;
|
||||||
|
this._barriers = [];
|
||||||
|
this._eventFilter = null;
|
||||||
|
|
||||||
|
this._isTriggered = false;
|
||||||
this._reset();
|
this._reset();
|
||||||
|
},
|
||||||
|
|
||||||
this._barrierHitId = this._barrier.connect('hit', Lang.bind(this, this._onBarrierHit));
|
addBarrier: function(barrier) {
|
||||||
this._barrierLeftId = this._barrier.connect('left', Lang.bind(this, this._onBarrierLeft));
|
barrier._pressureHitId = barrier.connect('hit', Lang.bind(this, this._onBarrierHit));
|
||||||
|
barrier._pressureLeftId = barrier.connect('left', Lang.bind(this, this._onBarrierLeft));
|
||||||
|
|
||||||
|
this._barriers.push(barrier);
|
||||||
|
},
|
||||||
|
|
||||||
|
_disconnectBarrier: function(barrier) {
|
||||||
|
barrier.disconnect(barrier._pressureHitId);
|
||||||
|
barrier.disconnect(barrier._pressureLeftId);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeBarrier: function(barrier) {
|
||||||
|
this._disconnectBarrier(barrier);
|
||||||
|
this._barriers.splice(this._barriers.indexOf(barrier), 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
this._barrier.disconnect(this._barrierHitId);
|
this._barriers.forEach(Lang.bind(this, this._disconnectBarrier));
|
||||||
this._barrier.disconnect(this._barrierLeftId);
|
this._barriers = [];
|
||||||
this._barrier = null;
|
},
|
||||||
|
|
||||||
|
setEventFilter: function(filter) {
|
||||||
|
this._eventFilter = filter;
|
||||||
},
|
},
|
||||||
|
|
||||||
_reset: function() {
|
_reset: function() {
|
||||||
@@ -1258,33 +1276,34 @@ const PressureBarrier = new Lang.Class({
|
|||||||
this._lastTime = 0;
|
this._lastTime = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
_getDistanceAcrossBarrier: function(event) {
|
_isHorizontal: function(barrier) {
|
||||||
if (this._orientation == Clutter.Orientation.HORIZONTAL)
|
return barrier.y1 == barrier.y2;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getDistanceAcrossBarrier: function(barrier, event) {
|
||||||
|
if (this._isHorizontal(barrier))
|
||||||
return Math.abs(event.dy);
|
return Math.abs(event.dy);
|
||||||
else
|
else
|
||||||
return Math.abs(event.dx);
|
return Math.abs(event.dx);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getDistanceAlongBarrier: function(event) {
|
_getDistanceAlongBarrier: function(barrier, event) {
|
||||||
if (this._orientation == Clutter.Orientation.HORIZONTAL)
|
if (this._isHorizontal(barrier))
|
||||||
return Math.abs(event.dx);
|
return Math.abs(event.dx);
|
||||||
else
|
else
|
||||||
return Math.abs(event.dy);
|
return Math.abs(event.dy);
|
||||||
},
|
},
|
||||||
|
|
||||||
_isBarrierEventTooOld: function(event) {
|
|
||||||
// Ignore all events older than this time
|
|
||||||
let threshold = this._lastTime - this._timeout;
|
|
||||||
return event.time < threshold;
|
|
||||||
},
|
|
||||||
|
|
||||||
_trimBarrierEvents: function() {
|
_trimBarrierEvents: function() {
|
||||||
// Events are guaranteed to be sorted in time order from
|
// Events are guaranteed to be sorted in time order from
|
||||||
// oldest to newest, so just look for the first old event,
|
// oldest to newest, so just look for the first old event,
|
||||||
// and then chop events after that off.
|
// and then chop events after that off.
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
let threshold = this._lastTime - this._timeout;
|
||||||
|
|
||||||
while (i < this._barrierEvents.length) {
|
while (i < this._barrierEvents.length) {
|
||||||
if (!this._isBarrierEventTooOld(this._barrierEvents[i]))
|
let [time, distance] = this._barrierEvents[i];
|
||||||
|
if (time >= threshold)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -1292,7 +1311,8 @@ const PressureBarrier = new Lang.Class({
|
|||||||
let firstNewEvent = i;
|
let firstNewEvent = i;
|
||||||
|
|
||||||
for (i = 0; i < firstNewEvent; i++) {
|
for (i = 0; i < firstNewEvent; i++) {
|
||||||
this._currentPressure -= this._getDistanceAcrossBarrier(this._barrierEvents[i]);
|
let [time, distance] = this._barrierEvents[i];
|
||||||
|
this._currentPressure -= distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._barrierEvents = this._barrierEvents.slice(firstNewEvent);
|
this._barrierEvents = this._barrierEvents.slice(firstNewEvent);
|
||||||
@@ -1300,24 +1320,35 @@ const PressureBarrier = new Lang.Class({
|
|||||||
|
|
||||||
_onBarrierLeft: function(barrier, event) {
|
_onBarrierLeft: function(barrier, event) {
|
||||||
this._reset();
|
this._reset();
|
||||||
|
this._isTriggered = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_trigger: function() {
|
||||||
|
this._isTriggered = true;
|
||||||
|
this.emit('trigger');
|
||||||
|
this._reset();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onBarrierHit: function(barrier, event) {
|
_onBarrierHit: function(barrier, event) {
|
||||||
// Throw out all events where the pointer was grabbed by another
|
// If we've triggered the barrier, wait until the pointer has the
|
||||||
// client, as the client that grabbed the pointer expects to have
|
// left the barrier hitbox until we trigger it again.
|
||||||
// complete control over it
|
if (this._isTriggered)
|
||||||
if (event.grabbed && Main.modalCount == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let isOverview = ((Main.keybindingMode & (Shell.KeyBindingMode.OVERVIEW)) != 0);
|
if (this._eventFilter && this._eventFilter(event))
|
||||||
|
|
||||||
// Throw out events where the grab is taken by something that's
|
|
||||||
// not the overview (modal dialogs, etc.)
|
|
||||||
if (event.grabbed && !isOverview)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let slide = this._getDistanceAlongBarrier(event);
|
// Throw out all events not in the proper keybinding mode
|
||||||
let distance = this._getDistanceAcrossBarrier(event);
|
if (!(this._keybindingMode & Main.keybindingMode))
|
||||||
|
return;
|
||||||
|
|
||||||
|
let slide = this._getDistanceAlongBarrier(barrier, event);
|
||||||
|
let distance = this._getDistanceAcrossBarrier(barrier, event);
|
||||||
|
|
||||||
|
if (distance >= this._threshold) {
|
||||||
|
this._trigger();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Throw out events where the cursor is move more
|
// Throw out events where the cursor is move more
|
||||||
// along the axis of the barrier than moving with
|
// along the axis of the barrier than moving with
|
||||||
@@ -1328,13 +1359,13 @@ const PressureBarrier = new Lang.Class({
|
|||||||
this._lastTime = event.time;
|
this._lastTime = event.time;
|
||||||
|
|
||||||
this._trimBarrierEvents();
|
this._trimBarrierEvents();
|
||||||
this._barrierEvents.push(event);
|
distance = Math.min(15, distance);
|
||||||
|
|
||||||
|
this._barrierEvents.push([event.time, distance]);
|
||||||
this._currentPressure += distance;
|
this._currentPressure += distance;
|
||||||
|
|
||||||
if (this._currentPressure >= this._threshold) {
|
if (this._currentPressure >= this._threshold)
|
||||||
this.emit('trigger');
|
this._trigger();
|
||||||
this._reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(PressureBarrier.prototype);
|
Signals.addSignalMethods(PressureBarrier.prototype);
|
||||||
|
|||||||
@@ -685,7 +685,8 @@ const Memory = new Lang.Class({
|
|||||||
const Extensions = new Lang.Class({
|
const Extensions = new Lang.Class({
|
||||||
Name: 'Extensions',
|
Name: 'Extensions',
|
||||||
|
|
||||||
_init: function() {
|
_init: function(lookingGlass) {
|
||||||
|
this._lookingGlass = lookingGlass;
|
||||||
this.actor = new St.BoxLayout({ vertical: true,
|
this.actor = new St.BoxLayout({ vertical: true,
|
||||||
name: 'lookingGlassExtensions' });
|
name: 'lookingGlassExtensions' });
|
||||||
this._noExtensions = new St.Label({ style_class: 'lg-extensions-none',
|
this._noExtensions = new St.Label({ style_class: 'lg-extensions-none',
|
||||||
@@ -912,7 +913,7 @@ const LookingGlass = new Lang.Class({
|
|||||||
this._memory = new Memory();
|
this._memory = new Memory();
|
||||||
notebook.appendPage('Memory', this._memory.actor);
|
notebook.appendPage('Memory', this._memory.actor);
|
||||||
|
|
||||||
this._extensions = new Extensions();
|
this._extensions = new Extensions(this);
|
||||||
notebook.appendPage('Extensions', this._extensions.actor);
|
notebook.appendPage('Extensions', this._extensions.actor);
|
||||||
|
|
||||||
this._entry.clutter_text.connect('activate', Lang.bind(this, function (o, e) {
|
this._entry.clutter_text.connect('activate', Lang.bind(this, function (o, e) {
|
||||||
|
|||||||
@@ -18,11 +18,13 @@ const ExtensionSystem = imports.ui.extensionSystem;
|
|||||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||||
const Keyboard = imports.ui.keyboard;
|
const Keyboard = imports.ui.keyboard;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
|
const OsdWindow = imports.ui.osdWindow;
|
||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
const Panel = imports.ui.panel;
|
const Panel = imports.ui.panel;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
const RunDialog = imports.ui.runDialog;
|
const RunDialog = imports.ui.runDialog;
|
||||||
const Layout = imports.ui.layout;
|
const Layout = imports.ui.layout;
|
||||||
|
const LoginManager = imports.misc.loginManager;
|
||||||
const LookingGlass = imports.ui.lookingGlass;
|
const LookingGlass = imports.ui.lookingGlass;
|
||||||
const NotificationDaemon = imports.ui.notificationDaemon;
|
const NotificationDaemon = imports.ui.notificationDaemon;
|
||||||
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
||||||
@@ -31,7 +33,6 @@ const Scripting = imports.ui.scripting;
|
|||||||
const SessionMode = imports.ui.sessionMode;
|
const SessionMode = imports.ui.sessionMode;
|
||||||
const ShellDBus = imports.ui.shellDBus;
|
const ShellDBus = imports.ui.shellDBus;
|
||||||
const ShellMountOperation = imports.ui.shellMountOperation;
|
const ShellMountOperation = imports.ui.shellMountOperation;
|
||||||
const UnlockDialog = imports.ui.unlockDialog;
|
|
||||||
const WindowManager = imports.ui.windowManager;
|
const WindowManager = imports.ui.windowManager;
|
||||||
const Magnifier = imports.ui.magnifier;
|
const Magnifier = imports.ui.magnifier;
|
||||||
const XdndHandler = imports.ui.xdndHandler;
|
const XdndHandler = imports.ui.xdndHandler;
|
||||||
@@ -51,12 +52,13 @@ let screenShield = null;
|
|||||||
let notificationDaemon = null;
|
let notificationDaemon = null;
|
||||||
let windowAttentionHandler = null;
|
let windowAttentionHandler = null;
|
||||||
let ctrlAltTabManager = null;
|
let ctrlAltTabManager = null;
|
||||||
|
let osdWindow = null;
|
||||||
let sessionMode = null;
|
let sessionMode = null;
|
||||||
let shellDBusService = null;
|
let shellDBusService = null;
|
||||||
let shellMountOpDBusService = null;
|
let shellMountOpDBusService = null;
|
||||||
let screenSaverDBus = null;
|
let screenSaverDBus = null;
|
||||||
let modalCount = 0;
|
let modalCount = 0;
|
||||||
let keybindingMode = Shell.KeyBindingMode.NORMAL;
|
let keybindingMode = Shell.KeyBindingMode.NONE;
|
||||||
let modalActorFocusStack = [];
|
let modalActorFocusStack = [];
|
||||||
let uiGroup = null;
|
let uiGroup = null;
|
||||||
let magnifier = null;
|
let magnifier = null;
|
||||||
@@ -69,6 +71,8 @@ let _cssStylesheet = null;
|
|||||||
let _overridesSettings = null;
|
let _overridesSettings = null;
|
||||||
|
|
||||||
function _sessionUpdated() {
|
function _sessionUpdated() {
|
||||||
|
_loadDefaultStylesheet();
|
||||||
|
|
||||||
wm.setCustomKeybindingHandler('panel-main-menu',
|
wm.setCustomKeybindingHandler('panel-main-menu',
|
||||||
Shell.KeyBindingMode.NORMAL |
|
Shell.KeyBindingMode.NORMAL |
|
||||||
Shell.KeyBindingMode.OVERVIEW,
|
Shell.KeyBindingMode.OVERVIEW,
|
||||||
@@ -80,8 +84,9 @@ function _sessionUpdated() {
|
|||||||
Shell.KeyBindingMode.NORMAL |
|
Shell.KeyBindingMode.NORMAL |
|
||||||
Shell.KeyBindingMode.OVERVIEW,
|
Shell.KeyBindingMode.OVERVIEW,
|
||||||
sessionMode.hasRunDialog ? openRunDialog : null);
|
sessionMode.hasRunDialog ? openRunDialog : null);
|
||||||
if (sessionMode.isGreeter)
|
|
||||||
screenShield.showDialog();
|
if (!sessionMode.hasRunDialog && lookingGlass)
|
||||||
|
lookingGlass.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
@@ -95,20 +100,21 @@ function start() {
|
|||||||
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
||||||
|
|
||||||
sessionMode = new SessionMode.SessionMode();
|
sessionMode = new SessionMode.SessionMode();
|
||||||
|
sessionMode.connect('sessions-loaded', _sessionsLoaded);
|
||||||
// start session after we know what mode we're running in
|
sessionMode.init();
|
||||||
let signalId = sessionMode.connect('updated', function() {
|
|
||||||
sessionMode.disconnect(signalId);
|
|
||||||
startSession();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function startSession() {
|
function _sessionsLoaded() {
|
||||||
sessionMode.connect('updated', _loadDefaultStylesheet);
|
sessionMode.connect('updated', _sessionUpdated);
|
||||||
|
_initializeUI();
|
||||||
|
|
||||||
shellDBusService = new ShellDBus.GnomeShell();
|
shellDBusService = new ShellDBus.GnomeShell();
|
||||||
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
|
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
|
||||||
|
|
||||||
|
_sessionUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _initializeUI() {
|
||||||
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
||||||
// also initialize ShellAppSystem first. ShellAppSystem
|
// also initialize ShellAppSystem first. ShellAppSystem
|
||||||
// needs to load all the .desktop files, and ShellWindowTracker
|
// needs to load all the .desktop files, and ShellWindowTracker
|
||||||
@@ -134,16 +140,13 @@ function startSession() {
|
|||||||
|
|
||||||
xdndHandler = new XdndHandler.XdndHandler();
|
xdndHandler = new XdndHandler.XdndHandler();
|
||||||
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
||||||
|
osdWindow = new OsdWindow.OsdWindow();
|
||||||
overview = new Overview.Overview();
|
overview = new Overview.Overview();
|
||||||
wm = new WindowManager.WindowManager();
|
wm = new WindowManager.WindowManager();
|
||||||
magnifier = new Magnifier.Magnifier();
|
magnifier = new Magnifier.Magnifier();
|
||||||
if (UnlockDialog.isSupported())
|
if (LoginManager.canLock())
|
||||||
screenShield = new ScreenShield.ScreenShield();
|
screenShield = new ScreenShield.ScreenShield();
|
||||||
else
|
|
||||||
screenShield = new ScreenShield.ScreenShieldFallback();
|
|
||||||
|
|
||||||
// The message tray relies on being constructed
|
|
||||||
// after the panel.
|
|
||||||
panel = new Panel.Panel();
|
panel = new Panel.Panel();
|
||||||
messageTray = new MessageTray.MessageTray();
|
messageTray = new MessageTray.MessageTray();
|
||||||
keyboard = new Keyboard.Keyboard();
|
keyboard = new Keyboard.Keyboard();
|
||||||
@@ -152,19 +155,19 @@ function startSession() {
|
|||||||
componentManager = new Components.ComponentManager();
|
componentManager = new Components.ComponentManager();
|
||||||
|
|
||||||
layoutManager.init();
|
layoutManager.init();
|
||||||
layoutManager.prepareStartupAnimation();
|
|
||||||
overview.init();
|
overview.init();
|
||||||
|
|
||||||
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
|
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
|
||||||
false, -1, 1);
|
false, -1, 1);
|
||||||
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
|
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
|
||||||
sessionMode.connect('updated', _sessionUpdated);
|
|
||||||
_sessionUpdated();
|
|
||||||
|
|
||||||
// Provide the bus object for gnome-session to
|
// Provide the bus object for gnome-session to
|
||||||
// initiate logouts.
|
// initiate logouts.
|
||||||
EndSessionDialog.init();
|
EndSessionDialog.init();
|
||||||
|
|
||||||
|
// We're ready for the session manager to move to the next phase
|
||||||
|
Meta.register_with_session();
|
||||||
|
|
||||||
_startDate = new Date();
|
_startDate = new Date();
|
||||||
|
|
||||||
log('GNOME Shell started at ' + _startDate);
|
log('GNOME Shell started at ' + _startDate);
|
||||||
@@ -190,13 +193,17 @@ function startSession() {
|
|||||||
ExtensionDownloader.init();
|
ExtensionDownloader.init();
|
||||||
ExtensionSystem.init();
|
ExtensionSystem.init();
|
||||||
|
|
||||||
// Run the startup animation as soon as the mainloop is idle enough.
|
if (sessionMode.isGreeter && screenShield) {
|
||||||
// This is necessary to have it smooth and without interruptions from
|
layoutManager.connect('startup-prepared', function() {
|
||||||
// completed IO tasks
|
screenShield.showDialog();
|
||||||
GLib.idle_add(GLib.PRIORITY_LOW, function() {
|
});
|
||||||
layoutManager.startupAnimation();
|
}
|
||||||
return false;
|
|
||||||
});
|
layoutManager.connect('startup-complete', function() {
|
||||||
|
if (keybindingMode == Shell.KeyBindingMode.NONE) {
|
||||||
|
keybindingMode = Shell.KeyBindingMode.NORMAL;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let _workspaces = [];
|
let _workspaces = [];
|
||||||
|
|||||||
@@ -1153,6 +1153,11 @@ const Source = new Lang.Class({
|
|||||||
return this.notifications.length;
|
return this.notifications.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get indicatorCount() {
|
||||||
|
let notifications = this.notifications.filter(function(n) { return !n.isTransient && !n.resident; });
|
||||||
|
return notifications.length;
|
||||||
|
},
|
||||||
|
|
||||||
get unseenCount() {
|
get unseenCount() {
|
||||||
return this.notifications.filter(function(n) { return !n.acknowledged; }).length;
|
return this.notifications.filter(function(n) { return !n.acknowledged; }).length;
|
||||||
},
|
},
|
||||||
@@ -1586,17 +1591,13 @@ const MessageTray = new Lang.Class({
|
|||||||
global.focus_manager.add_group(this.actor);
|
global.focus_manager.add_group(this.actor);
|
||||||
this._summary = new St.BoxLayout({ style_class: 'message-tray-summary',
|
this._summary = new St.BoxLayout({ style_class: 'message-tray-summary',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
track_hover: true,
|
|
||||||
x_align: Clutter.ActorAlign.END,
|
x_align: Clutter.ActorAlign.END,
|
||||||
x_expand: true,
|
x_expand: true,
|
||||||
y_align: Clutter.ActorAlign.CENTER,
|
y_align: Clutter.ActorAlign.CENTER,
|
||||||
y_expand: true });
|
y_expand: true });
|
||||||
this._summary.connect('notify::hover', Lang.bind(this, this._onSummaryHoverChanged));
|
|
||||||
this.actor.add_actor(this._summary);
|
this.actor.add_actor(this._summary);
|
||||||
this._summary.opacity = 0;
|
|
||||||
|
|
||||||
this._summaryMotionId = 0;
|
this._summaryMotionId = 0;
|
||||||
this._trayMotionId = 0;
|
|
||||||
|
|
||||||
this._summaryBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
|
this._summaryBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
|
||||||
{ reactive: true,
|
{ reactive: true,
|
||||||
@@ -1631,15 +1632,22 @@ const MessageTray = new Lang.Class({
|
|||||||
Main.layoutManager.connect('keyboard-visible-changed', Lang.bind(this, this._onKeyboardVisibleChanged));
|
Main.layoutManager.connect('keyboard-visible-changed', Lang.bind(this, this._onKeyboardVisibleChanged));
|
||||||
|
|
||||||
this._trayState = State.HIDDEN;
|
this._trayState = State.HIDDEN;
|
||||||
this._locked = false;
|
|
||||||
this._traySummoned = false;
|
this._traySummoned = false;
|
||||||
this._useLongerTrayLeftTimeout = false;
|
this._useLongerTrayLeftTimeout = false;
|
||||||
this._trayLeftTimeoutId = 0;
|
this._trayLeftTimeoutId = 0;
|
||||||
|
|
||||||
|
// pointerInTray is sort of a misnomer -- it tracks whether
|
||||||
|
// a message tray notification should expand. The value is
|
||||||
|
// partially driven by the hover state of the tray, but has
|
||||||
|
// a lot of complex state related to timeouts and the current
|
||||||
|
// state of the pointer when a notification pops up.
|
||||||
this._pointerInTray = false;
|
this._pointerInTray = false;
|
||||||
this._pointerInKeyboard = false;
|
|
||||||
|
// This tracks this.actor.hover and is used to fizzle
|
||||||
|
// out non-changing hover notifications in onTrayHoverChanged.
|
||||||
|
this._trayHovered = false;
|
||||||
|
|
||||||
this._keyboardVisible = false;
|
this._keyboardVisible = false;
|
||||||
this._summaryState = State.HIDDEN;
|
|
||||||
this._pointerInSummary = false;
|
|
||||||
this._notificationClosed = false;
|
this._notificationClosed = false;
|
||||||
this._notificationState = State.HIDDEN;
|
this._notificationState = State.HIDDEN;
|
||||||
this._notificationTimeoutId = 0;
|
this._notificationTimeoutId = 0;
|
||||||
@@ -1661,20 +1669,18 @@ const MessageTray = new Lang.Class({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Main.layoutManager.trayBox.add_actor(this.actor);
|
Main.layoutManager.trayBox.add_actor(this.actor);
|
||||||
this.actor.y = 0;
|
|
||||||
Main.layoutManager.trackChrome(this.actor);
|
Main.layoutManager.trackChrome(this.actor);
|
||||||
Main.layoutManager.trackChrome(this._notificationWidget);
|
Main.layoutManager.trackChrome(this._notificationWidget);
|
||||||
Main.layoutManager.trackChrome(this._closeButton);
|
Main.layoutManager.trackChrome(this._closeButton);
|
||||||
|
|
||||||
Main.layoutManager.connect('primary-fullscreen-changed', Lang.bind(this, this._onFullscreenChanged));
|
Main.layoutManager.connect('fullscreen-changed', Lang.bind(this, this._updateState));
|
||||||
|
Main.layoutManager.connect('hot-corners-changed', Lang.bind(this, this._hotCornersChanged));
|
||||||
|
|
||||||
// If the overview shows or hides while we're in
|
// If the overview shows or hides while we're in
|
||||||
// the message tray, revert back to normal mode.
|
// the message tray, revert back to normal mode.
|
||||||
Main.overview.connect('showing', Lang.bind(this, this._escapeTray));
|
Main.overview.connect('showing', Lang.bind(this, this._escapeTray));
|
||||||
Main.overview.connect('hiding', Lang.bind(this, this._escapeTray));
|
Main.overview.connect('hiding', Lang.bind(this, this._escapeTray));
|
||||||
|
|
||||||
// Track if we've added the activities button
|
|
||||||
this._activitiesButtonAdded = false;
|
|
||||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||||
|
|
||||||
Main.wm.addKeybinding('toggle-message-tray',
|
Main.wm.addKeybinding('toggle-message-tray',
|
||||||
@@ -1695,8 +1701,10 @@ const MessageTray = new Lang.Class({
|
|||||||
this._sources = new Hash.Map();
|
this._sources = new Hash.Map();
|
||||||
this._chatSummaryItemsCount = 0;
|
this._chatSummaryItemsCount = 0;
|
||||||
|
|
||||||
|
this._trayDwellTimeoutId = 0;
|
||||||
this._setupTrayDwellIfNeeded();
|
this._setupTrayDwellIfNeeded();
|
||||||
this._sessionUpdated();
|
this._sessionUpdated();
|
||||||
|
this._hotCornersChanged();
|
||||||
|
|
||||||
this._noMessages = new St.Label({ text: _("No Messages"),
|
this._noMessages = new St.Label({ text: _("No Messages"),
|
||||||
style_class: 'no-messages-label',
|
style_class: 'no-messages-label',
|
||||||
@@ -1737,13 +1745,11 @@ const MessageTray = new Lang.Class({
|
|||||||
|
|
||||||
_openContextMenu: function () {
|
_openContextMenu: function () {
|
||||||
let [x, y, mask] = global.get_pointer();
|
let [x, y, mask] = global.get_pointer();
|
||||||
this._lock();
|
|
||||||
this._contextMenu.setPosition(Math.round(x), Math.round(y));
|
this._contextMenu.setPosition(Math.round(x), Math.round(y));
|
||||||
this._grabHelper.grab({ actor: this._contextMenu.actor,
|
this._grabHelper.grab({ actor: this._contextMenu.actor,
|
||||||
grabFocus: true,
|
grabFocus: true,
|
||||||
onUngrab: Lang.bind(this, function () {
|
onUngrab: Lang.bind(this, function () {
|
||||||
this._contextMenu.close(BoxPointer.PopupAnimation.FULL);
|
this._contextMenu.close(BoxPointer.PopupAnimation.FULL);
|
||||||
this._unlock();
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
this._contextMenu.open(BoxPointer.PopupAnimation.FULL);
|
this._contextMenu.open(BoxPointer.PopupAnimation.FULL);
|
||||||
@@ -1759,7 +1765,6 @@ const MessageTray = new Lang.Class({
|
|||||||
if (!global.display.supports_extended_barriers()) {
|
if (!global.display.supports_extended_barriers()) {
|
||||||
let pointerWatcher = PointerWatcher.getPointerWatcher();
|
let pointerWatcher = PointerWatcher.getPointerWatcher();
|
||||||
pointerWatcher.addWatch(TRAY_DWELL_CHECK_INTERVAL, Lang.bind(this, this._checkTrayDwell));
|
pointerWatcher.addWatch(TRAY_DWELL_CHECK_INTERVAL, Lang.bind(this, this._checkTrayDwell));
|
||||||
this._trayDwellTimeoutId = 0;
|
|
||||||
this._trayDwelling = false;
|
this._trayDwelling = false;
|
||||||
this._trayDwellUserTime = 0;
|
this._trayDwellUserTime = 0;
|
||||||
}
|
}
|
||||||
@@ -1770,11 +1775,6 @@ const MessageTray = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_sessionUpdated: function() {
|
_sessionUpdated: function() {
|
||||||
if (!this._activitiesButtonAdded && Main.panel.statusArea.activities) {
|
|
||||||
this._activitiesButtonAdded = true;
|
|
||||||
this._grabHelper.addActor(Main.panel.statusArea.activities.hotCorner.actor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Main.sessionMode.isLocked || Main.sessionMode.isGreeter) && this._inCtrlAltTab) {
|
if ((Main.sessionMode.isLocked || Main.sessionMode.isGreeter) && this._inCtrlAltTab) {
|
||||||
Main.ctrlAltTabManager.removeGroup(this._summary);
|
Main.ctrlAltTabManager.removeGroup(this._summary);
|
||||||
this._inCtrlAltTab = false;
|
this._inCtrlAltTab = false;
|
||||||
@@ -1823,6 +1823,9 @@ const MessageTray = new Lang.Class({
|
|||||||
_trayDwellTimeout: function() {
|
_trayDwellTimeout: function() {
|
||||||
this._trayDwellTimeoutId = 0;
|
this._trayDwellTimeoutId = 0;
|
||||||
|
|
||||||
|
if (Main.layoutManager.bottomMonitor.inFullscreen)
|
||||||
|
return false;
|
||||||
|
|
||||||
// We don't want to open the tray when a modal dialog
|
// We don't want to open the tray when a modal dialog
|
||||||
// is up, so we check the modal count for that. When we are in the
|
// is up, so we check the modal count for that. When we are in the
|
||||||
// overview we have to take the overview's modal push into account
|
// overview we have to take the overview's modal push into account
|
||||||
@@ -1994,18 +1997,6 @@ const MessageTray = new Lang.Class({
|
|||||||
this._notificationQueue.splice(index, 1);
|
this._notificationQueue.splice(index, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
_lock: function() {
|
|
||||||
this._locked = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
_unlock: function() {
|
|
||||||
if (!this._locked)
|
|
||||||
return;
|
|
||||||
this._locked = false;
|
|
||||||
this._pointerInTray = this.actor.hover;
|
|
||||||
this._updateState();
|
|
||||||
},
|
|
||||||
|
|
||||||
openTray: function() {
|
openTray: function() {
|
||||||
if (Main.overview.animationInProgress)
|
if (Main.overview.animationInProgress)
|
||||||
return;
|
return;
|
||||||
@@ -2031,7 +2022,6 @@ const MessageTray = new Lang.Class({
|
|||||||
hide: function() {
|
hide: function() {
|
||||||
this._traySummoned = false;
|
this._traySummoned = false;
|
||||||
this.actor.set_hover(false);
|
this.actor.set_hover(false);
|
||||||
this._summary.set_hover(false);
|
|
||||||
this._updateState();
|
this._updateState();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -2091,13 +2081,19 @@ const MessageTray = new Lang.Class({
|
|||||||
this._updateState();
|
this._updateState();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onSummaryHoverChanged: function() {
|
_hotCornersChanged: function() {
|
||||||
this._pointerInSummary = this._summary.hover;
|
let primary = Main.layoutManager.primaryIndex;
|
||||||
this._updateState();
|
let corner = Main.layoutManager.hotCorners[primary];
|
||||||
|
if (corner && corner.actor)
|
||||||
|
this._grabHelper.addActor(corner.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onTrayHoverChanged: function() {
|
_onTrayHoverChanged: function() {
|
||||||
if (this.actor.hover) {
|
if (this.actor.hover == this._trayHovered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._trayHovered = this.actor.hover;
|
||||||
|
if (this._trayHovered) {
|
||||||
// No dwell inside notifications at the bottom of the screen
|
// No dwell inside notifications at the bottom of the screen
|
||||||
this._cancelTrayDwell();
|
this._cancelTrayDwell();
|
||||||
|
|
||||||
@@ -2105,13 +2101,6 @@ const MessageTray = new Lang.Class({
|
|||||||
if (this._trayState == State.HIDDEN && this._notificationState == State.HIDDEN)
|
if (this._trayState == State.HIDDEN && this._notificationState == State.HIDDEN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't do anything if this._useLongerTrayLeftTimeout is true, meaning the notification originally
|
|
||||||
// popped up under the pointer, but this._trayLeftTimeoutId is 0, meaning the pointer didn't leave
|
|
||||||
// the tray yet. We need to check for this case because sometimes _onTrayHoverChanged() gets called
|
|
||||||
// multiple times while this.actor.hover is true.
|
|
||||||
if (this._useLongerTrayLeftTimeout && !this._trayLeftTimeoutId)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._useLongerTrayLeftTimeout = false;
|
this._useLongerTrayLeftTimeout = false;
|
||||||
if (this._trayLeftTimeoutId) {
|
if (this._trayLeftTimeoutId) {
|
||||||
Mainloop.source_remove(this._trayLeftTimeoutId);
|
Mainloop.source_remove(this._trayLeftTimeoutId);
|
||||||
@@ -2160,11 +2149,6 @@ const MessageTray = new Lang.Class({
|
|||||||
this._updateState();
|
this._updateState();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onFullscreenChanged: function(obj, state) {
|
|
||||||
this._inFullscreen = state;
|
|
||||||
this._updateState();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onStatusChanged: function(status) {
|
_onStatusChanged: function(status) {
|
||||||
if (status == GnomeSession.PresenceStatus.BUSY) {
|
if (status == GnomeSession.PresenceStatus.BUSY) {
|
||||||
// remove notification and allow the summary to be closed now
|
// remove notification and allow the summary to be closed now
|
||||||
@@ -2196,7 +2180,6 @@ const MessageTray = new Lang.Class({
|
|||||||
this._trayLeftTimeoutId = 0;
|
this._trayLeftTimeoutId = 0;
|
||||||
this._useLongerTrayLeftTimeout = false;
|
this._useLongerTrayLeftTimeout = false;
|
||||||
this._pointerInTray = false;
|
this._pointerInTray = false;
|
||||||
this._pointerInSummary = false;
|
|
||||||
this._updateNotificationTimeout(0);
|
this._updateNotificationTimeout(0);
|
||||||
this._updateState();
|
this._updateState();
|
||||||
}
|
}
|
||||||
@@ -2204,9 +2187,7 @@ const MessageTray = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_escapeTray: function() {
|
_escapeTray: function() {
|
||||||
this._unlock();
|
|
||||||
this._pointerInTray = false;
|
this._pointerInTray = false;
|
||||||
this._pointerInSummary = false;
|
|
||||||
this._traySummoned = false;
|
this._traySummoned = false;
|
||||||
this._setClickedSummaryItem(null);
|
this._setClickedSummaryItem(null);
|
||||||
this._updateNotificationTimeout(0);
|
this._updateNotificationTimeout(0);
|
||||||
@@ -2215,7 +2196,7 @@ const MessageTray = new Lang.Class({
|
|||||||
|
|
||||||
// All of the logic for what happens when occurs here; the various
|
// All of the logic for what happens when occurs here; the various
|
||||||
// event handlers merely update variables such as
|
// event handlers merely update variables such as
|
||||||
// 'this._pointerInTray', 'this._summaryState', etc, and
|
// 'this._pointerInTray', 'this._traySummoned', etc, and
|
||||||
// _updateState() figures out what (if anything) needs to be done
|
// _updateState() figures out what (if anything) needs to be done
|
||||||
// at the present time.
|
// at the present time.
|
||||||
_updateState: function() {
|
_updateState: function() {
|
||||||
@@ -2223,25 +2204,22 @@ const MessageTray = new Lang.Class({
|
|||||||
let notificationQueue = this._notificationQueue;
|
let notificationQueue = this._notificationQueue;
|
||||||
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
|
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
|
||||||
let notificationForFeedback = notificationQueue.length > 0 && notificationQueue[0].forFeedback;
|
let notificationForFeedback = notificationQueue.length > 0 && notificationQueue[0].forFeedback;
|
||||||
let notificationsLimited = this._busy || this._inFullscreen;
|
let notificationsLimited = this._busy || Main.layoutManager.bottomMonitor.inFullscreen;
|
||||||
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent || notificationForFeedback) && Main.sessionMode.hasNotifications;
|
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent || notificationForFeedback) && Main.sessionMode.hasNotifications;
|
||||||
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
|
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
|
||||||
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
let notificationPinned = this._pointerInTray && !this._notificationRemoved;
|
||||||
let notificationExpanded = this._notification && this._notification.expanded;
|
let notificationExpanded = this._notification && this._notification.expanded;
|
||||||
let notificationExpired = this._notificationTimeoutId == 0 &&
|
let notificationExpired = this._notificationTimeoutId == 0 &&
|
||||||
!(this._notification && this._notification.urgency == Urgency.CRITICAL) &&
|
!(this._notification && this._notification.urgency == Urgency.CRITICAL) &&
|
||||||
!(this._notification && this._notification.focused) &&
|
!(this._notification && this._notification.focused) &&
|
||||||
!this._pointerInTray &&
|
!this._pointerInTray;
|
||||||
!this._locked &&
|
|
||||||
!(this._pointerInKeyboard && notificationExpanded);
|
|
||||||
let notificationLockedOut = !Main.sessionMode.hasNotifications && this._notification;
|
let notificationLockedOut = !Main.sessionMode.hasNotifications && this._notification;
|
||||||
let notificationMustClose = this._notificationRemoved || notificationLockedOut || (notificationExpired && this._userActiveWhileNotificationShown) || this._notificationClosed;
|
let notificationMustClose = this._notificationRemoved || notificationLockedOut || (notificationExpired && this._userActiveWhileNotificationShown) || this._notificationClosed;
|
||||||
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
|
let canShowNotification = notificationsPending && this._trayState == State.HIDDEN;
|
||||||
|
|
||||||
if (this._notificationState == State.HIDDEN) {
|
if (this._notificationState == State.HIDDEN) {
|
||||||
if (canShowNotification) {
|
if (canShowNotification)
|
||||||
this._showNotification();
|
this._showNotification();
|
||||||
}
|
|
||||||
} else if (this._notificationState == State.SHOWN) {
|
} else if (this._notificationState == State.SHOWN) {
|
||||||
if (notificationMustClose)
|
if (notificationMustClose)
|
||||||
this._hideNotification();
|
this._hideNotification();
|
||||||
@@ -2251,27 +2229,17 @@ const MessageTray = new Lang.Class({
|
|||||||
this._ensureNotificationFocused();
|
this._ensureNotificationFocused();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Summary
|
|
||||||
let summarySummoned = this._pointerInSummary || this._traySummoned;
|
|
||||||
let summaryPinned = this._pointerInTray || summarySummoned || this._locked;
|
|
||||||
let summaryHovered = this._pointerInTray || this._pointerInSummary;
|
|
||||||
|
|
||||||
let notificationsVisible = this._notificationState != State.HIDDEN;
|
let notificationsVisible = this._notificationState != State.HIDDEN;
|
||||||
let notificationsDone = !notificationsVisible && !notificationsPending;
|
let notificationsDone = !notificationsVisible && !notificationsPending;
|
||||||
|
|
||||||
let mustHideSummary = ((notificationsPending && notificationUrgent)
|
let mustHideTray = ((notificationsPending && notificationUrgent)
|
||||||
|| notificationsVisible || !Main.sessionMode.hasNotifications);
|
|| notificationsVisible || !Main.sessionMode.hasNotifications);
|
||||||
|
|
||||||
if (this._summaryState == State.HIDDEN && !mustHideSummary && summarySummoned)
|
|
||||||
this._showSummary();
|
|
||||||
else if (this._summaryState == State.SHOWN && (!summaryPinned || mustHideSummary))
|
|
||||||
this._hideSummary();
|
|
||||||
|
|
||||||
// Summary notification
|
// Summary notification
|
||||||
let haveClickedSummaryItem = this._clickedSummaryItem != null;
|
let haveClickedSummaryItem = this._clickedSummaryItem != null;
|
||||||
let summarySourceIsMainNotificationSource = (haveClickedSummaryItem && this._notification &&
|
let summarySourceIsMainNotificationSource = (haveClickedSummaryItem && this._notification &&
|
||||||
this._clickedSummaryItem.source == this._notification.source);
|
this._clickedSummaryItem.source == this._notification.source);
|
||||||
let canShowSummaryBoxPointer = this._summaryState == State.SHOWN;
|
let canShowSummaryBoxPointer = this._trayState == State.SHOWN;
|
||||||
// We only have sources with empty notification stacks for legacy tray icons. Currently, we never attempt
|
// We only have sources with empty notification stacks for legacy tray icons. Currently, we never attempt
|
||||||
// to show notifications for legacy tray icons, but this would be necessary if we did.
|
// to show notifications for legacy tray icons, but this would be necessary if we did.
|
||||||
let requestedNotificationStackIsEmpty = (this._clickedSummaryItemMouseButton == 1 && this._clickedSummaryItem.source.notifications.length == 0);
|
let requestedNotificationStackIsEmpty = (this._clickedSummaryItemMouseButton == 1 && this._clickedSummaryItem.source.notifications.length == 0);
|
||||||
@@ -2286,7 +2254,7 @@ const MessageTray = new Lang.Class({
|
|||||||
if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer && !requestedNotificationStackIsEmpty)
|
if (haveClickedSummaryItem && !summarySourceIsMainNotificationSource && canShowSummaryBoxPointer && !requestedNotificationStackIsEmpty)
|
||||||
this._showSummaryBoxPointer();
|
this._showSummaryBoxPointer();
|
||||||
} else if (this._summaryBoxPointerState == State.SHOWN) {
|
} else if (this._summaryBoxPointerState == State.SHOWN) {
|
||||||
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideSummary) {
|
if (!haveClickedSummaryItem || !canShowSummaryBoxPointer || wrongSummaryBoxPointer || mustHideTray) {
|
||||||
this._hideSummaryBoxPointer();
|
this._hideSummaryBoxPointer();
|
||||||
if (wrongSummaryBoxPointer)
|
if (wrongSummaryBoxPointer)
|
||||||
this._showSummaryBoxPointer();
|
this._showSummaryBoxPointer();
|
||||||
@@ -2296,9 +2264,7 @@ const MessageTray = new Lang.Class({
|
|||||||
// Tray itself
|
// Tray itself
|
||||||
let trayIsVisible = (this._trayState == State.SHOWING ||
|
let trayIsVisible = (this._trayState == State.SHOWING ||
|
||||||
this._trayState == State.SHOWN);
|
this._trayState == State.SHOWN);
|
||||||
let trayShouldBeVisible = (this._summaryState == State.SHOWING ||
|
let trayShouldBeVisible = this._traySummoned && !this._keyboardVisible && !mustHideTray;
|
||||||
this._summaryState == State.SHOWN) &&
|
|
||||||
!this._keyboardVisible;
|
|
||||||
if (!trayIsVisible && trayShouldBeVisible)
|
if (!trayIsVisible && trayShouldBeVisible)
|
||||||
trayShouldBeVisible = this._showTray();
|
trayShouldBeVisible = this._showTray();
|
||||||
else if (trayIsVisible && !trayShouldBeVisible)
|
else if (trayIsVisible && !trayShouldBeVisible)
|
||||||
@@ -2348,6 +2314,7 @@ const MessageTray = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.emit('showing');
|
||||||
this._tween(this.actor, '_trayState', State.SHOWN,
|
this._tween(this.actor, '_trayState', State.SHOWN,
|
||||||
{ y: -this.actor.height,
|
{ y: -this.actor.height,
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
@@ -2398,6 +2365,7 @@ const MessageTray = new Lang.Class({
|
|||||||
// is distracting, so hide it immediately in case it was visible.
|
// is distracting, so hide it immediately in case it was visible.
|
||||||
this._summaryBoxPointer.actor.hide();
|
this._summaryBoxPointer.actor.hide();
|
||||||
|
|
||||||
|
this.emit('hiding');
|
||||||
this._tween(this.actor, '_trayState', State.HIDDEN,
|
this._tween(this.actor, '_trayState', State.HIDDEN,
|
||||||
{ y: 0,
|
{ y: 0,
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
@@ -2434,7 +2402,7 @@ const MessageTray = new Lang.Class({
|
|||||||
_showNotification: function() {
|
_showNotification: function() {
|
||||||
this._notification = this._notificationQueue.shift();
|
this._notification = this._notificationQueue.shift();
|
||||||
|
|
||||||
this._userActiveWhileNotificationShown = this.idleMonitor.get_idletime() > IDLE_TIME;
|
this._userActiveWhileNotificationShown = this.idleMonitor.get_idletime() <= IDLE_TIME;
|
||||||
if (!this._userActiveWhileNotificationShown) {
|
if (!this._userActiveWhileNotificationShown) {
|
||||||
// If the user isn't active, set up a watch to let us know
|
// If the user isn't active, set up a watch to let us know
|
||||||
// when the user becomes active.
|
// when the user becomes active.
|
||||||
@@ -2569,6 +2537,14 @@ const MessageTray = new Lang.Class({
|
|||||||
this._notificationUnfocusedId = 0;
|
this._notificationUnfocusedId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._useLongerTrayLeftTimeout = false;
|
||||||
|
if (this._trayLeftTimeoutId) {
|
||||||
|
Mainloop.source_remove(this._trayLeftTimeoutId);
|
||||||
|
this._trayLeftTimeoutId = 0;
|
||||||
|
this._trayLeftMouseX = -1;
|
||||||
|
this._trayLeftMouseY = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (this._notificationRemoved) {
|
if (this._notificationRemoved) {
|
||||||
Tweener.removeTweens(this._notificationWidget);
|
Tweener.removeTweens(this._notificationWidget);
|
||||||
this._notificationWidget.y = this.actor.height;
|
this._notificationWidget.y = this.actor.height;
|
||||||
@@ -2599,7 +2575,11 @@ const MessageTray = new Lang.Class({
|
|||||||
this._notificationRemoved = false;
|
this._notificationRemoved = false;
|
||||||
this._closeButton.hide();
|
this._closeButton.hide();
|
||||||
this._pointerInTray = false;
|
this._pointerInTray = false;
|
||||||
this.actor.hover = false; // Clutter doesn't emit notify::hover when actors move
|
|
||||||
|
// Clutter will send a leave-event the next time the mouse
|
||||||
|
// moves, but we need to set this here now to update the
|
||||||
|
// state machine.
|
||||||
|
this.actor.hover = false;
|
||||||
this._notificationBin.child = null;
|
this._notificationBin.child = null;
|
||||||
this._notificationWidget.hide();
|
this._notificationWidget.hide();
|
||||||
},
|
},
|
||||||
@@ -2612,10 +2592,9 @@ const MessageTray = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_expandNotification: function(autoExpanding) {
|
_expandNotification: function(autoExpanding) {
|
||||||
// Don't grab focus in notifications that are auto-expanded.
|
// Don't focus notifications that are auto-expanding.
|
||||||
if (!autoExpanding)
|
if (!autoExpanding)
|
||||||
this._grabHelper.grab({ actor: this._notification.actor,
|
this._ensureNotificationFocused();
|
||||||
grabFocus: true });
|
|
||||||
|
|
||||||
if (!this._notificationExpandedId)
|
if (!this._notificationExpandedId)
|
||||||
this._notificationExpandedId =
|
this._notificationExpandedId =
|
||||||
@@ -2645,30 +2624,11 @@ const MessageTray = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// We use this function to grab focus when the user moves the pointer
|
|
||||||
// to a notification with CRITICAL urgency that was already auto-expanded.
|
|
||||||
_ensureNotificationFocused: function() {
|
_ensureNotificationFocused: function() {
|
||||||
this._grabHelper.grab({ actor: this._notification.actor,
|
this._grabHelper.grab({ actor: this._notification.actor,
|
||||||
grabFocus: true });
|
grabFocus: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
_showSummary: function() {
|
|
||||||
this._summary.opacity = 0;
|
|
||||||
this._tween(this._summary, '_summaryState', State.SHOWN,
|
|
||||||
{ opacity: 255,
|
|
||||||
time: ANIMATION_TIME,
|
|
||||||
transition: 'easeOutQuad',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_hideSummary: function() {
|
|
||||||
this._tween(this._summary, '_summaryState', State.HIDDEN,
|
|
||||||
{ opacity: 0,
|
|
||||||
time: ANIMATION_TIME,
|
|
||||||
transition: 'easeOutQuad',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_onSourceDoneDisplayingContent: function(source, closeTray) {
|
_onSourceDoneDisplayingContent: function(source, closeTray) {
|
||||||
if (closeTray) {
|
if (closeTray) {
|
||||||
this._escapeTray();
|
this._escapeTray();
|
||||||
@@ -2712,7 +2672,6 @@ const MessageTray = new Lang.Class({
|
|||||||
this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child,
|
this._grabHelper.grab({ actor: this._summaryBoxPointer.bin.child,
|
||||||
grabFocus: true,
|
grabFocus: true,
|
||||||
onUngrab: Lang.bind(this, this._onSummaryBoxPointerUngrabbed) });
|
onUngrab: Lang.bind(this, this._onSummaryBoxPointerUngrabbed) });
|
||||||
this._lock();
|
|
||||||
|
|
||||||
this._summaryBoxPointer.actor.opacity = 0;
|
this._summaryBoxPointer.actor.opacity = 0;
|
||||||
this._summaryBoxPointer.actor.show();
|
this._summaryBoxPointer.actor.show();
|
||||||
@@ -2747,10 +2706,8 @@ const MessageTray = new Lang.Class({
|
|||||||
this._clickedSummaryItem.actor.remove_style_pseudo_class('selected');
|
this._clickedSummaryItem.actor.remove_style_pseudo_class('selected');
|
||||||
this._clickedSummaryItem.actor.disconnect(this._clickedSummaryItemAllocationChangedId);
|
this._clickedSummaryItem.actor.disconnect(this._clickedSummaryItemAllocationChangedId);
|
||||||
this._summary.disconnect(this._summaryMotionId);
|
this._summary.disconnect(this._summaryMotionId);
|
||||||
Main.layoutManager.trayBox.disconnect(this._trayMotionId);
|
|
||||||
this._clickedSummaryItemAllocationChangedId = 0;
|
this._clickedSummaryItemAllocationChangedId = 0;
|
||||||
this._summaryMotionId = 0;
|
this._summaryMotionId = 0;
|
||||||
this._trayMotionId = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._clickedSummaryItem = item;
|
this._clickedSummaryItem = item;
|
||||||
@@ -2765,8 +2722,6 @@ const MessageTray = new Lang.Class({
|
|||||||
// _clickedSummaryItem.actor can change absolute position without changing allocation
|
// _clickedSummaryItem.actor can change absolute position without changing allocation
|
||||||
this._summaryMotionId = this._summary.connect('allocation-changed',
|
this._summaryMotionId = this._summary.connect('allocation-changed',
|
||||||
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
|
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
|
||||||
this._trayMotionId = Main.layoutManager.trayBox.connect('notify::anchor-y',
|
|
||||||
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -2803,8 +2758,6 @@ const MessageTray = new Lang.Class({
|
|||||||
this._sourceDoneDisplayingId = 0;
|
this._sourceDoneDisplayingId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._unlock();
|
|
||||||
|
|
||||||
if (this._summaryBoxPointerItem.source.notifications.length == 0) {
|
if (this._summaryBoxPointerItem.source.notifications.length == 0) {
|
||||||
this._summaryBoxPointer.actor.hide();
|
this._summaryBoxPointer.actor.hide();
|
||||||
this._hideSummaryBoxPointerCompleted();
|
this._hideSummaryBoxPointerCompleted();
|
||||||
|
|||||||
@@ -38,13 +38,15 @@ const ModalDialog = new Lang.Class({
|
|||||||
styleClass: null,
|
styleClass: null,
|
||||||
parentActor: Main.uiGroup,
|
parentActor: Main.uiGroup,
|
||||||
keybindingMode: Shell.KeyBindingMode.SYSTEM_MODAL,
|
keybindingMode: Shell.KeyBindingMode.SYSTEM_MODAL,
|
||||||
shouldFadeIn: true });
|
shouldFadeIn: true,
|
||||||
|
destroyOnClose: true });
|
||||||
|
|
||||||
this.state = State.CLOSED;
|
this.state = State.CLOSED;
|
||||||
this._hasModal = false;
|
this._hasModal = false;
|
||||||
this._keybindingMode = params.keybindingMode;
|
this._keybindingMode = params.keybindingMode;
|
||||||
this._shellReactive = params.shellReactive;
|
this._shellReactive = params.shellReactive;
|
||||||
this._shouldFadeIn = params.shouldFadeIn;
|
this._shouldFadeIn = params.shouldFadeIn;
|
||||||
|
this._destroyOnClose = params.destroyOnClose;
|
||||||
|
|
||||||
this._group = new St.Widget({ visible: false,
|
this._group = new St.Widget({ visible: false,
|
||||||
x: 0,
|
x: 0,
|
||||||
@@ -58,7 +60,9 @@ const ModalDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._group.connect('destroy', Lang.bind(this, this._onGroupDestroy));
|
this._group.connect('destroy', Lang.bind(this, this._onGroupDestroy));
|
||||||
|
|
||||||
|
this._pressedKey = null;
|
||||||
this._buttonKeys = {};
|
this._buttonKeys = {};
|
||||||
|
this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
||||||
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
|
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
|
||||||
|
|
||||||
this._backgroundBin = new St.Bin();
|
this._backgroundBin = new St.Bin();
|
||||||
@@ -80,7 +84,7 @@ const ModalDialog = new Lang.Class({
|
|||||||
let stack = new Shell.Stack();
|
let stack = new Shell.Stack();
|
||||||
this._backgroundBin.child = stack;
|
this._backgroundBin.child = stack;
|
||||||
|
|
||||||
this._eventBlocker = new Clutter.Group({ reactive: true });
|
this._eventBlocker = new Clutter.Actor({ reactive: true });
|
||||||
stack.add_actor(this._eventBlocker);
|
stack.add_actor(this._eventBlocker);
|
||||||
stack.add_actor(this.dialogLayout);
|
stack.add_actor(this.dialogLayout);
|
||||||
} else {
|
} else {
|
||||||
@@ -179,10 +183,19 @@ const ModalDialog = new Lang.Class({
|
|||||||
return button;
|
return button;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onKeyReleaseEvent: function(object, event) {
|
_onKeyPressEvent: function(object, event) {
|
||||||
let symbol = event.get_key_symbol();
|
this._pressedKey = event.get_key_symbol();
|
||||||
let buttonInfo = this._buttonKeys[symbol];
|
},
|
||||||
|
|
||||||
|
_onKeyReleaseEvent: function(object, event) {
|
||||||
|
let pressedKey = this._pressedKey;
|
||||||
|
this._pressedKey = null;
|
||||||
|
|
||||||
|
let symbol = event.get_key_symbol();
|
||||||
|
if (symbol != pressedKey)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
let buttonInfo = this._buttonKeys[symbol];
|
||||||
if (!buttonInfo)
|
if (!buttonInfo)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -266,6 +279,9 @@ const ModalDialog = new Lang.Class({
|
|||||||
this.state = State.CLOSED;
|
this.state = State.CLOSED;
|
||||||
this._group.hide();
|
this._group.hide();
|
||||||
this.emit('closed');
|
this.emit('closed');
|
||||||
|
|
||||||
|
if (this._destroyOnClose)
|
||||||
|
this.destroy();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ const NotificationDaemon = new Lang.Class({
|
|||||||
Main.overview.connect('hidden',
|
Main.overview.connect('hidden',
|
||||||
Lang.bind(this, this._onFocusAppChanged));
|
Lang.bind(this, this._onFocusAppChanged));
|
||||||
|
|
||||||
this._trayManager.manage_stage(global.stage, Main.messageTray.actor);
|
this._trayManager.manage_screen(global.screen, Main.messageTray.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
_imageForNotificationData: function(hints) {
|
_imageForNotificationData: function(hints) {
|
||||||
|
|||||||
179
js/ui/osdWindow.js
Normal file
179
js/ui/osdWindow.js
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Layout = imports.ui.layout;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const Mainloop = imports.mainloop;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const HIDE_TIMEOUT = 1500;
|
||||||
|
const FADE_TIME = 0.1;
|
||||||
|
const LEVEL_ANIMATION_TIME = 0.1;
|
||||||
|
|
||||||
|
const LevelBar = new Lang.Class({
|
||||||
|
Name: 'LevelBar',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._level = 0;
|
||||||
|
|
||||||
|
this.actor = new St.Bin({ style_class: 'level',
|
||||||
|
x_fill: true, y_fill: true });
|
||||||
|
this._bar = new St.DrawingArea();
|
||||||
|
this._bar.connect('repaint', Lang.bind(this, this._repaint));
|
||||||
|
|
||||||
|
this.actor.set_child(this._bar);
|
||||||
|
},
|
||||||
|
|
||||||
|
get level() {
|
||||||
|
return this._level;
|
||||||
|
},
|
||||||
|
|
||||||
|
set level(value) {
|
||||||
|
let newValue = Math.max(0, Math.min(value, 100));
|
||||||
|
if (newValue == this._level)
|
||||||
|
return;
|
||||||
|
this._level = newValue;
|
||||||
|
this._bar.queue_repaint();
|
||||||
|
},
|
||||||
|
|
||||||
|
_repaint: function() {
|
||||||
|
let cr = this._bar.get_context();
|
||||||
|
|
||||||
|
let node = this.actor.get_theme_node();
|
||||||
|
let radius = node.get_border_radius(0); // assume same radius for all corners
|
||||||
|
Clutter.cairo_set_source_color(cr, node.get_foreground_color());
|
||||||
|
|
||||||
|
let [w, h] = this._bar.get_surface_size();
|
||||||
|
w *= (this._level / 100.);
|
||||||
|
|
||||||
|
if (w == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cr.moveTo(radius, 0);
|
||||||
|
if (w >= radius)
|
||||||
|
cr.arc(w - radius, radius, radius, 1.5 * Math.PI, 2. * Math.PI);
|
||||||
|
else
|
||||||
|
cr.lineTo(w, 0);
|
||||||
|
if (w >= radius)
|
||||||
|
cr.arc(w - radius, h - radius, radius, 0, 0.5 * Math.PI);
|
||||||
|
else
|
||||||
|
cr.lineTo(w, h);
|
||||||
|
cr.arc(radius, h - radius, radius, 0.5 * Math.PI, Math.PI);
|
||||||
|
cr.arc(radius, radius, radius, Math.PI, 1.5 * Math.PI);
|
||||||
|
cr.fill();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const OsdWindow = new Lang.Class({
|
||||||
|
Name: 'OsdWindow',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.actor = new St.Widget({ x_expand: true,
|
||||||
|
y_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.CENTER,
|
||||||
|
y_align: Clutter.ActorAlign.CENTER });
|
||||||
|
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||||
|
this._box = new St.BoxLayout({ style_class: 'osd-window',
|
||||||
|
vertical: true });
|
||||||
|
this.actor.add_actor(this._box);
|
||||||
|
|
||||||
|
this._icon = new St.Icon();
|
||||||
|
this._box.add(this._icon, { expand: true });
|
||||||
|
|
||||||
|
this._label = new St.Label();
|
||||||
|
this._box.add(this._label);
|
||||||
|
|
||||||
|
this._level = new LevelBar();
|
||||||
|
this._box.add(this._level.actor);
|
||||||
|
|
||||||
|
this._hideTimeoutId = 0;
|
||||||
|
this._reset();
|
||||||
|
|
||||||
|
Main.layoutManager.connect('monitors-changed',
|
||||||
|
Lang.bind(this, this._monitorsChanged));
|
||||||
|
this._monitorsChanged();
|
||||||
|
|
||||||
|
Main.layoutManager.addChrome(this.actor, { affectsInputRegion: false });
|
||||||
|
},
|
||||||
|
|
||||||
|
setIcon: function(icon) {
|
||||||
|
this._icon.gicon = icon;
|
||||||
|
},
|
||||||
|
|
||||||
|
setLabel: function(label) {
|
||||||
|
this._label.visible = (label != undefined);
|
||||||
|
if (label)
|
||||||
|
this._label.text = label;
|
||||||
|
},
|
||||||
|
|
||||||
|
setLevel: function(level) {
|
||||||
|
this._level.actor.visible = (level != undefined);
|
||||||
|
if (this.actor.visible)
|
||||||
|
Tweener.addTween(this._level,
|
||||||
|
{ level: level,
|
||||||
|
time: LEVEL_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
else
|
||||||
|
this._level.level = level;
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function() {
|
||||||
|
if (!this._icon.gicon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!this.actor.visible) {
|
||||||
|
this.actor.show();
|
||||||
|
this.actor.opacity = 0;
|
||||||
|
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: FADE_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._hideTimeoutId)
|
||||||
|
Mainloop.source_remove(this._hideTimeoutId);
|
||||||
|
this._hideTimeoutId = Mainloop.timeout_add(HIDE_TIMEOUT,
|
||||||
|
Lang.bind(this, this._hide));
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel: function() {
|
||||||
|
if (!this._hideTimeoutId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Mainloop.source_remove(this._hideTimeoutId);
|
||||||
|
this._hideTimeoutId = 0;
|
||||||
|
this._hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
_hide: function() {
|
||||||
|
Tweener.addTween(this.actor,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: FADE_TIME,
|
||||||
|
transition: 'easeOutQuad',
|
||||||
|
onComplete: Lang.bind(this, this._reset) });
|
||||||
|
},
|
||||||
|
|
||||||
|
_reset: function() {
|
||||||
|
this.actor.hide();
|
||||||
|
this.setLabel(null);
|
||||||
|
this.setLevel(null);
|
||||||
|
},
|
||||||
|
|
||||||
|
_monitorsChanged: function() {
|
||||||
|
/* assume 110x110 on a 640x480 display and scale from there */
|
||||||
|
let monitor = Main.layoutManager.primaryMonitor;
|
||||||
|
let scalew = monitor.width / 640.0;
|
||||||
|
let scaleh = monitor.height / 480.0;
|
||||||
|
let scale = Math.min(scalew, scaleh);
|
||||||
|
let size = 110 * Math.max(1, scale);
|
||||||
|
|
||||||
|
this._box.set_size(size, size);
|
||||||
|
this._box.translation_y = monitor.height / 4;
|
||||||
|
|
||||||
|
this._icon.icon_size = size / 2;
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -13,6 +13,7 @@ const Gdk = imports.gi.Gdk;
|
|||||||
const Background = imports.ui.background;
|
const Background = imports.ui.background;
|
||||||
const Dash = imports.ui.dash;
|
const Dash = imports.ui.dash;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
|
const LayoutManager = imports.ui.layout;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const OverviewControls = imports.ui.overviewControls;
|
const OverviewControls = imports.ui.overviewControls;
|
||||||
@@ -32,6 +33,8 @@ const SHADE_ANIMATION_TIME = .20;
|
|||||||
|
|
||||||
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
|
const DND_WINDOW_SWITCH_TIMEOUT = 1250;
|
||||||
|
|
||||||
|
const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
|
||||||
|
|
||||||
const ShellInfo = new Lang.Class({
|
const ShellInfo = new Lang.Class({
|
||||||
Name: 'ShellInfo',
|
Name: 'ShellInfo',
|
||||||
|
|
||||||
@@ -116,26 +119,37 @@ const Overview = new Lang.Class({
|
|||||||
this._desktopFade = new St.Bin();
|
this._desktopFade = new St.Bin();
|
||||||
global.overlay_group.add_actor(this._desktopFade);
|
global.overlay_group.add_actor(this._desktopFade);
|
||||||
|
|
||||||
|
let layout = new Clutter.BinLayout();
|
||||||
|
this._stack = new Clutter.Actor({ layout_manager: layout });
|
||||||
|
this._stack.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
|
||||||
|
|
||||||
/* Translators: This is the main view to select
|
/* Translators: This is the main view to select
|
||||||
activities. See also note for "Activities" string. */
|
activities. See also note for "Activities" string. */
|
||||||
this._overview = new St.BoxLayout({ name: 'overview',
|
this._overview = new St.BoxLayout({ name: 'overview',
|
||||||
accessible_name: _("Overview"),
|
accessible_name: _("Overview"),
|
||||||
reactive: true,
|
reactive: true,
|
||||||
vertical: true });
|
vertical: true,
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true });
|
||||||
this._overview._delegate = this;
|
this._overview._delegate = this;
|
||||||
|
|
||||||
|
this._groupStack = new St.Widget({ layout_manager: new Clutter.BinLayout(),
|
||||||
|
x_expand: true, y_expand: true,
|
||||||
|
clip_to_allocation: true });
|
||||||
this._group = new St.BoxLayout({ name: 'overview-group',
|
this._group = new St.BoxLayout({ name: 'overview-group',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
clip_to_allocation: true });
|
x_expand: true, y_expand: true });
|
||||||
|
this._groupStack.add_actor(this._group);
|
||||||
|
|
||||||
this._backgroundGroup = new Meta.BackgroundGroup();
|
this._backgroundGroup = new Meta.BackgroundGroup();
|
||||||
global.overlay_group.add_child(this._backgroundGroup);
|
global.overlay_group.add_child(this._backgroundGroup);
|
||||||
this._backgroundGroup.hide();
|
this._backgroundGroup.hide();
|
||||||
this._bgManagers = [];
|
this._bgManagers = [];
|
||||||
|
|
||||||
|
this._activationTime = 0;
|
||||||
|
|
||||||
this.visible = false; // animating to overview, in overview, animating out
|
this.visible = false; // animating to overview, in overview, animating out
|
||||||
this._shown = false; // show() and not hide()
|
this._shown = false; // show() and not hide()
|
||||||
this._shownTemporarily = false; // showTemporarily() and not hideTemporarily()
|
|
||||||
this._modal = false; // have a modal grab
|
this._modal = false; // have a modal grab
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
this.visibleTarget = false;
|
this.visibleTarget = false;
|
||||||
@@ -148,8 +162,9 @@ const Overview = new Lang.Class({
|
|||||||
this._overview.add_actor(this._coverPane);
|
this._overview.add_actor(this._coverPane);
|
||||||
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
|
this._coverPane.connect('event', Lang.bind(this, function (actor, event) { return true; }));
|
||||||
|
|
||||||
this._overview.hide();
|
this._stack.hide();
|
||||||
global.overlay_group.add_actor(this._overview);
|
this._stack.add_actor(this._overview);
|
||||||
|
global.overlay_group.add_actor(this._stack);
|
||||||
|
|
||||||
this._coverPane.hide();
|
this._coverPane.hide();
|
||||||
|
|
||||||
@@ -269,15 +284,22 @@ const Overview = new Lang.Class({
|
|||||||
this._thumbnailsBox,
|
this._thumbnailsBox,
|
||||||
this._viewSelector);
|
this._viewSelector);
|
||||||
|
|
||||||
|
this._controls.dashActor.x_align = Clutter.ActorAlign.START;
|
||||||
|
this._controls.dashActor.y_expand = true;
|
||||||
|
|
||||||
|
// Put the dash in a separate layer to allow content to be centered
|
||||||
|
this._groupStack.add_actor(this._controls.dashActor);
|
||||||
|
|
||||||
// Pack all the actors into the group
|
// Pack all the actors into the group
|
||||||
this._group.add_actor(this._controls.dashActor);
|
this._group.add_actor(this._controls.dashSpacer);
|
||||||
this._group.add(this._viewSelector.actor, { x_fill: true,
|
this._group.add(this._viewSelector.actor, { x_fill: true,
|
||||||
expand: true });
|
expand: true });
|
||||||
this._group.add_actor(this._controls.thumbnailsActor);
|
this._group.add_actor(this._controls.thumbnailsActor);
|
||||||
|
|
||||||
// Add our same-line elements after the search entry
|
// Add our same-line elements after the search entry
|
||||||
this._overview.add(this._group, { y_fill: true,
|
this._overview.add(this._groupStack, { y_fill: true, expand: true });
|
||||||
expand: true });
|
|
||||||
|
this._stack.add_actor(this._controls.indicatorActor);
|
||||||
|
|
||||||
// TODO - recalculate everything when desktop size changes
|
// TODO - recalculate everything when desktop size changes
|
||||||
this.dashIconSize = this._dash.iconSize;
|
this.dashIconSize = this._dash.iconSize;
|
||||||
@@ -311,18 +333,22 @@ const Overview = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onDragBegin: function() {
|
_onDragBegin: function() {
|
||||||
|
this._inXdndDrag = true;
|
||||||
|
|
||||||
DND.addDragMonitor(this._dragMonitor);
|
DND.addDragMonitor(this._dragMonitor);
|
||||||
// Remember the workspace we started from
|
// Remember the workspace we started from
|
||||||
this._lastActiveWorkspaceIndex = global.screen.get_active_workspace_index();
|
this._lastActiveWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDragEnd: function(time) {
|
_onDragEnd: function(time) {
|
||||||
|
this._inXdndDrag = false;
|
||||||
|
|
||||||
// In case the drag was canceled while in the overview
|
// In case the drag was canceled while in the overview
|
||||||
// we have to go back to where we started and hide
|
// we have to go back to where we started and hide
|
||||||
// the overview
|
// the overview
|
||||||
if (this._shownTemporarily) {
|
if (this._shown) {
|
||||||
global.screen.get_workspace_by_index(this._lastActiveWorkspaceIndex).activate(time);
|
global.screen.get_workspace_by_index(this._lastActiveWorkspaceIndex).activate(time);
|
||||||
this.hideTemporarily();
|
this.hide();
|
||||||
}
|
}
|
||||||
this._resetWindowSwitchTimeout();
|
this._resetWindowSwitchTimeout();
|
||||||
this._lastHoveredWindow = null;
|
this._lastHoveredWindow = null;
|
||||||
@@ -370,7 +396,7 @@ const Overview = new Lang.Class({
|
|||||||
this._needsFakePointerEvent = true;
|
this._needsFakePointerEvent = true;
|
||||||
Main.activateWindow(dragEvent.targetActor._delegate.metaWindow,
|
Main.activateWindow(dragEvent.targetActor._delegate.metaWindow,
|
||||||
this._windowSwitchTimestamp);
|
this._windowSwitchTimestamp);
|
||||||
this.hideTemporarily();
|
this.hide();
|
||||||
this._lastHoveredWindow = null;
|
this._lastHoveredWindow = null;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -411,12 +437,8 @@ const Overview = new Lang.Class({
|
|||||||
// when it is next shown.
|
// when it is next shown.
|
||||||
this.hide();
|
this.hide();
|
||||||
|
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
|
||||||
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
|
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
|
||||||
|
|
||||||
this._overview.set_position(primary.x, primary.y);
|
|
||||||
this._overview.set_size(primary.width, primary.height);
|
|
||||||
|
|
||||||
this._coverPane.set_position(0, workArea.y);
|
this._coverPane.set_position(0, workArea.y);
|
||||||
this._coverPane.set_size(workArea.width, workArea.height);
|
this._coverPane.set_size(workArea.width, workArea.height);
|
||||||
|
|
||||||
@@ -470,9 +492,10 @@ const Overview = new Lang.Class({
|
|||||||
if (this._shown)
|
if (this._shown)
|
||||||
return;
|
return;
|
||||||
this._shown = true;
|
this._shown = true;
|
||||||
this._syncInputMode();
|
|
||||||
if (!this._modal)
|
if (!this._syncInputMode())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._animateVisible();
|
this._animateVisible();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -505,6 +528,7 @@ const Overview = new Lang.Class({
|
|||||||
this.visible = true;
|
this.visible = true;
|
||||||
this.animationInProgress = true;
|
this.animationInProgress = true;
|
||||||
this.visibleTarget = true;
|
this.visibleTarget = true;
|
||||||
|
this._activationTime = Date.now() / 1000;
|
||||||
|
|
||||||
// All the the actors in the window group are completely obscured,
|
// All the the actors in the window group are completely obscured,
|
||||||
// hiding the group holding them while the Overview is displayed greatly
|
// hiding the group holding them while the Overview is displayed greatly
|
||||||
@@ -516,14 +540,12 @@ const Overview = new Lang.Class({
|
|||||||
//
|
//
|
||||||
// Disable unredirection while in the overview
|
// Disable unredirection while in the overview
|
||||||
Meta.disable_unredirect_for_screen(global.screen);
|
Meta.disable_unredirect_for_screen(global.screen);
|
||||||
global.window_group.hide();
|
this._stack.show();
|
||||||
global.top_window_group.hide();
|
|
||||||
this._overview.show();
|
|
||||||
this._backgroundGroup.show();
|
this._backgroundGroup.show();
|
||||||
this._viewSelector.show();
|
this._viewSelector.show();
|
||||||
|
|
||||||
this._overview.opacity = 0;
|
this._stack.opacity = 0;
|
||||||
Tweener.addTween(this._overview,
|
Tweener.addTween(this._stack,
|
||||||
{ opacity: 255,
|
{ opacity: 255,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
@@ -537,24 +559,6 @@ const Overview = new Lang.Class({
|
|||||||
this.emit('showing');
|
this.emit('showing');
|
||||||
},
|
},
|
||||||
|
|
||||||
// showTemporarily:
|
|
||||||
//
|
|
||||||
// Animates the overview visible without grabbing mouse and keyboard input;
|
|
||||||
// if show() has already been called, this has no immediate effect, but
|
|
||||||
// will result in the overview not being hidden until hideTemporarily() is
|
|
||||||
// called.
|
|
||||||
showTemporarily: function() {
|
|
||||||
if (this.isDummy)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this._shownTemporarily)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._syncInputMode();
|
|
||||||
this._animateVisible();
|
|
||||||
this._shownTemporarily = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
// hide:
|
// hide:
|
||||||
//
|
//
|
||||||
// Reverses the effect of show()
|
// Reverses the effect of show()
|
||||||
@@ -565,30 +569,22 @@ const Overview = new Lang.Class({
|
|||||||
if (!this._shown)
|
if (!this._shown)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!this._shownTemporarily)
|
let event = Clutter.get_current_event();
|
||||||
this._animateNotVisible();
|
if (event) {
|
||||||
|
let type = event.type();
|
||||||
|
let button = (type == Clutter.EventType.BUTTON_PRESS ||
|
||||||
|
type == Clutter.EventType.BUTTON_RELEASE);
|
||||||
|
let ctrl = (event.get_state() & Clutter.ModifierType.CONTROL_MASK) != 0;
|
||||||
|
if (button && ctrl)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._animateNotVisible();
|
||||||
|
|
||||||
this._shown = false;
|
this._shown = false;
|
||||||
this._syncInputMode();
|
this._syncInputMode();
|
||||||
},
|
},
|
||||||
|
|
||||||
// hideTemporarily:
|
|
||||||
//
|
|
||||||
// Reverses the effect of showTemporarily()
|
|
||||||
hideTemporarily: function() {
|
|
||||||
if (this.isDummy)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!this._shownTemporarily)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!this._shown)
|
|
||||||
this._animateNotVisible();
|
|
||||||
|
|
||||||
this._shownTemporarily = false;
|
|
||||||
this._syncInputMode();
|
|
||||||
},
|
|
||||||
|
|
||||||
toggle: function() {
|
toggle: function() {
|
||||||
if (this.isDummy)
|
if (this.isDummy)
|
||||||
return;
|
return;
|
||||||
@@ -599,6 +595,20 @@ const Overview = new Lang.Class({
|
|||||||
this.show();
|
this.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Checks if the Activities button is currently sensitive to
|
||||||
|
// clicks. The first call to this function within the
|
||||||
|
// OVERVIEW_ACTIVATION_TIMEOUT time of the hot corner being
|
||||||
|
// triggered will return false. This avoids opening and closing
|
||||||
|
// the overview if the user both triggered the hot corner and
|
||||||
|
// clicked the Activities button.
|
||||||
|
shouldToggleByCornerOrButton: function() {
|
||||||
|
if (this.animationInProgress)
|
||||||
|
return false;
|
||||||
|
if (this._activationTime == 0 || Date.now() / 1000 - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
//// Private methods ////
|
//// Private methods ////
|
||||||
|
|
||||||
_syncInputMode: function() {
|
_syncInputMode: function() {
|
||||||
@@ -606,22 +616,23 @@ const Overview = new Lang.Class({
|
|||||||
// overview we don't have a problem with the release of a press/release
|
// overview we don't have a problem with the release of a press/release
|
||||||
// going to an application.
|
// going to an application.
|
||||||
if (this.animationInProgress)
|
if (this.animationInProgress)
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
if (this._shown) {
|
if (this._shown) {
|
||||||
if (!this._modal) {
|
let shouldBeModal = !this._inXdndDrag;
|
||||||
if (Main.pushModal(this._overview,
|
if (shouldBeModal) {
|
||||||
{ keybindingMode: Shell.KeyBindingMode.OVERVIEW }))
|
if (!this._modal) {
|
||||||
this._modal = true;
|
if (Main.pushModal(this._overview,
|
||||||
else
|
{ keybindingMode: Shell.KeyBindingMode.OVERVIEW })) {
|
||||||
this.hide();
|
this._modal = true;
|
||||||
|
} else {
|
||||||
|
this.hide();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
||||||
}
|
}
|
||||||
} else if (this._shownTemporarily) {
|
|
||||||
if (this._modal) {
|
|
||||||
Main.popModal(this._overview);
|
|
||||||
this._modal = false;
|
|
||||||
}
|
|
||||||
global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
|
|
||||||
} else {
|
} else {
|
||||||
if (this._modal) {
|
if (this._modal) {
|
||||||
Main.popModal(this._overview);
|
Main.popModal(this._overview);
|
||||||
@@ -630,6 +641,7 @@ const Overview = new Lang.Class({
|
|||||||
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
|
else if (global.stage_input_mode == Shell.StageInputMode.FULLSCREEN)
|
||||||
global.stage_input_mode = Shell.StageInputMode.NORMAL;
|
global.stage_input_mode = Shell.StageInputMode.NORMAL;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_animateNotVisible: function() {
|
_animateNotVisible: function() {
|
||||||
@@ -642,7 +654,7 @@ const Overview = new Lang.Class({
|
|||||||
this._viewSelector.zoomFromOverview();
|
this._viewSelector.zoomFromOverview();
|
||||||
|
|
||||||
// Make other elements fade out.
|
// Make other elements fade out.
|
||||||
Tweener.addTween(this._overview,
|
Tweener.addTween(this._stack,
|
||||||
{ opacity: 0,
|
{ opacity: 0,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
time: ANIMATION_TIME,
|
time: ANIMATION_TIME,
|
||||||
@@ -663,7 +675,7 @@ const Overview = new Lang.Class({
|
|||||||
|
|
||||||
this.emit('shown');
|
this.emit('shown');
|
||||||
// Handle any calls to hide* while we were showing
|
// Handle any calls to hide* while we were showing
|
||||||
if (!this._shown && !this._shownTemporarily)
|
if (!this._shown)
|
||||||
this._animateNotVisible();
|
this._animateNotVisible();
|
||||||
|
|
||||||
this._syncInputMode();
|
this._syncInputMode();
|
||||||
@@ -674,13 +686,10 @@ const Overview = new Lang.Class({
|
|||||||
// Re-enable unredirection
|
// Re-enable unredirection
|
||||||
Meta.enable_unredirect_for_screen(global.screen);
|
Meta.enable_unredirect_for_screen(global.screen);
|
||||||
|
|
||||||
global.window_group.show();
|
|
||||||
global.top_window_group.show();
|
|
||||||
|
|
||||||
this._viewSelector.hide();
|
this._viewSelector.hide();
|
||||||
this._desktopFade.hide();
|
this._desktopFade.hide();
|
||||||
this._backgroundGroup.hide();
|
this._backgroundGroup.hide();
|
||||||
this._overview.hide();
|
this._stack.hide();
|
||||||
|
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
@@ -689,7 +698,7 @@ const Overview = new Lang.Class({
|
|||||||
|
|
||||||
this.emit('hidden');
|
this.emit('hidden');
|
||||||
// Handle any calls to show* while we were hiding
|
// Handle any calls to show* while we were hiding
|
||||||
if (this._shown || this._shownTemporarily)
|
if (this._shown)
|
||||||
this._animateVisible();
|
this._animateVisible();
|
||||||
|
|
||||||
this._syncInputMode();
|
this._syncInputMode();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@ const SlidingControl = new Lang.Class({
|
|||||||
this.layout = new SlideLayout();
|
this.layout = new SlideLayout();
|
||||||
this.layout.slideDirection = params.slideDirection;
|
this.layout.slideDirection = params.slideDirection;
|
||||||
this.actor = new St.Widget({ layout_manager: this.layout,
|
this.actor = new St.Widget({ layout_manager: this.layout,
|
||||||
|
style_class: 'overview-controls',
|
||||||
clip_to_allocation: true });
|
clip_to_allocation: true });
|
||||||
|
|
||||||
Main.overview.connect('showing', Lang.bind(this, this._onOverviewShowing));
|
Main.overview.connect('showing', Lang.bind(this, this._onOverviewShowing));
|
||||||
@@ -247,7 +249,7 @@ const ThumbnailsSlider = new Lang.Class({
|
|||||||
_getAlwaysZoomOut: function() {
|
_getAlwaysZoomOut: function() {
|
||||||
// Always show the pager when hover, during a drag, or if workspaces are
|
// Always show the pager when hover, during a drag, or if workspaces are
|
||||||
// actually used, e.g. there are windows on more than one
|
// actually used, e.g. there are windows on more than one
|
||||||
let alwaysZoomOut = this.actor.hover || this.inDrag || global.screen.n_workspaces > 2;
|
let alwaysZoomOut = this.actor.hover || this.inDrag || !Meta.prefs_get_dynamic_workspaces() || global.screen.n_workspaces > 2;
|
||||||
|
|
||||||
if (!alwaysZoomOut) {
|
if (!alwaysZoomOut) {
|
||||||
let monitors = Main.layoutManager.monitors;
|
let monitors = Main.layoutManager.monitors;
|
||||||
@@ -328,19 +330,186 @@ const DashSlider = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const DashSpacer = new Lang.Class({
|
||||||
|
Name: 'DashSpacer',
|
||||||
|
Extends: St.Widget,
|
||||||
|
|
||||||
|
_init: function(params) {
|
||||||
|
this.parent(params);
|
||||||
|
|
||||||
|
this._bindConstraint = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
setDashActor: function(dashActor) {
|
||||||
|
if (this._bindConstraint) {
|
||||||
|
this.remove_constraint(this._bindConstraint);
|
||||||
|
this._bindConstraint = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dashActor) {
|
||||||
|
this._bindConstraint = new Clutter.BindConstraint({ source: dashActor,
|
||||||
|
coordinate: Clutter.BindCoordinate.SIZE });
|
||||||
|
this.add_constraint(this._bindConstraint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
vfunc_get_preferred_width: function(forHeight) {
|
||||||
|
let box = this.get_allocation_box();
|
||||||
|
let minWidth = this.parent(forHeight)[0];
|
||||||
|
let natWidth = box.x2 - box.x1;
|
||||||
|
return [minWidth, natWidth];
|
||||||
|
},
|
||||||
|
|
||||||
|
vfunc_get_preferred_height: function(forWidth) {
|
||||||
|
let box = this.get_allocation_box();
|
||||||
|
let minHeight = this.parent(forWidth)[0];
|
||||||
|
let natHeight = box.y2 - box.y1;
|
||||||
|
return [minHeight, natHeight];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const MessagesIndicator = new Lang.Class({
|
||||||
|
Name: 'MessagesIndicator',
|
||||||
|
|
||||||
|
_init: function(viewSelector) {
|
||||||
|
this._count = 0;
|
||||||
|
this._sources = [];
|
||||||
|
this._viewSelector = viewSelector;
|
||||||
|
|
||||||
|
this._container = new St.BoxLayout({ style_class: 'messages-indicator-contents',
|
||||||
|
reactive: true,
|
||||||
|
track_hover: true,
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.CENTER });
|
||||||
|
|
||||||
|
this._icon = new St.Icon({ icon_name: 'user-idle-symbolic',
|
||||||
|
icon_size: 16 });
|
||||||
|
this._container.add_actor(this._icon);
|
||||||
|
|
||||||
|
this._label = new St.Label();
|
||||||
|
this._container.add_actor(this._label);
|
||||||
|
|
||||||
|
this._highlight = new St.Widget({ style_class: 'messages-indicator-highlight',
|
||||||
|
x_expand: true,
|
||||||
|
y_expand: true,
|
||||||
|
y_align: Clutter.ActorAlign.END,
|
||||||
|
visible: false });
|
||||||
|
|
||||||
|
this._container.connect('notify::hover', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._highlight.visible = this._container.hover;
|
||||||
|
}));
|
||||||
|
|
||||||
|
let clickAction = new Clutter.ClickAction();
|
||||||
|
this._container.add_action(clickAction);
|
||||||
|
clickAction.connect('clicked', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
Main.messageTray.openTray();
|
||||||
|
}));
|
||||||
|
|
||||||
|
Main.messageTray.connect('showing', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._highlight.visible = false;
|
||||||
|
this._container.hover = false;
|
||||||
|
}));
|
||||||
|
|
||||||
|
let layout = new Clutter.BinLayout();
|
||||||
|
this.actor = new St.Widget({ layout_manager: layout,
|
||||||
|
style_class: 'messages-indicator',
|
||||||
|
y_expand: true,
|
||||||
|
y_align: Clutter.ActorAlign.END,
|
||||||
|
visible: false });
|
||||||
|
this.actor.add_actor(this._container);
|
||||||
|
this.actor.add_actor(this._highlight);
|
||||||
|
|
||||||
|
Main.messageTray.connect('source-added', Lang.bind(this, this._onSourceAdded));
|
||||||
|
Main.messageTray.connect('source-removed', Lang.bind(this, this._onSourceRemoved));
|
||||||
|
|
||||||
|
let sources = Main.messageTray.getSources();
|
||||||
|
sources.forEach(Lang.bind(this, function(source) { this._onSourceAdded(null, source); }));
|
||||||
|
|
||||||
|
this._viewSelector.connect('page-changed', Lang.bind(this, this._updateVisibility));
|
||||||
|
Main.overview.connect('showing', Lang.bind(this, this._updateVisibility));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onSourceAdded: function(tray, source) {
|
||||||
|
if (source.trayIcon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (source.isTransient)
|
||||||
|
return;
|
||||||
|
|
||||||
|
source.connect('count-updated', Lang.bind(this, this._updateCount));
|
||||||
|
this._sources.push(source);
|
||||||
|
this._updateCount();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onSourceRemoved: function(tray, source) {
|
||||||
|
this._sources.splice(this._sources.indexOf(source), 1);
|
||||||
|
this._updateCount();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateCount: function() {
|
||||||
|
let count = 0;
|
||||||
|
let hasChats = false;
|
||||||
|
this._sources.forEach(Lang.bind(this,
|
||||||
|
function(source) {
|
||||||
|
count += source.indicatorCount;
|
||||||
|
hasChats |= source.isChat;
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._count = count;
|
||||||
|
this._label.text = ngettext("%d new message",
|
||||||
|
"%d new messages",
|
||||||
|
count).format(count);
|
||||||
|
|
||||||
|
this._icon.visible = hasChats;
|
||||||
|
this._updateVisibility();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateVisibility: function() {
|
||||||
|
let activePage = this._viewSelector.getActivePage();
|
||||||
|
let visible = ((this._count > 0) && (activePage == ViewSelector.ViewPage.WINDOWS));
|
||||||
|
|
||||||
|
this.actor.visible = visible;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const ControlsManager = new Lang.Class({
|
const ControlsManager = new Lang.Class({
|
||||||
Name: 'ControlsManager',
|
Name: 'ControlsManager',
|
||||||
|
|
||||||
_init: function(dash, thumbnails, viewSelector) {
|
_init: function(dash, thumbnails, viewSelector) {
|
||||||
this._dashSlider = new DashSlider(dash);
|
this._dashSlider = new DashSlider(dash);
|
||||||
this.dashActor = this._dashSlider.actor;
|
this.dashActor = this._dashSlider.actor;
|
||||||
|
this.dashSpacer = new DashSpacer();
|
||||||
|
this.dashSpacer.setDashActor(this.dashActor);
|
||||||
|
|
||||||
this._thumbnailsSlider = new ThumbnailsSlider(thumbnails);
|
this._thumbnailsSlider = new ThumbnailsSlider(thumbnails);
|
||||||
this.thumbnailsActor = this._thumbnailsSlider.actor;
|
this.thumbnailsActor = this._thumbnailsSlider.actor;
|
||||||
|
|
||||||
|
this._indicator = new MessagesIndicator(viewSelector);
|
||||||
|
this.indicatorActor = this._indicator.actor;
|
||||||
|
|
||||||
this._viewSelector = viewSelector;
|
this._viewSelector = viewSelector;
|
||||||
this._viewSelector.connect('page-changed', Lang.bind(this, this._setVisibility));
|
this._viewSelector.connect('page-changed', Lang.bind(this, this._setVisibility));
|
||||||
this._viewSelector.connect('page-empty', Lang.bind(this, this._onPageEmpty));
|
this._viewSelector.connect('page-empty', Lang.bind(this, this._onPageEmpty));
|
||||||
|
|
||||||
|
Main.overview.connect('showing', Lang.bind(this, this._updateSpacerVisibility));
|
||||||
|
Main.overview.connect('item-drag-begin', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
let activePage = this._viewSelector.getActivePage();
|
||||||
|
if (activePage != ViewSelector.ViewPage.WINDOWS)
|
||||||
|
this._viewSelector.fadeHalf();
|
||||||
|
}));
|
||||||
|
Main.overview.connect('item-drag-end', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._viewSelector.fadeIn();
|
||||||
|
}));
|
||||||
|
Main.overview.connect('item-drag-cancelled', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._viewSelector.fadeIn();
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
_setVisibility: function() {
|
_setVisibility: function() {
|
||||||
@@ -368,8 +537,18 @@ const ControlsManager = new Lang.Class({
|
|||||||
this._thumbnailsSlider.slideOut();
|
this._thumbnailsSlider.slideOut();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateSpacerVisibility: function() {
|
||||||
|
if (Main.overview.animationInProgress && !Main.overview.visibleTarget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let activePage = this._viewSelector.getActivePage();
|
||||||
|
this.dashSpacer.visible = (activePage == ViewSelector.ViewPage.WINDOWS);
|
||||||
|
},
|
||||||
|
|
||||||
_onPageEmpty: function() {
|
_onPageEmpty: function() {
|
||||||
this._dashSlider.pageEmpty();
|
this._dashSlider.pageEmpty();
|
||||||
this._thumbnailsSlider.pageEmpty();
|
this._thumbnailsSlider.pageEmpty();
|
||||||
|
|
||||||
|
this._updateSpacerVisibility();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ const Atk = imports.gi.Atk;
|
|||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||||
const DND = imports.ui.dnd;
|
const DND = imports.ui.dnd;
|
||||||
const Layout = imports.ui.layout;
|
|
||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
@@ -203,7 +202,7 @@ const TextShadower = new Lang.Class({
|
|||||||
let child = children[i];
|
let child = children[i];
|
||||||
let childBox = new Clutter.ActorBox();
|
let childBox = new Clutter.ActorBox();
|
||||||
// The order of the labels here is arbitrary, except
|
// The order of the labels here is arbitrary, except
|
||||||
// we know the "real" label is at the end because Clutter.Group
|
// we know the "real" label is at the end because Clutter.Actor
|
||||||
// sorts by Z order
|
// sorts by Z order
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0: // top
|
case 0: // top
|
||||||
@@ -630,23 +629,15 @@ const ActivitiesButton = new Lang.Class({
|
|||||||
this.parent(0.0, null, true);
|
this.parent(0.0, null, true);
|
||||||
this.actor.accessible_role = Atk.Role.TOGGLE_BUTTON;
|
this.actor.accessible_role = Atk.Role.TOGGLE_BUTTON;
|
||||||
|
|
||||||
let container = new Shell.GenericContainer();
|
|
||||||
container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
|
|
||||||
container.connect('get-preferred-height', Lang.bind(this, this._containerGetPreferredHeight));
|
|
||||||
container.connect('allocate', Lang.bind(this, this._containerAllocate));
|
|
||||||
this.actor.add_actor(container);
|
|
||||||
this.actor.name = 'panelActivities';
|
this.actor.name = 'panelActivities';
|
||||||
|
|
||||||
/* Translators: If there is no suitable word for "Activities"
|
/* Translators: If there is no suitable word for "Activities"
|
||||||
in your language, you can use the word for "Overview". */
|
in your language, you can use the word for "Overview". */
|
||||||
this._label = new St.Label({ text: _("Activities") });
|
this._label = new St.Label({ text: _("Activities") });
|
||||||
container.add_actor(this._label);
|
this.actor.add_actor(this._label);
|
||||||
|
|
||||||
this.actor.label_actor = this._label;
|
this.actor.label_actor = this._label;
|
||||||
|
|
||||||
this.hotCorner = new Layout.HotCorner(Main.layoutManager);
|
|
||||||
container.add_actor(this.hotCorner.actor);
|
|
||||||
|
|
||||||
this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
||||||
this.actor.connect_after('button-release-event', Lang.bind(this, this._onButtonRelease));
|
this.actor.connect_after('button-release-event', Lang.bind(this, this._onButtonRelease));
|
||||||
this.actor.connect_after('key-release-event', Lang.bind(this, this._onKeyRelease));
|
this.actor.connect_after('key-release-event', Lang.bind(this, this._onKeyRelease));
|
||||||
@@ -661,44 +652,6 @@ const ActivitiesButton = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
this._xdndTimeOut = 0;
|
this._xdndTimeOut = 0;
|
||||||
|
|
||||||
// Since the hot corner uses stage coordinates, Clutter won't
|
|
||||||
// queue relayouts for us when the panel moves. Queue a relayout
|
|
||||||
// when that happens.
|
|
||||||
Main.layoutManager.connect('panel-box-changed', Lang.bind(this, function() {
|
|
||||||
container.queue_relayout();
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
_containerGetPreferredWidth: function(actor, forHeight, alloc) {
|
|
||||||
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_width(forHeight);
|
|
||||||
},
|
|
||||||
|
|
||||||
_containerGetPreferredHeight: function(actor, forWidth, alloc) {
|
|
||||||
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_height(forWidth);
|
|
||||||
},
|
|
||||||
|
|
||||||
_containerAllocate: function(actor, box, flags) {
|
|
||||||
this._label.allocate(box, flags);
|
|
||||||
|
|
||||||
// The hot corner needs to be outside any padding/alignment
|
|
||||||
// that has been imposed on us
|
|
||||||
let primary = Main.layoutManager.primaryMonitor;
|
|
||||||
let hotBox = new Clutter.ActorBox();
|
|
||||||
let ok, x, y;
|
|
||||||
if (actor.get_text_direction() == Clutter.TextDirection.LTR) {
|
|
||||||
[ok, x, y] = actor.transform_stage_point(primary.x, primary.y)
|
|
||||||
} else {
|
|
||||||
[ok, x, y] = actor.transform_stage_point(primary.x + primary.width, primary.y);
|
|
||||||
// hotCorner.actor has northeast gravity, so we don't need
|
|
||||||
// to adjust x for its width
|
|
||||||
}
|
|
||||||
|
|
||||||
hotBox.x1 = Math.round(x);
|
|
||||||
hotBox.x2 = hotBox.x1 + this.hotCorner.actor.width;
|
|
||||||
hotBox.y1 = Math.round(y);
|
|
||||||
hotBox.y2 = hotBox.y1 + this.hotCorner.actor.height;
|
|
||||||
this.hotCorner.actor.allocate(hotBox, flags);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDragOver: function(source, actor, x, y, time) {
|
handleDragOver: function(source, actor, x, y, time) {
|
||||||
@@ -708,14 +661,14 @@ const ActivitiesButton = new Lang.Class({
|
|||||||
if (this._xdndTimeOut != 0)
|
if (this._xdndTimeOut != 0)
|
||||||
Mainloop.source_remove(this._xdndTimeOut);
|
Mainloop.source_remove(this._xdndTimeOut);
|
||||||
this._xdndTimeOut = Mainloop.timeout_add(BUTTON_DND_ACTIVATION_TIMEOUT,
|
this._xdndTimeOut = Mainloop.timeout_add(BUTTON_DND_ACTIVATION_TIMEOUT,
|
||||||
Lang.bind(this, this._xdndShowOverview, actor));
|
Lang.bind(this, this._xdndToggleOverview, actor));
|
||||||
|
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onCapturedEvent: function(actor, event) {
|
_onCapturedEvent: function(actor, event) {
|
||||||
if (event.type() == Clutter.EventType.BUTTON_PRESS) {
|
if (event.type() == Clutter.EventType.BUTTON_PRESS) {
|
||||||
if (!this.hotCorner.shouldToggleOverviewOnClick())
|
if (!Main.overview.shouldToggleByCornerOrButton())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -732,15 +685,12 @@ const ActivitiesButton = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_xdndShowOverview: function(actor) {
|
_xdndToggleOverview: function(actor) {
|
||||||
let [x, y, mask] = global.get_pointer();
|
let [x, y, mask] = global.get_pointer();
|
||||||
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
|
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
|
||||||
|
|
||||||
if (pickedActor == this.actor) {
|
if (pickedActor == this.actor && Main.overview.shouldToggleByCornerOrButton())
|
||||||
if (!Main.overview.visible && !Main.overview.animationInProgress) {
|
Main.overview.toggle();
|
||||||
Main.overview.showTemporarily();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Mainloop.source_remove(this._xdndTimeOut);
|
Mainloop.source_remove(this._xdndTimeOut);
|
||||||
this._xdndTimeOut = 0;
|
this._xdndTimeOut = 0;
|
||||||
|
|||||||
@@ -2086,7 +2086,7 @@ const PopupMenuManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
removeMenu: function(menu) {
|
removeMenu: function(menu) {
|
||||||
if (menu == this._activeMenu)
|
if (menu == this.activeMenu)
|
||||||
this._closeMenu(menu);
|
this._closeMenu(menu);
|
||||||
|
|
||||||
let position = this._findMenu(menu);
|
let position = this._findMenu(menu);
|
||||||
@@ -2110,9 +2110,9 @@ const PopupMenuManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
get activeMenu() {
|
get activeMenu() {
|
||||||
let actor = this._grabHelper.currentGrab.actor;
|
let firstGrab = this._grabHelper.grabStack[0];
|
||||||
if (actor)
|
if (firstGrab)
|
||||||
return actor._delegate;
|
return firstGrab.actor._delegate;
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -127,8 +127,6 @@ function remoteProvidersLoaded(loadState) {
|
|||||||
// Special case gnome-control-center to be always active and always first
|
// Special case gnome-control-center to be always active and always first
|
||||||
sortOrder.unshift('gnome-control-center.desktop');
|
sortOrder.unshift('gnome-control-center.desktop');
|
||||||
|
|
||||||
let numSorted = sortOrder.length;
|
|
||||||
|
|
||||||
loadState.loadedProviders.sort(
|
loadState.loadedProviders.sort(
|
||||||
function(providerA, providerB) {
|
function(providerA, providerB) {
|
||||||
let idxA, idxB;
|
let idxA, idxB;
|
||||||
@@ -148,15 +146,6 @@ function remoteProvidersLoaded(loadState) {
|
|||||||
return GLib.utf8_collate(nameA, nameB);
|
return GLib.utf8_collate(nameA, nameB);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numSorted > 1) {
|
|
||||||
// if providerA is the last, it goes after everything
|
|
||||||
if ((idxA + 1) == numSorted)
|
|
||||||
return 1;
|
|
||||||
// if providerB is the last, it goes after everything
|
|
||||||
else if ((idxB + 1) == numSorted)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if providerA isn't found, it's sorted after providerB
|
// if providerA isn't found, it's sorted after providerB
|
||||||
if (idxA == -1)
|
if (idxA == -1)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -255,6 +244,7 @@ const RemoteSearchProvider = new Lang.Class({
|
|||||||
metas[i][prop] = metas[i][prop].deep_unpack();
|
metas[i][prop] = metas[i][prop].deep_unpack();
|
||||||
resultMetas.push({ id: metas[i]['id'],
|
resultMetas.push({ id: metas[i]['id'],
|
||||||
name: metas[i]['name'],
|
name: metas[i]['name'],
|
||||||
|
description: metas[i]['description'],
|
||||||
createIcon: Lang.bind(this,
|
createIcon: Lang.bind(this,
|
||||||
this.createIcon, metas[i]) });
|
this.createIcon, metas[i]) });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,138 +30,6 @@ const EXEC_ARG_KEY = 'exec-arg';
|
|||||||
|
|
||||||
const DIALOG_GROW_TIME = 0.1;
|
const DIALOG_GROW_TIME = 0.1;
|
||||||
|
|
||||||
const CommandCompleter = new Lang.Class({
|
|
||||||
Name: 'CommandCompleter',
|
|
||||||
|
|
||||||
_init : function() {
|
|
||||||
this._changedCount = 0;
|
|
||||||
this._paths = GLib.getenv('PATH').split(':');
|
|
||||||
this._paths.push(GLib.get_home_dir());
|
|
||||||
this._valid = false;
|
|
||||||
this._updateInProgress = false;
|
|
||||||
this._childs = new Array(this._paths.length);
|
|
||||||
this._monitors = new Array(this._paths.length);
|
|
||||||
for (let i = 0; i < this._paths.length; i++) {
|
|
||||||
this._childs[i] = [];
|
|
||||||
let file = Gio.file_new_for_path(this._paths[i]);
|
|
||||||
let info;
|
|
||||||
try {
|
|
||||||
info = file.query_info(Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE, null);
|
|
||||||
} catch (e) {
|
|
||||||
// FIXME catchall
|
|
||||||
this._paths[i] = null;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.get_attribute_uint32(Gio.FILE_ATTRIBUTE_STANDARD_TYPE) != Gio.FileType.DIRECTORY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
this._paths[i] = file.get_path();
|
|
||||||
this._monitors[i] = file.monitor_directory(Gio.FileMonitorFlags.NONE, null);
|
|
||||||
if (this._monitors[i] != null) {
|
|
||||||
this._monitors[i].connect('changed', Lang.bind(this, this._onChanged));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._paths = this._paths.filter(function(a) {
|
|
||||||
return a != null;
|
|
||||||
});
|
|
||||||
this._update(0);
|
|
||||||
},
|
|
||||||
|
|
||||||
update : function() {
|
|
||||||
if (this._valid)
|
|
||||||
return;
|
|
||||||
this._update(0);
|
|
||||||
},
|
|
||||||
|
|
||||||
_update : function(i) {
|
|
||||||
if (i == 0 && this._updateInProgress)
|
|
||||||
return;
|
|
||||||
this._updateInProgress = true;
|
|
||||||
this._changedCount = 0;
|
|
||||||
this._i = i;
|
|
||||||
if (i >= this._paths.length) {
|
|
||||||
this._valid = true;
|
|
||||||
this._updateInProgress = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let file = Gio.file_new_for_path(this._paths[i]);
|
|
||||||
this._childs[this._i] = [];
|
|
||||||
FileUtils.listDirAsync(file, Lang.bind(this, function (files) {
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
|
||||||
this._childs[this._i].push(files[i].get_name());
|
|
||||||
}
|
|
||||||
this._update(this._i + 1);
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
_onChanged : function(m, f, of, type) {
|
|
||||||
if (!this._valid)
|
|
||||||
return;
|
|
||||||
let path = f.get_parent().get_path();
|
|
||||||
let k = undefined;
|
|
||||||
for (let i = 0; i < this._paths.length; i++) {
|
|
||||||
if (this._paths[i] == path)
|
|
||||||
k = i;
|
|
||||||
}
|
|
||||||
if (k === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (type == Gio.FileMonitorEvent.CREATED) {
|
|
||||||
this._childs[k].push(f.get_basename());
|
|
||||||
}
|
|
||||||
if (type == Gio.FileMonitorEvent.DELETED) {
|
|
||||||
this._changedCount++;
|
|
||||||
if (this._changedCount > MAX_FILE_DELETED_BEFORE_INVALID) {
|
|
||||||
this._valid = false;
|
|
||||||
}
|
|
||||||
let name = f.get_basename();
|
|
||||||
this._childs[k] = this._childs[k].filter(function(e) {
|
|
||||||
return e != name;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (type == Gio.FileMonitorEvent.UNMOUNTED) {
|
|
||||||
this._childs[k] = [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getCompletion: function(text) {
|
|
||||||
let common = '';
|
|
||||||
let notInit = true;
|
|
||||||
if (!this._valid) {
|
|
||||||
this._update(0);
|
|
||||||
return common;
|
|
||||||
}
|
|
||||||
function _getCommon(s1, s2) {
|
|
||||||
let k = 0;
|
|
||||||
for (; k < s1.length && k < s2.length; k++) {
|
|
||||||
if (s1[k] != s2[k])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (k == 0)
|
|
||||||
return '';
|
|
||||||
return s1.substr(0, k);
|
|
||||||
}
|
|
||||||
function _hasPrefix(s1, prefix) {
|
|
||||||
return s1.indexOf(prefix) == 0;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < this._childs.length; i++) {
|
|
||||||
for (let k = 0; k < this._childs[i].length; k++) {
|
|
||||||
if (!_hasPrefix(this._childs[i][k], text))
|
|
||||||
continue;
|
|
||||||
if (notInit) {
|
|
||||||
common = this._childs[i][k];
|
|
||||||
notInit = false;
|
|
||||||
}
|
|
||||||
common = _getCommon(common, this._childs[i][k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (common.length)
|
|
||||||
return common.substr(text.length);
|
|
||||||
return common;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const RunDialog = new Lang.Class({
|
const RunDialog = new Lang.Class({
|
||||||
Name: 'RunDialog',
|
Name: 'RunDialog',
|
||||||
Extends: ModalDialog.ModalDialog,
|
Extends: ModalDialog.ModalDialog,
|
||||||
@@ -242,8 +110,6 @@ const RunDialog = new Lang.Class({
|
|||||||
key: Clutter.Escape }]);
|
key: Clutter.Escape }]);
|
||||||
|
|
||||||
this._pathCompleter = new Gio.FilenameCompleter();
|
this._pathCompleter = new Gio.FilenameCompleter();
|
||||||
this._commandCompleter = new CommandCompleter();
|
|
||||||
this._group.connect('notify::visible', Lang.bind(this._commandCompleter, this._commandCompleter.update));
|
|
||||||
|
|
||||||
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
|
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
|
||||||
entry: this._entryText });
|
entry: this._entryText });
|
||||||
@@ -259,18 +125,6 @@ const RunDialog = new Lang.Class({
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (symbol == Clutter.slash) {
|
|
||||||
// Need preload data before get completion. GFilenameCompleter load content of parent directory.
|
|
||||||
// Parent directory for /usr/include/ is /usr/. So need to add fake name('a').
|
|
||||||
let text = o.get_text().concat('/a');
|
|
||||||
let prefix;
|
|
||||||
if (text.lastIndexOf(' ') == -1)
|
|
||||||
prefix = text;
|
|
||||||
else
|
|
||||||
prefix = text.substr(text.lastIndexOf(' ') + 1);
|
|
||||||
this._getCompletion(prefix);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (symbol == Clutter.Tab) {
|
if (symbol == Clutter.Tab) {
|
||||||
let text = o.get_text();
|
let text = o.get_text();
|
||||||
let prefix;
|
let prefix;
|
||||||
@@ -282,8 +136,6 @@ const RunDialog = new Lang.Class({
|
|||||||
if (postfix != null && postfix.length > 0) {
|
if (postfix != null && postfix.length > 0) {
|
||||||
o.insert_text(postfix, -1);
|
o.insert_text(postfix, -1);
|
||||||
o.set_cursor_position(text.length + postfix.length);
|
o.set_cursor_position(text.length + postfix.length);
|
||||||
if (postfix[postfix.length - 1] == '/')
|
|
||||||
this._getCompletion(text + postfix + 'a');
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -291,11 +143,53 @@ const RunDialog = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getCommandCompletion: function(text) {
|
||||||
|
function _getCommon(s1, s2) {
|
||||||
|
if (s1 == null)
|
||||||
|
return s2;
|
||||||
|
|
||||||
|
let k = 0;
|
||||||
|
for (; k < s1.length && k < s2.length; k++) {
|
||||||
|
if (s1[k] != s2[k])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (k == 0)
|
||||||
|
return '';
|
||||||
|
return s1.substr(0, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
let paths = GLib.getenv('PATH').split(':');
|
||||||
|
paths.push(GLib.get_home_dir());
|
||||||
|
let someResults = paths.map(function(path) {
|
||||||
|
let results = [];
|
||||||
|
try {
|
||||||
|
let file = Gio.File.new_for_path(path);
|
||||||
|
let fileEnum = file.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, null);
|
||||||
|
let info;
|
||||||
|
while ((info = fileEnum.next_file(null))) {
|
||||||
|
let name = info.get_name();
|
||||||
|
if (name.slice(0, text.length) == text)
|
||||||
|
results.push(name);
|
||||||
|
}
|
||||||
|
} catch (e if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) &&
|
||||||
|
!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_DIRECTORY))) {
|
||||||
|
log(e);
|
||||||
|
} finally {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let results = someResults.reduce(function(a, b) {
|
||||||
|
return a.concat(b);
|
||||||
|
}, []);
|
||||||
|
let common = results.reduce(_getCommon, null);
|
||||||
|
return common.substr(text.length);
|
||||||
|
},
|
||||||
|
|
||||||
_getCompletion : function(text) {
|
_getCompletion : function(text) {
|
||||||
if (text.indexOf('/') != -1) {
|
if (text.indexOf('/') != -1) {
|
||||||
return this._pathCompleter.get_completion_suffix(text);
|
return this._pathCompleter.get_completion_suffix(text);
|
||||||
} else {
|
} else {
|
||||||
return this._commandCompleter.getCompletion(text);
|
return this._getCommandCompletion(text);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -38,11 +38,7 @@ const ARROW_DRAG_THRESHOLD = 0.1;
|
|||||||
const N_ARROWS = 3;
|
const N_ARROWS = 3;
|
||||||
const ARROW_ANIMATION_TIME = 0.6;
|
const ARROW_ANIMATION_TIME = 0.6;
|
||||||
const ARROW_ANIMATION_PEAK_OPACITY = 0.4;
|
const ARROW_ANIMATION_PEAK_OPACITY = 0.4;
|
||||||
|
const ARROW_IDLE_TIME = 30000; // ms
|
||||||
// The distance in px that the lock screen will move to when pressing
|
|
||||||
// a key that has no effect in the lock screen (bumping it)
|
|
||||||
const BUMP_SIZE = 25;
|
|
||||||
const BUMP_TIME = 0.3;
|
|
||||||
|
|
||||||
const SUMMARY_ICON_SIZE = 48;
|
const SUMMARY_ICON_SIZE = 48;
|
||||||
|
|
||||||
@@ -54,7 +50,7 @@ const SUMMARY_ICON_SIZE = 48;
|
|||||||
// - CURTAIN_SLIDE_TIME is used when raising the shield before unlocking
|
// - CURTAIN_SLIDE_TIME is used when raising the shield before unlocking
|
||||||
// - INITIAL_FADE_IN_TIME is used for the initial fade in at startup
|
// - INITIAL_FADE_IN_TIME is used for the initial fade in at startup
|
||||||
const STANDARD_FADE_TIME = 10;
|
const STANDARD_FADE_TIME = 10;
|
||||||
const MANUAL_FADE_TIME = 0.8;
|
const MANUAL_FADE_TIME = 0.3;
|
||||||
const BACKGROUND_FADE_TIME = 1.0;
|
const BACKGROUND_FADE_TIME = 1.0;
|
||||||
const CURTAIN_SLIDE_TIME = 0.3;
|
const CURTAIN_SLIDE_TIME = 0.3;
|
||||||
const INITIAL_FADE_IN_TIME = 0.25;
|
const INITIAL_FADE_IN_TIME = 0.25;
|
||||||
@@ -435,8 +431,8 @@ const ScreenShield = new Lang.Class({
|
|||||||
name: 'lockScreenGroup',
|
name: 'lockScreenGroup',
|
||||||
visible: false,
|
visible: false,
|
||||||
});
|
});
|
||||||
this._lockScreenGroup.connect('key-release-event',
|
this._lockScreenGroup.connect('key-press-event',
|
||||||
Lang.bind(this, this._onLockScreenKeyRelease));
|
Lang.bind(this, this._onLockScreenKeyPress));
|
||||||
this._lockScreenGroup.connect('scroll-event',
|
this._lockScreenGroup.connect('scroll-event',
|
||||||
Lang.bind(this, this._onLockScreenScroll));
|
Lang.bind(this, this._onLockScreenScroll));
|
||||||
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
|
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
|
||||||
@@ -447,7 +443,7 @@ const ScreenShield = new Lang.Class({
|
|||||||
|
|
||||||
this._lockScreenGroup.add_actor(this._lockScreenContents);
|
this._lockScreenGroup.add_actor(this._lockScreenContents);
|
||||||
|
|
||||||
this._backgroundGroup = new Meta.BackgroundGroup();
|
this._backgroundGroup = new Clutter.Actor();
|
||||||
|
|
||||||
this._lockScreenGroup.add_actor(this._backgroundGroup);
|
this._lockScreenGroup.add_actor(this._backgroundGroup);
|
||||||
this._backgroundGroup.lower_bottom();
|
this._backgroundGroup.lower_bottom();
|
||||||
@@ -456,6 +452,9 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._updateBackgrounds();
|
this._updateBackgrounds();
|
||||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateBackgrounds));
|
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateBackgrounds));
|
||||||
|
|
||||||
|
this._arrowAnimationId = 0;
|
||||||
|
this._arrowWatchId = 0;
|
||||||
|
this._arrowActiveWatchId = 0;
|
||||||
this._arrowContainer = new St.BoxLayout({ style_class: 'screen-shield-arrows',
|
this._arrowContainer = new St.BoxLayout({ style_class: 'screen-shield-arrows',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
x_align: Clutter.ActorAlign.CENTER,
|
x_align: Clutter.ActorAlign.CENTER,
|
||||||
@@ -507,14 +506,18 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
|
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
|
||||||
|
|
||||||
this._inhibitor = null;
|
this._inhibitor = null;
|
||||||
|
this._aboutToSuspend = false;
|
||||||
this._loginManager = LoginManager.getLoginManager();
|
this._loginManager = LoginManager.getLoginManager();
|
||||||
this._loginManager.connect('prepare-for-sleep',
|
this._loginManager.connect('prepare-for-sleep',
|
||||||
Lang.bind(this, this._prepareForSleep));
|
Lang.bind(this, this._prepareForSleep));
|
||||||
this._inhibitSuspend();
|
this._inhibitSuspend();
|
||||||
|
|
||||||
this._loginSession = this._loginManager.getCurrentSessionProxy();
|
this._loginManager.getCurrentSessionProxy(Lang.bind(this,
|
||||||
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
|
function(sessionProxy) {
|
||||||
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.deactivate(false); }));
|
this._loginSession = sessionProxy;
|
||||||
|
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
|
||||||
|
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.deactivate(false); }));
|
||||||
|
}));
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
|
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
|
||||||
|
|
||||||
@@ -538,21 +541,20 @@ const ScreenShield = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_createBackground: function(monitorIndex) {
|
_createBackground: function(monitorIndex) {
|
||||||
let bin = new St.Bin({ style_class: 'screen-shield-background' });
|
let monitor = Main.layoutManager.monitors[monitorIndex];
|
||||||
|
let widget = new St.Widget({ style_class: 'screen-shield-background',
|
||||||
|
x: monitor.x,
|
||||||
|
y: monitor.y,
|
||||||
|
width: monitor.width,
|
||||||
|
height: monitor.height });
|
||||||
|
|
||||||
let group = new Meta.BackgroundGroup();
|
let bgManager = new Background.BackgroundManager({ container: widget,
|
||||||
bin.child = group;
|
|
||||||
|
|
||||||
let bgManager = new Background.BackgroundManager({ container: group,
|
|
||||||
monitorIndex: monitorIndex,
|
monitorIndex: monitorIndex,
|
||||||
effects: Meta.BackgroundEffects.BLUR | Meta.BackgroundEffects.DESATURATE });
|
controlPosition: false });
|
||||||
|
|
||||||
bgManager.background.saturation = 0.6;
|
|
||||||
|
|
||||||
this._bgManagers.push(bgManager);
|
this._bgManagers.push(bgManager);
|
||||||
|
|
||||||
this._backgroundGroup.add_child(bin);
|
this._backgroundGroup.add_child(widget);
|
||||||
bin.lower_bottom();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateBackgrounds: function() {
|
_updateBackgrounds: function() {
|
||||||
@@ -589,28 +591,28 @@ const ScreenShield = new Lang.Class({
|
|||||||
return this._isModal;
|
return this._isModal;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onLockScreenKeyRelease: function(actor, event) {
|
_onLockScreenKeyPress: function(actor, event) {
|
||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
|
let unichar = event.get_key_unicode();
|
||||||
|
|
||||||
// Do nothing if the lock screen is not fully shown.
|
// Do nothing if the lock screen is not fully shown.
|
||||||
// This avoids reusing the previous (and stale) unlock
|
// This avoids reusing the previous (and stale) unlock
|
||||||
// dialog if esc is pressed while the curtain is going
|
// dialog if esc is pressed while the curtain is going
|
||||||
// down after cancel.
|
// down after cancel.
|
||||||
// Similarly, don't bump if the lock screen is not showing or is
|
|
||||||
// animating, as the bump overrides the animation and would
|
|
||||||
// remove any onComplete handler.
|
|
||||||
|
|
||||||
if (this._lockScreenState != MessageTray.State.SHOWN)
|
if (this._lockScreenState != MessageTray.State.SHOWN)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (symbol == Clutter.KEY_Escape ||
|
let isEnter = (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_KP_Enter);
|
||||||
symbol == Clutter.KEY_Return ||
|
if (!isEnter && !(GLib.unichar_isprint(unichar) || symbol == Clutter.KEY_Escape))
|
||||||
symbol == Clutter.KEY_KP_Enter) {
|
return false;
|
||||||
this._liftShield(false, 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._bumpLockScreen();
|
this._ensureUnlockDialog(true, true);
|
||||||
|
|
||||||
|
if (GLib.unichar_isgraph(unichar))
|
||||||
|
this._dialog.addCharacter(unichar);
|
||||||
|
|
||||||
|
this._liftShield(true, 0);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -648,6 +650,8 @@ const ScreenShield = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_prepareForSleep: function(loginManager, aboutToSuspend) {
|
_prepareForSleep: function(loginManager, aboutToSuspend) {
|
||||||
|
this._aboutToSuspend = aboutToSuspend;
|
||||||
|
|
||||||
if (aboutToSuspend) {
|
if (aboutToSuspend) {
|
||||||
if (!this._settings.get_boolean(LOCK_ENABLED_KEY)) {
|
if (!this._settings.get_boolean(LOCK_ENABLED_KEY)) {
|
||||||
this._uninhibitSuspend();
|
this._uninhibitSuspend();
|
||||||
@@ -848,19 +852,12 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._hideLockScreen(false, 0);
|
this._hideLockScreen(false, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
_bumpLockScreen: function() {
|
_hideLockScreenComplete: function() {
|
||||||
Tweener.removeTweens(this._lockScreenGroup);
|
if (Main.sessionMode.currentMode == 'lock-screen')
|
||||||
Tweener.addTween(this._lockScreenGroup,
|
Main.sessionMode.popMode('lock-screen');
|
||||||
{ y: -BUMP_SIZE,
|
|
||||||
time: BUMP_TIME / 2,
|
this._lockScreenState = MessageTray.State.HIDDEN;
|
||||||
transition: 'easeOutQuad',
|
this._lockScreenGroup.hide();
|
||||||
onComplete: function() {
|
|
||||||
Tweener.addTween(this,
|
|
||||||
{ y: 0,
|
|
||||||
time: BUMP_TIME / 2,
|
|
||||||
transition: 'easeInQuad' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_hideLockScreen: function(animate, velocity) {
|
_hideLockScreen: function(animate, velocity) {
|
||||||
@@ -886,21 +883,13 @@ const ScreenShield = new Lang.Class({
|
|||||||
{ y: -h,
|
{ y: -h,
|
||||||
time: time,
|
time: time,
|
||||||
transition: 'easeInQuad',
|
transition: 'easeInQuad',
|
||||||
onComplete: function() {
|
onComplete: Lang.bind(this, this._hideLockScreenComplete),
|
||||||
this._lockScreenState = MessageTray.State.HIDDEN;
|
|
||||||
this._lockScreenGroup.hide();
|
|
||||||
},
|
|
||||||
onCompleteScope: this,
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this._lockScreenState = MessageTray.State.HIDDEN;
|
this._hideLockScreenComplete();
|
||||||
this._lockScreenGroup.hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
global.stage.show_cursor();
|
global.stage.show_cursor();
|
||||||
|
|
||||||
if (Main.sessionMode.currentMode == 'lock-screen')
|
|
||||||
Main.sessionMode.popMode('lock-screen');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_ensureUnlockDialog: function(onPrimary, allowCancel) {
|
_ensureUnlockDialog: function(onPrimary, allowCancel) {
|
||||||
@@ -916,14 +905,12 @@ const ScreenShield = new Lang.Class({
|
|||||||
|
|
||||||
|
|
||||||
let time = global.get_current_time();
|
let time = global.get_current_time();
|
||||||
this._dialog.connect('loaded', Lang.bind(this, function() {
|
if (!this._dialog.open(time, onPrimary)) {
|
||||||
if (!this._dialog.open(time, onPrimary)) {
|
// This is kind of an impossible error: we're already modal
|
||||||
// This is kind of an impossible error: we're already modal
|
// by the time we reach this...
|
||||||
// by the time we reach this...
|
log('Could not open login dialog: failed to acquire grab');
|
||||||
log('Could not open login dialog: failed to acquire grab');
|
this.deactivate(true);
|
||||||
this.deactivate(true);
|
}
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed));
|
this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed));
|
||||||
this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded));
|
this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded));
|
||||||
@@ -989,16 +976,60 @@ const ScreenShield = new Lang.Class({
|
|||||||
Main.sessionMode.pushMode('lock-screen');
|
Main.sessionMode.pushMode('lock-screen');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_startArrowAnimation: function() {
|
||||||
|
this._arrowActiveWatchId = 0;
|
||||||
|
|
||||||
|
if (!this._arrowAnimationId) {
|
||||||
|
this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows));
|
||||||
|
this._animateArrows();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._arrowWatchId)
|
||||||
|
this._arrowWatchId = this.idleMonitor.add_idle_watch(ARROW_IDLE_TIME,
|
||||||
|
Lang.bind(this, this._pauseArrowAnimation));
|
||||||
|
},
|
||||||
|
|
||||||
|
_pauseArrowAnimation: function() {
|
||||||
|
if (this._arrowAnimationId) {
|
||||||
|
Mainloop.source_remove(this._arrowAnimationId);
|
||||||
|
this._arrowAnimationId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._arrowActiveWatchId)
|
||||||
|
this._arrowActiveWatchId = this.idleMonitor.add_user_active_watch(Lang.bind(this, this._startArrowAnimation));
|
||||||
|
},
|
||||||
|
|
||||||
|
_stopArrowAnimation: function() {
|
||||||
|
if (this._arrowAnimationId) {
|
||||||
|
Mainloop.source_remove(this._arrowAnimationId);
|
||||||
|
this._arrowAnimationId = 0;
|
||||||
|
}
|
||||||
|
if (this._arrowActiveWatchId) {
|
||||||
|
this.idleMonitor.remove_watch(this._arrowActiveWatchId);
|
||||||
|
this._arrowActiveWatchId = 0;
|
||||||
|
}
|
||||||
|
if (this._arrowWatchId) {
|
||||||
|
this.idleMonitor.remove_watch(this._arrowWatchId);
|
||||||
|
this._arrowWatchId = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_checkArrowAnimation: function() {
|
||||||
|
let idleTime = this.idleMonitor.get_idletime();
|
||||||
|
|
||||||
|
if (idleTime < ARROW_IDLE_TIME)
|
||||||
|
this._startArrowAnimation();
|
||||||
|
else
|
||||||
|
this._pauseArrowAnimation();
|
||||||
|
},
|
||||||
|
|
||||||
_lockScreenShown: function() {
|
_lockScreenShown: function() {
|
||||||
if (this._dialog && !this._isGreeter) {
|
if (this._dialog && !this._isGreeter) {
|
||||||
this._dialog.destroy();
|
this._dialog.destroy();
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._arrowAnimationId)
|
this._checkArrowAnimation();
|
||||||
Mainloop.source_remove(this._arrowAnimationId);
|
|
||||||
this._arrowAnimationId = Mainloop.timeout_add(6000, Lang.bind(this, this._animateArrows));
|
|
||||||
this._animateArrows();
|
|
||||||
|
|
||||||
let motionId = global.stage.connect('captured-event', function(stage, event) {
|
let motionId = global.stage.connect('captured-event', function(stage, event) {
|
||||||
if (event.type() == Clutter.EventType.MOTION) {
|
if (event.type() == Clutter.EventType.MOTION) {
|
||||||
@@ -1020,7 +1051,8 @@ const ScreenShield = new Lang.Class({
|
|||||||
if (prevIsActive != this._isActive)
|
if (prevIsActive != this._isActive)
|
||||||
this.emit('active-changed');
|
this.emit('active-changed');
|
||||||
|
|
||||||
this._uninhibitSuspend();
|
if (this._aboutToSuspend)
|
||||||
|
this._uninhibitSuspend();
|
||||||
|
|
||||||
this.emit('lock-screen-shown');
|
this.emit('lock-screen-shown');
|
||||||
},
|
},
|
||||||
@@ -1060,12 +1092,9 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._notificationsBox = null;
|
this._notificationsBox = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lockScreenContentsBox.destroy();
|
this._stopArrowAnimation();
|
||||||
|
|
||||||
if (this._arrowAnimationId) {
|
this._lockScreenContentsBox.destroy();
|
||||||
Mainloop.source_remove(this._arrowAnimationId);
|
|
||||||
this._arrowAnimationId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._hasLockScreen = false;
|
this._hasLockScreen = false;
|
||||||
},
|
},
|
||||||
@@ -1177,62 +1206,3 @@ const ScreenShield = new Lang.Class({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(ScreenShield.prototype);
|
Signals.addSignalMethods(ScreenShield.prototype);
|
||||||
|
|
||||||
/* Fallback code to handle session locking using gnome-screensaver,
|
|
||||||
in case the required GDM dependency is not there
|
|
||||||
*/
|
|
||||||
const ScreenShieldFallback = new Lang.Class({
|
|
||||||
Name: 'ScreenShieldFallback',
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
Util.spawn(['gnome-screensaver']);
|
|
||||||
|
|
||||||
this._proxy = new Gio.DBusProxy({ g_connection: Gio.DBus.session,
|
|
||||||
g_name: 'org.gnome.ScreenSaver',
|
|
||||||
g_object_path: '/org/gnome/ScreenSaver',
|
|
||||||
g_interface_name: 'org.gnome.ScreenSaver',
|
|
||||||
g_flags: (Gio.DBusProxyFlags.DO_NOT_AUTO_START |
|
|
||||||
Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES),
|
|
||||||
});
|
|
||||||
this._proxy.init(null);
|
|
||||||
|
|
||||||
this._proxy.connect('g-signal', Lang.bind(this, this._onSignal));
|
|
||||||
this._proxy.connect('notify::g-name-owner', Lang.bind(this, this._onNameOwnerChanged));
|
|
||||||
},
|
|
||||||
|
|
||||||
_onNameOwnerChanged: function(object, pspec) {
|
|
||||||
if (this._proxy.g_name_owner)
|
|
||||||
[this._locked] = this._proxy.call_sync('GetActive', null,
|
|
||||||
Gio.DBusCallFlags.NONE, -1, null).deep_unpack();
|
|
||||||
else
|
|
||||||
this._locked = false;
|
|
||||||
|
|
||||||
this.emit('active-changed', this._locked);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onSignal: function(proxy, senderName, signalName, params) {
|
|
||||||
if (signalName == 'ActiveChanged') {
|
|
||||||
[this._locked] = params.deep_unpack();
|
|
||||||
this.emit('active-changed', this._locked);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get locked() {
|
|
||||||
return this._locked;
|
|
||||||
},
|
|
||||||
|
|
||||||
lock: function() {
|
|
||||||
this._proxy.call('Lock', null, Gio.DBusCallFlags.NONE, -1, null,
|
|
||||||
Lang.bind(this, function(proxy, result) {
|
|
||||||
proxy.call_finish(result);
|
|
||||||
|
|
||||||
this.emit('lock-screen-shown');
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
unlock: function() {
|
|
||||||
this._proxy.call('SetActive', GLib.Variant.new('(b)', false),
|
|
||||||
Gio.DBusCallFlags.NONE, -1, null, null);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
Signals.addSignalMethods(ScreenShieldFallback.prototype);
|
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ const ScreenshotService = new Lang.Class({
|
|||||||
|
|
||||||
ScreenshotAreaAsync : function (params, invocation) {
|
ScreenshotAreaAsync : function (params, invocation) {
|
||||||
let [x, y, width, height, flash, filename, callback] = params;
|
let [x, y, width, height, flash, filename, callback] = params;
|
||||||
|
if (height <= 0 || width <= 0) {
|
||||||
|
invocation.return_error_literal(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,
|
||||||
|
"Invalid params");
|
||||||
|
return;
|
||||||
|
}
|
||||||
let screenshot = new Shell.Screenshot();
|
let screenshot = new Shell.Screenshot();
|
||||||
screenshot.screenshot_area (x, y, width, height, filename,
|
screenshot.screenshot_area (x, y, width, height, filename,
|
||||||
Lang.bind(this, this._onScreenshotComplete,
|
Lang.bind(this, this._onScreenshotComplete,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
|
|||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Gtk = imports.gi.Gtk;
|
const Gtk = imports.gi.Gtk;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Atk = imports.gi.Atk;
|
const Atk = imports.gi.Atk;
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ const Main = imports.ui.main;
|
|||||||
const Overview = imports.ui.overview;
|
const Overview = imports.ui.overview;
|
||||||
const Separator = imports.ui.separator;
|
const Separator = imports.ui.separator;
|
||||||
const Search = imports.ui.search;
|
const Search = imports.ui.search;
|
||||||
|
const Util = imports.misc.util;
|
||||||
|
|
||||||
const MAX_LIST_SEARCH_RESULTS_ROWS = 3;
|
const MAX_LIST_SEARCH_RESULTS_ROWS = 3;
|
||||||
const MAX_GRID_SEARCH_RESULTS_ROWS = 1;
|
const MAX_GRID_SEARCH_RESULTS_ROWS = 1;
|
||||||
@@ -102,11 +104,11 @@ const ListSearchResult = new Lang.Class({
|
|||||||
y_fill: false,
|
y_fill: false,
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
y_align: St.Align.START });
|
y_align: St.Align.START });
|
||||||
|
this.actor.label_actor = title;
|
||||||
|
|
||||||
// TODO: should highlight terms in the description here
|
|
||||||
if (this.metaInfo['description']) {
|
if (this.metaInfo['description']) {
|
||||||
let description = new St.Label({ style_class: 'list-search-result-description',
|
let description = new St.Label({ style_class: 'list-search-result-description' });
|
||||||
text: '"' + this.metaInfo['description'] + '"' });
|
description.clutter_text.set_markup(this.metaInfo['description']);
|
||||||
details.add(description, { x_fill: false,
|
details.add(description, { x_fill: false,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
@@ -140,6 +142,7 @@ const GridSearchResult = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.actor.set_child(content);
|
this.actor.set_child(content);
|
||||||
|
this.actor.label_actor = content.label_actor;
|
||||||
|
|
||||||
let draggable = DND.makeDraggable(this.actor);
|
let draggable = DND.makeDraggable(this.actor);
|
||||||
draggable.connect('drag-begin',
|
draggable.connect('drag-begin',
|
||||||
@@ -228,9 +231,14 @@ const ListSearchResults = new Lang.Class({
|
|||||||
this._pendingClear = true;
|
this._pendingClear = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_keyFocusIn: function(icon) {
|
||||||
|
this.emit('key-focus-in', icon);
|
||||||
|
},
|
||||||
|
|
||||||
renderResults: function(metas) {
|
renderResults: function(metas) {
|
||||||
for (let i = 0; i < metas.length; i++) {
|
for (let i = 0; i < metas.length; i++) {
|
||||||
let display = new ListSearchResult(this.provider, metas[i], this._terms);
|
let display = new ListSearchResult(this.provider, metas[i], this._terms);
|
||||||
|
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||||
this._content.add_actor(display.actor);
|
this._content.add_actor(display.actor);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -247,6 +255,7 @@ const ListSearchResults = new Lang.Class({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Signals.addSignalMethods(ListSearchResults.prototype);
|
||||||
|
|
||||||
const GridSearchResults = new Lang.Class({
|
const GridSearchResults = new Lang.Class({
|
||||||
Name: 'GridSearchResults',
|
Name: 'GridSearchResults',
|
||||||
@@ -289,9 +298,14 @@ const GridSearchResults = new Lang.Class({
|
|||||||
this._pendingClear = true;
|
this._pendingClear = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_keyFocusIn: function(icon) {
|
||||||
|
this.emit('key-focus-in', icon);
|
||||||
|
},
|
||||||
|
|
||||||
renderResults: function(metas) {
|
renderResults: function(metas) {
|
||||||
for (let i = 0; i < metas.length; i++) {
|
for (let i = 0; i < metas.length; i++) {
|
||||||
let display = new GridSearchResult(this.provider, metas[i], this._terms);
|
let display = new GridSearchResult(this.provider, metas[i], this._terms);
|
||||||
|
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||||
this._grid.addItem(display.actor);
|
this._grid.addItem(display.actor);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -308,6 +322,7 @@ const GridSearchResults = new Lang.Class({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Signals.addSignalMethods(GridSearchResults.prototype);
|
||||||
|
|
||||||
const SearchResults = new Lang.Class({
|
const SearchResults = new Lang.Class({
|
||||||
Name: 'SearchResults',
|
Name: 'SearchResults',
|
||||||
@@ -331,7 +346,8 @@ const SearchResults = new Lang.Class({
|
|||||||
|
|
||||||
this._scrollView = new St.ScrollView({ x_fill: true,
|
this._scrollView = new St.ScrollView({ x_fill: true,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
style_class: 'vfade' });
|
overlay_scrollbars: true,
|
||||||
|
style_class: 'search-display vfade' });
|
||||||
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
|
||||||
this._scrollView.add_actor(scrollChild);
|
this._scrollView.add_actor(scrollChild);
|
||||||
let action = new Clutter.PanAction({ interpolate: true });
|
let action = new Clutter.PanAction({ interpolate: true });
|
||||||
@@ -366,6 +382,10 @@ const SearchResults = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_keyFocusIn: function(provider, icon) {
|
||||||
|
Util.ensureActorVisibleInScrollView(this._scrollView, icon);
|
||||||
|
},
|
||||||
|
|
||||||
createProviderMeta: function(provider) {
|
createProviderMeta: function(provider) {
|
||||||
let providerBox = new St.BoxLayout({ style_class: 'search-section',
|
let providerBox = new St.BoxLayout({ style_class: 'search-section',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
@@ -379,6 +399,8 @@ const SearchResults = new Lang.Class({
|
|||||||
resultDisplay = new GridSearchResults(provider);
|
resultDisplay = new GridSearchResults(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resultDisplay.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
|
||||||
|
|
||||||
let resultDisplayBin = new St.Bin({ child: resultDisplay.actor,
|
let resultDisplayBin = new St.Bin({ child: resultDisplay.actor,
|
||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
@@ -557,6 +579,7 @@ const ProviderIcon = new Lang.Class({
|
|||||||
this.parent({ style_class: 'search-provider-icon',
|
this.parent({ style_class: 'search-provider-icon',
|
||||||
reactive: true,
|
reactive: true,
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
|
accessible_name: provider.appInfo.get_name(),
|
||||||
track_hover: true });
|
track_hover: true });
|
||||||
|
|
||||||
this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
this._content = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||||
|
|||||||
@@ -79,12 +79,13 @@ const _modes = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
'initial-setup': {
|
'initial-setup': {
|
||||||
|
hasWindows: true,
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
components: ['keyring'],
|
components: ['keyring'],
|
||||||
panel: {
|
panel: {
|
||||||
left: [],
|
left: [],
|
||||||
center: ['dateMenu'],
|
center: ['dateMenu'],
|
||||||
right: ['a11yGreeter', 'keyboard', 'volume']
|
right: ['a11yGreeter', 'keyboard', 'volume', 'battery']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -158,12 +159,7 @@ function listModes() {
|
|||||||
const SessionMode = new Lang.Class({
|
const SessionMode = new Lang.Class({
|
||||||
Name: 'SessionMode',
|
Name: 'SessionMode',
|
||||||
|
|
||||||
_init: function() {
|
init: function() {
|
||||||
global.connect('notify::session-mode', Lang.bind(this, this._sync));
|
|
||||||
this._modes = _modes;
|
|
||||||
this._modeStack = [DEFAULT_MODE];
|
|
||||||
this._sync();
|
|
||||||
|
|
||||||
_getModes(Lang.bind(this, function(modes) {
|
_getModes(Lang.bind(this, function(modes) {
|
||||||
this._modes = modes;
|
this._modes = modes;
|
||||||
let primary = modes[global.session_mode] &&
|
let primary = modes[global.session_mode] &&
|
||||||
@@ -171,6 +167,8 @@ const SessionMode = new Lang.Class({
|
|||||||
let mode = primary ? global.session_mode : 'user';
|
let mode = primary ? global.session_mode : 'user';
|
||||||
this._modeStack = [mode];
|
this._modeStack = [mode];
|
||||||
this._sync();
|
this._sync();
|
||||||
|
|
||||||
|
this.emit('sessions-loaded');
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Lang = imports.lang;
|
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
const Config = imports.misc.config;
|
const Config = imports.misc.config;
|
||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
|
const Hash = imports.misc.hash;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Screenshot = imports.ui.screenshot;
|
const Screenshot = imports.ui.screenshot;
|
||||||
|
|
||||||
@@ -18,6 +20,26 @@ const GnomeShellIface = <interface name="org.gnome.Shell">
|
|||||||
<arg type="b" direction="out" name="success" />
|
<arg type="b" direction="out" name="success" />
|
||||||
<arg type="s" direction="out" name="result" />
|
<arg type="s" direction="out" name="result" />
|
||||||
</method>
|
</method>
|
||||||
|
<method name="ShowOSD">
|
||||||
|
<arg type="a{sv}" direction="in" name="params"/>
|
||||||
|
</method>
|
||||||
|
<method name="GrabAccelerator">
|
||||||
|
<arg type="s" direction="in" name="accelerator"/>
|
||||||
|
<arg type="u" direction="in" name="flags"/>
|
||||||
|
<arg type="u" direction="out" name="action"/>
|
||||||
|
</method>
|
||||||
|
<method name="GrabAccelerators">
|
||||||
|
<arg type="a(su)" direction="in" name="accelerators"/>
|
||||||
|
<arg type="au" direction="out" name="actions"/>
|
||||||
|
</method>
|
||||||
|
<method name="UngrabAccelerator">
|
||||||
|
<arg type="u" direction="in" name="action"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
</method>
|
||||||
|
<signal name="AcceleratorActivated">
|
||||||
|
<arg name="action" type="u" />
|
||||||
|
<arg name="deviceid" type="u" />
|
||||||
|
</signal>
|
||||||
<property name="Mode" type="s" access="read" />
|
<property name="Mode" type="s" access="read" />
|
||||||
<property name="OverviewActive" type="b" access="readwrite" />
|
<property name="OverviewActive" type="b" access="readwrite" />
|
||||||
<property name="ShellVersion" type="s" access="read" />
|
<property name="ShellVersion" type="s" access="read" />
|
||||||
@@ -47,8 +69,16 @@ const GnomeShell = new Lang.Class({
|
|||||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
|
||||||
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
||||||
|
|
||||||
this._extensionsSerivce = new GnomeShellExtensions();
|
this._extensionsService = new GnomeShellExtensions();
|
||||||
this._screenshotService = new Screenshot.ScreenshotService();
|
this._screenshotService = new Screenshot.ScreenshotService();
|
||||||
|
|
||||||
|
this._grabbedAccelerators = new Hash.Map();
|
||||||
|
this._grabbers = new Hash.Map();
|
||||||
|
|
||||||
|
global.display.connect('accelerator-activated', Lang.bind(this,
|
||||||
|
function(display, action, deviceid) {
|
||||||
|
this._emitAcceleratorActivated(action, deviceid);
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,6 +114,102 @@ const GnomeShell = new Lang.Class({
|
|||||||
return [success, returnValue];
|
return [success, returnValue];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ShowOSD: function(params) {
|
||||||
|
for (let param in params)
|
||||||
|
params[param] = params[param].deep_unpack();
|
||||||
|
|
||||||
|
let icon = null;
|
||||||
|
if (params['icon'])
|
||||||
|
icon = Gio.Icon.new_for_string(params['icon']);
|
||||||
|
|
||||||
|
Main.osdWindow.setIcon(icon);
|
||||||
|
Main.osdWindow.setLabel(params['label']);
|
||||||
|
Main.osdWindow.setLevel(params['level']);
|
||||||
|
|
||||||
|
Main.osdWindow.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
GrabAcceleratorAsync: function(params, invocation) {
|
||||||
|
let [accel, flags] = params;
|
||||||
|
let sender = invocation.get_sender();
|
||||||
|
let bindingAction = this._grabAcceleratorForSender(accel, flags, sender);
|
||||||
|
return invocation.return_value(GLib.Variant.new('(u)', [bindingAction]));
|
||||||
|
},
|
||||||
|
|
||||||
|
GrabAcceleratorsAsync: function(params, invocation) {
|
||||||
|
let [accels] = params;
|
||||||
|
let sender = invocation.get_sender();
|
||||||
|
let bindingActions = [];
|
||||||
|
for (let i = 0; i < accels.length; i++) {
|
||||||
|
let [accel, flags] = accels[i];
|
||||||
|
bindingActions.push(this._grabAcceleratorForSender(accel, flags, sender));
|
||||||
|
}
|
||||||
|
return invocation.return_value(GLib.Variant.new('(au)', [bindingActions]));
|
||||||
|
},
|
||||||
|
|
||||||
|
UngrabAcceleratorAsync: function(params, invocation) {
|
||||||
|
let [action] = params;
|
||||||
|
let grabbedBy = this._grabbedAccelerators.get(action);
|
||||||
|
if (invocation.get_sender() != grabbedBy)
|
||||||
|
return invocation.return_value(GLib.Variant.new('(b)', [false]));
|
||||||
|
|
||||||
|
let ungrabSucceeded = global.display.ungrab_accelerator(action);
|
||||||
|
if (ungrabSucceeded)
|
||||||
|
this._grabbedAccelerators.delete(action);
|
||||||
|
return invocation.return_value(GLib.Variant.new('(b)', [ungrabSucceeded]));
|
||||||
|
},
|
||||||
|
|
||||||
|
_emitAcceleratorActivated: function(action, deviceid) {
|
||||||
|
let destination = this._grabbedAccelerators.get(action);
|
||||||
|
if (!destination)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let connection = this._dbusImpl.get_connection();
|
||||||
|
let info = this._dbusImpl.get_info();
|
||||||
|
connection.emit_signal(destination,
|
||||||
|
this._dbusImpl.get_object_path(),
|
||||||
|
info ? info.name : null,
|
||||||
|
'AcceleratorActivated',
|
||||||
|
GLib.Variant.new('(uu)', [action, deviceid]));
|
||||||
|
},
|
||||||
|
|
||||||
|
_grabAcceleratorForSender: function(accelerator, flags, sender) {
|
||||||
|
let bindingAction = global.display.grab_accelerator(accelerator);
|
||||||
|
if (bindingAction == Meta.KeyBindingAction.NONE)
|
||||||
|
return Meta.KeyBindingAction.NONE;
|
||||||
|
|
||||||
|
let bindingName = Meta.external_binding_name_for_action(bindingAction);
|
||||||
|
Main.wm.allowKeybinding(bindingName, flags);
|
||||||
|
|
||||||
|
this._grabbedAccelerators.set(bindingAction, sender);
|
||||||
|
|
||||||
|
if (!this._grabbers.has(sender)) {
|
||||||
|
let id = Gio.bus_watch_name(Gio.BusType.SESSION, sender, 0, null,
|
||||||
|
Lang.bind(this, this._onGrabberBusNameVanished));
|
||||||
|
this._grabbers.set(sender, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bindingAction;
|
||||||
|
},
|
||||||
|
|
||||||
|
_ungrabAccelerator: function(action) {
|
||||||
|
let ungrabSucceeded = global.display.ungrab_accelerator(action);
|
||||||
|
if (ungrabSucceeded)
|
||||||
|
this._grabbedAccelerators.delete(action);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onGrabberBusNameVanished: function(connection, name) {
|
||||||
|
let grabs = this._grabbedAccelerators.items();
|
||||||
|
for (let i = 0; i < grabs.length; i++) {
|
||||||
|
let [action, sender] = grabs[i];
|
||||||
|
if (sender == name)
|
||||||
|
this._ungrabAccelerator(action);
|
||||||
|
}
|
||||||
|
Gio.bus_unwatch_name(this._grabbers.get(name));
|
||||||
|
this._grabbers.delete(name);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
Mode: global.session_mode,
|
Mode: global.session_mode,
|
||||||
|
|
||||||
get OverviewActive() {
|
get OverviewActive() {
|
||||||
@@ -271,7 +397,7 @@ const ScreenSaverDBus = new Lang.Class({
|
|||||||
if (active)
|
if (active)
|
||||||
this._screenShield.activate(true);
|
this._screenShield.activate(true);
|
||||||
else
|
else
|
||||||
this._screenShield.unlock(false);
|
this._screenShield.deactivate(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
GetActive: function() {
|
GetActive: function() {
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ const EntryMenu = new Lang.Class({
|
|||||||
|
|
||||||
_updateCopyItem: function() {
|
_updateCopyItem: function() {
|
||||||
let selection = this._entry.clutter_text.get_selection();
|
let selection = this._entry.clutter_text.get_selection();
|
||||||
this._copyItem.setSensitive(selection && selection != '');
|
this._copyItem.setSensitive(!this._entry.clutter_text.password_char &&
|
||||||
|
selection && selection != '');
|
||||||
},
|
},
|
||||||
|
|
||||||
_updatePasteItem: function() {
|
_updatePasteItem: function() {
|
||||||
@@ -170,4 +171,10 @@ function addContextMenu(entry, params) {
|
|||||||
entry.connect('button-press-event', Lang.bind(null, _onButtonPressEvent, entry));
|
entry.connect('button-press-event', Lang.bind(null, _onButtonPressEvent, entry));
|
||||||
|
|
||||||
entry.connect('popup-menu', Lang.bind(null, _onPopup, entry));
|
entry.connect('popup-menu', Lang.bind(null, _onPopup, entry));
|
||||||
|
|
||||||
|
entry.connect('destroy', function() {
|
||||||
|
entry.menu.destroy();
|
||||||
|
entry.menu = null;
|
||||||
|
entry._menuManager = null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,36 @@ const KEY_INPUT_SOURCES = 'sources';
|
|||||||
const INPUT_SOURCE_TYPE_XKB = 'xkb';
|
const INPUT_SOURCE_TYPE_XKB = 'xkb';
|
||||||
const INPUT_SOURCE_TYPE_IBUS = 'ibus';
|
const INPUT_SOURCE_TYPE_IBUS = 'ibus';
|
||||||
|
|
||||||
|
// This is longest we'll keep the keyboard frozen until an input
|
||||||
|
// source is active.
|
||||||
|
const MAX_INPUT_SOURCE_ACTIVATION_TIME = 2000; // ms
|
||||||
|
|
||||||
|
const BUS_NAME = 'org.gnome.SettingsDaemon.Keyboard';
|
||||||
|
const OBJECT_PATH = '/org/gnome/SettingsDaemon/Keyboard';
|
||||||
|
|
||||||
|
const KeyboardManagerInterface =
|
||||||
|
<interface name="org.gnome.SettingsDaemon.Keyboard">
|
||||||
|
<method name="SetInputSource">
|
||||||
|
<arg type="u" direction="in" />
|
||||||
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const KeyboardManagerProxy = Gio.DBusProxy.makeProxyWrapper(KeyboardManagerInterface);
|
||||||
|
|
||||||
|
function releaseKeyboard() {
|
||||||
|
if (Main.modalCount > 0)
|
||||||
|
global.display.unfreeze_keyboard(global.get_current_time());
|
||||||
|
else
|
||||||
|
global.display.ungrab_keyboard(global.get_current_time());
|
||||||
|
}
|
||||||
|
|
||||||
|
function holdKeyboard() {
|
||||||
|
if (Main.modalCount > 0)
|
||||||
|
global.display.freeze_keyboard(global.get_current_time());
|
||||||
|
else
|
||||||
|
global.display.grab_keyboard(global.get_current_time());
|
||||||
|
}
|
||||||
|
|
||||||
const IBusManager = new Lang.Class({
|
const IBusManager = new Lang.Class({
|
||||||
Name: 'IBusManager',
|
Name: 'IBusManager',
|
||||||
|
|
||||||
@@ -230,6 +260,7 @@ const InputSource = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
activate: function() {
|
activate: function() {
|
||||||
|
holdKeyboard();
|
||||||
this.emit('activate');
|
this.emit('activate');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -262,11 +293,11 @@ const InputSourcePopup = new Lang.Class({
|
|||||||
this._select(this._selectedIndex);
|
this._select(this._selectedIndex);
|
||||||
},
|
},
|
||||||
|
|
||||||
_keyPressHandler: function(keysym, backwards, action) {
|
_keyPressHandler: function(keysym, _ignored, action) {
|
||||||
if (action == this._action)
|
if (action == this._action)
|
||||||
this._select(backwards ? this._previous() : this._next());
|
this._select(this._next());
|
||||||
else if (action == this._actionBackward)
|
else if (action == this._actionBackward)
|
||||||
this._select(backwards ? this._next() : this._previous());
|
this._select(this._previous());
|
||||||
else if (keysym == Clutter.Left)
|
else if (keysym == Clutter.Left)
|
||||||
this._select(this._previous());
|
this._select(this._previous());
|
||||||
else if (keysym == Clutter.Right)
|
else if (keysym == Clutter.Right)
|
||||||
@@ -336,14 +367,13 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
this._keybindingAction =
|
this._keybindingAction =
|
||||||
Main.wm.addKeybinding('switch-input-source',
|
Main.wm.addKeybinding('switch-input-source',
|
||||||
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
||||||
Meta.KeyBindingFlags.REVERSES,
|
Meta.KeyBindingFlags.NONE,
|
||||||
Shell.KeyBindingMode.ALL,
|
Shell.KeyBindingMode.ALL,
|
||||||
Lang.bind(this, this._switchInputSource));
|
Lang.bind(this, this._switchInputSource));
|
||||||
this._keybindingActionBackward =
|
this._keybindingActionBackward =
|
||||||
Main.wm.addKeybinding('switch-input-source-backward',
|
Main.wm.addKeybinding('switch-input-source-backward',
|
||||||
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
new Gio.Settings({ schema: "org.gnome.desktop.wm.keybindings" }),
|
||||||
Meta.KeyBindingFlags.REVERSES |
|
Meta.KeyBindingFlags.NONE,
|
||||||
Meta.KeyBindingFlags.REVERSED,
|
|
||||||
Shell.KeyBindingMode.ALL,
|
Shell.KeyBindingMode.ALL,
|
||||||
Lang.bind(this, this._switchInputSource));
|
Lang.bind(this, this._switchInputSource));
|
||||||
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
||||||
@@ -364,6 +394,13 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated));
|
this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated));
|
||||||
this._inputSourcesChanged();
|
this._inputSourcesChanged();
|
||||||
|
|
||||||
|
this._keyboardManager = new KeyboardManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
|
||||||
|
function(proxy, error) {
|
||||||
|
if (error)
|
||||||
|
log(error.message);
|
||||||
|
});
|
||||||
|
global.display.connect('modifiers-accelerator-activated', Lang.bind(this, this._modifiersSwitcher));
|
||||||
|
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
this._showLayoutItem = this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
|
this._showLayoutItem = this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, this._showLayout));
|
||||||
|
|
||||||
@@ -397,10 +434,44 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
this._inputSourcesChanged();
|
this._inputSourcesChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_modifiersSwitcher: function() {
|
||||||
|
let sourceIndexes = Object.keys(this._inputSources);
|
||||||
|
if (sourceIndexes.length == 0) {
|
||||||
|
releaseKeyboard();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let is = this._currentSource;
|
||||||
|
if (!is)
|
||||||
|
is = this._inputSources[sourceIndexes[0]];
|
||||||
|
|
||||||
|
let nextIndex = is.index + 1;
|
||||||
|
if (nextIndex > sourceIndexes[sourceIndexes.length - 1])
|
||||||
|
nextIndex = 0;
|
||||||
|
|
||||||
|
while (!(is = this._inputSources[nextIndex]))
|
||||||
|
nextIndex += 1;
|
||||||
|
|
||||||
|
is.activate();
|
||||||
|
},
|
||||||
|
|
||||||
_switchInputSource: function(display, screen, window, binding) {
|
_switchInputSource: function(display, screen, window, binding) {
|
||||||
|
if (this._mruSources.length < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// HACK: Fall back on simple input source switching since we
|
||||||
|
// can't show a popup switcher while the message tray is up
|
||||||
|
// without considerable work to consolidate the usage of
|
||||||
|
// pushModal/popModal and grabHelper. See
|
||||||
|
// https://bugzilla.gnome.org/show_bug.cgi?id=695143 .
|
||||||
|
if (Main.keybindingMode == Shell.KeyBindingMode.MESSAGE_TRAY) {
|
||||||
|
this._modifiersSwitcher();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
|
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
|
||||||
let modifiers = binding.get_modifiers();
|
let modifiers = binding.get_modifiers();
|
||||||
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
|
let backwards = false; // Not using this
|
||||||
if (!popup.show(backwards, binding.get_name(), binding.get_mask()))
|
if (!popup.show(backwards, binding.get_name(), binding.get_mask()))
|
||||||
popup.destroy();
|
popup.destroy();
|
||||||
},
|
},
|
||||||
@@ -413,6 +484,11 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
let oldSource;
|
let oldSource;
|
||||||
[oldSource, this._currentSource] = [this._currentSource, newSource];
|
[oldSource, this._currentSource] = [this._currentSource, newSource];
|
||||||
|
|
||||||
|
if (oldSource) {
|
||||||
|
oldSource.menuItem.setShowDot(false);
|
||||||
|
oldSource.indicatorLabel.hide();
|
||||||
|
}
|
||||||
|
|
||||||
if (!newSource || (nVisibleSources < 2 && !newSource.properties)) {
|
if (!newSource || (nVisibleSources < 2 && !newSource.properties)) {
|
||||||
// This source index might be invalid if we weren't able
|
// This source index might be invalid if we weren't able
|
||||||
// to build a menu item for it, so we hide ourselves since
|
// to build a menu item for it, so we hide ourselves since
|
||||||
@@ -427,11 +503,6 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
|
|
||||||
if (oldSource) {
|
|
||||||
oldSource.menuItem.setShowDot(false);
|
|
||||||
oldSource.indicatorLabel.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
newSource.menuItem.setShowDot(true);
|
newSource.menuItem.setShowDot(true);
|
||||||
newSource.indicatorLabel.show();
|
newSource.indicatorLabel.show();
|
||||||
|
|
||||||
@@ -484,10 +555,10 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
let is = new InputSource(type, id, displayName, shortName, i);
|
let is = new InputSource(type, id, displayName, shortName, i);
|
||||||
|
|
||||||
is.connect('activate', Lang.bind(this, function() {
|
is.connect('activate', Lang.bind(this, function() {
|
||||||
if (this._currentSource.index == is.index)
|
let inVariant = new GLib.Variant('(u)', [is.index]);
|
||||||
return;
|
this._keyboardManager.call('SetInputSource', inVariant, 0,
|
||||||
this._settings.set_value(KEY_CURRENT_INPUT_SOURCE,
|
MAX_INPUT_SOURCE_ACTIVATION_TIME,
|
||||||
GLib.Variant.new_uint32(is.index));
|
null, releaseKeyboard);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (!(is.shortName in inputSourcesByShortName))
|
if (!(is.shortName in inputSourcesByShortName))
|
||||||
@@ -700,7 +771,7 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
item.prop = prop;
|
item.prop = prop;
|
||||||
item.connect('activate', Lang.bind(this, function() {
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
this._ibusManager.activateProperty(item.prop.get_key(),
|
this._ibusManager.activateProperty(item.prop.get_key(),
|
||||||
IBus.PropState.CHECKED);
|
item.prop.get_state());
|
||||||
}));
|
}));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ const SwitcherPopup = new Lang.Class({
|
|||||||
// disturbed by the popup briefly flashing.
|
// disturbed by the popup briefly flashing.
|
||||||
this._initialDelayTimeoutId = Mainloop.timeout_add(POPUP_DELAY_TIMEOUT,
|
this._initialDelayTimeoutId = Mainloop.timeout_add(POPUP_DELAY_TIMEOUT,
|
||||||
Lang.bind(this, function () {
|
Lang.bind(this, function () {
|
||||||
|
Main.osdWindow.cancel();
|
||||||
this.actor.opacity = 255;
|
this.actor.opacity = 255;
|
||||||
this._initialDelayTimeoutId = 0;
|
this._initialDelayTimeoutId = 0;
|
||||||
}));
|
}));
|
||||||
@@ -304,7 +305,7 @@ const SwitcherList = new Lang.Class({
|
|||||||
this.actor.connect('allocate', Lang.bind(this, this._allocateTop));
|
this.actor.connect('allocate', Lang.bind(this, this._allocateTop));
|
||||||
|
|
||||||
// Here we use a GenericContainer so that we can force all the
|
// Here we use a GenericContainer so that we can force all the
|
||||||
// children except the separator to have the same width.
|
// children to have the same width.
|
||||||
this._list = new Shell.GenericContainer({ style_class: 'switcher-list-item-container' });
|
this._list = new Shell.GenericContainer({ style_class: 'switcher-list-item-container' });
|
||||||
this._list.spacing = 0;
|
this._list.spacing = 0;
|
||||||
this._list.connect('style-changed', Lang.bind(this, function() {
|
this._list.connect('style-changed', Lang.bind(this, function() {
|
||||||
@@ -339,7 +340,6 @@ const SwitcherList = new Lang.Class({
|
|||||||
|
|
||||||
this._items = [];
|
this._items = [];
|
||||||
this._highlighted = -1;
|
this._highlighted = -1;
|
||||||
this._separator = null;
|
|
||||||
this._squareItems = squareItems;
|
this._squareItems = squareItems;
|
||||||
this._minSize = 0;
|
this._minSize = 0;
|
||||||
this._scrollableRight = true;
|
this._scrollableRight = true;
|
||||||
@@ -402,12 +402,6 @@ const SwitcherList = new Lang.Class({
|
|||||||
this._itemEntered(index);
|
this._itemEntered(index);
|
||||||
},
|
},
|
||||||
|
|
||||||
addSeparator: function () {
|
|
||||||
let box = new St.Bin({ style_class: 'separator' });
|
|
||||||
this._separator = box;
|
|
||||||
this._list.add_actor(box);
|
|
||||||
},
|
|
||||||
|
|
||||||
highlight: function(index, justOutline) {
|
highlight: function(index, justOutline) {
|
||||||
if (this._highlighted != -1) {
|
if (this._highlighted != -1) {
|
||||||
this._items[this._highlighted].remove_style_pseudo_class('outlined');
|
this._items[this._highlighted].remove_style_pseudo_class('outlined');
|
||||||
@@ -515,14 +509,8 @@ const SwitcherList = new Lang.Class({
|
|||||||
_getPreferredWidth: function (actor, forHeight, alloc) {
|
_getPreferredWidth: function (actor, forHeight, alloc) {
|
||||||
let [maxChildMin, maxChildNat] = this._maxChildWidth(forHeight);
|
let [maxChildMin, maxChildNat] = this._maxChildWidth(forHeight);
|
||||||
|
|
||||||
let separatorWidth = 0;
|
|
||||||
if (this._separator) {
|
|
||||||
let [sepMin, sepNat] = this._separator.get_preferred_width(forHeight);
|
|
||||||
separatorWidth = sepNat + this._list.spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
||||||
alloc.min_size = this._items.length * maxChildMin + separatorWidth + totalSpacing;
|
alloc.min_size = this._items.length * maxChildMin + totalSpacing;
|
||||||
alloc.natural_size = alloc.min_size;
|
alloc.natural_size = alloc.min_size;
|
||||||
this._minSize = alloc.min_size;
|
this._minSize = alloc.min_size;
|
||||||
},
|
},
|
||||||
@@ -553,14 +541,7 @@ const SwitcherList = new Lang.Class({
|
|||||||
let [maxChildMin, maxChildNat] = this._maxChildWidth(childHeight);
|
let [maxChildMin, maxChildNat] = this._maxChildWidth(childHeight);
|
||||||
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
||||||
|
|
||||||
let separatorWidth = 0;
|
let childWidth = Math.floor(Math.max(0, box.x2 - box.x1 - totalSpacing) / this._items.length);
|
||||||
if (this._separator) {
|
|
||||||
let [sepMin, sepNat] = this._separator.get_preferred_width(childHeight);
|
|
||||||
separatorWidth = sepNat;
|
|
||||||
totalSpacing += this._list.spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
let childWidth = Math.floor(Math.max(0, box.x2 - box.x1 - totalSpacing - separatorWidth) / this._items.length);
|
|
||||||
|
|
||||||
let x = 0;
|
let x = 0;
|
||||||
let children = this._list.get_children();
|
let children = this._list.get_children();
|
||||||
@@ -580,14 +561,6 @@ const SwitcherList = new Lang.Class({
|
|||||||
children[i].allocate(childBox, flags);
|
children[i].allocate(childBox, flags);
|
||||||
|
|
||||||
x += this._list.spacing + childWidth;
|
x += this._list.spacing + childWidth;
|
||||||
} else if (children[i] == this._separator) {
|
|
||||||
// We want the separator to be more compact than the rest.
|
|
||||||
childBox.x1 = x;
|
|
||||||
childBox.y1 = 0;
|
|
||||||
childBox.x2 = x + separatorWidth;
|
|
||||||
childBox.y2 = childHeight;
|
|
||||||
children[i].allocate(childBox, flags);
|
|
||||||
x += this._list.spacing + separatorWidth;
|
|
||||||
} else {
|
} else {
|
||||||
// Something else, eg, AppSwitcher's arrows;
|
// Something else, eg, AppSwitcher's arrows;
|
||||||
// we don't allocate it.
|
// we don't allocate it.
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
|
const Gtk = imports.gi.Gtk;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
@@ -45,12 +45,9 @@ const Tweener = imports.tweener.tweener;
|
|||||||
// calls any of these is almost certainly wrong anyway, because they
|
// calls any of these is almost certainly wrong anyway, because they
|
||||||
// affect the entire application.)
|
// affect the entire application.)
|
||||||
|
|
||||||
let animationSettings = null;
|
|
||||||
|
|
||||||
// Called from Main.start
|
// Called from Main.start
|
||||||
function init() {
|
function init() {
|
||||||
Tweener.setFrameTicker(new ClutterFrameTicker());
|
Tweener.setFrameTicker(new ClutterFrameTicker());
|
||||||
animationSettings = new Gio.Settings({ schema: 'org.gnome.desktop.interface' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -77,7 +74,7 @@ function _wrapTweening(target, tweeningParameters) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!animationSettings.get_boolean('enable-animations'))
|
if (!Gtk.Settings.get_default().gtk_enable_animations)
|
||||||
tweeningParameters['time'] = 0.000001;
|
tweeningParameters['time'] = 0.000001;
|
||||||
|
|
||||||
_addHandler(target, tweeningParameters, 'onStart', _tweenStarted);
|
_addHandler(target, tweeningParameters, 'onStart', _tweenStarted);
|
||||||
|
|||||||
@@ -27,35 +27,6 @@ const LoginDialog = imports.gdm.loginDialog;
|
|||||||
// The timeout before going back automatically to the lock screen (in seconds)
|
// The timeout before going back automatically to the lock screen (in seconds)
|
||||||
const IDLE_TIMEOUT = 2 * 60;
|
const IDLE_TIMEOUT = 2 * 60;
|
||||||
|
|
||||||
function versionCompare(required, reference) {
|
|
||||||
required = required.split('.');
|
|
||||||
reference = reference.split('.');
|
|
||||||
|
|
||||||
for (let i = 0; i < required.length; i++) {
|
|
||||||
if (required[i] != reference[i])
|
|
||||||
return required[i] < reference[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSupported() {
|
|
||||||
try {
|
|
||||||
let params = GLib.Variant.new('(ss)', ['org.gnome.DisplayManager.Manager', 'Version']);
|
|
||||||
let result = Gio.DBus.system.call_sync('org.gnome.DisplayManager',
|
|
||||||
'/org/gnome/DisplayManager/Manager',
|
|
||||||
'org.freedesktop.DBus.Properties',
|
|
||||||
'Get', params, null,
|
|
||||||
Gio.DBusCallFlags.NONE,
|
|
||||||
-1, null);
|
|
||||||
|
|
||||||
let version = result.deep_unpack()[0].deep_unpack();
|
|
||||||
return versionCompare('3.5.91', version);
|
|
||||||
} catch(e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const UnlockDialog = new Lang.Class({
|
const UnlockDialog = new Lang.Class({
|
||||||
Name: 'UnlockDialog',
|
Name: 'UnlockDialog',
|
||||||
Extends: ModalDialog.ModalDialog,
|
Extends: ModalDialog.ModalDialog,
|
||||||
@@ -76,6 +47,7 @@ const UnlockDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._greeterClient = new Gdm.Client();
|
this._greeterClient = new Gdm.Client();
|
||||||
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
|
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
|
||||||
|
this._userVerified = false;
|
||||||
|
|
||||||
this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
|
this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
|
||||||
this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
|
this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
|
||||||
@@ -98,6 +70,7 @@ const UnlockDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
|
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
|
||||||
can_focus: true });
|
can_focus: true });
|
||||||
|
this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock));
|
||||||
this._promptEntry.clutter_text.set_password_char('\u25cf');
|
this._promptEntry.clutter_text.set_password_char('\u25cf');
|
||||||
ShellEntry.addContextMenu(this._promptEntry, { isPassword: true });
|
ShellEntry.addContextMenu(this._promptEntry, { isPassword: true });
|
||||||
this.setInitialKeyFocus(this._promptEntry);
|
this.setInitialKeyFocus(this._promptEntry);
|
||||||
@@ -169,11 +142,6 @@ const UnlockDialog = new Lang.Class({
|
|||||||
let batch = new Batch.Hold();
|
let batch = new Batch.Hold();
|
||||||
this._userVerifier.begin(this._userName, batch);
|
this._userVerifier.begin(this._userName, batch);
|
||||||
|
|
||||||
GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, function() {
|
|
||||||
this.emit('loaded');
|
|
||||||
return false;
|
|
||||||
}));
|
|
||||||
|
|
||||||
Main.ctrlAltTabManager.addGroup(this.dialogLayout, _("Unlock Window"), 'dialog-password-symbolic');
|
Main.ctrlAltTabManager.addGroup(this.dialogLayout, _("Unlock Window"), 'dialog-password-symbolic');
|
||||||
|
|
||||||
this._idleMonitor = new GnomeDesktop.IdleMonitor();
|
this._idleMonitor = new GnomeDesktop.IdleMonitor();
|
||||||
@@ -282,18 +250,35 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._userVerifier.answerQuery(query, this._promptEntry.text);
|
this._userVerifier.answerQuery(query, this._promptEntry.text);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onVerificationComplete: function() {
|
_finishUnlock: function() {
|
||||||
this._userVerifier.clear();
|
this._userVerifier.clear();
|
||||||
this.emit('unlocked');
|
this.emit('unlocked');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onVerificationComplete: function() {
|
||||||
|
this._userVerified = true;
|
||||||
|
if (!this._userVerifier.hasPendingMessages) {
|
||||||
|
this._finishUnlock();
|
||||||
|
} else {
|
||||||
|
let signalId = this._userVerifier.connect('no-more-messages',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._userVerifier.disconnect(signalId);
|
||||||
|
this._finishUnlock();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_onReset: function() {
|
_onReset: function() {
|
||||||
this.emit('failed');
|
if (!this._userVerified) {
|
||||||
|
this._userVerifier.clear();
|
||||||
|
this.emit('failed');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onVerificationFailed: function() {
|
_onVerificationFailed: function() {
|
||||||
this._currentQuery = null;
|
this._currentQuery = null;
|
||||||
this._firstQuestion = true;
|
this._firstQuestion = true;
|
||||||
|
this._userVerified = false;
|
||||||
|
|
||||||
this._promptEntry.text = '';
|
this._promptEntry.text = '';
|
||||||
this._promptEntry.clutter_text.set_password_char('\u25cf');
|
this._promptEntry.clutter_text.set_password_char('\u25cf');
|
||||||
@@ -333,4 +318,8 @@ const UnlockDialog = new Lang.Class({
|
|||||||
|
|
||||||
this.destroy();
|
this.destroy();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addCharacter: function(unichar) {
|
||||||
|
this._promptEntry.clutter_text.insert_unichar(unichar);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session
|
|||||||
<property name="Remote" type="b" access="read"/>
|
<property name="Remote" type="b" access="read"/>
|
||||||
<property name="Class" type="s" access="read"/>
|
<property name="Class" type="s" access="read"/>
|
||||||
<property name="Type" type="s" access="read"/>
|
<property name="Type" type="s" access="read"/>
|
||||||
|
<property name="State" type="s" access="read"/>
|
||||||
</interface>;
|
</interface>;
|
||||||
|
|
||||||
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
|
const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
|
||||||
@@ -599,7 +600,8 @@ const UserMenuButton = new Lang.Class({
|
|||||||
Lang.bind(this, this._updateHaveShutdown));
|
Lang.bind(this, this._updateHaveShutdown));
|
||||||
|
|
||||||
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
||||||
Main.screenShield.connect('locked-changed', Lang.bind(this, this._updatePresenceIcon));
|
if (Main.screenShield)
|
||||||
|
Main.screenShield.connect('locked-changed', Lang.bind(this, this._updatePresenceIcon));
|
||||||
this._sessionUpdated();
|
this._sessionUpdated();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -655,7 +657,7 @@ const UserMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
_updateLockScreen: function() {
|
_updateLockScreen: function() {
|
||||||
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
|
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
|
||||||
this._lockScreenItem.actor.visible = allowLockScreen;
|
this._lockScreenItem.actor.visible = allowLockScreen && LoginManager.canLock();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateInstallUpdates: function() {
|
_updateInstallUpdates: function() {
|
||||||
@@ -863,7 +865,8 @@ const UserMenuButton = new Lang.Class({
|
|||||||
_onLoginScreenActivate: function() {
|
_onLoginScreenActivate: function() {
|
||||||
this.menu.close(BoxPointer.PopupAnimation.NONE);
|
this.menu.close(BoxPointer.PopupAnimation.NONE);
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
Main.screenShield.lock(false);
|
if (Main.screenShield)
|
||||||
|
Main.screenShield.lock(false);
|
||||||
Gdm.goto_login_session_sync(null);
|
Gdm.goto_login_session_sync(null);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -888,6 +891,7 @@ const UserMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
let descriptionLabel = new St.Label({ style_class: 'end-session-dialog-description'});
|
let descriptionLabel = new St.Label({ style_class: 'end-session-dialog-description'});
|
||||||
descriptionLabel.set_text(_("Shutting down might cause them to lose unsaved work."));
|
descriptionLabel.set_text(_("Shutting down might cause them to lose unsaved work."));
|
||||||
|
descriptionLabel.clutter_text.line_wrap = true;
|
||||||
dialog.contentLayout.add(descriptionLabel, { x_fill: true,
|
dialog.contentLayout.add(descriptionLabel, { x_fill: true,
|
||||||
y_fill: true,
|
y_fill: true,
|
||||||
y_align: St.Align.START });
|
y_align: St.Align.START });
|
||||||
@@ -913,8 +917,10 @@ const UserMenuButton = new Lang.Class({
|
|||||||
session.user.get_real_name() : session.username;
|
session.user.get_real_name() : session.username;
|
||||||
|
|
||||||
if (session.info.remote)
|
if (session.info.remote)
|
||||||
|
/* Translators: Remote here refers to a remote session, like a ssh login */
|
||||||
userLabelText = _("%s (remote)").format(userName);
|
userLabelText = _("%s (remote)").format(userName);
|
||||||
else if (session.info.type == "tty")
|
else if (session.info.type == "tty")
|
||||||
|
/* Translators: Console here refers to a tty like a VT console */
|
||||||
userLabelText = _("%s (console)").format(userName);
|
userLabelText = _("%s (console)").format(userName);
|
||||||
else
|
else
|
||||||
userLabelText = userName;
|
userLabelText = userName;
|
||||||
@@ -961,6 +967,9 @@ const UserMenuButton = new Lang.Class({
|
|||||||
if (proxy.Class != 'user')
|
if (proxy.Class != 'user')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (proxy.State == 'closing')
|
||||||
|
continue;
|
||||||
|
|
||||||
if (proxy.Id == GLib.getenv('XDG_SESSION_ID'))
|
if (proxy.Id == GLib.getenv('XDG_SESSION_ID'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -83,11 +83,10 @@ const ViewSelector = new Lang.Class({
|
|||||||
this._entry.connect('notify::mapped', Lang.bind(this, this._onMapped));
|
this._entry.connect('notify::mapped', Lang.bind(this, this._onMapped));
|
||||||
global.stage.connect('notify::key-focus', Lang.bind(this, this._onStageKeyFocusChanged));
|
global.stage.connect('notify::key-focus', Lang.bind(this, this._onStageKeyFocusChanged));
|
||||||
|
|
||||||
this._inactiveIcon = new St.Icon({ style_class: 'search-entry-icon',
|
this._entry.set_primary_icon(new St.Icon({ style_class: 'search-entry-icon',
|
||||||
icon_name: 'edit-find-symbolic' });
|
icon_name: 'edit-find-symbolic' }));
|
||||||
this._activeIcon = new St.Icon({ style_class: 'search-entry-icon',
|
this._clearIcon = new St.Icon({ style_class: 'search-entry-icon',
|
||||||
icon_name: 'edit-clear-symbolic' });
|
icon_name: 'edit-clear-symbolic' });
|
||||||
this._entry.set_secondary_icon(this._inactiveIcon);
|
|
||||||
|
|
||||||
this._iconClickedId = 0;
|
this._iconClickedId = 0;
|
||||||
this._capturedEventId = 0;
|
this._capturedEventId = 0;
|
||||||
@@ -279,8 +278,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
else
|
else
|
||||||
Main.overview.hide();
|
Main.overview.hide();
|
||||||
return true;
|
return true;
|
||||||
} else if (Clutter.keysym_to_unicode(symbol) ||
|
} else if (this._shouldTriggerSearch(symbol)) {
|
||||||
(symbol == Clutter.BackSpace && this._searchActive)) {
|
|
||||||
this.startSearch(event);
|
this.startSearch(event);
|
||||||
} else if (!this._searchActive) {
|
} else if (!this._searchActive) {
|
||||||
if (symbol == Clutter.Tab || symbol == Clutter.Down) {
|
if (symbol == Clutter.Tab || symbol == Clutter.Down) {
|
||||||
@@ -345,6 +343,17 @@ const ViewSelector = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_shouldTriggerSearch: function(symbol) {
|
||||||
|
let unicode = Clutter.keysym_to_unicode(symbol);
|
||||||
|
if (unicode == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (getTermsForSearchString(String.fromCharCode(unicode)).length > 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return symbol == Clutter.BackSpace && this._searchActive;
|
||||||
|
},
|
||||||
|
|
||||||
startSearch: function(event) {
|
startSearch: function(event) {
|
||||||
global.stage.set_key_focus(this._text);
|
global.stage.set_key_focus(this._text);
|
||||||
this._text.event(event, true);
|
this._text.event(event, true);
|
||||||
@@ -366,7 +375,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
this._searchResults.startingSearch();
|
this._searchResults.startingSearch();
|
||||||
|
|
||||||
if (this._searchActive) {
|
if (this._searchActive) {
|
||||||
this._entry.set_secondary_icon(this._activeIcon);
|
this._entry.set_secondary_icon(this._clearIcon);
|
||||||
|
|
||||||
if (this._iconClickedId == 0)
|
if (this._iconClickedId == 0)
|
||||||
this._iconClickedId = this._entry.connect('secondary-icon-clicked',
|
this._iconClickedId = this._entry.connect('secondary-icon-clicked',
|
||||||
@@ -386,7 +395,7 @@ const ViewSelector = new Lang.Class({
|
|||||||
this._searchTimeoutId = 0;
|
this._searchTimeoutId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._entry.set_secondary_icon(this._inactiveIcon);
|
this._entry.set_secondary_icon(null);
|
||||||
this._searchCancelled();
|
this._searchCancelled();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -502,6 +511,22 @@ const ViewSelector = new Lang.Class({
|
|||||||
return ViewPage.APPS;
|
return ViewPage.APPS;
|
||||||
else
|
else
|
||||||
return ViewPage.SEARCH;
|
return ViewPage.SEARCH;
|
||||||
|
},
|
||||||
|
|
||||||
|
fadeIn: function() {
|
||||||
|
let actor = this._activePage;
|
||||||
|
Tweener.addTween(actor, { opacity: 255,
|
||||||
|
time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME / 2,
|
||||||
|
transition: 'easeInQuad'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
fadeHalf: function() {
|
||||||
|
let actor = this._activePage;
|
||||||
|
Tweener.addTween(actor, { opacity: 128,
|
||||||
|
time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME / 2,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(ViewSelector.prototype);
|
Signals.addSignalMethods(ViewSelector.prototype);
|
||||||
|
|||||||
@@ -11,12 +11,14 @@ const Layout = imports.ui.layout;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Panel = imports.ui.panel;
|
const Panel = imports.ui.panel;
|
||||||
|
|
||||||
// we could make these gsettings
|
|
||||||
const FISH_NAME = 'wanda';
|
const FISH_NAME = 'wanda';
|
||||||
|
const FISH_FILENAME = 'wanda.png';
|
||||||
const FISH_SPEED = 300;
|
const FISH_SPEED = 300;
|
||||||
const FISH_COMMAND = 'fortune';
|
const FISH_COMMAND = 'fortune';
|
||||||
|
// The size of an individual frame in the animation
|
||||||
|
const FISH_HEIGHT = 22;
|
||||||
|
const FISH_WIDTH = 36;
|
||||||
|
|
||||||
const GNOME_PANEL_PIXMAPDIR = '../gnome-panel/fish';
|
|
||||||
const FISH_GROUP = 'Fish Animation';
|
const FISH_GROUP = 'Fish Animation';
|
||||||
|
|
||||||
const MAGIC_FISH_KEY = 'free the fish';
|
const MAGIC_FISH_KEY = 'free the fish';
|
||||||
@@ -26,33 +28,16 @@ const WandaIcon = new Lang.Class({
|
|||||||
Extends: IconGrid.BaseIcon,
|
Extends: IconGrid.BaseIcon,
|
||||||
|
|
||||||
_init : function(fish, label, params) {
|
_init : function(fish, label, params) {
|
||||||
this._fish = fish;
|
|
||||||
let file = GLib.build_filenamev([global.datadir, GNOME_PANEL_PIXMAPDIR, fish + '.fish']);
|
|
||||||
|
|
||||||
if (GLib.file_test(file, GLib.FileTest.EXISTS)) {
|
|
||||||
this._keyfile = new GLib.KeyFile();
|
|
||||||
this._keyfile.load_from_file(file, GLib.KeyFileFlags.NONE);
|
|
||||||
|
|
||||||
this._imageFile = GLib.build_filenamev([global.datadir, GNOME_PANEL_PIXMAPDIR,
|
|
||||||
this._keyfile.get_string(FISH_GROUP, 'image')]);
|
|
||||||
|
|
||||||
let tmpPixbuf = GdkPixbuf.Pixbuf.new_from_file(this._imageFile);
|
|
||||||
|
|
||||||
this._imgHeight = tmpPixbuf.height;
|
|
||||||
this._imgWidth = tmpPixbuf.width / this._keyfile.get_integer(FISH_GROUP, 'frames');
|
|
||||||
} else {
|
|
||||||
this._imageFile = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.parent(label, params);
|
this.parent(label, params);
|
||||||
|
|
||||||
|
this._fish = fish;
|
||||||
|
this._imageFile = GLib.build_filenamev([global.datadir, fish + '.png']);
|
||||||
|
|
||||||
|
this._imgHeight = FISH_HEIGHT;
|
||||||
|
this._imgWidth = FISH_WIDTH;
|
||||||
},
|
},
|
||||||
|
|
||||||
createIcon: function(iconSize) {
|
createIcon: function(iconSize) {
|
||||||
if (!this._imageFile) {
|
|
||||||
return new St.Icon({ icon_name: 'face-smile',
|
|
||||||
icon_size: iconSize });
|
|
||||||
}
|
|
||||||
|
|
||||||
this._animations = new Panel.Animation(this._imageFile, this._imgWidth, this._imgHeight, FISH_SPEED);
|
this._animations = new Panel.Animation(this._imageFile, this._imgWidth, this._imgHeight, FISH_SPEED);
|
||||||
this._animations.play();
|
this._animations.play();
|
||||||
return this._animations.actor;
|
return this._animations.actor;
|
||||||
|
|||||||
@@ -564,9 +564,9 @@ const WindowManager = new Lang.Class({
|
|||||||
|
|
||||||
let switchData = {};
|
let switchData = {};
|
||||||
this._switchData = switchData;
|
this._switchData = switchData;
|
||||||
switchData.inGroup = new Clutter.Group();
|
switchData.inGroup = new Clutter.Actor();
|
||||||
switchData.outGroup = new Clutter.Group();
|
switchData.outGroup = new Clutter.Actor();
|
||||||
switchData.movingWindowBin = new Clutter.Group();
|
switchData.movingWindowBin = new Clutter.Actor();
|
||||||
switchData.windows = [];
|
switchData.windows = [];
|
||||||
|
|
||||||
let wgroup = global.window_group;
|
let wgroup = global.window_group;
|
||||||
@@ -593,7 +593,7 @@ const WindowManager = new Lang.Class({
|
|||||||
switchData.windows.push({ window: window,
|
switchData.windows.push({ window: window,
|
||||||
parent: window.get_parent() });
|
parent: window.get_parent() });
|
||||||
window.reparent(switchData.inGroup);
|
window.reparent(switchData.inGroup);
|
||||||
window.show_all();
|
window.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,15 +68,15 @@ const WindowClone = new Lang.Class({
|
|||||||
|
|
||||||
// The MetaShapedTexture that we clone has a size that includes
|
// The MetaShapedTexture that we clone has a size that includes
|
||||||
// the invisible border; this is inconvenient; rather than trying
|
// the invisible border; this is inconvenient; rather than trying
|
||||||
// to compensate all over the place we insert a ClutterGroup into
|
// to compensate all over the place we insert a ClutterActor into
|
||||||
// the hierarchy that is sized to only the visible portion.
|
// the hierarchy that is sized to only the visible portion.
|
||||||
this.actor = new Clutter.Group({ reactive: true,
|
this.actor = new Clutter.Actor({ reactive: true,
|
||||||
x: this.origX,
|
x: this.origX,
|
||||||
y: this.origY,
|
y: this.origY,
|
||||||
width: outerRect.width,
|
width: outerRect.width,
|
||||||
height: outerRect.height });
|
height: outerRect.height });
|
||||||
|
|
||||||
this.actor.add_actor(this._windowClone);
|
this.actor.add_child(this._windowClone);
|
||||||
|
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
|
|
||||||
@@ -121,15 +121,33 @@ const WindowClone = new Lang.Class({
|
|||||||
return this._slot;
|
return this._slot;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Find the actor just below us, respecting reparenting done
|
||||||
|
// by DND code
|
||||||
|
getActualStackAbove: function() {
|
||||||
|
if (this._stackAbove == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (this.inDrag || this._zooming) {
|
||||||
|
if (this._stackAbove._delegate)
|
||||||
|
return this._stackAbove._delegate.getActualStackAbove();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return this._stackAbove;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
setStackAbove: function (actor) {
|
setStackAbove: function (actor) {
|
||||||
this._stackAbove = actor;
|
this._stackAbove = actor;
|
||||||
if (this.inDrag)
|
if (this.inDrag)
|
||||||
// We'll fix up the stack after the drag
|
// We'll fix up the stack after the drag
|
||||||
return;
|
return;
|
||||||
if (this._stackAbove == null)
|
|
||||||
|
let actualAbove = this.getActualStackAbove();
|
||||||
|
if (actualAbove == null)
|
||||||
this.actor.lower_bottom();
|
this.actor.lower_bottom();
|
||||||
else
|
else
|
||||||
this.actor.raise(this._stackAbove);
|
this.actor.raise(actualAbove);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function () {
|
destroy: function () {
|
||||||
@@ -561,6 +579,80 @@ const WindowPositionFlags = {
|
|||||||
ANIMATE: 1 << 1
|
ANIMATE: 1 << 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Window Thumbnail Layout Algorithm
|
||||||
|
// =================================
|
||||||
|
//
|
||||||
|
// General overview
|
||||||
|
// ----------------
|
||||||
|
//
|
||||||
|
// The window thumbnail layout algorithm calculates some optimal layout
|
||||||
|
// by computing layouts with some number of rows, calculating how good
|
||||||
|
// each layout is, and stopping iterating when it finds one that is worse
|
||||||
|
// than the previous layout. A layout consists of which windows are in
|
||||||
|
// which rows, row sizes and other general state tracking that would make
|
||||||
|
// calculating window positions from this information fairly easy.
|
||||||
|
//
|
||||||
|
// We don't compute some global order of windows right now for optimal
|
||||||
|
// travel when animating into the overview; windows are assumed to be
|
||||||
|
// in some stable order.
|
||||||
|
//
|
||||||
|
// After a layout is computed that's considered the best layout, we
|
||||||
|
// compute the layout scale to fit it in the area, and then compute
|
||||||
|
// slots (sizes and positions) for each thumbnail.
|
||||||
|
//
|
||||||
|
// Layout generation
|
||||||
|
// -----------------
|
||||||
|
//
|
||||||
|
// Layout generation is naive and simple: we simply add windows to a row
|
||||||
|
// until we've added too many windows to a row, and then make a new row,
|
||||||
|
// until we have our required N rows. The potential issue with this strategy
|
||||||
|
// is that we may have too many windows at the bottom in some pathological
|
||||||
|
// cases, which tends to make the thumbnails have the shape of a pile of
|
||||||
|
// sand with a peak, with one window at the top.
|
||||||
|
//
|
||||||
|
// Scaling factors
|
||||||
|
// ---------------
|
||||||
|
//
|
||||||
|
// Thumbnail position is mostly straightforward -- the main issue is
|
||||||
|
// computing an optimal scale for each window that fits the constraints,
|
||||||
|
// and doesn't make the thumbnail too small to see. There are two factors
|
||||||
|
// involved in thumbnail scale to make sure that these two goals are met:
|
||||||
|
// the window scale (calculated by _computeWindowScale) and the layout
|
||||||
|
// scale (calculated by computeSizeAndScale).
|
||||||
|
//
|
||||||
|
// The calculation logic becomes slightly more complicated because row
|
||||||
|
// and column spacing are not scaled, they're constant, so we can't
|
||||||
|
// simply generate a bunch of window positions and then scale it. In
|
||||||
|
// practice, it's not too bad -- we can simply try to fit the layout
|
||||||
|
// in the input area minus whatever spacing we have, and then add
|
||||||
|
// it back afterwards.
|
||||||
|
//
|
||||||
|
// The window scale is constant for the window's size regardless of the
|
||||||
|
// input area or the layout scale or rows or anything else, and right
|
||||||
|
// now just enlarges the window if it's too small. The fact that this
|
||||||
|
// factor is stable makes it easy to calculate, so there's no sense
|
||||||
|
// in not applying it in most calculations.
|
||||||
|
//
|
||||||
|
// The layout scale depends on the input area, the rows, etc, but is the
|
||||||
|
// same for the entire layout, rather than being per-window. After
|
||||||
|
// generating the rows of windows, we basically do some basic math to
|
||||||
|
// fit the full, unscaled layout to the input area, as described above.
|
||||||
|
//
|
||||||
|
// With these two factors combined, the final scale of each thumbnail is
|
||||||
|
// simply windowScale * layoutScale... almost.
|
||||||
|
//
|
||||||
|
// There's one additional constraint: the thumbnail scale must never be
|
||||||
|
// larger than WINDOW_CLONE_MAXIMUM_SCALE, which means that the inequality:
|
||||||
|
//
|
||||||
|
// windowScale * layoutScale <= WINDOW_CLONE_MAXIMUM_SCALE
|
||||||
|
//
|
||||||
|
// must always be true. This is for each individual window -- while we
|
||||||
|
// could adjust layoutScale to make the largest thumbnail smaller than
|
||||||
|
// WINDOW_CLONE_MAXIMUM_SCALE, it would shrink windows which are already
|
||||||
|
// under the inequality. To solve this, we simply cheat: we simply keep
|
||||||
|
// each window's "cell" area to be the same, but we shrink the thumbnail
|
||||||
|
// and center it horizontally, and align it to the bottom vertically.
|
||||||
|
|
||||||
const LayoutStrategy = new Lang.Class({
|
const LayoutStrategy = new Lang.Class({
|
||||||
Name: 'LayoutStrategy',
|
Name: 'LayoutStrategy',
|
||||||
Abstract: true,
|
Abstract: true,
|
||||||
@@ -583,19 +675,15 @@ const LayoutStrategy = new Lang.Class({
|
|||||||
// meant to be scaled
|
// meant to be scaled
|
||||||
//
|
//
|
||||||
// * neither height/fullHeight have any sort of spacing or padding
|
// * neither height/fullHeight have any sort of spacing or padding
|
||||||
//
|
|
||||||
// * if cellWidth is present, all windows in the row will occupy
|
|
||||||
// the space of cellWidth, centered.
|
|
||||||
return { x: 0, y: 0,
|
return { x: 0, y: 0,
|
||||||
width: 0, height: 0,
|
width: 0, height: 0,
|
||||||
fullWidth: 0, fullHeight: 0,
|
fullWidth: 0, fullHeight: 0,
|
||||||
cellWidth: 0,
|
|
||||||
windows: [] };
|
windows: [] };
|
||||||
},
|
},
|
||||||
|
|
||||||
// Computes and returns a fancy scale for @window using the
|
// Computes and returns an individual scaling factor for @window,
|
||||||
// base scale, @scale.
|
// to be applied in addition to the overal layout scale.
|
||||||
_computeWindowScale: function(window, scale) {
|
_computeWindowScale: function(window) {
|
||||||
// Since we align windows next to each other, the height of the
|
// Since we align windows next to each other, the height of the
|
||||||
// thumbnails is much more important to preserve than the width of
|
// thumbnails is much more important to preserve than the width of
|
||||||
// them, so two windows with equal height, but maybe differering
|
// them, so two windows with equal height, but maybe differering
|
||||||
@@ -608,14 +696,13 @@ const LayoutStrategy = new Lang.Class({
|
|||||||
// good. We'll use a multiplier of 1.5 for this.
|
// good. We'll use a multiplier of 1.5 for this.
|
||||||
|
|
||||||
// Map from [0, 1] to [1.5, 1]
|
// Map from [0, 1] to [1.5, 1]
|
||||||
let fancyScale = _interpolate(1.5, 1, ratio) * scale;
|
return _interpolate(1.5, 1, ratio);
|
||||||
return fancyScale;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Compute the size of each row, by assigning to the properties
|
// Compute the size of each row, by assigning to the properties
|
||||||
// row.width, row.height, row.fullWidth, row.fullHeight, and
|
// row.width, row.height, row.fullWidth, row.fullHeight, and
|
||||||
// (optionally) row.cellWidth, for each row in @layout.rows.
|
// (optionally) for each row in @layout.rows. This method is
|
||||||
// This method is intended to be called by subclasses.
|
// intended to be called by subclasses.
|
||||||
_computeRowSizes: function(layout) {
|
_computeRowSizes: function(layout) {
|
||||||
throw new Error('_computeRowSizes not implemented');
|
throw new Error('_computeRowSizes not implemented');
|
||||||
},
|
},
|
||||||
@@ -676,7 +763,7 @@ const LayoutStrategy = new Lang.Class({
|
|||||||
computeWindowSlots: function(layout, area) {
|
computeWindowSlots: function(layout, area) {
|
||||||
this._computeRowSizes(layout);
|
this._computeRowSizes(layout);
|
||||||
|
|
||||||
let { rows: rows, scale: scale, state: state } = layout;
|
let { rows: rows, scale: scale } = layout;
|
||||||
|
|
||||||
let slots = [];
|
let slots = [];
|
||||||
|
|
||||||
@@ -697,24 +784,22 @@ const LayoutStrategy = new Lang.Class({
|
|||||||
for (let i = 0; i < rows.length; i++) {
|
for (let i = 0; i < rows.length; i++) {
|
||||||
let row = rows[i];
|
let row = rows[i];
|
||||||
row.y += baseY;
|
row.y += baseY;
|
||||||
let baseX = row.x;
|
let x = row.x;
|
||||||
for (let j = 0; j < row.windows.length; j++) {
|
for (let j = 0; j < row.windows.length; j++) {
|
||||||
let window = row.windows[j];
|
let window = row.windows[j];
|
||||||
|
|
||||||
let s = this._computeWindowScale(window, scale);
|
let s = scale * this._computeWindowScale(window);
|
||||||
|
let cellWidth = window.actor.width * s;
|
||||||
|
let cellHeight = window.actor.height * s;
|
||||||
|
|
||||||
s = Math.min(s, WINDOW_CLONE_MAXIMUM_SCALE);
|
s = Math.min(s, WINDOW_CLONE_MAXIMUM_SCALE);
|
||||||
let width = window.actor.width * s;
|
let cloneWidth = window.actor.width * s;
|
||||||
let height = window.actor.height * s;
|
|
||||||
let y = row.y + row.height - height;
|
|
||||||
|
|
||||||
let x = baseX;
|
let cloneX = x + (cellWidth - cloneWidth) / 2;
|
||||||
if (row.cellWidth) {
|
let cloneY = row.y + row.height - cellHeight;
|
||||||
x += (row.cellWidth - width) / 2;
|
|
||||||
width = row.cellWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
slots.push([x, y, s, window]);
|
slots.push([cloneX, cloneY, s, window]);
|
||||||
baseX += width + this._columnSpacing;
|
x += cellWidth + this._columnSpacing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return slots;
|
return slots;
|
||||||
@@ -753,7 +838,9 @@ const UnalignedLayoutStrategy = new Lang.Class({
|
|||||||
let rows = [];
|
let rows = [];
|
||||||
let totalWidth = 0;
|
let totalWidth = 0;
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
totalWidth += windows[i].actor.width;
|
let window = windows[i];
|
||||||
|
let s = this._computeWindowScale(window);
|
||||||
|
totalWidth += window.actor.width * s;
|
||||||
}
|
}
|
||||||
|
|
||||||
let idealRowWidth = totalWidth / numRows;
|
let idealRowWidth = totalWidth / numRows;
|
||||||
@@ -765,7 +852,7 @@ const UnalignedLayoutStrategy = new Lang.Class({
|
|||||||
|
|
||||||
for (; windowIdx < windows.length; windowIdx++) {
|
for (; windowIdx < windows.length; windowIdx++) {
|
||||||
let window = windows[windowIdx];
|
let window = windows[windowIdx];
|
||||||
let s = this._computeWindowScale(window, 1);
|
let s = this._computeWindowScale(window);
|
||||||
let width = window.actor.width * s;
|
let width = window.actor.width * s;
|
||||||
let height = window.actor.height * s;
|
let height = window.actor.height * s;
|
||||||
row.fullHeight = Math.max(row.fullHeight, height);
|
row.fullHeight = Math.max(row.fullHeight, height);
|
||||||
@@ -814,7 +901,7 @@ const Workspace = new Lang.Class({
|
|||||||
|
|
||||||
this.monitorIndex = monitorIndex;
|
this.monitorIndex = monitorIndex;
|
||||||
this._monitor = Main.layoutManager.monitors[this.monitorIndex];
|
this._monitor = Main.layoutManager.monitors[this.monitorIndex];
|
||||||
this._windowOverlaysGroup = new Clutter.Group();
|
this._windowOverlaysGroup = new Clutter.Actor();
|
||||||
// Without this the drop area will be overlapped.
|
// Without this the drop area will be overlapped.
|
||||||
this._windowOverlaysGroup.set_size(0, 0);
|
this._windowOverlaysGroup.set_size(0, 0);
|
||||||
|
|
||||||
@@ -839,7 +926,7 @@ const Workspace = new Lang.Class({
|
|||||||
this._windowOverlays = [];
|
this._windowOverlays = [];
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
if (this._isOverviewWindow(windows[i])) {
|
if (this._isOverviewWindow(windows[i])) {
|
||||||
this._addWindowClone(windows[i]);
|
this._addWindowClone(windows[i], true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -964,11 +1051,23 @@ const Workspace = new Lang.Class({
|
|||||||
if (clone.inDrag)
|
if (clone.inDrag)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
|
let cloneWidth = clone.actor.width * scale;
|
||||||
|
let cloneHeight = clone.actor.height * scale;
|
||||||
|
clone.slot = [x, y, cloneWidth, cloneHeight];
|
||||||
|
|
||||||
if (overlay && initialPositioning)
|
if (overlay && (initialPositioning || !clone.positioned))
|
||||||
overlay.hide();
|
overlay.hide();
|
||||||
|
|
||||||
|
if (!clone.positioned) {
|
||||||
|
// This window appeared after the overview was already up
|
||||||
|
// Grow the clone from the center of the slot
|
||||||
|
clone.actor.x = x + cloneWidth / 2;
|
||||||
|
clone.actor.y = y + cloneHeight / 2;
|
||||||
|
clone.actor.scale_x = 0;
|
||||||
|
clone.actor.scale_y = 0;
|
||||||
|
clone.positioned = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (animate && isOnCurrentWorkspace) {
|
if (animate && isOnCurrentWorkspace) {
|
||||||
if (!metaWindow.showing_on_its_workspace()) {
|
if (!metaWindow.showing_on_its_workspace()) {
|
||||||
/* Hidden windows should fade in and grow
|
/* Hidden windows should fade in and grow
|
||||||
@@ -1154,7 +1253,7 @@ const Workspace = new Lang.Class({
|
|||||||
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
|
if (!this._isMyWindow(win) || !this._isOverviewWindow(win))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let [clone, overlay] = this._addWindowClone(win);
|
let [clone, overlay] = this._addWindowClone(win, false);
|
||||||
|
|
||||||
if (win._overviewHint) {
|
if (win._overviewHint) {
|
||||||
let x = win._overviewHint.x - this.actor.x;
|
let x = win._overviewHint.x - this.actor.x;
|
||||||
@@ -1163,16 +1262,10 @@ const Workspace = new Lang.Class({
|
|||||||
delete win._overviewHint;
|
delete win._overviewHint;
|
||||||
|
|
||||||
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
|
clone.slot = [x, y, clone.actor.width * scale, clone.actor.height * scale];
|
||||||
|
clone.positioned = true;
|
||||||
clone.actor.set_position (x, y);
|
clone.actor.set_position (x, y);
|
||||||
clone.actor.set_scale (scale, scale);
|
clone.actor.set_scale (scale, scale);
|
||||||
clone.overlay.relayout(false);
|
clone.overlay.relayout(false);
|
||||||
} else {
|
|
||||||
// Position new windows at the top corner of the workspace rather
|
|
||||||
// than where they were placed for real to avoid the window
|
|
||||||
// being clipped to the workspaceView. Its not really more
|
|
||||||
// natural for the window to suddenly appear in the overview
|
|
||||||
// on some seemingly random location anyway.
|
|
||||||
clone.actor.set_position (this._x, this._y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._currentLayout = null;
|
this._currentLayout = null;
|
||||||
@@ -1319,10 +1412,11 @@ const Workspace = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Create a clone of a (non-desktop) window and add it to the window list
|
// Create a clone of a (non-desktop) window and add it to the window list
|
||||||
_addWindowClone : function(win) {
|
_addWindowClone : function(win, positioned) {
|
||||||
let clone = new WindowClone(win, this);
|
let clone = new WindowClone(win, this);
|
||||||
let overlay = new WindowOverlay(clone, this._windowOverlaysGroup);
|
let overlay = new WindowOverlay(clone, this._windowOverlaysGroup);
|
||||||
clone.overlay = overlay;
|
clone.overlay = overlay;
|
||||||
|
clone.positioned = positioned;
|
||||||
|
|
||||||
clone.connect('selected',
|
clone.connect('selected',
|
||||||
Lang.bind(this, this._onCloneSelected));
|
Lang.bind(this, this._onCloneSelected));
|
||||||
@@ -1349,6 +1443,11 @@ const Workspace = new Lang.Class({
|
|||||||
|
|
||||||
overlay.connect('show-close-button', Lang.bind(this, this._onShowOverlayClose));
|
overlay.connect('show-close-button', Lang.bind(this, this._onShowOverlayClose));
|
||||||
|
|
||||||
|
if (this._windows.length == 0)
|
||||||
|
clone.setStackAbove(null);
|
||||||
|
else
|
||||||
|
clone.setStackAbove(this._windows[this._windows.length - 1].actor);
|
||||||
|
|
||||||
this._windows.push(clone);
|
this._windows.push(clone);
|
||||||
this._windowOverlays.push(overlay);
|
this._windowOverlays.push(overlay);
|
||||||
|
|
||||||
|
|||||||
@@ -62,12 +62,35 @@ const WindowClone = new Lang.Class({
|
|||||||
this.inDrag = false;
|
this.inDrag = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Find the actor just below us, respecting reparenting done
|
||||||
|
// by DND code
|
||||||
|
getActualStackAbove: function() {
|
||||||
|
if (this._stackAbove == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (this.inDrag) {
|
||||||
|
if (this._stackAbove._delegate)
|
||||||
|
return this._stackAbove._delegate.getActualStackAbove();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return this._stackAbove;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
setStackAbove: function (actor) {
|
setStackAbove: function (actor) {
|
||||||
this._stackAbove = actor;
|
this._stackAbove = actor;
|
||||||
if (this._stackAbove == null)
|
|
||||||
|
// Don't apply the new stacking now, it will be applied
|
||||||
|
// when dragging ends and window are stacked again
|
||||||
|
if (actor.inDrag)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let actualAbove = this.getActualStackAbove();
|
||||||
|
if (actualAbove == null)
|
||||||
this.actor.lower_bottom();
|
this.actor.lower_bottom();
|
||||||
else
|
else
|
||||||
this.actor.raise(this._stackAbove);
|
this.actor.raise(actualAbove);
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function () {
|
destroy: function () {
|
||||||
@@ -166,8 +189,8 @@ const WorkspaceThumbnail = new Lang.Class({
|
|||||||
style_class: 'workspace-thumbnail' });
|
style_class: 'workspace-thumbnail' });
|
||||||
this.actor._delegate = this;
|
this.actor._delegate = this;
|
||||||
|
|
||||||
this._contents = new Clutter.Group();
|
this._contents = new Clutter.Actor();
|
||||||
this.actor.add_actor(this._contents);
|
this.actor.add_child(this._contents);
|
||||||
|
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
@@ -361,9 +384,8 @@ const WorkspaceThumbnail = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
destroy : function() {
|
destroy : function() {
|
||||||
this.actor.destroy();
|
if (this.actor)
|
||||||
this._bgManager.destroy();
|
this.actor.destroy();
|
||||||
this._bgManager = null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
workspaceRemoved : function() {
|
workspaceRemoved : function() {
|
||||||
@@ -384,6 +406,11 @@ const WorkspaceThumbnail = new Lang.Class({
|
|||||||
_onDestroy: function(actor) {
|
_onDestroy: function(actor) {
|
||||||
this.workspaceRemoved();
|
this.workspaceRemoved();
|
||||||
|
|
||||||
|
if (this._bgManager) {
|
||||||
|
this._bgManager.destroy();
|
||||||
|
this._bgManager = null;
|
||||||
|
}
|
||||||
|
|
||||||
this._windows = [];
|
this._windows = [];
|
||||||
this.actor = null;
|
this.actor = null;
|
||||||
},
|
},
|
||||||
@@ -535,6 +562,7 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
this._dropPlaceholderPos = -1;
|
this._dropPlaceholderPos = -1;
|
||||||
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
|
this._dropPlaceholder = new St.Bin({ style_class: 'placeholder' });
|
||||||
this.actor.add_actor(this._dropPlaceholder);
|
this.actor.add_actor(this._dropPlaceholder);
|
||||||
|
this._spliceIndex = -1;
|
||||||
|
|
||||||
this._targetScale = 0;
|
this._targetScale = 0;
|
||||||
this._scale = 0;
|
this._scale = 0;
|
||||||
@@ -551,7 +579,6 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
|
|
||||||
this.actor.connect('button-press-event', function() { return true; });
|
this.actor.connect('button-press-event', function() { return true; });
|
||||||
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
|
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonRelease));
|
||||||
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
|
||||||
|
|
||||||
Main.overview.connect('showing',
|
Main.overview.connect('showing',
|
||||||
Lang.bind(this, this._createThumbnails));
|
Lang.bind(this, this._createThumbnails));
|
||||||
@@ -590,7 +617,7 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
let thumbnail = this._thumbnails[i]
|
let thumbnail = this._thumbnails[i]
|
||||||
let [w, h] = thumbnail.actor.get_transformed_size();
|
let [w, h] = thumbnail.actor.get_transformed_size();
|
||||||
if (y >= thumbnail.actor.y && y <= thumbnail.actor.y + h) {
|
if (y >= thumbnail.actor.y && y <= thumbnail.actor.y + h) {
|
||||||
thumbnail.activate(event.time);
|
thumbnail.activate(event.get_time());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -718,6 +745,8 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
return win.get_workspace() >= newWorkspaceIndex;
|
return win.get_workspace() >= newWorkspaceIndex;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._spliceIndex = newWorkspaceIndex;
|
||||||
|
|
||||||
// ... move them down one.
|
// ... move them down one.
|
||||||
windows.forEach(function(win) {
|
windows.forEach(function(win) {
|
||||||
win.meta_window.change_workspace_by_index(win.get_workspace() + 1,
|
win.meta_window.change_workspace_by_index(win.get_workspace() + 1,
|
||||||
@@ -739,6 +768,14 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
WORKSPACE_KEEP_ALIVE_TIME);
|
WORKSPACE_KEEP_ALIVE_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start the animation on the workspace (which is actually
|
||||||
|
// an old one which just became empty)
|
||||||
|
let thumbnail = this._thumbnails[newWorkspaceIndex];
|
||||||
|
this._setThumbnailState(thumbnail, ThumbnailState.NEW);
|
||||||
|
thumbnail.slidePosition = 1;
|
||||||
|
|
||||||
|
this._queueUpdateStates();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -826,7 +863,8 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
this._thumbnails.push(thumbnail);
|
this._thumbnails.push(thumbnail);
|
||||||
this.actor.add_actor(thumbnail.actor);
|
this.actor.add_actor(thumbnail.actor);
|
||||||
|
|
||||||
if (start > 0) { // not the initial fill
|
if (start > 0 && this._spliceIndex == -1) {
|
||||||
|
// not the initial fill, and not splicing via DND
|
||||||
thumbnail.state = ThumbnailState.NEW;
|
thumbnail.state = ThumbnailState.NEW;
|
||||||
thumbnail.slidePosition = 1; // start slid out
|
thumbnail.slidePosition = 1; // start slid out
|
||||||
this._haveNewThumbnails = true;
|
this._haveNewThumbnails = true;
|
||||||
@@ -841,6 +879,9 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
|
|
||||||
// The thumbnails indicator actually needs to be on top of the thumbnails
|
// The thumbnails indicator actually needs to be on top of the thumbnails
|
||||||
this._indicator.raise_top();
|
this._indicator.raise_top();
|
||||||
|
|
||||||
|
// Clear the splice index, we got the message
|
||||||
|
this._spliceIndex = -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
removeThumbnails: function(start, count) {
|
removeThumbnails: function(start, count) {
|
||||||
@@ -1215,16 +1256,5 @@ const ThumbnailsBox = new Lang.Class({
|
|||||||
},
|
},
|
||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
_onScrollEvent: function (actor, event) {
|
|
||||||
switch (event.get_scroll_direction()) {
|
|
||||||
case Clutter.ScrollDirection.UP:
|
|
||||||
Main.wm.actionMoveWorkspace(Meta.MotionDirection.UP);
|
|
||||||
break;
|
|
||||||
case Clutter.ScrollDirection.DOWN:
|
|
||||||
Main.wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -386,6 +386,15 @@ const WorkspacesView = new Lang.Class({
|
|||||||
let current = Math.round(adj.value);
|
let current = Math.round(adj.value);
|
||||||
|
|
||||||
if (active != current) {
|
if (active != current) {
|
||||||
|
if (!this._workspaces[current]) {
|
||||||
|
// The current workspace was destroyed. This could happen
|
||||||
|
// when you are on the last empty workspace, and consolidate
|
||||||
|
// windows using the thumbnail bar.
|
||||||
|
// In that case, the intended behavior is to stay on the empty
|
||||||
|
// workspace, which is the last one, so pick it.
|
||||||
|
current = this._workspaces.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
let metaWorkspace = this._workspaces[current].metaWorkspace;
|
let metaWorkspace = this._workspaces[current].metaWorkspace;
|
||||||
metaWorkspace.activate(global.get_current_time());
|
metaWorkspace.activate(global.get_current_time());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,7 @@ const XdndHandler = new Lang.Class({
|
|||||||
Shell.util_set_hidden_from_pick(this._dummy, true);
|
Shell.util_set_hidden_from_pick(this._dummy, true);
|
||||||
this._dummy.hide();
|
this._dummy.hide();
|
||||||
|
|
||||||
// Mutter delays the creation of the output window as long
|
global.init_xdnd();
|
||||||
// as possible to avoid flicker. In case a plugin wants to
|
|
||||||
// access it directly it has to connect to the stage's show
|
|
||||||
// signal. (see comment in compositor.c:meta_compositor_manage_screen)
|
|
||||||
global.stage.connect('show', function () {
|
|
||||||
global.init_xdnd();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
global.connect('xdnd-enter', Lang.bind(this, this._onEnter));
|
global.connect('xdnd-enter', Lang.bind(this, this._onEnter));
|
||||||
global.connect('xdnd-position-changed', Lang.bind(this, this._onPositionChanged));
|
global.connect('xdnd-position-changed', Lang.bind(this, this._onPositionChanged));
|
||||||
@@ -75,7 +68,7 @@ const XdndHandler = new Lang.Class({
|
|||||||
source: cursorWindow});
|
source: cursorWindow});
|
||||||
|
|
||||||
this._cursorWindowClone = new Clutter.Clone({ source: cursorWindow });
|
this._cursorWindowClone = new Clutter.Clone({ source: cursorWindow });
|
||||||
global.overlay_group.add_actor(this._cursorWindowClone);
|
Main.uiGroup.add_actor(this._cursorWindowClone);
|
||||||
Shell.util_set_hidden_from_pick(this._cursorWindowClone, true);
|
Shell.util_set_hidden_from_pick(this._cursorWindowClone, true);
|
||||||
|
|
||||||
// Make sure that the clone has the same position as the source
|
// Make sure that the clone has the same position as the source
|
||||||
@@ -89,7 +82,7 @@ const XdndHandler = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onPositionChanged: function(obj, x, y) {
|
_onPositionChanged: function(obj, x, y) {
|
||||||
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
|
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
|
||||||
|
|
||||||
// Make sure that the cursor window is on top
|
// Make sure that the cursor window is on top
|
||||||
if (this._cursorWindowClone)
|
if (this._cursorWindowClone)
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ sr@latin
|
|||||||
sv
|
sv
|
||||||
ta
|
ta
|
||||||
te
|
te
|
||||||
|
tg
|
||||||
th
|
th
|
||||||
tr
|
tr
|
||||||
ug
|
ug
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# List of source files containing translatable strings.
|
||||||
|
# Please keep this file sorted alphabetically.
|
||||||
|
[encoding: UTF-8]
|
||||||
data/50-gnome-shell-screenshot.xml.in
|
data/50-gnome-shell-screenshot.xml.in
|
||||||
data/50-gnome-shell-system.xml.in
|
data/50-gnome-shell-system.xml.in
|
||||||
data/gnome-shell.desktop.in.in
|
data/gnome-shell.desktop.in.in
|
||||||
@@ -30,6 +33,7 @@ js/ui/lookingGlass.js
|
|||||||
js/ui/main.js
|
js/ui/main.js
|
||||||
js/ui/messageTray.js
|
js/ui/messageTray.js
|
||||||
js/ui/notificationDaemon.js
|
js/ui/notificationDaemon.js
|
||||||
|
js/ui/overviewControls.js
|
||||||
js/ui/overview.js
|
js/ui/overview.js
|
||||||
js/ui/panel.js
|
js/ui/panel.js
|
||||||
js/ui/popupMenu.js
|
js/ui/popupMenu.js
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
1164
po/en_GB.po
1164
po/en_GB.po
File diff suppressed because it is too large
Load Diff
275
po/et.po
275
po/et.po
@@ -13,8 +13,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: gnome-shell MASTER\n"
|
"Project-Id-Version: gnome-shell MASTER\n"
|
||||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||||
"shell&keywords=I18N+L10N&component=general\n"
|
"shell&keywords=I18N+L10N&component=general\n"
|
||||||
"POT-Creation-Date: 2012-12-09 13:03+0000\n"
|
"POT-Creation-Date: 2013-03-11 22:02+0000\n"
|
||||||
"PO-Revision-Date: 2012-12-19 16:47+0300\n"
|
"PO-Revision-Date: 2013-03-12 16:28+0300\n"
|
||||||
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
|
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
|
||||||
"Language-Team: Estonian <>\n"
|
"Language-Team: Estonian <>\n"
|
||||||
"Language: et\n"
|
"Language: et\n"
|
||||||
@@ -104,6 +104,16 @@ msgid ""
|
|||||||
"favorites area."
|
"favorites area."
|
||||||
msgstr "Nendele tunnustele vastavaid rakendusi kuvatakse lemmikutes."
|
msgstr "Nendele tunnustele vastavaid rakendusi kuvatakse lemmikutes."
|
||||||
|
|
||||||
|
msgid "List of categories that should be displayed as folders"
|
||||||
|
msgstr "Kategooriad, mida tuleb kuvada kaustadena"
|
||||||
|
|
||||||
|
msgid ""
|
||||||
|
"Each category name in this list will be represented as folder in the "
|
||||||
|
"application view, rather than being displayed inline in the main view."
|
||||||
|
msgstr ""
|
||||||
|
"Kõiki selles loetelus olevaid kategooriaid kuvatakse rakenduste vaates "
|
||||||
|
"kaustadena, mitte peavaates teistega koos."
|
||||||
|
|
||||||
msgid "History for command (Alt-F2) dialog"
|
msgid "History for command (Alt-F2) dialog"
|
||||||
msgstr "Käsudialoogi (Alt-F2) ajalugu"
|
msgstr "Käsudialoogi (Alt-F2) ajalugu"
|
||||||
|
|
||||||
@@ -135,12 +145,6 @@ msgstr ""
|
|||||||
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
|
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
|
||||||
"üks kasutaja ning avatud üks seanss."
|
"üks kasutaja ning avatud üks seanss."
|
||||||
|
|
||||||
msgid "Show full name in the user menu"
|
|
||||||
msgstr "Kasutajamenüüs näidatakse kasutaja tervet nime"
|
|
||||||
|
|
||||||
msgid "Whether the users full name is shown in the user menu or not."
|
|
||||||
msgstr "Kas kasutajamenüüs näidatakse kasutaja kogu nime või mitte."
|
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether to remember password for mounting encrypted or remote filesystems"
|
"Whether to remember password for mounting encrypted or remote filesystems"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -299,12 +303,8 @@ msgstr "Laiendus"
|
|||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr "Vali seadistatav laiendus kasutades ülemist valikukasti."
|
msgstr "Vali seadistatav laiendus kasutades ülemist valikukasti."
|
||||||
|
|
||||||
msgid "Session..."
|
msgid "Session…"
|
||||||
msgstr "Seanss..."
|
msgstr "Seanss…"
|
||||||
|
|
||||||
msgctxt "title"
|
|
||||||
msgid "Sign In"
|
|
||||||
msgstr "Sisselogimine"
|
|
||||||
|
|
||||||
#. translators: this message is shown below the user list on the
|
#. translators: this message is shown below the user list on the
|
||||||
#. login screen. It can be activated to reveal an entry for
|
#. login screen. It can be activated to reveal an entry for
|
||||||
@@ -368,16 +368,12 @@ msgstr "Käsku pole võimalik analüüsida:"
|
|||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr "'%s' käivitamine nurjus:"
|
msgstr "'%s' käivitamine nurjus:"
|
||||||
|
|
||||||
#. Translators: Filter to display all applications
|
msgid "Frequent"
|
||||||
|
msgstr "Sage"
|
||||||
|
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Kõik"
|
msgstr "Kõik"
|
||||||
|
|
||||||
msgid "APPLICATIONS"
|
|
||||||
msgstr "RAKENDUSED"
|
|
||||||
|
|
||||||
msgid "SETTINGS"
|
|
||||||
msgstr "SEADED"
|
|
||||||
|
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Uus aken"
|
msgstr "Uus aken"
|
||||||
|
|
||||||
@@ -395,6 +391,12 @@ msgstr "%s lisati lemmikutesse."
|
|||||||
msgid "%s has been removed from your favorites."
|
msgid "%s has been removed from your favorites."
|
||||||
msgstr "%s eemaldati lemmikutest."
|
msgstr "%s eemaldati lemmikutest."
|
||||||
|
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr "Sätted"
|
||||||
|
|
||||||
|
msgid "Change Background…"
|
||||||
|
msgstr "Muuda tausta…"
|
||||||
|
|
||||||
#. Translators: Shown in calendar event list for all day events
|
#. Translators: Shown in calendar event list for all day events
|
||||||
#. * Keep it short, best if you can use less then 10 characters
|
#. * Keep it short, best if you can use less then 10 characters
|
||||||
#.
|
#.
|
||||||
@@ -402,15 +404,18 @@ msgctxt "event list time"
|
|||||||
msgid "All Day"
|
msgid "All Day"
|
||||||
msgstr "Kogu päev"
|
msgstr "Kogu päev"
|
||||||
|
|
||||||
#. Translators: Shown in calendar event list, if 24h format
|
#. Translators: Shown in calendar event list, if 24h format,
|
||||||
|
#. \u2236 is a ratio character, similar to :
|
||||||
msgctxt "event list time"
|
msgctxt "event list time"
|
||||||
msgid "%H:%M"
|
msgid "%H\\u2236%M"
|
||||||
msgstr "%H:%M"
|
msgstr "%H\\u2236%M"
|
||||||
|
|
||||||
#. Transators: Shown in calendar event list, if 12h format
|
#. Transators: Shown in calendar event list, if 12h format,
|
||||||
|
#. \u2236 is a ratio character, similar to : and \u2009 is
|
||||||
|
#. a thin space
|
||||||
msgctxt "event list time"
|
msgctxt "event list time"
|
||||||
msgid "%l:%M %p"
|
msgid "%l\\u2236%M\\u2009%p"
|
||||||
msgstr "%l:%M %p"
|
msgstr "%l\\u2236%M\\u2009%p"
|
||||||
|
|
||||||
#. Translators: Calendar grid abbreviation for Sunday.
|
#. Translators: Calendar grid abbreviation for Sunday.
|
||||||
#. *
|
#. *
|
||||||
@@ -517,6 +522,12 @@ msgstr "Käesolev nädal"
|
|||||||
msgid "Next week"
|
msgid "Next week"
|
||||||
msgstr "Järgmine nädal"
|
msgstr "Järgmine nädal"
|
||||||
|
|
||||||
|
msgid "External drive connected"
|
||||||
|
msgstr "Väline ketas ühendati"
|
||||||
|
|
||||||
|
msgid "External drive disconnected"
|
||||||
|
msgstr "Väline ketas eemaldati"
|
||||||
|
|
||||||
msgid "Removable Devices"
|
msgid "Removable Devices"
|
||||||
msgstr "Eemaldatavad seadmed"
|
msgstr "Eemaldatavad seadmed"
|
||||||
|
|
||||||
@@ -801,12 +812,20 @@ msgstr "Aknad"
|
|||||||
msgid "Show Applications"
|
msgid "Show Applications"
|
||||||
msgstr "Rakenduste kuvamine"
|
msgstr "Rakenduste kuvamine"
|
||||||
|
|
||||||
msgid "Date and Time Settings"
|
#. Translators: this is the name of the dock/favorites area on
|
||||||
msgstr "Kuupäeva ja kellaaja sätted"
|
#. the left of the overview
|
||||||
|
msgid "Dash"
|
||||||
|
msgstr "Dokk"
|
||||||
|
|
||||||
msgid "Open Calendar"
|
msgid "Open Calendar"
|
||||||
msgstr "Ava kalender"
|
msgstr "Ava kalender"
|
||||||
|
|
||||||
|
msgid "Open Clocks"
|
||||||
|
msgstr "Ava kell"
|
||||||
|
|
||||||
|
msgid "Date & Time Settings"
|
||||||
|
msgstr "Kuupäeva ja kella sätted"
|
||||||
|
|
||||||
#. Translators: This is the date format to use when the calendar popup is
|
#. Translators: This is the date format to use when the calendar popup is
|
||||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
#.
|
#.
|
||||||
@@ -897,9 +916,6 @@ msgstr "Paigalda"
|
|||||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||||
msgstr "Kas laadida alla ja paigaldada '%s' aadressilt extensions.gnome.org?"
|
msgstr "Kas laadida alla ja paigaldada '%s' aadressilt extensions.gnome.org?"
|
||||||
|
|
||||||
msgid "tray"
|
|
||||||
msgstr "salv"
|
|
||||||
|
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "Klaviatuur"
|
msgstr "Klaviatuur"
|
||||||
|
|
||||||
@@ -920,6 +936,8 @@ msgstr "Näita vigu"
|
|||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Lubatud"
|
msgstr "Lubatud"
|
||||||
|
|
||||||
|
#. translators:
|
||||||
|
#. * The device has been disabled
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Keelatud"
|
msgstr "Keelatud"
|
||||||
|
|
||||||
@@ -944,6 +962,12 @@ msgstr "Ava"
|
|||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Eemalda"
|
msgstr "Eemalda"
|
||||||
|
|
||||||
|
msgid "Clear Messages"
|
||||||
|
msgstr "Kustuta teated"
|
||||||
|
|
||||||
|
msgid "Notification Settings"
|
||||||
|
msgstr "Märguannete sätted"
|
||||||
|
|
||||||
msgid "No Messages"
|
msgid "No Messages"
|
||||||
msgstr "Teateid pole"
|
msgstr "Teateid pole"
|
||||||
|
|
||||||
@@ -957,6 +981,12 @@ msgctxt "program"
|
|||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "Tundmatu"
|
msgstr "Tundmatu"
|
||||||
|
|
||||||
|
#, c-format
|
||||||
|
msgid "%d new message"
|
||||||
|
msgid_plural "%d new messages"
|
||||||
|
msgstr[0] "%d uus sõnum"
|
||||||
|
msgstr[1] "%d uut sõnumit"
|
||||||
|
|
||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
msgstr "Võta tagasi"
|
msgstr "Võta tagasi"
|
||||||
|
|
||||||
@@ -967,13 +997,8 @@ msgstr "Ülevaade"
|
|||||||
#. in the search entry when no search is
|
#. in the search entry when no search is
|
||||||
#. active; it should not exceed ~30
|
#. active; it should not exceed ~30
|
||||||
#. characters.
|
#. characters.
|
||||||
msgid "Type to search..."
|
msgid "Type to search…"
|
||||||
msgstr "Otsing..."
|
msgstr "Otsing…"
|
||||||
|
|
||||||
#. Translators: this is the name of the dock/favorites area on
|
|
||||||
#. the left of the overview
|
|
||||||
msgid "Dash"
|
|
||||||
msgstr "Dokk"
|
|
||||||
|
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Sulge"
|
msgstr "Sulge"
|
||||||
@@ -1005,12 +1030,6 @@ msgstr "Sulge"
|
|||||||
msgid "%A, %B %d"
|
msgid "%A, %B %d"
|
||||||
msgstr "%A, %d. %B"
|
msgstr "%A, %d. %B"
|
||||||
|
|
||||||
#, c-format
|
|
||||||
msgid "%d new message"
|
|
||||||
msgid_plural "%d new messages"
|
|
||||||
msgstr[0] "%d uus sõnum"
|
|
||||||
msgstr[1] "%d uut sõnumit"
|
|
||||||
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d new notification"
|
msgid "%d new notification"
|
||||||
msgid_plural "%d new notifications"
|
msgid_plural "%d new notifications"
|
||||||
@@ -1020,8 +1039,24 @@ msgstr[1] "%d uut märguannet"
|
|||||||
msgid "Lock"
|
msgid "Lock"
|
||||||
msgstr "Lukusta"
|
msgstr "Lukusta"
|
||||||
|
|
||||||
msgid "Searching..."
|
msgid "GNOME needs to lock the screen"
|
||||||
msgstr "Otsimine..."
|
msgstr "GNOME peab ekraani lukustama"
|
||||||
|
|
||||||
|
#. We could not become modal, so we can't activate the
|
||||||
|
#. screenshield. The user is probably very upset at this
|
||||||
|
#. point, but any application using global grabs is broken
|
||||||
|
#. Just tell him to stop using this app
|
||||||
|
#.
|
||||||
|
#. XXX: another option is to kick the user into the gdm login
|
||||||
|
#. screen, where we're not affected by grabs
|
||||||
|
msgid "Unable to lock"
|
||||||
|
msgstr "Pole võimalik lukustada"
|
||||||
|
|
||||||
|
msgid "Lock was blocked by an application"
|
||||||
|
msgstr "Rakendus blokeeris lukustamise"
|
||||||
|
|
||||||
|
msgid "Searching…"
|
||||||
|
msgstr "Otsing…"
|
||||||
|
|
||||||
msgid "No results."
|
msgid "No results."
|
||||||
msgstr "Tulemused puuduvad."
|
msgstr "Tulemused puuduvad."
|
||||||
@@ -1089,11 +1124,11 @@ msgstr "Bluetooth"
|
|||||||
msgid "Visibility"
|
msgid "Visibility"
|
||||||
msgstr "Nähtavus"
|
msgstr "Nähtavus"
|
||||||
|
|
||||||
msgid "Send Files to Device..."
|
msgid "Send Files to Device…"
|
||||||
msgstr "Failide saatmine seadmesse..."
|
msgstr "Failide saatmine seadmesse…"
|
||||||
|
|
||||||
msgid "Set up a New Device..."
|
msgid "Set Up a New Device…"
|
||||||
msgstr "Uue seadme häälestamine..."
|
msgstr "Uue seadme häälestamine…"
|
||||||
|
|
||||||
msgid "Bluetooth Settings"
|
msgid "Bluetooth Settings"
|
||||||
msgstr "Bluetoothi sätted"
|
msgstr "Bluetoothi sätted"
|
||||||
@@ -1111,8 +1146,8 @@ msgstr "ühenduse katkestamine..."
|
|||||||
msgid "connecting..."
|
msgid "connecting..."
|
||||||
msgstr "ühendumine..."
|
msgstr "ühendumine..."
|
||||||
|
|
||||||
msgid "Send Files..."
|
msgid "Send Files…"
|
||||||
msgstr "Failide saatmine..."
|
msgstr "Failide saatmine…"
|
||||||
|
|
||||||
msgid "Keyboard Settings"
|
msgid "Keyboard Settings"
|
||||||
msgstr "Klaviatuurisätted"
|
msgstr "Klaviatuurisätted"
|
||||||
@@ -1173,7 +1208,7 @@ msgstr "Olgu"
|
|||||||
msgid "Show Keyboard Layout"
|
msgid "Show Keyboard Layout"
|
||||||
msgstr "Klaviatuuripaigutuse kuvamine"
|
msgstr "Klaviatuuripaigutuse kuvamine"
|
||||||
|
|
||||||
msgid "Region and Language Settings"
|
msgid "Region & Language Settings"
|
||||||
msgstr "Asukoha ja keele sätted"
|
msgstr "Asukoha ja keele sätted"
|
||||||
|
|
||||||
msgid "Volume, network, battery"
|
msgid "Volume, network, battery"
|
||||||
@@ -1212,17 +1247,23 @@ msgstr "pole saadaval"
|
|||||||
msgid "connection failed"
|
msgid "connection failed"
|
||||||
msgstr "ühendumine nurjus"
|
msgstr "ühendumine nurjus"
|
||||||
|
|
||||||
msgid "More..."
|
msgid "More…"
|
||||||
msgstr "Veel..."
|
msgstr "Veel…"
|
||||||
|
|
||||||
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
#. TRANSLATORS: this is the indication that a connection for another logged in user is active,
|
||||||
#. and we cannot access its settings (including the name)
|
#. and we cannot access its settings (including the name)
|
||||||
msgid "Connected (private)"
|
msgid "Connected (private)"
|
||||||
msgstr "Ühendatud (privaatne)"
|
msgstr "Ühendatud (privaatne)"
|
||||||
|
|
||||||
|
msgid "Wired"
|
||||||
|
msgstr "Juhtmega"
|
||||||
|
|
||||||
msgid "Auto Ethernet"
|
msgid "Auto Ethernet"
|
||||||
msgstr "Automaatne ethernet"
|
msgstr "Automaatne ethernet"
|
||||||
|
|
||||||
|
msgid "Mobile broadband"
|
||||||
|
msgstr "Mobiiliühendus"
|
||||||
|
|
||||||
msgid "Auto broadband"
|
msgid "Auto broadband"
|
||||||
msgstr "Automaatne lairibaühendus"
|
msgstr "Automaatne lairibaühendus"
|
||||||
|
|
||||||
@@ -1269,8 +1310,8 @@ msgstr "Toitesätted..."
|
|||||||
|
|
||||||
#. 0 is reported when UPower does not have enough data
|
#. 0 is reported when UPower does not have enough data
|
||||||
#. to estimate battery life
|
#. to estimate battery life
|
||||||
msgid "Estimating..."
|
msgid "Estimating…"
|
||||||
msgstr "Andmete kogumine..."
|
msgstr "Andmete kogumine…"
|
||||||
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d hour remaining"
|
msgid "%d hour remaining"
|
||||||
@@ -1304,10 +1345,10 @@ msgctxt "percent of battery remaining"
|
|||||||
msgid "%d%%"
|
msgid "%d%%"
|
||||||
msgstr "%d%%"
|
msgstr "%d%%"
|
||||||
|
|
||||||
msgid "AC adapter"
|
msgid "AC Adapter"
|
||||||
msgstr "Võrgutoite adapter"
|
msgstr "Laadija"
|
||||||
|
|
||||||
msgid "Laptop battery"
|
msgid "Laptop Battery"
|
||||||
msgstr "Sülearvuti aku"
|
msgstr "Sülearvuti aku"
|
||||||
|
|
||||||
msgid "UPS"
|
msgid "UPS"
|
||||||
@@ -1322,10 +1363,10 @@ msgstr "Hiir"
|
|||||||
msgid "PDA"
|
msgid "PDA"
|
||||||
msgstr "Elektronmärkmik"
|
msgstr "Elektronmärkmik"
|
||||||
|
|
||||||
msgid "Cell phone"
|
msgid "Cell Phone"
|
||||||
msgstr "Mobiiltelefon"
|
msgstr "Mobiiltelefon"
|
||||||
|
|
||||||
msgid "Media player"
|
msgid "Media Player"
|
||||||
msgstr "Meediaesitaja"
|
msgstr "Meediaesitaja"
|
||||||
|
|
||||||
msgid "Tablet"
|
msgid "Tablet"
|
||||||
@@ -1338,6 +1379,9 @@ msgctxt "device"
|
|||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "Tundmatu"
|
msgstr "Tundmatu"
|
||||||
|
|
||||||
|
msgid "Volume changed"
|
||||||
|
msgstr "Helivaljus muutus"
|
||||||
|
|
||||||
#. Translators: This is the label for audio volume
|
#. Translators: This is the label for audio volume
|
||||||
msgid "Volume"
|
msgid "Volume"
|
||||||
msgstr "Helivaljus"
|
msgstr "Helivaljus"
|
||||||
@@ -1372,9 +1416,6 @@ msgstr "Ühendamata"
|
|||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Märguanded"
|
msgstr "Märguanded"
|
||||||
|
|
||||||
msgid "Settings"
|
|
||||||
msgstr "Sätted"
|
|
||||||
|
|
||||||
msgid "Switch User"
|
msgid "Switch User"
|
||||||
msgstr "Vaheta kasutajat"
|
msgstr "Vaheta kasutajat"
|
||||||
|
|
||||||
@@ -1394,6 +1435,22 @@ msgstr ""
|
|||||||
"Märguanded on nüüd keelatud, sealhulgas vestlusteated. Sinu netiolekut "
|
"Märguanded on nüüd keelatud, sealhulgas vestlusteated. Sinu netiolekut "
|
||||||
"muudeti, et teised teaksid, et sa ei pruugi nende teateid näha."
|
"muudeti, et teised teaksid, et sa ei pruugi nende teateid näha."
|
||||||
|
|
||||||
|
msgid "Other users are logged in."
|
||||||
|
msgstr "Teised kasutajad on sisse logitud."
|
||||||
|
|
||||||
|
msgid "Shutting down might cause them to lose unsaved work."
|
||||||
|
msgstr "Väljalülitamine võib põhjustada salvestamata töö kaotsimineku."
|
||||||
|
|
||||||
|
#. Translators: Remote here refers to a remote session, like a ssh login
|
||||||
|
#, c-format
|
||||||
|
msgid "%s (remote)"
|
||||||
|
msgstr "%s (kaugühendus)"
|
||||||
|
|
||||||
|
#. Translators: Console here refers to a tty like a VT console
|
||||||
|
#, c-format
|
||||||
|
msgid "%s (console)"
|
||||||
|
msgstr "%s (konsool)"
|
||||||
|
|
||||||
msgid "Applications"
|
msgid "Applications"
|
||||||
msgstr "Rakendused"
|
msgstr "Rakendused"
|
||||||
|
|
||||||
@@ -1412,9 +1469,6 @@ msgstr ""
|
|||||||
msgid "%s the Oracle says"
|
msgid "%s the Oracle says"
|
||||||
msgstr "Oraakel %s ütleb"
|
msgstr "Oraakel %s ütleb"
|
||||||
|
|
||||||
msgid "Your favorite Easter Egg"
|
|
||||||
msgstr "Sinu lemmiküllatusmuna"
|
|
||||||
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "'%s' is ready"
|
msgid "'%s' is ready"
|
||||||
msgstr "'%s' on valmis"
|
msgstr "'%s' on valmis"
|
||||||
@@ -1422,6 +1476,25 @@ msgstr "'%s' on valmis"
|
|||||||
msgid "Evolution Calendar"
|
msgid "Evolution Calendar"
|
||||||
msgstr "Evolutioni kalender"
|
msgstr "Evolutioni kalender"
|
||||||
|
|
||||||
|
#. translators:
|
||||||
|
#. * The number of sound outputs on a particular device
|
||||||
|
#, c-format
|
||||||
|
msgid "%u Output"
|
||||||
|
msgid_plural "%u Outputs"
|
||||||
|
msgstr[0] "%u väljund"
|
||||||
|
msgstr[1] "%u väljundit"
|
||||||
|
|
||||||
|
#. translators:
|
||||||
|
#. * The number of sound inputs on a particular device
|
||||||
|
#, c-format
|
||||||
|
msgid "%u Input"
|
||||||
|
msgid_plural "%u Inputs"
|
||||||
|
msgstr[0] "%u sisend"
|
||||||
|
msgstr[1] "%u sisendit"
|
||||||
|
|
||||||
|
msgid "System Sounds"
|
||||||
|
msgstr "Süsteemi helid"
|
||||||
|
|
||||||
msgid "Print version"
|
msgid "Print version"
|
||||||
msgstr "Printimise versioon"
|
msgstr "Printimise versioon"
|
||||||
|
|
||||||
@@ -1444,15 +1517,48 @@ msgstr "Paroolid ei kattu."
|
|||||||
msgid "Password cannot be blank"
|
msgid "Password cannot be blank"
|
||||||
msgstr "Parool ei saa olla tühi"
|
msgstr "Parool ei saa olla tühi"
|
||||||
|
|
||||||
msgid "United Kingdom"
|
|
||||||
msgstr "Suurbritannia"
|
|
||||||
|
|
||||||
msgid "Default"
|
|
||||||
msgstr "Vaikimisi"
|
|
||||||
|
|
||||||
msgid "Authentication dialog was dismissed by the user"
|
msgid "Authentication dialog was dismissed by the user"
|
||||||
msgstr "Kasutaja katkestas autentimisdialoogi"
|
msgstr "Kasutaja katkestas autentimisdialoogi"
|
||||||
|
|
||||||
|
#~ msgid "Show full name in the user menu"
|
||||||
|
#~ msgstr "Kasutajamenüüs näidatakse kasutaja tervet nime"
|
||||||
|
|
||||||
|
#~ msgid "Whether the users full name is shown in the user menu or not."
|
||||||
|
#~ msgstr "Kas kasutajamenüüs näidatakse kasutaja kogu nime või mitte."
|
||||||
|
|
||||||
|
#~ msgctxt "title"
|
||||||
|
#~ msgid "Sign In"
|
||||||
|
#~ msgstr "Sisselogimine"
|
||||||
|
|
||||||
|
#~ msgid "APPLICATIONS"
|
||||||
|
#~ msgstr "RAKENDUSED"
|
||||||
|
|
||||||
|
#~ msgid "SETTINGS"
|
||||||
|
#~ msgstr "SEADED"
|
||||||
|
|
||||||
|
#~ msgctxt "event list time"
|
||||||
|
#~ msgid "%H:%M"
|
||||||
|
#~ msgstr "%H:%M"
|
||||||
|
|
||||||
|
#~ msgctxt "event list time"
|
||||||
|
#~ msgid "%l:%M %p"
|
||||||
|
#~ msgstr "%l:%M %p"
|
||||||
|
|
||||||
|
#~ msgid "tray"
|
||||||
|
#~ msgstr "salv"
|
||||||
|
|
||||||
|
#~ msgid "More..."
|
||||||
|
#~ msgstr "Veel..."
|
||||||
|
|
||||||
|
#~ msgid "Your favorite Easter Egg"
|
||||||
|
#~ msgstr "Sinu lemmiküllatusmuna"
|
||||||
|
|
||||||
|
#~ msgid "United Kingdom"
|
||||||
|
#~ msgstr "Suurbritannia"
|
||||||
|
|
||||||
|
#~ msgid "Default"
|
||||||
|
#~ msgstr "Vaikimisi"
|
||||||
|
|
||||||
#~ msgid "Subscription request"
|
#~ msgid "Subscription request"
|
||||||
#~ msgstr "Tellimuse päring"
|
#~ msgstr "Tellimuse päring"
|
||||||
|
|
||||||
@@ -1471,28 +1577,9 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
|
|||||||
#~ msgid "Reconnect"
|
#~ msgid "Reconnect"
|
||||||
#~ msgstr "Ühendu uuesti"
|
#~ msgstr "Ühendu uuesti"
|
||||||
|
|
||||||
#~ msgid "Wired"
|
|
||||||
#~ msgstr "Juhtmega"
|
|
||||||
|
|
||||||
#~ msgid "Wireless"
|
#~ msgid "Wireless"
|
||||||
#~ msgstr "Juhtmeta"
|
#~ msgstr "Juhtmeta"
|
||||||
|
|
||||||
#~ msgid "Mobile broadband"
|
|
||||||
#~ msgstr "Mobiiliühendus"
|
|
||||||
|
|
||||||
#~ msgid "%u Output"
|
|
||||||
#~ msgid_plural "%u Outputs"
|
|
||||||
#~ msgstr[0] "%u väljund"
|
|
||||||
#~ msgstr[1] "%u väljundit"
|
|
||||||
|
|
||||||
#~ msgid "%u Input"
|
|
||||||
#~ msgid_plural "%u Inputs"
|
|
||||||
#~ msgstr[0] "%u sisend"
|
|
||||||
#~ msgstr[1] "%u sisendit"
|
|
||||||
|
|
||||||
#~ msgid "System Sounds"
|
|
||||||
#~ msgstr "Süsteemi helid"
|
|
||||||
|
|
||||||
#~ msgid "disabled OpenSearch providers"
|
#~ msgid "disabled OpenSearch providers"
|
||||||
#~ msgstr "keelatud OpenSearch pakkujad"
|
#~ msgstr "keelatud OpenSearch pakkujad"
|
||||||
|
|
||||||
|
|||||||
358
po/it.po
358
po/it.po
@@ -10,8 +10,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell 3.7.x\n"
|
"Project-Id-Version: gnome-shell 3.7.x\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2013-02-19 11:03+0100\n"
|
"POT-Creation-Date: 2013-03-02 15:53+0100\n"
|
||||||
"PO-Revision-Date: 2013-02-19 11:07+0100\n"
|
"PO-Revision-Date: 2013-03-02 15:54+0100\n"
|
||||||
"Last-Translator: Luca Ferretti <lferrett@gnome.org>\n"
|
"Last-Translator: Luca Ferretti <lferrett@gnome.org>\n"
|
||||||
"Language-Team: Italian <tp@lists.linux.it>\n"
|
"Language-Team: Italian <tp@lists.linux.it>\n"
|
||||||
"Language: it\n"
|
"Language: it\n"
|
||||||
@@ -58,7 +58,7 @@ msgid "Window management and application launching"
|
|||||||
msgstr "Gestisce finestre e avvia applicazioni"
|
msgstr "Gestisce finestre e avvia applicazioni"
|
||||||
|
|
||||||
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
|
#: ../data/gnome-shell-extension-prefs.desktop.in.in.h:1
|
||||||
#: ../js/extensionPrefs/main.js:152
|
#: ../js/extensionPrefs/main.js:153
|
||||||
msgid "GNOME Shell Extension Preferences"
|
msgid "GNOME Shell Extension Preferences"
|
||||||
msgstr "Preferenze estensioni di GNOME Shell"
|
msgstr "Preferenze estensioni di GNOME Shell"
|
||||||
|
|
||||||
@@ -128,14 +128,24 @@ msgstr ""
|
|||||||
"visualizzate nell'area dei preferiti."
|
"visualizzate nell'area dei preferiti."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:9
|
||||||
|
msgid "List of categories that should be displayed as folders"
|
||||||
|
msgstr "Elenco di categorie che dovrebbero essere mostrare come cartelle"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10
|
||||||
|
msgid ""
|
||||||
|
"Each category name in this list will be represented as folder in the "
|
||||||
|
"application view, rather than being displayed inline in the main view."
|
||||||
|
msgstr "Ciascun nome di categoria in questa lista sarà rappresentata come una cartella nella vista applicazioni, invece che essere mostrata nella vista principale"
|
||||||
|
|
||||||
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
|
||||||
msgid "History for command (Alt-F2) dialog"
|
msgid "History for command (Alt-F2) dialog"
|
||||||
msgstr "Cronologia per il dialogo dei comandi (Alt-F2)"
|
msgstr "Cronologia per il dialogo dei comandi (Alt-F2)"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:10
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:12
|
||||||
msgid "History for the looking glass dialog"
|
msgid "History for the looking glass dialog"
|
||||||
msgstr "Cronologia per il dialogo looking glass"
|
msgstr "Cronologia per il dialogo looking glass"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:11
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13
|
||||||
msgid ""
|
msgid ""
|
||||||
"Internally used to store the last IM presence explicitly set by the user. "
|
"Internally used to store the last IM presence explicitly set by the user. "
|
||||||
"The value here is from the TpConnectionPresenceType enumeration."
|
"The value here is from the TpConnectionPresenceType enumeration."
|
||||||
@@ -144,7 +154,7 @@ msgstr ""
|
|||||||
"esplicitamente dall'utente. Il valore corrisponde alla enumerazione "
|
"esplicitamente dall'utente. Il valore corrisponde alla enumerazione "
|
||||||
"TpConnectionPresenceType."
|
"TpConnectionPresenceType."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:12
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14
|
||||||
msgid ""
|
msgid ""
|
||||||
"Internally used to store the last session presence status for the user. The "
|
"Internally used to store the last session presence status for the user. The "
|
||||||
"value here is from the GsmPresenceStatus enumeration."
|
"value here is from the GsmPresenceStatus enumeration."
|
||||||
@@ -152,11 +162,11 @@ msgstr ""
|
|||||||
"Usato internamente per memorizzare lo stato di presenza dell'ultima sessione "
|
"Usato internamente per memorizzare lo stato di presenza dell'ultima sessione "
|
||||||
"per l'utente. Il valore corrisponde alla enumerazione GsmPresenceStatus."
|
"per l'utente. Il valore corrisponde alla enumerazione GsmPresenceStatus."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:13
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
|
||||||
msgid "Always show the 'Log out' menuitem in the user menu."
|
msgid "Always show the 'Log out' menuitem in the user menu."
|
||||||
msgstr "Mostra sempre l'elemento \"Termina sessione\" nel menù utente."
|
msgstr "Mostra sempre l'elemento \"Termina sessione\" nel menù utente."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:14
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16
|
||||||
msgid ""
|
msgid ""
|
||||||
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
|
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
|
||||||
"user, single-session situations."
|
"user, single-session situations."
|
||||||
@@ -164,13 +174,13 @@ msgstr ""
|
|||||||
"Questa chiave sovrascrive lo scomparsa automatica dell'elemento \"Termina "
|
"Questa chiave sovrascrive lo scomparsa automatica dell'elemento \"Termina "
|
||||||
"sessione\" nelle modalità singolo utente, sessione singola."
|
"sessione\" nelle modalità singolo utente, sessione singola."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:15
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether to remember password for mounting encrypted or remote filesystems"
|
"Whether to remember password for mounting encrypted or remote filesystems"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Indica se ricordare la password per montare file system remoti o cifrati"
|
"Indica se ricordare la password per montare file system remoti o cifrati"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:16
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18
|
||||||
msgid ""
|
msgid ""
|
||||||
"The shell will request a password when an encrypted device or a remote "
|
"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 "
|
"filesystem is mounted. If the password can be saved for future use a "
|
||||||
@@ -182,73 +192,73 @@ msgstr ""
|
|||||||
"aggiunta la corrispettiva casella di selezione. Questa chiave imposta lo "
|
"aggiunta la corrispettiva casella di selezione. Questa chiave imposta lo "
|
||||||
"stato predefinito di tale casella."
|
"stato predefinito di tale casella."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:17
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19
|
||||||
msgid "Show the week date in the calendar"
|
msgid "Show the week date in the calendar"
|
||||||
msgstr "Mostra il numero della settimana nel calendario"
|
msgstr "Mostra il numero della settimana nel calendario"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:18
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
|
||||||
msgid "If true, display the ISO week date in the calendar."
|
msgid "If true, display the ISO week date in the calendar."
|
||||||
msgstr "Se VERO, mostra il giorno della settimana ISO nel calendario."
|
msgstr "Se VERO, mostra il giorno della settimana ISO nel calendario."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:19
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
|
||||||
msgid "Keybinding to open the application menu"
|
msgid "Keybinding to open the application menu"
|
||||||
msgstr "Associazione tasti per aprire menù applicazioni"
|
msgstr "Associazione tasti per aprire menù applicazioni"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:20
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22
|
||||||
msgid "Keybinding to open the application menu."
|
msgid "Keybinding to open the application menu."
|
||||||
msgstr "Associazione di tasti per aprire il menù delle applicazioni."
|
msgstr "Associazione di tasti per aprire il menù delle applicazioni."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:21
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23
|
||||||
msgid "Keybinding to open the \"Show Applications\" view"
|
msgid "Keybinding to open the \"Show Applications\" view"
|
||||||
msgstr "Associazione tasti per aprire la vista \"Mostra applicazioni\""
|
msgstr "Associazione tasti per aprire la vista \"Mostra applicazioni\""
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:22
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
|
||||||
msgid ""
|
msgid ""
|
||||||
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
|
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Associazione di tasti per aprire la vista \"Mosta applicazioni\" della "
|
"Associazione di tasti per aprire la vista \"Mosta applicazioni\" della "
|
||||||
"panoramica Attività."
|
"panoramica Attività."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:23
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
|
||||||
msgid "Keybinding to toggle the visibility of the message tray"
|
msgid "Keybinding to toggle the visibility of the message tray"
|
||||||
msgstr "Associazione tasti per commutare la visibilità del cassetto messaggi"
|
msgstr "Associazione tasti per commutare la visibilità del cassetto messaggi"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:24
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26
|
||||||
msgid "Keybinding to toggle the visibility of the message tray."
|
msgid "Keybinding to toggle the visibility of the message tray."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Associazione di tasti per commutare la visibilità del cassetto messaggi."
|
"Associazione di tasti per commutare la visibilità del cassetto messaggi."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:25
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
|
||||||
msgid "Keybinding to focus the active notification"
|
msgid "Keybinding to focus the active notification"
|
||||||
msgstr "Associazione tasti dare il focus alla notifica attiva"
|
msgstr "Associazione tasti dare il focus alla notifica attiva"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:26
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28
|
||||||
msgid "Keybinding to focus the active notification."
|
msgid "Keybinding to focus the active notification."
|
||||||
msgstr "Associazione di tasti per dare il focus alla notifica attiva."
|
msgstr "Associazione di tasti per dare il focus alla notifica attiva."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:27
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29
|
||||||
msgid "Keybinding to toggle the screen recorder"
|
msgid "Keybinding to toggle the screen recorder"
|
||||||
msgstr "Associazione tasti per commutare registrazione schermo"
|
msgstr "Associazione tasti per commutare registrazione schermo"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:28
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30
|
||||||
msgid "Keybinding to start/stop the builtin screen recorder."
|
msgid "Keybinding to start/stop the builtin screen recorder."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Associazione di tasti per avviare/fermare il registratore di schermo "
|
"Associazione di tasti per avviare/fermare il registratore di schermo "
|
||||||
"incorporato."
|
"incorporato."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:29
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31
|
||||||
msgid "Which keyboard to use"
|
msgid "Which keyboard to use"
|
||||||
msgstr "Quale tastiera usare"
|
msgstr "Quale tastiera usare"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:30
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32
|
||||||
msgid "The type of keyboard to use."
|
msgid "The type of keyboard to use."
|
||||||
msgstr "Il tipo di tastiera da usare."
|
msgstr "Il tipo di tastiera da usare."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:31
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33
|
||||||
msgid "Framerate used for recording screencasts."
|
msgid "Framerate used for recording screencasts."
|
||||||
msgstr "Framerate per la registrazione di screencast."
|
msgstr "Framerate per la registrazione di screencast."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:32
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:34
|
||||||
msgid ""
|
msgid ""
|
||||||
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
"The framerate of the resulting screencast recordered by GNOME Shell's "
|
||||||
"screencast recorder in frames-per-second."
|
"screencast recorder in frames-per-second."
|
||||||
@@ -256,11 +266,11 @@ msgstr ""
|
|||||||
"Il framerate in fotogrammi al secondo dello screencast registrato attraverso "
|
"Il framerate in fotogrammi al secondo dello screencast registrato attraverso "
|
||||||
"il registratore della GNOME Shell."
|
"il registratore della GNOME Shell."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:33
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
|
||||||
msgid "The gstreamer pipeline used to encode the screencast"
|
msgid "The gstreamer pipeline used to encode the screencast"
|
||||||
msgstr "La pipeline di gstreamer utilizzata per codificare lo screencast"
|
msgstr "La pipeline di gstreamer utilizzata per codificare lo screencast"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:35
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
|
||||||
@@ -287,11 +297,11 @@ msgstr ""
|
|||||||
"usato come un segnaposto per una stima del valore di thread ottimale per il "
|
"usato come un segnaposto per una stima del valore di thread ottimale per il "
|
||||||
"sistema in uso."
|
"sistema in uso."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:36
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
|
||||||
msgid "File extension used for storing the screencast"
|
msgid "File extension used for storing the screencast"
|
||||||
msgstr "Estensione del file utilizzato per salvare lo screencast"
|
msgstr "Estensione del file utilizzato per salvare lo screencast"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:37
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39
|
||||||
msgid ""
|
msgid ""
|
||||||
"The filename for recorded screencasts will be a unique filename based on the "
|
"The filename for recorded screencasts will be a unique filename based on the "
|
||||||
"current date, and use this extension. It should be changed when recording to "
|
"current date, and use this extension. It should be changed when recording to "
|
||||||
@@ -301,11 +311,11 @@ msgstr ""
|
|||||||
"data corrente e utilizza questa estensione. Dovrebbe essere modificato "
|
"data corrente e utilizza questa estensione. Dovrebbe essere modificato "
|
||||||
"quando si registra utilizzando un diverso formato contenitore."
|
"quando si registra utilizzando un diverso formato contenitore."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:38
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40
|
||||||
msgid "The application icon mode."
|
msgid "The application icon mode."
|
||||||
msgstr "La modalità dell'icona dell'applicazione."
|
msgstr "La modalità dell'icona dell'applicazione."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:39
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:41
|
||||||
msgid ""
|
msgid ""
|
||||||
"Configures how the windows are shown in the switcher. Valid possibilities "
|
"Configures how the windows are shown in the switcher. Valid possibilities "
|
||||||
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
|
"are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-"
|
||||||
@@ -315,22 +325,22 @@ msgstr ""
|
|||||||
"sono: \"thumbnail-only\" (mostra una miniatura della finestra), \"app-icon-"
|
"sono: \"thumbnail-only\" (mostra una miniatura della finestra), \"app-icon-"
|
||||||
"only\" (mostra solo l'icona dell'applicazione) oppure \"both\"."
|
"only\" (mostra solo l'icona dell'applicazione) oppure \"both\"."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:40
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:42
|
||||||
msgid "Attach modal dialog to the parent window"
|
msgid "Attach modal dialog to the parent window"
|
||||||
msgstr "Collega la finestra modale a quella genitore"
|
msgstr "Collega la finestra modale a quella genitore"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:41
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43
|
||||||
msgid ""
|
msgid ""
|
||||||
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
|
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Questa chiave scavalca la chiave in org.gnome.mutter quando si esegue GNOME "
|
"Questa chiave scavalca la chiave in org.gnome.mutter quando si esegue GNOME "
|
||||||
"Shell."
|
"Shell."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:42
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:44
|
||||||
msgid "Arrangement of buttons on the titlebar"
|
msgid "Arrangement of buttons on the titlebar"
|
||||||
msgstr "Disposizione dei pulsanti nella barra del titolo"
|
msgstr "Disposizione dei pulsanti nella barra del titolo"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:43
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:45
|
||||||
msgid ""
|
msgid ""
|
||||||
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
|
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
|
||||||
"GNOME Shell."
|
"GNOME Shell."
|
||||||
@@ -338,76 +348,73 @@ msgstr ""
|
|||||||
"Questa chiave scavalca la chiave in org.gnome.desktop.wm.preferences quando "
|
"Questa chiave scavalca la chiave in org.gnome.desktop.wm.preferences quando "
|
||||||
"si esegue GNOME Shell."
|
"si esegue GNOME Shell."
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:44
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:46
|
||||||
msgid "Enable edge tiling when dropping windows on screen edges"
|
msgid "Enable edge tiling when dropping windows on screen edges"
|
||||||
msgstr "Abilita il tiling di bordo quando si trascinano le finestre sui bordi dello schermo"
|
msgstr ""
|
||||||
|
"Abilita il tiling di bordo quando si trascinano le finestre sui bordi dello "
|
||||||
|
"schermo"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:45
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:47
|
||||||
msgid "Workspaces are managed dynamically"
|
msgid "Workspaces are managed dynamically"
|
||||||
msgstr "Spazi di lavoro sono gestiti dinamicamente"
|
msgstr "Spazi di lavoro sono gestiti dinamicamente"
|
||||||
|
|
||||||
#: ../data/org.gnome.shell.gschema.xml.in.in.h:46
|
#: ../data/org.gnome.shell.gschema.xml.in.in.h:48
|
||||||
msgid "Workspaces only on primary monitor"
|
msgid "Workspaces only on primary monitor"
|
||||||
msgstr "Spazi di lavoro solo sul monitor primario"
|
msgstr "Spazi di lavoro solo sul monitor primario"
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:124
|
#: ../js/extensionPrefs/main.js:125
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "There was an error loading the preferences dialog for %s:"
|
msgid "There was an error loading the preferences dialog for %s:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Si è verificato un errore nel caricare il dialogo delle preferenze per %s:"
|
"Si è verificato un errore nel caricare il dialogo delle preferenze per %s:"
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:164
|
#: ../js/extensionPrefs/main.js:165
|
||||||
msgid "Extension"
|
msgid "Extension"
|
||||||
msgstr "Estensione"
|
msgstr "Estensione"
|
||||||
|
|
||||||
#: ../js/extensionPrefs/main.js:188
|
#: ../js/extensionPrefs/main.js:189
|
||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Selezionare una estensione da configurare usando la casella combinata qui "
|
"Selezionare una estensione da configurare usando la casella combinata qui "
|
||||||
"sopra."
|
"sopra."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:569
|
#: ../js/gdm/loginDialog.js:405
|
||||||
msgid "Session…"
|
msgid "Session…"
|
||||||
msgstr "Sessione…"
|
msgstr "Sessione…"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:726
|
|
||||||
msgctxt "title"
|
|
||||||
msgid "Sign In"
|
|
||||||
msgstr "Accesso"
|
|
||||||
|
|
||||||
#. translators: this message is shown below the user list on the
|
#. translators: this message is shown below the user list on the
|
||||||
#. login screen. It can be activated to reveal an entry for
|
#. login screen. It can be activated to reveal an entry for
|
||||||
#. manually entering the username.
|
#. manually entering the username.
|
||||||
#: ../js/gdm/loginDialog.js:790
|
#: ../js/gdm/loginDialog.js:629
|
||||||
msgid "Not listed?"
|
msgid "Not listed?"
|
||||||
msgstr "Non elencato?"
|
msgstr "Non elencato?"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:970 ../js/ui/components/networkAgent.js:137
|
#: ../js/gdm/loginDialog.js:783 ../js/ui/components/networkAgent.js:137
|
||||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
||||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:178
|
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:126
|
||||||
#: ../js/ui/userMenu.js:932
|
#: ../js/ui/userMenu.js:932
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Annulla"
|
msgstr "Annulla"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:986
|
#: ../js/gdm/loginDialog.js:799
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Accedi"
|
msgstr "Accedi"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:986
|
#: ../js/gdm/loginDialog.js:799
|
||||||
msgid "Next"
|
msgid "Next"
|
||||||
msgstr "Avanti"
|
msgstr "Avanti"
|
||||||
|
|
||||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||||
#. is not visible here since we only care about phase2 authentication
|
#. is not visible here since we only care about phase2 authentication
|
||||||
#. (and don't even care of which one)
|
#. (and don't even care of which one)
|
||||||
#: ../js/gdm/loginDialog.js:1095 ../js/ui/components/networkAgent.js:260
|
#: ../js/gdm/loginDialog.js:904 ../js/ui/components/networkAgent.js:260
|
||||||
#: ../js/ui/components/networkAgent.js:278
|
#: ../js/ui/components/networkAgent.js:278
|
||||||
msgid "Username: "
|
msgid "Username: "
|
||||||
msgstr "Nome utente: "
|
msgstr "Nome utente: "
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1391
|
#: ../js/gdm/loginDialog.js:1157
|
||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "Finestra di accesso"
|
msgstr "Finestra di accesso"
|
||||||
|
|
||||||
@@ -430,50 +437,53 @@ msgstr "Riavvia"
|
|||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Spegni"
|
msgstr "Spegni"
|
||||||
|
|
||||||
#: ../js/gdm/util.js:152
|
#: ../js/gdm/util.js:182
|
||||||
msgid "Authentication error"
|
msgid "Authentication error"
|
||||||
msgstr "Errore di autenticazione"
|
msgstr "Errore di autenticazione"
|
||||||
|
|
||||||
#. Translators: this message is shown below the password entry field
|
#. Translators: this message is shown below the password entry field
|
||||||
#. to indicate the user can swipe their finger instead
|
#. to indicate the user can swipe their finger instead
|
||||||
#: ../js/gdm/util.js:269
|
#: ../js/gdm/util.js:299
|
||||||
msgid "(or swipe finger)"
|
msgid "(or swipe finger)"
|
||||||
msgstr "(o passare il dito)"
|
msgstr "(o passare il dito)"
|
||||||
|
|
||||||
#: ../js/gdm/util.js:294
|
#: ../js/gdm/util.js:324
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "(e.g., user or %s)"
|
msgid "(e.g., user or %s)"
|
||||||
msgstr "(p.e. utente o %s)"
|
msgstr "(p.e. utente o %s)"
|
||||||
|
|
||||||
#: ../js/misc/util.js:92
|
#: ../js/misc/util.js:94
|
||||||
msgid "Command not found"
|
msgid "Command not found"
|
||||||
msgstr "Comando non trovato"
|
msgstr "Comando non trovato"
|
||||||
|
|
||||||
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
#. Replace "Error invoking GLib.shell_parse_argv: " with
|
||||||
#. something nicer
|
#. something nicer
|
||||||
#: ../js/misc/util.js:125
|
#: ../js/misc/util.js:127
|
||||||
msgid "Could not parse command:"
|
msgid "Could not parse command:"
|
||||||
msgstr "Impossibile analizzare il comando:"
|
msgstr "Impossibile analizzare il comando:"
|
||||||
|
|
||||||
#: ../js/misc/util.js:133
|
#: ../js/misc/util.js:135
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Execution of '%s' failed:"
|
msgid "Execution of '%s' failed:"
|
||||||
msgstr "Esecuzione di «%s» non riuscita:"
|
msgstr "Esecuzione di «%s» non riuscita:"
|
||||||
|
|
||||||
#. Translators: Filter to display all applications
|
#: ../js/ui/appDisplay.js:348
|
||||||
#: ../js/ui/appDisplay.js:259
|
msgid "Frequent"
|
||||||
|
msgstr "Frequenti"
|
||||||
|
|
||||||
|
#: ../js/ui/appDisplay.js:355
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tutte"
|
msgstr "Tutte"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:624
|
#: ../js/ui/appDisplay.js:913
|
||||||
msgid "New Window"
|
msgid "New Window"
|
||||||
msgstr "Nuova finestra"
|
msgstr "Nuova finestra"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:627 ../js/ui/dash.js:286
|
#: ../js/ui/appDisplay.js:916 ../js/ui/dash.js:284
|
||||||
msgid "Remove from Favorites"
|
msgid "Remove from Favorites"
|
||||||
msgstr "Rimuovi dai preferiti"
|
msgstr "Rimuovi dai preferiti"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:628
|
#: ../js/ui/appDisplay.js:917
|
||||||
msgid "Add to Favorites"
|
msgid "Add to Favorites"
|
||||||
msgstr "Aggiungi ai preferiti"
|
msgstr "Aggiungi ai preferiti"
|
||||||
|
|
||||||
@@ -489,6 +499,14 @@ msgstr "%s è stato aggiunto ai preferiti."
|
|||||||
msgid "%s has been removed from your favorites."
|
msgid "%s has been removed from your favorites."
|
||||||
msgstr "%s è stato rimosso dai preferiti."
|
msgstr "%s è stato rimosso dai preferiti."
|
||||||
|
|
||||||
|
#: ../js/ui/backgroundMenu.js:19 ../js/ui/userMenu.js:787
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr "Impostazioni"
|
||||||
|
|
||||||
|
#: ../js/ui/backgroundMenu.js:21
|
||||||
|
msgid "Change Background…"
|
||||||
|
msgstr "Cambia sfondo…"
|
||||||
|
|
||||||
#. Translators: Shown in calendar event list for all day events
|
#. Translators: Shown in calendar event list for all day events
|
||||||
#. * Keep it short, best if you can use less then 10 characters
|
#. * Keep it short, best if you can use less then 10 characters
|
||||||
#.
|
#.
|
||||||
@@ -800,39 +818,39 @@ msgid "Mute"
|
|||||||
msgstr "Disattiva notifiche"
|
msgstr "Disattiva notifiche"
|
||||||
|
|
||||||
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"
|
#. Translators: this is the word "Yesterday" followed by a time string. i.e. "Yesterday, 14:30"
|
||||||
#: ../js/ui/components/telepathyClient.js:938
|
#: ../js/ui/components/telepathyClient.js:942
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "<b>Yesterday</b>, <b>%H:%M</b>"
|
msgid "<b>Yesterday</b>, <b>%H:%M</b>"
|
||||||
msgstr "<b>Ieri</b>, <b>%-H.%M</b>"
|
msgstr "<b>Ieri</b>, <b>%-H.%M</b>"
|
||||||
|
|
||||||
#. Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30
|
#. Translators: this is the week day name followed by a time string. i.e. "Monday, 14:30
|
||||||
#: ../js/ui/components/telepathyClient.js:944
|
#: ../js/ui/components/telepathyClient.js:948
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "<b>%A</b>, <b>%H:%M</b>"
|
msgid "<b>%A</b>, <b>%H:%M</b>"
|
||||||
msgstr "<b>%A</b>, <b>%-H.%M</b>"
|
msgstr "<b>%A</b>, <b>%-H.%M</b>"
|
||||||
|
|
||||||
#. Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"
|
#. Translators: this is the month name and day number followed by a time string. i.e. "May 25, 14:30"
|
||||||
#: ../js/ui/components/telepathyClient.js:949
|
#: ../js/ui/components/telepathyClient.js:953
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "<b>%B</b> <b>%d</b>, <b>%H:%M</b>"
|
msgid "<b>%B</b> <b>%d</b>, <b>%H:%M</b>"
|
||||||
msgstr "<b>%d</b> <b>%B</b>, <b>%-H.%M</b>"
|
msgstr "<b>%d</b> <b>%B</b>, <b>%-H.%M</b>"
|
||||||
|
|
||||||
#. Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"
|
#. Translators: this is the month name, day number, year number followed by a time string. i.e. "May 25 2012, 14:30"
|
||||||
#: ../js/ui/components/telepathyClient.js:953
|
#: ../js/ui/components/telepathyClient.js:957
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
|
msgid "<b>%B</b> <b>%d</b> <b>%Y</b>, <b>%H:%M</b> "
|
||||||
msgstr "<b>%d</b> <b>%B</b> <b>%Y</b>, <b>%-H.%M</b>"
|
msgstr "<b>%d</b> <b>%B</b> <b>%Y</b>, <b>%-H.%M</b>"
|
||||||
|
|
||||||
#. Translators: this is the other person changing their old IM name to their new
|
#. Translators: this is the other person changing their old IM name to their new
|
||||||
#. IM name.
|
#. IM name.
|
||||||
#: ../js/ui/components/telepathyClient.js:981
|
#: ../js/ui/components/telepathyClient.js:985
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is now known as %s"
|
msgid "%s is now known as %s"
|
||||||
msgstr "%s ha cambiato nome in %s"
|
msgstr "%s ha cambiato nome in %s"
|
||||||
|
|
||||||
#. translators: argument is a room name like
|
#. translators: argument is a room name like
|
||||||
#. * room@jabber.org for example.
|
#. * room@jabber.org for example.
|
||||||
#: ../js/ui/components/telepathyClient.js:1084
|
#: ../js/ui/components/telepathyClient.js:1088
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Invitation to %s"
|
msgid "Invitation to %s"
|
||||||
msgstr "Invio su %s"
|
msgstr "Invio su %s"
|
||||||
@@ -840,38 +858,38 @@ msgstr "Invio su %s"
|
|||||||
#. translators: first argument is the name of a contact and the second
|
#. translators: first argument is the name of a contact and the second
|
||||||
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
|
#. * one the name of a room. "Alice is inviting you to join room@jabber.org
|
||||||
#. * for example.
|
#. * for example.
|
||||||
#: ../js/ui/components/telepathyClient.js:1092
|
#: ../js/ui/components/telepathyClient.js:1096
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is inviting you to join %s"
|
msgid "%s is inviting you to join %s"
|
||||||
msgstr "%s ti sta invitando su %s"
|
msgstr "%s ti sta invitando su %s"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1094
|
#: ../js/ui/components/telepathyClient.js:1098
|
||||||
#: ../js/ui/components/telepathyClient.js:1133
|
#: ../js/ui/components/telepathyClient.js:1137
|
||||||
#: ../js/ui/components/telepathyClient.js:1173
|
#: ../js/ui/components/telepathyClient.js:1177
|
||||||
#: ../js/ui/components/telepathyClient.js:1236
|
#: ../js/ui/components/telepathyClient.js:1240
|
||||||
msgid "Decline"
|
msgid "Decline"
|
||||||
msgstr "Declina"
|
msgstr "Declina"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1095
|
#: ../js/ui/components/telepathyClient.js:1099
|
||||||
#: ../js/ui/components/telepathyClient.js:1174
|
#: ../js/ui/components/telepathyClient.js:1178
|
||||||
#: ../js/ui/components/telepathyClient.js:1237
|
#: ../js/ui/components/telepathyClient.js:1241
|
||||||
msgid "Accept"
|
msgid "Accept"
|
||||||
msgstr "Accetta"
|
msgstr "Accetta"
|
||||||
|
|
||||||
#. translators: argument is a contact name like Alice for example.
|
#. translators: argument is a contact name like Alice for example.
|
||||||
#: ../js/ui/components/telepathyClient.js:1125
|
#: ../js/ui/components/telepathyClient.js:1129
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Video call from %s"
|
msgid "Video call from %s"
|
||||||
msgstr "Videochiamata da %s"
|
msgstr "Videochiamata da %s"
|
||||||
|
|
||||||
#. translators: argument is a contact name like Alice for example.
|
#. translators: argument is a contact name like Alice for example.
|
||||||
#: ../js/ui/components/telepathyClient.js:1128
|
#: ../js/ui/components/telepathyClient.js:1132
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Call from %s"
|
msgid "Call from %s"
|
||||||
msgstr "Chiamata da %s"
|
msgstr "Chiamata da %s"
|
||||||
|
|
||||||
#. translators: this is a button label (verb), not a noun
|
#. translators: this is a button label (verb), not a noun
|
||||||
#: ../js/ui/components/telepathyClient.js:1135
|
#: ../js/ui/components/telepathyClient.js:1139
|
||||||
msgid "Answer"
|
msgid "Answer"
|
||||||
msgstr "Rispondi"
|
msgstr "Rispondi"
|
||||||
|
|
||||||
@@ -880,112 +898,112 @@ msgstr "Rispondi"
|
|||||||
#. * file name. The string will be something
|
#. * file name. The string will be something
|
||||||
#. * like: "Alice is sending you test.ogg"
|
#. * like: "Alice is sending you test.ogg"
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/components/telepathyClient.js:1167
|
#: ../js/ui/components/telepathyClient.js:1171
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s is sending you %s"
|
msgid "%s is sending you %s"
|
||||||
msgstr "%s ti sta inviando %s"
|
msgstr "%s ti sta inviando %s"
|
||||||
|
|
||||||
#. To translators: The parameter is the contact's alias
|
#. To translators: The parameter is the contact's alias
|
||||||
#: ../js/ui/components/telepathyClient.js:1202
|
#: ../js/ui/components/telepathyClient.js:1206
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s would like permission to see when you are online"
|
msgid "%s would like permission to see when you are online"
|
||||||
msgstr "%s chiede il permesso di vedere quando sei online"
|
msgstr "%s chiede il permesso di vedere quando sei online"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1294
|
#: ../js/ui/components/telepathyClient.js:1298
|
||||||
msgid "Network error"
|
msgid "Network error"
|
||||||
msgstr "Errore di rete"
|
msgstr "Errore di rete"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1296
|
#: ../js/ui/components/telepathyClient.js:1300
|
||||||
msgid "Authentication failed"
|
msgid "Authentication failed"
|
||||||
msgstr "Autenticazione non riuscita"
|
msgstr "Autenticazione non riuscita"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1298
|
#: ../js/ui/components/telepathyClient.js:1302
|
||||||
msgid "Encryption error"
|
msgid "Encryption error"
|
||||||
msgstr "Errore di cifratura"
|
msgstr "Errore di cifratura"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1300
|
#: ../js/ui/components/telepathyClient.js:1304
|
||||||
msgid "Certificate not provided"
|
msgid "Certificate not provided"
|
||||||
msgstr "Certificato non fornito"
|
msgstr "Certificato non fornito"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1302
|
#: ../js/ui/components/telepathyClient.js:1306
|
||||||
msgid "Certificate untrusted"
|
msgid "Certificate untrusted"
|
||||||
msgstr "Certificato non fidato"
|
msgstr "Certificato non fidato"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1304
|
#: ../js/ui/components/telepathyClient.js:1308
|
||||||
msgid "Certificate expired"
|
msgid "Certificate expired"
|
||||||
msgstr "Certificato scaduto"
|
msgstr "Certificato scaduto"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1306
|
#: ../js/ui/components/telepathyClient.js:1310
|
||||||
msgid "Certificate not activated"
|
msgid "Certificate not activated"
|
||||||
msgstr "Certificato non attivato"
|
msgstr "Certificato non attivato"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1308
|
#: ../js/ui/components/telepathyClient.js:1312
|
||||||
msgid "Certificate hostname mismatch"
|
msgid "Certificate hostname mismatch"
|
||||||
msgstr "Corrispondenza errata nel nome host del certificato"
|
msgstr "Corrispondenza errata nel nome host del certificato"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1310
|
#: ../js/ui/components/telepathyClient.js:1314
|
||||||
msgid "Certificate fingerprint mismatch"
|
msgid "Certificate fingerprint mismatch"
|
||||||
msgstr "Corrispondenza errata nell'impronta digitare del certificato"
|
msgstr "Corrispondenza errata nell'impronta digitare del certificato"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1312
|
#: ../js/ui/components/telepathyClient.js:1316
|
||||||
msgid "Certificate self-signed"
|
msgid "Certificate self-signed"
|
||||||
msgstr "Certificato auto-firmato"
|
msgstr "Certificato auto-firmato"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1314
|
#: ../js/ui/components/telepathyClient.js:1318
|
||||||
msgid "Status is set to offline"
|
msgid "Status is set to offline"
|
||||||
msgstr "Lo stato è impostato a fuori rete"
|
msgstr "Lo stato è impostato a fuori rete"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1316
|
#: ../js/ui/components/telepathyClient.js:1320
|
||||||
msgid "Encryption is not available"
|
msgid "Encryption is not available"
|
||||||
msgstr "La cifratura non è disponibile"
|
msgstr "La cifratura non è disponibile"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1318
|
#: ../js/ui/components/telepathyClient.js:1322
|
||||||
msgid "Certificate is invalid"
|
msgid "Certificate is invalid"
|
||||||
msgstr "Il certificato non è valido"
|
msgstr "Il certificato non è valido"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1320
|
#: ../js/ui/components/telepathyClient.js:1324
|
||||||
msgid "Connection has been refused"
|
msgid "Connection has been refused"
|
||||||
msgstr "La connessione è stata rifiutata"
|
msgstr "La connessione è stata rifiutata"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1322
|
#: ../js/ui/components/telepathyClient.js:1326
|
||||||
msgid "Connection can't be established"
|
msgid "Connection can't be established"
|
||||||
msgstr "Impossibile stabilire la connessione"
|
msgstr "Impossibile stabilire la connessione"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1324
|
#: ../js/ui/components/telepathyClient.js:1328
|
||||||
msgid "Connection has been lost"
|
msgid "Connection has been lost"
|
||||||
msgstr "Connessione persa"
|
msgstr "Connessione persa"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1326
|
#: ../js/ui/components/telepathyClient.js:1330
|
||||||
msgid "This account is already connected to the server"
|
msgid "This account is already connected to the server"
|
||||||
msgstr "Questo account è già connesso al server"
|
msgstr "Questo account è già connesso al server"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1328
|
#: ../js/ui/components/telepathyClient.js:1332
|
||||||
msgid ""
|
msgid ""
|
||||||
"Connection has been replaced by a new connection using the same resource"
|
"Connection has been replaced by a new connection using the same resource"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La connessione è stata sostituita da una nuova connessione usando la stessa "
|
"La connessione è stata sostituita da una nuova connessione usando la stessa "
|
||||||
"risorsa"
|
"risorsa"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1330
|
#: ../js/ui/components/telepathyClient.js:1334
|
||||||
msgid "The account already exists on the server"
|
msgid "The account already exists on the server"
|
||||||
msgstr "L'account esiste già sul server"
|
msgstr "L'account esiste già sul server"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1332
|
#: ../js/ui/components/telepathyClient.js:1336
|
||||||
msgid "Server is currently too busy to handle the connection"
|
msgid "Server is currently too busy to handle the connection"
|
||||||
msgstr "Il server è al momento troppo occupato per gestire la connessione"
|
msgstr "Il server è al momento troppo occupato per gestire la connessione"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1334
|
#: ../js/ui/components/telepathyClient.js:1338
|
||||||
msgid "Certificate has been revoked"
|
msgid "Certificate has been revoked"
|
||||||
msgstr "Il certificato è stato revocato"
|
msgstr "Il certificato è stato revocato"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1336
|
#: ../js/ui/components/telepathyClient.js:1340
|
||||||
msgid ""
|
msgid ""
|
||||||
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
"Certificate uses an insecure cipher algorithm or is cryptographically weak"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Il certificato usa un algoritmo di cifratura non sicuro o è "
|
"Il certificato usa un algoritmo di cifratura non sicuro o è "
|
||||||
"crittograficamente debole"
|
"crittograficamente debole"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1338
|
#: ../js/ui/components/telepathyClient.js:1342
|
||||||
msgid ""
|
msgid ""
|
||||||
"The length of the server certificate, or the depth of the server certificate "
|
"The length of the server certificate, or the depth of the server certificate "
|
||||||
"chain, exceed the limits imposed by the cryptography library"
|
"chain, exceed the limits imposed by the cryptography library"
|
||||||
@@ -996,22 +1014,22 @@ msgstr ""
|
|||||||
|
|
||||||
# indica lo stato del device BT, per esempio gli auricolari
|
# indica lo stato del device BT, per esempio gli auricolari
|
||||||
# credo sia meglio l'aggettivo che il sostantivo
|
# credo sia meglio l'aggettivo che il sostantivo
|
||||||
#: ../js/ui/components/telepathyClient.js:1340
|
#: ../js/ui/components/telepathyClient.js:1344
|
||||||
msgid "Internal error"
|
msgid "Internal error"
|
||||||
msgstr "Errore interno"
|
msgstr "Errore interno"
|
||||||
|
|
||||||
#. translators: argument is the account name, like
|
#. translators: argument is the account name, like
|
||||||
#. * name@jabber.org for example.
|
#. * name@jabber.org for example.
|
||||||
#: ../js/ui/components/telepathyClient.js:1350
|
#: ../js/ui/components/telepathyClient.js:1354
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unable to connect to %s"
|
msgid "Unable to connect to %s"
|
||||||
msgstr "Impossibile connettersi a %s"
|
msgstr "Impossibile connettersi a %s"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1355
|
#: ../js/ui/components/telepathyClient.js:1359
|
||||||
msgid "View account"
|
msgid "View account"
|
||||||
msgstr "Visualizza account"
|
msgstr "Visualizza account"
|
||||||
|
|
||||||
#: ../js/ui/components/telepathyClient.js:1394
|
#: ../js/ui/components/telepathyClient.js:1398
|
||||||
msgid "Unknown reason"
|
msgid "Unknown reason"
|
||||||
msgstr "Motivo sconosciuto"
|
msgstr "Motivo sconosciuto"
|
||||||
|
|
||||||
@@ -1019,14 +1037,14 @@ msgstr "Motivo sconosciuto"
|
|||||||
msgid "Windows"
|
msgid "Windows"
|
||||||
msgstr "Finestre"
|
msgstr "Finestre"
|
||||||
|
|
||||||
#: ../js/ui/dash.js:250 ../js/ui/dash.js:288
|
#: ../js/ui/dash.js:248 ../js/ui/dash.js:286
|
||||||
msgid "Show Applications"
|
msgid "Show Applications"
|
||||||
msgstr "Mostra applicazioni"
|
msgstr "Mostra applicazioni"
|
||||||
|
|
||||||
# cruscotto?!?!?!?!?!?!?
|
# cruscotto?!?!?!?!?!?!?
|
||||||
#. Translators: this is the name of the dock/favorites area on
|
#. Translators: this is the name of the dock/favorites area on
|
||||||
#. the left of the overview
|
#. the left of the overview
|
||||||
#: ../js/ui/dash.js:418
|
#: ../js/ui/dash.js:435
|
||||||
msgid "Dash"
|
msgid "Dash"
|
||||||
msgstr "Dash"
|
msgstr "Dash"
|
||||||
|
|
||||||
@@ -1152,86 +1170,86 @@ msgstr "Installa"
|
|||||||
msgid "Download and install '%s' from extensions.gnome.org?"
|
msgid "Download and install '%s' from extensions.gnome.org?"
|
||||||
msgstr "Scaricare e installare «%s» da extensions.gnome.org?"
|
msgstr "Scaricare e installare «%s» da extensions.gnome.org?"
|
||||||
|
|
||||||
#: ../js/ui/keyboard.js:621 ../js/ui/status/keyboard.js:314
|
#: ../js/ui/keyboard.js:619 ../js/ui/status/keyboard.js:314
|
||||||
#: ../js/ui/status/power.js:211
|
#: ../js/ui/status/power.js:211
|
||||||
msgid "Keyboard"
|
msgid "Keyboard"
|
||||||
msgstr "Tastiera"
|
msgstr "Tastiera"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:692
|
#: ../js/ui/lookingGlass.js:693
|
||||||
msgid "No extensions installed"
|
msgid "No extensions installed"
|
||||||
msgstr "Nessuna estensione installata"
|
msgstr "Nessuna estensione installata"
|
||||||
|
|
||||||
#. Translators: argument is an extension UUID.
|
#. Translators: argument is an extension UUID.
|
||||||
#: ../js/ui/lookingGlass.js:746
|
#: ../js/ui/lookingGlass.js:747
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s has not emitted any errors."
|
msgid "%s has not emitted any errors."
|
||||||
msgstr "%s non ha emesso alcun errore."
|
msgstr "%s non ha emesso alcun errore."
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:752
|
#: ../js/ui/lookingGlass.js:753
|
||||||
msgid "Hide Errors"
|
msgid "Hide Errors"
|
||||||
msgstr "Nascondi errori"
|
msgstr "Nascondi errori"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:756 ../js/ui/lookingGlass.js:816
|
#: ../js/ui/lookingGlass.js:757 ../js/ui/lookingGlass.js:817
|
||||||
msgid "Show Errors"
|
msgid "Show Errors"
|
||||||
msgstr "Mostra errori"
|
msgstr "Mostra errori"
|
||||||
|
|
||||||
# (ndt) o abilitata?
|
# (ndt) o abilitata?
|
||||||
#: ../js/ui/lookingGlass.js:765
|
#: ../js/ui/lookingGlass.js:766
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr "Abilitato"
|
msgstr "Abilitato"
|
||||||
|
|
||||||
# (ndt) o disabilitata?
|
# (ndt) o disabilitata?
|
||||||
#. translators:
|
#. translators:
|
||||||
#. * The device has been disabled
|
#. * The device has been disabled
|
||||||
#: ../js/ui/lookingGlass.js:768 ../src/gvc/gvc-mixer-control.c:1830
|
#: ../js/ui/lookingGlass.js:769 ../src/gvc/gvc-mixer-control.c:1830
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Disabilitato"
|
msgstr "Disabilitato"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:770
|
#: ../js/ui/lookingGlass.js:771
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr "Errore"
|
msgstr "Errore"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:772
|
#: ../js/ui/lookingGlass.js:773
|
||||||
msgid "Out of date"
|
msgid "Out of date"
|
||||||
msgstr "Non aggiornato"
|
msgstr "Non aggiornato"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:774
|
#: ../js/ui/lookingGlass.js:775
|
||||||
msgid "Downloading"
|
msgid "Downloading"
|
||||||
msgstr "Scaricamento"
|
msgstr "Scaricamento"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:798
|
#: ../js/ui/lookingGlass.js:799
|
||||||
msgid "View Source"
|
msgid "View Source"
|
||||||
msgstr "Visualizza sorgente"
|
msgstr "Visualizza sorgente"
|
||||||
|
|
||||||
#: ../js/ui/lookingGlass.js:807
|
#: ../js/ui/lookingGlass.js:808
|
||||||
msgid "Web Page"
|
msgid "Web Page"
|
||||||
msgstr "Pagina web"
|
msgstr "Pagina web"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1201
|
#: ../js/ui/messageTray.js:1182
|
||||||
msgid "Open"
|
msgid "Open"
|
||||||
msgstr "Apri"
|
msgstr "Apri"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1208
|
#: ../js/ui/messageTray.js:1189
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Rimuovi"
|
msgstr "Rimuovi"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1520
|
#: ../js/ui/messageTray.js:1501
|
||||||
msgid "Clear Messages"
|
msgid "Clear Messages"
|
||||||
msgstr "Pulisci messaggi"
|
msgstr "Pulisci messaggi"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1547
|
#: ../js/ui/messageTray.js:1528
|
||||||
msgid "Notification Settings"
|
msgid "Notification Settings"
|
||||||
msgstr "Impostazioni notifiche"
|
msgstr "Impostazioni notifiche"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1725
|
#: ../js/ui/messageTray.js:1707
|
||||||
msgid "No Messages"
|
msgid "No Messages"
|
||||||
msgstr "Nessun messaggio"
|
msgstr "Nessun messaggio"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1806
|
#: ../js/ui/messageTray.js:1787
|
||||||
msgid "Message Tray"
|
msgid "Message Tray"
|
||||||
msgstr "Cassetto messaggi"
|
msgstr "Cassetto messaggi"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:2881
|
#: ../js/ui/messageTray.js:2864
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "Informazione di sistema"
|
msgstr "Informazione di sistema"
|
||||||
|
|
||||||
@@ -1240,11 +1258,18 @@ msgctxt "program"
|
|||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "Sconosciuto"
|
msgstr "Sconosciuto"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:93
|
#: ../js/ui/overviewControls.js:460 ../js/ui/screenShield.js:153
|
||||||
|
#, c-format
|
||||||
|
msgid "%d new message"
|
||||||
|
msgid_plural "%d new messages"
|
||||||
|
msgstr[0] "%d nuovo messaggio"
|
||||||
|
msgstr[1] "%d nuovi messaggi"
|
||||||
|
|
||||||
|
#: ../js/ui/overview.js:82
|
||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
msgstr "Annulla"
|
msgstr "Annulla"
|
||||||
|
|
||||||
#: ../js/ui/overview.js:140
|
#: ../js/ui/overview.js:129
|
||||||
msgid "Overview"
|
msgid "Overview"
|
||||||
msgstr "Panoramica"
|
msgstr "Panoramica"
|
||||||
|
|
||||||
@@ -1252,7 +1277,7 @@ msgstr "Panoramica"
|
|||||||
#. in the search entry when no search is
|
#. in the search entry when no search is
|
||||||
#. active; it should not exceed ~30
|
#. active; it should not exceed ~30
|
||||||
#. characters.
|
#. characters.
|
||||||
#: ../js/ui/overview.js:220
|
#: ../js/ui/overview.js:284
|
||||||
msgid "Type to search…"
|
msgid "Type to search…"
|
||||||
msgstr "Digita per cercare…"
|
msgstr "Digita per cercare…"
|
||||||
|
|
||||||
@@ -1266,7 +1291,7 @@ msgstr "Esci"
|
|||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Attività"
|
msgstr "Attività"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:982
|
#: ../js/ui/panel.js:983
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Barra superiore"
|
msgstr "Barra superiore"
|
||||||
|
|
||||||
@@ -1289,29 +1314,22 @@ msgstr "Chiudi"
|
|||||||
|
|
||||||
#. Translators: This is a time format for a date in
|
#. Translators: This is a time format for a date in
|
||||||
#. long format
|
#. long format
|
||||||
#: ../js/ui/screenShield.js:117
|
#: ../js/ui/screenShield.js:90
|
||||||
msgid "%A, %B %d"
|
msgid "%A, %B %d"
|
||||||
msgstr "%A, %d %B"
|
msgstr "%A, %d %B"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:180
|
#: ../js/ui/screenShield.js:155
|
||||||
#, c-format
|
|
||||||
msgid "%d new message"
|
|
||||||
msgid_plural "%d new messages"
|
|
||||||
msgstr[0] "%d nuovo messaggio"
|
|
||||||
msgstr[1] "%d nuovi messaggi"
|
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:182
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d new notification"
|
msgid "%d new notification"
|
||||||
msgid_plural "%d new notifications"
|
msgid_plural "%d new notifications"
|
||||||
msgstr[0] "%d nuova notifica"
|
msgstr[0] "%d nuova notifica"
|
||||||
msgstr[1] "%d nuove notifiche"
|
msgstr[1] "%d nuove notifiche"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:469 ../js/ui/userMenu.js:805
|
#: ../js/ui/screenShield.js:442 ../js/ui/userMenu.js:805
|
||||||
msgid "Lock"
|
msgid "Lock"
|
||||||
msgstr "Blocca"
|
msgstr "Blocca"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:635
|
#: ../js/ui/screenShield.js:639
|
||||||
msgid "GNOME needs to lock the screen"
|
msgid "GNOME needs to lock the screen"
|
||||||
msgstr "GNOME deve bloccare lo schermo"
|
msgstr "GNOME deve bloccare lo schermo"
|
||||||
|
|
||||||
@@ -1322,11 +1340,11 @@ msgstr "GNOME deve bloccare lo schermo"
|
|||||||
#.
|
#.
|
||||||
#. XXX: another option is to kick the user into the gdm login
|
#. XXX: another option is to kick the user into the gdm login
|
||||||
#. screen, where we're not affected by grabs
|
#. screen, where we're not affected by grabs
|
||||||
#: ../js/ui/screenShield.js:754 ../js/ui/screenShield.js:1165
|
#: ../js/ui/screenShield.js:758 ../js/ui/screenShield.js:1169
|
||||||
msgid "Unable to lock"
|
msgid "Unable to lock"
|
||||||
msgstr "Impossibile bloccare"
|
msgstr "Impossibile bloccare"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:755 ../js/ui/screenShield.js:1166
|
#: ../js/ui/screenShield.js:759 ../js/ui/screenShield.js:1170
|
||||||
msgid "Lock was blocked by an application"
|
msgid "Lock was blocked by an application"
|
||||||
msgstr "Il blocco è stato impedito da un'applicazione."
|
msgstr "Il blocco è stato impedito da un'applicazione."
|
||||||
|
|
||||||
@@ -1362,56 +1380,56 @@ msgstr "Password"
|
|||||||
msgid "Remember Password"
|
msgid "Remember Password"
|
||||||
msgstr "Ricorda password"
|
msgstr "Ricorda password"
|
||||||
|
|
||||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:192
|
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:140
|
||||||
msgid "Unlock"
|
msgid "Unlock"
|
||||||
msgstr "Sblocca"
|
msgstr "Sblocca"
|
||||||
|
|
||||||
# su Android è Rilevabile :P
|
# su Android è Rilevabile :P
|
||||||
#: ../js/ui/status/accessibility.js:35
|
#: ../js/ui/status/accessibility.js:36
|
||||||
msgid "Accessibility"
|
msgid "Accessibility"
|
||||||
msgstr "Accessibilità"
|
msgstr "Accessibilità"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:40
|
#: ../js/ui/status/accessibility.js:41
|
||||||
msgid "Zoom"
|
msgid "Zoom"
|
||||||
msgstr "Ingrandimento"
|
msgstr "Ingrandimento"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:47
|
#: ../js/ui/status/accessibility.js:48
|
||||||
msgid "Screen Reader"
|
msgid "Screen Reader"
|
||||||
msgstr "Lettore schermo"
|
msgstr "Lettore schermo"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:51
|
#: ../js/ui/status/accessibility.js:52
|
||||||
msgid "Screen Keyboard"
|
msgid "Screen Keyboard"
|
||||||
msgstr "Tastiera a schermo"
|
msgstr "Tastiera a schermo"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:55
|
#: ../js/ui/status/accessibility.js:56
|
||||||
msgid "Visual Alerts"
|
msgid "Visual Alerts"
|
||||||
msgstr "Avvisi visibili"
|
msgstr "Avvisi visibili"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:58
|
#: ../js/ui/status/accessibility.js:59
|
||||||
msgid "Sticky Keys"
|
msgid "Sticky Keys"
|
||||||
msgstr "Tasti singoli"
|
msgstr "Tasti singoli"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:61
|
#: ../js/ui/status/accessibility.js:62
|
||||||
msgid "Slow Keys"
|
msgid "Slow Keys"
|
||||||
msgstr "Tasti lenti"
|
msgstr "Tasti lenti"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:64
|
#: ../js/ui/status/accessibility.js:65
|
||||||
msgid "Bounce Keys"
|
msgid "Bounce Keys"
|
||||||
msgstr "Tasti rimbalzati"
|
msgstr "Tasti rimbalzati"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:67
|
#: ../js/ui/status/accessibility.js:68
|
||||||
msgid "Mouse Keys"
|
msgid "Mouse Keys"
|
||||||
msgstr "Mouse da tastiera"
|
msgstr "Mouse da tastiera"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:71
|
#: ../js/ui/status/accessibility.js:72
|
||||||
msgid "Universal Access Settings"
|
msgid "Universal Access Settings"
|
||||||
msgstr "Impostazioni accesso universale"
|
msgstr "Impostazioni accesso universale"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:107
|
#: ../js/ui/status/accessibility.js:129
|
||||||
msgid "High Contrast"
|
msgid "High Contrast"
|
||||||
msgstr "Contrasto elevato"
|
msgstr "Contrasto elevato"
|
||||||
|
|
||||||
#: ../js/ui/status/accessibility.js:154
|
#: ../js/ui/status/accessibility.js:178
|
||||||
msgid "Large Text"
|
msgid "Large Text"
|
||||||
msgstr "Caratteri grandi"
|
msgstr "Caratteri grandi"
|
||||||
|
|
||||||
@@ -1774,11 +1792,11 @@ msgstr "Volume"
|
|||||||
msgid "Microphone"
|
msgid "Microphone"
|
||||||
msgstr "Microfono"
|
msgstr "Microfono"
|
||||||
|
|
||||||
#: ../js/ui/unlockDialog.js:203
|
#: ../js/ui/unlockDialog.js:151
|
||||||
msgid "Log in as another user"
|
msgid "Log in as another user"
|
||||||
msgstr "Accedi come altro utente"
|
msgstr "Accedi come altro utente"
|
||||||
|
|
||||||
#: ../js/ui/unlockDialog.js:229
|
#: ../js/ui/unlockDialog.js:177
|
||||||
msgid "Unlock Window"
|
msgid "Unlock Window"
|
||||||
msgstr "Sblocca finestra"
|
msgstr "Sblocca finestra"
|
||||||
|
|
||||||
@@ -1810,10 +1828,6 @@ msgstr "Fuori rete"
|
|||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Notifiche"
|
msgstr "Notifiche"
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:787
|
|
||||||
msgid "Settings"
|
|
||||||
msgstr "Impostazioni"
|
|
||||||
|
|
||||||
#: ../js/ui/userMenu.js:795
|
#: ../js/ui/userMenu.js:795
|
||||||
msgid "Switch User"
|
msgid "Switch User"
|
||||||
msgstr "Cambia utente"
|
msgstr "Cambia utente"
|
||||||
@@ -1947,6 +1961,10 @@ msgstr "La password non può essere vuota"
|
|||||||
msgid "Authentication dialog was dismissed by the user"
|
msgid "Authentication dialog was dismissed by the user"
|
||||||
msgstr "Il dialogo di autenticazione è stato annullato dall'utente"
|
msgstr "Il dialogo di autenticazione è stato annullato dall'utente"
|
||||||
|
|
||||||
|
#~ msgctxt "title"
|
||||||
|
#~ msgid "Sign In"
|
||||||
|
#~ msgstr "Accesso"
|
||||||
|
|
||||||
#~ msgid "Clear"
|
#~ msgid "Clear"
|
||||||
#~ msgstr "Pulisci"
|
#~ msgstr "Pulisci"
|
||||||
|
|
||||||
|
|||||||
597
po/pt_BR.po
597
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user